[resumes][feat] add deletion for resumes (#539)

Co-authored-by: Terence Ho <>
pull/540/head
Terence 2 years ago committed by GitHub
parent 710e67063b
commit 237b08442e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -14,8 +14,9 @@ import {
MapPinIcon, MapPinIcon,
PencilSquareIcon, PencilSquareIcon,
StarIcon, StarIcon,
TrashIcon,
} from '@heroicons/react/20/solid'; } from '@heroicons/react/20/solid';
import { Button, Spinner } from '@tih/ui'; import { Button, Dialog, Spinner } from '@tih/ui';
import { useGoogleAnalytics } from '~/components/global/GoogleAnalytics'; import { useGoogleAnalytics } from '~/components/global/GoogleAnalytics';
import ResumeCommentsForm from '~/components/resumes/comments/ResumeCommentsForm'; import ResumeCommentsForm from '~/components/resumes/comments/ResumeCommentsForm';
@ -83,6 +84,16 @@ export default function ResumeReviewPage() {
}); });
}, },
}); });
const deleteResumeMutation = trpc.useMutation('resumes.resume.user.delete', {
onSuccess() {
invalidateResumeQueries();
gaEvent({
action: 'resumes.delete_button_click',
category: 'engagement',
label: 'Delete Resume',
});
},
});
const invalidateResumeQueries = () => { const invalidateResumeQueries = () => {
utils.invalidateQueries(['resumes.resume.findOne']); utils.invalidateQueries(['resumes.resume.findOne']);
@ -98,6 +109,7 @@ export default function ResumeReviewPage() {
const isResumeResolved = detailsQuery.data?.isResolved; const isResumeResolved = detailsQuery.data?.isResolved;
const [isEditMode, setIsEditMode] = useState(false); const [isEditMode, setIsEditMode] = useState(false);
const [isDeleteMode, setIsDeleteMode] = useState(false);
const [showCommentsForm, setShowCommentsForm] = useState(false); const [showCommentsForm, setShowCommentsForm] = useState(false);
const onStarButtonClick = () => { const onStarButtonClick = () => {
@ -163,6 +175,43 @@ export default function ResumeReviewPage() {
setIsEditMode(true); setIsEditMode(true);
}; };
const onDeleteButtonClick = () => {
setIsDeleteMode(true);
};
const onDeleteDialog = async () => {
return deleteResumeMutation.mutate(
{ id: resumeId as string },
{
onSuccess() {
// TODO: Delete from file storage
// redirect to browse with default settings
router.push({
pathname: '/resumes',
query: {
currentPage: JSON.stringify(1),
isFiltersOpen: JSON.stringify({
experience: false,
location: false,
role: false,
}),
searchValue: JSON.stringify(''),
shortcutSelected: JSON.stringify('all'),
sortOrder: JSON.stringify('latest'),
tabsValue: JSON.stringify(BROWSE_TABS_VALUES.ALL),
userFilters: JSON.stringify(INITIAL_FILTER_STATE),
},
});
},
},
);
};
const onCancelDialog = () => {
setIsDeleteMode(false);
};
const onResolveButtonClick = () => { const onResolveButtonClick = () => {
resolveMutation.mutate({ resolveMutation.mutate({
id: resumeId as string, id: resumeId as string,
@ -226,7 +275,7 @@ export default function ResumeReviewPage() {
<> <>
{/* Has to strict quality check (===), don't change it to == */} {/* Has to strict quality check (===), don't change it to == */}
{(detailsQuery.isError || detailsQuery.data === null) && ErrorPage} {(detailsQuery.isError || detailsQuery.data === null) && ErrorPage}
{detailsQuery.isLoading && ( {(detailsQuery.isLoading || deleteResumeMutation.isLoading) && (
<div className="w-full pt-4"> <div className="w-full pt-4">
<Spinner display="block" size="lg" /> <Spinner display="block" size="lg" />
</div> </div>
@ -254,6 +303,16 @@ export default function ResumeReviewPage() {
onClick={onEditButtonClick} onClick={onEditButtonClick}
/> />
</div> </div>
<div>
<Button
addonPosition="start"
className="hover:text-red-500"
icon={TrashIcon}
label="Delete"
variant="tertiary"
onClick={onDeleteButtonClick}
/>
</div>
<div> <div>
<button <button
className="isolate inline-flex items-center space-x-4 whitespace-nowrap rounded-md border border-slate-300 bg-white px-4 py-2 text-sm font-medium text-slate-700 hover:bg-slate-50 focus:ring-slate-600 disabled:hover:bg-white" className="isolate inline-flex items-center space-x-4 whitespace-nowrap rounded-md border border-slate-300 bg-white px-4 py-2 text-sm font-medium text-slate-700 hover:bg-slate-50 focus:ring-slate-600 disabled:hover:bg-white"
@ -422,6 +481,37 @@ export default function ResumeReviewPage() {
)} )}
</div> </div>
</div> </div>
{/* Delete resume dialog */}
<Dialog
isShown={isDeleteMode}
primaryButton={
<Button
disabled={deleteResumeMutation.isLoading}
display="block"
isLoading={deleteResumeMutation.isLoading}
label="Delete"
variant="danger"
onClick={onDeleteDialog}
/>
}
secondaryButton={
<Button
disabled={deleteResumeMutation.isLoading}
display="block"
label="Cancel"
variant="tertiary"
onClick={onCancelDialog}
/>
}
title="Are you sure?"
onClose={() => setIsDeleteMode(false)}>
<div>
Note that deleting this resume will delete all its contents as
well. This action is also irreversible! Please check before
confirming!
</div>
</Dialog>
</main> </main>
</> </>
)} )}

@ -435,4 +435,18 @@ export const resumesResumeUserRouter = createProtectedRouter()
return { filterCounts, mappedResumeData, totalRecords }; return { filterCounts, mappedResumeData, totalRecords };
}, },
})
.mutation('delete', {
input: z.object({
id: z.string(),
}),
async resolve({ ctx, input }) {
const { id } = input;
return await ctx.prisma.resumesResume.delete({
where: {
id,
},
});
},
}); });

Loading…
Cancel
Save