import { useState } from 'react'; import { Upload, X, Camera } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Card, CardContent } from '@/components/ui/card'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Textarea } from '@/components/ui/textarea'; import { useToast } from '@/hooks/use-toast'; import { supabase } from '@/integrations/supabase/client'; import { useAuth } from '@/hooks/useAuth'; interface PhotoSubmissionUploadProps { onSubmissionComplete?: () => void; parkId?: string; rideId?: string; } export function PhotoSubmissionUpload({ onSubmissionComplete, parkId, rideId }: PhotoSubmissionUploadProps) { const [selectedFiles, setSelectedFiles] = useState([]); const [uploading, setUploading] = useState(false); const [caption, setCaption] = useState(''); const [title, setTitle] = useState(''); const { toast } = useToast(); const { user } = useAuth(); const handleFileSelect = (event: React.ChangeEvent) => { const files = Array.from(event.target.files || []); const imageFiles = files.filter(file => file.type.startsWith('image/')); if (imageFiles.length !== files.length) { toast({ title: "Invalid Files", description: "Only image files are allowed", variant: "destructive", }); } setSelectedFiles(prev => [...prev, ...imageFiles].slice(0, 5)); // Max 5 files }; const removeFile = (index: number) => { setSelectedFiles(prev => prev.filter((_, i) => i !== index)); }; const uploadFileToCloudflare = async (file: File): Promise<{ id: string; url: string }> => { // Get upload URL from Supabase edge function const { data: uploadData, error: uploadError } = await supabase.functions.invoke('upload-image', { method: 'POST', body: JSON.stringify({ filename: file.name, contentType: file.type, }), }); if (uploadError || !uploadData?.uploadURL) { throw new Error('Failed to get upload URL'); } // Upload file directly to Cloudflare const formData = new FormData(); formData.append('file', file); const uploadResponse = await fetch(uploadData.uploadURL, { method: 'POST', body: formData, }); if (!uploadResponse.ok) { throw new Error('Failed to upload file to Cloudflare'); } const result = await uploadResponse.json(); // Get the delivery URL const { data: statusData, error: statusError } = await supabase.functions.invoke('upload-image', { method: 'GET', body: JSON.stringify({ imageId: result.result.id }), }); if (statusError || !statusData?.url) { throw new Error('Failed to get image URL'); } return { id: result.result.id, url: statusData.url, }; }; const handleSubmit = async () => { if (!user) { toast({ title: "Authentication Required", description: "Please log in to submit photos", variant: "destructive", }); return; } if (selectedFiles.length === 0) { toast({ title: "No Files Selected", description: "Please select at least one image to submit", variant: "destructive", }); return; } setUploading(true); try { // Upload files to Cloudflare Images first const photoSubmissions = await Promise.all( selectedFiles.map(async (file, index) => { const uploadResult = await uploadFileToCloudflare(file); return { filename: file.name, size: file.size, type: file.type, url: uploadResult.url, imageId: uploadResult.id, caption: index === 0 ? caption : '', // Only first image gets the caption }; }) ); // Submit to content_submissions table const { error } = await supabase .from('content_submissions') .insert({ user_id: user.id, submission_type: 'photo', content: { photos: photoSubmissions, title: title.trim() || undefined, caption: caption.trim() || undefined, park_id: parkId, ride_id: rideId, context: parkId ? 'park' : rideId ? 'ride' : 'general', }, status: 'pending', }); if (error) throw error; toast({ title: "Photos Submitted", description: "Your photos have been submitted for moderation review", }); // Reset form setSelectedFiles([]); setCaption(''); setTitle(''); onSubmissionComplete?.(); } catch (error) { console.error('Error submitting photos:', error); toast({ title: "Submission Failed", description: "Failed to submit photos. Please try again.", variant: "destructive", }); } finally { setUploading(false); } }; return (

Submit Photos

setTitle(e.target.value)} maxLength={100} />