- {layout.map((w) => (
-
-
removeWidget(w.id) : undefined}
- onDuplicate={showActions ? () => duplicateWidget(w.id) : undefined}
- >
- {renderWidget ? (
- renderWidget(w)
- ) : (
-
+ {widgets.map((widget) => (
+
+
+ {/* Render widget content based on type */}
+ {widget.type === 'card' && {String(widget.props?.content ?? '')}
}
+ {widget.type === 'stat' && (
+
+
{Number(widget.props?.value ?? 0)}
+
{String(widget.props?.label ?? '')}
+
+ )}
+ {widget.type === 'progress' && (
+
+
Progress
+
+
{Number(widget.props?.value ?? 0)}%
+
+ )}
+ {widget.type === 'activity' && (
+
+ {Array.isArray(widget.props?.items)
+ ? widget.props.items.map((item: string, idx: number) => (
+ - {String(item)}
+ ))
+ : null}
+
)}
+ {widget.type === 'chart' && (
+
+
+ {typeof widget.props?.kind === 'string' ? widget.props.kind.toUpperCase() : ''}{' '}
+ Chart
+
+ {/* Simple SVG bar chart */}
+ {Array.isArray(widget.props?.data) && widget.props?.kind === 'bar' ? (
+
+ ) : null}
+
+ )}
+ {widget.type === 'custom' && Custom widget
}
))}
);
}
-
-function DefaultWidgetRenderer({
- widget,
- chartAdapter,
-}: {
- widget: BaseWidgetConfig;
- chartAdapter?: ChartAdapter;
-}): JSX.Element {
- const { type, props } = widget;
- switch (type) {
- case 'card':
- return (
-
- {String(props?.content ?? 'Card')}
-
- );
- case 'stat':
- return (
-
-
- {String(props?.value ?? '0')}
-
-
- {String(props?.label ?? 'Stat')}
-
-
- );
- case 'progress': {
- const v = typeof props?.value === 'number' ? props.value : 0;
- return (
-
- );
- }
- case 'activity': {
- const items = Array.isArray(props?.items) ? (props!.items as unknown[]) : [];
- return (
-
- {items.length === 0 ? (
- - No activity
- ) : null}
- {items.map((it, i) => (
- - {String(it)}
- ))}
-
- );
- }
- case 'chart': {
- const kind = (props?.kind as ChartKind) ?? 'line';
- const adapter = chartAdapter ?? DefaultChartAdapter;
- return adapter.render(kind, props ?? {});
- }
- case 'custom':
- default:
- return (
-
Provide a custom renderer.
- );
- }
-}