diff --git a/apps/client/src/pages/builder/_components/toolbar.tsx b/apps/client/src/pages/builder/_components/toolbar.tsx index 439f90b39..a2568fa45 100644 --- a/apps/client/src/pages/builder/_components/toolbar.tsx +++ b/apps/client/src/pages/builder/_components/toolbar.tsx @@ -15,11 +15,13 @@ import { import { Button, Separator, Toggle, Tooltip } from "@reactive-resume/ui"; import { motion } from "framer-motion"; +import { useToast } from "@/client/hooks/use-toast"; import { usePrintResume } from "@/client/services/resume"; import { useBuilderStore } from "@/client/stores/builder"; import { useResumeStore, useTemporalResumeStore } from "@/client/stores/resume"; export const BuilderToolbar = () => { + const { toast } = useToast(); const setValue = useResumeStore((state) => state.setValue); const undo = useTemporalResumeStore((state) => state.undo); const redo = useTemporalResumeStore((state) => state.redo); @@ -42,6 +44,17 @@ export const BuilderToolbar = () => { openInNewTab(url); }; + const onCopy = async () => { + const { url } = await printResume({ id }); + await navigator.clipboard.writeText(url); + + toast({ + variant: "success", + title: t`A link has been copied to your clipboard.`, + description: t`Anyone with this link can view and download the resume. Share it on your profile or with recruiters.`, + }); + }; + const onZoomIn = () => frameRef?.contentWindow?.postMessage({ type: "ZOOM_IN" }, "*"); const onZoomOut = () => frameRef?.contentWindow?.postMessage({ type: "ZOOM_OUT" }, "*"); const onResetView = () => frameRef?.contentWindow?.postMessage({ type: "RESET_VIEW" }, "*"); @@ -117,7 +130,13 @@ export const BuilderToolbar = () => { - diff --git a/apps/client/src/pages/dashboard/resumes/_layouts/list/_components/resume-item.tsx b/apps/client/src/pages/dashboard/resumes/_layouts/list/_components/resume-item.tsx index 5891d83dd..ab5664586 100644 --- a/apps/client/src/pages/dashboard/resumes/_layouts/list/_components/resume-item.tsx +++ b/apps/client/src/pages/dashboard/resumes/_layouts/list/_components/resume-item.tsx @@ -3,6 +3,8 @@ import { CopySimple, DotsThreeVertical, FolderOpen, + Lock, + LockOpen, PencilSimple, TrashSimple, } from "@phosphor-icons/react"; @@ -38,6 +40,7 @@ type Props = { export const ResumeListItem = ({ resume }: Props) => { const navigate = useNavigate(); const { open } = useDialog("resume"); + const { open: lockOpen } = useDialog("lock"); const { url } = useResumePreview(resume.id); @@ -55,6 +58,10 @@ export const ResumeListItem = ({ resume }: Props) => { open("duplicate", { id: "resume", item: resume }); }; + const onLockChange = () => { + lockOpen(resume.locked ? "update" : "create", { id: "lock", item: resume }); + }; + const onDelete = () => { open("delete", { id: "resume", item: resume }); }; @@ -94,6 +101,27 @@ export const ResumeListItem = ({ resume }: Props) => { {t`Duplicate`} + {resume.locked ? ( + { + event.stopPropagation(); + onLockChange(); + }} + > + + {t`Unlock`} + + ) : ( + { + event.stopPropagation(); + onLockChange(); + }} + > + + {t`Lock`} + + )} { {t`Duplicate`} + {resume.locked ? ( + + + {t`Unlock`} + + ) : ( + + + {t`Lock`} + + )} diff --git a/libs/parser/src/json-resume/index.ts b/libs/parser/src/json-resume/index.ts index 2d9b8a439..f6cd1c56c 100644 --- a/libs/parser/src/json-resume/index.ts +++ b/libs/parser/src/json-resume/index.ts @@ -147,7 +147,7 @@ export class JsonResumeParser implements Parser { result.sections.certifications.items.push({ ...defaultCertification, id: createId(), - name: certificate.title ?? "", + name: certificate.name ?? "", date: certificate.date ?? "", issuer: certificate.issuer ?? "", summary: certificate.summary ?? "", diff --git a/libs/parser/src/json-resume/schema.ts b/libs/parser/src/json-resume/schema.ts index c73c1a0fa..4b7085253 100644 --- a/libs/parser/src/json-resume/schema.ts +++ b/libs/parser/src/json-resume/schema.ts @@ -63,7 +63,7 @@ const awardsSchema = z.object({ }); const certificatesSchema = z.object({ - title: z.string().optional(), + name: z.string().optional(), date: iso8601.optional(), issuer: z.string().optional(), summary: z.string().optional(),