refactor(v4.0.0-alpha): beginning of a new era

This commit is contained in:
Amruth Pillai
2023-11-05 12:31:42 +01:00
parent 0ba6a444e2
commit 22933bd412
505 changed files with 81829 additions and 0 deletions

View File

@ -0,0 +1,193 @@
import { Plus, PlusCircle } from "@phosphor-icons/react";
import {
Award,
Certification,
CustomSectionItem,
Education,
Experience,
Interest,
Language,
Profile,
Project,
Publication,
Reference,
Skill,
Volunteer,
} from "@reactive-resume/schema";
import { Button, ScrollArea, Separator } from "@reactive-resume/ui";
import { getCEFRLevel } from "@reactive-resume/utils";
import { Fragment, useRef } from "react";
import { Link } from "react-router-dom";
import { Icon } from "@/client/components/icon";
import { UserAvatar } from "@/client/components/user-avatar";
import { UserOptions } from "@/client/components/user-options";
import { useResumeStore } from "@/client/stores/resume";
import { BasicsSection } from "./sections/basics";
import { SectionBase } from "./sections/shared/section-base";
import { SectionIcon } from "./sections/shared/section-icon";
import { SummarySection } from "./sections/summary";
export const LeftSidebar = () => {
const containterRef = useRef<HTMLDivElement | null>(null);
const addSection = useResumeStore((state) => state.addSection);
const customSections = useResumeStore((state) => state.resume.data.sections.custom);
const scrollIntoView = (selector: string) => {
const section = containterRef.current?.querySelector(selector);
section?.scrollIntoView({ behavior: "smooth" });
};
return (
<div className="flex bg-secondary-accent/30 pt-16 lg:pt-0">
<div className="hidden basis-12 flex-col items-center justify-between bg-secondary-accent/30 py-4 sm:flex">
<Button asChild size="icon" variant="ghost" className="h-8 w-8 rounded-full">
<Link to="/dashboard">
<Icon size={14} />
</Link>
</Button>
<div className="flex flex-col items-center justify-center gap-y-2">
<SectionIcon id="basics" name="Basics" onClick={() => scrollIntoView("#basics")} />
<SectionIcon id="summary" onClick={() => scrollIntoView("#summary")} />
<SectionIcon id="profiles" onClick={() => scrollIntoView("#profiles")} />
<SectionIcon id="experience" onClick={() => scrollIntoView("#experience")} />
<SectionIcon id="education" onClick={() => scrollIntoView("#education")} />
<SectionIcon id="awards" onClick={() => scrollIntoView("#awards")} />
<SectionIcon id="certifications" onClick={() => scrollIntoView("#certifications")} />
<SectionIcon id="interests" onClick={() => scrollIntoView("#interests")} />
<SectionIcon id="languages" onClick={() => scrollIntoView("#languages")} />
<SectionIcon id="volunteer" onClick={() => scrollIntoView("#volunteer")} />
<SectionIcon id="projects" onClick={() => scrollIntoView("#projects")} />
<SectionIcon id="publications" onClick={() => scrollIntoView("#publications")} />
<SectionIcon id="skills" onClick={() => scrollIntoView("#skills")} />
<SectionIcon id="references" onClick={() => scrollIntoView("#references")} />
<SectionIcon
id="custom"
variant="outline"
name="Add a new section"
icon={<Plus size={14} />}
onClick={() => {
addSection();
scrollIntoView("& > section:last-of-type");
}}
/>
</div>
<UserOptions>
<Button size="icon" variant="ghost" className="rounded-full">
<UserAvatar size={28} />
</Button>
</UserOptions>
</div>
<ScrollArea orientation="vertical" className="h-screen flex-1">
<div ref={containterRef} className="grid gap-y-6 p-6 @container/left">
<BasicsSection />
<Separator />
<SummarySection />
<Separator />
<SectionBase<Profile>
id="profiles"
title={(item) => item.network}
description={(item) => item.username}
/>
<Separator />
<SectionBase<Experience>
id="experience"
title={(item) => item.company}
description={(item) => item.position}
/>
<Separator />
<SectionBase<Education>
id="education"
title={(item) => item.institution}
description={(item) => item.area}
/>
<Separator />
<SectionBase<Award>
id="awards"
title={(item) => item.title}
description={(item) => item.awarder}
/>
<Separator />
<SectionBase<Certification>
id="certifications"
title={(item) => item.name}
description={(item) => item.issuer}
/>
<Separator />
<SectionBase<Interest>
id="interests"
title={(item) => item.name}
description={(item) => {
if (item.keywords.length > 0) return `${item.keywords.length} keywords`;
}}
/>
<Separator />
<SectionBase<Language>
id="languages"
title={(item) => item.name}
description={(item) => item.fluency || getCEFRLevel(item.fluencyLevel)}
/>
<Separator />
<SectionBase<Volunteer>
id="volunteer"
title={(item) => item.organization}
description={(item) => item.position}
/>
<Separator />
<SectionBase<Project>
id="projects"
title={(item) => item.name}
description={(item) => item.description}
/>
<Separator />
<SectionBase<Publication>
id="publications"
title={(item) => item.name}
description={(item) => item.publisher}
/>
<Separator />
<SectionBase<Skill>
id="skills"
title={(item) => item.name}
description={(item) => {
if (item.description) return item.description;
if (item.keywords.length > 0) return `${item.keywords.length} keywords`;
}}
/>
<Separator />
<SectionBase<Reference>
id="references"
title={(item) => item.name}
description={(item) => item.description}
/>
{/* Custom Sections */}
{Object.values(customSections).map((section) => (
<Fragment key={section.id}>
<Separator />
<SectionBase<CustomSectionItem>
id={`custom.${section.id}`}
title={(item) => item.name}
description={(item) => item.description}
/>
</Fragment>
))}
<Separator />
<Button size="lg" variant="outline" onClick={addSection}>
<PlusCircle />
<span className="ml-2">Add a new section</span>
</Button>
</div>
</ScrollArea>
</div>
);
};