@voyantjs/availability-ui 0.66.0 → 0.68.0

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.
@@ -28,14 +28,18 @@ export interface AvailabilityOverviewMessages extends AvailabilityColumnsMessage
28
28
  severitySoldOut: string;
29
29
  };
30
30
  }
31
- export declare function AvailabilityOverview({ messages, products, constrainedSlots, openSlotsCount: providedOpenSlotsCount, filteredRules, filteredPickupPoints, productsWithoutUpcomingDepartures, search, setSearch, productFilter, setProductFilter, hasFilters, onClearFilters, onOpenSlot, onOpenProduct, onJumpToSlots, showFilters, }: {
31
+ export declare function AvailabilityOverview({ messages, products, constrainedSlots, constrainedSlotsCount: providedConstrainedSlotsCount, openSlotsCount: providedOpenSlotsCount, activeRulesCount: providedActiveRulesCount, activePickupPointsCount: providedActivePickupPointsCount, filteredRules, filteredPickupPoints, productsWithoutUpcomingDepartures, productsWithoutUpcomingDeparturesCount: providedProductsWithoutUpcomingDeparturesCount, search, setSearch, productFilter, setProductFilter, hasFilters, onClearFilters, onOpenSlot, onOpenProduct, onJumpToSlots, showFilters, }: {
32
32
  messages: AvailabilityOverviewMessages;
33
33
  products: ProductOption[];
34
34
  constrainedSlots: AvailabilitySlotRow[];
35
+ constrainedSlotsCount?: number;
35
36
  openSlotsCount?: number;
37
+ activeRulesCount?: number;
38
+ activePickupPointsCount?: number;
36
39
  filteredRules: AvailabilityRuleRow[];
37
40
  filteredPickupPoints: AvailabilityPickupPointRow[];
38
41
  productsWithoutUpcomingDepartures: ProductOption[];
42
+ productsWithoutUpcomingDeparturesCount?: number;
39
43
  search: string;
40
44
  setSearch: (value: string) => void;
41
45
  productFilter: string;
@@ -1 +1 @@
1
- {"version":3,"file":"availability-overview.d.ts","sourceRoot":"","sources":["../../src/components/availability-overview.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,0BAA0B,EAC1B,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,EACd,MAAM,8BAA8B,CAAA;AA6BrC,OAAO,EAAE,KAAK,2BAA2B,EAAsB,MAAM,2BAA2B,CAAA;AAShG,MAAM,WAAW,4BAA6B,SAAQ,2BAA2B;IAC/E,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,iBAAiB,EAAE,MAAM,CAAA;IACzB,QAAQ,EAAE;QACR,cAAc,EAAE,MAAM,CAAA;QACtB,oBAAoB,EAAE,MAAM,CAAA;QAC5B,qBAAqB,EAAE,MAAM,CAAA;QAC7B,2BAA2B,EAAE,MAAM,CAAA;QACnC,gBAAgB,EAAE,MAAM,CAAA;QACxB,sBAAsB,EAAE,MAAM,CAAA;QAC9B,iBAAiB,EAAE,MAAM,CAAA;QACzB,uBAAuB,EAAE,MAAM,CAAA;QAC/B,sBAAsB,EAAE,MAAM,CAAA;QAC9B,sBAAsB,EAAE,MAAM,CAAA;QAC9B,iBAAiB,EAAE,MAAM,CAAA;QACzB,iBAAiB,EAAE,MAAM,CAAA;QACzB,sBAAsB,EAAE,MAAM,CAAA;QAC9B,mBAAmB,EAAE,MAAM,CAAA;QAC3B,kBAAkB,EAAE,MAAM,CAAA;QAC1B,iBAAiB,EAAE,MAAM,CAAA;QACzB,cAAc,EAAE,MAAM,CAAA;QACtB,cAAc,EAAE,MAAM,CAAA;QACtB,mBAAmB,EAAE,MAAM,CAAA;QAC3B,cAAc,EAAE,MAAM,CAAA;QACtB,eAAe,EAAE,MAAM,CAAA;KACxB,CAAA;CACF;AAED,wBAAgB,oBAAoB,CAAC,EACnC,QAAQ,EACR,QAAQ,EACR,gBAAgB,EAChB,cAAc,EAAE,sBAAsB,EACtC,aAAa,EACb,oBAAoB,EACpB,iCAAiC,EACjC,MAAM,EACN,SAAS,EACT,aAAa,EACb,gBAAgB,EAChB,UAAU,EACV,cAAc,EACd,UAAU,EACV,aAAa,EACb,aAAa,EACb,WAAkB,GACnB,EAAE;IACD,QAAQ,EAAE,4BAA4B,CAAA;IACtC,QAAQ,EAAE,aAAa,EAAE,CAAA;IACzB,gBAAgB,EAAE,mBAAmB,EAAE,CAAA;IACvC,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,aAAa,EAAE,mBAAmB,EAAE,CAAA;IACpC,oBAAoB,EAAE,0BAA0B,EAAE,CAAA;IAClD,iCAAiC,EAAE,aAAa,EAAE,CAAA;IAClD,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,aAAa,EAAE,MAAM,CAAA;IACrB,gBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACzC,UAAU,EAAE,OAAO,CAAA;IACnB,cAAc,EAAE,MAAM,IAAI,CAAA;IAC1B,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;IACpC,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;IAC1C,aAAa,CAAC,EAAE,MAAM,IAAI,CAAA;IAC1B,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB,2CAuKA"}
1
+ {"version":3,"file":"availability-overview.d.ts","sourceRoot":"","sources":["../../src/components/availability-overview.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,0BAA0B,EAC1B,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,EACd,MAAM,8BAA8B,CAAA;AA6BrC,OAAO,EAAE,KAAK,2BAA2B,EAAsB,MAAM,2BAA2B,CAAA;AAShG,MAAM,WAAW,4BAA6B,SAAQ,2BAA2B;IAC/E,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,iBAAiB,EAAE,MAAM,CAAA;IACzB,QAAQ,EAAE;QACR,cAAc,EAAE,MAAM,CAAA;QACtB,oBAAoB,EAAE,MAAM,CAAA;QAC5B,qBAAqB,EAAE,MAAM,CAAA;QAC7B,2BAA2B,EAAE,MAAM,CAAA;QACnC,gBAAgB,EAAE,MAAM,CAAA;QACxB,sBAAsB,EAAE,MAAM,CAAA;QAC9B,iBAAiB,EAAE,MAAM,CAAA;QACzB,uBAAuB,EAAE,MAAM,CAAA;QAC/B,sBAAsB,EAAE,MAAM,CAAA;QAC9B,sBAAsB,EAAE,MAAM,CAAA;QAC9B,iBAAiB,EAAE,MAAM,CAAA;QACzB,iBAAiB,EAAE,MAAM,CAAA;QACzB,sBAAsB,EAAE,MAAM,CAAA;QAC9B,mBAAmB,EAAE,MAAM,CAAA;QAC3B,kBAAkB,EAAE,MAAM,CAAA;QAC1B,iBAAiB,EAAE,MAAM,CAAA;QACzB,cAAc,EAAE,MAAM,CAAA;QACtB,cAAc,EAAE,MAAM,CAAA;QACtB,mBAAmB,EAAE,MAAM,CAAA;QAC3B,cAAc,EAAE,MAAM,CAAA;QACtB,eAAe,EAAE,MAAM,CAAA;KACxB,CAAA;CACF;AAED,wBAAgB,oBAAoB,CAAC,EACnC,QAAQ,EACR,QAAQ,EACR,gBAAgB,EAChB,qBAAqB,EAAE,6BAA6B,EACpD,cAAc,EAAE,sBAAsB,EACtC,gBAAgB,EAAE,wBAAwB,EAC1C,uBAAuB,EAAE,+BAA+B,EACxD,aAAa,EACb,oBAAoB,EACpB,iCAAiC,EACjC,sCAAsC,EAAE,8CAA8C,EACtF,MAAM,EACN,SAAS,EACT,aAAa,EACb,gBAAgB,EAChB,UAAU,EACV,cAAc,EACd,UAAU,EACV,aAAa,EACb,aAAa,EACb,WAAkB,GACnB,EAAE;IACD,QAAQ,EAAE,4BAA4B,CAAA;IACtC,QAAQ,EAAE,aAAa,EAAE,CAAA;IACzB,gBAAgB,EAAE,mBAAmB,EAAE,CAAA;IACvC,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,aAAa,EAAE,mBAAmB,EAAE,CAAA;IACpC,oBAAoB,EAAE,0BAA0B,EAAE,CAAA;IAClD,iCAAiC,EAAE,aAAa,EAAE,CAAA;IAClD,sCAAsC,CAAC,EAAE,MAAM,CAAA;IAC/C,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,aAAa,EAAE,MAAM,CAAA;IACrB,gBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACzC,UAAU,EAAE,OAAO,CAAA;IACnB,cAAc,EAAE,MAAM,IAAI,CAAA;IAC1B,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;IACpC,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;IAC1C,aAAa,CAAC,EAAE,MAAM,IAAI,CAAA;IAC1B,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB,2CA0KA"}
@@ -11,23 +11,25 @@ function interpolate(template, values) {
11
11
  return value === undefined ? "" : String(value);
12
12
  });
13
13
  }
14
- export function AvailabilityOverview({ messages, products, constrainedSlots, openSlotsCount: providedOpenSlotsCount, filteredRules, filteredPickupPoints, productsWithoutUpcomingDepartures, search, setSearch, productFilter, setProductFilter, hasFilters, onClearFilters, onOpenSlot, onOpenProduct, onJumpToSlots, showFilters = true, }) {
14
+ export function AvailabilityOverview({ messages, products, constrainedSlots, constrainedSlotsCount: providedConstrainedSlotsCount, openSlotsCount: providedOpenSlotsCount, activeRulesCount: providedActiveRulesCount, activePickupPointsCount: providedActivePickupPointsCount, filteredRules, filteredPickupPoints, productsWithoutUpcomingDepartures, productsWithoutUpcomingDeparturesCount: providedProductsWithoutUpcomingDeparturesCount, search, setSearch, productFilter, setProductFilter, hasFilters, onClearFilters, onOpenSlot, onOpenProduct, onJumpToSlots, showFilters = true, }) {
15
15
  useAvailabilityUiMessagesOrDefault();
16
16
  const openSlotsCount = providedOpenSlotsCount ?? constrainedSlots.filter((slot) => slot.status === "open").length;
17
- const activeRulesCount = filteredRules.filter((rule) => rule.active).length;
18
- const activePickupPointsCount = filteredPickupPoints.filter((pickupPoint) => pickupPoint.active).length;
19
- const noDeparturesCount = productsWithoutUpcomingDepartures.length;
17
+ const constrainedSlotsCount = providedConstrainedSlotsCount ?? constrainedSlots.length;
18
+ const activeRulesCount = providedActiveRulesCount ?? filteredRules.filter((rule) => rule.active).length;
19
+ const activePickupPointsCount = providedActivePickupPointsCount ??
20
+ filteredPickupPoints.filter((pickupPoint) => pickupPoint.active).length;
21
+ const noDeparturesCount = providedProductsWithoutUpcomingDeparturesCount ?? productsWithoutUpcomingDepartures.length;
20
22
  const hasNoDeparturesProducts = noDeparturesCount > 0;
21
- const hasConstrainedSlots = constrainedSlots.length > 0;
23
+ const hasConstrainedSlots = constrainedSlotsCount > 0;
22
24
  const hasAttention = hasNoDeparturesProducts || hasConstrainedSlots;
23
- return (_jsxs(_Fragment, { children: [hasNoDeparturesProducts ? (_jsxs("div", { className: "flex flex-col gap-3 rounded-lg border border-amber-300 bg-amber-50 p-4 text-amber-900 sm:flex-row sm:items-center sm:justify-between dark:border-amber-700 dark:bg-amber-950/40 dark:text-amber-100", children: [_jsxs("div", { className: "flex items-start gap-3", children: [_jsx(AlertTriangle, { className: "mt-0.5 h-5 w-5 shrink-0" }), _jsxs("div", { className: "space-y-1", children: [_jsx("div", { className: "font-medium", children: messages.overview.actionRequiredTitle }), _jsx("p", { className: "text-sm text-amber-900/80 dark:text-amber-100/80", children: interpolate(messages.overview.actionRequiredBody, { count: noDeparturesCount }) })] })] }), onJumpToSlots ? (_jsx(Button, { size: "sm", className: "self-start sm:self-auto", onClick: onJumpToSlots, children: messages.overview.actionRequiredCta })) : null] })) : null, _jsxs("div", { className: "grid gap-3 grid-cols-2 xl:grid-cols-4", children: [_jsx(OverviewMetric, { title: messages.overview.openSlotsTitle, value: openSlotsCount, description: messages.overview.openSlotsDescription, icon: CalendarDays }), _jsx(OverviewMetric, { title: messages.overview.constrainedSlotsTitle, value: constrainedSlots.length, description: messages.overview.constrainedSlotsDescription, icon: Clock3 }), _jsx(OverviewMetric, { title: messages.overview.activeRulesTitle, value: activeRulesCount, description: messages.overview.activeRulesDescription, icon: Package }), _jsx(OverviewMetric, { title: messages.overview.pickupPointsTitle, value: activePickupPointsCount, description: messages.overview.pickupPointsDescription, icon: Truck })] }), _jsxs(Card, { size: "sm", children: [_jsxs(CardHeader, { className: "flex flex-row items-center justify-between gap-3", children: [_jsxs(CardTitle, { className: "flex items-center gap-2 text-sm", children: [messages.overview.attentionTitle, hasAttention ? (_jsx(Badge, { variant: "secondary", className: "tabular-nums", children: noDeparturesCount + constrainedSlots.length })) : null] }), !hasAttention ? (_jsxs("span", { className: "flex items-center gap-1.5 text-xs text-emerald-600 dark:text-emerald-400", children: [_jsx(CheckCircle2, { className: "h-4 w-4" }), messages.overview.attentionEmpty.split(".")[0]] })) : null] }), _jsx(CardContent, { className: "grid gap-3 lg:grid-cols-2", children: hasAttention ? (_jsxs(_Fragment, { children: [_jsx(AttentionColumn, { title: messages.overview.coverageGapsTitle, count: noDeparturesCount, items: productsWithoutUpcomingDepartures.slice(0, 4).map((product) => ({
25
+ return (_jsxs(_Fragment, { children: [hasNoDeparturesProducts ? (_jsxs("div", { className: "flex flex-col gap-3 rounded-lg border border-amber-300 bg-amber-50 p-4 text-amber-900 sm:flex-row sm:items-center sm:justify-between dark:border-amber-700 dark:bg-amber-950/40 dark:text-amber-100", children: [_jsxs("div", { className: "flex items-start gap-3", children: [_jsx(AlertTriangle, { className: "mt-0.5 h-5 w-5 shrink-0" }), _jsxs("div", { className: "space-y-1", children: [_jsx("div", { className: "font-medium", children: messages.overview.actionRequiredTitle }), _jsx("p", { className: "text-sm text-amber-900/80 dark:text-amber-100/80", children: interpolate(messages.overview.actionRequiredBody, { count: noDeparturesCount }) })] })] }), onJumpToSlots ? (_jsx(Button, { size: "sm", className: "self-start sm:self-auto", onClick: onJumpToSlots, children: messages.overview.actionRequiredCta })) : null] })) : null, _jsxs("div", { className: "grid gap-3 grid-cols-2 xl:grid-cols-4", children: [_jsx(OverviewMetric, { title: messages.overview.openSlotsTitle, value: openSlotsCount, description: messages.overview.openSlotsDescription, icon: CalendarDays }), _jsx(OverviewMetric, { title: messages.overview.constrainedSlotsTitle, value: constrainedSlotsCount, description: messages.overview.constrainedSlotsDescription, icon: Clock3 }), _jsx(OverviewMetric, { title: messages.overview.activeRulesTitle, value: activeRulesCount, description: messages.overview.activeRulesDescription, icon: Package }), _jsx(OverviewMetric, { title: messages.overview.pickupPointsTitle, value: activePickupPointsCount, description: messages.overview.pickupPointsDescription, icon: Truck })] }), _jsxs(Card, { size: "sm", children: [_jsxs(CardHeader, { className: "flex flex-row items-center justify-between gap-3", children: [_jsxs(CardTitle, { className: "flex items-center gap-2 text-sm", children: [messages.overview.attentionTitle, hasAttention ? (_jsx(Badge, { variant: "secondary", className: "tabular-nums", children: noDeparturesCount + constrainedSlotsCount })) : null] }), !hasAttention ? (_jsxs("span", { className: "flex items-center gap-1.5 text-xs text-emerald-600 dark:text-emerald-400", children: [_jsx(CheckCircle2, { className: "h-4 w-4" }), messages.overview.attentionEmpty.split(".")[0]] })) : null] }), _jsx(CardContent, { className: "grid gap-3 lg:grid-cols-2", children: hasAttention ? (_jsxs(_Fragment, { children: [_jsx(AttentionColumn, { title: messages.overview.coverageGapsTitle, count: noDeparturesCount, items: productsWithoutUpcomingDepartures.slice(0, 4).map((product) => ({
24
26
  id: product.id,
25
27
  primary: product.name,
26
28
  secondary: messages.overview.coverageGapDescription,
27
29
  severityLabel: messages.overview.severityCoverageGap,
28
30
  severityTone: "destructive",
29
31
  onClick: () => onOpenProduct(product.id),
30
- })), emptyMessage: messages.overview.coverageGapsEmpty }), _jsx(AttentionColumn, { title: messages.overview.capacityWatchlistTitle, count: constrainedSlots.length, items: constrainedSlots.slice(0, 4).map((slot) => ({
32
+ })), emptyMessage: messages.overview.coverageGapsEmpty }), _jsx(AttentionColumn, { title: messages.overview.capacityWatchlistTitle, count: constrainedSlotsCount, items: constrainedSlots.slice(0, 4).map((slot) => ({
31
33
  id: slot.id,
32
34
  primary: `${productNameById(products, slot.productId, slot.productName)} · ${slot.dateLocal}`,
33
35
  secondary: `${formatDateTime(slot.startsAt)} · ${messages.remainingPaxLabel}: ${slot.remainingPax ?? messages.details.noValue}`,
@@ -1 +1 @@
1
- {"version":3,"file":"availability-page.d.ts","sourceRoot":"","sources":["../../src/components/availability-page.tsx"],"names":[],"mappings":"AAIA,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,0BAA0B,EAE/B,KAAK,mBAAmB,EAmBzB,MAAM,8BAA8B,CAAA;AAmBrC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAItC,OAAO,EAEL,KAAK,iCAAiC,EAEtC,KAAK,oCAAoC,EAEzC,KAAK,6BAA6B,EAElC,KAAK,6BAA6B,EAElC,KAAK,kCAAkC,EACxC,MAAM,2BAA2B,CAAA;AAGlC,OAAO,EACL,KAAK,wBAAwB,EAC7B,KAAK,wBAAwB,EAM9B,MAAM,wBAAwB,CAAA;AAE/B,MAAM,MAAM,mBAAmB,GAC3B,OAAO,GACP,OAAO,GACP,aAAa,GACb,WAAW,GACX,eAAe,GACf,UAAU,CAAA;AAEd,MAAM,MAAM,4BAA4B,GAAG,KAAK,GAAG,QAAQ,GAAG,UAAU,CAAA;AACxE,MAAM,MAAM,gCAAgC,GAAG,KAAK,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAA;AAEpF,MAAM,MAAM,iCAAiC,GAAG,wBAAwB,CAAA;AACxE,MAAM,MAAM,iCAAiC,GAAG,wBAAwB,CAAA;AAExE,KAAK,mBAAmB,GAAG;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAE9D,MAAM,MAAM,iCAAiC,GAAG,CAC9C,OAAO,EAAE,6BAA6B,EACtC,OAAO,EAAE,mBAAmB,KACzB,OAAO,CAAC,IAAI,CAAC,CAAA;AAElB,MAAM,MAAM,sCAAsC,GAAG,CACnD,OAAO,EAAE,kCAAkC,EAC3C,OAAO,EAAE,mBAAmB,KACzB,OAAO,CAAC,IAAI,CAAC,CAAA;AAElB,MAAM,MAAM,iCAAiC,GAAG,CAC9C,OAAO,EAAE,6BAA6B,EACtC,OAAO,EAAE,mBAAmB,KACzB,OAAO,CAAC,IAAI,CAAC,CAAA;AAElB,MAAM,MAAM,qCAAqC,GAAG,CAClD,OAAO,EAAE,iCAAiC,EAC1C,OAAO,EAAE,mBAAmB,KACzB,OAAO,CAAC,IAAI,CAAC,CAAA;AAElB,MAAM,MAAM,wCAAwC,GAAG,CACrD,OAAO,EAAE,oCAAoC,EAC7C,OAAO,EAAE,mBAAmB,KACzB,OAAO,CAAC,IAAI,CAAC,CAAA;AAElB,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB,cAAc,CAAC,EAAE,SAAS,CAAA;IAC1B,aAAa,CAAC,EAAE,SAAS,CAAA;IACzB,UAAU,CAAC,EAAE,SAAS,CAAA;IACtB,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB,OAAO,CAAC,EAAE,SAAS,CAAA;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,mBAAmB,CAAA;IAChC,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,YAAY,EAAE,iCAAiC,CAAA;IAC/C,YAAY,EAAE,iCAAiC,CAAA;IAC/C,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;IACrC,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;IACrC,eAAe,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAA;IAC/C,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;IAC3C,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAA;IAC7B,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,uBAAuB,KAAK,IAAI,CAAA;IAC5D,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAA;IAChC,iBAAiB,CAAC,EAAE,CAAC,WAAW,EAAE,0BAA0B,KAAK,IAAI,CAAA;IACrE,YAAY,CAAC,EAAE,iCAAiC,CAAA;IAChD,iBAAiB,CAAC,EAAE,sCAAsC,CAAA;IAC1D,YAAY,CAAC,EAAE,iCAAiC,CAAA;IAChD,gBAAgB,CAAC,EAAE,qCAAqC,CAAA;IACxD,mBAAmB,CAAC,EAAE,wCAAwC,CAAA;IAC9D,KAAK,CAAC,EAAE,qBAAqB,CAAA;CAC9B;AAOD,wBAAgB,gBAAgB,CAAC,EAC/B,SAAS,EACT,UAAoB,EACpB,gBAAuB,EACvB,YAAY,EACZ,YAAY,EACZ,UAAmB,EACnB,UAAmB,EACnB,eAAwB,EACxB,aAAsB,EACtB,gBAAuB,EACvB,cAA6B,EAC7B,mBAA0B,EAC1B,iBAAmC,EACnC,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACnB,KAAK,EAAE,SAAS,GACjB,EAAE,qBAAqB,2CAkevB"}
1
+ {"version":3,"file":"availability-page.d.ts","sourceRoot":"","sources":["../../src/components/availability-page.tsx"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { useQueryClient } from "@tanstack/react-query";
4
- import { availabilityQueryKeys, useAvailabilityRuleMutation, useAvailabilitySlotMutation, useAvailabilityStartTimeMutation, useCloseouts, usePickupPoints, useProducts, useRules, useSlots, useStartTimes, } from "@voyantjs/availability-react";
4
+ import { availabilityQueryKeys, useAvailabilityOverview, useAvailabilityRuleMutation, useAvailabilitySlotMutation, useAvailabilityStartTimeMutation, useCloseouts, usePickupPoints, useProducts, useRules, useSlots, useStartTimes, } from "@voyantjs/availability-react";
5
5
  import { Button, cn, Label } from "@voyantjs/ui/components";
6
6
  import { AsyncCombobox } from "@voyantjs/ui/components/async-combobox";
7
7
  import { CalendarProvider, CalendarView, } from "@voyantjs/ui/components/big-calendar";
@@ -51,6 +51,10 @@ export function AvailabilityPage({ className, defaultTab = "slots", bulkActionTa
51
51
  const [editingCloseout, setEditingCloseout] = useState();
52
52
  const [editingPickupPoint, setEditingPickupPoint] = useState();
53
53
  const productsQuery = useProducts({ search: productSearch || undefined, limit: 25, offset: 0 });
54
+ const overviewQuery = useAvailabilityOverview({
55
+ productId: productFilter === "all" ? undefined : productFilter,
56
+ attentionLimit: 4,
57
+ });
54
58
  const rulesQuery = useRules({ limit: 25, offset: 0 });
55
59
  const startTimesQuery = useStartTimes({ limit: 25, offset: 0 });
56
60
  const slotsQuery = useSlots({ limit: 25, offset: 0 });
@@ -62,6 +66,7 @@ export function AvailabilityPage({ className, defaultTab = "slots", bulkActionTa
62
66
  const availabilitySlots = slotsQuery.data?.data ?? [];
63
67
  const closeouts = closeoutsQuery.data?.data ?? [];
64
68
  const pickupPoints = pickupPointsQuery.data?.data ?? [];
69
+ const overview = overviewQuery.data?.data;
65
70
  const matchesProduct = (productId) => productFilter === "all" || productId === productFilter;
66
71
  const matchesActive = (active, filter) => filter === "all" || (filter === "active" ? active : !active);
67
72
  const matchesDateRange = (date, range) => (!range?.from || date >= range.from) && (!range?.to || date <= range.to); // i18n-literal-ok comparison expression
@@ -98,7 +103,7 @@ export function AvailabilityPage({ className, defaultTab = "slots", bulkActionTa
98
103
  color: slotStatusToColor[slot.status],
99
104
  };
100
105
  });
101
- const queries = [
106
+ const primaryQueries = [
102
107
  productsQuery,
103
108
  rulesQuery,
104
109
  startTimesQuery,
@@ -106,8 +111,8 @@ export function AvailabilityPage({ className, defaultTab = "slots", bulkActionTa
106
111
  closeoutsQuery,
107
112
  pickupPointsQuery,
108
113
  ];
109
- const isLoading = queries.some((query) => query.isPending);
110
- const isError = queries.some((query) => query.isError);
114
+ const isLoading = primaryQueries.some((query) => query.isPending);
115
+ const isError = primaryQueries.some((query) => query.isError);
111
116
  const refreshAll = async () => {
112
117
  await queryClient.invalidateQueries({ queryKey: availabilityQueryKeys.all });
113
118
  };
@@ -164,7 +169,7 @@ export function AvailabilityPage({ className, defaultTab = "slots", bulkActionTa
164
169
  setPickupPointDialogOpen(false);
165
170
  setEditingPickupPoint(undefined);
166
171
  };
167
- return (_jsxs("div", { className: cn("flex flex-col gap-6 p-6", className), children: [_jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-start md:justify-between", children: [_jsxs("div", { children: [_jsx("h1", { className: "text-2xl font-bold tracking-tight", children: messages.title }), _jsx("p", { className: "text-sm text-muted-foreground", children: messages.description })] }), _jsxs("div", { className: "flex w-full flex-col gap-3 md:w-72", children: [_jsx(AsyncCombobox, { value: productFilter === "all" ? null : productFilter, onChange: (value) => setProductFilter(value ?? "all"), items: products, selectedItem: selectedProduct, getKey: (product) => product.id, getLabel: (product) => product.name, onSearchChange: setProductSearch, placeholder: messages.allProducts, emptyText: productsQuery.isFetching ? page.loading : page.filters.productSearchEmpty, triggerClassName: "w-full" }), pageSlots?.headerEnd] })] }), isLoading ? (_jsx(AvailabilityBodySkeleton, {})) : isError ? (_jsx("div", { className: "rounded-md border p-6 text-sm text-muted-foreground", children: page.loadFailed })) : (_jsxs(_Fragment, { children: [pageSlots?.beforeOverview, _jsx(AvailabilityOverview, { messages: messages, products: products, constrainedSlots: constrainedSlots, openSlotsCount: filteredSlots.filter((slot) => slot.status === "open").length, filteredRules: filteredRules, filteredPickupPoints: filteredPickupPoints, productsWithoutUpcomingDepartures: productsWithoutUpcomingDepartures, search: "", setSearch: () => { }, productFilter: productFilter, setProductFilter: setProductFilter, hasFilters: hasFilters, onClearFilters: () => setProductFilter("all"), onOpenSlot: onSlotOpen, onOpenProduct: onProductOpen, onJumpToSlots: () => setActiveTab("slots"), showFilters: false }), pageSlots?.afterOverview, pageSlots?.beforeTabs, _jsxs(Tabs, { value: activeTab, onValueChange: (value) => setActiveTab((value ?? "slots")), children: [_jsxs(TabsList, { className: "flex w-full justify-start overflow-x-auto", children: [_jsx(TabsTrigger, { value: "slots", children: messages.tabSlots }), _jsx(TabsTrigger, { value: "rules", children: messages.tabRules }), _jsx(TabsTrigger, { value: "start-times", children: messages.tabStartTimes }), _jsx(TabsTrigger, { value: "closeouts", children: messages.tabCloseouts }), _jsx(TabsTrigger, { value: "pickup-points", children: messages.tabPickupPoints }), _jsx(TabsTrigger, { value: "calendar", children: page.calendarTab })] }), _jsx(AvailabilitySlotsTab, { messages: messages, products: products, filteredSlots: filteredSlots, slotSelection: slotSelection, setSlotSelection: setSlotSelection, bulkActionTarget: bulkActionTarget, handleBulkUpdate: onBulkUpdate, handleBulkDelete: onBulkDelete, onCreate: () => {
172
+ return (_jsxs("div", { className: cn("flex flex-col gap-6 p-6", className), children: [_jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-start md:justify-between", children: [_jsxs("div", { children: [_jsx("h1", { className: "text-2xl font-bold tracking-tight", children: messages.title }), _jsx("p", { className: "text-sm text-muted-foreground", children: messages.description })] }), _jsxs("div", { className: "flex w-full flex-col gap-3 md:w-72", children: [_jsx(AsyncCombobox, { value: productFilter === "all" ? null : productFilter, onChange: (value) => setProductFilter(value ?? "all"), items: products, selectedItem: selectedProduct, getKey: (product) => product.id, getLabel: (product) => product.name, onSearchChange: setProductSearch, placeholder: messages.allProducts, emptyText: productsQuery.isFetching ? page.loading : page.filters.productSearchEmpty, triggerClassName: "w-full" }), pageSlots?.headerEnd] })] }), isLoading ? (_jsx(AvailabilityBodySkeleton, {})) : isError ? (_jsx("div", { className: "rounded-md border p-6 text-sm text-muted-foreground", children: page.loadFailed })) : (_jsxs(_Fragment, { children: [pageSlots?.beforeOverview, _jsx(AvailabilityOverview, { messages: messages, products: products, constrainedSlots: overview?.constrainedSlots ?? constrainedSlots, constrainedSlotsCount: overview?.constrainedSlotsCount, openSlotsCount: overview?.openSlotsCount, activeRulesCount: overview?.activeRulesCount, activePickupPointsCount: overview?.activePickupPointsCount, filteredRules: filteredRules, filteredPickupPoints: filteredPickupPoints, productsWithoutUpcomingDepartures: overview?.productsWithoutUpcomingDepartures ?? productsWithoutUpcomingDepartures, productsWithoutUpcomingDeparturesCount: overview?.productsWithoutUpcomingDeparturesCount, search: "", setSearch: () => { }, productFilter: productFilter, setProductFilter: setProductFilter, hasFilters: hasFilters, onClearFilters: () => setProductFilter("all"), onOpenSlot: onSlotOpen, onOpenProduct: onProductOpen, onJumpToSlots: () => setActiveTab("slots"), showFilters: false }), pageSlots?.afterOverview, pageSlots?.beforeTabs, _jsxs(Tabs, { value: activeTab, onValueChange: (value) => setActiveTab((value ?? "slots")), children: [_jsxs(TabsList, { className: "flex w-full justify-start overflow-x-auto", children: [_jsx(TabsTrigger, { value: "slots", children: messages.tabSlots }), _jsx(TabsTrigger, { value: "rules", children: messages.tabRules }), _jsx(TabsTrigger, { value: "start-times", children: messages.tabStartTimes }), _jsx(TabsTrigger, { value: "closeouts", children: messages.tabCloseouts }), _jsx(TabsTrigger, { value: "pickup-points", children: messages.tabPickupPoints }), _jsx(TabsTrigger, { value: "calendar", children: page.calendarTab })] }), _jsx(AvailabilitySlotsTab, { messages: messages, products: products, filteredSlots: filteredSlots, slotSelection: slotSelection, setSlotSelection: setSlotSelection, bulkActionTarget: bulkActionTarget, handleBulkUpdate: onBulkUpdate, handleBulkDelete: onBulkDelete, onCreate: () => {
168
173
  setEditingSlot(undefined);
169
174
  setSlotDialogOpen(true);
170
175
  }, onOpenRoute: onSlotOpen, onEdit: (row) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voyantjs/availability-ui",
3
- "version": "0.66.0",
3
+ "version": "0.68.0",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -42,8 +42,8 @@
42
42
  "react-dom": "^19.0.0",
43
43
  "react-hook-form": "^7.72.1",
44
44
  "zod": "^4.3.6",
45
- "@voyantjs/availability-react": "0.66.0",
46
- "@voyantjs/ui": "0.66.0"
45
+ "@voyantjs/availability-react": "0.68.0",
46
+ "@voyantjs/ui": "0.68.0"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@tanstack/react-query": "^5.100.11",
@@ -57,13 +57,13 @@
57
57
  "typescript": "^6.0.2",
58
58
  "vitest": "^4.1.2",
59
59
  "zod": "^4.3.6",
60
- "@voyantjs/availability-react": "0.66.0",
61
- "@voyantjs/i18n": "0.66.0",
62
- "@voyantjs/ui": "0.66.0",
60
+ "@voyantjs/availability-react": "0.68.0",
61
+ "@voyantjs/i18n": "0.68.0",
62
+ "@voyantjs/ui": "0.68.0",
63
63
  "@voyantjs/voyant-typescript-config": "0.1.0"
64
64
  },
65
65
  "dependencies": {
66
- "@voyantjs/i18n": "0.66.0"
66
+ "@voyantjs/i18n": "0.68.0"
67
67
  },
68
68
  "files": [
69
69
  "dist",