mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2026-07-26 01:44:53 +10:00
initial commit of v5
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
import { t } from "@lingui/core/macro";
|
||||
import { useMemo } from "react";
|
||||
import { match } from "ts-pattern";
|
||||
import type z from "zod";
|
||||
import { levelDesignSchema } from "@/schema/resume/data";
|
||||
import { Combobox, type ComboboxProps } from "../ui/combobox";
|
||||
|
||||
export type LevelType = z.infer<typeof levelDesignSchema>["type"];
|
||||
|
||||
type LevelTypeComboboxProps = Omit<ComboboxProps, "options">;
|
||||
|
||||
export const getLevelTypeName = (type: LevelType) => {
|
||||
return match(type)
|
||||
.with("hidden", () => t`Hidden`)
|
||||
.with("circle", () => t`Circle`)
|
||||
.with("square", () => t`Square`)
|
||||
.with("rectangle", () => t`Rectangle`)
|
||||
.with("rectangle-full", () => t`Rectangle (Full Width)`)
|
||||
.with("progress-bar", () => t`Progress Bar`)
|
||||
.with("icon", () => t`Icon`)
|
||||
.exhaustive();
|
||||
};
|
||||
|
||||
export function LevelTypeCombobox({ ...props }: LevelTypeComboboxProps) {
|
||||
const options = useMemo(() => {
|
||||
return levelDesignSchema.shape.type.options.map((option) => ({
|
||||
value: option,
|
||||
label: getLevelTypeName(option),
|
||||
}));
|
||||
}, []);
|
||||
|
||||
return <Combobox options={options} {...props} />;
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
import { t } from "@lingui/core/macro";
|
||||
import type z from "zod";
|
||||
import type { levelDesignSchema } from "@/schema/resume/data";
|
||||
import { cn } from "@/utils/style";
|
||||
import { PageIcon } from "../resume/shared/page-icon";
|
||||
|
||||
type Props = z.infer<typeof levelDesignSchema> & React.ComponentProps<"div"> & { level: number };
|
||||
|
||||
export function LevelDisplay({ icon, type, level, className, ...props }: Props) {
|
||||
if (level === 0) return null;
|
||||
if (type === "hidden") return null;
|
||||
|
||||
return (
|
||||
<div
|
||||
role="presentation"
|
||||
aria-label={t`Level ${level} of 5`}
|
||||
className={cn(
|
||||
"flex items-center gap-x-1.5",
|
||||
type === "progress-bar" && "gap-x-0",
|
||||
type === "rectangle-full" && "gap-x-2",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{Array.from({ length: 5 }).map((_, index) => {
|
||||
const isActive = index < level;
|
||||
|
||||
if (type === "progress-bar") {
|
||||
return (
|
||||
<div
|
||||
key={index}
|
||||
className={cn(
|
||||
"h-2.5 flex-1 border border-(--page-primary-color) border-x-0 first:border-l last:border-r",
|
||||
isActive && "bg-(--page-primary-color)",
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (type === "icon") {
|
||||
return (
|
||||
<PageIcon
|
||||
key={index}
|
||||
icon={icon}
|
||||
className={cn("h-3 overflow-visible text-(--page-primary-color)", !isActive && "opacity-40")}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
key={index}
|
||||
className={cn(
|
||||
"size-2.5 border border-(--page-primary-color)",
|
||||
isActive && "bg-(--page-primary-color)",
|
||||
type === "circle" && "rounded-full",
|
||||
type === "rectangle" && "w-7",
|
||||
type === "rectangle-full" && "w-auto flex-1",
|
||||
)}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user