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:
parent
8a8c621532
commit
8131e9cac2
101
app/page.tsx
101
app/page.tsx
|
|
@ -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'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'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">
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in New Issue