feat: funciones frontend React/TS — componentes UI, hooks Wails, charts y tipos
Componentes React reutilizables: card, dialog, tabs, select, alert, badge, button, input, label, skeleton, tooltip, progress_bar, page_header, form_field, settings_page, crud_page, analytics_page, dashboard_layout. Charts: area, bar, line, sparkline, kpi_card, chart_container. Hooks Wails: use_wails_query, use_wails_mutation, use_wails_stream, use_wails_event, use_animated_canvas. Funciones core: cn, format_compact, chart_colors, get_series_color, wails_cache, theme_config_to_colors. Tipos: chart_series, wails_ipc, theme_config, component_variants. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
import * as React from 'react'
|
||||
import { cn } from '../core/cn'
|
||||
|
||||
interface DashboardWidget {
|
||||
id: string
|
||||
title?: string
|
||||
span?: 1 | 2 | 3 | 4
|
||||
rowSpan?: 1 | 2
|
||||
content: React.ReactNode
|
||||
}
|
||||
|
||||
interface DashboardLayoutProps {
|
||||
widgets: DashboardWidget[]
|
||||
columns?: 1 | 2 | 3 | 4
|
||||
gap?: 'sm' | 'md' | 'lg'
|
||||
className?: string
|
||||
}
|
||||
|
||||
const gapClasses = { sm: 'gap-2', md: 'gap-4', lg: 'gap-6' }
|
||||
|
||||
const spanClasses: Record<number, string> = {
|
||||
1: 'col-span-1',
|
||||
2: 'col-span-1 md:col-span-2',
|
||||
3: 'col-span-1 md:col-span-2 lg:col-span-3',
|
||||
4: 'col-span-1 md:col-span-2 lg:col-span-4',
|
||||
}
|
||||
|
||||
const rowSpanClasses: Record<number, string> = {
|
||||
1: 'row-span-1',
|
||||
2: 'row-span-2',
|
||||
}
|
||||
|
||||
export function dashboardLayout({
|
||||
widgets,
|
||||
columns = 4,
|
||||
gap = 'md',
|
||||
className,
|
||||
}: DashboardLayoutProps): React.ReactElement {
|
||||
const gridCols: Record<number, string> = {
|
||||
1: 'grid-cols-1',
|
||||
2: 'grid-cols-1 md:grid-cols-2',
|
||||
3: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3',
|
||||
4: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-4',
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={cn('grid', gridCols[columns], gapClasses[gap], className)}>
|
||||
{widgets.map((widget) => (
|
||||
<div
|
||||
key={widget.id}
|
||||
className={cn(
|
||||
'rounded-xl border bg-card p-4 text-card-foreground shadow-sm',
|
||||
spanClasses[widget.span || 1],
|
||||
rowSpanClasses[widget.rowSpan || 1]
|
||||
)}
|
||||
>
|
||||
{widget.title && (
|
||||
<h3 className="mb-3 text-sm font-medium text-muted-foreground">{widget.title}</h3>
|
||||
)}
|
||||
{widget.content}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export type { DashboardWidget, DashboardLayoutProps }
|
||||
Reference in New Issue
Block a user