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
+45 -50
View File
@@ -1,61 +1,56 @@
import * as React from "react"
import { RadioGroup as RadioGroupPrimitive } from "@base-ui/react/radio-group"
import { Radio } from "@base-ui/react/radio"
import { cn } from "../core/cn"
import { Radio } from "@mantine/core"
function RadioGroup({ className, ...props }: RadioGroupPrimitive.Props) {
interface RadioGroupProps {
value?: string
defaultValue?: string
onValueChange?: (value: string) => void
disabled?: boolean
orientation?: "horizontal" | "vertical"
className?: string
children?: React.ReactNode
}
function RadioGroup({ className, value, defaultValue, onValueChange, orientation, children, ...props }: RadioGroupProps) {
return (
<RadioGroupPrimitive
<Radio.Group
data-slot="radio-group"
className={cn("grid gap-2", className)}
value={value}
defaultValue={defaultValue}
onChange={(val) => onValueChange?.(val)}
className={className}
{...props}
>
<div style={{ display: 'flex', flexDirection: orientation === 'horizontal' ? 'row' : 'column', gap: 'var(--mantine-spacing-sm)' }}>
{children}
</div>
</Radio.Group>
)
}
interface RadioGroupItemProps {
value: string
label?: string
disabled?: boolean
className?: string
labelClassName?: string
id?: string
}
function RadioGroupItem({ className, label, id, disabled, value, ...props }: RadioGroupItemProps) {
return (
<Radio
id={id}
data-slot="radio-group-item"
value={value}
label={label}
disabled={disabled}
className={className}
size="sm"
{...props}
/>
)
}
interface RadioGroupItemProps extends Radio.Root.Props {
label?: string
className?: string
labelClassName?: string
}
function RadioGroupItem({ className, label, id, labelClassName, ...props }: RadioGroupItemProps) {
const internalId = React.useId()
const itemId = id ?? internalId
return (
<div className="flex items-center gap-2">
<Radio.Root
id={itemId}
data-slot="radio-group-item"
className={cn(
"aspect-square size-4 rounded-full border border-input bg-transparent transition-colors outline-none",
"focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50",
"data-checked:border-primary",
"disabled:pointer-events-none disabled:opacity-50",
className
)}
{...props}
>
<Radio.Indicator
data-slot="radio-group-indicator"
className="flex items-center justify-center"
>
<span className="block size-2 rounded-full bg-primary" />
</Radio.Indicator>
</Radio.Root>
{label && (
<label
htmlFor={itemId}
data-slot="radio-group-label"
className={cn("text-sm font-medium leading-none cursor-pointer select-none", labelClassName)}
>
{label}
</label>
)}
</div>
)
}
export { RadioGroup, RadioGroupItem }
export type { RadioGroupItemProps }