Forms and Form Components
Overview
The application includes several form components for creating and editing entities like conferences, events, speakers, and quests. All forms follow consistent patterns for validation, error handling, and user feedback.
Form Components
ConferenceForm (src/components/ConferenceForm.tsx)
Form for creating and editing conferences.
Fields:
- Basic info: name, slug, tagline, description
- Dates: start date, end date, timezone
- Location: city, country, venue name, address, coordinates
- Virtual: is virtual, platform, URL
- Organizer: name, logo, website, email, phone
- Social: Twitter, LinkedIn, Instagram, Facebook, YouTube, Telegram, Discord
- Registration: registration URL, ticket URL, pricing
- Settings: status, featured, public, requires approval
- Theme: theme color, secondary color
- SEO: meta title, description, keywords, OG image
Features:
- Image upload for logos and banners
- Date picker for dates
- Coordinate input for location
- Rich text editor for description
- Validation for required fields
EventForm (src/components/EventForm.tsx)
Form for creating and editing events.
Fields:
- Basic: title, slug, subtitle, description
- Timing: date, start time, end time, timezone, time description
- Location: location name, address, coordinates, city
- Media: image, stream URL, recording URL
- Organizer: organizer name, logo
- Links: calendar link, registration URL, ticket URL, event URL
- Settings: status, format, capacity, featured, paid, category
- Speakers: speaker selection (multi-select)
- Tags: tag selection
Features:
- Image upload
- Speaker multi-select dropdown
- Date and time pickers
- Coordinate input
- Validation
SpeakerForm (src/components/SpeakerForm.tsx)
Form for creating and editing speakers.
Fields:
- Basic: first name, last name, email, phone, bio, title, organization
- Media: photo URL
- Links: website, LinkedIn, Twitter, GitHub, Instagram, Facebook, YouTube
- Location: location, country, city
- Details: languages, expertise, topics, experience, education, certifications
- Availability: availability, travel willing, virtual willing, fee range
- Settings: verified, active, featured
Features:
- Image upload for photo
- Multi-select for languages, expertise, topics
- Rich text editor for bio
- Validation
PushNotificationForm (src/components/PushNotificationForm.tsx)
Form for sending push notifications.
Fields:
- Title
- Body/Message
- Target: all users or specific users
- User IDs (if specific)
- Topic (if using topics)
- Image URL (optional)
- Link (optional)
Features:
- User selection
- Preview functionality
- Validation
Quest Forms
Quest forms are handled through the quest detail components:
- Quest Description: Rich text editor
- Quest Tasks: Dynamic task list with various task types
- Quest Reward: Reward configuration
- Quest Sponsor: Sponsor information
Form Patterns
Controlled Components
All forms use controlled components with React state:
const [formData, setFormData] = useState({
title: "",
description: "",
// ... other fields
});
const handleChange = (field: string, value: any) => {
setFormData(prev => ({
...prev,
[field]: value
}));
};Form Validation
Forms use client-side validation:
const validate = () => {
const errors: Record<string, string> = {};
if (!formData.title) {
errors.title = "Title is required";
}
if (!formData.date) {
errors.date = "Date is required";
}
return errors;
};Error Handling
Forms display errors and show toast notifications:
try {
await apiClient.createEvent(formData);
toast.success("Event created successfully!");
onSuccess?.();
} catch (error) {
toast.error("Failed to create event. Please try again.");
console.error(error);
}Loading States
Forms show loading states during submission:
const [loading, setLoading] = useState(false);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setLoading(true);
try {
// ... submit logic
} finally {
setLoading(false);
}
};Image Upload Component
ImageUpload (src/components/ImageUpload.tsx)
Reusable component for image uploads.
Features:
- Drag and drop support
- File selection via button
- Image preview
- Upload progress
- Error handling
- Image URL display
Usage:
<ImageUpload
value={imageUrl}
onChange={setImageUrl}
onUpload={handleImageUpload}
label="Upload Image"
/>Props:
value: Current image URLonChange: Callback when URL changesonUpload: Upload handler functionlabel: Label textaccept: Accepted file typesmaxSize: Maximum file size
Video Upload Component
VideoUpload (src/components/VideoUpload.tsx)
Component for video uploads.
Features:
- File selection
- Upload progress
- Video preview
- Error handling
Usage: Similar to ImageUpload component.
Form Best Practices
1. User Feedback
- Show loading states during submission
- Display success/error messages
- Provide clear validation errors
- Use toast notifications for feedback
2. Validation
- Validate on submit
- Show inline errors
- Highlight invalid fields
- Prevent submission if invalid
3. Accessibility
- Use proper labels
- Associate errors with fields
- Support keyboard navigation
- Provide ARIA attributes
4. Performance
- Debounce search inputs
- Lazy load large forms
- Optimize image uploads
- Minimize re-renders
5. Data Handling
- Sanitize inputs
- Validate data types
- Handle edge cases
- Provide default values
Common Form Patterns
Multi-Step Forms
For complex forms, use a stepper component:
<Stepper>
<Step title="Basic Info" />
<Step title="Details" />
<Step title="Review" />
</Stepper>Dynamic Fields
For forms with dynamic fields (like quest tasks):
const [tasks, setTasks] = useState<Task[]>([]);
const addTask = () => {
setTasks([...tasks, { id: uuid(), ...defaultTask }]);
};
const removeTask = (id: string) => {
setTasks(tasks.filter(t => t.id !== id));
};Conditional Fields
Show/hide fields based on other field values:
{formData.is_virtual && (
<div>
<Label>Virtual Platform</Label>
<Input {...register("virtual_platform")} />
</div>
)}Form Libraries
The application doesn't use a form library like React Hook Form or Formik, but implements custom form handling. Consider using a form library for:
- Complex validation
- Better performance
- Less boilerplate
- Better TypeScript support
Potential libraries:
- React Hook Form
- Formik
- React Final Form