diff --git a/src/components/krow/talent/LearnToday.jsx b/src/components/krow/talent/LearnToday.jsx
deleted file mode 100644
index c7a2dfb..0000000
--- a/src/components/krow/talent/LearnToday.jsx
+++ /dev/null
@@ -1,31 +0,0 @@
-import React from 'react';
-import { Link } from 'react-router-dom';
-import { BookOpen } from 'lucide-react';
-
-export default function LearnToday({ courses = [] }) {
- const recs = courses.filter((c) => c.status !== 'archived').slice(0, 4);
- return (
-
- Learn
- Micro-learning. 5-minute lessons. Learning increases value immediately.
- {recs.length === 0 ? (
- No recommendations yet.
- ) : (
-
- {recs.map((c) => (
-
-
-
-
-
{c.title}
-
{c.estimated_minutes} min · {c.category}
-
-
-
+{Math.max(1, Math.round((c.xp || 100) / 20))} Score
-
- ))}
-
- )}
-
- );
-}
\ No newline at end of file
diff --git a/src/components/krow/talent/ReputationHistory.jsx b/src/components/krow/talent/ReputationHistory.jsx
deleted file mode 100644
index e56baac..0000000
--- a/src/components/krow/talent/ReputationHistory.jsx
+++ /dev/null
@@ -1,38 +0,0 @@
-import React from 'react';
-import { TrendingUp } from 'lucide-react';
-import { getTalentScore, toFICO } from '@/lib/talentHome';
-
-export default function ReputationHistory({ profile }) {
- const cur = toFICO(getTalentScore(profile));
- const pts = [290, 322, 340, cur];
- const w = 280;
- const h = 72;
- const pad = 6;
- const min = 280;
- const max = 850;
- const x = (i) => pad + (i * (w - 2 * pad)) / (pts.length - 1);
- const y = (v) => h - pad - ((v - min) / (max - min)) * (h - 2 * pad);
- const path = pts.map((v, i) => `${i ? 'L' : 'M'}${x(i).toFixed(1)},${y(v).toFixed(1)}`).join(' ');
-
- return (
-
-
-
Reputation History
-
- {cur}
-
-
-
-
- {pts.map((v, i) => (
-
- ))}
-
-
- {pts.map((v, i) => (
- {v}
- ))}
-
-
- );
-}
\ No newline at end of file
diff --git a/src/components/krow/talent/TalentCreditScore.jsx b/src/components/krow/talent/TalentCreditScore.jsx
deleted file mode 100644
index a9f60b3..0000000
--- a/src/components/krow/talent/TalentCreditScore.jsx
+++ /dev/null
@@ -1,44 +0,0 @@
-import React from 'react';
-import { getFactors } from '@/lib/talentHome';
-
-function statusFor(v) {
- if (v >= 80) return { txt: 'Excellent', color: 'text-[#16A34A]', dot: 'bg-[#16A34A]' };
- if (v >= 60) return { txt: 'Good', color: 'text-[#0838E0]', dot: 'bg-[#0838E0]' };
- if (v >= 40) return { txt: 'Fair', color: 'text-[#D97706]', dot: 'bg-[#D97706]' };
- if (v > 0) return { txt: 'Poor', color: 'text-[#DC2626]', dot: 'bg-[#DC2626]' };
- return { txt: 'No data', color: 'text-[#9CA3AF]', dot: 'bg-[#D1D5DB]' };
-}
-
-function Factor({ label, value, weight }) {
- const s = statusFor(value);
- return (
-
-
-
-
- {label}
- {weight}% weight
-
-
-
-
{s.txt}
-
- );
-}
-
-export default function TalentCreditScore({ profile }) {
- const factors = getFactors(profile);
- return (
-
-
-
What's Driving Your Score
- Updated this month
-
-
- {factors.map((f) => )}
-
-
- );
-}
\ No newline at end of file
diff --git a/src/components/krow/talent/VerifiedExperience.jsx b/src/components/krow/talent/VerifiedExperience.jsx
deleted file mode 100644
index a0fb7d1..0000000
--- a/src/components/krow/talent/VerifiedExperience.jsx
+++ /dev/null
@@ -1,37 +0,0 @@
-import React from 'react';
-import { Star } from 'lucide-react';
-
-export default function VerifiedExperience({ profile }) {
- const fromExp = (profile.experience || []).map((e) => ({
- company: e.company || 'Company',
- shifts: Math.max(1, Math.round((e.years || 1) * 20)),
- }));
- const list = fromExp.length
- ? fromExp
- : [
- { company: 'Google', shifts: 58 },
- { company: 'Adobe', shifts: 26 },
- { company: 'EA', shifts: 15 },
- ];
-
- return (
-
- Verified Experience
-
- {list.map((x, i) => (
-
-
-
{x.company}
-
{x.shifts} shifts
-
-
- {Array.from({ length: 5 }).map((_, s) => (
-
- ))}
-
-
- ))}
-
-
- );
-}
\ No newline at end of file
diff --git a/src/components/krow/talent/VerifiedExperienceList.jsx b/src/components/krow/talent/VerifiedExperienceList.jsx
index aa47cb5..419e4aa 100644
--- a/src/components/krow/talent/VerifiedExperienceList.jsx
+++ b/src/components/krow/talent/VerifiedExperienceList.jsx
@@ -53,7 +53,7 @@ function Stars({ count }) {
// Verified Experience & Network — employer-facing list of the worker's last
// 3 jobs with time worked, a review rating, and reference / endorse actions.
-export default function VerifiedExperienceList({ profile, onReference, onEndorse }) {
+export default function VerifiedExperienceList({ profile, onReference }) {
const list = verifiedExperience(profile);
if (list.length === 0) return null;
diff --git a/src/components/krow/talent/VerifiedStamp.jsx b/src/components/krow/talent/VerifiedStamp.jsx
deleted file mode 100644
index 1a98943..0000000
--- a/src/components/krow/talent/VerifiedStamp.jsx
+++ /dev/null
@@ -1,58 +0,0 @@
-import React from 'react';
-
-// Scallop radius for the flower-like outer border
-const SCALLOP_R = (R, n) => R * Math.sin(Math.PI / n);
-
-function scallopPath(cx, cy, R, n) {
- const r = SCALLOP_R(R, n);
- const pts = [];
- for (let i = 0; i < n; i++) {
- const a = (i / n) * 2 * Math.PI - Math.PI / 2;
- pts.push([cx + R * Math.cos(a), cy + R * Math.sin(a)]);
- }
- let d = `M ${pts[0][0].toFixed(2)} ${pts[0][1].toFixed(2)} `;
- for (let i = 0; i < n; i++) {
- const p2 = pts[(i + 1) % n];
- d += `A ${r.toFixed(2)} ${r.toFixed(2)} 0 0 0 ${p2[0].toFixed(2)} ${p2[1].toFixed(2)} `;
- }
- return d + 'Z';
-}
-
-function starPath(cx, cy, outer, inner, points = 5) {
- let d = '';
- for (let i = 0; i < points * 2; i++) {
- const r = i % 2 === 0 ? outer : inner;
- const a = (i / (points * 2)) * 2 * Math.PI - Math.PI / 2;
- const x = cx + r * Math.cos(a);
- const y = cy + r * Math.sin(a);
- d += `${i === 0 ? 'M' : 'L'} ${x.toFixed(2)} ${y.toFixed(2)} `;
- }
- return d + 'Z';
-}
-
-export default function VerifiedStamp({ size = 26, className = '' }) {
- const cx = 50, cy = 50, R = 44, n = 12;
- const green = '#9FD34E';
- const textPath = `M ${cx} ${cy - 36} A 36 36 0 1 1 ${cx - 0.01} ${cy - 36}`;
- const label = 'VERIFIED \u2022 VERIFIED \u2022 VERIFIED \u2022';
-
- return (
-
-
-
-
-
-
- {label}
-
-
-
- );
-}
\ No newline at end of file
diff --git a/src/components/krow/talent/YourMarket.jsx b/src/components/krow/talent/YourMarket.jsx
deleted file mode 100644
index 047411a..0000000
--- a/src/components/krow/talent/YourMarket.jsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import React from 'react';
-import { Eye, FileText, Calendar, Clock } from 'lucide-react';
-
-export default function YourMarket({ profile, jobRecs = [] }) {
- const companies = (jobRecs || []).slice(0, 3).map(r => (r.title || 'Company').split(' ')[0]);
- const availability = (profile.availability || [])[0] || 'Available This Week';
-
- const cards = [
- { icon: Eye, label: 'Companies viewing you', dots: companies.length ? companies : ['Google', 'Bon Appetit', 'Compass'] },
- { icon: FileText, label: 'Applications', value: '2 Pending' },
- { icon: Calendar, label: 'Interviews', value: 'Tomorrow 9AM' },
- { icon: Clock, label: 'Availability', value: availability },
- ];
-
- return (
-
- Your Market
-
- {cards.map((c) => {
- const Icon = c.icon;
- return (
-
-
- {c.label}
-
- {c.dots ? (
-
- {c.dots.map((co, i) => (
-
- {co}
-
- ))}
-
- ) : (
-
{c.value}
- )}
-
- );
- })}
-
-
- );
-}
\ No newline at end of file
diff --git a/src/components/krow/talent/YourNetwork.jsx b/src/components/krow/talent/YourNetwork.jsx
deleted file mode 100644
index b8b8f97..0000000
--- a/src/components/krow/talent/YourNetwork.jsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import React from 'react';
-import { Star } from 'lucide-react';
-
-const SEED = [
- { name: 'Luis', role: 'Supervisor', events: 12, action: 'Request Reference' },
- { name: 'Chef Antonio', role: 'Chef', events: 45, action: 'Endorse Skill' },
-];
-
-export default function YourNetwork({ profile }) {
- const fromExp = (profile.experience || []).slice(0, 2).map((e, i) => ({
- name: SEED[i]?.name || e.role || 'Colleague',
- role: e.role || 'Colleague',
- events: Math.max(1, Math.round((e.years || 1) * 10)),
- action: i === 0 ? 'Request Reference' : 'Endorse Skill',
- }));
- const data = fromExp.length ? fromExp : SEED;
-
- return (
-
- Your Network
-
- {data.map((n, i) => (
-
-
-
{n.name}
-
- {n.role} · {n.events} events
-
-
- {Array.from({ length: 5 }).map((_, s) => (
-
- ))}
-
-
-
- {n.action}
-
-
- ))}
-
-
- );
-}
\ No newline at end of file
diff --git a/src/components/skills/AddSkillDialog.jsx b/src/components/skills/AddSkillDialog.jsx
deleted file mode 100644
index 9f88b45..0000000
--- a/src/components/skills/AddSkillDialog.jsx
+++ /dev/null
@@ -1,229 +0,0 @@
-import React from 'react';
-import { Sparkles, Upload } from 'lucide-react';
-import { Button, Field, Input, Modal, Textarea } from '@/components/ds';
-import { usePreferences, useUpdatePreferences } from '@/lib/krowHooks';
-import { PAGE_KEYS, validateSkillSource } from '@/lib/skills/registry';
-import { skillTemplate, upsertCustomSkill } from '@/lib/skills/customSkills';
-import {
- isReadableDefinition, normalizeUpload, owliverFieldsFromSource, patchFrontmatter,
-} from '@/lib/skills/skillFields';
-import { reportSave } from '@/lib/skills/saveFeedback';
-
-/**
- * Add an Owliver skill.
- *
- * One dialog, opened from Settings and from Owliver's own header, writing to
- * one registry — a second registration path would be a second source of truth
- * by another name.
- *
- * What is stored is the Markdown itself, not a parsed record. A custom skill is
- * then exactly the artefact a file on disk is, read by the same parser, and can
- * be copied into `src/skills/` later without conversion.
- *
- * The fields above the editor are a starting point, not a second schema: typing
- * in them composes frontmatter in the existing format, which the author can
- * then edit directly. The Markdown is always what gets saved.
- */
-
-export function AddSkillDialog({ open, onOpenChange }) {
- const preferences = usePreferences();
- const updatePreferences = useUpdatePreferences();
-
- const [meta, setMeta] = React.useState({ id: '', name: '', description: '', pages: '' });
- const [source, setSource] = React.useState('');
- const [touched, setTouched] = React.useState(false);
- const [error, setError] = React.useState('');
- const fileRef = React.useRef(null);
-
- /* A fresh sheet each time it opens, so an abandoned draft is not waiting the
- next time someone adds a skill. */
- React.useEffect(() => {
- if (!open) return;
- setMeta({ id: '', name: '', description: '', pages: '' });
- setSource('');
- setTouched(false);
- setError('');
- }, [open]);
-
- /**
- * A field edit, written into the definition.
- *
- * A fresh draft is composed from the template; once there is a definition to
- * preserve — an uploaded file, or Markdown typed by hand — the field patches
- * the key it owns and leaves everything else alone. It used to stop here
- * entirely, so after an upload these four boxes edited nothing that was saved.
- */
- const syncFromMeta = (next) => {
- setMeta(next);
- const pages = next.pages.split(',').map((p) => p.trim()).filter(Boolean);
-
- if (!touched) {
- setSource(skillTemplate({
- id: next.id,
- name: next.name,
- description: next.description,
- pages,
- }));
- return;
- }
-
- setSource(patchFrontmatter(source, {
- id: next.id || undefined,
- name: next.name || undefined,
- description: next.description || undefined,
- pages: pages.length ? pages : undefined,
- }));
- };
-
- /**
- * A definition uploaded from a file.
- *
- * Filled the Markdown box and left every field beside it empty, and said
- * nothing about whether the file was usable until Add was pressed. Both are
- * fixed here: the frontmatter fills the fields, and an unusable file says so
- * at the moment it arrives.
- */
- const readFile = (event) => {
- const file = event.target.files?.[0];
- if (!file) return;
-
- const reader = new FileReader();
- reader.onerror = () => setError('That file could not be read.');
- reader.onload = () => {
- const raw = normalizeUpload(reader.result);
- setSource(raw);
- setTouched(true);
-
- /* Nothing readable: the fields stay as they were rather than emptying to
- a row of placeholders that read as values. */
- if (!isReadableDefinition(raw)) {
- setError('That file has no frontmatter block, so there is nothing to read into the fields. '
- + 'A definition starts with `---` on its own line.');
- return;
- }
-
- setError(validateSkillSource(raw) || '');
- const fields = owliverFieldsFromSource(raw);
- setMeta({
- id: fields.id,
- name: fields.name,
- description: fields.description,
- pages: fields.pages.join(', '),
- });
- };
- reader.readAsText(file);
- event.target.value = '';
- };
-
- const save = () => {
- const problem = validateSkillSource(source);
- if (problem) {
- setError(problem);
- return;
- }
-
- const { skill, next } = upsertCustomSkill(preferences.customSkills || [], source);
-
- updatePreferences.mutate({ customSkills: next }, reportSave(`${skill.name} added`));
- onOpenChange(false);
- };
-
- return (
-
- onOpenChange(false)}>Cancel
- Add skill
- >
- }
- >
-
-
- );
-}
diff --git a/src/components/ui/accordion.jsx b/src/components/ui/accordion.jsx
deleted file mode 100644
index 1c4416a..0000000
--- a/src/components/ui/accordion.jsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import * as React from "react"
-import * as AccordionPrimitive from "@radix-ui/react-accordion"
-import { ChevronDown } from "lucide-react"
-
-import { cn } from "@/lib/utils"
-
-const Accordion = AccordionPrimitive.Root
-
-const AccordionItem = React.forwardRef(({ className, ...props }, ref) => (
-
-))
-AccordionItem.displayName = "AccordionItem"
-
-const AccordionTrigger = React.forwardRef(({ className, children, ...props }, ref) => (
-
- svg]:rotate-180",
- className
- )}
- {...props}>
- {children}
-
-
-
-))
-AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName
-
-const AccordionContent = React.forwardRef(({ className, children, ...props }, ref) => (
-
- {children}
-
-))
-AccordionContent.displayName = AccordionPrimitive.Content.displayName
-
-export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }
diff --git a/src/components/ui/alert-dialog.jsx b/src/components/ui/alert-dialog.jsx
deleted file mode 100644
index a4174f3..0000000
--- a/src/components/ui/alert-dialog.jsx
+++ /dev/null
@@ -1,97 +0,0 @@
-import * as React from "react"
-import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog"
-
-import { cn } from "@/lib/utils"
-import { buttonVariants } from "@/components/ui/button"
-
-const AlertDialog = AlertDialogPrimitive.Root
-
-const AlertDialogTrigger = AlertDialogPrimitive.Trigger
-
-const AlertDialogPortal = AlertDialogPrimitive.Portal
-
-const AlertDialogOverlay = React.forwardRef(({ className, ...props }, ref) => (
-
-))
-AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName
-
-const AlertDialogContent = React.forwardRef(({ className, ...props }, ref) => (
-
-
-
-
-))
-AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName
-
-const AlertDialogHeader = ({
- className,
- ...props
-}) => (
-
-)
-AlertDialogHeader.displayName = "AlertDialogHeader"
-
-const AlertDialogFooter = ({
- className,
- ...props
-}) => (
-
-)
-AlertDialogFooter.displayName = "AlertDialogFooter"
-
-const AlertDialogTitle = React.forwardRef(({ className, ...props }, ref) => (
-
-))
-AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName
-
-const AlertDialogDescription = React.forwardRef(({ className, ...props }, ref) => (
-
-))
-AlertDialogDescription.displayName =
- AlertDialogPrimitive.Description.displayName
-
-const AlertDialogAction = React.forwardRef(({ className, ...props }, ref) => (
-
-))
-AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName
-
-const AlertDialogCancel = React.forwardRef(({ className, ...props }, ref) => (
-
-))
-AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName
-
-export {
- AlertDialog,
- AlertDialogPortal,
- AlertDialogOverlay,
- AlertDialogTrigger,
- AlertDialogContent,
- AlertDialogHeader,
- AlertDialogFooter,
- AlertDialogTitle,
- AlertDialogDescription,
- AlertDialogAction,
- AlertDialogCancel,
-}
diff --git a/src/components/ui/alert.jsx b/src/components/ui/alert.jsx
deleted file mode 100644
index 28597e8..0000000
--- a/src/components/ui/alert.jsx
+++ /dev/null
@@ -1,47 +0,0 @@
-import * as React from "react"
-import { cva } from "class-variance-authority";
-
-import { cn } from "@/lib/utils"
-
-const alertVariants = cva(
- "relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7",
- {
- variants: {
- variant: {
- default: "bg-background text-foreground",
- destructive:
- "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive",
- },
- },
- defaultVariants: {
- variant: "default",
- },
- }
-)
-
-const Alert = React.forwardRef(({ className, variant, ...props }, ref) => (
-
-))
-Alert.displayName = "Alert"
-
-const AlertTitle = React.forwardRef(({ className, ...props }, ref) => (
-
-))
-AlertTitle.displayName = "AlertTitle"
-
-const AlertDescription = React.forwardRef(({ className, ...props }, ref) => (
-
-))
-AlertDescription.displayName = "AlertDescription"
-
-export { Alert, AlertTitle, AlertDescription }
diff --git a/src/components/ui/aspect-ratio.jsx b/src/components/ui/aspect-ratio.jsx
deleted file mode 100644
index c4abbf3..0000000
--- a/src/components/ui/aspect-ratio.jsx
+++ /dev/null
@@ -1,5 +0,0 @@
-import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio"
-
-const AspectRatio = AspectRatioPrimitive.Root
-
-export { AspectRatio }
diff --git a/src/components/ui/avatar.jsx b/src/components/ui/avatar.jsx
deleted file mode 100644
index 4920324..0000000
--- a/src/components/ui/avatar.jsx
+++ /dev/null
@@ -1,35 +0,0 @@
-"use client"
-
-import * as React from "react"
-import * as AvatarPrimitive from "@radix-ui/react-avatar"
-
-import { cn } from "@/lib/utils"
-
-const Avatar = React.forwardRef(({ className, ...props }, ref) => (
-
-))
-Avatar.displayName = AvatarPrimitive.Root.displayName
-
-const AvatarImage = React.forwardRef(({ className, ...props }, ref) => (
-
-))
-AvatarImage.displayName = AvatarPrimitive.Image.displayName
-
-const AvatarFallback = React.forwardRef(({ className, ...props }, ref) => (
-
-))
-AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName
-
-export { Avatar, AvatarImage, AvatarFallback }
diff --git a/src/components/ui/calendar.jsx b/src/components/ui/calendar.jsx
deleted file mode 100644
index 2a13f7d..0000000
--- a/src/components/ui/calendar.jsx
+++ /dev/null
@@ -1,74 +0,0 @@
-import * as React from "react"
-import { ChevronLeft, ChevronRight } from "lucide-react"
-import { DayPicker } from "react-day-picker"
-
-import { cn } from "@/lib/utils"
-import { buttonVariants } from "@/components/ui/button"
-
-// react-day-picker v9 renamed every element key and replaced the IconLeft /
-// IconRight slots with a single `Chevron` that receives an orientation. The
-// styling below is the same as before the upgrade, remapped onto the v9 names.
-function Calendar({
- className,
- classNames,
- showOutsideDays = true,
- ...props
-}) {
- return (
- (
.day-range-end)]:rounded-r-md [&:has(>.day-range-start)]:rounded-l-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md"
- : "[&:has([aria-selected])]:rounded-md"
- ),
- day_button: cn(
- buttonVariants({ variant: "ghost" }),
- "h-8 w-8 p-0 font-normal aria-selected:opacity-100"
- ),
- range_start: "day-range-start",
- range_end: "day-range-end",
- selected:
- "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
- today: "bg-accent text-accent-foreground",
- outside:
- "day-outside text-muted-foreground aria-selected:bg-accent/50 aria-selected:text-muted-foreground",
- disabled: "text-muted-foreground opacity-50",
- range_middle:
- "aria-selected:bg-accent aria-selected:text-accent-foreground",
- hidden: "invisible",
- ...classNames,
- }}
- components={{
- Chevron: ({ className, orientation, ...props }) => {
- const Icon = orientation === "left" ? ChevronLeft : ChevronRight
- return
- },
- }}
- {...props} />)
- );
-}
-Calendar.displayName = "Calendar"
-
-export { Calendar }
diff --git a/src/components/ui/carousel.jsx b/src/components/ui/carousel.jsx
deleted file mode 100644
index 99ea00e..0000000
--- a/src/components/ui/carousel.jsx
+++ /dev/null
@@ -1,193 +0,0 @@
-import * as React from "react"
-import useEmblaCarousel from "embla-carousel-react";
-import { ArrowLeft, ArrowRight } from "lucide-react"
-
-import { cn } from "@/lib/utils"
-import { Button } from "@/components/ui/button"
-
-const CarouselContext = React.createContext(null)
-
-function useCarousel() {
- const context = React.useContext(CarouselContext)
-
- if (!context) {
- throw new Error("useCarousel must be used within a ")
- }
-
- return context
-}
-
-const Carousel = React.forwardRef((
- {
- orientation = "horizontal",
- opts,
- setApi,
- plugins,
- className,
- children,
- ...props
- },
- ref
-) => {
- const [carouselRef, api] = useEmblaCarousel({
- ...opts,
- axis: orientation === "horizontal" ? "x" : "y",
- }, plugins)
- const [canScrollPrev, setCanScrollPrev] = React.useState(false)
- const [canScrollNext, setCanScrollNext] = React.useState(false)
-
- const onSelect = React.useCallback((api) => {
- if (!api) {
- return
- }
-
- setCanScrollPrev(api.canScrollPrev())
- setCanScrollNext(api.canScrollNext())
- }, [])
-
- const scrollPrev = React.useCallback(() => {
- api?.scrollPrev()
- }, [api])
-
- const scrollNext = React.useCallback(() => {
- api?.scrollNext()
- }, [api])
-
- const handleKeyDown = React.useCallback((event) => {
- if (event.key === "ArrowLeft") {
- event.preventDefault()
- scrollPrev()
- } else if (event.key === "ArrowRight") {
- event.preventDefault()
- scrollNext()
- }
- }, [scrollPrev, scrollNext])
-
- React.useEffect(() => {
- if (!api || !setApi) {
- return
- }
-
- setApi(api)
- }, [api, setApi])
-
- React.useEffect(() => {
- if (!api) {
- return
- }
-
- onSelect(api)
- api.on("reInit", onSelect)
- api.on("select", onSelect)
-
- return () => {
- api?.off("select", onSelect)
- };
- }, [api, onSelect])
-
- return (
- (
-
- {children}
-
- )
- );
-})
-Carousel.displayName = "Carousel"
-
-const CarouselContent = React.forwardRef(({ className, ...props }, ref) => {
- const { carouselRef, orientation } = useCarousel()
-
- return (
- ()
- );
-})
-CarouselContent.displayName = "CarouselContent"
-
-const CarouselItem = React.forwardRef(({ className, ...props }, ref) => {
- const { orientation } = useCarousel()
-
- return (
- (
)
- );
-})
-CarouselItem.displayName = "CarouselItem"
-
-const CarouselPrevious = React.forwardRef(({ className, variant = "outline", size = "icon", ...props }, ref) => {
- const { orientation, scrollPrev, canScrollPrev } = useCarousel()
-
- return (
- (
-
- Previous slide
- )
- );
-})
-CarouselPrevious.displayName = "CarouselPrevious"
-
-const CarouselNext = React.forwardRef(({ className, variant = "outline", size = "icon", ...props }, ref) => {
- const { orientation, scrollNext, canScrollNext } = useCarousel()
-
- return (
- (
-
- Next slide
- )
- );
-})
-CarouselNext.displayName = "CarouselNext"
-
-export { Carousel, CarouselContent, CarouselItem, CarouselPrevious, CarouselNext };
diff --git a/src/components/ui/chart.jsx b/src/components/ui/chart.jsx
deleted file mode 100644
index bcef106..0000000
--- a/src/components/ui/chart.jsx
+++ /dev/null
@@ -1,309 +0,0 @@
-"use client";
-import * as React from "react"
-import * as RechartsPrimitive from "recharts"
-
-import { cn } from "@/lib/utils"
-
-// Format: { THEME_NAME: CSS_SELECTOR }
-const THEMES = {
- light: "",
- dark: ".dark"
-}
-
-const ChartContext = React.createContext(null)
-
-function useChart() {
- const context = React.useContext(ChartContext)
-
- if (!context) {
- throw new Error("useChart must be used within a ")
- }
-
- return context
-}
-
-const ChartContainer = React.forwardRef(({ id, className, children, config, ...props }, ref) => {
- const uniqueId = React.useId()
- const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`
-
- return (
- (
-
-
-
- {children}
-
-
- )
- );
-})
-ChartContainer.displayName = "Chart"
-
-const ChartStyle = ({
- id,
- config
-}) => {
- const colorConfig = Object.entries(config).filter(([, config]) => config.theme || config.color)
-
- if (!colorConfig.length) {
- return null
- }
-
- return (
- (