feat(dashboard): implement customizable dashboard with widget support
- Added `react-grid-layout` for drag-and-drop functionality. - Created `DashboardCanvas` component to manage layout and widget interactions. - Introduced `WidgetContainer` and `WidgetPicker` components for widget management. - Implemented various widgets: Active Rides, Today Sales, Pending Purchase Orders, Stock Alerts, Recent Orders, and Loading Sheets. - Integrated API calls for fetching and saving dashboard preferences. - Defined default layouts for different user roles. - Created a card component for consistent widget styling.
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
'use client'
|
||||
|
||||
import { WIDGET_REGISTRY } from '@/lib/widgets/registry'
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { HugeiconsIcon } from '@hugeicons/react'
|
||||
import { Cancel01Icon, DragDropVerticalIcon } from '@hugeicons/core-free-icons'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
interface WidgetContainerProps {
|
||||
widgetType: string
|
||||
editMode: boolean
|
||||
onRemove: () => void
|
||||
}
|
||||
|
||||
export function WidgetContainer({ widgetType, editMode, onRemove }: WidgetContainerProps) {
|
||||
const def = WIDGET_REGISTRY[widgetType]
|
||||
const Component = def?.component
|
||||
|
||||
return (
|
||||
<Card className={cn('flex h-full flex-col overflow-hidden transition-shadow', editMode && 'ring-1 ring-border')}>
|
||||
<CardHeader className="flex-row items-center justify-between gap-2 pb-2 pt-3">
|
||||
<div className="flex min-w-0 items-center gap-2">
|
||||
{editMode && (
|
||||
<span
|
||||
className="drag-handle shrink-0 cursor-grab touch-none text-muted-foreground active:cursor-grabbing"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<HugeiconsIcon icon={DragDropVerticalIcon} size={14} strokeWidth={2} />
|
||||
</span>
|
||||
)}
|
||||
<CardTitle className="truncate">{def?.label ?? widgetType}</CardTitle>
|
||||
</div>
|
||||
{editMode && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon-sm"
|
||||
className="shrink-0 text-muted-foreground hover:text-destructive"
|
||||
onClick={onRemove}
|
||||
aria-label={`Remove ${def?.label ?? widgetType} widget`}
|
||||
>
|
||||
<HugeiconsIcon icon={Cancel01Icon} size={14} strokeWidth={2} />
|
||||
</Button>
|
||||
)}
|
||||
</CardHeader>
|
||||
<CardContent className="flex-1 overflow-hidden pt-0">
|
||||
{Component ? (
|
||||
<Component />
|
||||
) : (
|
||||
<p className="text-sm text-muted-foreground">Unknown widget type: {widgetType}</p>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user