-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[DEMO] Delete assignment/location #31
base: main
Are you sure you want to change the base?
Conversation
@@ -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'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The trash icon is imported from Chakra (the component library we use)
import { Assignment, Location } from '@prisma/client'; | ||
import { UseTRPCMutationResult } from '@trpc/react/shared'; | ||
|
||
interface AdminCardProps { | ||
assignmentOrLocation: Assignment | Location; | ||
editMutation: UseTRPCMutationResult<any, any, any, any>; | ||
handleDelete: (id: number) => Promise<void>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Every component has props that are typed. Try to avoid using any
but sometimes we might need to.
@@ -73,6 +74,7 @@ const AdminCard = (props: AdminCardProps) => { | |||
Active? | |||
</Text> | |||
<Switch onChange={handleActiveChange} mt={2.5} ml={3} isChecked={isChecked} /> | |||
<DeleteIcon ml={5} mt={2} onClick={() => handleDelete(assignmentOrLocation.id)} /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Render out the DeleteIcon
and call the handleDelete
method (passed in as a prop) with the ID.
@@ -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(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initialize the mutations that we created in admin.ts
await deleteLocationMutation.mutateAsync({ id }); | ||
setLocations(prev => prev!.filter(location => location.id !== id)); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These two are essentially identical, but one is for assignments and one is for locations. The key here is that we call the mutateAsync
method on the mutation which will actually send the request to our backend.
@@ -106,7 +119,7 @@ const AdminView = () => { | |||
</Flex> | |||
</Flex> | |||
{locations.map(location => ( | |||
<AdminCard key={location.id} assignmentOrLocation={location} editMutation={editLocationMutation} /> | |||
<AdminCard key={location.id} assignmentOrLocation={location} editMutation={editLocationMutation} handleDelete={handleDeleteLocation} /> | |||
))} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pass in the approprite handler as a prop. The top is for assignments and the bottom is for locations.
@@ -68,6 +68,34 @@ export const adminRouter = router({ | |||
}); | |||
}), | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is our backend. It's split into separate files (routers) such as ticket.ts
, admin.ts
, user.ts
and we can define our "endpoints" here. We can either create a query
(GET) or a mutation
(POST). Since deleting is modifying our DB, both of our operations will be mutations. The queries are further down in this file. (like getAllAssignments
).
Ignore the weird formatting:
@@ -68,6 +68,34 @@ export const adminRouter = router({ | |||
}); | |||
}), | |||
|
|||
deleteLocation: protectedStaffProcedure |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the client we initialized this with "trpc.admin.deleteLocation.useMutation();" For queries we use useQuery
. protectedStaffProcedure
means that only staff members can invoke this. In other places, we have protectedProcedure
meaning only signed in users can invoke it.
z.object({ | ||
id: z.number(), | ||
}), | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The input to this mutation is the ID that we want to delete. z
(zod) is an input validation library so our server<->client communication is fully typesafe. Meaning it won't let us accidentally pass a string into this method.
where: { | ||
id: input.id, | ||
}, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is equivalent to writing raw SQL to delete from the database but no one wants to do that so we use the prisma
ORM which allows us to just write typescript to interact with the database.
}, | ||
}); | ||
}), | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same thing for deleteAssignment
DO NOT MERGE THIS. IT WILL RUIN THE DATABASE
This is only for demo purposes to show how someone might go about implementing a feature like this. Look at the files for comments about each change.
The intention is to have a delete icon on each location/assignment in the admin panel. When you press it, it should delete the assignment from the databases:
We can't actually have this because tickets are required to have an assignment/location associated with them, so deleting a location/assignment would break the schema. However since we don't want all of them to be visible, #26 allows for hiding assignments and locations.