import type { LeftSidebarSection } from "@/libs/resume/section"; import { t } from "@lingui/core/macro"; import { Trans } from "@lingui/react/macro"; import { LockSimpleIcon } from "@phosphor-icons/react"; import { useMutation } from "@tanstack/react-query"; import { Fragment, useCallback, useRef } from "react"; import { toast } from "sonner"; import { match } from "ts-pattern"; import { Avatar, AvatarFallback, AvatarImage } from "@reactive-resume/ui/components/avatar"; import { Button } from "@reactive-resume/ui/components/button"; import { ScrollArea } from "@reactive-resume/ui/components/scroll-area"; import { Separator } from "@reactive-resume/ui/components/separator"; import { Tooltip, TooltipContent, TooltipTrigger } from "@reactive-resume/ui/components/tooltip"; import { getInitials } from "@reactive-resume/utils/string"; import { useCurrentResume, useIsResumeLocked, usePatchResume } from "@/features/resume/builder/draft"; import { UserDropdownMenu } from "@/features/user/dropdown-menu"; import { getResumeErrorMessage } from "@/libs/error-message"; import { orpc } from "@/libs/orpc/client"; import { getSectionIcon, getSectionTitle, leftSidebarSections } from "@/libs/resume/section"; import { BuilderSidebarEdge } from "../../-components/edge"; import { useBuilderSidebar } from "../../-store/sidebar"; import { AwardsSectionBuilder } from "./sections/awards"; import { BasicsSectionBuilder } from "./sections/basics"; import { CertificationsSectionBuilder } from "./sections/certifications"; import { CustomSectionBuilder } from "./sections/custom"; import { EducationSectionBuilder } from "./sections/education"; import { ExperienceSectionBuilder } from "./sections/experience"; import { InterestsSectionBuilder } from "./sections/interests"; import { LanguagesSectionBuilder } from "./sections/languages"; import { PictureSectionBuilder } from "./sections/picture"; import { ProfilesSectionBuilder } from "./sections/profiles"; import { ProjectsSectionBuilder } from "./sections/projects"; import { PublicationsSectionBuilder } from "./sections/publications"; import { ReferencesSectionBuilder } from "./sections/references"; import { SkillsSectionBuilder } from "./sections/skills"; import { SummarySectionBuilder } from "./sections/summary"; import { VolunteerSectionBuilder } from "./sections/volunteer"; function getSectionComponent(type: LeftSidebarSection) { return match(type) .with("picture", () => ) .with("basics", () => ) .with("summary", () => ) .with("profiles", () => ) .with("experience", () => ) .with("education", () => ) .with("projects", () => ) .with("skills", () => ) .with("languages", () => ) .with("interests", () => ) .with("awards", () => ) .with("certifications", () => ) .with("publications", () => ) .with("volunteer", () => ) .with("references", () => ) .with("custom", () => ) .exhaustive(); } export function BuilderSidebarLeft() { const scrollAreaRef = useRef(null); const isLocked = useIsResumeLocked(); return ( <>
{isLocked && }
{leftSidebarSections.map((section) => ( {getSectionComponent(section)} ))}
); } function LockBanner() { const resume = useCurrentResume(); const patchResume = usePatchResume(); const { mutate: setLocked, isPending } = useMutation(orpc.resume.setLocked.mutationOptions()); const handleUnlock = () => { setLocked( { id: resume.id, isLocked: false }, { onSuccess: () => { patchResume((draft) => { draft.isLocked = false; }); }, onError: (error) => { toast.error(getResumeErrorMessage(error)); }, }, ); }; return (

This resume is locked

Editing is disabled until you unlock it.

); } function SidebarEdge() { const { toggleSidebar } = useBuilderSidebar(); const scrollToSection = useCallback( (section: LeftSidebarSection) => { toggleSidebar("left", true); // Section ids are globally unique; document.getElementById reliably resolves the scroll target // (querying through the ScrollArea ref did not — its ref does not expose the scroll container). document .getElementById(`sidebar-${section}`) ?.scrollIntoView({ block: "start", inline: "nearest", behavior: "smooth" }); }, [toggleSidebar], ); return (
{leftSidebarSections.map((section) => ( scrollToSection(section)} > {getSectionIcon(section)} } /> {getSectionTitle(section)} ))}
{({ session }) => ( )}
); }