import type { ActionFunctionArgs, LoaderFunctionArgs, MetaFunction } from "@remix-run/node"; import { json, redirect } from "@remix-run/node"; import { Form, useActionData, useLoaderData, useNavigation } from "@remix-run/react"; import { requireAuthLevel } from "~/utils/auth.server"; import DashboardLayout from "~/components/DashboardLayout"; import FormModal from "~/components/FormModal"; import Toast from "~/components/Toast"; import { PrismaClient } from "@prisma/client"; import { useState, useEffect } from "react"; const prisma = new PrismaClient(); export const meta: MetaFunction = () => [{ title: "Reclamation Locations Management - Phosphat Report" }]; export const loader = async ({ request }: LoaderFunctionArgs) => { const user = await requireAuthLevel(request, 2); const reclamationLocations = await prisma.reclamationLocation.findMany({ orderBy: { name: 'asc' }, include: { _count: { select: { reports: true } } } }); return json({ user, reclamationLocations }); }; export const action = async ({ request }: ActionFunctionArgs) => { await requireAuthLevel(request, 2); const formData = await request.formData(); const intent = formData.get("intent"); const id = formData.get("id"); const name = formData.get("name"); if (intent === "create") { if (typeof name !== "string" || name.length === 0) { return json({ errors: { name: "Name is required" } }, { status: 400 }); } try { await prisma.reclamationLocation.create({ data: { name } }); return json({ success: "Reclamation location created successfully!" }); } catch (error) { return json({ errors: { form: "Reclamation location name already exists" } }, { status: 400 }); } } if (intent === "update") { if (typeof name !== "string" || name.length === 0) { return json({ errors: { name: "Name is required" } }, { status: 400 }); } if (typeof id !== "string") { return json({ errors: { form: "Invalid reclamation location ID" } }, { status: 400 }); } try { await prisma.reclamationLocation.update({ where: { id: parseInt(id) }, data: { name } }); return json({ success: "Reclamation location updated successfully!" }); } catch (error) { return json({ errors: { form: "Reclamation location name already exists" } }, { status: 400 }); } } if (intent === "delete") { if (typeof id !== "string") { return json({ errors: { form: "Invalid reclamation location ID" } }, { status: 400 }); } try { await prisma.reclamationLocation.delete({ where: { id: parseInt(id) } }); return json({ success: "Reclamation location deleted successfully!" }); } catch (error) { return json({ errors: { form: "Cannot delete reclamation location with existing reports" } }, { status: 400 }); } } return json({ errors: { form: "Invalid action" } }, { status: 400 }); }; export default function ReclamationLocations() { const { user, reclamationLocations } = useLoaderData(); const actionData = useActionData(); const navigation = useNavigation(); const [editingLocation, setEditingLocation] = useState<{ id: number; name: string } | null>(null); const [showModal, setShowModal] = useState(false); const [toast, setToast] = useState<{ message: string; type: "success" | "error" } | null>(null); const isSubmitting = navigation.state === "submitting"; const isEditing = editingLocation !== null; // Handle success/error messages useEffect(() => { if (actionData?.success) { setToast({ message: actionData.success, type: "success" }); setShowModal(false); setEditingLocation(null); } else if (actionData?.errors?.form) { setToast({ message: actionData.errors.form, type: "error" }); } }, [actionData]); const handleEdit = (location: { id: number; name: string }) => { setEditingLocation(location); setShowModal(true); }; const handleAdd = () => { setEditingLocation(null); setShowModal(true); }; const handleCloseModal = () => { setShowModal(false); setEditingLocation(null); }; return (

Reclamation Locations Management

Manage shoreline reclamation locations

{/* Locations Table */}
{reclamationLocations.map((location) => ( ))}
Location Name Reports Count Actions
{location.name}
{/*
Location #{location.id}
*/}
{location._count.reports} reports
{reclamationLocations.length === 0 && (

No reclamation locations

Get started by creating your first reclamation location.

)}
{/* Form Modal */} {/* Toast Notifications */} {toast && ( setToast(null)} /> )}
); }