Files
ERP_Distribution/distribution_fe/components/dashboard/widget-picker.tsx
T
Kalana B. Thilakarathna 29f181d5e1 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.
2026-08-29 16:51:25 +05:30

77 lines
2.6 KiB
TypeScript

'use client'
import { getWidgetsForRole, type WidgetDefinition } from '@/lib/widgets/registry'
import type { Role } from '@/contexts/auth-context'
import type { WidgetLayoutItem } from '@/lib/api/dashboard'
import {
Sheet,
SheetContent,
SheetHeader,
SheetTitle,
SheetDescription,
} from '@/components/ui/sheet'
import { Button } from '@/components/ui/button'
import { Separator } from '@/components/ui/separator'
import { HugeiconsIcon } from '@hugeicons/react'
import { Add01Icon } from '@hugeicons/core-free-icons'
interface WidgetPickerProps {
open: boolean
onClose: () => void
role: Role
currentLayout: WidgetLayoutItem[]
onAdd: (widgetType: string) => void
}
export function WidgetPicker({ open, onClose, role, currentLayout, onAdd }: WidgetPickerProps) {
const available = getWidgetsForRole(role)
const activeTypes = new Set(currentLayout.map(l => l.widgetType))
function handleAdd(def: WidgetDefinition) {
onAdd(def.type)
onClose()
}
return (
<Sheet open={open} onOpenChange={v => { if (!v) onClose() }}>
<SheetContent side="right" className="flex w-full flex-col gap-0 sm:max-w-sm">
<SheetHeader className="px-4 pb-3 pt-4">
<SheetTitle>Add Widget</SheetTitle>
<SheetDescription>
Choose a widget to add to your dashboard.
</SheetDescription>
</SheetHeader>
<Separator />
<div className="flex flex-1 flex-col gap-1 overflow-auto p-4">
{available.map(def => {
const alreadyAdded = activeTypes.has(def.type)
return (
<div
key={def.type}
className="flex items-start justify-between gap-3 rounded-xl border p-3"
>
<div className="flex min-w-0 flex-col gap-0.5">
<p className="text-sm font-medium">{def.label}</p>
<p className="text-xs text-muted-foreground">{def.description}</p>
<p className="mt-1 text-xs text-muted-foreground">
Default size: {def.defaultW}&times;{def.defaultH}
</p>
</div>
<Button
size="sm"
variant={alreadyAdded ? 'outline' : 'default'}
className="mt-0.5 shrink-0"
onClick={() => handleAdd(def)}
>
<HugeiconsIcon icon={Add01Icon} size={14} strokeWidth={2} />
{alreadyAdded ? 'Add another' : 'Add'}
</Button>
</div>
)
})}
</div>
</SheetContent>
</Sheet>
)
}