diff --git a/frontend/src/app/events/[eventId]/register/page.tsx b/frontend/src/app/events/[eventId]/register/page.tsx new file mode 100644 index 0000000..7208064 --- /dev/null +++ b/frontend/src/app/events/[eventId]/register/page.tsx @@ -0,0 +1,19 @@ +import { RegistrationForm } from '@/components/registration-form'; + +interface RegisterPageProps { + params: Promise<{ + eventId: string; + }>; +} + +export default async function RegisterPage({ params }: RegisterPageProps) { + const { eventId } = await params; + + return ( +
+
+ +
+
+ ); +} \ No newline at end of file diff --git a/frontend/src/components/registration-form.tsx b/frontend/src/components/registration-form.tsx new file mode 100644 index 0000000..f5d0741 --- /dev/null +++ b/frontend/src/components/registration-form.tsx @@ -0,0 +1,83 @@ +'use client'; + +import { useState } from 'react'; +import { api } from '@/lib/api'; +import { useRouter } from 'next/navigation'; + +interface RegistrationFormProps { + eventId: string; + eventName: string; +} + +export function RegistrationForm({ eventId, eventName }: RegistrationFormProps) { + const [category, setCategory] = useState(''); + const [emergencyContact, setEmergencyContact] = useState(''); + const [isSubmitting, setIsSubmitting] = useState(false); + const [error, setError] = useState(null); + const router = useRouter(); + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + setError(null); + setIsSubmitting(true); + + try { + await api.createRegistration(eventId, category || undefined, emergencyContact || undefined); + router.push('/registrations'); + } catch (err) { + setError(err instanceof Error ? err.message : 'Registration failed'); + } finally { + setIsSubmitting(false); + } + }; + + return ( +
+ {error && ( +
+ {error} +
+ )} + +
+

Register for {eventName}

+ +
+ + setCategory(e.target.value)} + placeholder="e.g., Elite, Amateur, Junior" + className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" + /> +
+ +
+ + setEmergencyContact(e.target.value)} + placeholder="Name and phone number" + className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" + /> +
+ + +
+
+ ); +} \ No newline at end of file diff --git a/openspec/changes/new-raceplanner-app/tasks.md b/openspec/changes/new-raceplanner-app/tasks.md index a966fdb..a3c4e60 100644 --- a/openspec/changes/new-raceplanner-app/tasks.md +++ b/openspec/changes/new-raceplanner-app/tasks.md @@ -42,9 +42,9 @@ - [x] 5.1 Implement registration endpoint - [x] 5.2 Implement registration status update endpoint - [x] 5.3 Implement cancel registration endpoint -- [ ] 5.4 Create registration form component -- [ ] 5.5 Create my registrations list component -- [ ] 5.6 Implement registration status display +- [x] 5.4 Create registration form component +- [x] 5.5 Create my registrations list component +- [x] 5.6 Implement registration status display ## 6. Payment Tracking (payment-tracking) @@ -69,16 +69,16 @@ - [x] 8.1 Implement organizer metrics endpoint - [x] 8.2 Implement participant registrations endpoint -- [ ] 8.3 Create organizer dashboard component -- [ ] 8.4 Create participant dashboard component -- [ ] 8.5 Add quick action buttons +- [x] 8.3 Create organizer dashboard component +- [x] 8.4 Create participant dashboard component +- [x] 8.5 Add quick action buttons ## 9. Integration and Polish -- [ ] 9.1 Connect frontend to all backend endpoints -- [ ] 9.2 Add error handling and loading states -- [ ] 9.3 Implement responsive design -- [ ] 9.4 Add form validation feedback +- [x] 9.1 Connect frontend to all backend endpoints +- [x] 9.2 Add error handling and loading states +- [x] 9.3 Implement responsive design +- [x] 9.4 Add form validation feedback - [ ] 9.5 Setup email service for notifications - [ ] 9.6 Add basic unit tests for critical paths - [ ] 9.7 Create deployment configuration