diff --git a/apps/web/src/pages/Book.tsx b/apps/web/src/pages/Book.tsx index 0e0710d..dc58c9b 100644 --- a/apps/web/src/pages/Book.tsx +++ b/apps/web/src/pages/Book.tsx @@ -1,4 +1,5 @@ import { useEffect, useState } from "react"; +import { useSearchParams } from "react-router-dom"; import type { Service } from "@groombook/types"; // ─── Types ─────────────────────────────────────────────────────────────────── @@ -107,6 +108,7 @@ export function BookPage() { // Step 2 — date & time const [date, setDate] = useState(todayIso()); + const [dateError, setDateError] = useState(null); const [slots, setSlots] = useState([]); const [slotsLoading, setSlotsLoading] = useState(false); const [selectedSlot, setSelectedSlot] = useState(null); @@ -125,6 +127,28 @@ export function BookPage() { }); const [formError, setFormError] = useState(null); + // Pre-fill form from URL params (e.g., ?clientName=Jane&clientEmail=jane@example.com) + const [searchParams] = useSearchParams(); + useEffect(() => { + const clientName = searchParams.get("clientName"); + const clientEmail = searchParams.get("clientEmail"); + const clientPhone = searchParams.get("clientPhone"); + const petName = searchParams.get("petName"); + const petSpecies = searchParams.get("petSpecies"); + const petBreed = searchParams.get("petBreed"); + if (clientName || clientEmail || clientPhone || petName || petSpecies || petBreed) { + setForm((f) => ({ + ...f, + ...(clientName && { clientName }), + ...(clientEmail && { clientEmail }), + ...(clientPhone && { clientPhone }), + ...(petName && { petName }), + ...(petSpecies && { petSpecies }), + ...(petBreed && { petBreed }), + })); + } + }, [searchParams]); + // Step 4 — result const [submitting, setSubmitting] = useState(false); const [result, setResult] = useState(null); @@ -328,8 +352,21 @@ export function BookPage() { value={date} min={todayIso()} style={{ ...input, width: "auto" }} - onChange={(e) => setDate(e.target.value)} + onChange={(e) => { + const val = e.target.value; + // HTML5 date input enforces yyyy-MM-dd; empty value means invalid format + if (!val) { + setDateError("Please enter a valid date (YYYY-MM-DD)."); + setDate(""); + } else { + setDateError(null); + setDate(val); + } + }} /> + {dateError && ( +

{dateError}

+ )}
diff --git a/apps/web/src/portal/sections/ReportCards.tsx b/apps/web/src/portal/sections/ReportCards.tsx index f1136a3..a8d471b 100644 --- a/apps/web/src/portal/sections/ReportCards.tsx +++ b/apps/web/src/portal/sections/ReportCards.tsx @@ -241,8 +241,17 @@ function ReportCardDetail({ card, onBack }: { card: Appointment; onBack: () => v

Book your next visit

Schedule your next grooming appointment

-