Skip to content
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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

MeshanKhosla
Copy link
Collaborator

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:
image

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.

@MeshanKhosla MeshanKhosla added the do not merge For PRs that should not be merged label Nov 4, 2022
@@ -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';
Copy link
Collaborator Author

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>;
Copy link
Collaborator Author

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)} />
Copy link
Collaborator Author

@MeshanKhosla MeshanKhosla Nov 4, 2022

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();
Copy link
Collaborator Author

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));
}

Copy link
Collaborator Author

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} />
))}
Copy link
Collaborator Author

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({
});
}),

Copy link
Collaborator Author

@MeshanKhosla MeshanKhosla Nov 4, 2022

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
Copy link
Collaborator Author

@MeshanKhosla MeshanKhosla Nov 4, 2022

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(),
}),
)
Copy link
Collaborator Author

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,
},
});
Copy link
Collaborator Author

@MeshanKhosla MeshanKhosla Nov 4, 2022

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.

},
});
}),

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same thing for deleteAssignment

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
do not merge For PRs that should not be merged
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant