diff --git a/app/globals.css b/app/globals.css
index a2dc41e..aace076 100644
--- a/app/globals.css
+++ b/app/globals.css
@@ -1,26 +1,692 @@
-@import "tailwindcss";
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
-:root {
- --background: #ffffff;
- --foreground: #171717;
-}
-
-@theme inline {
- --color-background: var(--background);
- --color-foreground: var(--foreground);
- --font-sans: var(--font-geist-sans);
- --font-mono: var(--font-geist-mono);
-}
-
-@media (prefers-color-scheme: dark) {
+@layer base {
:root {
- --background: #0a0a0a;
- --foreground: #ededed;
+ /* Light Mode - Smart-Admin Copilot Palette */
+ --background: 0 0% 100%;
+ --foreground: 222 47% 11%;
+ --card: 210 40% 98%;
+ --card-foreground: 222 47% 11%;
+ --popover: 0 0% 100%;
+ --popover-foreground: 222 47% 11%;
+ --primary: 221 83% 53%;
+ --primary-foreground: 0 0% 100%;
+ --secondary: 168 76% 40%;
+ --secondary-foreground: 0 0% 100%;
+ --accent: 262 83% 58%;
+ --accent-foreground: 0 0% 100%;
+ --muted: 210 40% 96%;
+ --muted-foreground: 215 16% 47%;
+ --destructive: 0 84% 60%;
+ --destructive-foreground: 0 0% 98%;
+ --border: 214 32% 91%;
+ --input: 214 32% 91%;
+ --ring: 221 83% 53%;
+ --radius: 0.75rem;
+
+ /* Custom Colors */
+ --success: 160 84% 39%;
+ --warning: 38 92% 50%;
+ --royal-blue: 221 83% 53%;
+ --teal: 168 76% 40%;
+ --violet: 262 83% 58%;
+ --emerald: 160 84% 39%;
+ --amber: 38 92% 50%;
+ --deep-slate: 222 47% 11%;
+ --medium-slate: 215 16% 47%;
+ --light-slate: 214 32% 91%;
+ --off-white: 210 40% 98%;
+ }
+
+ .dark {
+ /* Dark Mode - Smart-Admin Copilot Palette */
+ --background: 222 47% 5%;
+ --foreground: 210 40% 98%;
+ --card: 217 33% 17%;
+ --card-foreground: 210 40% 98%;
+ --popover: 217 33% 17%;
+ --popover-foreground: 210 40% 98%;
+ --primary: 217 91% 60%;
+ --primary-foreground: 0 0% 100%;
+ --secondary: 189 94% 43%;
+ --secondary-foreground: 0 0% 100%;
+ --accent: 258 90% 66%;
+ --accent-foreground: 0 0% 100%;
+ --muted: 217 33% 17%;
+ --muted-foreground: 215 20% 65%;
+ --destructive: 0 62% 30%;
+ --destructive-foreground: 0 0% 98%;
+ --border: 217 33% 25%;
+ --input: 217 33% 25%;
+ --ring: 217 91% 60%;
+
+ /* Custom Dark Colors */
+ --success: 158 64% 52%;
+ --warning: 48 96% 53%;
+ --bright-blue: 217 91% 60%;
+ --cyan: 189 94% 43%;
+ --purple: 258 90% 76%;
+ --green: 158 64% 52%;
+ --dark-slate: 217 33% 17%;
+ --almost-white: 210 40% 98%;
}
}
-body {
- background: var(--background);
- color: var(--foreground);
- font-family: Arial, Helvetica, sans-serif;
+@layer base {
+ * {
+ @apply border-border;
+ }
+
+ html {
+ scroll-behavior: smooth;
+ }
+
+ body {
+ @apply bg-background text-foreground antialiased;
+ font-feature-settings:
+ "rlig" 1,
+ "calt" 1;
+ }
+}
+
+@layer utilities {
+ /* Gradient Text */
+ .gradient-text {
+ @apply bg-clip-text text-transparent;
+ background-image: linear-gradient(
+ 135deg,
+ hsl(var(--primary)) 0%,
+ hsl(var(--accent)) 50%,
+ hsl(var(--secondary)) 100%
+ );
+ }
+
+ .gradient-text-hero-light {
+ @apply bg-clip-text text-transparent;
+ background-image: linear-gradient(
+ 135deg,
+ #0f172a 0%,
+ #1e40af 50%,
+ #0f172a 100%
+ );
+ }
+
+ .gradient-text-hero-dark {
+ @apply bg-clip-text text-transparent;
+ background-image: linear-gradient(
+ 135deg,
+ #f8fafc 0%,
+ #93c5fd 50%,
+ #f8fafc 100%
+ );
+ }
+
+ /* Glass Morphism */
+ .glass {
+ @apply backdrop-blur-xl;
+ background: rgba(255, 255, 255, 0.7);
+ border: 1px solid rgba(226, 232, 240, 0.5);
+ }
+
+ .dark .glass {
+ background: rgba(30, 41, 59, 0.7);
+ border: 1px solid rgba(51, 65, 85, 0.5);
+ }
+
+ .glass-strong {
+ @apply backdrop-blur-2xl;
+ background: rgba(255, 255, 255, 0.85);
+ border: 1px solid rgba(226, 232, 240, 0.6);
+ }
+
+ .dark .glass-strong {
+ background: rgba(15, 23, 42, 0.85);
+ border: 1px solid rgba(51, 65, 85, 0.6);
+ }
+
+ /* Gradient Backgrounds */
+ .gradient-bg-mesh {
+ background:
+ radial-gradient(
+ ellipse at 20% 20%,
+ rgba(59, 130, 246, 0.15) 0%,
+ transparent 50%
+ ),
+ radial-gradient(
+ ellipse at 80% 80%,
+ rgba(139, 92, 246, 0.15) 0%,
+ transparent 50%
+ ),
+ radial-gradient(
+ ellipse at 50% 50%,
+ rgba(20, 184, 166, 0.1) 0%,
+ transparent 60%
+ );
+ }
+
+ .dark .gradient-bg-mesh {
+ background:
+ radial-gradient(
+ ellipse at 20% 20%,
+ rgba(59, 130, 246, 0.2) 0%,
+ transparent 50%
+ ),
+ radial-gradient(
+ ellipse at 80% 80%,
+ rgba(139, 92, 246, 0.2) 0%,
+ transparent 50%
+ ),
+ radial-gradient(
+ ellipse at 50% 50%,
+ rgba(6, 182, 212, 0.15) 0%,
+ transparent 60%
+ );
+ }
+
+ /* Button Gradients */
+ .btn-gradient {
+ background: linear-gradient(135deg, #2563eb 0%, #7c3aed 100%);
+ transition: all 0.3s ease;
+ }
+
+ .btn-gradient:hover {
+ background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);
+ transform: scale(1.05);
+ box-shadow: 0 0 40px rgba(59, 130, 246, 0.4);
+ }
+
+ /* Glow Effects */
+ .glow-blue {
+ box-shadow: 0 0 40px rgba(59, 130, 246, 0.4);
+ }
+
+ .glow-violet {
+ box-shadow: 0 0 40px rgba(139, 92, 246, 0.4);
+ }
+
+ .glow-teal {
+ box-shadow: 0 0 40px rgba(20, 184, 166, 0.4);
+ }
+
+ /* Card Gradients */
+ .card-gradient-blue {
+ background: linear-gradient(
+ 135deg,
+ rgba(37, 99, 235, 0.1) 0%,
+ rgba(139, 92, 246, 0.1) 100%
+ );
+ }
+
+ .card-gradient-teal {
+ background: linear-gradient(
+ 135deg,
+ rgba(20, 184, 166, 0.1) 0%,
+ rgba(6, 182, 212, 0.1) 100%
+ );
+ }
+
+ .card-gradient-violet {
+ background: linear-gradient(
+ 135deg,
+ rgba(139, 92, 246, 0.1) 0%,
+ rgba(168, 85, 247, 0.1) 100%
+ );
+ }
+
+ .card-gradient-amber {
+ background: linear-gradient(
+ 135deg,
+ rgba(245, 158, 11, 0.1) 0%,
+ rgba(249, 115, 22, 0.1) 100%
+ );
+ }
+
+ .card-gradient-emerald {
+ background: linear-gradient(
+ 135deg,
+ rgba(16, 185, 129, 0.1) 0%,
+ rgba(34, 197, 94, 0.1) 100%
+ );
+ }
+
+ /* Animated Border */
+ .animated-border {
+ position: relative;
+ background:
+ linear-gradient(var(--background), var(--background)) padding-box,
+ linear-gradient(
+ 135deg,
+ hsl(var(--primary)),
+ hsl(var(--accent)),
+ hsl(var(--secondary))
+ )
+ border-box;
+ border: 1px solid transparent;
+ }
+
+ /* Noise Texture */
+ .noise-texture {
+ position: relative;
+ }
+
+ .noise-texture::before {
+ content: "";
+ position: absolute;
+ inset: 0;
+ background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E");
+ opacity: 0.03;
+ pointer-events: none;
+ z-index: 1;
+ }
+
+ /* Grid Pattern */
+ .grid-pattern {
+ background-image:
+ linear-gradient(rgba(148, 163, 184, 0.1) 1px, transparent 1px),
+ linear-gradient(90deg, rgba(148, 163, 184, 0.1) 1px, transparent 1px);
+ background-size: 40px 40px;
+ }
+
+ .dark .grid-pattern {
+ background-image:
+ linear-gradient(rgba(71, 85, 105, 0.2) 1px, transparent 1px),
+ linear-gradient(90deg, rgba(71, 85, 105, 0.2) 1px, transparent 1px);
+ }
+
+ /* 3D Transform */
+ .perspective-1000 {
+ perspective: 1000px;
+ }
+
+ .transform-3d {
+ transform-style: preserve-3d;
+ }
+
+ /* Hide scrollbar */
+ .hide-scrollbar {
+ -ms-overflow-style: none;
+ scrollbar-width: none;
+ }
+
+ .hide-scrollbar::-webkit-scrollbar {
+ display: none;
+ }
+}
+
+/* Custom Animations */
+@keyframes float {
+ 0%,
+ 100% {
+ transform: translateY(0px);
+ }
+ 50% {
+ transform: translateY(-20px);
+ }
+}
+
+@keyframes float-slow {
+ 0%,
+ 100% {
+ transform: translateY(0px) translateX(0px);
+ }
+ 50% {
+ transform: translateY(-15px) translateX(10px);
+ }
+}
+
+@keyframes pulse-glow {
+ 0%,
+ 100% {
+ box-shadow: 0 0 20px rgba(59, 130, 246, 0.3);
+ }
+ 50% {
+ box-shadow: 0 0 40px rgba(59, 130, 246, 0.6);
+ }
+}
+
+@keyframes gradient-shift {
+ 0% {
+ background-position: 0% 50%;
+ }
+ 50% {
+ background-position: 100% 50%;
+ }
+ 100% {
+ background-position: 0% 50%;
+ }
+}
+
+@keyframes shimmer {
+ 0% {
+ background-position: -200% 0;
+ }
+ 100% {
+ background-position: 200% 0;
+ }
+}
+
+@keyframes spin-slow {
+ from {
+ transform: rotate(0deg);
+ }
+ to {
+ transform: rotate(360deg);
+ }
+}
+
+@keyframes bounce-subtle {
+ 0%,
+ 100% {
+ transform: translateY(0);
+ }
+ 50% {
+ transform: translateY(-5px);
+ }
+}
+
+@keyframes slide-up {
+ from {
+ opacity: 0;
+ transform: translateY(30px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+@keyframes slide-down {
+ from {
+ opacity: 0;
+ transform: translateY(-30px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+@keyframes fade-in {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+}
+
+@keyframes scale-in {
+ from {
+ opacity: 0;
+ transform: scale(0.9);
+ }
+ to {
+ opacity: 1;
+ transform: scale(1);
+ }
+}
+
+@keyframes count-up {
+ from {
+ opacity: 0;
+ transform: translateY(10px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+@keyframes draw-line {
+ from {
+ stroke-dashoffset: 1000;
+ }
+ to {
+ stroke-dashoffset: 0;
+ }
+}
+
+@keyframes particle-float {
+ 0%,
+ 100% {
+ transform: translateY(0) translateX(0);
+ opacity: 0.5;
+ }
+ 25% {
+ transform: translateY(-30px) translateX(10px);
+ opacity: 0.8;
+ }
+ 50% {
+ transform: translateY(-20px) translateX(-10px);
+ opacity: 0.6;
+ }
+ 75% {
+ transform: translateY(-40px) translateX(5px);
+ opacity: 0.9;
+ }
+}
+
+@keyframes ring {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 25% {
+ transform: rotate(15deg);
+ }
+ 50% {
+ transform: rotate(0deg);
+ }
+ 75% {
+ transform: rotate(-15deg);
+ }
+ 100% {
+ transform: rotate(0deg);
+ }
+}
+
+/* Animation Classes */
+.animate-float {
+ animation: float 6s ease-in-out infinite;
+}
+
+.animate-float-slow {
+ animation: float-slow 8s ease-in-out infinite;
+}
+
+.animate-float-delayed {
+ animation: float 6s ease-in-out infinite;
+ animation-delay: 2s;
+}
+
+.animate-pulse-glow {
+ animation: pulse-glow 3s ease-in-out infinite;
+}
+
+.animate-gradient-shift {
+ background-size: 200% 200%;
+ animation: gradient-shift 8s ease infinite;
+}
+
+.animate-shimmer {
+ background: linear-gradient(
+ 90deg,
+ transparent,
+ rgba(255, 255, 255, 0.2),
+ transparent
+ );
+ background-size: 200% 100%;
+ animation: shimmer 2s infinite;
+}
+
+.animate-spin-slow {
+ animation: spin-slow 20s linear infinite;
+}
+
+.animate-bounce-subtle {
+ animation: bounce-subtle 2s ease-in-out infinite;
+}
+
+.animate-slide-up {
+ animation: slide-up 0.6s ease-out forwards;
+}
+
+.animate-slide-down {
+ animation: slide-down 0.6s ease-out forwards;
+}
+
+.animate-fade-in {
+ animation: fade-in 0.5s ease-out forwards;
+}
+
+.animate-scale-in {
+ animation: scale-in 0.5s ease-out forwards;
+}
+
+.animate-particle-float {
+ animation: particle-float 10s ease-in-out infinite;
+}
+
+.animate-ring {
+ animation: ring 0.5s ease-in-out;
+}
+
+/* Stagger Animation Delays */
+.stagger-1 {
+ animation-delay: 0.1s;
+}
+.stagger-2 {
+ animation-delay: 0.2s;
+}
+.stagger-3 {
+ animation-delay: 0.3s;
+}
+.stagger-4 {
+ animation-delay: 0.4s;
+}
+.stagger-5 {
+ animation-delay: 0.5s;
+}
+.stagger-6 {
+ animation-delay: 0.6s;
+}
+.stagger-7 {
+ animation-delay: 0.7s;
+}
+.stagger-8 {
+ animation-delay: 0.8s;
+}
+
+/* Scroll Animation Classes */
+.scroll-animate {
+ opacity: 0;
+ transform: translateY(30px);
+ transition:
+ opacity 0.6s ease-out,
+ transform 0.6s ease-out;
+}
+
+.scroll-animate.visible {
+ opacity: 1;
+ transform: translateY(0);
+}
+
+.scroll-animate-left {
+ opacity: 0;
+ transform: translateX(-50px);
+ transition:
+ opacity 0.6s ease-out,
+ transform 0.6s ease-out;
+}
+
+.scroll-animate-left.visible {
+ opacity: 1;
+ transform: translateX(0);
+}
+
+.scroll-animate-right {
+ opacity: 0;
+ transform: translateX(50px);
+ transition:
+ opacity 0.6s ease-out,
+ transform 0.6s ease-out;
+}
+
+.scroll-animate-right.visible {
+ opacity: 1;
+ transform: translateX(0);
+}
+
+.scroll-animate-scale {
+ opacity: 0;
+ transform: scale(0.9);
+ transition:
+ opacity 0.6s ease-out,
+ transform 0.6s ease-out;
+}
+
+.scroll-animate-scale.visible {
+ opacity: 1;
+ transform: scale(1);
+}
+
+/* Hover Effects */
+.hover-lift {
+ transition:
+ transform 0.3s ease,
+ box-shadow 0.3s ease;
+}
+
+.hover-lift:hover {
+ transform: translateY(-4px);
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
+}
+
+.dark .hover-lift:hover {
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
+}
+
+.hover-scale {
+ transition: transform 0.3s ease;
+}
+
+.hover-scale:hover {
+ transform: scale(1.05);
+}
+
+.hover-glow {
+ transition: box-shadow 0.3s ease;
+}
+
+.hover-glow:hover {
+ box-shadow: 0 0 30px rgba(59, 130, 246, 0.4);
+}
+
+/* Focus States */
+.focus-ring:focus-visible {
+ outline: none;
+ ring: 2px;
+ ring-color: hsl(var(--ring));
+ ring-offset: 2px;
+ ring-offset-color: hsl(var(--background));
+}
+
+/* Reduced Motion */
+@media (prefers-reduced-motion: reduce) {
+ *,
+ *::before,
+ *::after {
+ animation-duration: 0.01ms !important;
+ animation-iteration-count: 1 !important;
+ transition-duration: 0.01ms !important;
+ }
+
+ .scroll-animate,
+ .scroll-animate-left,
+ .scroll-animate-right,
+ .scroll-animate-scale {
+ opacity: 1;
+ transform: none;
+ }
}
diff --git a/app/layout.tsx b/app/layout.tsx
index f7fa87e..ba3b658 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -1,6 +1,7 @@
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
+import { Providers } from "./provider";
const geistSans = Geist({
variable: "--font-geist-sans",
@@ -23,11 +24,11 @@ export default function RootLayout({
children: React.ReactNode;
}>) {
return (
-
+
- {children}
+ {children}
);
diff --git a/app/page.tsx b/app/page.tsx
index 295f8fd..b3437d5 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -1,65 +1,159 @@
-import Image from "next/image";
+"use client";
+
+import { useEffect, useState } from "react";
+import { Navbar } from "@/components/views/Home/Navbar";
+import { Hero } from "@/components/views/Home/Hero";
+import { Features } from "@/components/views/Home/Features";
+import { HowItWorks } from "@/components/views/Home/HowItWorks";
+import { Stats } from "@/components/views/Home/Stats";
+import { Footer } from "@/components/views/Home/Footer";
+import { Sparkles } from "lucide-react";
+
+//Loading Screen
+function LoadingScreen({ onComplete }: { onComplete: () => void }) {
+ const [progress, setProgress] = useState(0);
+
+ useEffect(() => {
+ const interval = setInterval(() => {
+ setProgress((prev) => {
+ if (prev >= 100) {
+ clearInterval(interval);
+ setTimeout(onComplete, 300);
+ return 100;
+ }
+ return prev + Math.random() * 15;
+ });
+ }, 100);
+
+ return () => clearInterval(interval);
+ }, [onComplete]);
-export default function Home() {
return (
-
-
-
+
+
+
-
-
- To get started, edit the page.tsx file.
-
-
- Looking for a starting point or more instructions? Head over to{" "}
-
- Templates
- {" "}
- or the{" "}
-
- Learning
- {" "}
- center.
-
-
-
-
+
+
+
+ Smart-Admin Copilot
+
+
+
+
+
+ Loading amazing experience...
+
+
+ );
+}
+
+//Scroll Progress
+function ScrollProgressBar() {
+ const [progress, setProgress] = useState(0);
+
+ useEffect(() => {
+ const handleScroll = () => {
+ const scrollTop = window.scrollY;
+ const docHeight =
+ document.documentElement.scrollHeight - window.innerHeight;
+ const scrollPercent = (scrollTop / docHeight) * 100;
+ setProgress(scrollPercent);
+ };
+
+ window.addEventListener("scroll", handleScroll, { passive: true });
+ return () => window.removeEventListener("scroll", handleScroll);
+ }, []);
+
+ return (
+
+ );
+}
+
+//Back To Top
+function BackToTop() {
+ const [isVisible, setIsVisible] = useState(false);
+
+ useEffect(() => {
+ const handleScroll = () => {
+ setIsVisible(window.scrollY > 500);
+ };
+
+ window.addEventListener("scroll", handleScroll, { passive: true });
+ return () => window.removeEventListener("scroll", handleScroll);
+ }, []);
+
+ const scrollToTop = () => {
+ window.scrollTo({ top: 0, behavior: "smooth" });
+ };
+
+ return (
+
+ );
+}
+
+//Main Page
+export default function Home() {
+ const [isLoading, setIsLoading] = useState(true);
+
+ const handleLoadingComplete = () => {
+ setIsLoading(false);
+ };
+
+ if (isLoading) {
+ return ;
+ }
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
);
}
diff --git a/app/provider.tsx b/app/provider.tsx
new file mode 100644
index 0000000..82d3d90
--- /dev/null
+++ b/app/provider.tsx
@@ -0,0 +1,11 @@
+"use client";
+import { ThemeProvider } from "next-themes";
+import { ReactNode } from "react";
+
+export function Providers({ children }: { children: ReactNode }) {
+ return (
+
+ {children}
+
+ );
+}
diff --git a/components.json b/components.json
new file mode 100644
index 0000000..7b3464b
--- /dev/null
+++ b/components.json
@@ -0,0 +1,23 @@
+{
+ "$schema": "https://ui.shadcn.com/schema.json",
+ "style": "new-york",
+ "rsc": true,
+ "tsx": true,
+ "tailwind": {
+ "config": "tailwind.config.ts",
+ "css": "app/globals.css",
+ "baseColor": "neutral",
+ "cssVariables": true,
+ "prefix": ""
+ },
+ "iconLibrary": "lucide",
+ "rtl": false,
+ "aliases": {
+ "components": "@/components",
+ "utils": "@/lib/utils",
+ "ui": "@/components/ui",
+ "lib": "@/lib",
+ "hooks": "@/hooks"
+ },
+ "registries": {}
+}
diff --git a/components/ui/accordion.tsx b/components/ui/accordion.tsx
new file mode 100644
index 0000000..2f55a32
--- /dev/null
+++ b/components/ui/accordion.tsx
@@ -0,0 +1,57 @@
+"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/components/ui/alert-dialog.tsx b/components/ui/alert-dialog.tsx
new file mode 100644
index 0000000..57760f2
--- /dev/null
+++ b/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/components/ui/alert.tsx b/components/ui/alert.tsx
new file mode 100644
index 0000000..5afd41d
--- /dev/null
+++ b/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 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<
+ 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/components/ui/aspect-ratio.tsx b/components/ui/aspect-ratio.tsx
new file mode 100644
index 0000000..d6a5226
--- /dev/null
+++ b/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/components/ui/avatar.tsx b/components/ui/avatar.tsx
new file mode 100644
index 0000000..51e507b
--- /dev/null
+++ b/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/components/ui/badge.tsx b/components/ui/badge.tsx
new file mode 100644
index 0000000..e87d62b
--- /dev/null
+++ b/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-md 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 shadow hover:bg-primary/80",
+ secondary:
+ "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
+ destructive:
+ "border-transparent bg-destructive text-destructive-foreground shadow 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/components/ui/breadcrumb.tsx b/components/ui/breadcrumb.tsx
new file mode 100644
index 0000000..60e6c96
--- /dev/null
+++ b/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]:w-3.5 [&>svg]:h-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/components/ui/button.tsx b/components/ui/button.tsx
new file mode 100644
index 0000000..65d4fcd
--- /dev/null
+++ b/components/ui/button.tsx
@@ -0,0 +1,57 @@
+import * as React from "react"
+import { Slot } from "@radix-ui/react-slot"
+import { cva, type VariantProps } from "class-variance-authority"
+
+import { cn } from "@/lib/utils"
+
+const buttonVariants = cva(
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
+ {
+ variants: {
+ variant: {
+ default:
+ "bg-primary text-primary-foreground shadow hover:bg-primary/90",
+ destructive:
+ "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
+ outline:
+ "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
+ secondary:
+ "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
+ ghost: "hover:bg-accent hover:text-accent-foreground",
+ link: "text-primary underline-offset-4 hover:underline",
+ },
+ size: {
+ default: "h-9 px-4 py-2",
+ sm: "h-8 rounded-md px-3 text-xs",
+ lg: "h-10 rounded-md px-8",
+ icon: "h-9 w-9",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ size: "default",
+ },
+ }
+)
+
+export interface ButtonProps
+ extends React.ButtonHTMLAttributes,
+ VariantProps {
+ asChild?: boolean
+}
+
+const Button = React.forwardRef(
+ ({ className, variant, size, asChild = false, ...props }, ref) => {
+ const Comp = asChild ? Slot : "button"
+ return (
+
+ )
+ }
+)
+Button.displayName = "Button"
+
+export { Button, buttonVariants }
diff --git a/components/ui/calendar.tsx b/components/ui/calendar.tsx
new file mode 100644
index 0000000..a623682
--- /dev/null
+++ b/components/ui/calendar.tsx
@@ -0,0 +1,213 @@
+"use client"
+
+import * as React from "react"
+import {
+ ChevronDownIcon,
+ ChevronLeftIcon,
+ ChevronRightIcon,
+} from "lucide-react"
+import { DayButton, DayPicker, getDefaultClassNames } from "react-day-picker"
+
+import { cn } from "@/lib/utils"
+import { Button, buttonVariants } from "@/components/ui/button"
+
+function Calendar({
+ className,
+ classNames,
+ showOutsideDays = true,
+ captionLayout = "label",
+ buttonVariant = "ghost",
+ formatters,
+ components,
+ ...props
+}: React.ComponentProps & {
+ buttonVariant?: React.ComponentProps["variant"]
+}) {
+ const defaultClassNames = getDefaultClassNames()
+
+ return (
+ svg]:rotate-180`,
+ String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
+ className
+ )}
+ captionLayout={captionLayout}
+ formatters={{
+ formatMonthDropdown: (date) =>
+ date.toLocaleString("default", { month: "short" }),
+ ...formatters,
+ }}
+ classNames={{
+ root: cn("w-fit", defaultClassNames.root),
+ months: cn(
+ "relative flex flex-col gap-4 md:flex-row",
+ defaultClassNames.months
+ ),
+ month: cn("flex w-full flex-col gap-4", defaultClassNames.month),
+ nav: cn(
+ "absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1",
+ defaultClassNames.nav
+ ),
+ button_previous: cn(
+ buttonVariants({ variant: buttonVariant }),
+ "h-[--cell-size] w-[--cell-size] select-none p-0 aria-disabled:opacity-50",
+ defaultClassNames.button_previous
+ ),
+ button_next: cn(
+ buttonVariants({ variant: buttonVariant }),
+ "h-[--cell-size] w-[--cell-size] select-none p-0 aria-disabled:opacity-50",
+ defaultClassNames.button_next
+ ),
+ month_caption: cn(
+ "flex h-[--cell-size] w-full items-center justify-center px-[--cell-size]",
+ defaultClassNames.month_caption
+ ),
+ dropdowns: cn(
+ "flex h-[--cell-size] w-full items-center justify-center gap-1.5 text-sm font-medium",
+ defaultClassNames.dropdowns
+ ),
+ dropdown_root: cn(
+ "has-focus:border-ring border-input shadow-xs has-focus:ring-ring/50 has-focus:ring-[3px] relative rounded-md border",
+ defaultClassNames.dropdown_root
+ ),
+ dropdown: cn(
+ "bg-popover absolute inset-0 opacity-0",
+ defaultClassNames.dropdown
+ ),
+ caption_label: cn(
+ "select-none font-medium",
+ captionLayout === "label"
+ ? "text-sm"
+ : "[&>svg]:text-muted-foreground flex h-8 items-center gap-1 rounded-md pl-2 pr-1 text-sm [&>svg]:size-3.5",
+ defaultClassNames.caption_label
+ ),
+ table: "w-full border-collapse",
+ weekdays: cn("flex", defaultClassNames.weekdays),
+ weekday: cn(
+ "text-muted-foreground flex-1 select-none rounded-md text-[0.8rem] font-normal",
+ defaultClassNames.weekday
+ ),
+ week: cn("mt-2 flex w-full", defaultClassNames.week),
+ week_number_header: cn(
+ "w-[--cell-size] select-none",
+ defaultClassNames.week_number_header
+ ),
+ week_number: cn(
+ "text-muted-foreground select-none text-[0.8rem]",
+ defaultClassNames.week_number
+ ),
+ day: cn(
+ "group/day relative aspect-square h-full w-full select-none p-0 text-center [&:first-child[data-selected=true]_button]:rounded-l-md [&:last-child[data-selected=true]_button]:rounded-r-md",
+ defaultClassNames.day
+ ),
+ range_start: cn(
+ "bg-accent rounded-l-md",
+ defaultClassNames.range_start
+ ),
+ range_middle: cn("rounded-none", defaultClassNames.range_middle),
+ range_end: cn("bg-accent rounded-r-md", defaultClassNames.range_end),
+ today: cn(
+ "bg-accent text-accent-foreground rounded-md data-[selected=true]:rounded-none",
+ defaultClassNames.today
+ ),
+ outside: cn(
+ "text-muted-foreground aria-selected:text-muted-foreground",
+ defaultClassNames.outside
+ ),
+ disabled: cn(
+ "text-muted-foreground opacity-50",
+ defaultClassNames.disabled
+ ),
+ hidden: cn("invisible", defaultClassNames.hidden),
+ ...classNames,
+ }}
+ components={{
+ Root: ({ className, rootRef, ...props }) => {
+ return (
+
+ )
+ },
+ Chevron: ({ className, orientation, ...props }) => {
+ if (orientation === "left") {
+ return (
+
+ )
+ }
+
+ if (orientation === "right") {
+ return (
+
+ )
+ }
+
+ return (
+
+ )
+ },
+ DayButton: CalendarDayButton,
+ WeekNumber: ({ children, ...props }) => {
+ return (
+
+
+ {children}
+
+ |
+ )
+ },
+ ...components,
+ }}
+ {...props}
+ />
+ )
+}
+
+function CalendarDayButton({
+ className,
+ day,
+ modifiers,
+ ...props
+}: React.ComponentProps) {
+ const defaultClassNames = getDefaultClassNames()
+
+ const ref = React.useRef(null)
+ React.useEffect(() => {
+ if (modifiers.focused) ref.current?.focus()
+ }, [modifiers.focused])
+
+ return (
+