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
+16 -32
View File
@@ -1,25 +1,21 @@
import * as React from "react"
import { cn } from "../core/cn"
import { Search, X } from "lucide-react"
import * as React from 'react'
import { TextInput, CloseButton } from '@mantine/core'
import { IconSearch } from '@tabler/icons-react'
interface SearchBarProps {
/** Called with the debounced search query */
onSearch: (query: string) => void
/** Placeholder text */
placeholder?: string
/** Debounce delay in ms (default 300) */
debounceMs?: number
/** Additional CSS classes for the outer wrapper */
className?: string
}
function SearchBar({
onSearch,
placeholder = "Search...",
placeholder = 'Search...',
debounceMs = 300,
className,
}: SearchBarProps) {
const [query, setQuery] = React.useState("")
const [query, setQuery] = React.useState('')
const timerRef = React.useRef<ReturnType<typeof setTimeout> | null>(null)
const onSearchRef = React.useRef(onSearch)
onSearchRef.current = onSearch
@@ -35,29 +31,17 @@ function SearchBar({
}, [query, debounceMs])
return (
<div
className={cn(
"flex flex-1 items-center gap-2 rounded border border-border bg-input px-2 py-1",
className,
)}
>
<Search size={14} className="text-muted-foreground shrink-0" />
<input
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder={placeholder}
className="flex-1 bg-transparent text-sm text-foreground outline-none placeholder:text-muted-foreground"
/>
{query && (
<button
onClick={() => setQuery("")}
className="p-0.5 text-muted-foreground hover:text-foreground"
aria-label="Clear search"
>
<X size={12} />
</button>
)}
</div>
<TextInput
value={query}
onChange={(e) => setQuery(e.currentTarget.value)}
placeholder={placeholder}
leftSection={<IconSearch size={14} />}
rightSection={query ? (
<CloseButton size="sm" onClick={() => setQuery('')} aria-label="Clear search" />
) : undefined}
className={className}
size="sm"
/>
)
}