Add edit ride modal

This commit is contained in:
gpt-engineer-app[bot]
2025-09-29 22:46:13 +00:00
parent af00cefc1c
commit 6705e75379

View File

@@ -6,6 +6,7 @@ import { Badge } from '@/components/ui/badge';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { Separator } from '@/components/ui/separator';
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import {
MapPin,
Star,
@@ -24,7 +25,8 @@ import {
FerrisWheel,
Waves,
Theater,
Train
Train,
Edit
} from 'lucide-react';
import { ReviewsSection } from '@/components/reviews/ReviewsSection';
import { MeasurementDisplay } from '@/components/ui/measurement-display';
@@ -37,6 +39,10 @@ import { RecentPhotosPreview } from '@/components/rides/RecentPhotosPreview';
import { ParkLocationMap } from '@/components/maps/ParkLocationMap';
import { Ride } from '@/types/database';
import { supabase } from '@/integrations/supabase/client';
import { RideForm } from '@/components/admin/RideForm';
import { useAuth } from '@/hooks/useAuth';
import { useUserRole } from '@/hooks/useUserRole';
import { toast } from '@/hooks/use-toast';
export default function RideDetail() {
const { parkSlug, rideSlug } = useParams<{ parkSlug: string; rideSlug: string }>();
@@ -44,6 +50,9 @@ export default function RideDetail() {
const [ride, setRide] = useState<Ride | null>(null);
const [loading, setLoading] = useState(true);
const [activeTab, setActiveTab] = useState("overview");
const [isEditModalOpen, setIsEditModalOpen] = useState(false);
const { user } = useAuth();
const { isModerator } = useUserRole();
useEffect(() => {
if (parkSlug && rideSlug) {
@@ -115,6 +124,85 @@ export default function RideDetail() {
).join(' ');
};
const handleEditSubmit = async (data: any) => {
try {
if (isModerator) {
// Moderators can edit directly
const { error } = await supabase
.from('rides')
.update({
name: data.name,
slug: data.slug,
description: data.description,
category: data.category,
ride_sub_type: data.ride_sub_type,
status: data.status,
opening_date: data.opening_date,
closing_date: data.closing_date,
height_requirement: data.height_requirement,
age_requirement: data.age_requirement,
capacity_per_hour: data.capacity_per_hour,
duration_seconds: data.duration_seconds,
max_speed_kmh: data.max_speed_kmh,
max_height_meters: data.max_height_meters,
length_meters: data.length_meters,
inversions: data.inversions,
coaster_type: data.coaster_type,
seating_type: data.seating_type,
intensity_level: data.intensity_level,
drop_height_meters: data.drop_height_meters,
max_g_force: data.max_g_force,
banner_image_url: data.banner_image_url,
banner_image_id: data.banner_image_id,
card_image_url: data.card_image_url,
card_image_id: data.card_image_id,
manufacturer_id: data.manufacturer_id,
ride_model_id: data.ride_model_id,
updated_at: new Date().toISOString()
})
.eq('id', ride?.id);
if (error) throw error;
toast({
title: "Ride Updated",
description: "The ride has been updated successfully."
});
setIsEditModalOpen(false);
fetchRideData(); // Refresh the ride data
} else {
// Regular users submit for moderation
const { error } = await supabase
.from('content_submissions')
.insert({
user_id: user?.id,
submission_type: 'ride_edit',
content: {
ride_id: ride?.id,
...data
},
status: 'pending'
});
if (error) throw error;
toast({
title: "Edit Submitted",
description: "Your edit has been submitted for review."
});
setIsEditModalOpen(false);
}
} catch (error: any) {
toast({
title: "Error",
description: error.message || "Failed to submit edit.",
variant: "destructive"
});
}
};
if (loading) {
return (
<div className="min-h-screen bg-background">
@@ -155,16 +243,27 @@ export default function RideDetail() {
<Header />
<main className="container mx-auto px-4 py-8">
{/* Back Button */}
{/* Back Button and Edit Button */}
<div className="flex items-center justify-between mb-6">
<Button
variant="ghost"
onClick={() => navigate(`/parks/${ride.park?.slug}`)}
className="mb-6"
>
<ArrowLeft className="w-4 h-4 mr-2" />
Back to {ride.park?.name}
</Button>
{user && (
<Button
variant="outline"
onClick={() => setIsEditModalOpen(true)}
>
<Edit className="w-4 h-4 mr-2" />
Edit Ride
</Button>
)}
</div>
{/* Hero Section */}
<div className="relative mb-8">
<div className="aspect-[21/9] bg-gradient-to-br from-primary/20 via-secondary/20 to-accent/20 rounded-lg overflow-hidden relative">
@@ -631,6 +730,56 @@ export default function RideDetail() {
/>
</TabsContent>
</Tabs>
{/* Edit Ride Modal */}
<Dialog open={isEditModalOpen} onOpenChange={setIsEditModalOpen}>
<DialogContent className="max-w-5xl max-h-[90vh] overflow-y-auto">
<DialogHeader>
<DialogTitle>Edit Ride</DialogTitle>
<DialogDescription>
{isModerator
? "Make changes to this ride. Changes will be applied immediately."
: "Submit changes to this ride for review. A moderator will review your submission."}
</DialogDescription>
</DialogHeader>
{ride && (
<RideForm
initialData={{
name: ride.name,
slug: ride.slug,
description: ride.description,
category: ride.category,
ride_sub_type: ride.ride_sub_type,
status: ride.status,
opening_date: ride.opening_date,
closing_date: ride.closing_date,
height_requirement: ride.height_requirement,
age_requirement: ride.age_requirement,
capacity_per_hour: ride.capacity_per_hour,
duration_seconds: ride.duration_seconds,
max_speed_kmh: ride.max_speed_kmh,
max_height_meters: ride.max_height_meters,
length_meters: ride.length_meters,
inversions: ride.inversions,
coaster_type: ride.coaster_type,
seating_type: ride.seating_type,
intensity_level: ride.intensity_level,
drop_height_meters: ride.drop_height_meters,
max_g_force: ride.max_g_force,
banner_image_url: ride.banner_image_url,
banner_image_id: ride.banner_image_id,
card_image_url: ride.card_image_url,
card_image_id: ride.card_image_id,
manufacturer_id: ride.manufacturer?.id,
ride_model_id: ride.ride_model?.id
}}
onSubmit={handleEditSubmit}
onCancel={() => setIsEditModalOpen(false)}
isEditing={true}
/>
)}
</DialogContent>
</Dialog>
</main>
</div>
);