home page
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Geist, Geist_Mono } from "next/font/google";
|
||||
import "./globals.css";
|
||||
import Navbar from "@/components/nav-bar";
|
||||
|
||||
const geistSans = Geist({
|
||||
variable: "--font-geist-sans",
|
||||
@@ -27,6 +28,7 @@ export default function RootLayout({
|
||||
<body
|
||||
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
||||
>
|
||||
<Navbar />
|
||||
{children}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,69 +1,109 @@
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import Image from "next/image";
|
||||
import Features, { FeatureItem } from "@/components/features";
|
||||
import Hero from "@/components/hero";
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<Card className="w-[350px]">
|
||||
<CardHeader>
|
||||
<CardTitle>Create project</CardTitle>
|
||||
<CardDescription>
|
||||
Deploy your new project in one-click.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<form>
|
||||
<div className="grid w-full items-center gap-4">
|
||||
<div className="flex flex-col space-y-1.5">
|
||||
<Label htmlFor="name">Name</Label>
|
||||
<Input
|
||||
id="name"
|
||||
placeholder="Name of your project"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col space-y-1.5">
|
||||
<Label htmlFor="framework">Framework</Label>
|
||||
<Select>
|
||||
<SelectTrigger id="framework">
|
||||
<SelectValue placeholder="Select" />
|
||||
</SelectTrigger>
|
||||
<SelectContent position="popper">
|
||||
<SelectItem value="next">
|
||||
Next.js
|
||||
</SelectItem>
|
||||
<SelectItem value="sveltekit">
|
||||
SvelteKit
|
||||
</SelectItem>
|
||||
<SelectItem value="astro">Astro</SelectItem>
|
||||
<SelectItem value="nuxt">
|
||||
Nuxt.js
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</CardContent>
|
||||
<CardFooter className="flex justify-between">
|
||||
<Button variant="outline">Cancel</Button>
|
||||
<Button>Deploy</Button>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
<main>
|
||||
<Hero />
|
||||
<Features
|
||||
title="DÉVELOPPEMENT DU SYSTÈME"
|
||||
description="Latosa Escrima Concepts est un système martial dynamique et en constante évolution. Ce système repose sur une approche logique, qui progresse au fil du développement des compétences techniques des pratiquants."
|
||||
cta="Envie de découvrir Latosa Escrima ?"
|
||||
>
|
||||
<FeatureItem
|
||||
title="Les Fondements de Latosa Escrima Concepts"
|
||||
position="left"
|
||||
image="https://shadcnblocks.com/images/block/placeholder-2.svg"
|
||||
>
|
||||
<ol className="list-decimal text-justify flex flex-col gap-4">
|
||||
<li>
|
||||
Un Système Centré sur les Concepts{" "}
|
||||
<ul className="list-disc list-inside">
|
||||
<li>
|
||||
Étude et application des meilleurs concepts
|
||||
et stratégies issus de différentes approches
|
||||
martiales.
|
||||
</li>
|
||||
<li>
|
||||
Comprendre ce que l’on fait, comment on le
|
||||
fait et pourquoi on le fait.
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
Éducation au Mouvement et à l’Efficacité
|
||||
<ul className="list-disc list-inside">
|
||||
<li>
|
||||
Plus qu’un enchaînement de techniques : une
|
||||
véritable éducation aux mouvements corporels
|
||||
et à l’efficacité des armes.
|
||||
</li>
|
||||
<li>
|
||||
Priorité à l’authenticité et à la réalité.
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ol>
|
||||
</FeatureItem>
|
||||
<FeatureItem
|
||||
title="L’Évolution du Système"
|
||||
position="right"
|
||||
image="https://shadcnblocks.com/images/block/placeholder-2.svg"
|
||||
>
|
||||
<ol className="list-none text-justify flex flex-col gap-4">
|
||||
<li>
|
||||
<span className="font-bold">
|
||||
Les Premières Étapes
|
||||
</span>
|
||||
<ul className="list-disc list-inside">
|
||||
<li>
|
||||
Initialement centré sur les techniques et
|
||||
mouvements, le système s’est montré efficace
|
||||
mais incomplet.
|
||||
</li>
|
||||
<li>
|
||||
Recherche de ce qui différencie les arts
|
||||
martiaux philippins des autres disciplines.
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<span className="font-bold">
|
||||
La Découverte des Concepts Clés
|
||||
</span>{" "}
|
||||
<ul className="list-disc list-inside">
|
||||
<li>
|
||||
Rôle central des concepts de combat :
|
||||
<ul className="list-disc list-inside pl-4">
|
||||
<li>Puissance dans les frappes.</li>
|
||||
<li>Blocage ferme.</li>
|
||||
<li>Équilibre et attitude.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
Restructuration des exercices pour intégrer
|
||||
et transmettre ces concepts fondamentaux.
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ol>
|
||||
</FeatureItem>
|
||||
<FeatureItem
|
||||
title="Les Principes du Système Aujourd’hui"
|
||||
position="left"
|
||||
image="https://shadcnblocks.com/images/block/placeholder-2.svg"
|
||||
>
|
||||
Latosa Escrima Concepts repose sur cinq concepts
|
||||
fondamentaux :
|
||||
<ul className="list-disc list-inside">
|
||||
<li>Équilibre</li>
|
||||
<li>Vitesse (Timing et Distance)</li>
|
||||
<li>Puissance</li>
|
||||
<li>Concentration</li>
|
||||
<li>Transition</li>
|
||||
</ul>
|
||||
</FeatureItem>
|
||||
</Features>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
79
latosa-frontend/components/features.tsx
Normal file
79
latosa-frontend/components/features.tsx
Normal file
@@ -0,0 +1,79 @@
|
||||
import { ArrowRight } from "lucide-react";
|
||||
|
||||
const Features: React.FC<
|
||||
React.PropsWithChildren<{
|
||||
title: string;
|
||||
description: string;
|
||||
cta: string;
|
||||
}>
|
||||
> = ({ title, description, cta, children }) => {
|
||||
return (
|
||||
<section className="py-32 px-4">
|
||||
<div className="container flex flex-col gap-16 lg:px-16">
|
||||
<div className="lg:max-w-sm">
|
||||
<h2 className="mb-3 text-xl font-semibold md:mb-4 md:text-4xl lg:mb-6">
|
||||
{title}
|
||||
</h2>
|
||||
<p className="mb-8 text-muted-foreground lg:text-lg">
|
||||
{description}
|
||||
</p>
|
||||
<a
|
||||
href="#"
|
||||
className="group flex items-center text-xs font-medium md:text-base lg:text-lg"
|
||||
>
|
||||
{cta}
|
||||
<ArrowRight className="ml-2 size-4 transition-transform group-hover:translate-x-1" />
|
||||
</a>
|
||||
</div>
|
||||
<div className="grid gap-6 md:grid-cols-2 lg:gap-8">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Features;
|
||||
|
||||
export const FeatureItem: React.FC<
|
||||
React.PropsWithChildren<{
|
||||
title: string;
|
||||
image: string;
|
||||
position: "left" | "right";
|
||||
}>
|
||||
> = ({ title, children, image, position }) => {
|
||||
const _image = () => (
|
||||
<div className="md:min-h-[24rem] lg:min-h-[28rem] xl:min-h-[32rem]">
|
||||
<img
|
||||
src={image}
|
||||
alt={title}
|
||||
className="aspect-[16/9] h-full w-full object-cover object-center"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
const _content = () => (
|
||||
<div className="flex flex-col justify-center px-6 py-8 md:px-8 md:py-10 lg:px-10 lg:py-12">
|
||||
<h3 className="mb-3 text-lg font-semibold md:mb-4 md:text-2xl lg:mb-6">
|
||||
{title}
|
||||
</h3>
|
||||
<div className="text-muted-foreground lg:text-lg">{children}</div>
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div
|
||||
className={`flex ${position === "left" ? "flex-col" : "flex-col-reverse"} overflow-clip rounded-xl border border-border md:col-span-2 md:grid md:grid-cols-2 md:gap-6 lg:gap-8`}
|
||||
>
|
||||
{position === "left" ? (
|
||||
<>
|
||||
<_image />
|
||||
<_content />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<_content />
|
||||
<_image />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
46
latosa-frontend/components/hero.tsx
Normal file
46
latosa-frontend/components/hero.tsx
Normal file
@@ -0,0 +1,46 @@
|
||||
import { ExternalLink } from "lucide-react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button, buttonVariants } from "@/components/ui/button";
|
||||
|
||||
const Hero = () => {
|
||||
return (
|
||||
<section
|
||||
style={{ height: "calc(100vh - 68px)" }}
|
||||
className="flex justify-center items-center relative overflow-hidden py-32"
|
||||
>
|
||||
<div className="">
|
||||
<div className="bg-blue-50 magicpattern absolute inset-x-0 top-0 -z-10 flex h-full w-full items-center justify-center opacity-100" />
|
||||
<div className="mx-auto flex max-w-5xl flex-col items-center">
|
||||
<div className="z-10 flex flex-col items-center gap-6 text-center">
|
||||
<img
|
||||
src="https://shadcnblocks.com/images/block/block-1.svg"
|
||||
alt="logo"
|
||||
className="h-16"
|
||||
/>
|
||||
<Badge variant="outline">Latosa-Escrima</Badge>
|
||||
<div>
|
||||
<h1 className="mb-6 text-pretty text-2xl font-bold lg:text-5xl">
|
||||
Trouvez votre équilibre avec Latosa-Escrima
|
||||
</h1>
|
||||
<p className="text-muted-foreground lg:text-xl">
|
||||
Une évolution des arts martiaux Philippins
|
||||
</p>
|
||||
</div>
|
||||
<div className="mt-4 flex justify-center gap-2">
|
||||
<Button>Nous contacter</Button>
|
||||
<Button variant="outline">
|
||||
À propos
|
||||
<ExternalLink className="ml-2 h-4" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Hero;
|
||||
416
latosa-frontend/components/nav-bar.tsx
Normal file
416
latosa-frontend/components/nav-bar.tsx
Normal file
@@ -0,0 +1,416 @@
|
||||
import { Book, Menu, Sunset, Trees, Zap } from "lucide-react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
import {
|
||||
Accordion,
|
||||
AccordionContent,
|
||||
AccordionItem,
|
||||
AccordionTrigger,
|
||||
} from "@/components/ui/accordion";
|
||||
import { Button, buttonVariants } from "@/components/ui/button";
|
||||
import {
|
||||
NavigationMenu,
|
||||
NavigationMenuContent,
|
||||
NavigationMenuItem,
|
||||
NavigationMenuLink,
|
||||
NavigationMenuList,
|
||||
NavigationMenuTrigger,
|
||||
navigationMenuTriggerStyle,
|
||||
} from "@/components/ui/navigation-menu";
|
||||
import {
|
||||
Sheet,
|
||||
SheetContent,
|
||||
SheetHeader,
|
||||
SheetTitle,
|
||||
SheetTrigger,
|
||||
} from "@/components/ui/sheet";
|
||||
|
||||
const subMenuItemsOne = [
|
||||
{
|
||||
title: "Blog",
|
||||
description: "The latest industry news, updates, and info",
|
||||
icon: <Book className="size-5 shrink-0" />,
|
||||
},
|
||||
{
|
||||
title: "Compnay",
|
||||
description: "Our mission is to innovate and empower the world",
|
||||
icon: <Trees className="size-5 shrink-0" />,
|
||||
},
|
||||
{
|
||||
title: "Careers",
|
||||
description: "Browse job listing and discover our workspace",
|
||||
icon: <Sunset className="size-5 shrink-0" />,
|
||||
},
|
||||
{
|
||||
title: "Support",
|
||||
description:
|
||||
"Get in touch with our support team or visit our community forums",
|
||||
icon: <Zap className="size-5 shrink-0" />,
|
||||
},
|
||||
];
|
||||
|
||||
const subMenuItemsTwo = [
|
||||
{
|
||||
title: "Help Center",
|
||||
description: "Get all the answers you need right here",
|
||||
icon: <Zap className="size-5 shrink-0" />,
|
||||
},
|
||||
{
|
||||
title: "Contact Us",
|
||||
description: "We are here to help you with any questions you have",
|
||||
icon: <Sunset className="size-5 shrink-0" />,
|
||||
},
|
||||
{
|
||||
title: "Status",
|
||||
description: "Check the current status of our services and APIs",
|
||||
icon: <Trees className="size-5 shrink-0" />,
|
||||
},
|
||||
{
|
||||
title: "Terms of Service",
|
||||
description: "Our terms and conditions for using our services",
|
||||
icon: <Book className="size-5 shrink-0" />,
|
||||
},
|
||||
];
|
||||
|
||||
const Navbar = () => {
|
||||
return (
|
||||
<section className="p-4">
|
||||
<div className="">
|
||||
<nav className="hidden justify-between lg:flex">
|
||||
<div className="flex items-center gap-6">
|
||||
<div className="flex items-center gap-2">
|
||||
<img
|
||||
src="https://shadcnblocks.com/images/block/block-1.svg"
|
||||
className="w-8"
|
||||
alt="logo"
|
||||
/>
|
||||
<span className="text-xl font-bold">
|
||||
Latosa-Escrima
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<a
|
||||
className={cn(
|
||||
"text-muted-foreground",
|
||||
navigationMenuTriggerStyle,
|
||||
buttonVariants({
|
||||
variant: "ghost",
|
||||
}),
|
||||
)}
|
||||
href="#"
|
||||
>
|
||||
Home
|
||||
</a>
|
||||
<NavigationMenu>
|
||||
<NavigationMenuList>
|
||||
<NavigationMenuItem className="text-muted-foreground">
|
||||
<NavigationMenuTrigger>
|
||||
<span>Products</span>
|
||||
</NavigationMenuTrigger>
|
||||
<NavigationMenuContent>
|
||||
<ul className="w-80 p-3">
|
||||
<NavigationMenuLink>
|
||||
{subMenuItemsOne.map(
|
||||
(item, idx) => (
|
||||
<li key={idx}>
|
||||
<a
|
||||
className={cn(
|
||||
"flex select-none gap-4 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",
|
||||
)}
|
||||
href="#"
|
||||
>
|
||||
{item.icon}
|
||||
<div>
|
||||
<div className="text-sm font-semibold">
|
||||
{
|
||||
item.title
|
||||
}
|
||||
</div>
|
||||
<p className="text-sm leading-snug text-muted-foreground">
|
||||
{
|
||||
item.description
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
),
|
||||
)}
|
||||
</NavigationMenuLink>
|
||||
</ul>
|
||||
</NavigationMenuContent>
|
||||
</NavigationMenuItem>
|
||||
<NavigationMenuItem className="text-muted-foreground">
|
||||
<NavigationMenuTrigger>
|
||||
Resources
|
||||
</NavigationMenuTrigger>
|
||||
<NavigationMenuContent>
|
||||
<ul className="w-80 p-3">
|
||||
<NavigationMenuLink>
|
||||
{subMenuItemsTwo.map(
|
||||
(item, idx) => (
|
||||
<li key={idx}>
|
||||
<a
|
||||
className={cn(
|
||||
"flex select-none gap-4 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",
|
||||
)}
|
||||
href="#"
|
||||
>
|
||||
{item.icon}
|
||||
<div>
|
||||
<div className="text-sm font-semibold">
|
||||
{
|
||||
item.title
|
||||
}
|
||||
</div>
|
||||
<p className="text-sm leading-snug text-muted-foreground">
|
||||
{
|
||||
item.description
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
),
|
||||
)}
|
||||
</NavigationMenuLink>
|
||||
</ul>
|
||||
</NavigationMenuContent>
|
||||
</NavigationMenuItem>
|
||||
</NavigationMenuList>
|
||||
</NavigationMenu>
|
||||
|
||||
<a
|
||||
className={cn(
|
||||
"text-muted-foreground",
|
||||
navigationMenuTriggerStyle,
|
||||
buttonVariants({
|
||||
variant: "ghost",
|
||||
}),
|
||||
)}
|
||||
href="#"
|
||||
>
|
||||
Pricing
|
||||
</a>
|
||||
<a
|
||||
className={cn(
|
||||
"text-muted-foreground",
|
||||
navigationMenuTriggerStyle,
|
||||
buttonVariants({
|
||||
variant: "ghost",
|
||||
}),
|
||||
)}
|
||||
href="#"
|
||||
>
|
||||
Blog
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
<Button variant="outline">Log in</Button>
|
||||
<Button>Sign up</Button>
|
||||
</div>
|
||||
</nav>
|
||||
<div className="block lg:hidden">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-2">
|
||||
<img
|
||||
src="https://shadcnblocks.com/images/block/block-1.svg"
|
||||
className="w-8"
|
||||
alt="logo"
|
||||
/>
|
||||
<span className="text-xl font-bold">
|
||||
Shadcn Blocks
|
||||
</span>
|
||||
</div>
|
||||
<Sheet>
|
||||
<SheetTrigger asChild>
|
||||
<Button variant="outline" size="icon">
|
||||
<Menu className="size-4" />
|
||||
</Button>
|
||||
</SheetTrigger>
|
||||
<SheetContent className="overflow-y-auto">
|
||||
<SheetHeader>
|
||||
<SheetTitle>
|
||||
<div className="flex items-center gap-2">
|
||||
<img
|
||||
src="https://shadcnblocks.com/images/block/block-1.svg"
|
||||
className="w-8"
|
||||
alt="logo"
|
||||
/>
|
||||
<span className="text-xl font-bold">
|
||||
Shadcn Blocks
|
||||
</span>
|
||||
</div>
|
||||
</SheetTitle>
|
||||
</SheetHeader>
|
||||
<div className="mb-8 mt-8 flex flex-col gap-4">
|
||||
<a href="#" className="font-semibold">
|
||||
Home
|
||||
</a>
|
||||
<Accordion
|
||||
type="single"
|
||||
collapsible
|
||||
className="w-full"
|
||||
>
|
||||
<AccordionItem
|
||||
value="products"
|
||||
className="border-b-0"
|
||||
>
|
||||
<AccordionTrigger className="mb-4 py-0 font-semibold hover:no-underline">
|
||||
Products
|
||||
</AccordionTrigger>
|
||||
<AccordionContent className="mt-2">
|
||||
{subMenuItemsOne.map(
|
||||
(item, idx) => (
|
||||
<a
|
||||
key={idx}
|
||||
className={cn(
|
||||
"flex select-none gap-4 rounded-md p-3 leading-none outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground",
|
||||
)}
|
||||
href="#"
|
||||
>
|
||||
{item.icon}
|
||||
<div>
|
||||
<div className="text-sm font-semibold">
|
||||
{item.title}
|
||||
</div>
|
||||
<p className="text-sm leading-snug text-muted-foreground">
|
||||
{
|
||||
item.description
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
</a>
|
||||
),
|
||||
)}
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
<AccordionItem
|
||||
value="resources"
|
||||
className="border-b-0"
|
||||
>
|
||||
<AccordionTrigger className="py-0 font-semibold hover:no-underline">
|
||||
Resources
|
||||
</AccordionTrigger>
|
||||
<AccordionContent className="mt-2">
|
||||
{subMenuItemsTwo.map(
|
||||
(item, idx) => (
|
||||
<a
|
||||
key={idx}
|
||||
className={cn(
|
||||
"flex select-none gap-4 rounded-md p-3 leading-none outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground",
|
||||
)}
|
||||
href="#"
|
||||
>
|
||||
{item.icon}
|
||||
<div>
|
||||
<div className="text-sm font-semibold">
|
||||
{item.title}
|
||||
</div>
|
||||
<p className="text-sm leading-snug text-muted-foreground">
|
||||
{
|
||||
item.description
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
</a>
|
||||
),
|
||||
)}
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
<a href="#" className="font-semibold">
|
||||
Pricing
|
||||
</a>
|
||||
<a href="#" className="font-semibold">
|
||||
Blog
|
||||
</a>
|
||||
</div>
|
||||
<div className="border-t pt-4">
|
||||
<div className="grid grid-cols-2 justify-start">
|
||||
<a
|
||||
className={cn(
|
||||
buttonVariants({
|
||||
variant: "ghost",
|
||||
}),
|
||||
"justify-start text-muted-foreground",
|
||||
)}
|
||||
href="#"
|
||||
>
|
||||
Press
|
||||
</a>
|
||||
<a
|
||||
className={cn(
|
||||
buttonVariants({
|
||||
variant: "ghost",
|
||||
}),
|
||||
"justify-start text-muted-foreground",
|
||||
)}
|
||||
href="#"
|
||||
>
|
||||
Contact
|
||||
</a>
|
||||
<a
|
||||
className={cn(
|
||||
buttonVariants({
|
||||
variant: "ghost",
|
||||
}),
|
||||
"justify-start text-muted-foreground",
|
||||
)}
|
||||
href="#"
|
||||
>
|
||||
Imprint
|
||||
</a>
|
||||
<a
|
||||
className={cn(
|
||||
buttonVariants({
|
||||
variant: "ghost",
|
||||
}),
|
||||
"justify-start text-muted-foreground",
|
||||
)}
|
||||
href="#"
|
||||
>
|
||||
Sitemap
|
||||
</a>
|
||||
<a
|
||||
className={cn(
|
||||
buttonVariants({
|
||||
variant: "ghost",
|
||||
}),
|
||||
"justify-start text-muted-foreground",
|
||||
)}
|
||||
href="#"
|
||||
>
|
||||
Legal
|
||||
</a>
|
||||
<a
|
||||
className={cn(
|
||||
buttonVariants({
|
||||
variant: "ghost",
|
||||
}),
|
||||
"justify-start text-muted-foreground",
|
||||
)}
|
||||
href="#"
|
||||
>
|
||||
Cookie Settings
|
||||
</a>
|
||||
</div>
|
||||
<div className="mt-2 flex flex-col gap-3">
|
||||
<Button variant="outline">
|
||||
Log in
|
||||
</Button>
|
||||
<Button>Sign up</Button>
|
||||
</div>
|
||||
</div>
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Navbar;
|
||||
57
latosa-frontend/components/ui/accordion.tsx
Normal file
57
latosa-frontend/components/ui/accordion.tsx
Normal file
@@ -0,0 +1,57 @@
|
||||
"use client";
|
||||
|
||||
import * as React from "react";
|
||||
import * as AccordionPrimitive from "@radix-ui/react-accordion";
|
||||
import { ChevronDown } from "lucide-react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const Accordion = AccordionPrimitive.Root;
|
||||
|
||||
const AccordionItem = React.forwardRef<
|
||||
React.ComponentRef<typeof AccordionPrimitive.Item>,
|
||||
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<AccordionPrimitive.Item
|
||||
ref={ref}
|
||||
className={cn("border-b", className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
AccordionItem.displayName = "AccordionItem";
|
||||
|
||||
const AccordionTrigger = React.forwardRef<
|
||||
React.ComponentRef<typeof AccordionPrimitive.Trigger>,
|
||||
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>
|
||||
>(({ className, children, ...props }, ref) => (
|
||||
<AccordionPrimitive.Header className="flex">
|
||||
<AccordionPrimitive.Trigger
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"flex flex-1 items-center justify-between py-4 text-sm font-medium transition-all hover:underline text-left [&[data-state=open]>svg]:rotate-180",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
<ChevronDown className="h-4 w-4 shrink-0 text-muted-foreground transition-transform duration-200" />
|
||||
</AccordionPrimitive.Trigger>
|
||||
</AccordionPrimitive.Header>
|
||||
));
|
||||
AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName;
|
||||
|
||||
const AccordionContent = React.forwardRef<
|
||||
React.ComponentRef<typeof AccordionPrimitive.Content>,
|
||||
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>
|
||||
>(({ className, children, ...props }, ref) => (
|
||||
<AccordionPrimitive.Content
|
||||
ref={ref}
|
||||
className="overflow-hidden text-sm data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down"
|
||||
{...props}
|
||||
>
|
||||
<div className={cn("pb-4 pt-0", className)}>{children}</div>
|
||||
</AccordionPrimitive.Content>
|
||||
));
|
||||
AccordionContent.displayName = AccordionPrimitive.Content.displayName;
|
||||
|
||||
export { Accordion, AccordionItem, AccordionTrigger, AccordionContent };
|
||||
36
latosa-frontend/components/ui/badge.tsx
Normal file
36
latosa-frontend/components/ui/badge.tsx
Normal file
@@ -0,0 +1,36 @@
|
||||
import * as React from "react";
|
||||
import { cva, type VariantProps } from "class-variance-authority";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const badgeVariants = cva(
|
||||
"inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
default:
|
||||
"border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80",
|
||||
secondary:
|
||||
"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
||||
destructive:
|
||||
"border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80",
|
||||
outline: "text-foreground",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: "default",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
export interface BadgeProps
|
||||
extends React.HTMLAttributes<HTMLDivElement>,
|
||||
VariantProps<typeof badgeVariants> {}
|
||||
|
||||
function Badge({ className, variant, ...props }: BadgeProps) {
|
||||
return (
|
||||
<div className={cn(badgeVariants({ variant }), className)} {...props} />
|
||||
);
|
||||
}
|
||||
|
||||
export { Badge, badgeVariants };
|
||||
128
latosa-frontend/components/ui/navigation-menu.tsx
Normal file
128
latosa-frontend/components/ui/navigation-menu.tsx
Normal file
@@ -0,0 +1,128 @@
|
||||
import * as React from "react";
|
||||
import * as NavigationMenuPrimitive from "@radix-ui/react-navigation-menu";
|
||||
import { cva } from "class-variance-authority";
|
||||
import { ChevronDown } from "lucide-react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const NavigationMenu = React.forwardRef<
|
||||
React.ComponentRef<typeof NavigationMenuPrimitive.Root>,
|
||||
React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Root>
|
||||
>(({ className, children, ...props }, ref) => (
|
||||
<NavigationMenuPrimitive.Root
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative z-10 flex max-w-max flex-1 items-center justify-center",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
<NavigationMenuViewport />
|
||||
</NavigationMenuPrimitive.Root>
|
||||
));
|
||||
NavigationMenu.displayName = NavigationMenuPrimitive.Root.displayName;
|
||||
|
||||
const NavigationMenuList = React.forwardRef<
|
||||
React.ComponentRef<typeof NavigationMenuPrimitive.List>,
|
||||
React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.List>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<NavigationMenuPrimitive.List
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"group flex flex-1 list-none items-center justify-center space-x-1",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName;
|
||||
|
||||
const NavigationMenuItem = NavigationMenuPrimitive.Item;
|
||||
|
||||
const navigationMenuTriggerStyle = cva(
|
||||
"group inline-flex h-9 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.ComponentRef<typeof NavigationMenuPrimitive.Trigger>,
|
||||
React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Trigger>
|
||||
>(({ className, children, ...props }, ref) => (
|
||||
<NavigationMenuPrimitive.Trigger
|
||||
ref={ref}
|
||||
className={cn(navigationMenuTriggerStyle(), "group", className)}
|
||||
{...props}
|
||||
>
|
||||
{children}{" "}
|
||||
<ChevronDown
|
||||
className="relative top-[1px] ml-1 h-3 w-3 transition duration-300 group-data-[state=open]:rotate-180"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</NavigationMenuPrimitive.Trigger>
|
||||
));
|
||||
NavigationMenuTrigger.displayName = NavigationMenuPrimitive.Trigger.displayName;
|
||||
|
||||
const NavigationMenuContent = React.forwardRef<
|
||||
React.ComponentRef<typeof NavigationMenuPrimitive.Content>,
|
||||
React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Content>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<NavigationMenuPrimitive.Content
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"left-0 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,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
NavigationMenuContent.displayName = NavigationMenuPrimitive.Content.displayName;
|
||||
|
||||
const NavigationMenuLink = NavigationMenuPrimitive.Link;
|
||||
|
||||
const NavigationMenuViewport = React.forwardRef<
|
||||
React.ComponentRef<typeof NavigationMenuPrimitive.Viewport>,
|
||||
React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Viewport>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<div className={cn("absolute left-0 top-full flex justify-center")}>
|
||||
<NavigationMenuPrimitive.Viewport
|
||||
className={cn(
|
||||
"origin-top-center relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border bg-popover text-popover-foreground shadow 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,
|
||||
)}
|
||||
ref={ref}
|
||||
{...props}
|
||||
/>
|
||||
</div>
|
||||
));
|
||||
NavigationMenuViewport.displayName =
|
||||
NavigationMenuPrimitive.Viewport.displayName;
|
||||
|
||||
const NavigationMenuIndicator = React.forwardRef<
|
||||
React.ComponentRef<typeof NavigationMenuPrimitive.Indicator>,
|
||||
React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Indicator>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<NavigationMenuPrimitive.Indicator
|
||||
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,
|
||||
)}
|
||||
{...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;
|
||||
|
||||
export {
|
||||
navigationMenuTriggerStyle,
|
||||
NavigationMenu,
|
||||
NavigationMenuList,
|
||||
NavigationMenuItem,
|
||||
NavigationMenuContent,
|
||||
NavigationMenuTrigger,
|
||||
NavigationMenuLink,
|
||||
NavigationMenuIndicator,
|
||||
NavigationMenuViewport,
|
||||
};
|
||||
@@ -33,7 +33,7 @@ const SelectTrigger = React.forwardRef<
|
||||
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
|
||||
|
||||
const SelectScrollUpButton = React.forwardRef<
|
||||
React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
|
||||
React.ComponentRef<typeof SelectPrimitive.ScrollUpButton>,
|
||||
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<SelectPrimitive.ScrollUpButton
|
||||
@@ -50,7 +50,7 @@ const SelectScrollUpButton = React.forwardRef<
|
||||
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
|
||||
|
||||
const SelectScrollDownButton = React.forwardRef<
|
||||
React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
|
||||
React.ComponentRef<typeof SelectPrimitive.ScrollDownButton>,
|
||||
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<SelectPrimitive.ScrollDownButton
|
||||
@@ -68,7 +68,7 @@ SelectScrollDownButton.displayName =
|
||||
SelectPrimitive.ScrollDownButton.displayName;
|
||||
|
||||
const SelectContent = React.forwardRef<
|
||||
React.ElementRef<typeof SelectPrimitive.Content>,
|
||||
React.ComponentRef<typeof SelectPrimitive.Content>,
|
||||
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
|
||||
>(({ className, children, position = "popper", ...props }, ref) => (
|
||||
<SelectPrimitive.Portal>
|
||||
@@ -100,7 +100,7 @@ const SelectContent = React.forwardRef<
|
||||
SelectContent.displayName = SelectPrimitive.Content.displayName;
|
||||
|
||||
const SelectLabel = React.forwardRef<
|
||||
React.ElementRef<typeof SelectPrimitive.Label>,
|
||||
React.ComponentRef<typeof SelectPrimitive.Label>,
|
||||
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<SelectPrimitive.Label
|
||||
@@ -112,7 +112,7 @@ const SelectLabel = React.forwardRef<
|
||||
SelectLabel.displayName = SelectPrimitive.Label.displayName;
|
||||
|
||||
const SelectItem = React.forwardRef<
|
||||
React.ElementRef<typeof SelectPrimitive.Item>,
|
||||
React.ComponentRef<typeof SelectPrimitive.Item>,
|
||||
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
|
||||
>(({ className, children, ...props }, ref) => (
|
||||
<SelectPrimitive.Item
|
||||
@@ -134,7 +134,7 @@ const SelectItem = React.forwardRef<
|
||||
SelectItem.displayName = SelectPrimitive.Item.displayName;
|
||||
|
||||
const SelectSeparator = React.forwardRef<
|
||||
React.ElementRef<typeof SelectPrimitive.Separator>,
|
||||
React.ComponentRef<typeof SelectPrimitive.Separator>,
|
||||
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<SelectPrimitive.Separator
|
||||
|
||||
138
latosa-frontend/components/ui/sheet.tsx
Normal file
138
latosa-frontend/components/ui/sheet.tsx
Normal file
@@ -0,0 +1,138 @@
|
||||
"use client";
|
||||
|
||||
import * as React from "react";
|
||||
import * as SheetPrimitive from "@radix-ui/react-dialog";
|
||||
import { cva, type VariantProps } from "class-variance-authority";
|
||||
import { X } from "lucide-react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const Sheet = SheetPrimitive.Root;
|
||||
|
||||
const SheetTrigger = SheetPrimitive.Trigger;
|
||||
|
||||
const SheetClose = SheetPrimitive.Close;
|
||||
|
||||
const SheetPortal = SheetPrimitive.Portal;
|
||||
|
||||
const SheetOverlay = React.forwardRef<
|
||||
React.ComponentRef<typeof SheetPrimitive.Overlay>,
|
||||
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<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,
|
||||
)}
|
||||
{...props}
|
||||
ref={ref}
|
||||
/>
|
||||
));
|
||||
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName;
|
||||
|
||||
const sheetVariants = cva(
|
||||
"fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500 data-[state=open]:animate-in data-[state=closed]:animate-out",
|
||||
{
|
||||
variants: {
|
||||
side: {
|
||||
top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
|
||||
bottom: "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
|
||||
left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
|
||||
right: "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
side: "right",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
interface SheetContentProps
|
||||
extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
|
||||
VariantProps<typeof sheetVariants> {}
|
||||
|
||||
const SheetContent = React.forwardRef<
|
||||
React.ComponentRef<typeof SheetPrimitive.Content>,
|
||||
SheetContentProps
|
||||
>(({ side = "right", className, children, ...props }, ref) => (
|
||||
<SheetPortal>
|
||||
<SheetOverlay />
|
||||
<SheetPrimitive.Content
|
||||
ref={ref}
|
||||
className={cn(sheetVariants({ side }), className)}
|
||||
{...props}
|
||||
>
|
||||
<SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary">
|
||||
<X className="h-4 w-4" />
|
||||
<span className="sr-only">Close</span>
|
||||
</SheetPrimitive.Close>
|
||||
{children}
|
||||
</SheetPrimitive.Content>
|
||||
</SheetPortal>
|
||||
));
|
||||
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>) => (
|
||||
<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.ComponentRef<typeof SheetPrimitive.Title>,
|
||||
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<SheetPrimitive.Title
|
||||
ref={ref}
|
||||
className={cn("text-lg font-semibold text-foreground", className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
SheetTitle.displayName = SheetPrimitive.Title.displayName;
|
||||
|
||||
const SheetDescription = React.forwardRef<
|
||||
React.ComponentRef<typeof SheetPrimitive.Description>,
|
||||
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<SheetPrimitive.Description
|
||||
ref={ref}
|
||||
className={cn("text-sm text-muted-foreground", className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
SheetDescription.displayName = SheetPrimitive.Description.displayName;
|
||||
|
||||
export {
|
||||
Sheet,
|
||||
SheetPortal,
|
||||
SheetOverlay,
|
||||
SheetTrigger,
|
||||
SheetClose,
|
||||
SheetContent,
|
||||
SheetHeader,
|
||||
SheetFooter,
|
||||
SheetTitle,
|
||||
SheetDescription,
|
||||
};
|
||||
160
latosa-frontend/package-lock.json
generated
160
latosa-frontend/package-lock.json
generated
@@ -8,7 +8,10 @@
|
||||
"name": "latosa-frontend",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-accordion": "^1.2.2",
|
||||
"@radix-ui/react-dialog": "^1.1.4",
|
||||
"@radix-ui/react-label": "^2.1.1",
|
||||
"@radix-ui/react-navigation-menu": "^1.2.3",
|
||||
"@radix-ui/react-select": "^2.1.4",
|
||||
"@radix-ui/react-slot": "^1.1.1",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
@@ -923,6 +926,37 @@
|
||||
"integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@radix-ui/react-accordion": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.2.tgz",
|
||||
"integrity": "sha512-b1oh54x4DMCdGsB4/7ahiSrViXxaBwRPotiZNnYXjLha9vfuURSAZErki6qjDoSIV0eXx5v57XnTGVtGwnfp2g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/primitive": "1.1.1",
|
||||
"@radix-ui/react-collapsible": "1.1.2",
|
||||
"@radix-ui/react-collection": "1.1.1",
|
||||
"@radix-ui/react-compose-refs": "1.1.1",
|
||||
"@radix-ui/react-context": "1.1.1",
|
||||
"@radix-ui/react-direction": "1.1.0",
|
||||
"@radix-ui/react-id": "1.1.0",
|
||||
"@radix-ui/react-primitive": "2.0.1",
|
||||
"@radix-ui/react-use-controllable-state": "1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-arrow": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.1.tgz",
|
||||
@@ -946,6 +980,36 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-collapsible": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.2.tgz",
|
||||
"integrity": "sha512-PliMB63vxz7vggcyq0IxNYk8vGDrLXVWw4+W4B8YnwI1s18x7YZYqlG9PLX7XxAJUi0g2DxP4XKJMFHh/iVh9A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/primitive": "1.1.1",
|
||||
"@radix-ui/react-compose-refs": "1.1.1",
|
||||
"@radix-ui/react-context": "1.1.1",
|
||||
"@radix-ui/react-id": "1.1.0",
|
||||
"@radix-ui/react-presence": "1.1.2",
|
||||
"@radix-ui/react-primitive": "2.0.1",
|
||||
"@radix-ui/react-use-controllable-state": "1.1.0",
|
||||
"@radix-ui/react-use-layout-effect": "1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-collection": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.1.tgz",
|
||||
@@ -1002,6 +1066,42 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-dialog": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.4.tgz",
|
||||
"integrity": "sha512-Ur7EV1IwQGCyaAuyDRiOLA5JIUZxELJljF+MbM/2NC0BYwfuRrbpS30BiQBJrVruscgUkieKkqXYDOoByaxIoA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/primitive": "1.1.1",
|
||||
"@radix-ui/react-compose-refs": "1.1.1",
|
||||
"@radix-ui/react-context": "1.1.1",
|
||||
"@radix-ui/react-dismissable-layer": "1.1.3",
|
||||
"@radix-ui/react-focus-guards": "1.1.1",
|
||||
"@radix-ui/react-focus-scope": "1.1.1",
|
||||
"@radix-ui/react-id": "1.1.0",
|
||||
"@radix-ui/react-portal": "1.1.3",
|
||||
"@radix-ui/react-presence": "1.1.2",
|
||||
"@radix-ui/react-primitive": "2.0.1",
|
||||
"@radix-ui/react-slot": "1.1.1",
|
||||
"@radix-ui/react-use-controllable-state": "1.1.0",
|
||||
"aria-hidden": "^1.1.1",
|
||||
"react-remove-scroll": "^2.6.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-direction": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz",
|
||||
@@ -1125,6 +1225,42 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-navigation-menu": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.2.3.tgz",
|
||||
"integrity": "sha512-IQWAsQ7dsLIYDrn0WqPU+cdM7MONTv9nqrLVYoie3BPiabSfUVDe6Fr+oEt0Cofsr9ONDcDe9xhmJbL1Uq1yKg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/primitive": "1.1.1",
|
||||
"@radix-ui/react-collection": "1.1.1",
|
||||
"@radix-ui/react-compose-refs": "1.1.1",
|
||||
"@radix-ui/react-context": "1.1.1",
|
||||
"@radix-ui/react-direction": "1.1.0",
|
||||
"@radix-ui/react-dismissable-layer": "1.1.3",
|
||||
"@radix-ui/react-id": "1.1.0",
|
||||
"@radix-ui/react-presence": "1.1.2",
|
||||
"@radix-ui/react-primitive": "2.0.1",
|
||||
"@radix-ui/react-use-callback-ref": "1.1.0",
|
||||
"@radix-ui/react-use-controllable-state": "1.1.0",
|
||||
"@radix-ui/react-use-layout-effect": "1.1.0",
|
||||
"@radix-ui/react-use-previous": "1.1.0",
|
||||
"@radix-ui/react-visually-hidden": "1.1.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-popper": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.1.tgz",
|
||||
@@ -1181,6 +1317,30 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-presence": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.2.tgz",
|
||||
"integrity": "sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-compose-refs": "1.1.1",
|
||||
"@radix-ui/react-use-layout-effect": "1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-primitive": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.1.tgz",
|
||||
|
||||
@@ -9,7 +9,10 @@
|
||||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@radix-ui/react-accordion": "^1.2.2",
|
||||
"@radix-ui/react-dialog": "^1.1.4",
|
||||
"@radix-ui/react-label": "^2.1.1",
|
||||
"@radix-ui/react-navigation-menu": "^1.2.3",
|
||||
"@radix-ui/react-select": "^2.1.4",
|
||||
"@radix-ui/react-slot": "^1.1.1",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
|
||||
@@ -56,6 +56,28 @@ export default {
|
||||
md: "calc(var(--radius) - 2px)",
|
||||
sm: "calc(var(--radius) - 4px)",
|
||||
},
|
||||
keyframes: {
|
||||
"accordion-down": {
|
||||
from: {
|
||||
height: "0",
|
||||
},
|
||||
to: {
|
||||
height: "var(--radix-accordion-content-height)",
|
||||
},
|
||||
},
|
||||
"accordion-up": {
|
||||
from: {
|
||||
height: "var(--radix-accordion-content-height)",
|
||||
},
|
||||
to: {
|
||||
height: "0",
|
||||
},
|
||||
},
|
||||
},
|
||||
animation: {
|
||||
"accordion-down": "accordion-down 0.2s ease-out",
|
||||
"accordion-up": "accordion-up 0.2s ease-out",
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [require("tailwindcss-animate")],
|
||||
|
||||
Reference in New Issue
Block a user