feat: add layout and sidebar components with navigation structure
chore: update dependencies and configuration for Tailwind CSS docs: create components.json and skills-lock.json for project structure
This commit is contained in:
21
frontend/components.json
Normal file
21
frontend/components.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema.json",
|
||||
"style": "default",
|
||||
"rsc": false,
|
||||
"tsx": true,
|
||||
"tailwind": {
|
||||
"config": "tailwind.config.ts",
|
||||
"css": "src/styles/globals.css",
|
||||
"baseColor": "slate",
|
||||
"cssVariables": true,
|
||||
"prefix": ""
|
||||
},
|
||||
"aliases": {
|
||||
"components": "@/components",
|
||||
"utils": "@/lib/utils",
|
||||
"ui": "@/components/ui",
|
||||
"lib": "@/lib",
|
||||
"hooks": "@/hooks"
|
||||
},
|
||||
"iconLibrary": "lucide"
|
||||
}
|
||||
@@ -10,14 +10,18 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@radix-ui/react-avatar": "^1.1.11",
|
||||
"@radix-ui/react-checkbox": "^1.3.3",
|
||||
"@radix-ui/react-collapsible": "^1.1.12",
|
||||
"@radix-ui/react-dialog": "^1.1.15",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
||||
"@radix-ui/react-label": "^2.1.8",
|
||||
"@radix-ui/react-scroll-area": "^1.2.10",
|
||||
"@radix-ui/react-select": "^2.2.6",
|
||||
"@radix-ui/react-separator": "^1.1.8",
|
||||
"@radix-ui/react-tabs": "^1.1.13",
|
||||
"@radix-ui/react-toast": "^1.2.15",
|
||||
"@radix-ui/react-tooltip": "^1.2.8",
|
||||
"@tanstack/react-form": "^1.28.3",
|
||||
"@tanstack/react-query": "^5.90.21",
|
||||
"@tanstack/react-router": "^1.162.2",
|
||||
@@ -32,6 +36,7 @@
|
||||
"@eslint/js": "^9.39.1",
|
||||
"@radix-ui/react-slot": "^1.2.4",
|
||||
"@tailwindcss/postcss": "^4.2.0",
|
||||
"@tailwindcss/vite": "^4.2.0",
|
||||
"@types/node": "^24.10.1",
|
||||
"@types/react": "^19.2.7",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
|
||||
10
frontend/skills-lock.json
Normal file
10
frontend/skills-lock.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"version": 1,
|
||||
"skills": {
|
||||
"shadcn-ui": {
|
||||
"source": "google-labs-code/stitch-skills",
|
||||
"sourceType": "github",
|
||||
"computedHash": "dadbca54d35a33fe73e40018611af2179689305bf6da812ab2643987fefd9da3"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,38 +1,14 @@
|
||||
import { useState } from 'react';
|
||||
import { Outlet } from '@tanstack/react-router';
|
||||
import { Header } from './Header';
|
||||
import { Sidebar } from './Sidebar';
|
||||
|
||||
interface LayoutProps {
|
||||
sidebarOpen?: boolean;
|
||||
onSidebarChange?: (open: boolean) => void;
|
||||
}
|
||||
|
||||
export function Layout({ sidebarOpen = false, onSidebarChange }: LayoutProps) {
|
||||
const [isSidebarOpen, setIsSidebarOpen] = useState(sidebarOpen);
|
||||
|
||||
const handleSidebarToggle = (open: boolean) => {
|
||||
setIsSidebarOpen(open);
|
||||
onSidebarChange?.(open);
|
||||
};
|
||||
import { AppSidebar } from './Sidebar';
|
||||
|
||||
export function Layout() {
|
||||
return (
|
||||
<div className="min-h-screen bg-background">
|
||||
{/* Sidebar */}
|
||||
<Sidebar isOpen={isSidebarOpen} onClose={() => handleSidebarToggle(false)} />
|
||||
|
||||
{/* Contenido principal */}
|
||||
<div className="md:pl-64">
|
||||
{/* Header */}
|
||||
<Header onMenuToggle={() => handleSidebarToggle(true)} />
|
||||
|
||||
{/* Main content */}
|
||||
<main className="container mx-auto p-6">
|
||||
<AppSidebar>
|
||||
<main className="flex-1 p-6">
|
||||
<div className="space-y-6">
|
||||
<Outlet />
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</AppSidebar>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,119 +1,309 @@
|
||||
import { Link, useLocation } from '@tanstack/react-router';
|
||||
import { Home, Gamepad2, FileText, Settings, Database, Tag, Download, Upload } from 'lucide-react';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { ScrollArea } from '@/components/ui/scroll-area';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
'use client';
|
||||
|
||||
interface SidebarProps {
|
||||
isOpen?: boolean;
|
||||
onClose?: () => void;
|
||||
import * as React from 'react';
|
||||
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
|
||||
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible';
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuLabel,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuTrigger,
|
||||
} from '@/components/ui/dropdown-menu';
|
||||
import {
|
||||
Sidebar,
|
||||
SidebarContent,
|
||||
SidebarFooter,
|
||||
SidebarGroup,
|
||||
SidebarGroupLabel,
|
||||
SidebarHeader,
|
||||
SidebarInset,
|
||||
SidebarMenu,
|
||||
SidebarMenuButton,
|
||||
SidebarMenuItem,
|
||||
SidebarMenuSub,
|
||||
SidebarMenuSubButton,
|
||||
SidebarMenuSubItem,
|
||||
SidebarProvider,
|
||||
SidebarRail,
|
||||
SidebarTrigger,
|
||||
useSidebar,
|
||||
} from '@/components/ui/sidebar';
|
||||
import {
|
||||
Gamepad2,
|
||||
Home,
|
||||
Settings,
|
||||
User,
|
||||
Database,
|
||||
Star,
|
||||
TrendingUp,
|
||||
ChevronRight,
|
||||
ChevronsUpDown,
|
||||
} from 'lucide-react';
|
||||
|
||||
const data = {
|
||||
user: {
|
||||
name: 'Game Library',
|
||||
email: 'admin@gamelibrary.com',
|
||||
avatar: '/avatars/default.jpg',
|
||||
},
|
||||
teams: [
|
||||
{
|
||||
name: 'Personal',
|
||||
logo: Gamepad2,
|
||||
plan: 'Standard',
|
||||
},
|
||||
{
|
||||
name: 'Work',
|
||||
logo: Database,
|
||||
plan: 'Professional',
|
||||
},
|
||||
],
|
||||
navMain: [
|
||||
{
|
||||
title: 'Dashboard',
|
||||
url: '/',
|
||||
icon: Home,
|
||||
isActive: true,
|
||||
},
|
||||
{
|
||||
title: 'Games',
|
||||
url: '/games',
|
||||
icon: Gamepad2,
|
||||
items: [
|
||||
{
|
||||
title: 'All Games',
|
||||
url: '/games',
|
||||
},
|
||||
{
|
||||
title: 'Favorites',
|
||||
url: '/games/favorites',
|
||||
},
|
||||
{
|
||||
title: 'Recently Played',
|
||||
url: '/games/recent',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Collections',
|
||||
url: '/collections',
|
||||
icon: Star,
|
||||
items: [
|
||||
{
|
||||
title: 'My Collections',
|
||||
url: '/collections',
|
||||
},
|
||||
{
|
||||
title: 'Shared Collections',
|
||||
url: '/collections/shared',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Statistics',
|
||||
url: '/stats',
|
||||
icon: TrendingUp,
|
||||
},
|
||||
{
|
||||
title: 'Settings',
|
||||
url: '/settings',
|
||||
icon: Settings,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
function TeamSwitcher({
|
||||
teams,
|
||||
}: {
|
||||
teams: {
|
||||
name: string;
|
||||
logo: React.ElementType;
|
||||
plan: string;
|
||||
}[];
|
||||
}) {
|
||||
const { isMobile } = useSidebar();
|
||||
const [activeTeam, setActiveTeam] = React.useState(teams[0]);
|
||||
|
||||
if (!activeTeam) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const navigation = [
|
||||
{ name: 'Dashboard', href: '/', icon: Home, count: null },
|
||||
{ name: 'Juegos', href: '/games', icon: Gamepad2, count: null },
|
||||
{
|
||||
name: 'Plataformas',
|
||||
href: '/platforms',
|
||||
icon: Database,
|
||||
count: null,
|
||||
},
|
||||
{
|
||||
name: 'Etiquetas',
|
||||
href: '/tags',
|
||||
icon: Tag,
|
||||
count: null,
|
||||
},
|
||||
{ name: 'Importar ROMs', href: '/import', icon: Download, count: null },
|
||||
{ name: 'Exportar', href: '/export', icon: Upload, count: null },
|
||||
{ name: 'Configuración', href: '/settings', icon: Settings, count: null },
|
||||
];
|
||||
return (
|
||||
<SidebarMenu>
|
||||
<SidebarMenuItem>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<SidebarMenuButton
|
||||
size="lg"
|
||||
className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
|
||||
>
|
||||
<div className="bg-sidebar-primary text-sidebar-primary-foreground flex aspect-square size-8 items-center justify-center rounded-lg">
|
||||
<activeTeam.logo className="size-4" />
|
||||
</div>
|
||||
<div className="grid flex-1 text-left text-sm leading-tight">
|
||||
<span className="truncate font-medium">{activeTeam.name}</span>
|
||||
<span className="truncate text-xs">{activeTeam.plan}</span>
|
||||
</div>
|
||||
<ChevronsUpDown className="ml-auto" />
|
||||
</SidebarMenuButton>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent
|
||||
className="w-(--radix-dropdown-menu-trigger-width) min-w-56 rounded-lg"
|
||||
align="start"
|
||||
side={isMobile ? 'bottom' : 'right'}
|
||||
sideOffset={4}
|
||||
>
|
||||
<DropdownMenuGroup>
|
||||
<DropdownMenuLabel className="text-muted-foreground text-xs">Teams</DropdownMenuLabel>
|
||||
{teams.map((team) => (
|
||||
<DropdownMenuItem
|
||||
key={team.name}
|
||||
onClick={() => setActiveTeam(team)}
|
||||
className="cursor-pointer"
|
||||
>
|
||||
<div className="bg-sidebar-primary text-sidebar-primary-foreground flex aspect-square size-8 items-center justify-center rounded-lg mr-2">
|
||||
<team.logo className="size-4" />
|
||||
</div>
|
||||
<div className="grid flex-1 text-left text-sm leading-tight">
|
||||
<span className="truncate font-medium">{team.name}</span>
|
||||
<span className="truncate text-xs">{team.plan}</span>
|
||||
</div>
|
||||
</DropdownMenuItem>
|
||||
))}
|
||||
</DropdownMenuGroup>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</SidebarMenuItem>
|
||||
</SidebarMenu>
|
||||
);
|
||||
}
|
||||
|
||||
export function Sidebar({ isOpen, onClose }: SidebarProps) {
|
||||
const location = useLocation();
|
||||
function NavMain({
|
||||
items,
|
||||
}: {
|
||||
items: {
|
||||
title: string;
|
||||
url: string;
|
||||
icon?: React.ElementType;
|
||||
isActive?: boolean;
|
||||
items?: {
|
||||
title: string;
|
||||
url: string;
|
||||
}[];
|
||||
}[];
|
||||
}) {
|
||||
return (
|
||||
<SidebarGroup>
|
||||
<SidebarGroupLabel>Main Navigation</SidebarGroupLabel>
|
||||
<SidebarMenu>
|
||||
{items.map((item) => (
|
||||
<Collapsible key={item.title} defaultOpen={item.isActive} className="group/collapsible">
|
||||
<SidebarMenuItem>
|
||||
<CollapsibleTrigger render={<SidebarMenuButton tooltip={item.title} />}>
|
||||
{item.icon && <item.icon />}
|
||||
<span>{item.title}</span>
|
||||
<ChevronRight className="ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90" />
|
||||
</CollapsibleTrigger>
|
||||
<CollapsibleContent>
|
||||
<SidebarMenuSub>
|
||||
{item.items?.map((subItem) => (
|
||||
<SidebarMenuSubItem key={subItem.title}>
|
||||
<SidebarMenuSubButton render={<a href={subItem.url} />}>
|
||||
<span>{subItem.title}</span>
|
||||
</SidebarMenuSubButton>
|
||||
</SidebarMenuSubItem>
|
||||
))}
|
||||
</SidebarMenuSub>
|
||||
</CollapsibleContent>
|
||||
</SidebarMenuItem>
|
||||
</Collapsible>
|
||||
))}
|
||||
</SidebarMenu>
|
||||
</SidebarGroup>
|
||||
);
|
||||
}
|
||||
|
||||
function NavUser({ user }: { user: { name: string; email: string; avatar: string } }) {
|
||||
const { isMobile } = useSidebar();
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Overlay para móviles */}
|
||||
{isOpen && <div className="fixed inset-0 z-40 bg-black/50 md:hidden" onClick={onClose} />}
|
||||
|
||||
{/* Sidebar */}
|
||||
<div
|
||||
className={cn(
|
||||
'fixed left-0 top-0 z-50 h-full w-64 transform border-r bg-background transition-transform duration-300 ease-in-out md:relative md:translate-x-0',
|
||||
isOpen ? 'translate-x-0' : '-translate-x-full md:translate-x-0'
|
||||
)}
|
||||
<SidebarMenu>
|
||||
<SidebarMenuItem>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<SidebarMenuButton
|
||||
size="lg"
|
||||
className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
|
||||
>
|
||||
<div className="flex h-full flex-col">
|
||||
{/* Header del sidebar */}
|
||||
<div className="flex h-14 items-center border-b px-4">
|
||||
<div className="flex items-center space-x-2">
|
||||
<Avatar className="h-8 w-8 rounded-full">
|
||||
<AvatarImage src={user.avatar} alt={user.name} />
|
||||
<AvatarFallback>{user.name.charAt(0)}</AvatarFallback>
|
||||
</Avatar>
|
||||
<div className="grid flex-1 text-left text-sm leading-tight">
|
||||
<span className="truncate font-medium">{user.name}</span>
|
||||
<span className="truncate text-xs text-muted-foreground">{user.email}</span>
|
||||
</div>
|
||||
<ChevronsUpDown className="ml-auto size-4" />
|
||||
</SidebarMenuButton>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent
|
||||
className="w-(--radix-dropdown-menu-trigger-width) min-w-56 rounded-lg"
|
||||
align="start"
|
||||
side={isMobile ? 'bottom' : 'right'}
|
||||
sideOffset={4}
|
||||
>
|
||||
<DropdownMenuLabel className="text-muted-foreground text-xs">
|
||||
Logged in as
|
||||
</DropdownMenuLabel>
|
||||
<DropdownMenuGroup>
|
||||
<DropdownMenuItem>
|
||||
<User className="mr-2 h-4 w-4" />
|
||||
<span>Profile</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem>
|
||||
<Settings className="mr-2 h-4 w-4" />
|
||||
<span>Settings</span>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuGroup>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem>
|
||||
<span>Log out</span>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</SidebarMenuItem>
|
||||
</SidebarMenu>
|
||||
);
|
||||
}
|
||||
|
||||
export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
|
||||
return (
|
||||
<SidebarProvider>
|
||||
<Sidebar collapsible="icon" {...props}>
|
||||
<SidebarHeader>
|
||||
<TeamSwitcher teams={data.teams} />
|
||||
</SidebarHeader>
|
||||
<SidebarContent>
|
||||
<NavMain items={data.navMain} />
|
||||
</SidebarContent>
|
||||
<SidebarFooter>
|
||||
<NavUser user={data.user} />
|
||||
</SidebarFooter>
|
||||
<SidebarRail />
|
||||
</Sidebar>
|
||||
<SidebarInset>
|
||||
<header className="flex h-16 shrink-0 items-center gap-2 border-b bg-background px-4 transition-[width,height] ease-linear group-has-[collapsible=icon]/sidebar-wrapper:h-12">
|
||||
<div className="flex items-center gap-2">
|
||||
<SidebarTrigger className="-ml-1" />
|
||||
<div className="flex items-center gap-2">
|
||||
<Gamepad2 className="h-6 w-6" />
|
||||
<span className="font-bold">Quasar</span>
|
||||
</div>
|
||||
<Button variant="ghost" size="sm" className="ml-auto md:hidden" onClick={onClose}>
|
||||
✕
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{/* Contenido del sidebar */}
|
||||
<ScrollArea className="flex-1">
|
||||
<nav className="p-4 space-y-1">
|
||||
{navigation.map((item) => {
|
||||
const Icon = item.icon;
|
||||
const isActive = location.pathname === item.href;
|
||||
|
||||
return (
|
||||
<Link
|
||||
key={item.name}
|
||||
to={item.href}
|
||||
onClick={onClose}
|
||||
className={cn(
|
||||
'flex items-center justify-between rounded-lg px-3 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground',
|
||||
isActive ? 'bg-accent text-accent-foreground' : 'text-muted-foreground'
|
||||
)}
|
||||
>
|
||||
<div className="flex items-center space-x-3">
|
||||
<Icon className="h-4 w-4" />
|
||||
<span>{item.name}</span>
|
||||
</div>
|
||||
{item.count !== null && (
|
||||
<Badge variant="secondary" className="text-xs">
|
||||
{item.count}
|
||||
</Badge>
|
||||
)}
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</nav>
|
||||
|
||||
{/* Sección adicional con información */}
|
||||
<div className="mt-8 p-4 border-t">
|
||||
<h3 className="text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-3">
|
||||
Información
|
||||
</h3>
|
||||
<div className="space-y-2 text-xs text-muted-foreground">
|
||||
<div className="flex justify-between">
|
||||
<span>Versión</span>
|
||||
<span>1.0.0</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span>Última actualización</span>
|
||||
<span>2024-01-15</span>
|
||||
<h1 className="text-lg font-semibold">Game Library</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ScrollArea>
|
||||
|
||||
{/* Footer del sidebar */}
|
||||
<div className="flex h-14 items-center border-t px-4">
|
||||
<div className="flex items-center space-x-2 text-xs text-muted-foreground">
|
||||
<span>© 2024 Quasar</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
</header>
|
||||
</SidebarInset>
|
||||
</SidebarProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@import "tailwindcss/preflight";
|
||||
@import "tailwindcss";
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
|
||||
@@ -38,6 +38,16 @@ const config: Config = {
|
||||
DEFAULT: 'hsl(var(--secondary))',
|
||||
foreground: 'hsl(var(--secondary-foreground))',
|
||||
},
|
||||
sidebar: {
|
||||
DEFAULT: 'hsl(var(--sidebar))',
|
||||
foreground: 'hsl(var(--sidebar-foreground))',
|
||||
primary: 'hsl(var(--sidebar-primary))',
|
||||
primaryForeground: 'hsl(var(--sidebar-primary-foreground))',
|
||||
accent: 'hsl(var(--sidebar-accent))',
|
||||
accentForeground: 'hsl(var(--sidebar-accent-foreground))',
|
||||
border: 'hsl(var(--sidebar-border))',
|
||||
ring: 'hsl(var(--sidebar-ring))',
|
||||
},
|
||||
},
|
||||
borderRadius: {
|
||||
lg: 'var(--radius)',
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { defineConfig } from 'vite';
|
||||
import react from '@vitejs/plugin-react';
|
||||
import tailwindcss from '@tailwindcss/vite';
|
||||
import path from 'path';
|
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
plugins: [react(), tailwindcss()],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.resolve(__dirname, './src'),
|
||||
|
||||
146
yarn.lock
146
yarn.lock
@@ -1395,6 +1395,29 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@radix-ui/react-avatar@npm:^1.1.11":
|
||||
version: 1.1.11
|
||||
resolution: "@radix-ui/react-avatar@npm:1.1.11"
|
||||
dependencies:
|
||||
"@radix-ui/react-context": "npm:1.1.3"
|
||||
"@radix-ui/react-primitive": "npm:2.1.4"
|
||||
"@radix-ui/react-use-callback-ref": "npm:1.1.1"
|
||||
"@radix-ui/react-use-is-hydrated": "npm:0.1.0"
|
||||
"@radix-ui/react-use-layout-effect": "npm: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
|
||||
checksum: 10c0/b1b3d4b11a8e05a8479d2410fb4e7b1bf825135c4cd42f7e5152568a54a55a3073bd87d50325150417a29306e7b1b371289dc3c4f11739af8a2a7bb8dd7c38c9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@radix-ui/react-checkbox@npm:^1.3.3":
|
||||
version: 1.3.3
|
||||
resolution: "@radix-ui/react-checkbox@npm:1.3.3"
|
||||
@@ -1421,6 +1444,32 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@radix-ui/react-collapsible@npm:^1.1.12":
|
||||
version: 1.1.12
|
||||
resolution: "@radix-ui/react-collapsible@npm:1.1.12"
|
||||
dependencies:
|
||||
"@radix-ui/primitive": "npm:1.1.3"
|
||||
"@radix-ui/react-compose-refs": "npm:1.1.2"
|
||||
"@radix-ui/react-context": "npm:1.1.2"
|
||||
"@radix-ui/react-id": "npm:1.1.1"
|
||||
"@radix-ui/react-presence": "npm:1.1.5"
|
||||
"@radix-ui/react-primitive": "npm:2.1.3"
|
||||
"@radix-ui/react-use-controllable-state": "npm:1.2.2"
|
||||
"@radix-ui/react-use-layout-effect": "npm: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
|
||||
checksum: 10c0/777cced73fbbec9cfafe6325aa5605e90f49d889af2778f4c4a6be101c07cacd69ae817d0b41cc27e3181f49392e2c06db7f32d6b084db047a51805ec70729b3
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@radix-ui/react-collection@npm:1.1.7":
|
||||
version: 1.1.7
|
||||
resolution: "@radix-ui/react-collection@npm:1.1.7"
|
||||
@@ -1469,6 +1518,19 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@radix-ui/react-context@npm:1.1.3":
|
||||
version: 1.1.3
|
||||
resolution: "@radix-ui/react-context@npm:1.1.3"
|
||||
peerDependencies:
|
||||
"@types/react": "*"
|
||||
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||
peerDependenciesMeta:
|
||||
"@types/react":
|
||||
optional: true
|
||||
checksum: 10c0/0f271b4100dbb007ad2675f2529453f07454f214b7ce796d72680bf2dff050d0719083ee6e8962919a74048ff853eff2e50de07d8f8c674d6be91bfa76204cc2
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@radix-ui/react-dialog@npm:^1.1.15":
|
||||
version: 1.1.15
|
||||
resolution: "@radix-ui/react-dialog@npm:1.1.15"
|
||||
@@ -1865,6 +1927,25 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@radix-ui/react-separator@npm:^1.1.8":
|
||||
version: 1.1.8
|
||||
resolution: "@radix-ui/react-separator@npm:1.1.8"
|
||||
dependencies:
|
||||
"@radix-ui/react-primitive": "npm:2.1.4"
|
||||
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
|
||||
checksum: 10c0/92e1353f696a22167c90f2c610b440be1fae3c05128287560914f124eef83d74c06ad25431923f3595032e6d89c23d479c95434390f4c0d9d4a68ec8d563ae0c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@radix-ui/react-slot@npm:1.2.3":
|
||||
version: 1.2.3
|
||||
resolution: "@radix-ui/react-slot@npm:1.2.3"
|
||||
@@ -1951,6 +2032,36 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@radix-ui/react-tooltip@npm:^1.2.8":
|
||||
version: 1.2.8
|
||||
resolution: "@radix-ui/react-tooltip@npm:1.2.8"
|
||||
dependencies:
|
||||
"@radix-ui/primitive": "npm:1.1.3"
|
||||
"@radix-ui/react-compose-refs": "npm:1.1.2"
|
||||
"@radix-ui/react-context": "npm:1.1.2"
|
||||
"@radix-ui/react-dismissable-layer": "npm:1.1.11"
|
||||
"@radix-ui/react-id": "npm:1.1.1"
|
||||
"@radix-ui/react-popper": "npm:1.2.8"
|
||||
"@radix-ui/react-portal": "npm:1.1.9"
|
||||
"@radix-ui/react-presence": "npm:1.1.5"
|
||||
"@radix-ui/react-primitive": "npm:2.1.3"
|
||||
"@radix-ui/react-slot": "npm:1.2.3"
|
||||
"@radix-ui/react-use-controllable-state": "npm:1.2.2"
|
||||
"@radix-ui/react-visually-hidden": "npm:1.2.3"
|
||||
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
|
||||
checksum: 10c0/de0cbae9c571a00671f160928d819e59502f59be8749f536ab4b180181d9d70aee3925a5b2555f8f32d0bea622bc35f65b70ca7ff0449e4844f891302310cc48
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@radix-ui/react-use-callback-ref@npm:1.1.1":
|
||||
version: 1.1.1
|
||||
resolution: "@radix-ui/react-use-callback-ref@npm:1.1.1"
|
||||
@@ -2010,6 +2121,21 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@radix-ui/react-use-is-hydrated@npm:0.1.0":
|
||||
version: 0.1.0
|
||||
resolution: "@radix-ui/react-use-is-hydrated@npm:0.1.0"
|
||||
dependencies:
|
||||
use-sync-external-store: "npm:^1.5.0"
|
||||
peerDependencies:
|
||||
"@types/react": "*"
|
||||
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||
peerDependenciesMeta:
|
||||
"@types/react":
|
||||
optional: true
|
||||
checksum: 10c0/635079bafe32829fc7405895154568ea94a22689b170489fd6d77668e4885e72ff71ed6d0ea3d602852841ef0f1927aa400fee2178d5dfbeb8bc9297da7d6498
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@radix-ui/react-use-layout-effect@npm:1.1.1":
|
||||
version: 1.1.1
|
||||
resolution: "@radix-ui/react-use-layout-effect@npm:1.1.1"
|
||||
@@ -2627,6 +2753,19 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@tailwindcss/vite@npm:^4.2.0":
|
||||
version: 4.2.0
|
||||
resolution: "@tailwindcss/vite@npm:4.2.0"
|
||||
dependencies:
|
||||
"@tailwindcss/node": "npm:4.2.0"
|
||||
"@tailwindcss/oxide": "npm:4.2.0"
|
||||
tailwindcss: "npm:4.2.0"
|
||||
peerDependencies:
|
||||
vite: ^5.2.0 || ^6 || ^7
|
||||
checksum: 10c0/4bd28ea2984907930a2ea4818581ce24bbb7276ffc4d316b32143eef2f2bf9f82bd2b937fe6bb78c9be96b61df5464d884b9c7b1e71f0eb3df2c4a890d34ff79
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@tanstack/devtools-event-client@npm:^0.4.0":
|
||||
version: 0.4.0
|
||||
resolution: "@tanstack/devtools-event-client@npm:0.4.0"
|
||||
@@ -5095,16 +5234,21 @@ __metadata:
|
||||
resolution: "frontend@workspace:frontend"
|
||||
dependencies:
|
||||
"@eslint/js": "npm:^9.39.1"
|
||||
"@radix-ui/react-avatar": "npm:^1.1.11"
|
||||
"@radix-ui/react-checkbox": "npm:^1.3.3"
|
||||
"@radix-ui/react-collapsible": "npm:^1.1.12"
|
||||
"@radix-ui/react-dialog": "npm:^1.1.15"
|
||||
"@radix-ui/react-dropdown-menu": "npm:^2.1.16"
|
||||
"@radix-ui/react-label": "npm:^2.1.8"
|
||||
"@radix-ui/react-scroll-area": "npm:^1.2.10"
|
||||
"@radix-ui/react-select": "npm:^2.2.6"
|
||||
"@radix-ui/react-separator": "npm:^1.1.8"
|
||||
"@radix-ui/react-slot": "npm:^1.2.4"
|
||||
"@radix-ui/react-tabs": "npm:^1.1.13"
|
||||
"@radix-ui/react-toast": "npm:^1.2.15"
|
||||
"@radix-ui/react-tooltip": "npm:^1.2.8"
|
||||
"@tailwindcss/postcss": "npm:^4.2.0"
|
||||
"@tailwindcss/vite": "npm:^4.2.0"
|
||||
"@tanstack/react-form": "npm:^1.28.3"
|
||||
"@tanstack/react-query": "npm:^5.90.21"
|
||||
"@tanstack/react-router": "npm:^1.162.2"
|
||||
@@ -7841,7 +7985,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"use-sync-external-store@npm:^1.6.0":
|
||||
"use-sync-external-store@npm:^1.5.0, use-sync-external-store@npm:^1.6.0":
|
||||
version: 1.6.0
|
||||
resolution: "use-sync-external-store@npm:1.6.0"
|
||||
peerDependencies:
|
||||
|
||||
Reference in New Issue
Block a user