feat: add food interest tracking to registration flow
Add "I would like to include food for the week" checkbox to the payment
step with co-producing meals messaging. Track food interest in Google
Sheets as column Q ("Want Food").
- Add wantFood field to RegistrationData interface
- Add interactive food checkbox replacing static note in payment step
- Pass wantFood through register API to Google Sheets
- Expand sheet ranges from A:P to A:Q, add "Want Food" header
- Preserve food column on payment status updates
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
c64c4fb554
commit
b8567b0f54
|
|
@ -5,7 +5,7 @@ export async function POST(request: NextRequest) {
|
|||
try {
|
||||
const body = await request.json()
|
||||
|
||||
const { name, email, contact, contributions, expectations, howHeard, dietary, crewConsent } = body
|
||||
const { name, email, contact, contributions, expectations, howHeard, dietary, crewConsent, wantFood } = body
|
||||
|
||||
// Validate required fields
|
||||
if (!name || !email || !contact || !contributions || !expectations || !crewConsent) {
|
||||
|
|
@ -28,6 +28,7 @@ export async function POST(request: NextRequest) {
|
|||
howHeard: howHeard || "",
|
||||
dietary: Array.isArray(dietary) ? dietary.join(", ") : dietary || "",
|
||||
crewConsent,
|
||||
wantFood: wantFood || false,
|
||||
})
|
||||
|
||||
console.log(`[Register API] Registration added for ${name} at row ${rowNumber}`)
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ export default function RegisterPage() {
|
|||
const [step, setStep] = useState<"form" | "payment">("form")
|
||||
const [isSubmitting, setIsSubmitting] = useState(false)
|
||||
const [includeAccommodation, setIncludeAccommodation] = useState(true)
|
||||
const [wantFood, setWantFood] = useState(false)
|
||||
const [accommodationVenue, setAccommodationVenue] = useState<"commons-hub" | "herrnhof">("commons-hub")
|
||||
const [accommodationType, setAccommodationType] = useState("ch-multi")
|
||||
const [formData, setFormData] = useState({
|
||||
|
|
@ -85,6 +86,7 @@ export default function RegisterPage() {
|
|||
howHeard: formData.howHeard,
|
||||
dietary: dietaryString,
|
||||
crewConsent: formData.crewConsent,
|
||||
wantFood,
|
||||
}),
|
||||
})
|
||||
|
||||
|
|
@ -283,14 +285,27 @@ export default function RegisterPage() {
|
|||
</p>
|
||||
)}
|
||||
|
||||
{/* Food note */}
|
||||
{/* Food */}
|
||||
<div className="py-4 border-b border-border">
|
||||
<p className="text-sm text-muted-foreground">
|
||||
<span className="font-medium text-foreground">Food:</span>{" "}
|
||||
We'll follow up via email with food options and pricing closer to the event.
|
||||
<div className="flex items-start gap-3">
|
||||
<Checkbox
|
||||
id="include-food"
|
||||
checked={wantFood}
|
||||
onCheckedChange={(checked) => setWantFood(checked as boolean)}
|
||||
className="mt-1"
|
||||
/>
|
||||
<div className="flex-1">
|
||||
<Label htmlFor="include-food" className="font-medium cursor-pointer">
|
||||
I would like to include food for the week
|
||||
</Label>
|
||||
<p className="text-sm text-muted-foreground mt-1">
|
||||
We are exploring co-producing our own meals as a community. More details and costs
|
||||
will be shared soon — checking this box registers your interest so we can plan accordingly.
|
||||
Your dietary preferences from step 1 have been noted.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Processing fee */}
|
||||
<div className="flex items-start justify-between py-3">
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ export interface RegistrationData {
|
|||
howHeard: string
|
||||
dietary: string
|
||||
crewConsent: string
|
||||
wantFood: boolean
|
||||
}
|
||||
|
||||
export interface PaymentUpdateData {
|
||||
|
|
@ -65,12 +66,13 @@ export async function addRegistration(data: RegistrationData): Promise<number> {
|
|||
"", // N: Payment Date
|
||||
"", // O: Accommodation Venue
|
||||
"", // P: Accommodation Type
|
||||
data.wantFood ? "Yes" : "No", // Q: Want Food
|
||||
],
|
||||
]
|
||||
|
||||
const response = await sheets.spreadsheets.values.append({
|
||||
spreadsheetId: SPREADSHEET_ID,
|
||||
range: `${SHEET_NAME}!A:P`,
|
||||
range: `${SHEET_NAME}!A:Q`,
|
||||
valueInputOption: "USER_ENTERED",
|
||||
insertDataOption: "INSERT_ROWS",
|
||||
requestBody: { values },
|
||||
|
|
@ -97,7 +99,7 @@ export async function updatePaymentStatus(data: PaymentUpdateData): Promise<bool
|
|||
// First, get all rows to find the matching registration
|
||||
const response = await sheets.spreadsheets.values.get({
|
||||
spreadsheetId: SPREADSHEET_ID,
|
||||
range: `${SHEET_NAME}!A:P`,
|
||||
range: `${SHEET_NAME}!A:Q`,
|
||||
})
|
||||
|
||||
const rows = response.data.values || []
|
||||
|
|
@ -124,7 +126,7 @@ export async function updatePaymentStatus(data: PaymentUpdateData): Promise<bool
|
|||
|
||||
// Update the row with payment information
|
||||
const existingRow = rows[targetRowIndex - 1]
|
||||
const updateRange = `${SHEET_NAME}!C${targetRowIndex}:P${targetRowIndex}`
|
||||
const updateRange = `${SHEET_NAME}!C${targetRowIndex}:Q${targetRowIndex}`
|
||||
const updateValues = [
|
||||
[
|
||||
data.email || existingRow[2] || "", // C: Email (from Mollie or existing)
|
||||
|
|
@ -141,6 +143,7 @@ export async function updatePaymentStatus(data: PaymentUpdateData): Promise<bool
|
|||
data.paymentDate || new Date().toISOString(), // N: Payment Date
|
||||
data.accommodationVenue || "", // O: Accommodation Venue
|
||||
data.accommodationType || "", // P: Accommodation Type
|
||||
existingRow[16] || "", // Q: Want Food (preserve)
|
||||
],
|
||||
]
|
||||
|
||||
|
|
@ -169,7 +172,7 @@ export async function initializeSheetHeaders(): Promise<void> {
|
|||
// Check if first row has data
|
||||
const response = await sheets.spreadsheets.values.get({
|
||||
spreadsheetId: SPREADSHEET_ID,
|
||||
range: `${SHEET_NAME}!A1:P1`,
|
||||
range: `${SHEET_NAME}!A1:Q1`,
|
||||
})
|
||||
|
||||
if (!response.data.values || response.data.values.length === 0) {
|
||||
|
|
@ -192,12 +195,13 @@ export async function initializeSheetHeaders(): Promise<void> {
|
|||
"Payment Date",
|
||||
"Accommodation Venue",
|
||||
"Accommodation Type",
|
||||
"Want Food",
|
||||
],
|
||||
]
|
||||
|
||||
await sheets.spreadsheets.values.update({
|
||||
spreadsheetId: SPREADSHEET_ID,
|
||||
range: `${SHEET_NAME}!A1:P1`,
|
||||
range: `${SHEET_NAME}!A1:Q1`,
|
||||
valueInputOption: "USER_ENTERED",
|
||||
requestBody: { values: headers },
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in New Issue