diff --git a/src/components/admin/AdminCard.tsx b/src/components/admin/AdminCard.tsx index b1fd108..8694f09 100644 --- a/src/components/admin/AdminCard.tsx +++ b/src/components/admin/AdminCard.tsx @@ -12,13 +12,14 @@ import { Input, EditableInput, } from '@chakra-ui/react'; -import { CheckIcon, CloseIcon, EditIcon } from '@chakra-ui/icons'; +import { CheckIcon, CloseIcon, DeleteIcon, EditIcon } from '@chakra-ui/icons'; import { Assignment, Location } from '@prisma/client'; import { UseTRPCMutationResult } from '@trpc/react/shared'; interface AdminCardProps { assignmentOrLocation: Assignment | Location; editMutation: UseTRPCMutationResult; + handleDelete: (id: number) => Promise; } const EditableControls = () => { @@ -40,7 +41,7 @@ const EditableControls = () => { * Component which represents a single assignment or location */ const AdminCard = (props: AdminCardProps) => { - const { assignmentOrLocation, editMutation } = props; + const { assignmentOrLocation, editMutation, handleDelete } = props; const boxColor = useColorModeValue('gray.100', 'gray.700'); const [isChecked, setIsChecked] = useState(assignmentOrLocation.active); @@ -73,6 +74,7 @@ const AdminCard = (props: AdminCardProps) => { Active? + handleDelete(assignmentOrLocation.id)} /> ); diff --git a/src/components/admin/AdminView.tsx b/src/components/admin/AdminView.tsx index de3e850..3be06ed 100644 --- a/src/components/admin/AdminView.tsx +++ b/src/components/admin/AdminView.tsx @@ -24,6 +24,8 @@ const AdminView = () => { const createLocationMutation = trpc.admin.createLocation.useMutation(); const editLocationMutation = trpc.admin.editLocation.useMutation(); const setSiteSettingsMutation = trpc.admin.setSiteSettings.useMutation(); + const deleteAssignmentMutation = trpc.admin.deleteAssignment.useMutation(); + const deleteLocationMutation = trpc.admin.deleteLocation.useMutation(); useEffect(() => { if (siteSettings) { @@ -56,6 +58,17 @@ const AdminView = () => { setLocations(prev => [...prev!, data]); }; + const handleDeleteAssignment = async (id: number) => { + await deleteAssignmentMutation.mutateAsync({ id }); + // We can also just invalidate the query, but this makes the UI feel more responsive + setAssignments(prev => prev!.filter(assignment => assignment.id !== id)); + } + + const handleDeleteLocation = async (id: number) => { + await deleteLocationMutation.mutateAsync({ id }); + setLocations(prev => prev!.filter(location => location.id !== id)); + } + // Sets the pending stage to enabled or disabled depending on the current state const handleTogglePendingStageEnabled = async () => { setIsPendingStageEnabled(prev => !prev); @@ -91,7 +104,7 @@ const AdminView = () => { {assignments.map(assignment => ( - + ))} @@ -106,7 +119,7 @@ const AdminView = () => { {locations.map(location => ( - + ))} diff --git a/src/server/trpc/router/admin.ts b/src/server/trpc/router/admin.ts index 09225aa..478d38b 100644 --- a/src/server/trpc/router/admin.ts +++ b/src/server/trpc/router/admin.ts @@ -68,6 +68,34 @@ export const adminRouter = router({ }); }), + deleteLocation: protectedStaffProcedure + .input( + z.object({ + id: z.number(), + }), + ) + .mutation(async ({ input, ctx }) => { + return ctx.prisma.location.delete({ + where: { + id: input.id, + }, + }); + }), + + deleteAssignment: protectedStaffProcedure + .input( + z.object({ + id: z.number(), + }), + ) + .mutation(async ({ input, ctx }) => { + return ctx.prisma.assignment.delete({ + where: { + id: input.id, + }, + }); + }), + setSiteSettings: protectedStaffProcedure .input( z.object({