mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-23 17:31:14 -05:00
Implement Park Form and Edit/Add Functionality
This commit is contained in:
@@ -15,7 +15,8 @@ import {
|
||||
ChevronDown,
|
||||
Sliders,
|
||||
X,
|
||||
FerrisWheel
|
||||
FerrisWheel,
|
||||
Plus
|
||||
} from 'lucide-react';
|
||||
import { Park } from '@/types/database';
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
@@ -26,6 +27,10 @@ import { ParkListView } from '@/components/parks/ParkListView';
|
||||
import { ParkSearch } from '@/components/parks/ParkSearch';
|
||||
import { ParkSortOptions } from '@/components/parks/ParkSortOptions';
|
||||
import { useToast } from '@/hooks/use-toast';
|
||||
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/dialog';
|
||||
import { ParkForm } from '@/components/admin/ParkForm';
|
||||
import { useAuth } from '@/hooks/useAuth';
|
||||
import { useUserRole } from '@/hooks/useUserRole';
|
||||
|
||||
export interface FilterState {
|
||||
search: string;
|
||||
@@ -70,8 +75,11 @@ export default function Parks() {
|
||||
const [sort, setSort] = useState<SortState>(initialSort);
|
||||
const [viewMode, setViewMode] = useState<'grid' | 'list'>('grid');
|
||||
const [showFilters, setShowFilters] = useState(false);
|
||||
const [isAddParkModalOpen, setIsAddParkModalOpen] = useState(false);
|
||||
const navigate = useNavigate();
|
||||
const { toast } = useToast();
|
||||
const { user } = useAuth();
|
||||
const { isModerator } = useUserRole();
|
||||
|
||||
useEffect(() => {
|
||||
fetchParks();
|
||||
@@ -227,6 +235,80 @@ export default function Parks() {
|
||||
navigate(`/parks/${park.slug}`);
|
||||
};
|
||||
|
||||
const handleAddParkClick = () => {
|
||||
if (!user) {
|
||||
navigate('/auth');
|
||||
return;
|
||||
}
|
||||
setIsAddParkModalOpen(true);
|
||||
};
|
||||
|
||||
const handleParkSubmit = async (parkData: any) => {
|
||||
if (!user) {
|
||||
navigate('/auth');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (isModerator()) {
|
||||
// Moderators can create parks directly
|
||||
const { error } = await supabase
|
||||
.from('parks')
|
||||
.insert({
|
||||
name: parkData.name,
|
||||
slug: parkData.slug,
|
||||
description: parkData.description || null,
|
||||
park_type: parkData.park_type,
|
||||
status: parkData.status,
|
||||
opening_date: parkData.opening_date || null,
|
||||
closing_date: parkData.closing_date || null,
|
||||
website_url: parkData.website_url || null,
|
||||
phone: parkData.phone || null,
|
||||
email: parkData.email || null,
|
||||
banner_image_url: parkData.banner_image_url || null,
|
||||
banner_image_id: parkData.banner_image_id || null,
|
||||
card_image_url: parkData.card_image_url || null,
|
||||
card_image_id: parkData.card_image_id || null
|
||||
});
|
||||
|
||||
if (error) throw error;
|
||||
|
||||
toast({
|
||||
title: "Park Created",
|
||||
description: "The park has been created successfully.",
|
||||
});
|
||||
|
||||
setIsAddParkModalOpen(false);
|
||||
fetchParks();
|
||||
} else {
|
||||
// Regular users submit for moderation
|
||||
const { error } = await supabase
|
||||
.from('content_submissions')
|
||||
.insert({
|
||||
user_id: user.id,
|
||||
submission_type: 'park',
|
||||
status: 'pending',
|
||||
content: parkData
|
||||
});
|
||||
|
||||
if (error) throw error;
|
||||
|
||||
toast({
|
||||
title: "Submission Sent",
|
||||
description: "Your park submission has been sent for moderation review.",
|
||||
});
|
||||
|
||||
setIsAddParkModalOpen(false);
|
||||
}
|
||||
} catch (error: any) {
|
||||
toast({
|
||||
title: "Submission Failed",
|
||||
description: error.message || "Failed to submit park.",
|
||||
variant: "destructive"
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="min-h-screen bg-background">
|
||||
@@ -278,16 +360,26 @@ export default function Parks() {
|
||||
</Badge>
|
||||
</div>
|
||||
|
||||
{activeFilterCount > 0 && (
|
||||
<div className="flex items-center gap-2">
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={clearAllFilters}
|
||||
className="text-destructive hover:text-destructive"
|
||||
onClick={handleAddParkClick}
|
||||
className="gap-2"
|
||||
>
|
||||
<X className="w-4 h-4 mr-2" />
|
||||
Clear all filters
|
||||
<Plus className="w-4 h-4" />
|
||||
Add Park
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{activeFilterCount > 0 && (
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={clearAllFilters}
|
||||
className="text-destructive hover:text-destructive"
|
||||
>
|
||||
<X className="w-4 h-4 mr-2" />
|
||||
Clear all filters
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -374,6 +466,23 @@ export default function Parks() {
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Add Park Modal */}
|
||||
<Dialog open={isAddParkModalOpen} onOpenChange={setIsAddParkModalOpen}>
|
||||
<DialogContent className="max-w-4xl max-h-[90vh] overflow-y-auto">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Add New Park</DialogTitle>
|
||||
<DialogDescription>
|
||||
Add a new park to the database. {isModerator() ? 'The park will be added immediately.' : 'Your submission will be reviewed before being published.'}
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<ParkForm
|
||||
onSubmit={handleParkSubmit}
|
||||
onCancel={() => setIsAddParkModalOpen(false)}
|
||||
isEditing={false}
|
||||
/>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user