CitizenReportForm Component
Overview
The CitizenReportForm allows users to submit traffic reports with photos, descriptions, and location data, enabling citizen-powered traffic intelligence.
Features
- Photo Upload: Camera or file upload with preview
- Location Detection: Auto-detect GPS location or manual pin
- Category Selection: Accident, congestion, hazard, etc.
- Text Description: Rich text editor for details
- Validation: Client-side validation before submission
- Real-time Feedback: Submission status and confirmation
Props
interface CitizenReportFormProps {
onSubmit?: (report: CitizenReport) => void;
defaultLocation?: [number, number];
enableCamera?: boolean;
maxPhotos?: number;
}
Usage
Basic Usage
import CitizenReportForm from '@/components/CitizenReportForm';
export default function ReportPage() {
const handleSubmit = (report) => {
console.log('Report submitted:', report);
};
return (
<CitizenReportForm
onSubmit={handleSubmit}
enableCamera={true}
maxPhotos={3}
/>
);
}
With Location
<CitizenReportForm
defaultLocation={[10.7769, 106.7009]}
onSubmit={handleSubmit}
/>
Component Structure
const CitizenReportForm: React.FC<CitizenReportFormProps> = ({
onSubmit,
defaultLocation,
enableCamera = true,
maxPhotos = 3
}) => {
const [formData, setFormData] = useState({
category: '',
description: '',
location: defaultLocation || null,
photos: []
});
const handlePhotoUpload = (files: File[]) => {
// Upload logic
};
const handleLocationSelect = (coords: [number, number]) => {
setFormData(prev => ({ ...prev, location: coords }));
};
const handleSubmit = async () => {
const result = await submitReport(formData);
onSubmit?.(result);
};
return (
<form onSubmit={handleSubmit}>
<CategorySelect value={formData.category} onChange={...} />
<LocationPicker value={formData.location} onChange={handleLocationSelect} />
<PhotoUpload max={maxPhotos} onChange={handlePhotoUpload} />
<TextArea value={formData.description} onChange={...} />
<Button type="submit">Submit Report</Button>
</form>
);
};
Form Fields
Category Selection
<Select
label="Report Type"
options={[
{ value: 'accident', label: 'Accident' },
{ value: 'congestion', label: 'Traffic Jam' },
{ value: 'hazard', label: 'Road Hazard' },
{ value: 'construction', label: 'Construction' },
{ value: 'other', label: 'Other' }
]}
/>
Photo Upload
<PhotoUpload
max={3}
accept="image/*"
onUpload={handlePhotoUpload}
enableCamera={true}
/>