import { zodResolver } from "@hookform/resolvers/zod"; import { t } from "@lingui/macro"; import { CaretDown, Flask, MagicWand, Plus } from "@phosphor-icons/react"; import { createResumeSchema, ResumeDto } from "@reactive-resume/dto"; import { idSchema, sampleResume } from "@reactive-resume/schema"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, Button, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, Input, Tooltip, } from "@reactive-resume/ui"; import { cn, generateRandomName, kebabCase } from "@reactive-resume/utils"; import { useEffect } from "react"; import { useForm } from "react-hook-form"; import { z } from "zod"; import { useCreateResume, useDeleteResume, useUpdateResume } from "@/client/services/resume"; import { useImportResume } from "@/client/services/resume/import"; import { useDialog } from "@/client/stores/dialog"; const formSchema = createResumeSchema.extend({ id: idSchema.optional() }); type FormValues = z.infer; export const ResumeDialog = () => { const { isOpen, mode, payload, close } = useDialog("resume"); const isCreate = mode === "create"; const isUpdate = mode === "update"; const isDelete = mode === "delete"; const isDuplicate = mode === "duplicate"; const { createResume, loading: createLoading } = useCreateResume(); const { updateResume, loading: updateLoading } = useUpdateResume(); const { deleteResume, loading: deleteLoading } = useDeleteResume(); const { importResume: duplicateResume, loading: duplicateLoading } = useImportResume(); const loading = createLoading || updateLoading || deleteLoading || duplicateLoading; const form = useForm({ resolver: zodResolver(formSchema), defaultValues: { title: "", slug: "" }, }); useEffect(() => { if (isOpen) onReset(); }, [isOpen, payload]); useEffect(() => { const slug = kebabCase(form.watch("title")); form.setValue("slug", slug); }, [form.watch("title")]); const onSubmit = async (values: FormValues) => { if (isCreate) { await createResume({ slug: values.slug, title: values.title, visibility: "private" }); } if (isUpdate) { if (!payload.item?.id) return; await updateResume({ ...payload.item, title: values.title, slug: values.slug, }); } if (isDuplicate) { if (!payload.item?.id) return; await duplicateResume({ title: values.title, slug: values.slug, data: payload.item.data, }); } if (isDelete) { if (!payload.item?.id) return; await deleteResume({ id: payload.item.id }); } close(); }; const onReset = () => { if (isCreate) form.reset({ title: "", slug: "" }); if (isUpdate) form.reset({ id: payload.item?.id, title: payload.item?.title, slug: payload.item?.slug }); if (isDuplicate) form.reset({ title: `${payload.item?.title} (Copy)`, slug: `${payload.item?.slug}-copy` }); if (isDelete) form.reset({ id: payload.item?.id, title: payload.item?.title, slug: payload.item?.slug }); }; const onGenerateRandomName = () => { const name = generateRandomName(); form.setValue("title", name); form.setValue("slug", kebabCase(name)); }; const onCreateSample = async () => { const randomName = generateRandomName(); const { title, slug } = form.getValues(); await duplicateResume({ title: title || randomName, slug: slug ?? kebabCase(randomName), data: sampleResume, }); close(); }; if (isDelete) { return (
{t`Are you sure you want to delete your resume?`} {t`This action cannot be undone. This will permanently delete your resume and cannot be recovered.`} {t`Cancel`} {t`Delete`}
); } return (

{isCreate && t`Create a new resume`} {isUpdate && t`Update an existing resume`} {isDuplicate && t`Duplicate an existing resume`}

{isCreate && t`Start building your resume by giving it a name.`} {isUpdate && t`Changed your mind about the name? Give it a new one.`} {isDuplicate && t`Give your old resume a new name.`}
( {t`Title`}
{(isCreate || isDuplicate) && ( )}
{t`Tip: You can name the resume referring to the position you are applying for.`}
)} /> ( {t`Slug`} )} />
{isCreate && ( {t`Create Sample Resume`} )}
); };