refactor: migrate frontend from shadcn/Tailwind to Mantine v9

Reescribe todos los componentes UI para usar Mantine v9 en lugar de shadcn/Tailwind.
Elimina cn(), CVA, components.json, theme_provider custom y globals.css con Tailwind.
Añade 25+ componentes nuevos (AppShell, AuthForm, DatePickerInput, Dropzone, etc.)
y MantineProvider como wrapper estándar del sistema de temas.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-06 23:46:44 +02:00
parent 4b2bb6998a
commit 97a3c84625
163 changed files with 6008 additions and 6310 deletions
+34 -36
View File
@@ -1,28 +1,24 @@
import * as React from "react"
import { ChevronRightIcon, MoreHorizontalIcon } from "lucide-react"
import { cn } from "../core/cn"
import { Anchor, Text, Box } from "@mantine/core"
import { IconChevronRight, IconDots } from "@tabler/icons-react"
function Breadcrumb({ ...props }: React.ComponentPropsWithoutRef<"nav">) {
return <nav data-slot="breadcrumb" aria-label="breadcrumb" {...props} />
function Breadcrumb({ children, ...props }: React.ComponentPropsWithoutRef<"nav">) {
return <nav data-slot="breadcrumb" aria-label="breadcrumb" {...props}>{children}</nav>
}
function BreadcrumbList({ className, ...props }: React.ComponentPropsWithoutRef<"ol">) {
function BreadcrumbList({ className, children, ...props }: React.ComponentPropsWithoutRef<"ol">) {
return (
<ol
data-slot="breadcrumb-list"
className={cn("flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5", className)}
{...props}
/>
<ol data-slot="breadcrumb-list" style={{ listStyle: "none", display: "flex", flexWrap: "wrap", alignItems: "center", gap: 8, padding: 0, margin: 0 }} className={className} {...props}>
{children}
</ol>
)
}
function BreadcrumbItem({ className, ...props }: React.ComponentPropsWithoutRef<"li">) {
function BreadcrumbItem({ className, children, ...props }: React.ComponentPropsWithoutRef<"li">) {
return (
<li
data-slot="breadcrumb-item"
className={cn("inline-flex items-center gap-1.5", className)}
{...props}
/>
<li data-slot="breadcrumb-item" style={{ display: "flex", alignItems: "center", gap: 8 }} className={className} {...props}>
{children}
</li>
)
}
@@ -35,31 +31,29 @@ function BreadcrumbLink({
}: React.ComponentPropsWithoutRef<"a"> & { asChild?: boolean }) {
if (asChild) {
return (
<span data-slot="breadcrumb-link" className={cn("transition-colors hover:text-foreground", className)} {...(props as React.ComponentPropsWithoutRef<"span">)}>
<Text data-slot="breadcrumb-link" component="span" size="sm" className={className} {...(props as React.ComponentPropsWithoutRef<"span">)}>
{children}
</span>
</Text>
)
}
return (
<a
data-slot="breadcrumb-link"
href={href}
className={cn("transition-colors hover:text-foreground", className)}
{...props}
>
<Anchor data-slot="breadcrumb-link" href={href} size="sm" className={className} {...props}>
{children}
</a>
</Anchor>
)
}
function BreadcrumbPage({ className, ...props }: React.ComponentPropsWithoutRef<"span">) {
return (
<span
<Text
data-slot="breadcrumb-page"
component="span"
size="sm"
fw={500}
role="link"
aria-current="page"
aria-disabled="true"
className={cn("font-medium text-foreground", className)}
className={className}
{...props}
/>
)
@@ -67,30 +61,34 @@ function BreadcrumbPage({ className, ...props }: React.ComponentPropsWithoutRef<
function BreadcrumbSeparator({ children, className, ...props }: React.ComponentProps<"li">) {
return (
<li
<Box
data-slot="breadcrumb-separator"
component="li"
role="presentation"
aria-hidden="true"
className={cn("[&>svg]:size-3.5", className)}
className={className}
style={{ display: "flex", alignItems: "center" }}
{...props}
>
{children ?? <ChevronRightIcon />}
</li>
{children ?? <IconChevronRight size={14} />}
</Box>
)
}
function BreadcrumbEllipsis({ className, ...props }: React.ComponentPropsWithoutRef<"span">) {
return (
<span
<Box
data-slot="breadcrumb-ellipsis"
component="span"
role="presentation"
aria-hidden="true"
className={cn("flex size-9 items-center justify-center", className)}
style={{ display: "flex", width: 36, height: 36, alignItems: "center", justifyContent: "center" }}
className={className}
{...props}
>
<MoreHorizontalIcon className="size-4" />
<span className="sr-only">More</span>
</span>
<IconDots size={16} />
<span style={{ position: "absolute", width: 1, height: 1, padding: 0, margin: -1, overflow: "hidden", clip: "rect(0,0,0,0)", whiteSpace: "nowrap", borderWidth: 0 }}>More</span>
</Box>
)
}