Compare commits

..

4 Commits

Author SHA1 Message Date
Felipe Cardoso
678e1db0a3 Update max additional guests logic and refine guest counts display
All checks were successful
Build and Push Docker Images / changes (push) Successful in 5s
Build and Push Docker Images / build-backend (push) Has been skipped
Build and Push Docker Images / build-frontend (push) Successful in 1m15s
Set default max additional guests to 10 and renamed related labels for clarity. Improved guest count calculation by adding total confirmed guests and refining additional guest computations. Updated the UI to reflect these changes concisely and consistently.
2025-03-20 18:33:02 +01:00
Felipe Cardoso
a2c3f16dc7 Update guests-list to use RSVP data for dietary and notes
All checks were successful
Build and Push Docker Images / changes (push) Successful in 11s
Build and Push Docker Images / build-backend (push) Has been skipped
Build and Push Docker Images / build-frontend (push) Successful in 1m49s
Replaced `guest.dietary_restrictions` and `guest.notes` with `guest.rsvp.dietary_requirements` and `guest.rsvp.response_message`. This ensures the data reflects RSVP-specific fields and improves code consistency with the RSVP model.
2025-03-19 20:49:29 +01:00
Felipe Cardoso
44e6b2a6dc Refactor guest schema and add RSVP field to GuestBase.
Reorganized imports for better readability and compliance with standards. Added an optional `rsvp` field to the `GuestBase` model to include RSVP details. This enhances the schema's flexibility and supports additional guest-related data.
2025-03-19 20:47:12 +01:00
Felipe Cardoso
42508af610 Add optional RSVP field to guest schema
This commit introduces an optional `rsvp` field to the guest-related types and schemas. The field is nullable and references the `RSVPSchema`, allowing better handling of RSVP data in the application.
2025-03-19 20:47:07 +01:00
4 changed files with 40 additions and 23 deletions

View File

@@ -1,11 +1,10 @@
import uuid
from pydantic import BaseModel, EmailStr, ConfigDict
from datetime import datetime from datetime import datetime
from typing import Optional, Any, Dict from typing import Optional, Any, Dict
from app.models.guest import GuestStatus
from uuid import UUID from uuid import UUID
from pydantic import BaseModel, EmailStr, ConfigDict
from app.models.guest import GuestStatus
from app.schemas.rsvp import RSVPSchema, RSVPStatus from app.schemas.rsvp import RSVPSchema, RSVPStatus
@@ -50,6 +49,8 @@ class GuestRead(GuestBase):
is_blocked: bool is_blocked: bool
model_config = ConfigDict(from_attributes=True) model_config = ConfigDict(from_attributes=True)
invitation_code: str invitation_code: str
rsvp: Optional[RSVPSchema] = None
class GuestWithRSVPResponse(BaseModel): class GuestWithRSVPResponse(BaseModel):
""" """
@@ -62,6 +63,7 @@ class GuestWithRSVPResponse(BaseModel):
class Config: class Config:
from_attributes = True from_attributes = True
def map_rsvp_status_to_guest_status(rsvp_status: RSVPStatus) -> GuestStatus: def map_rsvp_status_to_guest_status(rsvp_status: RSVPStatus) -> GuestStatus:
if rsvp_status == RSVPStatus.ATTENDING: if rsvp_status == RSVPStatus.ATTENDING:
return GuestStatus.CONFIRMED return GuestStatus.CONFIRMED
@@ -70,4 +72,4 @@ def map_rsvp_status_to_guest_status(rsvp_status: RSVPStatus) -> GuestStatus:
elif rsvp_status == RSVPStatus.MAYBE: elif rsvp_status == RSVPStatus.MAYBE:
return GuestStatus.PENDING return GuestStatus.PENDING
else: else:
return GuestStatus.INVITED return GuestStatus.INVITED

View File

@@ -2427,6 +2427,16 @@ export const GuestReadSchema = {
type: "string", type: "string",
title: "Invitation Code", title: "Invitation Code",
}, },
rsvp: {
anyOf: [
{
$ref: "#/components/schemas/RSVPSchema",
},
{
type: "null",
},
],
},
}, },
type: "object", type: "object",
required: [ required: [

View File

@@ -370,6 +370,7 @@ export type GuestRead = {
actual_additional_guests: number; actual_additional_guests: number;
is_blocked: boolean; is_blocked: boolean;
invitation_code: string; invitation_code: string;
rsvp?: RsvpSchema | null;
}; };
export type GuestStatus = export type GuestStatus =

View File

@@ -101,7 +101,7 @@ const GuestListTable = ({ event }: GuestListTableProps) => {
full_name: "", full_name: "",
email: "", email: "",
phone: "", phone: "",
max_additional_guests: 0, max_additional_guests: 10,
dietary_restrictions: "", dietary_restrictions: "",
notes: "", notes: "",
can_bring_guests: true, can_bring_guests: true,
@@ -293,7 +293,7 @@ const GuestListTable = ({ event }: GuestListTableProps) => {
"Phone", "Phone",
"Invitation Code", "Invitation Code",
"Status", "Status",
"Additional Guests", "Max Additional Guests",
]; ];
const csvContent = [ const csvContent = [
headers.join(","), headers.join(","),
@@ -348,6 +348,12 @@ const GuestListTable = ({ event }: GuestListTableProps) => {
} }
}, [addGuestOpen, editGuestOpen, currentGuest]); }, [addGuestOpen, editGuestOpen, currentGuest]);
const confirmedGuestCount =
guests?.filter((g) => g.status === GuestStatus.CONFIRMED).length || 0;
const confirmedAdditionalGuestsCount =
guests?.reduce((acc, g) => acc + (g.actual_additional_guests || 0), 0) || 0;
const totalConfirmedGuestsCount =
confirmedGuestCount + confirmedAdditionalGuestsCount;
return ( return (
<div className="space-y-4 w-full"> <div className="space-y-4 w-full">
{error && ( {error && (
@@ -414,14 +420,14 @@ const GuestListTable = ({ event }: GuestListTableProps) => {
</div> </div>
<div className="grid grid-cols-4 items-center gap-4"> <div className="grid grid-cols-4 items-center gap-4">
<Label htmlFor="max_additional_guests" className="text-right"> <Label htmlFor="max_additional_guests" className="text-right">
Additional Guests Max Add. Guests
</Label> </Label>
<Input <Input
id="max_additional_guests" id="max_additional_guests"
name="max_additional_guests" name="max_additional_guests"
type="number" type="number"
min="0" min="0"
value={formData.max_additional_guests || 0} value={formData.max_additional_guests || 10}
onChange={handleInputChange} onChange={handleInputChange}
className="col-span-3" className="col-span-3"
/> />
@@ -578,8 +584,8 @@ const GuestListTable = ({ event }: GuestListTableProps) => {
{/* Dietary Restrictions Column */} {/* Dietary Restrictions Column */}
<TableCell> <TableCell>
{guest.dietary_restrictions && {guest.rsvp?.dietary_requirements &&
guest.dietary_restrictions.length > 0 ? ( guest.rsvp.dietary_requirements.length > 0 ? (
<Popover> <Popover>
<PopoverTrigger asChild> <PopoverTrigger asChild>
<Button <Button
@@ -592,7 +598,7 @@ const GuestListTable = ({ event }: GuestListTableProps) => {
</PopoverTrigger> </PopoverTrigger>
<PopoverContent className="max-w-xs"> <PopoverContent className="max-w-xs">
<p className="text-sm"> <p className="text-sm">
{guest.dietary_restrictions} {guest.rsvp.dietary_requirements}
</p> </p>
</PopoverContent> </PopoverContent>
</Popover> </Popover>
@@ -603,7 +609,8 @@ const GuestListTable = ({ event }: GuestListTableProps) => {
{/* Notes Column */} {/* Notes Column */}
<TableCell> <TableCell>
{guest.notes && guest.notes.length > 0 ? ( {guest.rsvp?.response_message &&
guest.rsvp.response_message.length > 0 ? (
<Popover> <Popover>
<PopoverTrigger asChild> <PopoverTrigger asChild>
<Button <Button
@@ -615,7 +622,9 @@ const GuestListTable = ({ event }: GuestListTableProps) => {
</Button> </Button>
</PopoverTrigger> </PopoverTrigger>
<PopoverContent className="max-w-xs"> <PopoverContent className="max-w-xs">
<p className="text-sm">{guest.notes}</p> <p className="text-sm">
{guest.rsvp.response_message}
</p>
</PopoverContent> </PopoverContent>
</Popover> </Popover>
) : ( ) : (
@@ -682,14 +691,9 @@ const GuestListTable = ({ event }: GuestListTableProps) => {
Showing {filteredGuests.length} of {guests?.length || 0} guests Showing {filteredGuests.length} of {guests?.length || 0} guests
</div> </div>
<div> <div>
Total Confirmed:{" "} Guests Confirmed: {confirmedGuestCount} | Additional Guests:{" "}
{guests?.filter((g) => g.status === GuestStatus.CONFIRMED).length || {confirmedAdditionalGuestsCount} | Total Guests:{" "}
0}{" "} {totalConfirmedGuestsCount}
| Total Additional Guests:{" "}
{guests?.reduce(
(acc, g) => acc + (g.max_additional_guests || 0),
0,
) || 0}
</div> </div>
</div> </div>
@@ -743,7 +747,7 @@ const GuestListTable = ({ event }: GuestListTableProps) => {
htmlFor="edit_max_additional_guests" htmlFor="edit_max_additional_guests"
className="text-right" className="text-right"
> >
Additional Guests Max Add. Guests
</Label> </Label>
<Input <Input
id="edit_max_additional_guests" id="edit_max_additional_guests"