mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-25 06:31:17 -05:00
feat: Implement add ride modal and moderation
This commit is contained in:
@@ -8,13 +8,15 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
|||||||
import { Separator } from '@/components/ui/separator';
|
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 { MapPin, Star, Clock, Phone, Globe, Calendar, ArrowLeft, Users, Zap, Camera, Castle, FerrisWheel, Waves, Tent, Plus } from 'lucide-react';
|
||||||
import { useAuth } from '@/hooks/useAuth';
|
import { useAuth } from '@/hooks/useAuth';
|
||||||
import { useUserRole } from '@/hooks/useUserRole';
|
|
||||||
import { ReviewsSection } from '@/components/reviews/ReviewsSection';
|
import { ReviewsSection } from '@/components/reviews/ReviewsSection';
|
||||||
import { RideCard } from '@/components/rides/RideCard';
|
import { RideCard } from '@/components/rides/RideCard';
|
||||||
import { Park, Ride } from '@/types/database';
|
import { Park, Ride } from '@/types/database';
|
||||||
import { ParkLocationMap } from '@/components/maps/ParkLocationMap';
|
import { ParkLocationMap } from '@/components/maps/ParkLocationMap';
|
||||||
import { EntityPhotoGallery } from '@/components/upload/EntityPhotoGallery';
|
import { EntityPhotoGallery } from '@/components/upload/EntityPhotoGallery';
|
||||||
import { supabase } from '@/integrations/supabase/client';
|
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() {
|
export default function ParkDetail() {
|
||||||
const {
|
const {
|
||||||
slug
|
slug
|
||||||
@@ -23,10 +25,10 @@ export default function ParkDetail() {
|
|||||||
}>();
|
}>();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
const { isModerator, isAdmin } = useUserRole();
|
|
||||||
const [park, setPark] = useState<Park | null>(null);
|
const [park, setPark] = useState<Park | null>(null);
|
||||||
const [rides, setRides] = useState<Ride[]>([]);
|
const [rides, setRides] = useState<Ride[]>([]);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
|
const [isAddRideModalOpen, setIsAddRideModalOpen] = useState(false);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (slug) {
|
if (slug) {
|
||||||
fetchParkData();
|
fetchParkData();
|
||||||
@@ -87,6 +89,48 @@ export default function ParkDetail() {
|
|||||||
const formatParkType = (type: string) => {
|
const formatParkType = (type: string) => {
|
||||||
return type.split('_').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');
|
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) {
|
if (loading) {
|
||||||
return <div className="min-h-screen bg-background">
|
return <div className="min-h-screen bg-background">
|
||||||
<Header />
|
<Header />
|
||||||
@@ -416,12 +460,10 @@ export default function ParkDetail() {
|
|||||||
{/* Header with Add Ride button */}
|
{/* Header with Add Ride button */}
|
||||||
<div className="flex items-center justify-between mb-6">
|
<div className="flex items-center justify-between mb-6">
|
||||||
<h2 className="text-2xl font-bold">Rides at {park.name}</h2>
|
<h2 className="text-2xl font-bold">Rides at {park.name}</h2>
|
||||||
{user && (isModerator() || isAdmin()) && (
|
<Button onClick={handleAddRideClick}>
|
||||||
<Button onClick={() => navigate(`/parks/${park.slug}/rides/new`)}>
|
<Plus className="w-4 h-4 mr-2" />
|
||||||
<Plus className="w-4 h-4 mr-2" />
|
Add Ride
|
||||||
Add Ride
|
</Button>
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Conditional rendering */}
|
{/* Conditional rendering */}
|
||||||
@@ -460,6 +502,22 @@ export default function ParkDetail() {
|
|||||||
/>
|
/>
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
</Tabs>
|
</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>
|
</main>
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user