Compare commits

..

No commits in common. "3dfee64e8e4c26b506fafcc6f4d2154dc0f35c1d" and "4d00d4b936551d87eb9f35e3673f9f51b5888db2" have entirely different histories.

70 changed files with 3460 additions and 3486 deletions

View File

@ -1,37 +0,0 @@
{
"$schema": "https://biomejs.dev/schemas/1.6.4/schema.json",
"organizeImports": {
"enabled": true
},
"files": {
"include": [
"./src/**/*.ts",
"./src/**/*.tsx"
]
},
"vcs": {
"enabled": true,
"clientKind": "git"
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"performance": {
"recommended": true,
"noDelete": "off"
},
"suspicious": {
"noExplicitAny": "warn"
},
"complexity": {
"useLiteralKeys": "off"
}
}
},
"formatter": {
"indentStyle": "tab",
"indentWidth": 2,
"lineWidth": 90
}
}

View File

@ -6,8 +6,7 @@
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"check": "biome check --skip-errors --apply src"
"lint": "next lint"
},
"dependencies": {
"@fontsource-variable/kode-mono": "^5.0.3",
@ -63,7 +62,6 @@
"zod": "^3.23.8"
},
"devDependencies": {
"@biomejs/biome": "1.8.1",
"@types/jest": "^29.5.12",
"@types/node": "^20",
"@types/react": "^18",

91
pnpm-lock.yaml generated
View File

@ -162,9 +162,6 @@ importers:
specifier: ^3.23.8
version: 3.23.8
devDependencies:
'@biomejs/biome':
specifier: 1.8.1
version: 1.8.1
'@types/jest':
specifier: ^29.5.12
version: 29.5.12
@ -371,59 +368,6 @@ packages:
'@bcoe/v8-coverage@0.2.3':
resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
'@biomejs/biome@1.8.1':
resolution: {integrity: sha512-fQXGfvq6DIXem12dGQCM2tNF+vsNHH1qs3C7WeOu75Pd0trduoTmoO7G4ntLJ2qDs5wuw981H+cxQhi1uHnAtA==}
engines: {node: '>=14.21.3'}
hasBin: true
'@biomejs/cli-darwin-arm64@1.8.1':
resolution: {integrity: sha512-XLiB7Uu6GALIOBWzQ2aMD0ru4Ly5/qSeQF7kk3AabzJ/kwsEWSe33iVySBP/SS2qv25cgqNiLksjGcw2bHT3mw==}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [darwin]
'@biomejs/cli-darwin-x64@1.8.1':
resolution: {integrity: sha512-uMTSxVLMfqkBVqyc25hSn83jBbp+wtWjzM/pHFlKXt3htJuw7FErVGW0nmQ9Sxa9vJ7GcqoltLMl28VQRIMYzg==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [darwin]
'@biomejs/cli-linux-arm64-musl@1.8.1':
resolution: {integrity: sha512-UQ8Wc01J0wQL+5AYOc7qkJn20B4PZmQL1KrmDZh7ot0DvD6aX4+8mmfd/dG5b6Zjo/44QvCKcvkFGCMRYuhWZA==}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [linux]
'@biomejs/cli-linux-arm64@1.8.1':
resolution: {integrity: sha512-3SzZRuC/9Oi2P2IBNPsEj0KXxSXUEYRR2kfRF/Ve8QAfGgrt4qnwuWd6QQKKN5R+oYH691qjm+cXBKEcrP1v/Q==}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [linux]
'@biomejs/cli-linux-x64-musl@1.8.1':
resolution: {integrity: sha512-fYbP/kNu/rtZ4kKzWVocIdqZOtBSUEg9qUhZaao3dy3CRzafR6u6KDtBeSCnt47O+iLnks1eOR1TUxzr5+QuqA==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [linux]
'@biomejs/cli-linux-x64@1.8.1':
resolution: {integrity: sha512-AeBycVdNrTzsyYKEOtR2R0Ph0hCD0sCshcp2aOnfGP0hCZbtFg09D0SdKLbyzKntisY41HxKVrydYiaApp+2uw==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [linux]
'@biomejs/cli-win32-arm64@1.8.1':
resolution: {integrity: sha512-6tEd1H/iFKpgpE3OIB7oNgW5XkjiVMzMRPL8zYoZ036YfuJ5nMYm9eB9H/y81+8Z76vL48fiYzMPotJwukGPqQ==}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [win32]
'@biomejs/cli-win32-x64@1.8.1':
resolution: {integrity: sha512-g2H31jJzYmS4jkvl6TiyEjEX+Nv79a5km/xn+5DARTp5MBFzC9gwceusSSB2AkJKqZzY131AiACAWjKrVt5Ijw==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [win32]
'@floating-ui/core@1.6.2':
resolution: {integrity: sha512-+2XpQV9LLZeanU4ZevzRnGFg2neDeKHgFLjP6YLW+tly0IvrhqT4u8enLGjLH3qeh85g19xY5rsAusfwTdn5lg==}
@ -2850,41 +2794,6 @@ snapshots:
'@bcoe/v8-coverage@0.2.3': {}
'@biomejs/biome@1.8.1':
optionalDependencies:
'@biomejs/cli-darwin-arm64': 1.8.1
'@biomejs/cli-darwin-x64': 1.8.1
'@biomejs/cli-linux-arm64': 1.8.1
'@biomejs/cli-linux-arm64-musl': 1.8.1
'@biomejs/cli-linux-x64': 1.8.1
'@biomejs/cli-linux-x64-musl': 1.8.1
'@biomejs/cli-win32-arm64': 1.8.1
'@biomejs/cli-win32-x64': 1.8.1
'@biomejs/cli-darwin-arm64@1.8.1':
optional: true
'@biomejs/cli-darwin-x64@1.8.1':
optional: true
'@biomejs/cli-linux-arm64-musl@1.8.1':
optional: true
'@biomejs/cli-linux-arm64@1.8.1':
optional: true
'@biomejs/cli-linux-x64-musl@1.8.1':
optional: true
'@biomejs/cli-linux-x64@1.8.1':
optional: true
'@biomejs/cli-win32-arm64@1.8.1':
optional: true
'@biomejs/cli-win32-x64@1.8.1':
optional: true
'@floating-ui/core@1.6.2':
dependencies:
'@floating-ui/utils': 0.2.2

View File

@ -1,18 +1,17 @@
import type { Metadata } from "next";
import "@fontsource-variable/kode-mono";
import '@fontsource-variable/kode-mono';
import "./globals.css";
import { Footer } from "@/components/footer";
import { Header } from "@/components/header";
import { PrimaryNavigationMenu } from "@/components/primary-nav";
import { Providers } from "@/components/providers/providers";
import { ThemeProvider } from "@/components/providers/theme-provider";
import {ThemeProvider} from "@/components/providers/theme-provider";
import type React from "react";
import {Footer} from "@/components/footer";
import {Header} from "@/components/header";
import {PrimaryNavigationMenu} from "@/components/primary-nav";
import {Providers} from "@/components/providers/providers";
export const metadata: Metadata = {
title: "YeloBit",
description: "Generated by create next app",
icons: "yellow-bit.svg",
};
icons: "yellow-bit.svg"};
export default function RootLayout({
children,
@ -22,15 +21,15 @@ export default function RootLayout({
return (
<html lang="en">
<head>
<link rel="icon" href="/public/favicon.ico" sizes="any" />
<link rel="icon" href="/public/favicon.ico" sizes="any"/>
</head>
<body className={"w-full min-h-screen flex flex-col items-center justify-between"}>
<Providers>
<Header>
<PrimaryNavigationMenu />
<PrimaryNavigationMenu/>
</Header>
{children}
<Footer />
<Footer/>
</Providers>
</body>
</html>

View File

@ -1,15 +1,16 @@
"use client";
"use client"
import {useContext} from "react";
import {UserDataContext} from "@/components/providers/userdata-provider";
import {AccountInfo} from "@/components/account-info";
import { AccountInfo } from "@/components/account-info";
import { UserDataContext } from "@/components/providers/userdata-provider";
import { useContext } from "react";
export function AccountDialog() {
const userContext = useContext(UserDataContext);
const userContext = useContext(UserDataContext)
if (!userContext?.userData) {
userContext?.setUserData({ name: "Mathis" });
return <p>Loading...</p>;
userContext?.setUserData({name: "Mathis"})
return (<p>Loading...</p>)
}
//TODO No account context
@ -17,5 +18,5 @@ export function AccountDialog() {
//TODO Loading context
//TODO Account context
return <AccountInfo userData={userContext.userData} />;
return (<AccountInfo userData={userContext.userData}/>)
}

View File

@ -1,8 +1,9 @@
"use client";
"use client"
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {IUserData} from "@/interfaces/userdata.interface";
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import {
Sheet,
SheetClose,
@ -12,11 +13,11 @@ import {
SheetHeader,
SheetTitle,
SheetTrigger,
} from "@/components/ui/sheet";
import type { IUserData } from "@/interfaces/userdata.interface";
import { User } from "lucide-react";
} from "@/components/ui/sheet"
import {User} from "lucide-react";
export function AccountInfo({ userData }: { userData: IUserData }) {
export function AccountInfo({userData}: {userData: IUserData}) {
return (
<Sheet>
<SheetTrigger asChild>
@ -37,14 +38,7 @@ export function AccountInfo({ userData }: { userData: IUserData }) {
<Label htmlFor="name" className="text-right">
Name
</Label>
<Input
id="name"
placeholder={userData.firstName}
className="col-span-3"
onChange={(event) => {
console.log(event.target.value);
}}
/>
<Input id="name" placeholder={userData.firstName} className="col-span-3" onChange={(event)=>{console.log(event.target.value)}} />
</div>
<div className="grid grid-cols-4 items-center gap-4">
<Label htmlFor="username" className="text-right">
@ -60,5 +54,5 @@ export function AccountInfo({ userData }: { userData: IUserData }) {
</SheetFooter>
</SheetContent>
</Sheet>
);
)
}

View File

@ -1,59 +1,33 @@
import { Copyright } from "lucide-react";
import {Copyright} from "lucide-react";
import Link from "next/link";
export function Footer() {
return (
<footer
className={
"flex flex-col-reverse md:flex-row justify-between gap-2 md:gap-1 items-center p-2 border-t-2 w-full"
}
>
<div
className={
"flex flex-row gap-1 items-center justify-center md:justify-start md:w-1/3 opacity-50"
}
>
<Copyright className={"w-4"} />
<footer className={"flex flex-col-reverse md:flex-row justify-between gap-2 md:gap-1 items-center p-2 border-t-2 w-full"}>
<div className={"flex flex-row gap-1 items-center justify-center md:justify-start md:w-1/3 opacity-50"}>
<Copyright className={"w-4"}/>
<h4 className={"pr-2"}>Yidhra Studio</h4>
<p>
MIT <em>2024</em>
</p>
<p>MIT <em>2024</em></p>
</div>
<div
className={
"flex flex-col flex-wrap md:flex-row max-h-24 md:flex-nowrap gap-1 md:gap-2 items-center justify-evenly w-full md:w-1/3"
}
>
<Link
href={"#"}
className={"p-1 hover:-translate-y-1.5 hover:text-primary w-1/2"}
>
<div className={"flex flex-col flex-wrap md:flex-row max-h-24 md:flex-nowrap gap-1 md:gap-2 items-center justify-evenly w-full md:w-1/3"}>
<Link href={"#"} className={"p-1 hover:-translate-y-1.5 hover:text-primary w-1/2"}>
<h3 className={"text-nowrap text-center"}>Data privacy</h3>
</Link>
<Link
href={"#"}
className={"p-1 hover:-translate-y-1.5 hover:text-primary w-1/2"}
>
<Link href={"#"} className={"p-1 hover:-translate-y-1.5 hover:text-primary w-1/2"}>
<h3 className={"text-nowrap text-center"}>Terms and conditions</h3>
</Link>
<Link
href={"#"}
className={"p-1 hover:-translate-y-1.5 hover:text-primary w-1/2"}
>
<Link href={"#"} className={"p-1 hover:-translate-y-1.5 hover:text-primary w-1/2"}>
<h3 className={"text-nowrap text-center"}>Legal notice</h3>
</Link>
<Link
href={"#"}
className={"p-1 hover:-translate-y-1.5 hover:text-primary w-1/2"}
>
<Link href={"#"} className={"p-1 hover:-translate-y-1.5 hover:text-primary w-1/2"}>
<h3 className={"text-nowrap text-center"}>Support Center</h3>
</Link>
</div>
<div
className={
"flex flex-row gap-1 items-center justify-center md:justify-end md:w-1/3"
}
></div>
<div className={"flex flex-row gap-1 items-center justify-center md:justify-end md:w-1/3"}>
</div>
</footer>
);
)
}

View File

@ -1,33 +1,26 @@
import { AccountDialog } from "@/components/account-dialog";
import { ThemeBtnSelector } from "@/components/theme-btn-selector";
import Image from "next/image";
import type React from "react";
import React from "react";
import {ThemeBtnSelector} from "@/components/theme-btn-selector";
import {AccountDialog} from "@/components/account-dialog";
export function Header({title, children}: {title?: string, children?: React.ReactNode}) {
export function Header({
title,
children,
}: { title?: string; children?: React.ReactNode }) {
return (
<header
className={
"flex flex-col md:flex-row justify-between items-center w-full p-1 md:px-3 md:py-2 border-b-2"
}
>
<div
className={
"flex flex-row justify-center md:justify-start items-center gap-2 md:w-1/3"
}
>
<Image src={"yellow-bit.svg"} alt={"Logo of YeloBit"} width={42} height={42} />
<h1 className={"font-bold text-xl align-middle text-center text-wrap"}>
{title || "YeloBit"}
</h1>
<header className={"flex flex-col md:flex-row justify-between items-center w-full p-1 md:px-3 md:py-2 border-b-2"}>
<div className={"flex flex-row justify-center md:justify-start items-center gap-2 md:w-1/3"}>
<Image src={'yellow-bit.svg'} alt={'Logo of YeloBit'} width={42} height={42}/>
<h1 className={"font-bold text-xl align-middle text-center text-wrap"}>{title || 'YeloBit'}</h1>
</div>
<div className={"w-1/3 flex flex-row justify-center items-center"}>
{children}
</div>
<div className={"w-1/3 flex flex-row justify-center items-center"}>{children}</div>
<div className={"w-1/3 flex flex-row justify-end gap-2 items-center"}>
<AccountDialog />
<ThemeBtnSelector />
<AccountDialog/>
<ThemeBtnSelector/>
</div>
</header>
);
)
}

View File

@ -1,8 +1,9 @@
"use client";
"use client"
import Link from "next/link";
import * as React from "react";
import * as React from "react"
import Link from "next/link"
import { cn } from "@/lib/utils"
import {
NavigationMenu,
NavigationMenuContent,
@ -11,10 +12,9 @@ import {
NavigationMenuList,
NavigationMenuTrigger,
navigationMenuTriggerStyle,
} from "@/components/ui/navigation-menu";
import { cn } from "@/lib/utils";
import { Boxes, Info } from "lucide-react";
} from "@/components/ui/navigation-menu"
import Image from "next/image";
import {Boxes, Info} from "lucide-react";
const components: { title: string; href: string; description: string }[] = [
{
@ -26,7 +26,8 @@ const components: { title: string; href: string; description: string }[] = [
{
title: "Hover Card",
href: "/docs/primitives/hover-card",
description: "For sighted users to preview content available behind a link.",
description:
"For sighted users to preview content available behind a link.",
},
{
title: "Progress",
@ -51,17 +52,14 @@ const components: { title: string; href: string; description: string }[] = [
description:
"A popup that displays information related to an element when the element receives keyboard focus or the mouse hovers over it.",
},
];
]
export function PrimaryNavigationMenu() {
return (
<NavigationMenu>
<NavigationMenuList className={"flex flex-row flex-wrap md:flex-nowrap"}>
<NavigationMenuItem className={"relative"}>
<NavigationMenuTrigger className={"gap-1"}>
<Info className={"w-4"} />
Getting started
</NavigationMenuTrigger>
<NavigationMenuTrigger className={"gap-1"}><Info className={"w-4"} />Getting started</NavigationMenuTrigger>
<NavigationMenuContent className={""}>
<ul className="grid gap-3 p-6 md:w-[400px] lg:w-[500px] lg:grid-cols-[.75fr_1fr]">
<li className="row-span-3">
@ -70,16 +68,14 @@ export function PrimaryNavigationMenu() {
className="flex h-full w-full select-none flex-col justify-end rounded-md bg-gradient-to-b from-muted/50 to-muted p-6 no-underline outline-none focus:shadow-md"
href="/"
>
<Image
src={"logo-red.svg"}
alt={"Logo of Yidhra Studio"}
width={64}
height={64}
/>
<div className="mb-2 mt-4 text-lg font-medium">shadcn/ui</div>
<Image src={'logo-red.svg'} alt={'Logo of Yidhra Studio'} width={64} height={64}/>
<div className="mb-2 mt-4 text-lg font-medium">
shadcn/ui
</div>
<p className="text-sm leading-tight text-muted-foreground">
Beautifully designed components that you can copy and paste into
your apps. Accessible. Customizable. Open Source.
Beautifully designed components that you can copy and
paste into your apps. Accessible. Customizable. Open
Source.
</p>
</a>
</NavigationMenuLink>
@ -97,10 +93,7 @@ export function PrimaryNavigationMenu() {
</NavigationMenuContent>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuTrigger className={"gap-1"}>
<Boxes className={"w-4"} />
Features
</NavigationMenuTrigger>
<NavigationMenuTrigger className={"gap-1"}><Boxes className={"w-4"} />Features</NavigationMenuTrigger>
<NavigationMenuContent>
<ul className="grid w-[400px] gap-3 p-4 md:w-[500px] md:grid-cols-2 lg:w-[600px] ">
{components.map((component) => (
@ -124,7 +117,7 @@ export function PrimaryNavigationMenu() {
</NavigationMenuItem>
</NavigationMenuList>
</NavigationMenu>
);
)
}
const ListItem = React.forwardRef<
@ -138,7 +131,7 @@ const ListItem = React.forwardRef<
ref={ref}
className={cn(
"block select-none space-y-1 rounded-md p-3 leading-none no-underline outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground",
className,
className
)}
{...props}
>
@ -149,6 +142,6 @@ const ListItem = React.forwardRef<
</a>
</NavigationMenuLink>
</li>
);
});
ListItem.displayName = "ListItem";
)
})
ListItem.displayName = "ListItem"

View File

@ -1,14 +1,23 @@
"use client";
import { Footer } from "@/components/footer";
import { Header } from "@/components/header";
import { ThemeProvider } from "@/components/providers/theme-provider";
import { UserDataProvider } from "@/components/providers/userdata-provider";
import type React from "react";
"use client"
import React from "react";
import {Header} from "@/components/header";
import {Footer} from "@/components/footer";
import {ThemeProvider} from "@/components/providers/theme-provider";
import {UserDataProvider} from "@/components/providers/userdata-provider";
export function Providers({children}: { children: React.ReactNode }) {
export function Providers({ children }: { children: React.ReactNode }) {
return (
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
<UserDataProvider>{children}</UserDataProvider>
<ThemeProvider
attribute="class"
defaultTheme="system"
enableSystem
>
<UserDataProvider>
{children}
</UserDataProvider>
</ThemeProvider>
);
)
}

View File

@ -1,9 +1,9 @@
"use client";
"use client"
import { ThemeProvider as NextThemesProvider } from "next-themes";
import type { ThemeProviderProps } from "next-themes/dist/types";
import * as React from "react";
import * as React from "react"
import { ThemeProvider as NextThemesProvider } from "next-themes"
import { type ThemeProviderProps } from "next-themes/dist/types"
export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
return <NextThemesProvider {...props}>{children}</NextThemesProvider>;
return <NextThemesProvider {...props}>{children}</NextThemesProvider>
}

View File

@ -1,24 +1,20 @@
import type { IUserData } from "@/interfaces/userdata.interface";
import { useEncodedLocalStorage } from "@/services/localStorage";
import React from "react";
import React from 'react';
import {IUserData} from "@/interfaces/userdata.interface";
import {useEncodedLocalStorage} from "@/services/localStorage";
export interface IUserDataProvider {
userData: IUserData | undefined;
setUserData: React.Dispatch<React.SetStateAction<IUserData | undefined>>;
setUserData: React.Dispatch<React.SetStateAction<IUserData | undefined>>
}
export const UserDataContext = React.createContext<IUserDataProvider | undefined>(
undefined,
);
export const UserDataContext = React.createContext<IUserDataProvider | undefined>(undefined);
export const UserDataProvider = ({children}: {children: React.ReactNode}) => {
const [userData, setUserData] = useEncodedLocalStorage<IUserData | undefined>("user_data", undefined);
export const UserDataProvider = ({ children }: { children: React.ReactNode }) => {
const [userData, setUserData] = useEncodedLocalStorage<IUserData | undefined>(
"user_data",
undefined,
);
return (
<UserDataContext.Provider value={{ userData, setUserData }}>
<UserDataContext.Provider value={{userData, setUserData}}>
{children}
</UserDataContext.Provider>
);

View File

@ -1,19 +1,19 @@
"use client";
"use client"
import { MoonStar, Sun } from "lucide-react";
import { useTheme } from "next-themes";
import * as React from "react";
import * as React from "react"
import {MoonStar, Sun} from "lucide-react";
import { useTheme } from "next-themes"
import { Button } from "@/components/ui/button";
import { Button } from "@/components/ui/button"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
} from "@/components/ui/dropdown-menu"
export function ThemeBtnSelector() {
const { setTheme } = useTheme();
const { setTheme } = useTheme()
return (
<DropdownMenu>
@ -25,10 +25,16 @@ export function ThemeBtnSelector() {
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem onClick={() => setTheme("light")}>Light</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme("dark")}>Dark</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme("system")}>System</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme("light")}>
Light
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme("dark")}>
Dark
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme("system")}>
System
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
)
}

View File

@ -1,20 +1,24 @@
"use client";
"use client"
import * as AccordionPrimitive from "@radix-ui/react-accordion";
import { ChevronDown } from "lucide-react";
import * as React from "react";
import * as React from "react"
import * as AccordionPrimitive from "@radix-ui/react-accordion"
import { ChevronDown } from "lucide-react"
import { cn } from "@/lib/utils";
import { cn } from "@/lib/utils"
const Accordion = AccordionPrimitive.Root;
const Accordion = AccordionPrimitive.Root
const AccordionItem = React.forwardRef<
React.ElementRef<typeof AccordionPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>
>(({ className, ...props }, ref) => (
<AccordionPrimitive.Item ref={ref} className={cn("border-b", className)} {...props} />
));
AccordionItem.displayName = "AccordionItem";
<AccordionPrimitive.Item
ref={ref}
className={cn("border-b", className)}
{...props}
/>
))
AccordionItem.displayName = "AccordionItem"
const AccordionTrigger = React.forwardRef<
React.ElementRef<typeof AccordionPrimitive.Trigger>,
@ -25,7 +29,7 @@ const AccordionTrigger = React.forwardRef<
ref={ref}
className={cn(
"flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180",
className,
className
)}
{...props}
>
@ -33,8 +37,8 @@ const AccordionTrigger = React.forwardRef<
<ChevronDown className="h-4 w-4 shrink-0 transition-transform duration-200" />
</AccordionPrimitive.Trigger>
</AccordionPrimitive.Header>
));
AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName;
))
AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName
const AccordionContent = React.forwardRef<
React.ElementRef<typeof AccordionPrimitive.Content>,
@ -47,8 +51,8 @@ const AccordionContent = React.forwardRef<
>
<div className={cn("pb-4 pt-0", className)}>{children}</div>
</AccordionPrimitive.Content>
));
))
AccordionContent.displayName = AccordionPrimitive.Content.displayName;
AccordionContent.displayName = AccordionPrimitive.Content.displayName
export { Accordion, AccordionItem, AccordionTrigger, AccordionContent };
export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }

View File

@ -1,16 +1,16 @@
"use client";
"use client"
import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";
import * as React from "react";
import * as React from "react"
import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog"
import { buttonVariants } from "@/components/ui/button";
import { cn } from "@/lib/utils";
import { cn } from "@/lib/utils"
import { buttonVariants } from "@/components/ui/button"
const AlertDialog = AlertDialogPrimitive.Root;
const AlertDialog = AlertDialogPrimitive.Root
const AlertDialogTrigger = AlertDialogPrimitive.Trigger;
const AlertDialogTrigger = AlertDialogPrimitive.Trigger
const AlertDialogPortal = AlertDialogPrimitive.Portal;
const AlertDialogPortal = AlertDialogPrimitive.Portal
const AlertDialogOverlay = React.forwardRef<
React.ElementRef<typeof AlertDialogPrimitive.Overlay>,
@ -19,13 +19,13 @@ const AlertDialogOverlay = React.forwardRef<
<AlertDialogPrimitive.Overlay
className={cn(
"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
className,
className
)}
{...props}
ref={ref}
/>
));
AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;
))
AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName
const AlertDialogContent = React.forwardRef<
React.ElementRef<typeof AlertDialogPrimitive.Content>,
@ -37,24 +37,27 @@ const AlertDialogContent = React.forwardRef<
ref={ref}
className={cn(
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
className,
className
)}
{...props}
/>
</AlertDialogPortal>
));
AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName;
))
AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName
const AlertDialogHeader = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn("flex flex-col space-y-2 text-center sm:text-left", className)}
className={cn(
"flex flex-col space-y-2 text-center sm:text-left",
className
)}
{...props}
/>
);
AlertDialogHeader.displayName = "AlertDialogHeader";
)
AlertDialogHeader.displayName = "AlertDialogHeader"
const AlertDialogFooter = ({
className,
@ -63,12 +66,12 @@ const AlertDialogFooter = ({
<div
className={cn(
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
className,
className
)}
{...props}
/>
);
AlertDialogFooter.displayName = "AlertDialogFooter";
)
AlertDialogFooter.displayName = "AlertDialogFooter"
const AlertDialogTitle = React.forwardRef<
React.ElementRef<typeof AlertDialogPrimitive.Title>,
@ -79,8 +82,8 @@ const AlertDialogTitle = React.forwardRef<
className={cn("text-lg font-semibold", className)}
{...props}
/>
));
AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;
))
AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName
const AlertDialogDescription = React.forwardRef<
React.ElementRef<typeof AlertDialogPrimitive.Description>,
@ -91,8 +94,9 @@ const AlertDialogDescription = React.forwardRef<
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
));
AlertDialogDescription.displayName = AlertDialogPrimitive.Description.displayName;
))
AlertDialogDescription.displayName =
AlertDialogPrimitive.Description.displayName
const AlertDialogAction = React.forwardRef<
React.ElementRef<typeof AlertDialogPrimitive.Action>,
@ -103,8 +107,8 @@ const AlertDialogAction = React.forwardRef<
className={cn(buttonVariants(), className)}
{...props}
/>
));
AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName;
))
AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName
const AlertDialogCancel = React.forwardRef<
React.ElementRef<typeof AlertDialogPrimitive.Cancel>,
@ -112,11 +116,15 @@ const AlertDialogCancel = React.forwardRef<
>(({ className, ...props }, ref) => (
<AlertDialogPrimitive.Cancel
ref={ref}
className={cn(buttonVariants({ variant: "outline" }), "mt-2 sm:mt-0", className)}
className={cn(
buttonVariants({ variant: "outline" }),
"mt-2 sm:mt-0",
className
)}
{...props}
/>
));
AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;
))
AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName
export {
AlertDialog,
@ -130,4 +138,4 @@ export {
AlertDialogDescription,
AlertDialogAction,
AlertDialogCancel,
};
}

View File

@ -1,7 +1,7 @@
import { type VariantProps, cva } from "class-variance-authority";
import * as React from "react";
import * as React from "react"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils";
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",
@ -16,8 +16,8 @@ const alertVariants = cva(
defaultVariants: {
variant: "default",
},
},
);
}
)
const Alert = React.forwardRef<
HTMLDivElement,
@ -29,8 +29,8 @@ const Alert = React.forwardRef<
className={cn(alertVariants({ variant }), className)}
{...props}
/>
));
Alert.displayName = "Alert";
))
Alert.displayName = "Alert"
const AlertTitle = React.forwardRef<
HTMLParagraphElement,
@ -41,15 +41,19 @@ const AlertTitle = React.forwardRef<
className={cn("mb-1 font-medium leading-none tracking-tight", className)}
{...props}
/>
));
AlertTitle.displayName = "AlertTitle";
))
AlertTitle.displayName = "AlertTitle"
const AlertDescription = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLParagraphElement>
>(({ className, ...props }, ref) => (
<div ref={ref} className={cn("text-sm [&_p]:leading-relaxed", className)} {...props} />
));
AlertDescription.displayName = "AlertDescription";
<div
ref={ref}
className={cn("text-sm [&_p]:leading-relaxed", className)}
{...props}
/>
))
AlertDescription.displayName = "AlertDescription"
export { Alert, AlertTitle, AlertDescription };
export { Alert, AlertTitle, AlertDescription }

View File

@ -1,7 +1,7 @@
"use client";
"use client"
import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio";
import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio"
const AspectRatio = AspectRatioPrimitive.Root;
const AspectRatio = AspectRatioPrimitive.Root
export { AspectRatio };
export { AspectRatio }

View File

@ -1,9 +1,9 @@
"use client";
"use client"
import * as AvatarPrimitive from "@radix-ui/react-avatar";
import * as React from "react";
import * as React from "react"
import * as AvatarPrimitive from "@radix-ui/react-avatar"
import { cn } from "@/lib/utils";
import { cn } from "@/lib/utils"
const Avatar = React.forwardRef<
React.ElementRef<typeof AvatarPrimitive.Root>,
@ -13,12 +13,12 @@ const Avatar = React.forwardRef<
ref={ref}
className={cn(
"relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
className,
className
)}
{...props}
/>
));
Avatar.displayName = AvatarPrimitive.Root.displayName;
))
Avatar.displayName = AvatarPrimitive.Root.displayName
const AvatarImage = React.forwardRef<
React.ElementRef<typeof AvatarPrimitive.Image>,
@ -29,8 +29,8 @@ const AvatarImage = React.forwardRef<
className={cn("aspect-square h-full w-full", className)}
{...props}
/>
));
AvatarImage.displayName = AvatarPrimitive.Image.displayName;
))
AvatarImage.displayName = AvatarPrimitive.Image.displayName
const AvatarFallback = React.forwardRef<
React.ElementRef<typeof AvatarPrimitive.Fallback>,
@ -40,11 +40,11 @@ const AvatarFallback = React.forwardRef<
ref={ref}
className={cn(
"flex h-full w-full items-center justify-center rounded-full bg-muted",
className,
className
)}
{...props}
/>
));
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
))
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName
export { Avatar, AvatarImage, AvatarFallback };
export { Avatar, AvatarImage, AvatarFallback }

View File

@ -1,7 +1,7 @@
import { type VariantProps, cva } from "class-variance-authority";
import type * as React from "react";
import * as React from "react"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils";
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",
@ -20,15 +20,17 @@ const badgeVariants = cva(
defaultVariants: {
variant: "default",
},
},
);
}
)
export interface BadgeProps
extends React.HTMLAttributes<HTMLDivElement>,
VariantProps<typeof badgeVariants> {}
function Badge({ className, variant, ...props }: BadgeProps) {
return <div className={cn(badgeVariants({ variant }), className)} {...props} />;
return (
<div className={cn(badgeVariants({ variant }), className)} {...props} />
)
}
export { Badge, badgeVariants };
export { Badge, badgeVariants }

View File

@ -1,16 +1,16 @@
import { Slot } from "@radix-ui/react-slot";
import { ChevronRight, MoreHorizontal } from "lucide-react";
import * as React from "react";
import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { ChevronRight, MoreHorizontal } from "lucide-react"
import { cn } from "@/lib/utils";
import { cn } from "@/lib/utils"
const Breadcrumb = React.forwardRef<
HTMLElement,
React.ComponentPropsWithoutRef<"nav"> & {
separator?: React.ReactNode;
separator?: React.ReactNode
}
>(({ ...props }, ref) => <nav ref={ref} aria-label="breadcrumb" {...props} />);
Breadcrumb.displayName = "Breadcrumb";
>(({ ...props }, ref) => <nav ref={ref} aria-label="breadcrumb" {...props} />)
Breadcrumb.displayName = "Breadcrumb"
const BreadcrumbList = React.forwardRef<
HTMLOListElement,
@ -20,12 +20,12 @@ const BreadcrumbList = React.forwardRef<
ref={ref}
className={cn(
"flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5",
className,
className
)}
{...props}
/>
));
BreadcrumbList.displayName = "BreadcrumbList";
))
BreadcrumbList.displayName = "BreadcrumbList"
const BreadcrumbItem = React.forwardRef<
HTMLLIElement,
@ -36,16 +36,16 @@ const BreadcrumbItem = React.forwardRef<
className={cn("inline-flex items-center gap-1.5", className)}
{...props}
/>
));
BreadcrumbItem.displayName = "BreadcrumbItem";
))
BreadcrumbItem.displayName = "BreadcrumbItem"
const BreadcrumbLink = React.forwardRef<
HTMLAnchorElement,
React.ComponentPropsWithoutRef<"a"> & {
asChild?: boolean;
asChild?: boolean
}
>(({ asChild, className, ...props }, ref) => {
const Comp = asChild ? Slot : "a";
const Comp = asChild ? Slot : "a"
return (
<Comp
@ -53,9 +53,9 @@ const BreadcrumbLink = React.forwardRef<
className={cn("transition-colors hover:text-foreground", className)}
{...props}
/>
);
});
BreadcrumbLink.displayName = "BreadcrumbLink";
)
})
BreadcrumbLink.displayName = "BreadcrumbLink"
const BreadcrumbPage = React.forwardRef<
HTMLSpanElement,
@ -69,8 +69,8 @@ const BreadcrumbPage = React.forwardRef<
className={cn("font-normal text-foreground", className)}
{...props}
/>
));
BreadcrumbPage.displayName = "BreadcrumbPage";
))
BreadcrumbPage.displayName = "BreadcrumbPage"
const BreadcrumbSeparator = ({
children,
@ -85,10 +85,13 @@ const BreadcrumbSeparator = ({
>
{children ?? <ChevronRight />}
</li>
);
BreadcrumbSeparator.displayName = "BreadcrumbSeparator";
)
BreadcrumbSeparator.displayName = "BreadcrumbSeparator"
const BreadcrumbEllipsis = ({ className, ...props }: React.ComponentProps<"span">) => (
const BreadcrumbEllipsis = ({
className,
...props
}: React.ComponentProps<"span">) => (
<span
role="presentation"
aria-hidden="true"
@ -98,8 +101,8 @@ const BreadcrumbEllipsis = ({ className, ...props }: React.ComponentProps<"span"
<MoreHorizontal className="h-4 w-4" />
<span className="sr-only">More</span>
</span>
);
BreadcrumbEllipsis.displayName = "BreadcrumbElipssis";
)
BreadcrumbEllipsis.displayName = "BreadcrumbElipssis"
export {
Breadcrumb,
@ -109,4 +112,4 @@ export {
BreadcrumbPage,
BreadcrumbSeparator,
BreadcrumbEllipsis,
};
}

View File

@ -1,8 +1,8 @@
import { Slot } from "@radix-ui/react-slot";
import { type VariantProps, cva } from "class-variance-authority";
import * as React from "react";
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";
import { cn } from "@/lib/utils"
const buttonVariants = cva(
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
@ -10,10 +10,12 @@ const buttonVariants = cva(
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
destructive:
"bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline:
"border border-input bg-background hover:bg-accent hover:text-accent-foreground",
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
secondary:
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
},
@ -28,27 +30,27 @@ const buttonVariants = cva(
variant: "default",
size: "default",
},
},
);
}
)
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean;
asChild?: boolean
}
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button";
const Comp = asChild ? Slot : "button"
return (
<Comp
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
/>
);
},
);
Button.displayName = "Button";
)
}
)
Button.displayName = "Button"
export { Button, buttonVariants };
export { Button, buttonVariants }

View File

@ -1,13 +1,13 @@
"use client";
"use client"
import { ChevronLeft, ChevronRight } from "lucide-react";
import type * as React from "react";
import { DayPicker } from "react-day-picker";
import * as React from "react"
import { ChevronLeft, ChevronRight } from "lucide-react"
import { DayPicker } from "react-day-picker"
import { buttonVariants } from "@/components/ui/button";
import { cn } from "@/lib/utils";
import { cn } from "@/lib/utils"
import { buttonVariants } from "@/components/ui/button"
export type CalendarProps = React.ComponentProps<typeof DayPicker>;
export type CalendarProps = React.ComponentProps<typeof DayPicker>
function Calendar({
className,
@ -27,18 +27,19 @@ function Calendar({
nav: "space-x-1 flex items-center",
nav_button: cn(
buttonVariants({ variant: "outline" }),
"h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100",
"h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100"
),
nav_button_previous: "absolute left-1",
nav_button_next: "absolute right-1",
table: "w-full border-collapse space-y-1",
head_row: "flex",
head_cell: "text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]",
head_cell:
"text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]",
row: "flex w-full mt-2",
cell: "h-9 w-9 text-center text-sm p-0 relative [&:has([aria-selected].day-range-end)]:rounded-r-md [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20",
day: cn(
buttonVariants({ variant: "ghost" }),
"h-9 w-9 p-0 font-normal aria-selected:opacity-100",
"h-9 w-9 p-0 font-normal aria-selected:opacity-100"
),
day_range_end: "day-range-end",
day_selected:
@ -47,7 +48,8 @@ function Calendar({
day_outside:
"day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30",
day_disabled: "text-muted-foreground opacity-50",
day_range_middle: "aria-selected:bg-accent aria-selected:text-accent-foreground",
day_range_middle:
"aria-selected:bg-accent aria-selected:text-accent-foreground",
day_hidden: "invisible",
...classNames,
}}
@ -57,8 +59,8 @@ function Calendar({
}}
{...props}
/>
);
)
}
Calendar.displayName = "Calendar";
Calendar.displayName = "Calendar"
export { Calendar };
export { Calendar }

View File

@ -1,31 +1,33 @@
import * as React from "react";
import * as React from "react"
import { cn } from "@/lib/utils";
import { cn } from "@/lib/utils"
const Card = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
({ className, ...props }, ref) => (
const Card = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn(
"rounded-lg border bg-card text-card-foreground shadow-sm",
className,
className
)}
{...props}
/>
),
);
Card.displayName = "Card";
))
Card.displayName = "Card"
const CardHeader = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
({ className, ...props }, ref) => (
const CardHeader = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("flex flex-col space-y-1.5 p-6", className)}
{...props}
/>
),
);
CardHeader.displayName = "CardHeader";
))
CardHeader.displayName = "CardHeader"
const CardTitle = React.forwardRef<
HTMLParagraphElement,
@ -33,33 +35,45 @@ const CardTitle = React.forwardRef<
>(({ className, ...props }, ref) => (
<h3
ref={ref}
className={cn("text-2xl font-semibold leading-none tracking-tight", className)}
className={cn(
"text-2xl font-semibold leading-none tracking-tight",
className
)}
{...props}
/>
));
CardTitle.displayName = "CardTitle";
))
CardTitle.displayName = "CardTitle"
const CardDescription = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLParagraphElement>
>(({ className, ...props }, ref) => (
<p ref={ref} className={cn("text-sm text-muted-foreground", className)} {...props} />
));
CardDescription.displayName = "CardDescription";
<p
ref={ref}
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
))
CardDescription.displayName = "CardDescription"
const CardContent = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
));
CardContent.displayName = "CardContent";
))
CardContent.displayName = "CardContent"
const CardFooter = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
({ className, ...props }, ref) => (
<div ref={ref} className={cn("flex items-center p-6 pt-0", className)} {...props} />
),
);
CardFooter.displayName = "CardFooter";
const CardFooter = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("flex items-center p-6 pt-0", className)}
{...props}
/>
))
CardFooter.displayName = "CardFooter"
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent };
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }

View File

@ -1,43 +1,45 @@
"use client";
"use client"
import useEmblaCarousel, { type UseEmblaCarouselType } from "embla-carousel-react";
import { ArrowLeft, ArrowRight } from "lucide-react";
import * as React from "react";
import * as React from "react"
import useEmblaCarousel, {
type UseEmblaCarouselType,
} from "embla-carousel-react"
import { ArrowLeft, ArrowRight } from "lucide-react"
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
import { cn } from "@/lib/utils"
import { Button } from "@/components/ui/button"
type CarouselApi = UseEmblaCarouselType[1];
type UseCarouselParameters = Parameters<typeof useEmblaCarousel>;
type CarouselOptions = UseCarouselParameters[0];
type CarouselPlugin = UseCarouselParameters[1];
type CarouselApi = UseEmblaCarouselType[1]
type UseCarouselParameters = Parameters<typeof useEmblaCarousel>
type CarouselOptions = UseCarouselParameters[0]
type CarouselPlugin = UseCarouselParameters[1]
type CarouselProps = {
opts?: CarouselOptions;
plugins?: CarouselPlugin;
orientation?: "horizontal" | "vertical";
setApi?: (api: CarouselApi) => void;
};
opts?: CarouselOptions
plugins?: CarouselPlugin
orientation?: "horizontal" | "vertical"
setApi?: (api: CarouselApi) => void
}
type CarouselContextProps = {
carouselRef: ReturnType<typeof useEmblaCarousel>[0];
api: ReturnType<typeof useEmblaCarousel>[1];
scrollPrev: () => void;
scrollNext: () => void;
canScrollPrev: boolean;
canScrollNext: boolean;
} & CarouselProps;
carouselRef: ReturnType<typeof useEmblaCarousel>[0]
api: ReturnType<typeof useEmblaCarousel>[1]
scrollPrev: () => void
scrollNext: () => void
canScrollPrev: boolean
canScrollNext: boolean
} & CarouselProps
const CarouselContext = React.createContext<CarouselContextProps | null>(null);
const CarouselContext = React.createContext<CarouselContextProps | null>(null)
function useCarousel() {
const context = React.useContext(CarouselContext);
const context = React.useContext(CarouselContext)
if (!context) {
throw new Error("useCarousel must be used within a <Carousel />");
throw new Error("useCarousel must be used within a <Carousel />")
}
return context;
return context
}
const Carousel = React.forwardRef<
@ -45,70 +47,78 @@ const Carousel = React.forwardRef<
React.HTMLAttributes<HTMLDivElement> & CarouselProps
>(
(
{ orientation = "horizontal", opts, setApi, plugins, className, children, ...props },
ref,
{
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);
plugins
)
const [canScrollPrev, setCanScrollPrev] = React.useState(false)
const [canScrollNext, setCanScrollNext] = React.useState(false)
const onSelect = React.useCallback((api: CarouselApi) => {
if (!api) {
return;
return
}
setCanScrollPrev(api.canScrollPrev());
setCanScrollNext(api.canScrollNext());
}, []);
setCanScrollPrev(api.canScrollPrev())
setCanScrollNext(api.canScrollNext())
}, [])
const scrollPrev = React.useCallback(() => {
api?.scrollPrev();
}, [api]);
api?.scrollPrev()
}, [api])
const scrollNext = React.useCallback(() => {
api?.scrollNext();
}, [api]);
api?.scrollNext()
}, [api])
const handleKeyDown = React.useCallback(
(event: React.KeyboardEvent<HTMLDivElement>) => {
if (event.key === "ArrowLeft") {
event.preventDefault();
scrollPrev();
event.preventDefault()
scrollPrev()
} else if (event.key === "ArrowRight") {
event.preventDefault();
scrollNext();
event.preventDefault()
scrollNext()
}
},
[scrollPrev, scrollNext],
);
[scrollPrev, scrollNext]
)
React.useEffect(() => {
if (!api || !setApi) {
return;
return
}
setApi(api);
}, [api, setApi]);
setApi(api)
}, [api, setApi])
React.useEffect(() => {
if (!api) {
return;
return
}
onSelect(api);
api.on("reInit", onSelect);
api.on("select", onSelect);
onSelect(api)
api.on("reInit", onSelect)
api.on("select", onSelect)
return () => {
api?.off("select", onSelect);
};
}, [api, onSelect]);
api?.off("select", onSelect)
}
}, [api, onSelect])
return (
<CarouselContext.Provider
@ -116,7 +126,8 @@ const Carousel = React.forwardRef<
carouselRef,
api: api,
opts,
orientation: orientation || (opts?.axis === "y" ? "vertical" : "horizontal"),
orientation:
orientation || (opts?.axis === "y" ? "vertical" : "horizontal"),
scrollPrev,
scrollNext,
canScrollPrev,
@ -134,16 +145,16 @@ const Carousel = React.forwardRef<
{children}
</div>
</CarouselContext.Provider>
);
},
);
Carousel.displayName = "Carousel";
)
}
)
Carousel.displayName = "Carousel"
const CarouselContent = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => {
const { carouselRef, orientation } = useCarousel();
const { carouselRef, orientation } = useCarousel()
return (
<div ref={carouselRef} className="overflow-hidden">
@ -152,20 +163,20 @@ const CarouselContent = React.forwardRef<
className={cn(
"flex",
orientation === "horizontal" ? "-ml-4" : "-mt-4 flex-col",
className,
className
)}
{...props}
/>
</div>
);
});
CarouselContent.displayName = "CarouselContent";
)
})
CarouselContent.displayName = "CarouselContent"
const CarouselItem = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => {
const { orientation } = useCarousel();
const { orientation } = useCarousel()
return (
<div
@ -175,19 +186,19 @@ const CarouselItem = React.forwardRef<
className={cn(
"min-w-0 shrink-0 grow-0 basis-full",
orientation === "horizontal" ? "pl-4" : "pt-4",
className,
className
)}
{...props}
/>
);
});
CarouselItem.displayName = "CarouselItem";
)
})
CarouselItem.displayName = "CarouselItem"
const CarouselPrevious = React.forwardRef<
HTMLButtonElement,
React.ComponentProps<typeof Button>
>(({ className, variant = "outline", size = "icon", ...props }, ref) => {
const { orientation, scrollPrev, canScrollPrev } = useCarousel();
const { orientation, scrollPrev, canScrollPrev } = useCarousel()
return (
<Button
@ -199,7 +210,7 @@ const CarouselPrevious = React.forwardRef<
orientation === "horizontal"
? "-left-12 top-1/2 -translate-y-1/2"
: "-top-12 left-1/2 -translate-x-1/2 rotate-90",
className,
className
)}
disabled={!canScrollPrev}
onClick={scrollPrev}
@ -208,15 +219,15 @@ const CarouselPrevious = React.forwardRef<
<ArrowLeft className="h-4 w-4" />
<span className="sr-only">Previous slide</span>
</Button>
);
});
CarouselPrevious.displayName = "CarouselPrevious";
)
})
CarouselPrevious.displayName = "CarouselPrevious"
const CarouselNext = React.forwardRef<
HTMLButtonElement,
React.ComponentProps<typeof Button>
>(({ className, variant = "outline", size = "icon", ...props }, ref) => {
const { orientation, scrollNext, canScrollNext } = useCarousel();
const { orientation, scrollNext, canScrollNext } = useCarousel()
return (
<Button
@ -228,7 +239,7 @@ const CarouselNext = React.forwardRef<
orientation === "horizontal"
? "-right-12 top-1/2 -translate-y-1/2"
: "-bottom-12 left-1/2 -translate-x-1/2 rotate-90",
className,
className
)}
disabled={!canScrollNext}
onClick={scrollNext}
@ -237,9 +248,9 @@ const CarouselNext = React.forwardRef<
<ArrowRight className="h-4 w-4" />
<span className="sr-only">Next slide</span>
</Button>
);
});
CarouselNext.displayName = "CarouselNext";
)
})
CarouselNext.displayName = "CarouselNext"
export {
type CarouselApi,
@ -248,4 +259,4 @@ export {
CarouselItem,
CarouselPrevious,
CarouselNext,
};
}

View File

@ -1,10 +1,10 @@
"use client";
"use client"
import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
import { Check } from "lucide-react";
import * as React from "react";
import * as React from "react"
import * as CheckboxPrimitive from "@radix-ui/react-checkbox"
import { Check } from "lucide-react"
import { cn } from "@/lib/utils";
import { cn } from "@/lib/utils"
const Checkbox = React.forwardRef<
React.ElementRef<typeof CheckboxPrimitive.Root>,
@ -14,7 +14,7 @@ const Checkbox = React.forwardRef<
ref={ref}
className={cn(
"peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
className,
className
)}
{...props}
>
@ -24,7 +24,7 @@ const Checkbox = React.forwardRef<
<Check className="h-4 w-4" />
</CheckboxPrimitive.Indicator>
</CheckboxPrimitive.Root>
));
Checkbox.displayName = CheckboxPrimitive.Root.displayName;
))
Checkbox.displayName = CheckboxPrimitive.Root.displayName
export { Checkbox };
export { Checkbox }

View File

@ -1,11 +1,11 @@
"use client";
"use client"
import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
import * as CollapsiblePrimitive from "@radix-ui/react-collapsible"
const Collapsible = CollapsiblePrimitive.Root;
const Collapsible = CollapsiblePrimitive.Root
const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger;
const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger
const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent;
const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent
export { Collapsible, CollapsibleTrigger, CollapsibleContent };
export { Collapsible, CollapsibleTrigger, CollapsibleContent }

View File

@ -1,12 +1,12 @@
"use client";
"use client"
import type { DialogProps } from "@radix-ui/react-dialog";
import { Command as CommandPrimitive } from "cmdk";
import { Search } from "lucide-react";
import * as React from "react";
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 { Dialog, DialogContent } from "@/components/ui/dialog";
import { cn } from "@/lib/utils";
import { cn } from "@/lib/utils"
import { Dialog, DialogContent } from "@/components/ui/dialog"
const Command = React.forwardRef<
React.ElementRef<typeof CommandPrimitive>,
@ -16,12 +16,12 @@ const Command = React.forwardRef<
ref={ref}
className={cn(
"flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
className,
className
)}
{...props}
/>
));
Command.displayName = CommandPrimitive.displayName;
))
Command.displayName = CommandPrimitive.displayName
interface CommandDialogProps extends DialogProps {}
@ -34,8 +34,8 @@ const CommandDialog = ({ children, ...props }: CommandDialogProps) => {
</Command>
</DialogContent>
</Dialog>
);
};
)
}
const CommandInput = React.forwardRef<
React.ElementRef<typeof CommandPrimitive.Input>,
@ -47,14 +47,14 @@ const CommandInput = React.forwardRef<
ref={ref}
className={cn(
"flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
className,
className
)}
{...props}
/>
</div>
));
))
CommandInput.displayName = CommandPrimitive.Input.displayName;
CommandInput.displayName = CommandPrimitive.Input.displayName
const CommandList = React.forwardRef<
React.ElementRef<typeof CommandPrimitive.List>,
@ -65,18 +65,22 @@ const CommandList = React.forwardRef<
className={cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className)}
{...props}
/>
));
))
CommandList.displayName = CommandPrimitive.List.displayName;
CommandList.displayName = CommandPrimitive.List.displayName
const CommandEmpty = React.forwardRef<
React.ElementRef<typeof CommandPrimitive.Empty>,
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>
>((props, ref) => (
<CommandPrimitive.Empty ref={ref} className="py-6 text-center text-sm" {...props} />
));
<CommandPrimitive.Empty
ref={ref}
className="py-6 text-center text-sm"
{...props}
/>
))
CommandEmpty.displayName = CommandPrimitive.Empty.displayName;
CommandEmpty.displayName = CommandPrimitive.Empty.displayName
const CommandGroup = React.forwardRef<
React.ElementRef<typeof CommandPrimitive.Group>,
@ -86,13 +90,13 @@ const CommandGroup = React.forwardRef<
ref={ref}
className={cn(
"overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground",
className,
className
)}
{...props}
/>
));
))
CommandGroup.displayName = CommandPrimitive.Group.displayName;
CommandGroup.displayName = CommandPrimitive.Group.displayName
const CommandSeparator = React.forwardRef<
React.ElementRef<typeof CommandPrimitive.Separator>,
@ -103,8 +107,8 @@ const CommandSeparator = React.forwardRef<
className={cn("-mx-1 h-px bg-border", className)}
{...props}
/>
));
CommandSeparator.displayName = CommandPrimitive.Separator.displayName;
))
CommandSeparator.displayName = CommandPrimitive.Separator.displayName
const CommandItem = React.forwardRef<
React.ElementRef<typeof CommandPrimitive.Item>,
@ -114,13 +118,13 @@ const CommandItem = React.forwardRef<
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-50",
className,
className
)}
{...props}
/>
));
))
CommandItem.displayName = CommandPrimitive.Item.displayName;
CommandItem.displayName = CommandPrimitive.Item.displayName
const CommandShortcut = ({
className,
@ -128,12 +132,15 @@ const CommandShortcut = ({
}: React.HTMLAttributes<HTMLSpanElement>) => {
return (
<span
className={cn("ml-auto text-xs tracking-widest text-muted-foreground", className)}
className={cn(
"ml-auto text-xs tracking-widest text-muted-foreground",
className
)}
{...props}
/>
);
};
CommandShortcut.displayName = "CommandShortcut";
)
}
CommandShortcut.displayName = "CommandShortcut"
export {
Command,
@ -145,4 +152,4 @@ export {
CommandItem,
CommandShortcut,
CommandSeparator,
};
}

View File

@ -1,27 +1,27 @@
"use client";
"use client"
import * as ContextMenuPrimitive from "@radix-ui/react-context-menu";
import { Check, ChevronRight, Circle } from "lucide-react";
import * as React from "react";
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";
import { cn } from "@/lib/utils"
const ContextMenu = ContextMenuPrimitive.Root;
const ContextMenu = ContextMenuPrimitive.Root
const ContextMenuTrigger = ContextMenuPrimitive.Trigger;
const ContextMenuTrigger = ContextMenuPrimitive.Trigger
const ContextMenuGroup = ContextMenuPrimitive.Group;
const ContextMenuGroup = ContextMenuPrimitive.Group
const ContextMenuPortal = ContextMenuPrimitive.Portal;
const ContextMenuPortal = ContextMenuPrimitive.Portal
const ContextMenuSub = ContextMenuPrimitive.Sub;
const ContextMenuSub = ContextMenuPrimitive.Sub
const ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup;
const ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup
const ContextMenuSubTrigger = React.forwardRef<
React.ElementRef<typeof ContextMenuPrimitive.SubTrigger>,
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.SubTrigger> & {
inset?: boolean;
inset?: boolean
}
>(({ className, inset, children, ...props }, ref) => (
<ContextMenuPrimitive.SubTrigger
@ -29,15 +29,15 @@ const ContextMenuSubTrigger = React.forwardRef<
className={cn(
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
inset && "pl-8",
className,
className
)}
{...props}
>
{children}
<ChevronRight className="ml-auto h-4 w-4" />
</ContextMenuPrimitive.SubTrigger>
));
ContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName;
))
ContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName
const ContextMenuSubContent = React.forwardRef<
React.ElementRef<typeof ContextMenuPrimitive.SubContent>,
@ -47,12 +47,12 @@ const ContextMenuSubContent = React.forwardRef<
ref={ref}
className={cn(
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className,
className
)}
{...props}
/>
));
ContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName;
))
ContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName
const ContextMenuContent = React.forwardRef<
React.ElementRef<typeof ContextMenuPrimitive.Content>,
@ -63,18 +63,18 @@ const ContextMenuContent = React.forwardRef<
ref={ref}
className={cn(
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md animate-in fade-in-80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className,
className
)}
{...props}
/>
</ContextMenuPrimitive.Portal>
));
ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName;
))
ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName
const ContextMenuItem = React.forwardRef<
React.ElementRef<typeof ContextMenuPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Item> & {
inset?: boolean;
inset?: boolean
}
>(({ className, inset, ...props }, ref) => (
<ContextMenuPrimitive.Item
@ -82,12 +82,12 @@ const ContextMenuItem = React.forwardRef<
className={cn(
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
inset && "pl-8",
className,
className
)}
{...props}
/>
));
ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName;
))
ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName
const ContextMenuCheckboxItem = React.forwardRef<
React.ElementRef<typeof ContextMenuPrimitive.CheckboxItem>,
@ -97,7 +97,7 @@ const ContextMenuCheckboxItem = React.forwardRef<
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className,
className
)}
checked={checked}
{...props}
@ -109,8 +109,9 @@ const ContextMenuCheckboxItem = React.forwardRef<
</span>
{children}
</ContextMenuPrimitive.CheckboxItem>
));
ContextMenuCheckboxItem.displayName = ContextMenuPrimitive.CheckboxItem.displayName;
))
ContextMenuCheckboxItem.displayName =
ContextMenuPrimitive.CheckboxItem.displayName
const ContextMenuRadioItem = React.forwardRef<
React.ElementRef<typeof ContextMenuPrimitive.RadioItem>,
@ -120,7 +121,7 @@ const ContextMenuRadioItem = React.forwardRef<
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className,
className
)}
{...props}
>
@ -131,13 +132,13 @@ const ContextMenuRadioItem = React.forwardRef<
</span>
{children}
</ContextMenuPrimitive.RadioItem>
));
ContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName;
))
ContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName
const ContextMenuLabel = React.forwardRef<
React.ElementRef<typeof ContextMenuPrimitive.Label>,
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Label> & {
inset?: boolean;
inset?: boolean
}
>(({ className, inset, ...props }, ref) => (
<ContextMenuPrimitive.Label
@ -145,12 +146,12 @@ const ContextMenuLabel = React.forwardRef<
className={cn(
"px-2 py-1.5 text-sm font-semibold text-foreground",
inset && "pl-8",
className,
className
)}
{...props}
/>
));
ContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName;
))
ContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName
const ContextMenuSeparator = React.forwardRef<
React.ElementRef<typeof ContextMenuPrimitive.Separator>,
@ -161,8 +162,8 @@ const ContextMenuSeparator = React.forwardRef<
className={cn("-mx-1 my-1 h-px bg-border", className)}
{...props}
/>
));
ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName;
))
ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName
const ContextMenuShortcut = ({
className,
@ -170,12 +171,15 @@ const ContextMenuShortcut = ({
}: React.HTMLAttributes<HTMLSpanElement>) => {
return (
<span
className={cn("ml-auto text-xs tracking-widest text-muted-foreground", className)}
className={cn(
"ml-auto text-xs tracking-widest text-muted-foreground",
className
)}
{...props}
/>
);
};
ContextMenuShortcut.displayName = "ContextMenuShortcut";
)
}
ContextMenuShortcut.displayName = "ContextMenuShortcut"
export {
ContextMenu,
@ -193,4 +197,4 @@ export {
ContextMenuSubContent,
ContextMenuSubTrigger,
ContextMenuRadioGroup,
};
}

View File

@ -1,18 +1,18 @@
"use client";
"use client"
import * as DialogPrimitive from "@radix-ui/react-dialog";
import { X } from "lucide-react";
import * as React from "react";
import * as React from "react"
import * as DialogPrimitive from "@radix-ui/react-dialog"
import { X } from "lucide-react"
import { cn } from "@/lib/utils";
import { cn } from "@/lib/utils"
const Dialog = DialogPrimitive.Root;
const Dialog = DialogPrimitive.Root
const DialogTrigger = DialogPrimitive.Trigger;
const DialogTrigger = DialogPrimitive.Trigger
const DialogPortal = DialogPrimitive.Portal;
const DialogPortal = DialogPrimitive.Portal
const DialogClose = DialogPrimitive.Close;
const DialogClose = DialogPrimitive.Close
const DialogOverlay = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Overlay>,
@ -22,12 +22,12 @@ const DialogOverlay = React.forwardRef<
ref={ref}
className={cn(
"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
className,
className
)}
{...props}
/>
));
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
))
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName
const DialogContent = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Content>,
@ -39,7 +39,7 @@ const DialogContent = React.forwardRef<
ref={ref}
className={cn(
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
className,
className
)}
{...props}
>
@ -50,27 +50,36 @@ const DialogContent = React.forwardRef<
</DialogPrimitive.Close>
</DialogPrimitive.Content>
</DialogPortal>
));
DialogContent.displayName = DialogPrimitive.Content.displayName;
))
DialogContent.displayName = DialogPrimitive.Content.displayName
const DialogHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn("flex flex-col space-y-1.5 text-center sm:text-left", className)}
{...props}
/>
);
DialogHeader.displayName = "DialogHeader";
const DialogFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
const DialogHeader = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
className,
"flex flex-col space-y-1.5 text-center sm:text-left",
className
)}
{...props}
/>
);
DialogFooter.displayName = "DialogFooter";
)
DialogHeader.displayName = "DialogHeader"
const DialogFooter = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
className
)}
{...props}
/>
)
DialogFooter.displayName = "DialogFooter"
const DialogTitle = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Title>,
@ -78,11 +87,14 @@ const DialogTitle = React.forwardRef<
>(({ className, ...props }, ref) => (
<DialogPrimitive.Title
ref={ref}
className={cn("text-lg font-semibold leading-none tracking-tight", className)}
className={cn(
"text-lg font-semibold leading-none tracking-tight",
className
)}
{...props}
/>
));
DialogTitle.displayName = DialogPrimitive.Title.displayName;
))
DialogTitle.displayName = DialogPrimitive.Title.displayName
const DialogDescription = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Description>,
@ -93,8 +105,8 @@ const DialogDescription = React.forwardRef<
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
));
DialogDescription.displayName = DialogPrimitive.Description.displayName;
))
DialogDescription.displayName = DialogPrimitive.Description.displayName
export {
Dialog,
@ -107,4 +119,4 @@ export {
DialogFooter,
DialogTitle,
DialogDescription,
};
}

View File

@ -1,23 +1,26 @@
"use client";
"use client"
import * as React from "react";
import { Drawer as DrawerPrimitive } from "vaul";
import * as React from "react"
import { Drawer as DrawerPrimitive } from "vaul"
import { cn } from "@/lib/utils";
import { cn } from "@/lib/utils"
const Drawer = ({
shouldScaleBackground = true,
...props
}: React.ComponentProps<typeof DrawerPrimitive.Root>) => (
<DrawerPrimitive.Root shouldScaleBackground={shouldScaleBackground} {...props} />
);
Drawer.displayName = "Drawer";
<DrawerPrimitive.Root
shouldScaleBackground={shouldScaleBackground}
{...props}
/>
)
Drawer.displayName = "Drawer"
const DrawerTrigger = DrawerPrimitive.Trigger;
const DrawerTrigger = DrawerPrimitive.Trigger
const DrawerPortal = DrawerPrimitive.Portal;
const DrawerPortal = DrawerPrimitive.Portal
const DrawerClose = DrawerPrimitive.Close;
const DrawerClose = DrawerPrimitive.Close
const DrawerOverlay = React.forwardRef<
React.ElementRef<typeof DrawerPrimitive.Overlay>,
@ -28,8 +31,8 @@ const DrawerOverlay = React.forwardRef<
className={cn("fixed inset-0 z-50 bg-black/80", className)}
{...props}
/>
));
DrawerOverlay.displayName = DrawerPrimitive.Overlay.displayName;
))
DrawerOverlay.displayName = DrawerPrimitive.Overlay.displayName
const DrawerContent = React.forwardRef<
React.ElementRef<typeof DrawerPrimitive.Content>,
@ -41,7 +44,7 @@ const DrawerContent = React.forwardRef<
ref={ref}
className={cn(
"fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border bg-background",
className,
className
)}
{...props}
>
@ -49,21 +52,30 @@ const DrawerContent = React.forwardRef<
{children}
</DrawerPrimitive.Content>
</DrawerPortal>
));
DrawerContent.displayName = "DrawerContent";
))
DrawerContent.displayName = "DrawerContent"
const DrawerHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
const DrawerHeader = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn("grid gap-1.5 p-4 text-center sm:text-left", className)}
{...props}
/>
);
DrawerHeader.displayName = "DrawerHeader";
)
DrawerHeader.displayName = "DrawerHeader"
const DrawerFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
<div className={cn("mt-auto flex flex-col gap-2 p-4", className)} {...props} />
);
DrawerFooter.displayName = "DrawerFooter";
const DrawerFooter = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn("mt-auto flex flex-col gap-2 p-4", className)}
{...props}
/>
)
DrawerFooter.displayName = "DrawerFooter"
const DrawerTitle = React.forwardRef<
React.ElementRef<typeof DrawerPrimitive.Title>,
@ -71,11 +83,14 @@ const DrawerTitle = React.forwardRef<
>(({ className, ...props }, ref) => (
<DrawerPrimitive.Title
ref={ref}
className={cn("text-lg font-semibold leading-none tracking-tight", className)}
className={cn(
"text-lg font-semibold leading-none tracking-tight",
className
)}
{...props}
/>
));
DrawerTitle.displayName = DrawerPrimitive.Title.displayName;
))
DrawerTitle.displayName = DrawerPrimitive.Title.displayName
const DrawerDescription = React.forwardRef<
React.ElementRef<typeof DrawerPrimitive.Description>,
@ -86,8 +101,8 @@ const DrawerDescription = React.forwardRef<
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
));
DrawerDescription.displayName = DrawerPrimitive.Description.displayName;
))
DrawerDescription.displayName = DrawerPrimitive.Description.displayName
export {
Drawer,
@ -100,4 +115,4 @@ export {
DrawerFooter,
DrawerTitle,
DrawerDescription,
};
}

View File

@ -1,27 +1,27 @@
"use client";
"use client"
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
import { Check, ChevronRight, Circle } from "lucide-react";
import * as React from "react";
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";
import { cn } from "@/lib/utils"
const DropdownMenu = DropdownMenuPrimitive.Root;
const DropdownMenu = DropdownMenuPrimitive.Root
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger
const DropdownMenuGroup = DropdownMenuPrimitive.Group;
const DropdownMenuGroup = DropdownMenuPrimitive.Group
const DropdownMenuPortal = DropdownMenuPrimitive.Portal;
const DropdownMenuPortal = DropdownMenuPrimitive.Portal
const DropdownMenuSub = DropdownMenuPrimitive.Sub;
const DropdownMenuSub = DropdownMenuPrimitive.Sub
const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup
const DropdownMenuSubTrigger = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
inset?: boolean;
inset?: boolean
}
>(({ className, inset, children, ...props }, ref) => (
<DropdownMenuPrimitive.SubTrigger
@ -29,15 +29,16 @@ const DropdownMenuSubTrigger = React.forwardRef<
className={cn(
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent",
inset && "pl-8",
className,
className
)}
{...props}
>
{children}
<ChevronRight className="ml-auto h-4 w-4" />
</DropdownMenuPrimitive.SubTrigger>
));
DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
))
DropdownMenuSubTrigger.displayName =
DropdownMenuPrimitive.SubTrigger.displayName
const DropdownMenuSubContent = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,
@ -47,12 +48,13 @@ const DropdownMenuSubContent = React.forwardRef<
ref={ref}
className={cn(
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className,
className
)}
{...props}
/>
));
DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
))
DropdownMenuSubContent.displayName =
DropdownMenuPrimitive.SubContent.displayName
const DropdownMenuContent = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Content>,
@ -64,18 +66,18 @@ const DropdownMenuContent = React.forwardRef<
sideOffset={sideOffset}
className={cn(
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className,
className
)}
{...props}
/>
</DropdownMenuPrimitive.Portal>
));
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
))
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName
const DropdownMenuItem = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
inset?: boolean;
inset?: boolean
}
>(({ className, inset, ...props }, ref) => (
<DropdownMenuPrimitive.Item
@ -83,12 +85,12 @@ const DropdownMenuItem = React.forwardRef<
className={cn(
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
inset && "pl-8",
className,
className
)}
{...props}
/>
));
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
))
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName
const DropdownMenuCheckboxItem = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
@ -98,7 +100,7 @@ const DropdownMenuCheckboxItem = React.forwardRef<
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className,
className
)}
checked={checked}
{...props}
@ -110,8 +112,9 @@ const DropdownMenuCheckboxItem = React.forwardRef<
</span>
{children}
</DropdownMenuPrimitive.CheckboxItem>
));
DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
))
DropdownMenuCheckboxItem.displayName =
DropdownMenuPrimitive.CheckboxItem.displayName
const DropdownMenuRadioItem = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
@ -121,7 +124,7 @@ const DropdownMenuRadioItem = React.forwardRef<
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className,
className
)}
{...props}
>
@ -132,22 +135,26 @@ const DropdownMenuRadioItem = React.forwardRef<
</span>
{children}
</DropdownMenuPrimitive.RadioItem>
));
DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
))
DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName
const DropdownMenuLabel = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Label>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
inset?: boolean;
inset?: boolean
}
>(({ className, inset, ...props }, ref) => (
<DropdownMenuPrimitive.Label
ref={ref}
className={cn("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className)}
className={cn(
"px-2 py-1.5 text-sm font-semibold",
inset && "pl-8",
className
)}
{...props}
/>
));
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
))
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName
const DropdownMenuSeparator = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
@ -158,8 +165,8 @@ const DropdownMenuSeparator = React.forwardRef<
className={cn("-mx-1 my-1 h-px bg-muted", className)}
{...props}
/>
));
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
))
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName
const DropdownMenuShortcut = ({
className,
@ -170,9 +177,9 @@ const DropdownMenuShortcut = ({
className={cn("ml-auto text-xs tracking-widest opacity-60", className)}
{...props}
/>
);
};
DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
)
}
DropdownMenuShortcut.displayName = "DropdownMenuShortcut"
export {
DropdownMenu,
@ -190,4 +197,4 @@ export {
DropdownMenuSubContent,
DropdownMenuSubTrigger,
DropdownMenuRadioGroup,
};
}

View File

@ -1,13 +1,13 @@
"use client";
import { cn } from "@/lib/utils";
import { AnimatePresence, LayoutGroup, motion } from "framer-motion";
import React, { useCallback, useEffect, useRef, useState } from "react";
import { AnimatePresence, motion, LayoutGroup } from "framer-motion";
import { cn } from "@/lib/utils";
export const FlipWords = ({
words,
duration = 3000,
className,
}: {
}: {
words: string[];
duration?: number;
className?: string;
@ -60,7 +60,7 @@ export const FlipWords = ({
}}
className={cn(
"z-10 inline-block relative text-left text-neutral-900 dark:text-neutral-100 px-2",
className,
className
)}
key={currentWord}
>

View File

@ -1,34 +1,34 @@
import type * as LabelPrimitive from "@radix-ui/react-label";
import { Slot } from "@radix-ui/react-slot";
import * as React from "react";
import * as React from "react"
import * as LabelPrimitive from "@radix-ui/react-label"
import { Slot } from "@radix-ui/react-slot"
import {
Controller,
type ControllerProps,
type FieldPath,
type FieldValues,
ControllerProps,
FieldPath,
FieldValues,
FormProvider,
useFormContext,
} from "react-hook-form";
} from "react-hook-form"
import { Label } from "@/components/ui/label";
import { cn } from "@/lib/utils";
import { cn } from "@/lib/utils"
import { Label } from "@/components/ui/label"
const Form = FormProvider;
const Form = FormProvider
type FormFieldContextValue<
TFieldValues extends FieldValues = FieldValues,
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
> = {
name: TName;
};
name: TName
}
const FormFieldContext = React.createContext<FormFieldContextValue>(
{} as FormFieldContextValue,
);
{} as FormFieldContextValue
)
const FormField = <
TFieldValues extends FieldValues = FieldValues,
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
>({
...props
}: ControllerProps<TFieldValues, TName>) => {
@ -36,21 +36,21 @@ const FormField = <
<FormFieldContext.Provider value={{ name: props.name }}>
<Controller {...props} />
</FormFieldContext.Provider>
);
};
)
}
const useFormField = () => {
const fieldContext = React.useContext(FormFieldContext);
const itemContext = React.useContext(FormItemContext);
const { getFieldState, formState } = useFormContext();
const fieldContext = React.useContext(FormFieldContext)
const itemContext = React.useContext(FormItemContext)
const { getFieldState, formState } = useFormContext()
const fieldState = getFieldState(fieldContext.name, formState);
const fieldState = getFieldState(fieldContext.name, formState)
if (!fieldContext) {
throw new Error("useFormField should be used within <FormField>");
throw new Error("useFormField should be used within <FormField>")
}
const { id } = itemContext;
const { id } = itemContext
return {
id,
@ -59,35 +59,36 @@ const useFormField = () => {
formDescriptionId: `${id}-form-item-description`,
formMessageId: `${id}-form-item-message`,
...fieldState,
};
};
}
}
type FormItemContextValue = {
id: string;
};
id: string
}
const FormItemContext = React.createContext<FormItemContextValue>(
{} as FormItemContextValue,
);
{} as FormItemContextValue
)
const FormItem = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
({ className, ...props }, ref) => {
const id = React.useId();
const FormItem = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => {
const id = React.useId()
return (
<FormItemContext.Provider value={{ id }}>
<div ref={ref} className={cn("space-y-2", className)} {...props} />
</FormItemContext.Provider>
);
},
);
FormItem.displayName = "FormItem";
)
})
FormItem.displayName = "FormItem"
const FormLabel = React.forwardRef<
React.ElementRef<typeof LabelPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>
>(({ className, ...props }, ref) => {
const { error, formItemId } = useFormField();
const { error, formItemId } = useFormField()
return (
<Label
@ -96,35 +97,37 @@ const FormLabel = React.forwardRef<
htmlFor={formItemId}
{...props}
/>
);
});
FormLabel.displayName = "FormLabel";
)
})
FormLabel.displayName = "FormLabel"
const FormControl = React.forwardRef<
React.ElementRef<typeof Slot>,
React.ComponentPropsWithoutRef<typeof Slot>
>(({ ...props }, ref) => {
const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
const { error, formItemId, formDescriptionId, formMessageId } = useFormField()
return (
<Slot
ref={ref}
id={formItemId}
aria-describedby={
!error ? `${formDescriptionId}` : `${formDescriptionId} ${formMessageId}`
!error
? `${formDescriptionId}`
: `${formDescriptionId} ${formMessageId}`
}
aria-invalid={!!error}
{...props}
/>
);
});
FormControl.displayName = "FormControl";
)
})
FormControl.displayName = "FormControl"
const FormDescription = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLParagraphElement>
>(({ className, ...props }, ref) => {
const { formDescriptionId } = useFormField();
const { formDescriptionId } = useFormField()
return (
<p
@ -133,19 +136,19 @@ const FormDescription = React.forwardRef<
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
);
});
FormDescription.displayName = "FormDescription";
)
})
FormDescription.displayName = "FormDescription"
const FormMessage = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLParagraphElement>
>(({ className, children, ...props }, ref) => {
const { error, formMessageId } = useFormField();
const body = error ? String(error?.message) : children;
const { error, formMessageId } = useFormField()
const body = error ? String(error?.message) : children
if (!body) {
return null;
return null
}
return (
@ -157,9 +160,9 @@ const FormMessage = React.forwardRef<
>
{body}
</p>
);
});
FormMessage.displayName = "FormMessage";
)
})
FormMessage.displayName = "FormMessage"
export {
useFormField,
@ -170,4 +173,4 @@ export {
FormDescription,
FormMessage,
FormField,
};
}

View File

@ -1,18 +1,18 @@
"use client";
import React from "react";
import {
type MotionValue,
motion,
useScroll,
useSpring,
useTransform,
useSpring,
MotionValue,
} from "framer-motion";
import Image from "next/image";
import Link from "next/link";
import React from "react";
interface HeroParallaxProps {
products: product[];
children?: React.ReactNode;
children?: React.ReactNode
}
interface product {
@ -21,7 +21,7 @@ interface product {
thumbnail: string;
}
export const HeroParallax = ({ products, children }: HeroParallaxProps) => {
export const HeroParallax = ({ products, children }: HeroParallaxProps ) => {
const firstRow = products.slice(0, 5);
const secondRow = products.slice(5, 10);
const thirdRow = products.slice(10, 15);
@ -35,27 +35,27 @@ export const HeroParallax = ({ products, children }: HeroParallaxProps) => {
const translateX = useSpring(
useTransform(scrollYProgress, [0, 1], [0, 1000]),
springConfig,
springConfig
);
const translateXReverse = useSpring(
useTransform(scrollYProgress, [0, 1], [0, -1000]),
springConfig,
springConfig
);
const rotateX = useSpring(
useTransform(scrollYProgress, [0, 0.2], [15, 0]),
springConfig,
springConfig
);
const opacity = useSpring(
useTransform(scrollYProgress, [0, 0.2], [0.2, 1]),
springConfig,
springConfig
);
const rotateZ = useSpring(
useTransform(scrollYProgress, [0, 0.2], [20, 0]),
springConfig,
springConfig
);
const translateY = useSpring(
useTransform(scrollYProgress, [0, 0.2], [-700, 500]),
springConfig,
springConfig
);
return (
<div
@ -74,7 +74,11 @@ export const HeroParallax = ({ products, children }: HeroParallaxProps) => {
>
<motion.div className="flex flex-row-reverse space-x-reverse space-x-20 mb-20">
{firstRow.map((product) => (
<ProductCard product={product} translate={translateX} key={product.title} />
<ProductCard
product={product}
translate={translateX}
key={product.title}
/>
))}
</motion.div>
<motion.div className="flex flex-row mb-20 space-x-20 ">
@ -88,7 +92,11 @@ export const HeroParallax = ({ products, children }: HeroParallaxProps) => {
</motion.div>
<motion.div className="flex flex-row-reverse space-x-reverse space-x-20">
{thirdRow.map((product) => (
<ProductCard product={product} translate={translateX} key={product.title} />
<ProductCard
product={product}
translate={translateX}
key={product.title}
/>
))}
</motion.div>
</motion.div>
@ -99,7 +107,7 @@ export const HeroParallax = ({ products, children }: HeroParallaxProps) => {
export const ProductCard = ({
product,
translate,
}: {
}: {
product: {
title: string;
link: string;
@ -118,7 +126,10 @@ export const ProductCard = ({
key={product.title}
className="group/product h-96 w-[30rem] relative flex-shrink-0"
>
<Link href={product.link} className="block group-hover/product:shadow-2xl ">
<Link
href={product.link}
className="block group-hover/product:shadow-2xl "
>
<Image
src={product.thumbnail}
height="600"

View File

@ -1,13 +1,13 @@
"use client";
"use client"
import * as HoverCardPrimitive from "@radix-ui/react-hover-card";
import * as React from "react";
import * as React from "react"
import * as HoverCardPrimitive from "@radix-ui/react-hover-card"
import { cn } from "@/lib/utils";
import { cn } from "@/lib/utils"
const HoverCard = HoverCardPrimitive.Root;
const HoverCard = HoverCardPrimitive.Root
const HoverCardTrigger = HoverCardPrimitive.Trigger;
const HoverCardTrigger = HoverCardPrimitive.Trigger
const HoverCardContent = React.forwardRef<
React.ElementRef<typeof HoverCardPrimitive.Content>,
@ -19,11 +19,11 @@ const HoverCardContent = React.forwardRef<
sideOffset={sideOffset}
className={cn(
"z-50 w-64 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className,
className
)}
{...props}
/>
));
HoverCardContent.displayName = HoverCardPrimitive.Content.displayName;
))
HoverCardContent.displayName = HoverCardPrimitive.Content.displayName
export { HoverCard, HoverCardTrigger, HoverCardContent };
export { HoverCard, HoverCardTrigger, HoverCardContent }

View File

@ -1,10 +1,10 @@
"use client";
"use client"
import { OTPInput, OTPInputContext } from "input-otp";
import { Dot } from "lucide-react";
import * as React from "react";
import * as React from "react"
import { OTPInput, OTPInputContext } from "input-otp"
import { Dot } from "lucide-react"
import { cn } from "@/lib/utils";
import { cn } from "@/lib/utils"
const InputOTP = React.forwardRef<
React.ElementRef<typeof OTPInput>,
@ -14,28 +14,28 @@ const InputOTP = React.forwardRef<
ref={ref}
containerClassName={cn(
"flex items-center gap-2 has-[:disabled]:opacity-50",
containerClassName,
containerClassName
)}
className={cn("disabled:cursor-not-allowed", className)}
{...props}
/>
));
InputOTP.displayName = "InputOTP";
))
InputOTP.displayName = "InputOTP"
const InputOTPGroup = React.forwardRef<
React.ElementRef<"div">,
React.ComponentPropsWithoutRef<"div">
>(({ className, ...props }, ref) => (
<div ref={ref} className={cn("flex items-center", className)} {...props} />
));
InputOTPGroup.displayName = "InputOTPGroup";
))
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];
const inputOTPContext = React.useContext(OTPInputContext)
const { char, hasFakeCaret, isActive } = inputOTPContext.slots[index]
return (
<div
@ -43,7 +43,7 @@ const InputOTPSlot = React.forwardRef<
className={cn(
"relative flex h-10 w-10 items-center justify-center border-y border-r border-input text-sm transition-all first:rounded-l-md first:border-l last:rounded-r-md",
isActive && "z-10 ring-2 ring-ring ring-offset-background",
className,
className
)}
{...props}
>
@ -54,9 +54,9 @@ const InputOTPSlot = React.forwardRef<
</div>
)}
</div>
);
});
InputOTPSlot.displayName = "InputOTPSlot";
)
})
InputOTPSlot.displayName = "InputOTPSlot"
const InputOTPSeparator = React.forwardRef<
React.ElementRef<"div">,
@ -65,7 +65,7 @@ const InputOTPSeparator = React.forwardRef<
<div ref={ref} role="separator" {...props}>
<Dot />
</div>
));
InputOTPSeparator.displayName = "InputOTPSeparator";
))
InputOTPSeparator.displayName = "InputOTPSeparator"
export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator };
export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator }

View File

@ -1,8 +1,9 @@
import * as React from "react";
import * as React from "react"
import { cn } from "@/lib/utils";
import { cn } from "@/lib/utils"
export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {}
export interface InputProps
extends React.InputHTMLAttributes<HTMLInputElement> {}
const Input = React.forwardRef<HTMLInputElement, InputProps>(
({ className, type, ...props }, ref) => {
@ -11,14 +12,14 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
type={type}
className={cn(
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className,
className
)}
ref={ref}
{...props}
/>
);
},
);
Input.displayName = "Input";
)
}
)
Input.displayName = "Input"
export { Input };
export { Input }

View File

@ -1,22 +1,26 @@
"use client";
"use client"
import * as LabelPrimitive from "@radix-ui/react-label";
import { type VariantProps, cva } from "class-variance-authority";
import * as React from "react";
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";
import { cn } from "@/lib/utils"
const labelVariants = cva(
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
);
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
)
const Label = React.forwardRef<
React.ElementRef<typeof LabelPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> &
VariantProps<typeof labelVariants>
>(({ className, ...props }, ref) => (
<LabelPrimitive.Root ref={ref} className={cn(labelVariants(), className)} {...props} />
));
Label.displayName = LabelPrimitive.Root.displayName;
<LabelPrimitive.Root
ref={ref}
className={cn(labelVariants(), className)}
{...props}
/>
))
Label.displayName = LabelPrimitive.Root.displayName
export { Label };
export { Label }

View File

@ -1,20 +1,20 @@
"use client";
"use client"
import * as MenubarPrimitive from "@radix-ui/react-menubar";
import { Check, ChevronRight, Circle } from "lucide-react";
import * as React from "react";
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";
import { cn } from "@/lib/utils"
const MenubarMenu = MenubarPrimitive.Menu;
const MenubarMenu = MenubarPrimitive.Menu
const MenubarGroup = MenubarPrimitive.Group;
const MenubarGroup = MenubarPrimitive.Group
const MenubarPortal = MenubarPrimitive.Portal;
const MenubarPortal = MenubarPrimitive.Portal
const MenubarSub = MenubarPrimitive.Sub;
const MenubarSub = MenubarPrimitive.Sub
const MenubarRadioGroup = MenubarPrimitive.RadioGroup;
const MenubarRadioGroup = MenubarPrimitive.RadioGroup
const Menubar = React.forwardRef<
React.ElementRef<typeof MenubarPrimitive.Root>,
@ -24,12 +24,12 @@ const Menubar = React.forwardRef<
ref={ref}
className={cn(
"flex h-10 items-center space-x-1 rounded-md border bg-background p-1",
className,
className
)}
{...props}
/>
));
Menubar.displayName = MenubarPrimitive.Root.displayName;
))
Menubar.displayName = MenubarPrimitive.Root.displayName
const MenubarTrigger = React.forwardRef<
React.ElementRef<typeof MenubarPrimitive.Trigger>,
@ -39,17 +39,17 @@ const MenubarTrigger = React.forwardRef<
ref={ref}
className={cn(
"flex cursor-default select-none items-center rounded-sm px-3 py-1.5 text-sm font-medium outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
className,
className
)}
{...props}
/>
));
MenubarTrigger.displayName = MenubarPrimitive.Trigger.displayName;
))
MenubarTrigger.displayName = MenubarPrimitive.Trigger.displayName
const MenubarSubTrigger = React.forwardRef<
React.ElementRef<typeof MenubarPrimitive.SubTrigger>,
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.SubTrigger> & {
inset?: boolean;
inset?: boolean
}
>(({ className, inset, children, ...props }, ref) => (
<MenubarPrimitive.SubTrigger
@ -57,15 +57,15 @@ const MenubarSubTrigger = React.forwardRef<
className={cn(
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
inset && "pl-8",
className,
className
)}
{...props}
>
{children}
<ChevronRight className="ml-auto h-4 w-4" />
</MenubarPrimitive.SubTrigger>
));
MenubarSubTrigger.displayName = MenubarPrimitive.SubTrigger.displayName;
))
MenubarSubTrigger.displayName = MenubarPrimitive.SubTrigger.displayName
const MenubarSubContent = React.forwardRef<
React.ElementRef<typeof MenubarPrimitive.SubContent>,
@ -75,17 +75,21 @@ const MenubarSubContent = React.forwardRef<
ref={ref}
className={cn(
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className,
className
)}
{...props}
/>
));
MenubarSubContent.displayName = MenubarPrimitive.SubContent.displayName;
))
MenubarSubContent.displayName = MenubarPrimitive.SubContent.displayName
const MenubarContent = React.forwardRef<
React.ElementRef<typeof MenubarPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Content>
>(({ className, align = "start", alignOffset = -4, sideOffset = 8, ...props }, ref) => (
>(
(
{ className, align = "start", alignOffset = -4, sideOffset = 8, ...props },
ref
) => (
<MenubarPrimitive.Portal>
<MenubarPrimitive.Content
ref={ref}
@ -94,18 +98,19 @@ const MenubarContent = React.forwardRef<
sideOffset={sideOffset}
className={cn(
"z-50 min-w-[12rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className,
className
)}
{...props}
/>
</MenubarPrimitive.Portal>
));
MenubarContent.displayName = MenubarPrimitive.Content.displayName;
)
)
MenubarContent.displayName = MenubarPrimitive.Content.displayName
const MenubarItem = React.forwardRef<
React.ElementRef<typeof MenubarPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Item> & {
inset?: boolean;
inset?: boolean
}
>(({ className, inset, ...props }, ref) => (
<MenubarPrimitive.Item
@ -113,12 +118,12 @@ const MenubarItem = React.forwardRef<
className={cn(
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
inset && "pl-8",
className,
className
)}
{...props}
/>
));
MenubarItem.displayName = MenubarPrimitive.Item.displayName;
))
MenubarItem.displayName = MenubarPrimitive.Item.displayName
const MenubarCheckboxItem = React.forwardRef<
React.ElementRef<typeof MenubarPrimitive.CheckboxItem>,
@ -128,7 +133,7 @@ const MenubarCheckboxItem = React.forwardRef<
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className,
className
)}
checked={checked}
{...props}
@ -140,8 +145,8 @@ const MenubarCheckboxItem = React.forwardRef<
</span>
{children}
</MenubarPrimitive.CheckboxItem>
));
MenubarCheckboxItem.displayName = MenubarPrimitive.CheckboxItem.displayName;
))
MenubarCheckboxItem.displayName = MenubarPrimitive.CheckboxItem.displayName
const MenubarRadioItem = React.forwardRef<
React.ElementRef<typeof MenubarPrimitive.RadioItem>,
@ -151,7 +156,7 @@ const MenubarRadioItem = React.forwardRef<
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className,
className
)}
{...props}
>
@ -162,22 +167,26 @@ const MenubarRadioItem = React.forwardRef<
</span>
{children}
</MenubarPrimitive.RadioItem>
));
MenubarRadioItem.displayName = MenubarPrimitive.RadioItem.displayName;
))
MenubarRadioItem.displayName = MenubarPrimitive.RadioItem.displayName
const MenubarLabel = React.forwardRef<
React.ElementRef<typeof MenubarPrimitive.Label>,
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Label> & {
inset?: boolean;
inset?: boolean
}
>(({ className, inset, ...props }, ref) => (
<MenubarPrimitive.Label
ref={ref}
className={cn("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className)}
className={cn(
"px-2 py-1.5 text-sm font-semibold",
inset && "pl-8",
className
)}
{...props}
/>
));
MenubarLabel.displayName = MenubarPrimitive.Label.displayName;
))
MenubarLabel.displayName = MenubarPrimitive.Label.displayName
const MenubarSeparator = React.forwardRef<
React.ElementRef<typeof MenubarPrimitive.Separator>,
@ -188,8 +197,8 @@ const MenubarSeparator = React.forwardRef<
className={cn("-mx-1 my-1 h-px bg-muted", className)}
{...props}
/>
));
MenubarSeparator.displayName = MenubarPrimitive.Separator.displayName;
))
MenubarSeparator.displayName = MenubarPrimitive.Separator.displayName
const MenubarShortcut = ({
className,
@ -197,12 +206,15 @@ const MenubarShortcut = ({
}: React.HTMLAttributes<HTMLSpanElement>) => {
return (
<span
className={cn("ml-auto text-xs tracking-widest text-muted-foreground", className)}
className={cn(
"ml-auto text-xs tracking-widest text-muted-foreground",
className
)}
{...props}
/>
);
};
MenubarShortcut.displayname = "MenubarShortcut";
)
}
MenubarShortcut.displayname = "MenubarShortcut"
export {
Menubar,
@ -221,4 +233,4 @@ export {
MenubarGroup,
MenubarSub,
MenubarShortcut,
};
}

View File

@ -1,9 +1,9 @@
import * as NavigationMenuPrimitive from "@radix-ui/react-navigation-menu";
import { cva } from "class-variance-authority";
import { ChevronDown } from "lucide-react";
import * as React from "react";
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";
import { cn } from "@/lib/utils"
const NavigationMenu = React.forwardRef<
React.ElementRef<typeof NavigationMenuPrimitive.Root>,
@ -13,15 +13,15 @@ const NavigationMenu = React.forwardRef<
ref={ref}
className={cn(
"relative z-10 flex max-w-max flex-1 items-center justify-center",
className,
className
)}
{...props}
>
{children}
<NavigationMenuViewport />
</NavigationMenuPrimitive.Root>
));
NavigationMenu.displayName = NavigationMenuPrimitive.Root.displayName;
))
NavigationMenu.displayName = NavigationMenuPrimitive.Root.displayName
const NavigationMenuList = React.forwardRef<
React.ElementRef<typeof NavigationMenuPrimitive.List>,
@ -31,18 +31,18 @@ const NavigationMenuList = React.forwardRef<
ref={ref}
className={cn(
"group flex flex-1 list-none items-center justify-center space-x-1",
className,
className
)}
{...props}
/>
));
NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName;
))
NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName
const NavigationMenuItem = NavigationMenuPrimitive.Item;
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",
);
"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<typeof NavigationMenuPrimitive.Trigger>,
@ -59,8 +59,8 @@ const NavigationMenuTrigger = React.forwardRef<
aria-hidden="true"
/>
</NavigationMenuPrimitive.Trigger>
));
NavigationMenuTrigger.displayName = NavigationMenuPrimitive.Trigger.displayName;
))
NavigationMenuTrigger.displayName = NavigationMenuPrimitive.Trigger.displayName
const NavigationMenuContent = React.forwardRef<
React.ElementRef<typeof NavigationMenuPrimitive.Content>,
@ -70,14 +70,14 @@ const NavigationMenuContent = React.forwardRef<
ref={ref}
className={cn(
"md:left-0 md:top-0 w-full data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 md:absolute md:w-auto ",
className,
className
)}
{...props}
/>
));
NavigationMenuContent.displayName = NavigationMenuPrimitive.Content.displayName;
))
NavigationMenuContent.displayName = NavigationMenuPrimitive.Content.displayName
const NavigationMenuLink = NavigationMenuPrimitive.Link;
const NavigationMenuLink = NavigationMenuPrimitive.Link
const NavigationMenuViewport = React.forwardRef<
React.ElementRef<typeof NavigationMenuPrimitive.Viewport>,
@ -87,14 +87,15 @@ const NavigationMenuViewport = React.forwardRef<
<NavigationMenuPrimitive.Viewport
className={cn(
"origin-top-center relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-screen md:w-full overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 md:w-[var(--radix-navigation-menu-viewport-width)]",
className,
className
)}
ref={ref}
{...props}
/>
</div>
));
NavigationMenuViewport.displayName = NavigationMenuPrimitive.Viewport.displayName;
))
NavigationMenuViewport.displayName =
NavigationMenuPrimitive.Viewport.displayName
const NavigationMenuIndicator = React.forwardRef<
React.ElementRef<typeof NavigationMenuPrimitive.Indicator>,
@ -104,14 +105,15 @@ const NavigationMenuIndicator = React.forwardRef<
ref={ref}
className={cn(
"top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in",
className,
className
)}
{...props}
>
<div className="relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm bg-border shadow-md" />
</NavigationMenuPrimitive.Indicator>
));
NavigationMenuIndicator.displayName = NavigationMenuPrimitive.Indicator.displayName;
))
NavigationMenuIndicator.displayName =
NavigationMenuPrimitive.Indicator.displayName
export {
navigationMenuTriggerStyle,
@ -123,4 +125,4 @@ export {
NavigationMenuLink,
NavigationMenuIndicator,
NavigationMenuViewport,
};
}

View File

@ -1,8 +1,8 @@
import { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react";
import * as React from "react";
import * as React from "react"
import { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react"
import { type ButtonProps, buttonVariants } from "@/components/ui/button";
import { cn } from "@/lib/utils";
import { cn } from "@/lib/utils"
import { ButtonProps, buttonVariants } from "@/components/ui/button"
const Pagination = ({ className, ...props }: React.ComponentProps<"nav">) => (
<nav
@ -11,31 +11,33 @@ const Pagination = ({ className, ...props }: React.ComponentProps<"nav">) => (
className={cn("mx-auto flex w-full justify-center", className)}
{...props}
/>
);
Pagination.displayName = "Pagination";
)
Pagination.displayName = "Pagination"
const PaginationContent = React.forwardRef<HTMLUListElement, React.ComponentProps<"ul">>(
({ className, ...props }, ref) => (
const PaginationContent = React.forwardRef<
HTMLUListElement,
React.ComponentProps<"ul">
>(({ className, ...props }, ref) => (
<ul
ref={ref}
className={cn("flex flex-row items-center gap-1", className)}
{...props}
/>
),
);
PaginationContent.displayName = "PaginationContent";
))
PaginationContent.displayName = "PaginationContent"
const PaginationItem = React.forwardRef<HTMLLIElement, React.ComponentProps<"li">>(
({ className, ...props }, ref) => (
const PaginationItem = React.forwardRef<
HTMLLIElement,
React.ComponentProps<"li">
>(({ className, ...props }, ref) => (
<li ref={ref} className={cn("", className)} {...props} />
),
);
PaginationItem.displayName = "PaginationItem";
))
PaginationItem.displayName = "PaginationItem"
type PaginationLinkProps = {
isActive?: boolean;
isActive?: boolean
} & Pick<ButtonProps, "size"> &
React.ComponentProps<"a">;
React.ComponentProps<"a">
const PaginationLink = ({
className,
@ -50,12 +52,12 @@ const PaginationLink = ({
variant: isActive ? "outline" : "ghost",
size,
}),
className,
className
)}
{...props}
/>
);
PaginationLink.displayName = "PaginationLink";
)
PaginationLink.displayName = "PaginationLink"
const PaginationPrevious = ({
className,
@ -70,8 +72,8 @@ const PaginationPrevious = ({
<ChevronLeft className="h-4 w-4" />
<span>Previous</span>
</PaginationLink>
);
PaginationPrevious.displayName = "PaginationPrevious";
)
PaginationPrevious.displayName = "PaginationPrevious"
const PaginationNext = ({
className,
@ -86,10 +88,13 @@ const PaginationNext = ({
<span>Next</span>
<ChevronRight className="h-4 w-4" />
</PaginationLink>
);
PaginationNext.displayName = "PaginationNext";
)
PaginationNext.displayName = "PaginationNext"
const PaginationEllipsis = ({ className, ...props }: React.ComponentProps<"span">) => (
const PaginationEllipsis = ({
className,
...props
}: React.ComponentProps<"span">) => (
<span
aria-hidden
className={cn("flex h-9 w-9 items-center justify-center", className)}
@ -98,8 +103,8 @@ const PaginationEllipsis = ({ className, ...props }: React.ComponentProps<"span"
<MoreHorizontal className="h-4 w-4" />
<span className="sr-only">More pages</span>
</span>
);
PaginationEllipsis.displayName = "PaginationEllipsis";
)
PaginationEllipsis.displayName = "PaginationEllipsis"
export {
Pagination,
@ -109,4 +114,4 @@ export {
PaginationLink,
PaginationNext,
PaginationPrevious,
};
}

View File

@ -1,13 +1,13 @@
"use client";
"use client"
import * as PopoverPrimitive from "@radix-ui/react-popover";
import * as React from "react";
import * as React from "react"
import * as PopoverPrimitive from "@radix-ui/react-popover"
import { cn } from "@/lib/utils";
import { cn } from "@/lib/utils"
const Popover = PopoverPrimitive.Root;
const Popover = PopoverPrimitive.Root
const PopoverTrigger = PopoverPrimitive.Trigger;
const PopoverTrigger = PopoverPrimitive.Trigger
const PopoverContent = React.forwardRef<
React.ElementRef<typeof PopoverPrimitive.Content>,
@ -20,12 +20,12 @@ const PopoverContent = React.forwardRef<
sideOffset={sideOffset}
className={cn(
"z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className,
className
)}
{...props}
/>
</PopoverPrimitive.Portal>
));
PopoverContent.displayName = PopoverPrimitive.Content.displayName;
))
PopoverContent.displayName = PopoverPrimitive.Content.displayName
export { Popover, PopoverTrigger, PopoverContent };
export { Popover, PopoverTrigger, PopoverContent }

View File

@ -1,9 +1,9 @@
"use client";
"use client"
import * as ProgressPrimitive from "@radix-ui/react-progress";
import * as React from "react";
import * as React from "react"
import * as ProgressPrimitive from "@radix-ui/react-progress"
import { cn } from "@/lib/utils";
import { cn } from "@/lib/utils"
const Progress = React.forwardRef<
React.ElementRef<typeof ProgressPrimitive.Root>,
@ -13,7 +13,7 @@ const Progress = React.forwardRef<
ref={ref}
className={cn(
"relative h-4 w-full overflow-hidden rounded-full bg-secondary",
className,
className
)}
{...props}
>
@ -22,7 +22,7 @@ const Progress = React.forwardRef<
style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
/>
</ProgressPrimitive.Root>
));
Progress.displayName = ProgressPrimitive.Root.displayName;
))
Progress.displayName = ProgressPrimitive.Root.displayName
export { Progress };
export { Progress }

View File

@ -1,10 +1,10 @@
"use client";
"use client"
import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
import { Circle } from "lucide-react";
import * as React from "react";
import * as React from "react"
import * as RadioGroupPrimitive from "@radix-ui/react-radio-group"
import { Circle } from "lucide-react"
import { cn } from "@/lib/utils";
import { cn } from "@/lib/utils"
const RadioGroup = React.forwardRef<
React.ElementRef<typeof RadioGroupPrimitive.Root>,
@ -16,9 +16,9 @@ const RadioGroup = React.forwardRef<
{...props}
ref={ref}
/>
);
});
RadioGroup.displayName = RadioGroupPrimitive.Root.displayName;
)
})
RadioGroup.displayName = RadioGroupPrimitive.Root.displayName
const RadioGroupItem = React.forwardRef<
React.ElementRef<typeof RadioGroupPrimitive.Item>,
@ -29,7 +29,7 @@ const RadioGroupItem = React.forwardRef<
ref={ref}
className={cn(
"aspect-square h-4 w-4 rounded-full border border-primary text-primary ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className,
className
)}
{...props}
>
@ -37,8 +37,8 @@ const RadioGroupItem = React.forwardRef<
<Circle className="h-2.5 w-2.5 fill-current text-current" />
</RadioGroupPrimitive.Indicator>
</RadioGroupPrimitive.Item>
);
});
RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName;
)
})
RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName
export { RadioGroup, RadioGroupItem };
export { RadioGroup, RadioGroupItem }

View File

@ -1,9 +1,9 @@
"use client";
"use client"
import { GripVertical } from "lucide-react";
import * as ResizablePrimitive from "react-resizable-panels";
import { GripVertical } from "lucide-react"
import * as ResizablePrimitive from "react-resizable-panels"
import { cn } from "@/lib/utils";
import { cn } from "@/lib/utils"
const ResizablePanelGroup = ({
className,
@ -12,25 +12,25 @@ const ResizablePanelGroup = ({
<ResizablePrimitive.PanelGroup
className={cn(
"flex h-full w-full data-[panel-group-direction=vertical]:flex-col",
className,
className
)}
{...props}
/>
);
)
const ResizablePanel = ResizablePrimitive.Panel;
const ResizablePanel = ResizablePrimitive.Panel
const ResizableHandle = ({
withHandle,
className,
...props
}: React.ComponentProps<typeof ResizablePrimitive.PanelResizeHandle> & {
withHandle?: boolean;
withHandle?: boolean
}) => (
<ResizablePrimitive.PanelResizeHandle
className={cn(
"relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:-translate-y-1/2 data-[panel-group-direction=vertical]:after:translate-x-0 [&[data-panel-group-direction=vertical]>div]:rotate-90",
className,
className
)}
{...props}
>
@ -40,6 +40,6 @@ const ResizableHandle = ({
</div>
)}
</ResizablePrimitive.PanelResizeHandle>
);
)
export { ResizablePanelGroup, ResizablePanel, ResizableHandle };
export { ResizablePanelGroup, ResizablePanel, ResizableHandle }

View File

@ -1,9 +1,9 @@
"use client";
"use client"
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
import * as React from "react";
import * as React from "react"
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"
import { cn } from "@/lib/utils";
import { cn } from "@/lib/utils"
const ScrollArea = React.forwardRef<
React.ElementRef<typeof ScrollAreaPrimitive.Root>,
@ -20,8 +20,8 @@ const ScrollArea = React.forwardRef<
<ScrollBar />
<ScrollAreaPrimitive.Corner />
</ScrollAreaPrimitive.Root>
));
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
))
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName
const ScrollBar = React.forwardRef<
React.ElementRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,
@ -32,16 +32,17 @@ const ScrollBar = React.forwardRef<
orientation={orientation}
className={cn(
"flex touch-none select-none transition-colors",
orientation === "vertical" && "h-full w-2.5 border-l border-l-transparent p-[1px]",
orientation === "vertical" &&
"h-full w-2.5 border-l border-l-transparent p-[1px]",
orientation === "horizontal" &&
"h-2.5 flex-col border-t border-t-transparent p-[1px]",
className,
className
)}
{...props}
>
<ScrollAreaPrimitive.ScrollAreaThumb className="relative flex-1 rounded-full bg-border" />
</ScrollAreaPrimitive.ScrollAreaScrollbar>
));
ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;
))
ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName
export { ScrollArea, ScrollBar };
export { ScrollArea, ScrollBar }

View File

@ -1,16 +1,16 @@
"use client";
"use client"
import * as SelectPrimitive from "@radix-ui/react-select";
import { Check, ChevronDown, ChevronUp } from "lucide-react";
import * as React from "react";
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";
import { cn } from "@/lib/utils"
const Select = SelectPrimitive.Root;
const Select = SelectPrimitive.Root
const SelectGroup = SelectPrimitive.Group;
const SelectGroup = SelectPrimitive.Group
const SelectValue = SelectPrimitive.Value;
const SelectValue = SelectPrimitive.Value
const SelectTrigger = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Trigger>,
@ -20,7 +20,7 @@ const SelectTrigger = React.forwardRef<
ref={ref}
className={cn(
"flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
className,
className
)}
{...props}
>
@ -29,8 +29,8 @@ const SelectTrigger = React.forwardRef<
<ChevronDown className="h-4 w-4 opacity-50" />
</SelectPrimitive.Icon>
</SelectPrimitive.Trigger>
));
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
))
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName
const SelectScrollUpButton = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
@ -38,13 +38,16 @@ const SelectScrollUpButton = React.forwardRef<
>(({ className, ...props }, ref) => (
<SelectPrimitive.ScrollUpButton
ref={ref}
className={cn("flex cursor-default items-center justify-center py-1", className)}
className={cn(
"flex cursor-default items-center justify-center py-1",
className
)}
{...props}
>
<ChevronUp className="h-4 w-4" />
</SelectPrimitive.ScrollUpButton>
));
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
))
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName
const SelectScrollDownButton = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
@ -52,13 +55,17 @@ const SelectScrollDownButton = React.forwardRef<
>(({ className, ...props }, ref) => (
<SelectPrimitive.ScrollDownButton
ref={ref}
className={cn("flex cursor-default items-center justify-center py-1", className)}
className={cn(
"flex cursor-default items-center justify-center py-1",
className
)}
{...props}
>
<ChevronDown className="h-4 w-4" />
</SelectPrimitive.ScrollDownButton>
));
SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
))
SelectScrollDownButton.displayName =
SelectPrimitive.ScrollDownButton.displayName
const SelectContent = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Content>,
@ -71,7 +78,7 @@ const SelectContent = React.forwardRef<
"relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
position === "popper" &&
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
className,
className
)}
position={position}
{...props}
@ -81,7 +88,7 @@ const SelectContent = React.forwardRef<
className={cn(
"p-1",
position === "popper" &&
"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]",
"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
)}
>
{children}
@ -89,8 +96,8 @@ const SelectContent = React.forwardRef<
<SelectScrollDownButton />
</SelectPrimitive.Content>
</SelectPrimitive.Portal>
));
SelectContent.displayName = SelectPrimitive.Content.displayName;
))
SelectContent.displayName = SelectPrimitive.Content.displayName
const SelectLabel = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Label>,
@ -101,8 +108,8 @@ const SelectLabel = React.forwardRef<
className={cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className)}
{...props}
/>
));
SelectLabel.displayName = SelectPrimitive.Label.displayName;
))
SelectLabel.displayName = SelectPrimitive.Label.displayName
const SelectItem = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Item>,
@ -112,7 +119,7 @@ const SelectItem = React.forwardRef<
ref={ref}
className={cn(
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className,
className
)}
{...props}
>
@ -124,8 +131,8 @@ const SelectItem = React.forwardRef<
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
</SelectPrimitive.Item>
));
SelectItem.displayName = SelectPrimitive.Item.displayName;
))
SelectItem.displayName = SelectPrimitive.Item.displayName
const SelectSeparator = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Separator>,
@ -136,8 +143,8 @@ const SelectSeparator = React.forwardRef<
className={cn("-mx-1 my-1 h-px bg-muted", className)}
{...props}
/>
));
SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
))
SelectSeparator.displayName = SelectPrimitive.Separator.displayName
export {
Select,
@ -150,4 +157,4 @@ export {
SelectSeparator,
SelectScrollUpButton,
SelectScrollDownButton,
};
}

View File

@ -1,14 +1,18 @@
"use client";
"use client"
import * as SeparatorPrimitive from "@radix-ui/react-separator";
import * as React from "react";
import * as React from "react"
import * as SeparatorPrimitive from "@radix-ui/react-separator"
import { cn } from "@/lib/utils";
import { cn } from "@/lib/utils"
const Separator = React.forwardRef<
React.ElementRef<typeof SeparatorPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root>
>(({ className, orientation = "horizontal", decorative = true, ...props }, ref) => (
>(
(
{ className, orientation = "horizontal", decorative = true, ...props },
ref
) => (
<SeparatorPrimitive.Root
ref={ref}
decorative={decorative}
@ -16,11 +20,12 @@ const Separator = React.forwardRef<
className={cn(
"shrink-0 bg-border",
orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
className,
className
)}
{...props}
/>
));
Separator.displayName = SeparatorPrimitive.Root.displayName;
)
)
Separator.displayName = SeparatorPrimitive.Root.displayName
export { Separator };
export { Separator }

View File

@ -1,19 +1,19 @@
"use client";
"use client"
import * as SheetPrimitive from "@radix-ui/react-dialog";
import { type VariantProps, cva } from "class-variance-authority";
import { X } from "lucide-react";
import * as React from "react";
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";
import { cn } from "@/lib/utils"
const Sheet = SheetPrimitive.Root;
const Sheet = SheetPrimitive.Root
const SheetTrigger = SheetPrimitive.Trigger;
const SheetTrigger = SheetPrimitive.Trigger
const SheetClose = SheetPrimitive.Close;
const SheetClose = SheetPrimitive.Close
const SheetPortal = SheetPrimitive.Portal;
const SheetPortal = SheetPrimitive.Portal
const SheetOverlay = React.forwardRef<
React.ElementRef<typeof SheetPrimitive.Overlay>,
@ -22,13 +22,13 @@ const SheetOverlay = React.forwardRef<
<SheetPrimitive.Overlay
className={cn(
"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
className,
className
)}
{...props}
ref={ref}
/>
));
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName;
))
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",
@ -46,8 +46,8 @@ const sheetVariants = cva(
defaultVariants: {
side: "right",
},
},
);
}
)
interface SheetContentProps
extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
@ -71,27 +71,36 @@ const SheetContent = React.forwardRef<
</SheetPrimitive.Close>
</SheetPrimitive.Content>
</SheetPortal>
));
SheetContent.displayName = SheetPrimitive.Content.displayName;
))
SheetContent.displayName = SheetPrimitive.Content.displayName
const SheetHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn("flex flex-col space-y-2 text-center sm:text-left", className)}
{...props}
/>
);
SheetHeader.displayName = "SheetHeader";
const SheetFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
const SheetHeader = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
className,
"flex flex-col space-y-2 text-center sm:text-left",
className
)}
{...props}
/>
);
SheetFooter.displayName = "SheetFooter";
)
SheetHeader.displayName = "SheetHeader"
const SheetFooter = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
className
)}
{...props}
/>
)
SheetFooter.displayName = "SheetFooter"
const SheetTitle = React.forwardRef<
React.ElementRef<typeof SheetPrimitive.Title>,
@ -102,8 +111,8 @@ const SheetTitle = React.forwardRef<
className={cn("text-lg font-semibold text-foreground", className)}
{...props}
/>
));
SheetTitle.displayName = SheetPrimitive.Title.displayName;
))
SheetTitle.displayName = SheetPrimitive.Title.displayName
const SheetDescription = React.forwardRef<
React.ElementRef<typeof SheetPrimitive.Description>,
@ -114,8 +123,8 @@ const SheetDescription = React.forwardRef<
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
));
SheetDescription.displayName = SheetPrimitive.Description.displayName;
))
SheetDescription.displayName = SheetPrimitive.Description.displayName
export {
Sheet,
@ -128,4 +137,4 @@ export {
SheetFooter,
SheetTitle,
SheetDescription,
};
}

View File

@ -1,9 +1,15 @@
import { cn } from "@/lib/utils";
import { cn } from "@/lib/utils"
function Skeleton({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
function Skeleton({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) {
return (
<div className={cn("animate-pulse rounded-md bg-muted", className)} {...props} />
);
<div
className={cn("animate-pulse rounded-md bg-muted", className)}
{...props}
/>
)
}
export { Skeleton };
export { Skeleton }

View File

@ -1,9 +1,9 @@
"use client";
"use client"
import * as SliderPrimitive from "@radix-ui/react-slider";
import * as React from "react";
import * as React from "react"
import * as SliderPrimitive from "@radix-ui/react-slider"
import { cn } from "@/lib/utils";
import { cn } from "@/lib/utils"
const Slider = React.forwardRef<
React.ElementRef<typeof SliderPrimitive.Root>,
@ -11,7 +11,10 @@ const Slider = React.forwardRef<
>(({ className, ...props }, ref) => (
<SliderPrimitive.Root
ref={ref}
className={cn("relative flex w-full touch-none select-none items-center", className)}
className={cn(
"relative flex w-full touch-none select-none items-center",
className
)}
{...props}
>
<SliderPrimitive.Track className="relative h-2 w-full grow overflow-hidden rounded-full bg-secondary">
@ -19,7 +22,7 @@ const Slider = React.forwardRef<
</SliderPrimitive.Track>
<SliderPrimitive.Thumb className="block h-5 w-5 rounded-full border-2 border-primary bg-background ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50" />
</SliderPrimitive.Root>
));
Slider.displayName = SliderPrimitive.Root.displayName;
))
Slider.displayName = SliderPrimitive.Root.displayName
export { Slider };
export { Slider }

View File

@ -1,12 +1,12 @@
"use client";
"use client"
import { useTheme } from "next-themes";
import { Toaster as Sonner } from "sonner";
import { useTheme } from "next-themes"
import { Toaster as Sonner } from "sonner"
type ToasterProps = React.ComponentProps<typeof Sonner>;
type ToasterProps = React.ComponentProps<typeof Sonner>
const Toaster = ({ ...props }: ToasterProps) => {
const { theme = "system" } = useTheme();
const { theme = "system" } = useTheme()
return (
<Sonner
@ -19,12 +19,13 @@ const Toaster = ({ ...props }: ToasterProps) => {
description: "group-[.toast]:text-muted-foreground",
actionButton:
"group-[.toast]:bg-primary group-[.toast]:text-primary-foreground",
cancelButton: "group-[.toast]:bg-muted group-[.toast]:text-muted-foreground",
cancelButton:
"group-[.toast]:bg-muted group-[.toast]:text-muted-foreground",
},
}}
{...props}
/>
);
};
)
}
export { Toaster };
export { Toaster }

View File

@ -1,9 +1,9 @@
"use client";
"use client"
import * as SwitchPrimitives from "@radix-ui/react-switch";
import * as React from "react";
import * as React from "react"
import * as SwitchPrimitives from "@radix-ui/react-switch"
import { cn } from "@/lib/utils";
import { cn } from "@/lib/utils"
const Switch = React.forwardRef<
React.ElementRef<typeof SwitchPrimitives.Root>,
@ -12,18 +12,18 @@ const Switch = React.forwardRef<
<SwitchPrimitives.Root
className={cn(
"peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
className,
className
)}
{...props}
ref={ref}
>
<SwitchPrimitives.Thumb
className={cn(
"pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0",
"pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0"
)}
/>
</SwitchPrimitives.Root>
));
Switch.displayName = SwitchPrimitives.Root.displayName;
))
Switch.displayName = SwitchPrimitives.Root.displayName
export { Switch };
export { Switch }

View File

@ -1,9 +1,11 @@
import * as React from "react";
import * as React from "react"
import { cn } from "@/lib/utils";
import { cn } from "@/lib/utils"
const Table = React.forwardRef<HTMLTableElement, React.HTMLAttributes<HTMLTableElement>>(
({ className, ...props }, ref) => (
const Table = React.forwardRef<
HTMLTableElement,
React.HTMLAttributes<HTMLTableElement>
>(({ className, ...props }, ref) => (
<div className="relative w-full overflow-auto">
<table
ref={ref}
@ -11,25 +13,28 @@ const Table = React.forwardRef<HTMLTableElement, React.HTMLAttributes<HTMLTableE
{...props}
/>
</div>
),
);
Table.displayName = "Table";
))
Table.displayName = "Table"
const TableHeader = React.forwardRef<
HTMLTableSectionElement,
React.HTMLAttributes<HTMLTableSectionElement>
>(({ className, ...props }, ref) => (
<thead ref={ref} className={cn("[&_tr]:border-b", className)} {...props} />
));
TableHeader.displayName = "TableHeader";
))
TableHeader.displayName = "TableHeader"
const TableBody = React.forwardRef<
HTMLTableSectionElement,
React.HTMLAttributes<HTMLTableSectionElement>
>(({ className, ...props }, ref) => (
<tbody ref={ref} className={cn("[&_tr:last-child]:border-0", className)} {...props} />
));
TableBody.displayName = "TableBody";
<tbody
ref={ref}
className={cn("[&_tr:last-child]:border-0", className)}
{...props}
/>
))
TableBody.displayName = "TableBody"
const TableFooter = React.forwardRef<
HTMLTableSectionElement,
@ -37,11 +42,14 @@ const TableFooter = React.forwardRef<
>(({ className, ...props }, ref) => (
<tfoot
ref={ref}
className={cn("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0", className)}
className={cn(
"border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",
className
)}
{...props}
/>
));
TableFooter.displayName = "TableFooter";
))
TableFooter.displayName = "TableFooter"
const TableRow = React.forwardRef<
HTMLTableRowElement,
@ -51,12 +59,12 @@ const TableRow = React.forwardRef<
ref={ref}
className={cn(
"border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",
className,
className
)}
{...props}
/>
));
TableRow.displayName = "TableRow";
))
TableRow.displayName = "TableRow"
const TableHead = React.forwardRef<
HTMLTableCellElement,
@ -66,12 +74,12 @@ const TableHead = React.forwardRef<
ref={ref}
className={cn(
"h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0",
className,
className
)}
{...props}
/>
));
TableHead.displayName = "TableHead";
))
TableHead.displayName = "TableHead"
const TableCell = React.forwardRef<
HTMLTableCellElement,
@ -82,8 +90,8 @@ const TableCell = React.forwardRef<
className={cn("p-4 align-middle [&:has([role=checkbox])]:pr-0", className)}
{...props}
/>
));
TableCell.displayName = "TableCell";
))
TableCell.displayName = "TableCell"
const TableCaption = React.forwardRef<
HTMLTableCaptionElement,
@ -94,8 +102,8 @@ const TableCaption = React.forwardRef<
className={cn("mt-4 text-sm text-muted-foreground", className)}
{...props}
/>
));
TableCaption.displayName = "TableCaption";
))
TableCaption.displayName = "TableCaption"
export {
Table,
@ -106,4 +114,4 @@ export {
TableRow,
TableCell,
TableCaption,
};
}

View File

@ -1,11 +1,11 @@
"use client";
"use client"
import * as TabsPrimitive from "@radix-ui/react-tabs";
import * as React from "react";
import * as React from "react"
import * as TabsPrimitive from "@radix-ui/react-tabs"
import { cn } from "@/lib/utils";
import { cn } from "@/lib/utils"
const Tabs = TabsPrimitive.Root;
const Tabs = TabsPrimitive.Root
const TabsList = React.forwardRef<
React.ElementRef<typeof TabsPrimitive.List>,
@ -15,12 +15,12 @@ const TabsList = React.forwardRef<
ref={ref}
className={cn(
"inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground",
className,
className
)}
{...props}
/>
));
TabsList.displayName = TabsPrimitive.List.displayName;
))
TabsList.displayName = TabsPrimitive.List.displayName
const TabsTrigger = React.forwardRef<
React.ElementRef<typeof TabsPrimitive.Trigger>,
@ -30,12 +30,12 @@ const TabsTrigger = React.forwardRef<
ref={ref}
className={cn(
"inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
className,
className
)}
{...props}
/>
));
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
))
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName
const TabsContent = React.forwardRef<
React.ElementRef<typeof TabsPrimitive.Content>,
@ -45,11 +45,11 @@ const TabsContent = React.forwardRef<
ref={ref}
className={cn(
"mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
className,
className
)}
{...props}
/>
));
TabsContent.displayName = TabsPrimitive.Content.displayName;
))
TabsContent.displayName = TabsPrimitive.Content.displayName
export { Tabs, TabsList, TabsTrigger, TabsContent };
export { Tabs, TabsList, TabsTrigger, TabsContent }

View File

@ -1,6 +1,6 @@
import * as React from "react";
import * as React from "react"
import { cn } from "@/lib/utils";
import { cn } from "@/lib/utils"
export interface TextareaProps
extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}
@ -11,14 +11,14 @@ const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
<textarea
className={cn(
"flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className,
className
)}
ref={ref}
{...props}
/>
);
},
);
Textarea.displayName = "Textarea";
)
}
)
Textarea.displayName = "Textarea"
export { Textarea };
export { Textarea }

View File

@ -1,77 +1,63 @@
import {
Bug,
CircleAlert,
CircleCheckBig,
CircleHelp,
MessageSquareText,
Minus,
OctagonX,
Plus,
} from "lucide-react";
import {Bug, CircleAlert, CircleCheckBig, CircleHelp, MessageSquareText, Minus, OctagonX, Plus} from "lucide-react";
import React from "react";
export enum toastType {
info = "info",
warn = "warn",
error = "error",
refused = "refused",
refused= "refused",
success = "success",
add = "add",
del = "del",
message = "message",
message = "message"
}
export function ToastBox({
title,
message,
type,
}: { title?: string; message: string; type: toastType }) {
export function ToastBox({title, message, type}: {title?: string, message: string, type: toastType}) {
let icon: any;
let bgColor: string;
switch (type) {
case toastType.message:
icon = <MessageSquareText />;
bgColor = "bg-accent";
break;
case toastType.message :
icon = <MessageSquareText />
bgColor = 'bg-accent'
break
case toastType.add:
icon = <Plus />;
bgColor = "bg-accent";
break;
icon = <Plus />
bgColor = 'bg-accent'
break
case toastType.del:
icon = <Minus />;
bgColor = "bg-accent";
break;
icon = <Minus />
bgColor = 'bg-accent'
break
case toastType.info:
icon = <CircleHelp />;
bgColor = "bg-accent";
break;
icon = <CircleHelp />
bgColor = 'bg-accent'
break
case toastType.warn:
icon = <CircleAlert />;
bgColor = "bg-orange-500";
break;
icon = <CircleAlert />
bgColor = 'bg-orange-500'
break
case toastType.error:
icon = <Bug />;
bgColor = "bg-red-500";
break;
icon = <Bug />
bgColor = 'bg-red-500'
break
case toastType.success:
icon = <CircleCheckBig />;
bgColor = "bg-green-500";
break;
icon = <CircleCheckBig />
bgColor = 'bg-green-500'
break
case toastType.refused:
icon = <OctagonX />;
bgColor = "bg-red-700";
break;
icon = <OctagonX />
bgColor = 'bg-red-700'
break
}
return (
<div
className={`flex flex-row items-center gap-2 scale-90 md:scale-100 p-2 rounded border ${bgColor}`}
>
<div className={`flex flex-row items-center gap-2 scale-90 md:scale-100 p-2 rounded border ${bgColor}`}>
{icon}
<div className={"flex flex-col justify-center items-start"}>
{title && <h3 className={"text-nowrap font-bold text-xl"}>{title}</h3>}
<p className={"text-wrap"}>{message}</p>
</div>
</div>
);
)
}

View File

@ -1,13 +1,13 @@
"use client";
"use client"
import * as ToastPrimitives from "@radix-ui/react-toast";
import { type VariantProps, cva } from "class-variance-authority";
import { X } from "lucide-react";
import * as React from "react";
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";
import { cn } from "@/lib/utils"
const ToastProvider = ToastPrimitives.Provider;
const ToastProvider = ToastPrimitives.Provider
const ToastViewport = React.forwardRef<
React.ElementRef<typeof ToastPrimitives.Viewport>,
@ -17,12 +17,12 @@ const ToastViewport = React.forwardRef<
ref={ref}
className={cn(
"fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]",
className,
className
)}
{...props}
/>
));
ToastViewport.displayName = ToastPrimitives.Viewport.displayName;
))
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",
@ -37,8 +37,8 @@ const toastVariants = cva(
defaultVariants: {
variant: "default",
},
},
);
}
)
const Toast = React.forwardRef<
React.ElementRef<typeof ToastPrimitives.Root>,
@ -51,9 +51,9 @@ const Toast = React.forwardRef<
className={cn(toastVariants({ variant }), className)}
{...props}
/>
);
});
Toast.displayName = ToastPrimitives.Root.displayName;
)
})
Toast.displayName = ToastPrimitives.Root.displayName
const ToastAction = React.forwardRef<
React.ElementRef<typeof ToastPrimitives.Action>,
@ -63,12 +63,12 @@ const ToastAction = React.forwardRef<
ref={ref}
className={cn(
"inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium ring-offset-background transition-colors hover:bg-secondary focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 group-[.destructive]:border-muted/40 group-[.destructive]:hover:border-destructive/30 group-[.destructive]:hover:bg-destructive group-[.destructive]:hover:text-destructive-foreground group-[.destructive]:focus:ring-destructive",
className,
className
)}
{...props}
/>
));
ToastAction.displayName = ToastPrimitives.Action.displayName;
))
ToastAction.displayName = ToastPrimitives.Action.displayName
const ToastClose = React.forwardRef<
React.ElementRef<typeof ToastPrimitives.Close>,
@ -78,15 +78,15 @@ const ToastClose = React.forwardRef<
ref={ref}
className={cn(
"absolute right-2 top-2 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-2 group-hover:opacity-100 group-[.destructive]:text-red-300 group-[.destructive]:hover:text-red-50 group-[.destructive]:focus:ring-red-400 group-[.destructive]:focus:ring-offset-red-600",
className,
className
)}
toast-close=""
{...props}
>
<X className="h-4 w-4" />
</ToastPrimitives.Close>
));
ToastClose.displayName = ToastPrimitives.Close.displayName;
))
ToastClose.displayName = ToastPrimitives.Close.displayName
const ToastTitle = React.forwardRef<
React.ElementRef<typeof ToastPrimitives.Title>,
@ -97,8 +97,8 @@ const ToastTitle = React.forwardRef<
className={cn("text-sm font-semibold", className)}
{...props}
/>
));
ToastTitle.displayName = ToastPrimitives.Title.displayName;
))
ToastTitle.displayName = ToastPrimitives.Title.displayName
const ToastDescription = React.forwardRef<
React.ElementRef<typeof ToastPrimitives.Description>,
@ -109,12 +109,12 @@ const ToastDescription = React.forwardRef<
className={cn("text-sm opacity-90", className)}
{...props}
/>
));
ToastDescription.displayName = ToastPrimitives.Description.displayName;
))
ToastDescription.displayName = ToastPrimitives.Description.displayName
type ToastProps = React.ComponentPropsWithoutRef<typeof Toast>;
type ToastProps = React.ComponentPropsWithoutRef<typeof Toast>
type ToastActionElement = React.ReactElement<typeof ToastAction>;
type ToastActionElement = React.ReactElement<typeof ToastAction>
export {
type ToastProps,
@ -126,4 +126,4 @@ export {
ToastDescription,
ToastClose,
ToastAction,
};
}

View File

@ -1,4 +1,4 @@
"use client";
"use client"
import {
Toast,
@ -7,25 +7,29 @@ import {
ToastProvider,
ToastTitle,
ToastViewport,
} from "@/components/ui/toast";
import { useToast } from "@/components/ui/use-toast";
} from "@/components/ui/toast"
import { useToast } from "@/components/ui/use-toast"
export function Toaster() {
const { toasts } = useToast();
const { toasts } = useToast()
return (
<ToastProvider>
{toasts.map(({ id, title, description, action, ...props }) => (
{toasts.map(function ({ id, title, description, action, ...props }) {
return (
<Toast key={id} {...props}>
<div className="grid gap-1">
{title && <ToastTitle>{title}</ToastTitle>}
{description && <ToastDescription>{description}</ToastDescription>}
{description && (
<ToastDescription>{description}</ToastDescription>
)}
</div>
{action}
<ToastClose />
</Toast>
))}
)
})}
<ToastViewport />
</ToastProvider>
);
)
}

View File

@ -1,16 +1,18 @@
"use client";
"use client"
import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group";
import type { VariantProps } from "class-variance-authority";
import * as React from "react";
import * as React from "react"
import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group"
import { VariantProps } from "class-variance-authority"
import { toggleVariants } from "@/components/ui/toggle";
import { cn } from "@/lib/utils";
import { cn } from "@/lib/utils"
import { toggleVariants } from "@/components/ui/toggle"
const ToggleGroupContext = React.createContext<VariantProps<typeof toggleVariants>>({
const ToggleGroupContext = React.createContext<
VariantProps<typeof toggleVariants>
>({
size: "default",
variant: "default",
});
})
const ToggleGroup = React.forwardRef<
React.ElementRef<typeof ToggleGroupPrimitive.Root>,
@ -26,16 +28,16 @@ const ToggleGroup = React.forwardRef<
{children}
</ToggleGroupContext.Provider>
</ToggleGroupPrimitive.Root>
));
))
ToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName;
ToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName
const ToggleGroupItem = React.forwardRef<
React.ElementRef<typeof ToggleGroupPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Item> &
VariantProps<typeof toggleVariants>
>(({ className, children, variant, size, ...props }, ref) => {
const context = React.useContext(ToggleGroupContext);
const context = React.useContext(ToggleGroupContext)
return (
<ToggleGroupPrimitive.Item
@ -45,15 +47,15 @@ const ToggleGroupItem = React.forwardRef<
variant: context.variant || variant,
size: context.size || size,
}),
className,
className
)}
{...props}
>
{children}
</ToggleGroupPrimitive.Item>
);
});
)
})
ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName;
ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName
export { ToggleGroup, ToggleGroupItem };
export { ToggleGroup, ToggleGroupItem }

View File

@ -1,10 +1,10 @@
"use client";
"use client"
import * as TogglePrimitive from "@radix-ui/react-toggle";
import { type VariantProps, cva } from "class-variance-authority";
import * as React from "react";
import * as React from "react"
import * as TogglePrimitive from "@radix-ui/react-toggle"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils";
import { cn } from "@/lib/utils"
const toggleVariants = cva(
"inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground",
@ -25,8 +25,8 @@ const toggleVariants = cva(
variant: "default",
size: "default",
},
},
);
}
)
const Toggle = React.forwardRef<
React.ElementRef<typeof TogglePrimitive.Root>,
@ -38,8 +38,8 @@ const Toggle = React.forwardRef<
className={cn(toggleVariants({ variant, size, className }))}
{...props}
/>
));
))
Toggle.displayName = TogglePrimitive.Root.displayName;
Toggle.displayName = TogglePrimitive.Root.displayName
export { Toggle, toggleVariants };
export { Toggle, toggleVariants }

View File

@ -1,15 +1,15 @@
"use client";
"use client"
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
import * as React from "react";
import * as React from "react"
import * as TooltipPrimitive from "@radix-ui/react-tooltip"
import { cn } from "@/lib/utils";
import { cn } from "@/lib/utils"
const TooltipProvider = TooltipPrimitive.Provider;
const TooltipProvider = TooltipPrimitive.Provider
const Tooltip = TooltipPrimitive.Root;
const Tooltip = TooltipPrimitive.Root
const TooltipTrigger = TooltipPrimitive.Trigger;
const TooltipTrigger = TooltipPrimitive.Trigger
const TooltipContent = React.forwardRef<
React.ElementRef<typeof TooltipPrimitive.Content>,
@ -20,11 +20,11 @@ const TooltipContent = React.forwardRef<
sideOffset={sideOffset}
className={cn(
"z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className,
className
)}
{...props}
/>
));
TooltipContent.displayName = TooltipPrimitive.Content.displayName;
))
TooltipContent.displayName = TooltipPrimitive.Content.displayName
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }

View File

@ -1,75 +1,78 @@
"use client";
"use client"
// Inspired by react-hot-toast library
import * as React from "react";
import * as React from "react"
import type { ToastActionElement, ToastProps } from "@/components/ui/toast";
import type {
ToastActionElement,
ToastProps,
} from "@/components/ui/toast"
const TOAST_LIMIT = 1;
const TOAST_REMOVE_DELAY = 1000000;
const TOAST_LIMIT = 1
const TOAST_REMOVE_DELAY = 1000000
type ToasterToast = ToastProps & {
id: string;
title?: React.ReactNode;
description?: React.ReactNode;
action?: ToastActionElement;
};
id: string
title?: React.ReactNode
description?: React.ReactNode
action?: ToastActionElement
}
const actionTypes = {
ADD_TOAST: "ADD_TOAST",
UPDATE_TOAST: "UPDATE_TOAST",
DISMISS_TOAST: "DISMISS_TOAST",
REMOVE_TOAST: "REMOVE_TOAST",
} as const;
} as const
let count = 0;
let count = 0
function genId() {
count = (count + 1) % Number.MAX_SAFE_INTEGER;
return count.toString();
count = (count + 1) % Number.MAX_SAFE_INTEGER
return count.toString()
}
type ActionType = typeof actionTypes;
type ActionType = typeof actionTypes
type Action =
| {
type: ActionType["ADD_TOAST"];
toast: ToasterToast;
type: ActionType["ADD_TOAST"]
toast: ToasterToast
}
| {
type: ActionType["UPDATE_TOAST"];
toast: Partial<ToasterToast>;
type: ActionType["UPDATE_TOAST"]
toast: Partial<ToasterToast>
}
| {
type: ActionType["DISMISS_TOAST"];
toastId?: ToasterToast["id"];
type: ActionType["DISMISS_TOAST"]
toastId?: ToasterToast["id"]
}
| {
type: ActionType["REMOVE_TOAST"];
toastId?: ToasterToast["id"];
};
type: ActionType["REMOVE_TOAST"]
toastId?: ToasterToast["id"]
}
interface State {
toasts: ToasterToast[];
toasts: ToasterToast[]
}
const toastTimeouts = new Map<string, ReturnType<typeof setTimeout>>();
const toastTimeouts = new Map<string, ReturnType<typeof setTimeout>>()
const addToRemoveQueue = (toastId: string) => {
if (toastTimeouts.has(toastId)) {
return;
return
}
const timeout = setTimeout(() => {
toastTimeouts.delete(toastId);
toastTimeouts.delete(toastId)
dispatch({
type: "REMOVE_TOAST",
toastId: toastId,
});
}, TOAST_REMOVE_DELAY);
})
}, TOAST_REMOVE_DELAY)
toastTimeouts.set(toastId, timeout);
};
toastTimeouts.set(toastId, timeout)
}
export const reducer = (state: State, action: Action): State => {
switch (action.type) {
@ -77,27 +80,27 @@ export const reducer = (state: State, action: Action): State => {
return {
...state,
toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT),
};
}
case "UPDATE_TOAST":
return {
...state,
toasts: state.toasts.map((t) =>
t.id === action.toast.id ? { ...t, ...action.toast } : t,
t.id === action.toast.id ? { ...t, ...action.toast } : t
),
};
}
case "DISMISS_TOAST": {
const { toastId } = action;
const { toastId } = action
// ! Side effects ! - This could be extracted into a dismissToast() action,
// but I'll keep it here for simplicity
if (toastId) {
addToRemoveQueue(toastId);
addToRemoveQueue(toastId)
} else {
state.toasts.forEach((toast) => {
addToRemoveQueue(toast.id);
});
addToRemoveQueue(toast.id)
})
}
return {
@ -108,46 +111,46 @@ export const reducer = (state: State, action: Action): State => {
...t,
open: false,
}
: t,
: t
),
};
}
}
case "REMOVE_TOAST":
if (action.toastId === undefined) {
return {
...state,
toasts: [],
};
}
}
return {
...state,
toasts: state.toasts.filter((t) => t.id !== action.toastId),
};
}
};
const listeners: Array<(state: State) => void> = [];
let memoryState: State = { toasts: [] };
function dispatch(action: Action) {
memoryState = reducer(memoryState, action);
listeners.forEach((listener) => {
listener(memoryState);
});
}
}
type Toast = Omit<ToasterToast, "id">;
const listeners: Array<(state: State) => void> = []
let memoryState: State = { toasts: [] }
function dispatch(action: Action) {
memoryState = reducer(memoryState, action)
listeners.forEach((listener) => {
listener(memoryState)
})
}
type Toast = Omit<ToasterToast, "id">
function toast({ ...props }: Toast) {
const id = genId();
const id = genId()
const update = (props: ToasterToast) =>
dispatch({
type: "UPDATE_TOAST",
toast: { ...props, id },
});
const dismiss = () => dispatch({ type: "DISMISS_TOAST", toastId: id });
})
const dismiss = () => dispatch({ type: "DISMISS_TOAST", toastId: id })
dispatch({
type: "ADD_TOAST",
@ -156,36 +159,36 @@ function toast({ ...props }: Toast) {
id,
open: true,
onOpenChange: (open) => {
if (!open) dismiss();
if (!open) dismiss()
},
},
});
})
return {
id: id,
dismiss,
update,
};
}
}
function useToast() {
const [state, setState] = React.useState<State>(memoryState);
const [state, setState] = React.useState<State>(memoryState)
React.useEffect(() => {
listeners.push(setState);
listeners.push(setState)
return () => {
const index = listeners.indexOf(setState);
const index = listeners.indexOf(setState)
if (index > -1) {
listeners.splice(index, 1);
listeners.splice(index, 1)
}
};
}, [state]);
}
}, [state])
return {
...state,
toast,
dismiss: (toastId?: string) => dispatch({ type: "DISMISS_TOAST", toastId }),
};
}
}
export { useToast, toast };
export { useToast, toast }

View File

@ -1,4 +1,4 @@
import type { IUserData } from "@/interfaces/userdata.interface";
import {IUserData} from "@/interfaces/userdata.interface";
// ----- Request -----
@ -17,19 +17,20 @@ export interface IApiLoginReq {
password: string;
}
// ----- Response -----
export interface IAbstractApiResponse {
message?: Array<string>;
error?: string;
statusCode?: number;
statusCode?: number
}
export interface IApiRegisterRes extends IAbstractApiResponse {
access_token?: string;
user?: IUserData;
user?: IUserData
}
export interface IApiLoginRes extends IAbstractApiResponse {
access_token?: string;
access_token?: string
}

View File

@ -1,6 +1,6 @@
import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
import { type ClassValue, clsx } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
return twMerge(clsx(inputs))
}

View File

@ -1,73 +1,55 @@
"use client";
"use client"
import type {
IApiLoginReq,
IApiLoginRes,
IApiRegisterReq,
IApiRegisterRes,
} from "@/interfaces/api.interface";
import type { IUserData } from "@/interfaces/userdata.interface";
import { createContext, useContext, useState } from 'react';
import {IUserData} from "@/interfaces/userdata.interface";
import {IApiLoginReq, IApiLoginRes, IApiRegisterReq, IApiRegisterRes} from "@/interfaces/api.interface";
import ApiRequest from "@/services/apiRequest";
import { useEncodedLocalStorage } from "@/services/localStorage";
import { createContext, useContext, useState } from "react";
import {useEncodedLocalStorage} from "@/services/localStorage";
const UserDataContext = createContext<IUserData | null>(null);
const [userData, setUserData] = useEncodedLocalStorage<IUserData | null>(
"user_data",
null,
);
const UserDataContext = createContext<IUserData | null>(null)
const [userData, setUserData] = useEncodedLocalStorage<IUserData | null>("user_data", null)
//TODO Run register task
export async function doRegister(
registerData: IApiRegisterReq,
): Promise<IApiRegisterRes | null> {
console.trace(registerData);
export async function doRegister(registerData: IApiRegisterReq): Promise<IApiRegisterRes | null> {
console.trace(registerData)
try {
const ReqRes = await ApiRequest.standard.post.json<IApiRegisterReq, IApiRegisterRes>(
"auth/signup",
registerData,
);
console.trace(ReqRes.data);
const ReqRes = await ApiRequest.standard.post.json<IApiRegisterReq, IApiRegisterRes>("auth/signup", registerData)
console.trace(ReqRes.data)
if (ReqRes.data.user) {
setUserData(ReqRes.data.user);
setUserData(ReqRes.data.user)
}
ReqRes.data.message?.forEach((err) => console.warn(err));
return ReqRes.data;
ReqRes.data.message?.forEach((err)=> console.warn(err))
return ReqRes.data
} catch (error) {
console.error("Error during registration:", error);
return null;
console.error('Error during registration:', error);
return null
}
}
//TODO Run login task
export async function doLogin(loginData: IApiLoginReq) {
try {
const ReqRes = await ApiRequest.standard.post.json<IApiLoginReq, IApiLoginRes>(
"auth/login",
loginData,
);
console.trace(ReqRes.data);
const ReqRes = await ApiRequest.standard.post.json<IApiLoginReq, IApiLoginRes>("auth/login", loginData)
console.trace(ReqRes.data)
//if (ReqRes.data.user) {
// setUserData(ReqRes.data.user)
//}
ReqRes.data.message?.forEach((err) => console.warn(err));
return ReqRes.data;
ReqRes.data.message?.forEach((err)=> console.warn(err))
return ReqRes.data
} catch (err) {
console.error("Error during login:", err);
return null;
console.error('Error during login:', err);
return null
}
}
//TODO Run disconnect task
export function doDisconnect() {
if (typeof window !== "undefined") {
window.localStorage.removeItem("sub");
return true;
if (typeof window !== 'undefined') {
window.localStorage.removeItem('sub')
return true
}
console.log(
"Whut ? Why trying to remove an item from the localStorage when runner in SSR ?",
);
return false;
console.log('Whut ? Why trying to remove an item from the localStorage when runner in SSR ?')
return false
}
//TODO Run update user data

View File

@ -1,83 +1,75 @@
"use client";
'use client'
import axios, { type AxiosResponse } from "axios";
import axios, {type AxiosResponse} from "axios";
const baseUrl = process.env.NEXT_PUBLIC_API_URL || "http://localhost:3333/";
const baseUrl = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3333'
const AxiosConfigs = {
authenticated: {
json: () => {
return {
headers: {
"content-type": "application/json",
Authorization: `Bearer ${typeof window !== "undefined" ? window.localStorage.getItem("sub") : "not-ssr"}`,
'content-type': 'application/json',
Authorization: `Bearer ${typeof window !== 'undefined' ? window.localStorage.getItem('sub') : "not-ssr"}`,
},
validateStatus: (status: number) => {
validateStatus: function (status: number) {
return status < 500; // Resolve only if the status code is less than 500
},
};
},
}
}
}
},
standard: {
json: () => {
return {
headers: {
"content-type": "application/json",
'content-type': 'application/json'
},
validateStatus: (status: number) => {
validateStatus: function (status: number) {
return status < 500; // Resolve only if the status code is less than 500
},
};
},
},
};
async function doAuthenticatedJsonPostReq<ReqT, ResT>(
route: string,
body: ReqT,
): Promise<AxiosResponse<ResT>> {
return await axios.post(baseUrl + route, body, AxiosConfigs.authenticated.json());
}
}
}
}
}
async function doAuthenticatedGetReq<ResT>(route: string): Promise<AxiosResponse<ResT>> {
return await axios.get(baseUrl + route, AxiosConfigs.authenticated.json());
async function doAuthenticatedJsonPostReq<ReqT, ResT>(route:string, body:ReqT): Promise<AxiosResponse<ResT>> {
return await axios.post(baseUrl + route, body, AxiosConfigs.authenticated.json())
}
async function doAuthenticatedPatchReq<ReqT, ResT>(
route: string,
body: ReqT,
): Promise<AxiosResponse<ResT>> {
return await axios.patch(baseUrl + route, body, AxiosConfigs.authenticated.json());
async function doAuthenticatedGetReq<ResT>(route:string): Promise<AxiosResponse<ResT>> {
return await axios.get(baseUrl + route, AxiosConfigs.authenticated.json())
}
async function doAuthenticatedDelReq<ResT>(route: string): Promise<AxiosResponse<ResT>> {
return await axios.delete(baseUrl + route, AxiosConfigs.authenticated.json());
async function doAuthenticatedPatchReq<ReqT, ResT>(route:string, body: ReqT): Promise<AxiosResponse<ResT>> {
return await axios.patch(baseUrl + route, body, AxiosConfigs.authenticated.json())
}
async function doAuthenticatedDelReq<ResT>(route:string): Promise<AxiosResponse<ResT>> {
return await axios.delete(baseUrl + route, AxiosConfigs.authenticated.json())
}
//TODO form/multipart req
async function doJsonPostReq<ReqT, ResT>(
route: string,
body: ReqT,
): Promise<AxiosResponse<ResT>> {
return await axios.post(baseUrl + route, body, AxiosConfigs.standard.json());
async function doJsonPostReq<ReqT, ResT>(route:string, body: ReqT): Promise<AxiosResponse<ResT>> {
return await axios.post(baseUrl + route, body, AxiosConfigs.standard.json())
}
async function doJsonGetReq<ResT>(route: string): Promise<AxiosResponse<ResT>> {
async function doJsonGetReq<ResT>(route:string): Promise<AxiosResponse<ResT>> {
return await axios.get(baseUrl + route, AxiosConfigs.standard.json());
}
const ApiRequest = {
authenticated: {
post: { json: doAuthenticatedJsonPostReq },
patch: { json: doAuthenticatedPatchReq },
delete: { json: doAuthenticatedDelReq },
get: { json: doAuthenticatedGetReq },
post: {json: doAuthenticatedJsonPostReq},
patch: {json: doAuthenticatedPatchReq},
delete: {json: doAuthenticatedDelReq},
get: {json: doAuthenticatedGetReq}
},
standard: {
post: { json: doJsonPostReq },
get: { json: doJsonGetReq },
},
};
post: {json: doJsonPostReq},
get: {json: doJsonGetReq}
}
}
export default ApiRequest;

View File

@ -1,9 +1,6 @@
"use client";
'use client'
import type React from "react";
import { useEffect, useRef, useState } from "react";
const localStorage = typeof window !== "undefined" ? window.localStorage : null;
import React, {useEffect, useRef, useState} from "react";
/**
* A custom React hook that allows you to store and retrieve data in the browser's localStorage.
@ -12,33 +9,34 @@ const localStorage = typeof window !== "undefined" ? window.localStorage : null;
* @param {T} initial - The initial value for the stored data.
* @returns {[T, React.Dispatch<React.SetStateAction<T>>]} - An array containing the stored value and a function to update the stored value.
*/
export function useLocalStorage<T>(
key: string,
initial: T,
): [T, React.Dispatch<React.SetStateAction<T>>] {
export function useLocalStorage<T>(key: string, initial: T): [T, React.Dispatch<React.SetStateAction<T>>] {
const readValue = () => {
const item = localStorage?.getItem(key);
const item = typeof window !== 'undefined' ? window.localStorage.getItem(key) : null
if (item) {
try {
return JSON.parse(item);
} catch (error) {
console.warn(`Error reading localStorage key “${key}”:`, error);
return JSON.parse(item)
} catch(error) {
console.warn(`Error reading localStorage key “${key}”:`, error)
}
}
return initial;
};
const [storedValue, setStoredValue] = useState<T>(readValue);
return initial
}
const [storedValue, setStoredValue] = useState<T>(readValue)
useEffect(() => {
try {
localStorage?.setItem(key, JSON.stringify(storedValue));
typeof window !== 'undefined' && window.localStorage.setItem(key, JSON.stringify(storedValue))
} catch (error) {
console.warn(`Error setting localStorage key “${key}”:`, error);
console.warn(`Error setting localStorage key “${key}”:`, error)
}
}, [key, storedValue]);
return [storedValue, setStoredValue];
}, [key, storedValue])
return [storedValue, setStoredValue]
}
/**
* Custom hook that provides a way to store and retrieve encoded values in local storage.
*
@ -49,22 +47,19 @@ export function useLocalStorage<T>(
*
* @return {readonly [T, React.Dispatch<React.SetStateAction<T>>]} - An array containing the encoded value and a function to update the encoded value.
*/
export function useEncodedLocalStorage<T>(
key: string,
fallbackValue: T,
): readonly [T, React.Dispatch<React.SetStateAction<T>>] {
console.log("Pong !");
export function useEncodedLocalStorage<T>(key: string, fallbackValue: T): readonly [T, React.Dispatch<React.SetStateAction<T>>] {
console.log("Pong !")
const [encodedValue, setEncodedValue] = useState<T>(() => {
const stored = localStorage?.getItem(key);
const stored = localStorage.getItem(key);
return stored ? safelyParse(stored, fallbackValue) : fallbackValue;
});
const prevValue = useRef(encodedValue);
useEffect(() => {
console.log({ encodedValue });
console.log({encodedValue})
if (!b64ValEqual(prevValue.current, encodedValue)) {
localStorage?.setItem(key, safelyStringify(encodedValue));
localStorage.setItem(key, safelyStringify(encodedValue));
}
prevValue.current = encodedValue; // Set ref to current value
}, [key, encodedValue]);
@ -82,6 +77,7 @@ export function useEncodedLocalStorage<T>(
return btoa(JSON.stringify(v1)) === btoa(JSON.stringify(v2));
}
function safelyStringify(value: T): string {
try {
return btoa(JSON.stringify(value));