diff --git a/app/globals.css b/app/globals.css
index b0e6fff..8abdb15 100644
--- a/app/globals.css
+++ b/app/globals.css
@@ -1,76 +1,76 @@
@tailwind base;
- @tailwind components;
- @tailwind utilities;
+@tailwind components;
+@tailwind utilities;
- @layer base {
- :root {
- --background: 0 0% 100%;
- --foreground: 222.2 84% 4.9%;
+@layer base {
+ :root {
+ --background: 0 0% 100%;
+ --foreground: 222.2 84% 4.9%;
- --card: 0 0% 100%;
- --card-foreground: 222.2 84% 4.9%;
+ --card: 0 0% 100%;
+ --card-foreground: 222.2 84% 4.9%;
- --popover: 0 0% 100%;
- --popover-foreground: 222.2 84% 4.9%;
+ --popover: 0 0% 100%;
+ --popover-foreground: 222.2 84% 4.9%;
- --primary: 222.2 47.4% 11.2%;
- --primary-foreground: 210 40% 98%;
+ --primary: 222.2 47.4% 11.2%;
+ --primary-foreground: 210 40% 98%;
- --secondary: 210 40% 96.1%;
- --secondary-foreground: 222.2 47.4% 11.2%;
+ --secondary: 210 40% 96.1%;
+ --secondary-foreground: 222.2 47.4% 11.2%;
- --muted: 210 40% 96.1%;
- --muted-foreground: 215.4 16.3% 46.9%;
+ --muted: 210 40% 96.1%;
+ --muted-foreground: 215.4 16.3% 46.9%;
- --accent: 210 40% 96.1%;
- --accent-foreground: 222.2 47.4% 11.2%;
+ --accent: 210 40% 96.1%;
+ --accent-foreground: 222.2 47.4% 11.2%;
- --destructive: 0 84.2% 60.2%;
- --destructive-foreground: 210 40% 98%;
+ --destructive: 0 84.2% 60.2%;
+ --destructive-foreground: 210 40% 98%;
- --border: 214.3 31.8% 91.4%;
- --input: 214.3 31.8% 91.4%;
- --ring: 222.2 84% 4.9%;
+ --border: 214.3 31.8% 91.4%;
+ --input: 214.3 31.8% 91.4%;
+ --ring: 222.2 84% 4.9%;
- --radius: 0.5rem;
- }
+ --radius: 0.5rem;
+ }
- .dark {
- --background: 222.2 84% 4.9%;
- --foreground: 210 40% 98%;
+ .dark {
+ --background: 222.2 84% 4.9%;
+ --foreground: 210 40% 98%;
- --card: 222.2 84% 4.9%;
- --card-foreground: 210 40% 98%;
+ --card: 222.2 84% 4.9%;
+ --card-foreground: 210 40% 98%;
- --popover: 222.2 84% 4.9%;
- --popover-foreground: 210 40% 98%;
+ --popover: 222.2 84% 4.9%;
+ --popover-foreground: 210 40% 98%;
- --primary: 210 40% 98%;
- --primary-foreground: 222.2 47.4% 11.2%;
+ --primary: 210 40% 98%;
+ --primary-foreground: 222.2 47.4% 11.2%;
- --secondary: 217.2 32.6% 17.5%;
- --secondary-foreground: 210 40% 98%;
+ --secondary: 217.2 32.6% 17.5%;
+ --secondary-foreground: 210 40% 98%;
- --muted: 217.2 32.6% 17.5%;
- --muted-foreground: 215 20.2% 65.1%;
+ --muted: 217.2 32.6% 17.5%;
+ --muted-foreground: 215 20.2% 65.1%;
- --accent: 217.2 32.6% 17.5%;
- --accent-foreground: 210 40% 98%;
+ --accent: 217.2 32.6% 17.5%;
+ --accent-foreground: 210 40% 98%;
- --destructive: 0 62.8% 30.6%;
- --destructive-foreground: 210 40% 98%;
+ --destructive: 0 62.8% 30.6%;
+ --destructive-foreground: 210 40% 98%;
- --border: 217.2 32.6% 17.5%;
- --input: 217.2 32.6% 17.5%;
- --ring: 212.7 26.8% 83.9%;
- }
+ --border: 217.2 32.6% 17.5%;
+ --input: 217.2 32.6% 17.5%;
+ --ring: 212.7 26.8% 83.9%;
}
+}
- @layer base {
- * {
- @apply border-border;
- }
- body {
- @apply bg-background text-foreground;
- }
- }
\ No newline at end of file
+@layer base {
+ * {
+ @apply border-border;
+ }
+ body {
+ @apply bg-background text-foreground;
+ }
+}
diff --git a/components.json b/components.json
index 811d2db..08837cd 100644
--- a/components.json
+++ b/components.json
@@ -1,7 +1,7 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "default",
- "rsc": true,
+ "rsc": false,
"tsx": true,
"tailwind": {
"config": "tailwind.config.js",
@@ -14,4 +14,4 @@
"components": "@/components",
"utils": "@/lib/utils"
}
-}
\ No newline at end of file
+}
diff --git a/index.html b/index.html
index 6e6f25c..23b0d5a 100644
--- a/index.html
+++ b/index.html
@@ -5,6 +5,7 @@
+
Vite + React + TS
diff --git a/package.json b/package.json
index bb0baaa..ab4b43c 100644
--- a/package.json
+++ b/package.json
@@ -12,18 +12,56 @@
"prepare": "husky"
},
"dependencies": {
+ "@hookform/resolvers": "3.4.2",
+ "@radix-ui/react-accordion": "1.1.2",
+ "@radix-ui/react-alert-dialog": "1.0.5",
+ "@radix-ui/react-aspect-ratio": "1.0.3",
+ "@radix-ui/react-avatar": "1.0.4",
+ "@radix-ui/react-checkbox": "1.0.4",
+ "@radix-ui/react-collapsible": "1.0.3",
+ "@radix-ui/react-context-menu": "2.1.5",
+ "@radix-ui/react-dialog": "1.0.5",
+ "@radix-ui/react-dropdown-menu": "2.0.6",
+ "@radix-ui/react-hover-card": "1.0.7",
+ "@radix-ui/react-label": "2.0.2",
+ "@radix-ui/react-menubar": "1.0.4",
+ "@radix-ui/react-navigation-menu": "1.1.4",
+ "@radix-ui/react-popover": "1.0.7",
+ "@radix-ui/react-progress": "1.0.3",
+ "@radix-ui/react-radio-group": "1.1.3",
+ "@radix-ui/react-scroll-area": "1.0.5",
+ "@radix-ui/react-select": "2.0.0",
+ "@radix-ui/react-separator": "1.0.3",
+ "@radix-ui/react-slider": "1.1.2",
"@radix-ui/react-slot": "1.0.2",
+ "@radix-ui/react-switch": "1.0.3",
+ "@radix-ui/react-tabs": "1.0.4",
+ "@radix-ui/react-toast": "1.1.5",
+ "@radix-ui/react-toggle": "1.0.3",
+ "@radix-ui/react-toggle-group": "1.0.4",
+ "@radix-ui/react-tooltip": "1.0.7",
"autoprefixer": "10.4.19",
"class-variance-authority": "0.7.0",
"clsx": "2.1.1",
+ "cmdk": "1.0.0",
+ "date-fns": "3.6.0",
+ "embla-carousel-react": "8.1.3",
"husky": "9.0.11",
+ "input-otp": "1.2.4",
"lucide-react": "0.381.0",
+ "next-themes": "0.3.0",
"prettier": "3.2.5",
"react": "^18.2.0",
+ "react-day-picker": "8.10.1",
"react-dom": "^18.2.0",
+ "react-hook-form": "7.51.5",
+ "react-resizable-panels": "2.0.19",
+ "sonner": "1.4.41",
"tailwind-merge": "2.3.0",
"tailwindcss": "3.4.3",
- "tailwindcss-animate": "1.0.7"
+ "tailwindcss-animate": "1.0.7",
+ "vaul": "0.9.1",
+ "zod": "3.23.8"
},
"devDependencies": {
"@commitlint/cli": "19.3.0",
@@ -37,6 +75,7 @@
"eslint": "^8.57.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.6",
+ "postcss": "8.4.38",
"typescript": "^5.2.2",
"vite": "^5.2.0"
}
diff --git a/src/App.tsx b/src/App.tsx
index f1f7506..0169207 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,11 +1,11 @@
-import { Button } from "@/components/ui/button";
+import { Home } from "@/pages/Home";
import "./App.css";
function App() {
return (
<>
-
+
>
);
diff --git a/src/components/atoms/InputWithButton.tsx b/src/components/atoms/InputWithButton.tsx
new file mode 100644
index 0000000..f436d0e
--- /dev/null
+++ b/src/components/atoms/InputWithButton.tsx
@@ -0,0 +1,20 @@
+import { Button } from "@/components/ui/button";
+import { Input } from "@/components/ui/input";
+
+import { TEXT } from "@/constants";
+import "./index.css";
+
+export function InputWithButton() {
+ return (
+
+
+
+
+ );
+}
diff --git a/src/components/atoms/index.css b/src/components/atoms/index.css
new file mode 100644
index 0000000..d796083
--- /dev/null
+++ b/src/components/atoms/index.css
@@ -0,0 +1,5 @@
+.fact-input {
+ width: 1000px;
+}
+.fact-button {
+}
diff --git a/src/components/ui/accordion.tsx b/src/components/ui/accordion.tsx
new file mode 100644
index 0000000..55685f6
--- /dev/null
+++ b/src/components/ui/accordion.tsx
@@ -0,0 +1,58 @@
+"use client";
+
+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<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+AccordionItem.displayName = "AccordionItem";
+
+const AccordionTrigger = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, ...props }, ref) => (
+
+ svg]:rotate-180",
+ className,
+ )}
+ {...props}
+ >
+ {children}
+
+
+
+));
+AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName;
+
+const AccordionContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, ...props }, ref) => (
+
+ {children}
+
+));
+
+AccordionContent.displayName = AccordionPrimitive.Content.displayName;
+
+export { Accordion, AccordionItem, AccordionTrigger, AccordionContent };
diff --git a/src/components/ui/alert-dialog.tsx b/src/components/ui/alert-dialog.tsx
new file mode 100644
index 0000000..3add93c
--- /dev/null
+++ b/src/components/ui/alert-dialog.tsx
@@ -0,0 +1,141 @@
+"use client";
+
+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<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;
+
+const AlertDialogContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+
+
+
+));
+AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName;
+
+const AlertDialogHeader = ({
+ className,
+ ...props
+}: React.HTMLAttributes) => (
+
+);
+AlertDialogHeader.displayName = "AlertDialogHeader";
+
+const AlertDialogFooter = ({
+ className,
+ ...props
+}: React.HTMLAttributes) => (
+
+);
+AlertDialogFooter.displayName = "AlertDialogFooter";
+
+const AlertDialogTitle = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;
+
+const AlertDialogDescription = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+AlertDialogDescription.displayName =
+ AlertDialogPrimitive.Description.displayName;
+
+const AlertDialogAction = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName;
+
+const AlertDialogCancel = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ 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.tsx b/src/components/ui/alert.tsx
new file mode 100644
index 0000000..13219e7
--- /dev/null
+++ b/src/components/ui/alert.tsx
@@ -0,0 +1,59 @@
+import * as React from "react";
+import { cva, type VariantProps } from "class-variance-authority";
+
+import { cn } from "@/lib/utils";
+
+const alertVariants = cva(
+ "relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground",
+ {
+ 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<
+ HTMLDivElement,
+ React.HTMLAttributes & VariantProps
+>(({ className, variant, ...props }, ref) => (
+
+));
+Alert.displayName = "Alert";
+
+const AlertTitle = React.forwardRef<
+ HTMLParagraphElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+));
+AlertTitle.displayName = "AlertTitle";
+
+const AlertDescription = React.forwardRef<
+ HTMLParagraphElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+));
+AlertDescription.displayName = "AlertDescription";
+
+export { Alert, AlertTitle, AlertDescription };
diff --git a/src/components/ui/aspect-ratio.tsx b/src/components/ui/aspect-ratio.tsx
new file mode 100644
index 0000000..359bc94
--- /dev/null
+++ b/src/components/ui/aspect-ratio.tsx
@@ -0,0 +1,7 @@
+"use client";
+
+import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio";
+
+const AspectRatio = AspectRatioPrimitive.Root;
+
+export { AspectRatio };
diff --git a/src/components/ui/avatar.tsx b/src/components/ui/avatar.tsx
new file mode 100644
index 0000000..09cd14d
--- /dev/null
+++ b/src/components/ui/avatar.tsx
@@ -0,0 +1,50 @@
+"use client";
+
+import * as React from "react";
+import * as AvatarPrimitive from "@radix-ui/react-avatar";
+
+import { cn } from "@/lib/utils";
+
+const Avatar = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+Avatar.displayName = AvatarPrimitive.Root.displayName;
+
+const AvatarImage = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+AvatarImage.displayName = AvatarPrimitive.Image.displayName;
+
+const AvatarFallback = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
+
+export { Avatar, AvatarImage, AvatarFallback };
diff --git a/src/components/ui/badge.tsx b/src/components/ui/badge.tsx
new file mode 100644
index 0000000..d3d5d60
--- /dev/null
+++ b/src/components/ui/badge.tsx
@@ -0,0 +1,36 @@
+import * as React from "react";
+import { cva, type VariantProps } from "class-variance-authority";
+
+import { cn } from "@/lib/utils";
+
+const badgeVariants = cva(
+ "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
+ {
+ variants: {
+ variant: {
+ default:
+ "border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
+ secondary:
+ "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
+ destructive:
+ "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
+ outline: "text-foreground",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ },
+ },
+);
+
+export interface BadgeProps
+ extends React.HTMLAttributes,
+ VariantProps {}
+
+function Badge({ className, variant, ...props }: BadgeProps) {
+ return (
+
+ );
+}
+
+export { Badge, badgeVariants };
diff --git a/src/components/ui/breadcrumb.tsx b/src/components/ui/breadcrumb.tsx
new file mode 100644
index 0000000..6934f83
--- /dev/null
+++ b/src/components/ui/breadcrumb.tsx
@@ -0,0 +1,115 @@
+import * as React from "react";
+import { Slot } from "@radix-ui/react-slot";
+import { ChevronRight, MoreHorizontal } from "lucide-react";
+
+import { cn } from "@/lib/utils";
+
+const Breadcrumb = React.forwardRef<
+ HTMLElement,
+ React.ComponentPropsWithoutRef<"nav"> & {
+ separator?: React.ReactNode;
+ }
+>(({ ...props }, ref) => );
+Breadcrumb.displayName = "Breadcrumb";
+
+const BreadcrumbList = React.forwardRef<
+ HTMLOListElement,
+ React.ComponentPropsWithoutRef<"ol">
+>(({ className, ...props }, ref) => (
+
+));
+BreadcrumbList.displayName = "BreadcrumbList";
+
+const BreadcrumbItem = React.forwardRef<
+ HTMLLIElement,
+ React.ComponentPropsWithoutRef<"li">
+>(({ className, ...props }, ref) => (
+
+));
+BreadcrumbItem.displayName = "BreadcrumbItem";
+
+const BreadcrumbLink = React.forwardRef<
+ HTMLAnchorElement,
+ React.ComponentPropsWithoutRef<"a"> & {
+ asChild?: boolean;
+ }
+>(({ asChild, className, ...props }, ref) => {
+ const Comp = asChild ? Slot : "a";
+
+ return (
+
+ );
+});
+BreadcrumbLink.displayName = "BreadcrumbLink";
+
+const BreadcrumbPage = React.forwardRef<
+ HTMLSpanElement,
+ React.ComponentPropsWithoutRef<"span">
+>(({ className, ...props }, ref) => (
+
+));
+BreadcrumbPage.displayName = "BreadcrumbPage";
+
+const BreadcrumbSeparator = ({
+ children,
+ className,
+ ...props
+}: React.ComponentProps<"li">) => (
+ svg]:size-3.5", className)}
+ {...props}
+ >
+ {children ?? }
+
+);
+BreadcrumbSeparator.displayName = "BreadcrumbSeparator";
+
+const BreadcrumbEllipsis = ({
+ className,
+ ...props
+}: React.ComponentProps<"span">) => (
+
+
+ More
+
+);
+BreadcrumbEllipsis.displayName = "BreadcrumbElipssis";
+
+export {
+ Breadcrumb,
+ BreadcrumbList,
+ BreadcrumbItem,
+ BreadcrumbLink,
+ BreadcrumbPage,
+ BreadcrumbSeparator,
+ BreadcrumbEllipsis,
+};
diff --git a/src/components/ui/card.tsx b/src/components/ui/card.tsx
new file mode 100644
index 0000000..dc3b01d
--- /dev/null
+++ b/src/components/ui/card.tsx
@@ -0,0 +1,86 @@
+import * as React from "react";
+
+import { cn } from "@/lib/utils";
+
+const Card = React.forwardRef<
+ HTMLDivElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+));
+Card.displayName = "Card";
+
+const CardHeader = React.forwardRef<
+ HTMLDivElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+));
+CardHeader.displayName = "CardHeader";
+
+const CardTitle = React.forwardRef<
+ HTMLParagraphElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+));
+CardTitle.displayName = "CardTitle";
+
+const CardDescription = React.forwardRef<
+ HTMLParagraphElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+));
+CardDescription.displayName = "CardDescription";
+
+const CardContent = React.forwardRef<
+ HTMLDivElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+));
+CardContent.displayName = "CardContent";
+
+const CardFooter = React.forwardRef<
+ HTMLDivElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+));
+CardFooter.displayName = "CardFooter";
+
+export {
+ Card,
+ CardHeader,
+ CardFooter,
+ CardTitle,
+ CardDescription,
+ CardContent,
+};
diff --git a/src/components/ui/carousel.tsx b/src/components/ui/carousel.tsx
new file mode 100644
index 0000000..bbfa730
--- /dev/null
+++ b/src/components/ui/carousel.tsx
@@ -0,0 +1,262 @@
+"use client";
+
+import * as React from "react";
+import useEmblaCarousel, {
+ type UseEmblaCarouselType,
+} from "embla-carousel-react";
+import { ArrowLeft, ArrowRight } from "lucide-react";
+
+import { cn } from "@/lib/utils";
+import { Button } from "@/components/ui/button";
+
+type CarouselApi = UseEmblaCarouselType[1];
+type UseCarouselParameters = Parameters;
+type CarouselOptions = UseCarouselParameters[0];
+type CarouselPlugin = UseCarouselParameters[1];
+
+type CarouselProps = {
+ opts?: CarouselOptions;
+ plugins?: CarouselPlugin;
+ orientation?: "horizontal" | "vertical";
+ setApi?: (api: CarouselApi) => void;
+};
+
+type CarouselContextProps = {
+ carouselRef: ReturnType[0];
+ api: ReturnType[1];
+ scrollPrev: () => void;
+ scrollNext: () => void;
+ canScrollPrev: boolean;
+ canScrollNext: boolean;
+} & CarouselProps;
+
+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<
+ HTMLDivElement,
+ React.HTMLAttributes & CarouselProps
+>(
+ (
+ {
+ 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: CarouselApi) => {
+ 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: React.KeyboardEvent) => {
+ 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<
+ HTMLDivElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => {
+ const { carouselRef, orientation } = useCarousel();
+
+ return (
+
+ );
+});
+CarouselContent.displayName = "CarouselContent";
+
+const CarouselItem = React.forwardRef<
+ HTMLDivElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => {
+ const { orientation } = useCarousel();
+
+ return (
+
+ );
+});
+CarouselItem.displayName = "CarouselItem";
+
+const CarouselPrevious = React.forwardRef<
+ HTMLButtonElement,
+ React.ComponentProps
+>(({ className, variant = "outline", size = "icon", ...props }, ref) => {
+ const { orientation, scrollPrev, canScrollPrev } = useCarousel();
+
+ return (
+
+ );
+});
+CarouselPrevious.displayName = "CarouselPrevious";
+
+const CarouselNext = React.forwardRef<
+ HTMLButtonElement,
+ React.ComponentProps
+>(({ className, variant = "outline", size = "icon", ...props }, ref) => {
+ const { orientation, scrollNext, canScrollNext } = useCarousel();
+
+ return (
+
+ );
+});
+CarouselNext.displayName = "CarouselNext";
+
+export {
+ type CarouselApi,
+ Carousel,
+ CarouselContent,
+ CarouselItem,
+ CarouselPrevious,
+ CarouselNext,
+};
diff --git a/src/components/ui/checkbox.tsx b/src/components/ui/checkbox.tsx
new file mode 100644
index 0000000..5985e3c
--- /dev/null
+++ b/src/components/ui/checkbox.tsx
@@ -0,0 +1,30 @@
+"use client";
+
+import * as React from "react";
+import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
+import { Check } from "lucide-react";
+
+import { cn } from "@/lib/utils";
+
+const Checkbox = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+
+
+
+
+));
+Checkbox.displayName = CheckboxPrimitive.Root.displayName;
+
+export { Checkbox };
diff --git a/src/components/ui/collapsible.tsx b/src/components/ui/collapsible.tsx
new file mode 100644
index 0000000..cb003d1
--- /dev/null
+++ b/src/components/ui/collapsible.tsx
@@ -0,0 +1,11 @@
+"use client";
+
+import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
+
+const Collapsible = CollapsiblePrimitive.Root;
+
+const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger;
+
+const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent;
+
+export { Collapsible, CollapsibleTrigger, CollapsibleContent };
diff --git a/src/components/ui/command.tsx b/src/components/ui/command.tsx
new file mode 100644
index 0000000..d63373a
--- /dev/null
+++ b/src/components/ui/command.tsx
@@ -0,0 +1,155 @@
+"use client";
+
+import * as React from "react";
+import { type DialogProps } from "@radix-ui/react-dialog";
+import { Command as CommandPrimitive } from "cmdk";
+import { Search } from "lucide-react";
+
+import { cn } from "@/lib/utils";
+import { Dialog, DialogContent } from "@/components/ui/dialog";
+
+const Command = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+Command.displayName = CommandPrimitive.displayName;
+
+interface CommandDialogProps extends DialogProps {}
+
+const CommandDialog = ({ children, ...props }: CommandDialogProps) => {
+ return (
+
+ );
+};
+
+const CommandInput = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+
+
+
+));
+
+CommandInput.displayName = CommandPrimitive.Input.displayName;
+
+const CommandList = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+
+CommandList.displayName = CommandPrimitive.List.displayName;
+
+const CommandEmpty = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>((props, ref) => (
+
+));
+
+CommandEmpty.displayName = CommandPrimitive.Empty.displayName;
+
+const CommandGroup = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+
+CommandGroup.displayName = CommandPrimitive.Group.displayName;
+
+const CommandSeparator = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+CommandSeparator.displayName = CommandPrimitive.Separator.displayName;
+
+const CommandItem = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+
+CommandItem.displayName = CommandPrimitive.Item.displayName;
+
+const CommandShortcut = ({
+ className,
+ ...props
+}: React.HTMLAttributes) => {
+ return (
+
+ );
+};
+CommandShortcut.displayName = "CommandShortcut";
+
+export {
+ Command,
+ CommandDialog,
+ CommandInput,
+ CommandList,
+ CommandEmpty,
+ CommandGroup,
+ CommandItem,
+ CommandShortcut,
+ CommandSeparator,
+};
diff --git a/src/components/ui/context-menu.tsx b/src/components/ui/context-menu.tsx
new file mode 100644
index 0000000..7408e3f
--- /dev/null
+++ b/src/components/ui/context-menu.tsx
@@ -0,0 +1,200 @@
+"use client";
+
+import * as React from "react";
+import * as ContextMenuPrimitive from "@radix-ui/react-context-menu";
+import { Check, ChevronRight, Circle } from "lucide-react";
+
+import { cn } from "@/lib/utils";
+
+const ContextMenu = ContextMenuPrimitive.Root;
+
+const ContextMenuTrigger = ContextMenuPrimitive.Trigger;
+
+const ContextMenuGroup = ContextMenuPrimitive.Group;
+
+const ContextMenuPortal = ContextMenuPrimitive.Portal;
+
+const ContextMenuSub = ContextMenuPrimitive.Sub;
+
+const ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup;
+
+const ContextMenuSubTrigger = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef & {
+ inset?: boolean;
+ }
+>(({ className, inset, children, ...props }, ref) => (
+
+ {children}
+
+
+));
+ContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName;
+
+const ContextMenuSubContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+ContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName;
+
+const ContextMenuContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+
+
+));
+ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName;
+
+const ContextMenuItem = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef & {
+ inset?: boolean;
+ }
+>(({ className, inset, ...props }, ref) => (
+
+));
+ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName;
+
+const ContextMenuCheckboxItem = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, checked, ...props }, ref) => (
+
+
+
+
+
+
+ {children}
+
+));
+ContextMenuCheckboxItem.displayName =
+ ContextMenuPrimitive.CheckboxItem.displayName;
+
+const ContextMenuRadioItem = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, ...props }, ref) => (
+
+
+
+
+
+
+ {children}
+
+));
+ContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName;
+
+const ContextMenuLabel = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef & {
+ inset?: boolean;
+ }
+>(({ className, inset, ...props }, ref) => (
+
+));
+ContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName;
+
+const ContextMenuSeparator = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName;
+
+const ContextMenuShortcut = ({
+ className,
+ ...props
+}: React.HTMLAttributes) => {
+ return (
+
+ );
+};
+ContextMenuShortcut.displayName = "ContextMenuShortcut";
+
+export {
+ ContextMenu,
+ ContextMenuTrigger,
+ ContextMenuContent,
+ ContextMenuItem,
+ ContextMenuCheckboxItem,
+ ContextMenuRadioItem,
+ ContextMenuLabel,
+ ContextMenuSeparator,
+ ContextMenuShortcut,
+ ContextMenuGroup,
+ ContextMenuPortal,
+ ContextMenuSub,
+ ContextMenuSubContent,
+ ContextMenuSubTrigger,
+ ContextMenuRadioGroup,
+};
diff --git a/src/components/ui/dialog.tsx b/src/components/ui/dialog.tsx
new file mode 100644
index 0000000..e72c2b5
--- /dev/null
+++ b/src/components/ui/dialog.tsx
@@ -0,0 +1,122 @@
+"use client";
+
+import * as React from "react";
+import * as DialogPrimitive from "@radix-ui/react-dialog";
+import { X } from "lucide-react";
+
+import { cn } from "@/lib/utils";
+
+const Dialog = DialogPrimitive.Root;
+
+const DialogTrigger = DialogPrimitive.Trigger;
+
+const DialogPortal = DialogPrimitive.Portal;
+
+const DialogClose = DialogPrimitive.Close;
+
+const DialogOverlay = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
+
+const DialogContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, ...props }, ref) => (
+
+
+
+ {children}
+
+
+ Close
+
+
+
+));
+DialogContent.displayName = DialogPrimitive.Content.displayName;
+
+const DialogHeader = ({
+ className,
+ ...props
+}: React.HTMLAttributes) => (
+
+);
+DialogHeader.displayName = "DialogHeader";
+
+const DialogFooter = ({
+ className,
+ ...props
+}: React.HTMLAttributes) => (
+
+);
+DialogFooter.displayName = "DialogFooter";
+
+const DialogTitle = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+DialogTitle.displayName = DialogPrimitive.Title.displayName;
+
+const DialogDescription = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+DialogDescription.displayName = DialogPrimitive.Description.displayName;
+
+export {
+ Dialog,
+ DialogPortal,
+ DialogOverlay,
+ DialogClose,
+ DialogTrigger,
+ DialogContent,
+ DialogHeader,
+ DialogFooter,
+ DialogTitle,
+ DialogDescription,
+};
diff --git a/src/components/ui/drawer.tsx b/src/components/ui/drawer.tsx
new file mode 100644
index 0000000..350f8b6
--- /dev/null
+++ b/src/components/ui/drawer.tsx
@@ -0,0 +1,118 @@
+"use client";
+
+import * as React from "react";
+import { Drawer as DrawerPrimitive } from "vaul";
+
+import { cn } from "@/lib/utils";
+
+const Drawer = ({
+ shouldScaleBackground = true,
+ ...props
+}: React.ComponentProps) => (
+
+);
+Drawer.displayName = "Drawer";
+
+const DrawerTrigger = DrawerPrimitive.Trigger;
+
+const DrawerPortal = DrawerPrimitive.Portal;
+
+const DrawerClose = DrawerPrimitive.Close;
+
+const DrawerOverlay = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+DrawerOverlay.displayName = DrawerPrimitive.Overlay.displayName;
+
+const DrawerContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, ...props }, ref) => (
+
+
+
+
+ {children}
+
+
+));
+DrawerContent.displayName = "DrawerContent";
+
+const DrawerHeader = ({
+ className,
+ ...props
+}: React.HTMLAttributes) => (
+
+);
+DrawerHeader.displayName = "DrawerHeader";
+
+const DrawerFooter = ({
+ className,
+ ...props
+}: React.HTMLAttributes) => (
+
+);
+DrawerFooter.displayName = "DrawerFooter";
+
+const DrawerTitle = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+DrawerTitle.displayName = DrawerPrimitive.Title.displayName;
+
+const DrawerDescription = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+DrawerDescription.displayName = DrawerPrimitive.Description.displayName;
+
+export {
+ Drawer,
+ DrawerPortal,
+ DrawerOverlay,
+ DrawerTrigger,
+ DrawerClose,
+ DrawerContent,
+ DrawerHeader,
+ DrawerFooter,
+ DrawerTitle,
+ DrawerDescription,
+};
diff --git a/src/components/ui/dropdown-menu.tsx b/src/components/ui/dropdown-menu.tsx
new file mode 100644
index 0000000..3a0c7fe
--- /dev/null
+++ b/src/components/ui/dropdown-menu.tsx
@@ -0,0 +1,200 @@
+"use client";
+
+import * as React from "react";
+import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
+import { Check, ChevronRight, Circle } from "lucide-react";
+
+import { cn } from "@/lib/utils";
+
+const DropdownMenu = DropdownMenuPrimitive.Root;
+
+const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
+
+const DropdownMenuGroup = DropdownMenuPrimitive.Group;
+
+const DropdownMenuPortal = DropdownMenuPrimitive.Portal;
+
+const DropdownMenuSub = DropdownMenuPrimitive.Sub;
+
+const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
+
+const DropdownMenuSubTrigger = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef & {
+ inset?: boolean;
+ }
+>(({ className, inset, children, ...props }, ref) => (
+
+ {children}
+
+
+));
+DropdownMenuSubTrigger.displayName =
+ DropdownMenuPrimitive.SubTrigger.displayName;
+
+const DropdownMenuSubContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+DropdownMenuSubContent.displayName =
+ DropdownMenuPrimitive.SubContent.displayName;
+
+const DropdownMenuContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, sideOffset = 4, ...props }, ref) => (
+
+
+
+));
+DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
+
+const DropdownMenuItem = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef & {
+ inset?: boolean;
+ }
+>(({ className, inset, ...props }, ref) => (
+
+));
+DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
+
+const DropdownMenuCheckboxItem = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, checked, ...props }, ref) => (
+
+
+
+
+
+
+ {children}
+
+));
+DropdownMenuCheckboxItem.displayName =
+ DropdownMenuPrimitive.CheckboxItem.displayName;
+
+const DropdownMenuRadioItem = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, ...props }, ref) => (
+
+
+
+
+
+
+ {children}
+
+));
+DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
+
+const DropdownMenuLabel = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef & {
+ inset?: boolean;
+ }
+>(({ className, inset, ...props }, ref) => (
+
+));
+DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
+
+const DropdownMenuSeparator = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
+
+const DropdownMenuShortcut = ({
+ className,
+ ...props
+}: React.HTMLAttributes) => {
+ return (
+
+ );
+};
+DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
+
+export {
+ DropdownMenu,
+ DropdownMenuTrigger,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuCheckboxItem,
+ DropdownMenuRadioItem,
+ DropdownMenuLabel,
+ DropdownMenuSeparator,
+ DropdownMenuShortcut,
+ DropdownMenuGroup,
+ DropdownMenuPortal,
+ DropdownMenuSub,
+ DropdownMenuSubContent,
+ DropdownMenuSubTrigger,
+ DropdownMenuRadioGroup,
+};
diff --git a/src/components/ui/form.tsx b/src/components/ui/form.tsx
new file mode 100644
index 0000000..497718a
--- /dev/null
+++ b/src/components/ui/form.tsx
@@ -0,0 +1,177 @@
+import * as React from "react";
+import * as LabelPrimitive from "@radix-ui/react-label";
+import { Slot } from "@radix-ui/react-slot";
+import {
+ Controller,
+ ControllerProps,
+ FieldPath,
+ FieldValues,
+ FormProvider,
+ useFormContext,
+} from "react-hook-form";
+
+import { cn } from "@/lib/utils";
+import { Label } from "@/components/ui/label";
+
+const Form = FormProvider;
+
+type FormFieldContextValue<
+ TFieldValues extends FieldValues = FieldValues,
+ TName extends FieldPath = FieldPath,
+> = {
+ name: TName;
+};
+
+const FormFieldContext = React.createContext(
+ {} as FormFieldContextValue,
+);
+
+const FormField = <
+ TFieldValues extends FieldValues = FieldValues,
+ TName extends FieldPath = FieldPath,
+>({
+ ...props
+}: ControllerProps) => {
+ return (
+
+
+
+ );
+};
+
+const useFormField = () => {
+ const fieldContext = React.useContext(FormFieldContext);
+ const itemContext = React.useContext(FormItemContext);
+ const { getFieldState, formState } = useFormContext();
+
+ const fieldState = getFieldState(fieldContext.name, formState);
+
+ if (!fieldContext) {
+ throw new Error("useFormField should be used within ");
+ }
+
+ const { id } = itemContext;
+
+ return {
+ id,
+ name: fieldContext.name,
+ formItemId: `${id}-form-item`,
+ formDescriptionId: `${id}-form-item-description`,
+ formMessageId: `${id}-form-item-message`,
+ ...fieldState,
+ };
+};
+
+type FormItemContextValue = {
+ id: string;
+};
+
+const FormItemContext = React.createContext(
+ {} as FormItemContextValue,
+);
+
+const FormItem = React.forwardRef<
+ HTMLDivElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => {
+ const id = React.useId();
+
+ return (
+
+
+
+ );
+});
+FormItem.displayName = "FormItem";
+
+const FormLabel = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => {
+ const { error, formItemId } = useFormField();
+
+ return (
+
+ );
+});
+FormLabel.displayName = "FormLabel";
+
+const FormControl = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ ...props }, ref) => {
+ const { error, formItemId, formDescriptionId, formMessageId } =
+ useFormField();
+
+ return (
+
+ );
+});
+FormControl.displayName = "FormControl";
+
+const FormDescription = React.forwardRef<
+ HTMLParagraphElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => {
+ const { formDescriptionId } = useFormField();
+
+ return (
+
+ );
+});
+FormDescription.displayName = "FormDescription";
+
+const FormMessage = React.forwardRef<
+ HTMLParagraphElement,
+ React.HTMLAttributes
+>(({ className, children, ...props }, ref) => {
+ const { error, formMessageId } = useFormField();
+ const body = error ? String(error?.message) : children;
+
+ if (!body) {
+ return null;
+ }
+
+ return (
+
+ {body}
+
+ );
+});
+FormMessage.displayName = "FormMessage";
+
+export {
+ useFormField,
+ Form,
+ FormItem,
+ FormLabel,
+ FormControl,
+ FormDescription,
+ FormMessage,
+ FormField,
+};
diff --git a/src/components/ui/hover-card.tsx b/src/components/ui/hover-card.tsx
new file mode 100644
index 0000000..9e8c62d
--- /dev/null
+++ b/src/components/ui/hover-card.tsx
@@ -0,0 +1,29 @@
+"use client";
+
+import * as React from "react";
+import * as HoverCardPrimitive from "@radix-ui/react-hover-card";
+
+import { cn } from "@/lib/utils";
+
+const HoverCard = HoverCardPrimitive.Root;
+
+const HoverCardTrigger = HoverCardPrimitive.Trigger;
+
+const HoverCardContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
+
+));
+HoverCardContent.displayName = HoverCardPrimitive.Content.displayName;
+
+export { HoverCard, HoverCardTrigger, HoverCardContent };
diff --git a/src/components/ui/index.tsx b/src/components/ui/index.tsx
new file mode 100644
index 0000000..b7bbee2
--- /dev/null
+++ b/src/components/ui/index.tsx
@@ -0,0 +1,2 @@
+export * from "./button";
+export * from "./input";
diff --git a/src/components/ui/input-otp.tsx b/src/components/ui/input-otp.tsx
new file mode 100644
index 0000000..4609653
--- /dev/null
+++ b/src/components/ui/input-otp.tsx
@@ -0,0 +1,71 @@
+"use client";
+
+import * as React from "react";
+import { OTPInput, OTPInputContext } from "input-otp";
+import { Dot } from "lucide-react";
+
+import { cn } from "@/lib/utils";
+
+const InputOTP = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, containerClassName, ...props }, ref) => (
+
+));
+InputOTP.displayName = "InputOTP";
+
+const InputOTPGroup = React.forwardRef<
+ React.ElementRef<"div">,
+ React.ComponentPropsWithoutRef<"div">
+>(({ className, ...props }, ref) => (
+
+));
+InputOTPGroup.displayName = "InputOTPGroup";
+
+const InputOTPSlot = React.forwardRef<
+ React.ElementRef<"div">,
+ React.ComponentPropsWithoutRef<"div"> & { index: number }
+>(({ index, className, ...props }, ref) => {
+ const inputOTPContext = React.useContext(OTPInputContext);
+ const { char, hasFakeCaret, isActive } = inputOTPContext.slots[index];
+
+ return (
+
+ {char}
+ {hasFakeCaret && (
+
+ )}
+
+ );
+});
+InputOTPSlot.displayName = "InputOTPSlot";
+
+const InputOTPSeparator = React.forwardRef<
+ React.ElementRef<"div">,
+ React.ComponentPropsWithoutRef<"div">
+>(({ ...props }, ref) => (
+
+
+
+));
+InputOTPSeparator.displayName = "InputOTPSeparator";
+
+export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator };
diff --git a/src/components/ui/input.tsx b/src/components/ui/input.tsx
new file mode 100644
index 0000000..9d631e7
--- /dev/null
+++ b/src/components/ui/input.tsx
@@ -0,0 +1,25 @@
+import * as React from "react";
+
+import { cn } from "@/lib/utils";
+
+export interface InputProps
+ extends React.InputHTMLAttributes {}
+
+const Input = React.forwardRef(
+ ({ className, type, ...props }, ref) => {
+ return (
+
+ );
+ },
+);
+Input.displayName = "Input";
+
+export { Input };
diff --git a/src/components/ui/label.tsx b/src/components/ui/label.tsx
new file mode 100644
index 0000000..84f8b0c
--- /dev/null
+++ b/src/components/ui/label.tsx
@@ -0,0 +1,26 @@
+"use client";
+
+import * as React from "react";
+import * as LabelPrimitive from "@radix-ui/react-label";
+import { cva, type VariantProps } from "class-variance-authority";
+
+import { cn } from "@/lib/utils";
+
+const labelVariants = cva(
+ "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
+);
+
+const Label = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef &
+ VariantProps
+>(({ className, ...props }, ref) => (
+
+));
+Label.displayName = LabelPrimitive.Root.displayName;
+
+export { Label };
diff --git a/src/components/ui/menubar.tsx b/src/components/ui/menubar.tsx
new file mode 100644
index 0000000..843ef7b
--- /dev/null
+++ b/src/components/ui/menubar.tsx
@@ -0,0 +1,236 @@
+"use client";
+
+import * as React from "react";
+import * as MenubarPrimitive from "@radix-ui/react-menubar";
+import { Check, ChevronRight, Circle } from "lucide-react";
+
+import { cn } from "@/lib/utils";
+
+const MenubarMenu = MenubarPrimitive.Menu;
+
+const MenubarGroup = MenubarPrimitive.Group;
+
+const MenubarPortal = MenubarPrimitive.Portal;
+
+const MenubarSub = MenubarPrimitive.Sub;
+
+const MenubarRadioGroup = MenubarPrimitive.RadioGroup;
+
+const Menubar = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+Menubar.displayName = MenubarPrimitive.Root.displayName;
+
+const MenubarTrigger = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+MenubarTrigger.displayName = MenubarPrimitive.Trigger.displayName;
+
+const MenubarSubTrigger = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef & {
+ inset?: boolean;
+ }
+>(({ className, inset, children, ...props }, ref) => (
+
+ {children}
+
+
+));
+MenubarSubTrigger.displayName = MenubarPrimitive.SubTrigger.displayName;
+
+const MenubarSubContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+MenubarSubContent.displayName = MenubarPrimitive.SubContent.displayName;
+
+const MenubarContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(
+ (
+ { className, align = "start", alignOffset = -4, sideOffset = 8, ...props },
+ ref,
+ ) => (
+
+
+
+ ),
+);
+MenubarContent.displayName = MenubarPrimitive.Content.displayName;
+
+const MenubarItem = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef & {
+ inset?: boolean;
+ }
+>(({ className, inset, ...props }, ref) => (
+
+));
+MenubarItem.displayName = MenubarPrimitive.Item.displayName;
+
+const MenubarCheckboxItem = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, checked, ...props }, ref) => (
+
+
+
+
+
+
+ {children}
+
+));
+MenubarCheckboxItem.displayName = MenubarPrimitive.CheckboxItem.displayName;
+
+const MenubarRadioItem = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, ...props }, ref) => (
+
+
+
+
+
+
+ {children}
+
+));
+MenubarRadioItem.displayName = MenubarPrimitive.RadioItem.displayName;
+
+const MenubarLabel = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef & {
+ inset?: boolean;
+ }
+>(({ className, inset, ...props }, ref) => (
+
+));
+MenubarLabel.displayName = MenubarPrimitive.Label.displayName;
+
+const MenubarSeparator = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+MenubarSeparator.displayName = MenubarPrimitive.Separator.displayName;
+
+const MenubarShortcut = ({
+ className,
+ ...props
+}: React.HTMLAttributes) => {
+ return (
+
+ );
+};
+MenubarShortcut.displayname = "MenubarShortcut";
+
+export {
+ Menubar,
+ MenubarMenu,
+ MenubarTrigger,
+ MenubarContent,
+ MenubarItem,
+ MenubarSeparator,
+ MenubarLabel,
+ MenubarCheckboxItem,
+ MenubarRadioGroup,
+ MenubarRadioItem,
+ MenubarPortal,
+ MenubarSubContent,
+ MenubarSubTrigger,
+ MenubarGroup,
+ MenubarSub,
+ MenubarShortcut,
+};
diff --git a/src/components/ui/navigation-menu.tsx b/src/components/ui/navigation-menu.tsx
new file mode 100644
index 0000000..b709c4d
--- /dev/null
+++ b/src/components/ui/navigation-menu.tsx
@@ -0,0 +1,128 @@
+import * as React from "react";
+import * as NavigationMenuPrimitive from "@radix-ui/react-navigation-menu";
+import { cva } from "class-variance-authority";
+import { ChevronDown } from "lucide-react";
+
+import { cn } from "@/lib/utils";
+
+const NavigationMenu = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, ...props }, ref) => (
+
+ {children}
+
+
+));
+NavigationMenu.displayName = NavigationMenuPrimitive.Root.displayName;
+
+const NavigationMenuList = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName;
+
+const NavigationMenuItem = NavigationMenuPrimitive.Item;
+
+const navigationMenuTriggerStyle = cva(
+ "group inline-flex h-10 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50",
+);
+
+const NavigationMenuTrigger = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, ...props }, ref) => (
+
+ {children}{" "}
+
+
+));
+NavigationMenuTrigger.displayName = NavigationMenuPrimitive.Trigger.displayName;
+
+const NavigationMenuContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+NavigationMenuContent.displayName = NavigationMenuPrimitive.Content.displayName;
+
+const NavigationMenuLink = NavigationMenuPrimitive.Link;
+
+const NavigationMenuViewport = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+
+
+));
+NavigationMenuViewport.displayName =
+ NavigationMenuPrimitive.Viewport.displayName;
+
+const NavigationMenuIndicator = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+
+
+));
+NavigationMenuIndicator.displayName =
+ NavigationMenuPrimitive.Indicator.displayName;
+
+export {
+ navigationMenuTriggerStyle,
+ NavigationMenu,
+ NavigationMenuList,
+ NavigationMenuItem,
+ NavigationMenuContent,
+ NavigationMenuTrigger,
+ NavigationMenuLink,
+ NavigationMenuIndicator,
+ NavigationMenuViewport,
+};
diff --git a/src/components/ui/pagination.tsx b/src/components/ui/pagination.tsx
new file mode 100644
index 0000000..4f6a1cd
--- /dev/null
+++ b/src/components/ui/pagination.tsx
@@ -0,0 +1,117 @@
+import * as React from "react";
+import { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react";
+
+import { cn } from "@/lib/utils";
+import { ButtonProps, buttonVariants } from "@/components/ui/button";
+
+const Pagination = ({ className, ...props }: React.ComponentProps<"nav">) => (
+
+);
+Pagination.displayName = "Pagination";
+
+const PaginationContent = React.forwardRef<
+ HTMLUListElement,
+ React.ComponentProps<"ul">
+>(({ className, ...props }, ref) => (
+
+));
+PaginationContent.displayName = "PaginationContent";
+
+const PaginationItem = React.forwardRef<
+ HTMLLIElement,
+ React.ComponentProps<"li">
+>(({ className, ...props }, ref) => (
+
+));
+PaginationItem.displayName = "PaginationItem";
+
+type PaginationLinkProps = {
+ isActive?: boolean;
+} & Pick &
+ React.ComponentProps<"a">;
+
+const PaginationLink = ({
+ className,
+ isActive,
+ size = "icon",
+ ...props
+}: PaginationLinkProps) => (
+
+);
+PaginationLink.displayName = "PaginationLink";
+
+const PaginationPrevious = ({
+ className,
+ ...props
+}: React.ComponentProps) => (
+
+
+ Previous
+
+);
+PaginationPrevious.displayName = "PaginationPrevious";
+
+const PaginationNext = ({
+ className,
+ ...props
+}: React.ComponentProps) => (
+
+ Next
+
+
+);
+PaginationNext.displayName = "PaginationNext";
+
+const PaginationEllipsis = ({
+ className,
+ ...props
+}: React.ComponentProps<"span">) => (
+
+
+ More pages
+
+);
+PaginationEllipsis.displayName = "PaginationEllipsis";
+
+export {
+ Pagination,
+ PaginationContent,
+ PaginationEllipsis,
+ PaginationItem,
+ PaginationLink,
+ PaginationNext,
+ PaginationPrevious,
+};
diff --git a/src/components/ui/popover.tsx b/src/components/ui/popover.tsx
new file mode 100644
index 0000000..73be7bb
--- /dev/null
+++ b/src/components/ui/popover.tsx
@@ -0,0 +1,31 @@
+"use client";
+
+import * as React from "react";
+import * as PopoverPrimitive from "@radix-ui/react-popover";
+
+import { cn } from "@/lib/utils";
+
+const Popover = PopoverPrimitive.Root;
+
+const PopoverTrigger = PopoverPrimitive.Trigger;
+
+const PopoverContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
+
+
+
+));
+PopoverContent.displayName = PopoverPrimitive.Content.displayName;
+
+export { Popover, PopoverTrigger, PopoverContent };
diff --git a/src/components/ui/progress.tsx b/src/components/ui/progress.tsx
new file mode 100644
index 0000000..8221536
--- /dev/null
+++ b/src/components/ui/progress.tsx
@@ -0,0 +1,28 @@
+"use client";
+
+import * as React from "react";
+import * as ProgressPrimitive from "@radix-ui/react-progress";
+
+import { cn } from "@/lib/utils";
+
+const Progress = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, value, ...props }, ref) => (
+
+
+
+));
+Progress.displayName = ProgressPrimitive.Root.displayName;
+
+export { Progress };
diff --git a/src/components/ui/radio-group.tsx b/src/components/ui/radio-group.tsx
new file mode 100644
index 0000000..a4988ee
--- /dev/null
+++ b/src/components/ui/radio-group.tsx
@@ -0,0 +1,44 @@
+"use client";
+
+import * as React from "react";
+import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
+import { Circle } from "lucide-react";
+
+import { cn } from "@/lib/utils";
+
+const RadioGroup = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => {
+ return (
+
+ );
+});
+RadioGroup.displayName = RadioGroupPrimitive.Root.displayName;
+
+const RadioGroupItem = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => {
+ return (
+
+
+
+
+
+ );
+});
+RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName;
+
+export { RadioGroup, RadioGroupItem };
diff --git a/src/components/ui/resizable.tsx b/src/components/ui/resizable.tsx
new file mode 100644
index 0000000..765b840
--- /dev/null
+++ b/src/components/ui/resizable.tsx
@@ -0,0 +1,45 @@
+"use client";
+
+import { GripVertical } from "lucide-react";
+import * as ResizablePrimitive from "react-resizable-panels";
+
+import { cn } from "@/lib/utils";
+
+const ResizablePanelGroup = ({
+ className,
+ ...props
+}: React.ComponentProps) => (
+
+);
+
+const ResizablePanel = ResizablePrimitive.Panel;
+
+const ResizableHandle = ({
+ withHandle,
+ className,
+ ...props
+}: React.ComponentProps & {
+ withHandle?: boolean;
+}) => (
+ div]:rotate-90",
+ className,
+ )}
+ {...props}
+ >
+ {withHandle && (
+
+
+
+ )}
+
+);
+
+export { ResizablePanelGroup, ResizablePanel, ResizableHandle };
diff --git a/src/components/ui/scroll-area.tsx b/src/components/ui/scroll-area.tsx
new file mode 100644
index 0000000..b1f1127
--- /dev/null
+++ b/src/components/ui/scroll-area.tsx
@@ -0,0 +1,48 @@
+"use client";
+
+import * as React from "react";
+import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
+
+import { cn } from "@/lib/utils";
+
+const ScrollArea = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, ...props }, ref) => (
+
+
+ {children}
+
+
+
+
+));
+ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
+
+const ScrollBar = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, orientation = "vertical", ...props }, ref) => (
+
+
+
+));
+ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;
+
+export { ScrollArea, ScrollBar };
diff --git a/src/components/ui/select.tsx b/src/components/ui/select.tsx
new file mode 100644
index 0000000..9218f68
--- /dev/null
+++ b/src/components/ui/select.tsx
@@ -0,0 +1,160 @@
+"use client";
+
+import * as React from "react";
+import * as SelectPrimitive from "@radix-ui/react-select";
+import { Check, ChevronDown, ChevronUp } from "lucide-react";
+
+import { cn } from "@/lib/utils";
+
+const Select = SelectPrimitive.Root;
+
+const SelectGroup = SelectPrimitive.Group;
+
+const SelectValue = SelectPrimitive.Value;
+
+const SelectTrigger = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, ...props }, ref) => (
+ span]:line-clamp-1",
+ className,
+ )}
+ {...props}
+ >
+ {children}
+
+
+
+
+));
+SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
+
+const SelectScrollUpButton = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+
+
+));
+SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
+
+const SelectScrollDownButton = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+
+
+));
+SelectScrollDownButton.displayName =
+ SelectPrimitive.ScrollDownButton.displayName;
+
+const SelectContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, position = "popper", ...props }, ref) => (
+
+
+
+
+ {children}
+
+
+
+
+));
+SelectContent.displayName = SelectPrimitive.Content.displayName;
+
+const SelectLabel = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+SelectLabel.displayName = SelectPrimitive.Label.displayName;
+
+const SelectItem = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, ...props }, ref) => (
+
+
+
+
+
+
+
+ {children}
+
+));
+SelectItem.displayName = SelectPrimitive.Item.displayName;
+
+const SelectSeparator = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
+
+export {
+ Select,
+ SelectGroup,
+ SelectValue,
+ SelectTrigger,
+ SelectContent,
+ SelectLabel,
+ SelectItem,
+ SelectSeparator,
+ SelectScrollUpButton,
+ SelectScrollDownButton,
+};
diff --git a/src/components/ui/separator.tsx b/src/components/ui/separator.tsx
new file mode 100644
index 0000000..9ac3b95
--- /dev/null
+++ b/src/components/ui/separator.tsx
@@ -0,0 +1,31 @@
+"use client";
+
+import * as React from "react";
+import * as SeparatorPrimitive from "@radix-ui/react-separator";
+
+import { cn } from "@/lib/utils";
+
+const Separator = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(
+ (
+ { className, orientation = "horizontal", decorative = true, ...props },
+ ref,
+ ) => (
+
+ ),
+);
+Separator.displayName = SeparatorPrimitive.Root.displayName;
+
+export { Separator };
diff --git a/src/components/ui/sheet.tsx b/src/components/ui/sheet.tsx
new file mode 100644
index 0000000..575f05d
--- /dev/null
+++ b/src/components/ui/sheet.tsx
@@ -0,0 +1,140 @@
+"use client";
+
+import * as React from "react";
+import * as SheetPrimitive from "@radix-ui/react-dialog";
+import { cva, type VariantProps } from "class-variance-authority";
+import { X } from "lucide-react";
+
+import { cn } from "@/lib/utils";
+
+const Sheet = SheetPrimitive.Root;
+
+const SheetTrigger = SheetPrimitive.Trigger;
+
+const SheetClose = SheetPrimitive.Close;
+
+const SheetPortal = SheetPrimitive.Portal;
+
+const SheetOverlay = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+SheetOverlay.displayName = SheetPrimitive.Overlay.displayName;
+
+const sheetVariants = cva(
+ "fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
+ {
+ variants: {
+ side: {
+ top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
+ bottom:
+ "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
+ left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
+ right:
+ "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
+ },
+ },
+ defaultVariants: {
+ side: "right",
+ },
+ },
+);
+
+interface SheetContentProps
+ extends React.ComponentPropsWithoutRef,
+ VariantProps {}
+
+const SheetContent = React.forwardRef<
+ React.ElementRef,
+ SheetContentProps
+>(({ side = "right", className, children, ...props }, ref) => (
+
+
+
+ {children}
+
+
+ Close
+
+
+
+));
+SheetContent.displayName = SheetPrimitive.Content.displayName;
+
+const SheetHeader = ({
+ className,
+ ...props
+}: React.HTMLAttributes) => (
+
+);
+SheetHeader.displayName = "SheetHeader";
+
+const SheetFooter = ({
+ className,
+ ...props
+}: React.HTMLAttributes) => (
+
+);
+SheetFooter.displayName = "SheetFooter";
+
+const SheetTitle = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+SheetTitle.displayName = SheetPrimitive.Title.displayName;
+
+const SheetDescription = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+SheetDescription.displayName = SheetPrimitive.Description.displayName;
+
+export {
+ Sheet,
+ SheetPortal,
+ SheetOverlay,
+ SheetTrigger,
+ SheetClose,
+ SheetContent,
+ SheetHeader,
+ SheetFooter,
+ SheetTitle,
+ SheetDescription,
+};
diff --git a/src/components/ui/skeleton.tsx b/src/components/ui/skeleton.tsx
new file mode 100644
index 0000000..2cdf440
--- /dev/null
+++ b/src/components/ui/skeleton.tsx
@@ -0,0 +1,15 @@
+import { cn } from "@/lib/utils";
+
+function Skeleton({
+ className,
+ ...props
+}: React.HTMLAttributes) {
+ return (
+
+ );
+}
+
+export { Skeleton };
diff --git a/src/components/ui/slider.tsx b/src/components/ui/slider.tsx
new file mode 100644
index 0000000..c8ffd27
--- /dev/null
+++ b/src/components/ui/slider.tsx
@@ -0,0 +1,28 @@
+"use client";
+
+import * as React from "react";
+import * as SliderPrimitive from "@radix-ui/react-slider";
+
+import { cn } from "@/lib/utils";
+
+const Slider = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+
+
+
+
+
+));
+Slider.displayName = SliderPrimitive.Root.displayName;
+
+export { Slider };
diff --git a/src/components/ui/sonner.tsx b/src/components/ui/sonner.tsx
new file mode 100644
index 0000000..549cf84
--- /dev/null
+++ b/src/components/ui/sonner.tsx
@@ -0,0 +1,31 @@
+"use client";
+
+import { useTheme } from "next-themes";
+import { Toaster as Sonner } from "sonner";
+
+type ToasterProps = React.ComponentProps;
+
+const Toaster = ({ ...props }: ToasterProps) => {
+ const { theme = "system" } = useTheme();
+
+ return (
+
+ );
+};
+
+export { Toaster };
diff --git a/src/components/ui/switch.tsx b/src/components/ui/switch.tsx
new file mode 100644
index 0000000..b73edee
--- /dev/null
+++ b/src/components/ui/switch.tsx
@@ -0,0 +1,29 @@
+"use client";
+
+import * as React from "react";
+import * as SwitchPrimitives from "@radix-ui/react-switch";
+
+import { cn } from "@/lib/utils";
+
+const Switch = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+
+
+));
+Switch.displayName = SwitchPrimitives.Root.displayName;
+
+export { Switch };
diff --git a/src/components/ui/table.tsx b/src/components/ui/table.tsx
new file mode 100644
index 0000000..73cf6b4
--- /dev/null
+++ b/src/components/ui/table.tsx
@@ -0,0 +1,117 @@
+import * as React from "react";
+
+import { cn } from "@/lib/utils";
+
+const Table = React.forwardRef<
+ HTMLTableElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+));
+Table.displayName = "Table";
+
+const TableHeader = React.forwardRef<
+ HTMLTableSectionElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+));
+TableHeader.displayName = "TableHeader";
+
+const TableBody = React.forwardRef<
+ HTMLTableSectionElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+));
+TableBody.displayName = "TableBody";
+
+const TableFooter = React.forwardRef<
+ HTMLTableSectionElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+ tr]:last:border-b-0",
+ className,
+ )}
+ {...props}
+ />
+));
+TableFooter.displayName = "TableFooter";
+
+const TableRow = React.forwardRef<
+ HTMLTableRowElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+));
+TableRow.displayName = "TableRow";
+
+const TableHead = React.forwardRef<
+ HTMLTableCellElement,
+ React.ThHTMLAttributes
+>(({ className, ...props }, ref) => (
+ |
+));
+TableHead.displayName = "TableHead";
+
+const TableCell = React.forwardRef<
+ HTMLTableCellElement,
+ React.TdHTMLAttributes
+>(({ className, ...props }, ref) => (
+ |
+));
+TableCell.displayName = "TableCell";
+
+const TableCaption = React.forwardRef<
+ HTMLTableCaptionElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+));
+TableCaption.displayName = "TableCaption";
+
+export {
+ Table,
+ TableHeader,
+ TableBody,
+ TableFooter,
+ TableHead,
+ TableRow,
+ TableCell,
+ TableCaption,
+};
diff --git a/src/components/ui/tabs.tsx b/src/components/ui/tabs.tsx
new file mode 100644
index 0000000..ca123a0
--- /dev/null
+++ b/src/components/ui/tabs.tsx
@@ -0,0 +1,55 @@
+"use client";
+
+import * as React from "react";
+import * as TabsPrimitive from "@radix-ui/react-tabs";
+
+import { cn } from "@/lib/utils";
+
+const Tabs = TabsPrimitive.Root;
+
+const TabsList = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+TabsList.displayName = TabsPrimitive.List.displayName;
+
+const TabsTrigger = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
+
+const TabsContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+TabsContent.displayName = TabsPrimitive.Content.displayName;
+
+export { Tabs, TabsList, TabsTrigger, TabsContent };
diff --git a/src/components/ui/textarea.tsx b/src/components/ui/textarea.tsx
new file mode 100644
index 0000000..9f00573
--- /dev/null
+++ b/src/components/ui/textarea.tsx
@@ -0,0 +1,24 @@
+import * as React from "react";
+
+import { cn } from "@/lib/utils";
+
+export interface TextareaProps
+ extends React.TextareaHTMLAttributes {}
+
+const Textarea = React.forwardRef(
+ ({ className, ...props }, ref) => {
+ return (
+
+ );
+ },
+);
+Textarea.displayName = "Textarea";
+
+export { Textarea };
diff --git a/src/components/ui/toast.tsx b/src/components/ui/toast.tsx
new file mode 100644
index 0000000..0b671b7
--- /dev/null
+++ b/src/components/ui/toast.tsx
@@ -0,0 +1,129 @@
+"use client";
+
+import * as React from "react";
+import * as ToastPrimitives from "@radix-ui/react-toast";
+import { cva, type VariantProps } from "class-variance-authority";
+import { X } from "lucide-react";
+
+import { cn } from "@/lib/utils";
+
+const ToastProvider = ToastPrimitives.Provider;
+
+const ToastViewport = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+ToastViewport.displayName = ToastPrimitives.Viewport.displayName;
+
+const toastVariants = cva(
+ "group pointer-events-auto relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full",
+ {
+ variants: {
+ variant: {
+ default: "border bg-background text-foreground",
+ destructive:
+ "destructive group border-destructive bg-destructive text-destructive-foreground",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ },
+ },
+);
+
+const Toast = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef &
+ VariantProps
+>(({ className, variant, ...props }, ref) => {
+ return (
+
+ );
+});
+Toast.displayName = ToastPrimitives.Root.displayName;
+
+const ToastAction = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+ToastAction.displayName = ToastPrimitives.Action.displayName;
+
+const ToastClose = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+