feat: Implement add ride modal and moderation

This commit is contained in:
gpt-engineer-app[bot]
2025-09-29 20:09:09 +00:00
parent ff152970fd
commit c504f25a64

View File

@@ -8,13 +8,15 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { Separator } from '@/components/ui/separator';
import { MapPin, Star, Clock, Phone, Globe, Calendar, ArrowLeft, Users, Zap, Camera, Castle, FerrisWheel, Waves, Tent, Plus } from 'lucide-react';
import { useAuth } from '@/hooks/useAuth';
import { useUserRole } from '@/hooks/useUserRole';
import { ReviewsSection } from '@/components/reviews/ReviewsSection';
import { RideCard } from '@/components/rides/RideCard';
import { Park, Ride } from '@/types/database';
import { ParkLocationMap } from '@/components/maps/ParkLocationMap';
import { EntityPhotoGallery } from '@/components/upload/EntityPhotoGallery';
import { supabase } from '@/integrations/supabase/client';
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { RideForm } from '@/components/admin/RideForm';
import { toast } from '@/hooks/use-toast';
export default function ParkDetail() {
const {
slug
@@ -23,10 +25,10 @@ export default function ParkDetail() {
}>();
const navigate = useNavigate();
const { user } = useAuth();
const { isModerator, isAdmin } = useUserRole();
const [park, setPark] = useState<Park | null>(null);
const [rides, setRides] = useState<Ride[]>([]);
const [loading, setLoading] = useState(true);
const [isAddRideModalOpen, setIsAddRideModalOpen] = useState(false);
useEffect(() => {
if (slug) {
fetchParkData();
@@ -87,6 +89,48 @@ export default function ParkDetail() {
const formatParkType = (type: string) => {
return type.split('_').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');
};
const handleAddRideClick = () => {
if (!user) {
navigate('/auth');
return;
}
setIsAddRideModalOpen(true);
};
const handleRideSubmit = async (rideData: any) => {
if (!user) return;
try {
const { error } = await supabase
.from('content_submissions')
.insert({
user_id: user.id,
submission_type: 'ride',
status: 'pending',
content: {
...rideData,
park_id: park?.id,
park_slug: park?.slug
}
});
if (error) throw error;
toast({
title: "Ride Submitted",
description: "Your ride submission has been sent for moderation review.",
});
setIsAddRideModalOpen(false);
} catch (error: any) {
toast({
title: "Submission Failed",
description: error.message || "Failed to submit ride for review.",
variant: "destructive"
});
}
};
if (loading) {
return <div className="min-h-screen bg-background">
<Header />
@@ -416,12 +460,10 @@ export default function ParkDetail() {
{/* Header with Add Ride button */}
<div className="flex items-center justify-between mb-6">
<h2 className="text-2xl font-bold">Rides at {park.name}</h2>
{user && (isModerator() || isAdmin()) && (
<Button onClick={() => navigate(`/parks/${park.slug}/rides/new`)}>
<Plus className="w-4 h-4 mr-2" />
Add Ride
</Button>
)}
<Button onClick={handleAddRideClick}>
<Plus className="w-4 h-4 mr-2" />
Add Ride
</Button>
</div>
{/* Conditional rendering */}
@@ -460,6 +502,22 @@ export default function ParkDetail() {
/>
</TabsContent>
</Tabs>
{/* Add Ride Modal */}
<Dialog open={isAddRideModalOpen} onOpenChange={setIsAddRideModalOpen}>
<DialogContent className="max-w-5xl max-h-[90vh] overflow-y-auto">
<DialogHeader>
<DialogTitle>Add New Ride to {park.name}</DialogTitle>
<DialogDescription>
Submit a new ride for moderation. All submissions are reviewed before being published.
</DialogDescription>
</DialogHeader>
<RideForm
onSubmit={handleRideSubmit}
onCancel={() => setIsAddRideModalOpen(false)}
/>
</DialogContent>
</Dialog>
</main>
</div>;
}