@bpfdev/oly-ui 1.0.9 → 1.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -323,6 +323,499 @@ import { AddCommentInput } from '@bpfdev/oly-ui';
323
323
 
324
324
  ---
325
325
 
326
+ ### WidgetHeaderFilter
327
+
328
+ A compact trigger + popover filter designed to sit in a widget header row. Supports single and multi-select modes.
329
+
330
+ ```tsx
331
+ import { WidgetHeaderFilter } from '@bpfdev/oly-ui';
332
+
333
+ const GENDER_OPTIONS = [
334
+ { id: 1, name: 'All' },
335
+ { id: 2, name: 'Male' },
336
+ { id: 3, name: 'Female' },
337
+ ];
338
+
339
+ function GenderFilter() {
340
+ const [selected, setSelected] = React.useState([GENDER_OPTIONS[0]]);
341
+ return (
342
+ <WidgetHeaderFilter
343
+ label="Select Gender"
344
+ list={GENDER_OPTIONS}
345
+ data={selected}
346
+ setData={setSelected}
347
+ triggerMinWidth={140}
348
+ />
349
+ );
350
+ }
351
+ ```
352
+
353
+ ---
354
+
355
+ ### TimePeriodFilter
356
+
357
+ A date-range / time-period selector with preset options (today, week, month, custom range).
358
+
359
+ ```tsx
360
+ import { TimePeriodFilter } from '@bpfdev/oly-ui';
361
+
362
+ <TimePeriodFilter value={period} onChange={setPeriod} />;
363
+ ```
364
+
365
+ ---
366
+
367
+ ### ChartWidgetSegmentedTabs
368
+
369
+ A segmented tab control for switching between chart views within a widget.
370
+
371
+ ```tsx
372
+ import { ChartWidgetSegmentedTabs } from '@bpfdev/oly-ui';
373
+ import type { ChartWidgetSegmentedTab } from '@bpfdev/oly-ui';
374
+
375
+ const tabs: ChartWidgetSegmentedTab[] = [
376
+ { value: 'daily', label: 'Daily' },
377
+ { value: 'weekly', label: 'Weekly' },
378
+ { value: 'monthly', label: 'Monthly' },
379
+ ];
380
+
381
+ <ChartWidgetSegmentedTabs
382
+ tabs={tabs}
383
+ value={activeTab}
384
+ onChange={setActiveTab}
385
+ />;
386
+ ```
387
+
388
+ ---
389
+
390
+ ### ChartWidgetInfoButton
391
+
392
+ A compact info icon button that opens a popover with a title, description, and help bullets. Designed for widget headers.
393
+
394
+ ```tsx
395
+ import { ChartWidgetInfoButton } from '@bpfdev/oly-ui';
396
+
397
+ <ChartWidgetInfoButton
398
+ density="compact"
399
+ popover={{
400
+ title: 'Customer Journey Analysis',
401
+ description:
402
+ 'Tracks the progression of customers from walk-ins to billing.',
403
+ helpBullets: [
404
+ 'Walk-in → Billing: % of walk-ins that complete a billing visit.',
405
+ 'Trial → Billing: % of trial visits that result in billing.',
406
+ ],
407
+ }}
408
+ />;
409
+ ```
410
+
411
+ ---
412
+
413
+ ### ChartWidgetHeaderSeparator
414
+
415
+ A thin vertical divider used to separate controls in a widget header row.
416
+
417
+ ```tsx
418
+ import { ChartWidgetHeaderSeparator } from '@bpfdev/oly-ui';
419
+
420
+ <Stack direction="row" alignItems="center" gap={1}>
421
+ <GenderFilter />
422
+ <ChartWidgetHeaderSeparator />
423
+ <ChartWidgetInfoButton ... />
424
+ </Stack>;
425
+ ```
426
+
427
+ ---
428
+
429
+ ### ChartEmptyState
430
+
431
+ A centered empty-state illustration and message shown when a chart has no data.
432
+
433
+ ```tsx
434
+ import { ChartEmptyState } from '@bpfdev/oly-ui';
435
+
436
+ <ChartEmptyState message="No data available for the selected period." />;
437
+ ```
438
+
439
+ ---
440
+
441
+ ### FalconStatBanner / FalconStatBannerGroup
442
+
443
+ A stat banner for displaying a labeled metric inline. Group multiple banners with `FalconStatBannerGroup`.
444
+
445
+ ```tsx
446
+ import { FalconStatBanner, FalconStatBannerGroup } from '@bpfdev/oly-ui';
447
+
448
+ <FalconStatBannerGroup>
449
+ <FalconStatBanner label="Total Walk-ins" value={1430} />
450
+ <FalconStatBanner label="Conversion Rate" value="36.9%" />
451
+ <FalconStatBanner label="Avg. Dwell Time" value="4m 12s" />
452
+ </FalconStatBannerGroup>;
453
+ ```
454
+
455
+ ---
456
+
457
+ ### FalconAuditTimeline
458
+
459
+ A timeline widget for visualising audit activity across months.
460
+
461
+ ```tsx
462
+ import { FalconAuditTimeline } from '@bpfdev/oly-ui';
463
+ import type { MonthData } from '@bpfdev/oly-ui';
464
+
465
+ const months: MonthData[] = [
466
+ { month: 'Jan', completed: 12, pending: 3, failed: 1 },
467
+ { month: 'Feb', completed: 18, pending: 2, failed: 0 },
468
+ ];
469
+
470
+ <FalconAuditTimeline months={months} />;
471
+ ```
472
+
473
+ ---
474
+
475
+ ### FalconExportDialog
476
+
477
+ A dialog for selecting export format and date range before downloading a report.
478
+
479
+ ```tsx
480
+ import { FalconExportDialog } from '@bpfdev/oly-ui';
481
+
482
+ <FalconExportDialog
483
+ open={isOpen}
484
+ onClose={() => setIsOpen(false)}
485
+ onExport={handleExport}
486
+ />;
487
+ ```
488
+
489
+ ---
490
+
491
+ ### FalconExportReportDialog
492
+
493
+ An extended export dialog that includes filter options (e.g. location, gender) alongside format and date selection.
494
+
495
+ ```tsx
496
+ import { FalconExportReportDialog } from '@bpfdev/oly-ui';
497
+ import type { FilterOption } from '@bpfdev/oly-ui';
498
+
499
+ const locationOptions: FilterOption[] = [
500
+ { id: 1, name: 'Mall A' },
501
+ { id: 2, name: 'Mall B' },
502
+ ];
503
+
504
+ <FalconExportReportDialog
505
+ open={isOpen}
506
+ onClose={() => setIsOpen(false)}
507
+ onExport={handleExport}
508
+ filterOptions={locationOptions}
509
+ />;
510
+ ```
511
+
512
+ ---
513
+
514
+ ### KpiStatCard
515
+
516
+ A KPI stat card showing a label, numeric value, optional trend indicator, and an icon. Supports inline (compact) and detailed (icon backdrop) layouts.
517
+
518
+ ```tsx
519
+ import { KpiStatCard } from '@bpfdev/oly-ui';
520
+
521
+ <KpiStatCard
522
+ label="Total Walk-ins"
523
+ value={1430}
524
+ trend={{ value: 12.5, direction: 'up' }}
525
+ icon="tabler:users"
526
+ />;
527
+ ```
528
+
529
+ | Prop | Type | Default | Description |
530
+ | ----------- | ------------------ | ------- | ------------------------------- |
531
+ | `label` | `string` | — | Card label text |
532
+ | `value` | `number \| string` | — | Primary metric value |
533
+ | `trend` | `KpiTrend` | — | Optional `{ value, direction }` |
534
+ | `icon` | `string` | — | Iconify icon id |
535
+ | `isLoading` | `boolean` | `false` | Shows skeleton when `true` |
536
+
537
+ ---
538
+
539
+ ### JourneyStatCard
540
+
541
+ A coloured stat card with an Iconify icon, uppercase label, and large numeric value. Used inside `CustomerJourneyAnalysis` but works standalone in any layout.
542
+
543
+ ```tsx
544
+ import { JourneyStatCard } from '@bpfdev/oly-ui';
545
+
546
+ // Standalone (rounded corners)
547
+ <JourneyStatCard
548
+ icon="tabler:users"
549
+ bg="#6DA0EF"
550
+ label="Walk-ins"
551
+ value={143}
552
+ borderRadius={2}
553
+ />
554
+
555
+ // Flush strip — wrap three cards in a clipped flex container
556
+ <Box sx={{ display: 'flex', borderRadius: '12px', overflow: 'hidden' }}>
557
+ <JourneyStatCard icon="tabler:users" bg="#6DA0EF" label="Walk-ins" value={143} />
558
+ <JourneyStatCard icon="tabler:door-enter" bg="#F5A334" label="Trial Visits" value={357} />
559
+ <JourneyStatCard icon="tabler:shopping-bag" bg="#5EC45E" label="Billing Visits" value={89} />
560
+ </Box>
561
+ ```
562
+
563
+ | Prop | Type | Default | Description |
564
+ | --------------- | ------------------ | ----------------------- | -------------------------------------------------------- |
565
+ | `icon` | `string` | — | Iconify icon id (e.g. `tabler:users`) |
566
+ | `bg` | `string` | — | Card background color |
567
+ | `label` | `string` | — | Uppercase label shown below the icon |
568
+ | `value` | `number \| string` | — | Numeric value shown prominently |
569
+ | `iconSize` | `number` | `52` | Icon size (px) |
570
+ | `iconColor` | `string` | `#ffffff` | Icon color |
571
+ | `labelColor` | `string` | `rgba(255,255,255,0.9)` | Label text color |
572
+ | `labelFontSize` | `number` | `13` | Label font size (px) |
573
+ | `valueColor` | `string` | `#ffffff` | Value text color |
574
+ | `valueFontSize` | `number` | `40` | Value font size (px) |
575
+ | `borderRadius` | `number \| string` | `0` | Card border radius. Set `2` for standalone rounded style |
576
+ | `minHeight` | `number` | `200` | Minimum card height (px) |
577
+ | `isLoading` | `boolean` | `false` | Shows skeleton shimmer |
578
+ | `showOuterCard` | `boolean` | `false` | Wraps card in a white outer container |
579
+ | `sx` | `SxProps` | — | Extra MUI `sx` on the root |
580
+
581
+ ---
582
+
583
+ ### JourneyMetricCard
584
+
585
+ A metric display card showing a label and a large formatted value. Used in the 2×2 metrics grid inside `CustomerJourneyAnalysis`.
586
+
587
+ ```tsx
588
+ import { JourneyMetricCard } from '@bpfdev/oly-ui';
589
+
590
+ <JourneyMetricCard
591
+ label="Walk-in → Billing Conversion"
592
+ value="36.9%"
593
+ valueColor="#1E293B"
594
+ labelColor="#6B7280"
595
+ />;
596
+ ```
597
+
598
+ | Prop | Type | Default | Description |
599
+ | ----------------- | ------------------------------- | ---------- | -------------------------- |
600
+ | `label` | `string` | — | Descriptor text |
601
+ | `value` | `string` | — | Formatted metric value |
602
+ | `labelColor` | `string` | `#6B7280` | Label text color |
603
+ | `labelFontSize` | `number` | `13` | Label font size (px) |
604
+ | `valueColor` | `string` | `#111827` | Value text color |
605
+ | `valueFontSize` | `number` | `28` | Value font size (px) |
606
+ | `valueFontWeight` | `number` | `700` | Value font weight |
607
+ | `textAlign` | `'left' \| 'center' \| 'right'` | `'center'` | Text alignment |
608
+ | `isLoading` | `boolean` | `false` | Shows skeleton shimmer |
609
+ | `sx` | `SxProps` | — | Extra MUI `sx` on the root |
610
+
611
+ ---
612
+
613
+ ### CustomerJourneyAnalysis
614
+
615
+ A full-width customer journey funnel widget. Shows walk-in, trial visit, and billing visit counts in coloured stat cards alongside a 2×2 conversion metrics grid. Every label, number, color, font, icon, and layout value is customisable via props.
616
+
617
+ ```tsx
618
+ import { CustomerJourneyAnalysis } from '@bpfdev/oly-ui';
619
+
620
+ <CustomerJourneyAnalysis
621
+ walkIns={143}
622
+ trialVisits={357}
623
+ billingVisits={89}
624
+ walkInToBillingConversion={36.9}
625
+ trialToBillingConversion={27}
626
+ avgTrialsPerWalkIn={3.2}
627
+ avgBillingPerTrial={2.4}
628
+ headerActions={<GenderFilter />}
629
+ />;
630
+ ```
631
+
632
+ **Required props**
633
+
634
+ | Prop | Type | Description |
635
+ | --------------------------- | -------- | ------------------------------------- |
636
+ | `walkIns` | `number` | Walk-in visit count |
637
+ | `trialVisits` | `number` | Trial visit count |
638
+ | `billingVisits` | `number` | Billing visit count |
639
+ | `walkInToBillingConversion` | `number` | Walk-in → billing conversion rate (%) |
640
+ | `trialToBillingConversion` | `number` | Trial → billing conversion rate (%) |
641
+ | `avgTrialsPerWalkIn` | `number` | Avg. trial visits per walk-in |
642
+ | `avgBillingPerTrial` | `number` | Avg. billing visits per trial |
643
+
644
+ **Key optional props**
645
+
646
+ | Prop | Type | Default | Description |
647
+ | ------------------------- | ------------------- | ------------------------------ | ------------------------------------------------- |
648
+ | `title` | `string` | `'Customer Journey Analysis'` | Widget heading |
649
+ | `walkInsLabel` | `string` | `'Walk-ins'` | Label on the first stat card |
650
+ | `trialVisitsLabel` | `string` | `'Trial Visits'` | Label on the second stat card |
651
+ | `billingVisitsLabel` | `string` | `'Billing Visits'` | Label on the third stat card |
652
+ | `walkInsBg` | `string` | `#5B8DEF` | Walk-ins card background color |
653
+ | `trialVisitsBg` | `string` | `#F59E42` | Trial Visits card background color |
654
+ | `billingVisitsBg` | `string` | `#6EBE7A` | Billing Visits card background color |
655
+ | `walkInsIcon` | `string` | `tabler:users` | Iconify icon for Walk-ins card |
656
+ | `trialVisitsIcon` | `string` | `mynaui:door-open` | Iconify icon for Trial Visits card |
657
+ | `billingVisitsIcon` | `string` | `mingcute:shopping-bag-3-line` | Iconify icon for Billing Visits card |
658
+ | `metricsCardBg` | `string` | `#F9FAFB` | Background color of each metric card |
659
+ | `isLoading` | `boolean` | `false` | Shows skeleton shimmers across all cards |
660
+ | `headerActions` | `ReactNode` | — | Slot for filters / info button in the header row |
661
+ | `walkInsCardConfig` | `JourneyStatConfig` | — | Per-card overrides for the Walk-ins stat card |
662
+ | `trialVisitsCardConfig` | `JourneyStatConfig` | — | Per-card overrides for the Trial Visits stat card |
663
+ | `billingVisitsCardConfig` | `JourneyStatConfig` | — | Per-card overrides for the Billing Visits card |
664
+ | `statCardDefaults` | `JourneyStatConfig` | — | Shared defaults applied to all three stat cards |
665
+ | `cardSx` | `SxProps` | — | Extra `sx` on the outer card wrapper |
666
+
667
+ ---
668
+
669
+ ### RankedBarList
670
+
671
+ A horizontal ranked bar chart with optional segmented bars, tooltips, and a configurable legend.
672
+
673
+ ```tsx
674
+ import { RankedBarList } from '@bpfdev/oly-ui';
675
+ import type { RankedBarListItem } from '@bpfdev/oly-ui';
676
+
677
+ const items: RankedBarListItem[] = [
678
+ { label: 'Store A', value: 1200 },
679
+ { label: 'Store B', value: 850 },
680
+ { label: 'Store C', value: 640 },
681
+ ];
682
+
683
+ <RankedBarList items={items} />;
684
+ ```
685
+
686
+ ---
687
+
688
+ ### FootfallByGender
689
+
690
+ A bar/line chart widget showing footfall broken down by gender over time.
691
+
692
+ ```tsx
693
+ import { FootfallByGender } from '@bpfdev/oly-ui';
694
+ import type { FootfallByGenderRow } from '@bpfdev/oly-ui';
695
+
696
+ const rows: FootfallByGenderRow[] = [
697
+ { label: 'Mon', male: 320, female: 280 },
698
+ { label: 'Tue', male: 410, female: 360 },
699
+ ];
700
+
701
+ <FootfallByGender rows={rows} />;
702
+ ```
703
+
704
+ ---
705
+
706
+ ### FootfallByAgeGroups
707
+
708
+ A bar/line chart widget showing footfall broken down by age group over time.
709
+
710
+ ```tsx
711
+ import { FootfallByAgeGroups } from '@bpfdev/oly-ui';
712
+ import type { FootfallByAgeGroupsRow } from '@bpfdev/oly-ui';
713
+
714
+ const rows: FootfallByAgeGroupsRow[] = [
715
+ { label: 'Mon', youth: 120, adult: 300, senior: 80 },
716
+ { label: 'Tue', youth: 150, adult: 340, senior: 90 },
717
+ ];
718
+
719
+ <FootfallByAgeGroups rows={rows} />;
720
+ ```
721
+
722
+ ---
723
+
724
+ ### PasserbyConversion
725
+
726
+ A chart widget comparing passerby count to walk-in conversion over time.
727
+
728
+ ```tsx
729
+ import { PasserbyConversion } from '@bpfdev/oly-ui';
730
+ import type { PasserbyConversionRow } from '@bpfdev/oly-ui';
731
+
732
+ const rows: PasserbyConversionRow[] = [
733
+ { label: 'Mon', passerby: 1200, walkIns: 320 },
734
+ { label: 'Tue', passerby: 1500, walkIns: 410 },
735
+ ];
736
+
737
+ <PasserbyConversion rows={rows} />;
738
+ ```
739
+
740
+ ---
741
+
742
+ ### WalkinAnalysis
743
+
744
+ A donut/pie chart widget breaking down walk-in visits by category (new vs. repeat, or custom slices).
745
+
746
+ ```tsx
747
+ import { WalkinAnalysis } from '@bpfdev/oly-ui';
748
+ import type { WalkinAnalysisSlice } from '@bpfdev/oly-ui';
749
+
750
+ const slices: WalkinAnalysisSlice[] = [
751
+ { label: 'New', value: 420, color: '#6DA0EF' },
752
+ { label: 'Repeat', value: 280, color: '#F5A334' },
753
+ ];
754
+
755
+ <WalkinAnalysis slices={slices} />;
756
+ ```
757
+
758
+ ---
759
+
760
+ ### WalkinTraffic
761
+
762
+ A time-series chart widget showing walk-in traffic by hour or day.
763
+
764
+ ```tsx
765
+ import { WalkinTraffic } from '@bpfdev/oly-ui';
766
+ import type { WalkinTrafficRow } from '@bpfdev/oly-ui';
767
+
768
+ const rows: WalkinTrafficRow[] = [
769
+ { label: '09:00', value: 45 },
770
+ { label: '10:00', value: 78 },
771
+ { label: '11:00', value: 112 },
772
+ ];
773
+
774
+ <WalkinTraffic rows={rows} />;
775
+ ```
776
+
777
+ ---
778
+
779
+ ### BillingCounterAnalytics
780
+
781
+ A widget visualising billing counter activity — queue lengths, service times, and counter utilisation.
782
+
783
+ ```tsx
784
+ import { BillingCounterAnalytics } from '@bpfdev/oly-ui';
785
+ ```
786
+
787
+ ---
788
+
789
+ ### QueueTimeBreakdown
790
+
791
+ A widget displaying queue time distribution by area or counter, with area, donut, and stacked-bar chart variants.
792
+
793
+ ```tsx
794
+ import { QueueTimeBreakdown } from '@bpfdev/oly-ui';
795
+ ```
796
+
797
+ ---
798
+
799
+ ### FootFallHeatMap
800
+
801
+ A heat-map chart showing footfall intensity by hour and day of week.
802
+
803
+ ```tsx
804
+ import { FootFallHeatMap } from '@bpfdev/oly-ui';
805
+ ```
806
+
807
+ ---
808
+
809
+ ### PeakBillingHours
810
+
811
+ A chart widget highlighting the peak billing hours within a selected time window.
812
+
813
+ ```tsx
814
+ import { PeakBillingHours } from '@bpfdev/oly-ui';
815
+ ```
816
+
817
+ ---
818
+
326
819
  ## Tailwind CSS preset
327
820
 
328
821
  If you use Tailwind, extend your config with the Falcon color tokens: