Widgets

Domain-specific widget library organized by category including charts, media, IoT controls, Nextcloud integrations, and automation components.

Last updated: 2025-02-18

Widgets

Certexi's 112+ widgets are purpose-built components for logistics and warehouse management. Each widget is self-contained with its own data fetching, state management, and error handling.

Chart Widgets

Data visualization components powered by Recharts:

WidgetDescription
ThroughputChartUnits processed over time (bar/line)
UtilizationGaugeZone capacity gauge with thresholds
StageDistributionPie chart of units per workflow stage
WeightVarianceChartEntry vs exit weight comparison
OperatorPerformanceBar chart of units per operator
DwellTimeHeatmapHeatmap of time spent per stage
IncidentTrendIncident frequency over time
ComplianceScoreCompliance KPI radial progress

Usage

import { ThroughputChart } from '@/components/widgets/charts/throughput-chart';

<ThroughputChart warehouseId={1} period="7d" granularity="day" height={300} />;

KPI / gauge sandbox

Widget-style cards using the same primitives (Progress, Badge, Card):

KPI cards
<div className="grid grid-cols-2 gap-4 max-w-lg">
  <Card>
    <CardHeader className="pb-2">
      <CardDescription>Active units</CardDescription>
      <CardTitle className="text-2xl">24</CardTitle>
    </CardHeader>
    <CardContent>
      <Progress value={72} className="h-2" />
      <p className="text-xs text-muted-foreground mt-2">72% capacity</p>
    </CardContent>
  </Card>
  <Card>
    <CardHeader className="pb-2">
      <CardDescription>Compliance</CardDescription>
      <CardTitle className="text-2xl flex items-center gap-2">
        98% <Badge variant="secondary">OK</Badge>
      </CardTitle>
    </CardHeader>
    <CardContent>
      <Progress value={98} className="h-2" />
    </CardContent>
  </Card>
</div>

Media Widgets

Components for handling evidence media:

WidgetDescription
PhotoCaptureCamera capture with EXIF metadata
PhotoGalleryEvidence photo grid with lightbox
VideoPlayerHLS video player for CCTV clips
VideoRecorderShort clip recording
SignaturePadDigital signature capture
DocumentViewerPDF and image document viewer
AudioRecorderVoice note recording
QRScannerQR/barcode scanning overlay

Status and alert sandbox

Status widget
<Card className="max-w-md">
  <CardHeader className="pb-2">
    <div className="flex items-center justify-between">
      <CardTitle>Camera 3 — Loading dock</CardTitle>
      <Badge variant="secondary">Live</Badge>
    </div>
    <CardDescription>Motion detection enabled</CardDescription>
  </CardHeader>
  <CardContent className="space-y-3">
    <Alert>
      <AlertTitle>Motion detected</AlertTitle>
      <AlertDescription>
        Last event 2 min ago. Clip saved to buffer.
      </AlertDescription>
    </Alert>
    <div className="flex gap-2">
      <Button size="sm">View clip</Button>
      <Button size="sm" variant="outline">Snapshot</Button>
    </div>
  </CardContent>
</Card>

IoT Widgets

Real-time IoT device interaction:

WidgetDescription
MotionClipControlStart/stop motion detection per camera
EnhancedMotionViewerCombined detection with AI overlay
BrowserDetectionOverlayTensorFlow.js bounding boxes
CameraGridMulti-camera view with status
ScaleDisplayReal-time scale reading display
ScaleHistoryScale reading trend chart
NFCScannerNFC tag read/write interface
CameraStatusCamera health and streaming status

Motion Detection Control

import { MotionClipControl } from '@/components/iot/motion-clip-control';

<MotionClipControl
  cctvId={1}
  sessionId={123}
  compact={false}
  onStatusChange={(recording, stats) => {
    console.log('Recording:', recording, stats);
  }}
/>;

Nextcloud Widgets

Integration components for Nextcloud services:

WidgetDescription
TablesBrowserBrowse and manage Nextcloud Tables
TableEditorInline row editing for table data
FilePickerNextcloud file browser and picker
FileUploaderDrag-and-drop file upload to Nextcloud
FormBuilderNextcloud Forms integration
ShareManagerTable/file sharing controls
ActivityFeedRecent Nextcloud activity stream

WHMS Widgets

Warehouse management specific components:

WidgetDescription
FloorPlanCanvasInteractive floor plan with slot polygons
SlotPolygonIndividual slot polygon component
SlotSidebarSlot details and properties panel
ZonePickerZone selection and configuration
PlacementFlowFull placement wizard (scan → photo → confirm)
RemovalFlowRemoval confirmation workflow
UtilizationWidgetZone utilization dashboard
AssetLocatorAsset search and location display

Floor Plan Editor

import { FloorPlanCanvas } from '@/components/whms/layout-editor/floor-plan-canvas';

<FloorPlanCanvas
  floorPlanUrl="/floor-plans/warehouse-a.png"
  slots={slots}
  onSlotClick={(slot) => setSelectedSlot(slot)}
  editable={isAdmin}
/>;

Tabbed widget sandbox

Many widgets use tabs for Overview / Evidence / Timeline. Same pattern with Tabs:

Tabbed widget
<Tabs defaultValue="overview" className="max-w-lg">
  <TabsList>
    <TabsTrigger value="overview">Overview</TabsTrigger>
    <TabsTrigger value="evidence">Evidence</TabsTrigger>
    <TabsTrigger value="timeline">Timeline</TabsTrigger>
  </TabsList>
  <TabsContent value="overview" className="p-4 border rounded-b-md">
    <p className="text-sm text-muted-foreground">
      Transport unit details and current stage. Throughput and utilization
      charts render here in real widgets.
    </p>
  </TabsContent>
  <TabsContent value="evidence" className="p-4 border rounded-b-md">
    <p className="text-sm text-muted-foreground">
      Photos, clips, and documents attached to this unit.
    </p>
  </TabsContent>
  <TabsContent value="timeline" className="p-4 border rounded-b-md">
    <p className="text-sm text-muted-foreground">
      Event timeline: weighing, inspection, handoff.
    </p>
  </TabsContent>
</Tabs>

Dashboard layout sandbox

Typical dashboard grid combining several widget cards:

Dashboard layout
<div className="grid grid-cols-2 gap-4 max-w-2xl">
  <Card>
    <CardHeader className="pb-2">
      <CardTitle className="text-base">Throughput (24h)</CardTitle>
    </CardHeader>
    <CardContent>
      <Progress value={65} className="h-2 mb-2" />
      <p className="text-xs text-muted-foreground">156 units</p>
    </CardContent>
  </Card>
  <Card>
    <CardHeader className="pb-2">
      <CardTitle className="text-base">Approval queue</CardTitle>
    </CardHeader>
    <CardContent>
      <p className="text-2xl font-semibold">3</p>
      <p className="text-xs text-muted-foreground">Pending</p>
    </CardContent>
  </Card>
  <Card className="col-span-2">
    <CardHeader className="pb-2">
      <CardTitle className="text-base">Recent activity</CardTitle>
    </CardHeader>
    <CardContent>
      <p className="text-sm text-muted-foreground">
        Stage changes, weighings, and evidence events appear here.
      </p>
    </CardContent>
  </Card>
</div>

Workflow Widgets

Customs workflow management components:

WidgetDescription
KanbanBoardDrag-and-drop stage progression
StageCardTransport unit card with evidence status
WorkflowTimelineEvent timeline for a transport unit
ApprovalQueuePending approvals for supervisors
EvidencePanelSide panel with all evidence for a unit
WeighingStationCombined scale + camera + form interface

Social & Gamification

Engagement and team management widgets:

WidgetDescription
LeaderboardOperator performance rankings
AchievementBadgeGamification achievement display
QuestTrackerActive quest/challenge progress
TeamDashboardTeam metrics and activity

Automation Widgets

Process automation and rules management:

WidgetDescription
RuleBuilderVisual rule condition builder
TriggerConfigAutomation trigger configuration
WebhookManagerWebhook endpoint management
AlertConfigAlert threshold configuration
ScheduleEditorCron-style schedule editor

Widget Composition

Widgets are designed to compose together. A typical dashboard combines multiple widgets:

<div className="grid grid-cols-12 gap-4">
  <div className="col-span-8">
    <KanbanBoard warehouseId={1} />
  </div>
  <div className="col-span-4 space-y-4">
    <UtilizationWidget warehouseId={1} />
    <ThroughputChart period="24h" height={200} />
    <ApprovalQueue limit={5} />
  </div>
</div>