added engagement congratulations to guest book

This commit is contained in:
2025-07-15 09:23:33 -04:00
parent 5931d042b5
commit 3a2b20e468
7 changed files with 220 additions and 26 deletions

View File

@@ -13,6 +13,7 @@ export default function EditGuestBookEntryModal({ isOpen, onClose, initialData,
email?: string email?: string
phone?: string phone?: string
address?: string address?: string
congratulated?: boolean | null
side?: string side?: string
notes?: string notes?: string
} }
@@ -109,6 +110,21 @@ export default function EditGuestBookEntryModal({ isOpen, onClose, initialData,
value={formData.address || ''} value={formData.address || ''}
onChange={handleChange} onChange={handleChange}
/> />
<div className="flex items-center gap-2">
<input
type="checkbox"
name="congratulated"
checked={!!formData.congratulated}
onChange={(e) =>
setFormData((prev) => ({
...prev,
congratulated: e.target.checked,
}))
}
className="checkbox"
/>
<label htmlFor="congratulated">Congratulated</label>
</div>
<input <input
className="input input-bordered w-full" className="input input-bordered w-full"
type="text" type="text"

View File

@@ -10,6 +10,7 @@ interface GuestBookEntry {
email?: string | null email?: string | null
phone?: string | null phone?: string | null
address?: string | null address?: string | null
congratulated?: boolean | null
notes?: string | null notes?: string | null
} }
@@ -27,6 +28,7 @@ export default function GuestBookList({ entries, view }: { entries: GuestBookEnt
email?: string email?: string
phone?: string phone?: string
address?: string address?: string
congratulated?: boolean | null
side?: string side?: string
notes?: string notes?: string
}) { }) {
@@ -40,6 +42,7 @@ export default function GuestBookList({ entries, view }: { entries: GuestBookEnt
email: updated.email, email: updated.email,
phone: updated.phone, phone: updated.phone,
address: updated.address, address: updated.address,
congratulated: updated.congratulated,
side: updated.side, side: updated.side,
notes: updated.notes, notes: updated.notes,
}), }),
@@ -68,6 +71,7 @@ export default function GuestBookList({ entries, view }: { entries: GuestBookEnt
<th className='px-4 py-2'>Email</th> <th className='px-4 py-2'>Email</th>
<th className='px-4 py-2'>Phone</th> <th className='px-4 py-2'>Phone</th>
<th className='px-4 py-2'>Address</th> <th className='px-4 py-2'>Address</th>
<th className='px-4 py-2'>Congratulated Engagement</th>
<th className='px-4 py-2'>Notes</th> <th className='px-4 py-2'>Notes</th>
</tr> </tr>
</thead> </thead>
@@ -82,6 +86,7 @@ export default function GuestBookList({ entries, view }: { entries: GuestBookEnt
<td className='border border-brand-primary px-4 py-2'>{entry.email || 'N/A'}</td> <td className='border border-brand-primary px-4 py-2'>{entry.email || 'N/A'}</td>
<td className='border border-brand-primary px-4 py-2'>{entry.phone || 'N/A'}</td> <td className='border border-brand-primary px-4 py-2'>{entry.phone || 'N/A'}</td>
<td className='border border-brand-primary px-4 py-2'>{entry.address || 'N/A'}</td> <td className='border border-brand-primary px-4 py-2'>{entry.address || 'N/A'}</td>
<td className='border border-brand-primary px-4 py-2'>{entry.congratulated == true ? 'Yes' : "No"}</td>
<td className='border border-brand-primary px-4 py-2'>{entry.notes || 'N/A'}</td> <td className='border border-brand-primary px-4 py-2'>{entry.notes || 'N/A'}</td>
</tr> </tr>
))} ))}
@@ -122,6 +127,7 @@ export default function GuestBookList({ entries, view }: { entries: GuestBookEnt
email: editingEntry.email || '', email: editingEntry.email || '',
phone: editingEntry.phone || '', phone: editingEntry.phone || '',
address: editingEntry.address || '', address: editingEntry.address || '',
congratulated: editingEntry.congratulated,
side: editingEntry.side, side: editingEntry.side,
notes: editingEntry.notes || '', notes: editingEntry.notes || '',
}} }}

169
drift_fix.sql Normal file
View File

@@ -0,0 +1,169 @@
-- CreateEnum
CREATE TYPE "Role" AS ENUM ('COUPLE', 'PLANNER', 'GUEST');
-- CreateEnum
CREATE TYPE "RsvpStatus" AS ENUM ('YES', 'NO', 'PENDING');
-- CreateTable
CREATE TABLE "User" (
"id" TEXT NOT NULL,
"email" TEXT NOT NULL,
"password" TEXT,
"name" TEXT,
"username" TEXT NOT NULL,
"role" "Role" NOT NULL DEFAULT 'GUEST',
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Event" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"date" TIMESTAMP(3),
"locationid" TEXT,
"creatorId" TEXT NOT NULL,
"notes" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "Event_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Location" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"address" TEXT NOT NULL,
"city" TEXT NOT NULL,
"state" TEXT NOT NULL,
"postalCode" TEXT NOT NULL,
"country" TEXT NOT NULL DEFAULT 'United States',
"phone" TEXT,
"email" TEXT,
CONSTRAINT "Location_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Guest" (
"id" TEXT NOT NULL,
"eventId" TEXT NOT NULL,
"name" TEXT NOT NULL,
"email" TEXT,
"rsvp" "RsvpStatus" NOT NULL DEFAULT 'PENDING',
CONSTRAINT "Guest_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "InviteToken" (
"id" TEXT NOT NULL,
"email" TEXT NOT NULL,
"role" "Role" NOT NULL,
"token" TEXT NOT NULL,
"eventId" TEXT,
"expiresAt" TIMESTAMP(3) NOT NULL,
"accepted" BOOLEAN NOT NULL DEFAULT false,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "InviteToken_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "GuestBookEntry" (
"id" TEXT NOT NULL,
"fName" TEXT NOT NULL,
"lName" TEXT NOT NULL,
"email" TEXT,
"phone" TEXT,
"address" TEXT,
"notes" TEXT,
"side" TEXT NOT NULL,
"congratulated" BOOLEAN,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "GuestBookEntry_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "EventGuest" (
"id" TEXT NOT NULL,
"eventId" TEXT NOT NULL,
"guestBookEntryId" TEXT NOT NULL,
"rsvp" "RsvpStatus" NOT NULL DEFAULT 'PENDING',
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "EventGuest_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "EventTodo" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"complete" BOOLEAN NOT NULL DEFAULT false,
"dueDate" TIMESTAMP(3),
"notes" TEXT,
"eventId" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "EventTodo_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "FileUpload" (
"id" TEXT NOT NULL,
"filepath" TEXT NOT NULL,
"filename" TEXT NOT NULL,
"filetype" TEXT NOT NULL,
"filesize" INTEGER NOT NULL,
"uploadedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"uploadedById" TEXT NOT NULL,
"eventId" TEXT,
CONSTRAINT "FileUpload_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
-- CreateIndex
CREATE UNIQUE INDEX "User_username_key" ON "User"("username");
-- CreateIndex
CREATE UNIQUE INDEX "InviteToken_email_key" ON "InviteToken"("email");
-- CreateIndex
CREATE UNIQUE INDEX "InviteToken_token_key" ON "InviteToken"("token");
-- CreateIndex
CREATE UNIQUE INDEX "EventGuest_eventId_guestBookEntryId_key" ON "EventGuest"("eventId", "guestBookEntryId");
-- CreateIndex
CREATE UNIQUE INDEX "FileUpload_filename_uploadedById_key" ON "FileUpload"("filename", "uploadedById");
-- AddForeignKey
ALTER TABLE "Event" ADD CONSTRAINT "Event_locationid_fkey" FOREIGN KEY ("locationid") REFERENCES "Location"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Event" ADD CONSTRAINT "Event_creatorId_fkey" FOREIGN KEY ("creatorId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Guest" ADD CONSTRAINT "Guest_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "Event"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "EventGuest" ADD CONSTRAINT "EventGuest_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "Event"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "EventGuest" ADD CONSTRAINT "EventGuest_guestBookEntryId_fkey" FOREIGN KEY ("guestBookEntryId") REFERENCES "GuestBookEntry"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "EventTodo" ADD CONSTRAINT "EventTodo_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "Event"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "FileUpload" ADD CONSTRAINT "FileUpload_uploadedById_fkey" FOREIGN KEY ("uploadedById") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "FileUpload" ADD CONSTRAINT "FileUpload_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "Event"("id") ON DELETE SET NULL ON UPDATE CASCADE;

View File

@@ -97,33 +97,33 @@ export const queries = {
}) { }) {
// ⏱ Quick recent entries (e.g., homepage) // ⏱ Quick recent entries (e.g., homepage)
if (takeOnlyRecent) { if (takeOnlyRecent) {
const entries = await prisma.guestBookEntry.findMany({ const entries = await prisma.guestBookEntry.findMany({
take: takeOnlyRecent, take: takeOnlyRecent,
orderBy: { createdAt: 'desc' }, orderBy: { createdAt: 'desc' },
}) })
return entries return entries
} }
// 📄 Paginated GuestBook view // 📄 Paginated GuestBook view
const skip = ((page ?? 1) - 1) * pageSize const skip = ((page ?? 1) - 1) * pageSize
const [entries, totalCount] = await Promise.all([ const [entries, totalCount] = await Promise.all([
prisma.guestBookEntry.findMany({ prisma.guestBookEntry.findMany({
skip, skip,
take: pageSize, take: pageSize,
orderBy: newestFirst orderBy: newestFirst
? { createdAt: 'desc' } ? { createdAt: 'desc' }
: [{ lName: 'asc' }, { fName: 'asc' }], : [{ lName: 'asc' }, { fName: 'asc' }],
}), }),
prisma.guestBookEntry.count(), prisma.guestBookEntry.count(),
]) ])
const totalPages = Math.ceil(totalCount / pageSize) const totalPages = Math.ceil(totalCount / pageSize)
return { return {
entries, entries,
totalPages, totalPages,
currentPage: page ?? 1, currentPage: page ?? 1,
} }
}, },

BIN
prisma/migrations/.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "GuestBookEntry" ADD COLUMN "congratulated" BOOLEAN;

View File

@@ -84,16 +84,17 @@ model InviteToken {
} }
model GuestBookEntry { model GuestBookEntry {
id String @id @default(cuid()) id String @id @default(cuid())
fName String fName String
lName String lName String
email String? email String?
phone String? phone String?
address String? address String?
notes String? notes String?
side String // e.g., "Brian", "Janice", etc. side String
eventGuests EventGuest[] congratulated Boolean?
createdAt DateTime @default(now()) eventGuests EventGuest[]
createdAt DateTime @default(now())
} }
model EventGuest { model EventGuest {