Simplify payment step: group accommodation by venue, remove food option, match CCG/VotC prices

- Show all accommodation options grouped under their venue headers instead of two-step selection
- Remove duplicate "Event Registration" card header
- Remove "I would like to include food" checkbox, replace with note about room/dietary follow-up
- Update accommodation prices to match CCG/VotC (shared €275, single €665)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2026-03-20 12:09:07 -07:00
parent 8a8c621532
commit 8131e9cac2
2 changed files with 33 additions and 76 deletions

View File

@ -34,7 +34,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 [selectedVenueKey, setSelectedVenueKey] = useState(ACCOMMODATION_VENUES[0]?.key || "")
const [accommodationType, setAccommodationType] = useState(
ACCOMMODATION_VENUES[0]?.options[0]?.id || ""
@ -98,7 +98,7 @@ export default function RegisterPage() {
howHeard: formData.howHeard,
dietary: dietaryString,
crewConsent: formData.crewConsent,
wantFood,
}),
})
@ -147,13 +147,7 @@ export default function RegisterPage() {
</div>
<Card className="mb-8 border-primary/40">
<CardHeader>
<CardTitle>Event Registration</CardTitle>
<CardDescription>
{pricingSummary}
</CardDescription>
</CardHeader>
<CardContent>
<CardContent className="pt-6">
<div className="space-y-4">
{/* Ticket */}
<div className="flex items-start justify-between py-4 border-b border-border">
@ -185,51 +179,37 @@ export default function RegisterPage() {
)}
</div>
{includeAccommodation ? (
<div className="mt-3 space-y-4">
{/* Venue selection */}
<div className="mt-3">
<RadioGroup
value={selectedVenueKey}
value={accommodationType}
onValueChange={(value: string) => {
setSelectedVenueKey(value)
const venue = ACCOMMODATION_VENUES.find((v) => v.key === value)
if (venue?.options[0]) {
setAccommodationType(venue.options[0].id)
}
setAccommodationType(value)
const venue = ACCOMMODATION_VENUES.find((v) =>
v.options.some((o) => o.id === value)
)
if (venue) setSelectedVenueKey(venue.key)
}}
className="space-y-2"
className="space-y-4"
>
{ACCOMMODATION_VENUES.map((venue) => (
<div key={venue.key} className="flex items-center space-x-2">
<RadioGroupItem value={venue.key} id={`venue-${venue.key}`} />
<Label htmlFor={`venue-${venue.key}`} className="font-medium cursor-pointer text-sm">
{venue.name}
</Label>
<div key={venue.key}>
<p className="font-medium text-sm mb-1">{venue.name}</p>
<p className="text-xs text-muted-foreground mb-2">
{venue.description}
</p>
<div className="pl-4 border-l-2 border-primary/20 space-y-2">
{venue.options.map((opt) => (
<div key={opt.id} className="flex items-center space-x-2">
<RadioGroupItem value={opt.id} id={opt.id} />
<Label htmlFor={opt.id} className="font-normal cursor-pointer text-sm">
{opt.label} {opt.price.toFixed(2)} ({opt.nightlyRate}/night)
</Label>
</div>
))}
</div>
</div>
))}
</RadioGroup>
{/* Sub-options for selected venue */}
{ACCOMMODATION_VENUES.filter((v) => v.key === selectedVenueKey).map((venue) => (
<div key={venue.key} className="pl-6 border-l-2 border-primary/20">
<p className="text-xs text-muted-foreground mb-2">
{venue.description}
</p>
<RadioGroup
value={accommodationType}
onValueChange={setAccommodationType}
className="space-y-2"
>
{venue.options.map((opt) => (
<div key={opt.id} className="flex items-center space-x-2">
<RadioGroupItem value={opt.id} id={opt.id} />
<Label htmlFor={opt.id} className="font-normal cursor-pointer text-sm">
{opt.label} {opt.price.toFixed(2)} ({opt.nightlyRate}/night)
</Label>
</div>
))}
</RadioGroup>
</div>
))}
</div>
) : (
<p className="text-sm text-muted-foreground mt-1">
@ -240,32 +220,9 @@ export default function RegisterPage() {
</div>
</div>
{includeAccommodation && (
<p className="text-xs text-muted-foreground bg-muted/50 rounded-lg p-3">
We&apos;ll follow up closer to the event to confirm room assignments and accommodation details.
</p>
)}
{/* Food */}
<div className="py-4 border-b border-border">
<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
</Label>
<p className="text-sm text-muted-foreground mt-1">
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>
<p className="text-xs text-muted-foreground bg-muted/50 rounded-lg p-3">
Additional Note: We&apos;ll follow up closer to the event to confirm room assignments and dietary preferences.
</p>
{/* Processing fee */}
<div className="flex items-start justify-between py-3">

View File

@ -74,8 +74,8 @@ export const ACCOMMODATION_VENUES: AccommodationVenue[] = [
{
id: "va-shared",
label: "Bed in shared room",
price: 280,
nightlyRate: 40,
price: 275,
nightlyRate: 39,
venue: "Venue A",
venueKey: "venue-a",
},
@ -97,8 +97,8 @@ export const ACCOMMODATION_VENUES: AccommodationVenue[] = [
{
id: "vb-single",
label: "Single room",
price: 560,
nightlyRate: 80,
price: 665,
nightlyRate: 95,
venue: "Venue B",
venueKey: "venue-b",
},