@voyantjs/products-ui 0.52.2 → 0.52.4

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.
@@ -0,0 +1,17 @@
1
+ export interface ProductActionLedgerCardProps {
2
+ productId: string;
3
+ limit?: number;
4
+ messages?: Partial<ProductActionLedgerCardMessages>;
5
+ className?: string;
6
+ }
7
+ export interface ProductActionLedgerCardMessages {
8
+ title: string;
9
+ description: string;
10
+ loadOlder: string;
11
+ empty: string;
12
+ loadFailed: string;
13
+ }
14
+ export declare function ProductActionLedgerCard({ productId, limit, messages: messagesOverride, className, }: ProductActionLedgerCardProps): import("react/jsx-runtime").JSX.Element;
15
+ export declare const actionLedgerStatusVariant: Record<string, "default" | "secondary" | "outline" | "destructive">;
16
+ export declare const actionLedgerRiskVariant: Record<string, "default" | "secondary" | "outline" | "destructive">;
17
+ //# sourceMappingURL=product-action-ledger-card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product-action-ledger-card.d.ts","sourceRoot":"","sources":["../../src/components/product-action-ledger-card.tsx"],"names":[],"mappings":"AAeA,MAAM,WAAW,4BAA4B;IAC3C,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC,+BAA+B,CAAC,CAAA;IACnD,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,+BAA+B;IAC9C,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;CACnB;AAUD,wBAAgB,uBAAuB,CAAC,EACtC,SAAS,EACT,KAAU,EACV,QAAQ,EAAE,gBAAgB,EAC1B,SAAS,GACV,EAAE,4BAA4B,2CAiE9B;AA4ED,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAC5C,MAAM,EACN,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,aAAa,CAapD,CAAA;AAED,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAC1C,MAAM,EACN,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,aAAa,CAMpD,CAAA"}
@@ -0,0 +1,73 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useProductActionLedger } from "@voyantjs/products-react";
4
+ import { Badge } from "@voyantjs/ui/components/badge";
5
+ import { Button } from "@voyantjs/ui/components/button";
6
+ import { cn } from "@voyantjs/ui/lib/utils";
7
+ import { Activity, Loader2 } from "lucide-react";
8
+ import { useEffect, useState } from "react";
9
+ import { useProductsUiI18nOrDefault } from "../i18n/provider.js";
10
+ const defaultProductActionLedgerCardMessages = {
11
+ title: "Activity", // i18n-literal-ok: package-owned fallback copy; callers can override.
12
+ description: "Recent product edits and the actor that made them.", // i18n-literal-ok: package-owned fallback copy; callers can override.
13
+ loadOlder: "Load older activity", // i18n-literal-ok: package-owned fallback copy; callers can override.
14
+ empty: "No product activity recorded.", // i18n-literal-ok: package-owned fallback copy; callers can override.
15
+ loadFailed: "Failed to load product activity.", // i18n-literal-ok: package-owned fallback copy; callers can override.
16
+ };
17
+ export function ProductActionLedgerCard({ productId, limit = 20, messages: messagesOverride, className, }) {
18
+ const messages = { ...defaultProductActionLedgerCardMessages, ...messagesOverride };
19
+ const [cursor, setCursor] = useState(null);
20
+ const actionLedgerQuery = useProductActionLedger(productId, { cursor, limit });
21
+ const { formatDateTime } = useProductsUiI18nOrDefault();
22
+ const [pages, setPages] = useState([]);
23
+ useEffect(() => {
24
+ const page = actionLedgerQuery.data;
25
+ if (!page)
26
+ return;
27
+ setPages((currentPages) => {
28
+ if (currentPages.some((currentPage) => currentPage.data[0]?.id === page.data[0]?.id)) {
29
+ return currentPages;
30
+ }
31
+ return cursor ? [...currentPages, page] : [page];
32
+ });
33
+ }, [actionLedgerQuery.data, cursor]);
34
+ const entries = pages.flatMap((page) => page.data);
35
+ const nextCursor = pages.at(-1)?.pageInfo.nextCursor ?? null;
36
+ return (_jsx(ActionLedgerSection, { title: messages.title, description: messages.description, className: className, children: actionLedgerQuery.isPending && entries.length === 0 ? (_jsx(ActionLedgerLoadingRow, {})) : actionLedgerQuery.isError && entries.length === 0 ? (_jsx(ActionLedgerEmptyRow, { children: messages.loadFailed })) : entries.length === 0 ? (_jsx(ActionLedgerEmptyRow, { children: messages.empty })) : (_jsxs("div", { className: "flex flex-col gap-3", children: [_jsx("ul", { className: "divide-y rounded-md border bg-background", children: entries.map((entry) => (_jsx(ProductActionLedgerEntryItem, { entry: entry, timestamp: formatDateTime(entry.occurredAt) }, entry.id))) }), nextCursor ? (_jsxs(Button, { type: "button", variant: "outline", size: "sm", className: "self-start", disabled: actionLedgerQuery.isFetching, onClick: () => setCursor(nextCursor), children: [actionLedgerQuery.isFetching ? (_jsx(Loader2, { className: "size-4 animate-spin", "aria-hidden": "true" })) : null, messages.loadOlder] })) : null] })) }));
37
+ }
38
+ function ProductActionLedgerEntryItem({ entry, timestamp, }) {
39
+ return (_jsxs("li", { className: "flex items-start gap-3 p-3", children: [_jsx(Activity, { className: "mt-0.5 size-4 shrink-0 text-muted-foreground", "aria-hidden": "true" }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("p", { className: "truncate font-medium text-sm", children: formatActionLedgerName(entry.actionName) }), _jsx(Badge, { variant: actionLedgerStatusVariant[entry.status] ?? "secondary", children: entry.status.replace(/_/g, " ") }), _jsx(Badge, { variant: actionLedgerRiskVariant[entry.evaluatedRisk] ?? "outline", children: entry.evaluatedRisk })] }), _jsxs("p", { className: "mt-1 text-muted-foreground text-xs", children: [entry.principalType, ":", entry.principalId, " - ", timestamp] }), entry.mutationSummary ? (_jsx("p", { className: "mt-1 truncate text-muted-foreground text-xs", children: entry.mutationSummary })) : null] })] }));
40
+ }
41
+ function ActionLedgerSection({ title, description, children, className, }) {
42
+ return (_jsxs("section", { "data-slot": "product-action-ledger-card", className: cn("rounded-md border bg-background", className), children: [_jsxs("div", { className: "space-y-1 border-b px-4 py-3", children: [_jsx("h2", { className: "font-semibold text-sm", children: title }), _jsx("p", { className: "text-muted-foreground text-xs", children: description })] }), _jsx("div", { className: "p-4", children: children })] }));
43
+ }
44
+ function ActionLedgerEmptyRow({ children }) {
45
+ return _jsx("p", { className: "py-6 text-center text-sm text-muted-foreground", children: children });
46
+ }
47
+ function ActionLedgerLoadingRow() {
48
+ return (_jsx("div", { className: "flex justify-center py-6", children: _jsx(Loader2, { className: "size-5 animate-spin text-muted-foreground" }) }));
49
+ }
50
+ function formatActionLedgerName(actionName) {
51
+ const withoutDomain = actionName.replace(/^product\./, "");
52
+ const label = withoutDomain.replace(/[._-]/g, " ");
53
+ return label.charAt(0).toUpperCase() + label.slice(1);
54
+ }
55
+ export const actionLedgerStatusVariant = {
56
+ requested: "outline",
57
+ awaiting_approval: "secondary",
58
+ approved: "secondary",
59
+ denied: "destructive",
60
+ succeeded: "default",
61
+ failed: "destructive",
62
+ reversed: "secondary",
63
+ compensated: "secondary",
64
+ expired: "secondary",
65
+ cancelled: "secondary",
66
+ superseded: "secondary",
67
+ };
68
+ export const actionLedgerRiskVariant = {
69
+ low: "outline",
70
+ medium: "secondary",
71
+ high: "destructive",
72
+ critical: "destructive",
73
+ };
@@ -1,7 +1,6 @@
1
- import { type ProductDayServiceRecord, type ProductRecord } from "@voyantjs/products-react";
1
+ import { type ProductRecord } from "@voyantjs/products-react";
2
2
  import * as React from "react";
3
- import type { ProductDayServiceFormProps } from "./product-day-service-form.js";
4
- import { type ProductItineraryDayRowRenderContext } from "./product-itinerary-day-row.js";
3
+ import { type ProductItinerarySectionProps } from "./product-itinerary-section.js";
5
4
  import { type ProductMediaSectionProps } from "./product-media-section.js";
6
5
  import { type ProductOptionsSectionProps } from "./product-options-section.js";
7
6
  export interface ProductDetailPageSlots {
@@ -23,10 +22,10 @@ export interface ProductDetailPageProps {
23
22
  onDeleted?: () => void;
24
23
  uploadMedia?: ProductMediaSectionProps["uploadMedia"];
25
24
  renderOptionDetails?: ProductOptionsSectionProps["renderOptionDetails"];
26
- renderItineraryDayDetails?: (context: ProductItineraryDayRowRenderContext) => React.ReactNode;
27
- renderItineraryServiceActions?: (service: ProductDayServiceRecord) => React.ReactNode;
28
- renderSupplierServiceField?: ProductDayServiceFormProps["renderSupplierServiceField"];
29
- onSupplierServiceSelected?: ProductDayServiceFormProps["onSupplierServiceSelected"];
25
+ renderItineraryDayDetails?: ProductItinerarySectionProps["renderDayDetails"];
26
+ renderItineraryServiceActions?: ProductItinerarySectionProps["renderServiceActions"];
27
+ renderSupplierServiceField?: ProductItinerarySectionProps["renderSupplierServiceField"];
28
+ onSupplierServiceSelected?: ProductItinerarySectionProps["onSupplierServiceSelected"];
30
29
  slots?: ProductDetailPageSlots;
31
30
  }
32
31
  export declare function ProductDetailPage({ id, className, onBack, onBookingCreate, onDeleted, uploadMedia, renderOptionDetails, renderItineraryDayDetails, renderItineraryServiceActions, renderSupplierServiceField, onSupplierServiceSelected, slots, }: ProductDetailPageProps): import("react/jsx-runtime").JSX.Element;
@@ -52,15 +51,4 @@ export interface ProductDetailSidebarProps {
52
51
  className?: string;
53
52
  }
54
53
  export declare function ProductDetailSidebar({ product, className }: ProductDetailSidebarProps): import("react/jsx-runtime").JSX.Element;
55
- export interface ProductItinerarySectionProps {
56
- productId: string;
57
- title?: string;
58
- description?: string;
59
- renderDayDetails?: (context: ProductItineraryDayRowRenderContext) => React.ReactNode;
60
- renderServiceActions?: (service: ProductDayServiceRecord) => React.ReactNode;
61
- renderSupplierServiceField?: ProductDayServiceFormProps["renderSupplierServiceField"];
62
- onSupplierServiceSelected?: ProductDayServiceFormProps["onSupplierServiceSelected"];
63
- className?: string;
64
- }
65
- export declare function ProductItinerarySection({ productId, title, description, renderDayDetails, renderServiceActions, renderSupplierServiceField, onSupplierServiceSelected, className, }: ProductItinerarySectionProps): import("react/jsx-runtime").JSX.Element;
66
54
  //# sourceMappingURL=product-detail-page.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"product-detail-page.d.ts","sourceRoot":"","sources":["../../src/components/product-detail-page.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"product-detail-page.d.ts","sourceRoot":"","sources":["../../src/components/product-detail-page.tsx"],"names":[],"mappings":"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"}
@@ -1,19 +1,16 @@
1
1
  "use client";
2
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
- import { useProduct, useProductDayMutation, useProductDayServiceMutation, useProductItineraries, useProductItineraryDays, useProductItineraryMutation, useProductMutation, } from "@voyantjs/products-react";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useProduct, useProductMutation } from "@voyantjs/products-react";
4
4
  import { Badge } from "@voyantjs/ui/components/badge";
5
5
  import { Button } from "@voyantjs/ui/components/button";
6
6
  import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@voyantjs/ui/components/card";
7
- import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@voyantjs/ui/components/select";
8
7
  import { cn } from "@voyantjs/ui/lib/utils";
9
- import { ArrowLeft, Edit, FileText, Loader2, Plus, ReceiptText, Trash2 } from "lucide-react";
8
+ import { ArrowLeft, Edit, FileText, Loader2, ReceiptText, Trash2 } from "lucide-react";
10
9
  import * as React from "react";
11
10
  import { useProductsUiI18nOrDefault, useProductsUiMessagesOrDefault } from "../i18n/provider.js";
12
- import { ProductDayDialog } from "./product-day-dialog.js";
13
- import { ProductDayServiceDialog } from "./product-day-service-dialog.js";
11
+ import { ProductActionLedgerCard } from "./product-action-ledger-card.js";
14
12
  import { ProductDialog } from "./product-dialog.js";
15
- import { ProductItineraryDayRow, } from "./product-itinerary-day-row.js";
16
- import { ProductItineraryDialog } from "./product-itinerary-dialog.js";
13
+ import { ProductItinerarySection, } from "./product-itinerary-section.js";
17
14
  import { ProductMediaSection } from "./product-media-section.js";
18
15
  import { ProductOptionsSection, } from "./product-options-section.js";
19
16
  import { ProductVersionsSection } from "./product-versions-section.js";
@@ -46,7 +43,7 @@ export function ProductDetailPage({ id, className, onBack, onBookingCreate, onDe
46
43
  setDeleteError(error instanceof Error ? error.message : pageMessages.states.deleteFailed);
47
44
  }
48
45
  };
49
- return (_jsxs("div", { "data-slot": "product-detail-page", className: cn("flex flex-col gap-6 p-6", className), children: [_jsx(ProductDetailHeader, { product: product, onBack: onBack, onEdit: () => setEditOpen(true), onDelete: () => void handleDelete(), onBookingCreate: onBookingCreate ? () => onBookingCreate(product) : undefined, deleting: remove.isPending, actionsSlot: slots?.header }), deleteError ? _jsx("p", { className: "text-sm text-destructive", children: deleteError }) : null, slots?.afterHeader, _jsxs("div", { className: "grid gap-6 xl:grid-cols-[minmax(0,1fr)_320px]", children: [_jsxs("div", { className: "flex min-w-0 flex-col gap-6", children: [slots?.overviewStart, _jsx(ProductOverviewCard, { product: product }), _jsx(ProductCommercialCard, { product: product }), slots?.overviewEnd, _jsx(ProductMediaSection, { productId: product.id, uploadMedia: uploadMedia }), slots?.mediaEnd, _jsx(ProductItinerarySection, { productId: product.id, renderDayDetails: renderItineraryDayDetails, renderServiceActions: renderItineraryServiceActions, renderSupplierServiceField: renderSupplierServiceField, onSupplierServiceSelected: onSupplierServiceSelected }), slots?.itineraryEnd, _jsx(ProductOptionsSection, { productId: product.id, renderOptionDetails: renderOptionDetails }), slots?.optionsEnd, _jsx(ProductVersionsSection, { productId: product.id }), slots?.versionsEnd] }), _jsxs("div", { className: "flex min-w-0 flex-col gap-6", children: [_jsx(ProductDetailSidebar, { product: product }), slots?.sidebar] })] }), _jsx(ProductDialog, { open: editOpen, onOpenChange: setEditOpen, product: product, onSuccess: () => setEditOpen(false) })] }));
46
+ return (_jsxs("div", { "data-slot": "product-detail-page", className: cn("flex flex-col gap-6 p-6", className), children: [_jsx(ProductDetailHeader, { product: product, onBack: onBack, onEdit: () => setEditOpen(true), onDelete: () => void handleDelete(), onBookingCreate: onBookingCreate ? () => onBookingCreate(product) : undefined, deleting: remove.isPending, actionsSlot: slots?.header }), deleteError ? _jsx("p", { className: "text-sm text-destructive", children: deleteError }) : null, slots?.afterHeader, _jsxs("div", { className: "grid gap-6 xl:grid-cols-[minmax(0,1fr)_320px]", children: [_jsxs("div", { className: "flex min-w-0 flex-col gap-6", children: [slots?.overviewStart, _jsx(ProductOverviewCard, { product: product }), _jsx(ProductCommercialCard, { product: product }), slots?.overviewEnd, _jsx(ProductMediaSection, { productId: product.id, uploadMedia: uploadMedia }), slots?.mediaEnd, _jsx(ProductItinerarySection, { productId: product.id, renderDayDetails: renderItineraryDayDetails, renderServiceActions: renderItineraryServiceActions, renderSupplierServiceField: renderSupplierServiceField, onSupplierServiceSelected: onSupplierServiceSelected }), slots?.itineraryEnd, _jsx(ProductOptionsSection, { productId: product.id, renderOptionDetails: renderOptionDetails }), slots?.optionsEnd, _jsx(ProductVersionsSection, { productId: product.id }), slots?.versionsEnd] }), _jsxs("div", { className: "flex min-w-0 flex-col gap-6", children: [_jsx(ProductDetailSidebar, { product: product }), _jsx(ProductActionLedgerCard, { productId: product.id }), slots?.sidebar] })] }), _jsx(ProductDialog, { open: editOpen, onOpenChange: setEditOpen, product: product, onSuccess: () => setEditOpen(false) })] }));
50
47
  }
51
48
  export function ProductDetailHeader({ product, onBack, onEdit, onDelete, onBookingCreate, deleting = false, actionsSlot, className, }) {
52
49
  const messages = useProductsUiMessagesOrDefault();
@@ -75,98 +72,6 @@ export function ProductDetailSidebar({ product, className }) {
75
72
  const { formatDateTime } = useProductsUiI18nOrDefault();
76
73
  return (_jsxs(Card, { "data-slot": "product-detail-sidebar", className: className, children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: pageMessages.sections.sidebar.title }), _jsx(CardDescription, { children: pageMessages.sections.sidebar.description })] }), _jsxs(CardContent, { className: "space-y-4", children: [_jsxs("div", { className: "flex flex-wrap gap-2", children: [_jsx(Badge, { children: messages.common.productStatusLabels[product.status] }), _jsx(Badge, { variant: "outline", children: messages.common.productBookingModeLabels[product.bookingMode] }), product.activated ? _jsx(Badge, { variant: "secondary", children: messages.common.active }) : null] }), _jsx(ProductField, { label: pageMessages.fields.tags, value: product.tags.join(", ") }), _jsx(ProductField, { label: pageMessages.fields.createdAt, value: formatDateTime(product.createdAt) }), _jsx(ProductField, { label: pageMessages.fields.updatedAt, value: formatDateTime(product.updatedAt) })] })] }));
77
74
  }
78
- export function ProductItinerarySection({ productId, title, description, renderDayDetails, renderServiceActions, renderSupplierServiceField, onSupplierServiceSelected, className, }) {
79
- const messages = useProductsUiMessagesOrDefault();
80
- const pageMessages = messages.productDetailPage;
81
- const itinerariesQuery = useProductItineraries(productId);
82
- const itineraries = React.useMemo(() => (itinerariesQuery.data?.data ?? []).slice().sort((a, b) => a.sortOrder - b.sortOrder), [itinerariesQuery.data?.data]);
83
- const [selectedItineraryId, setSelectedItineraryId] = React.useState(null);
84
- const selectedItinerary = itineraries.find((itinerary) => itinerary.id === selectedItineraryId) ?? null;
85
- const daysQuery = useProductItineraryDays(productId, selectedItineraryId, {
86
- enabled: Boolean(selectedItineraryId),
87
- });
88
- const days = React.useMemo(() => (daysQuery.data?.data ?? []).slice().sort((a, b) => a.dayNumber - b.dayNumber), [daysQuery.data?.data]);
89
- const itineraryMutation = useProductItineraryMutation();
90
- const dayMutation = useProductDayMutation();
91
- const serviceMutation = useProductDayServiceMutation();
92
- const [itineraryDialogOpen, setItineraryDialogOpen] = React.useState(false);
93
- const [editingItinerary, setEditingItinerary] = React.useState(null);
94
- const [dayDialogOpen, setDayDialogOpen] = React.useState(false);
95
- const [editingDay, setEditingDay] = React.useState(null);
96
- const [serviceDialogOpen, setServiceDialogOpen] = React.useState(false);
97
- const [serviceDayId, setServiceDayId] = React.useState(null);
98
- const [editingService, setEditingService] = React.useState(null);
99
- const [expandedDayId, setExpandedDayId] = React.useState(null);
100
- React.useEffect(() => {
101
- if (itineraries.length === 0) {
102
- setSelectedItineraryId(null);
103
- return;
104
- }
105
- setSelectedItineraryId((current) => {
106
- if (current && itineraries.some((itinerary) => itinerary.id === current))
107
- return current;
108
- return itineraries.find((itinerary) => itinerary.isDefault)?.id ?? itineraries[0]?.id ?? null;
109
- });
110
- }, [itineraries]);
111
- const nextDayNumber = days.length > 0 ? Math.max(...days.map((day) => day.dayNumber)) + 1 : 1;
112
- return (_jsxs(Card, { "data-slot": "product-itinerary-section", className: className, children: [_jsxs(CardHeader, { className: "flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between", children: [_jsxs("div", { className: "space-y-1", children: [_jsx(CardTitle, { children: title ?? pageMessages.sections.itinerary.title }), _jsx(CardDescription, { children: description ?? pageMessages.sections.itinerary.description })] }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [itineraries.length > 0 ? (_jsxs(Select, { value: selectedItineraryId ?? undefined, onValueChange: (value) => setSelectedItineraryId(value), children: [_jsx(SelectTrigger, { className: "w-[220px]", children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: itineraries.map((itinerary) => (_jsx(SelectItem, { value: itinerary.id, children: itinerary.name }, itinerary.id))) })] })) : null, _jsxs(Button, { type: "button", variant: "outline", onClick: () => {
113
- setEditingItinerary(null);
114
- setItineraryDialogOpen(true);
115
- }, children: [_jsx(Plus, { className: "mr-2 size-4", "aria-hidden": "true" }), pageMessages.actions.addItinerary] }), selectedItinerary ? (_jsxs(_Fragment, { children: [_jsxs(Button, { type: "button", variant: "outline", onClick: () => {
116
- setEditingItinerary(selectedItinerary);
117
- setItineraryDialogOpen(true);
118
- }, children: [_jsx(Edit, { className: "mr-2 size-4", "aria-hidden": "true" }), pageMessages.actions.editItinerary] }), _jsxs(Button, { type: "button", variant: "outline", onClick: () => {
119
- if (!confirm(pageMessages.states.deleteItineraryConfirm.replace("{name}", selectedItinerary.name))) {
120
- return;
121
- }
122
- void itineraryMutation.remove.mutateAsync({
123
- productId,
124
- itineraryId: selectedItinerary.id,
125
- });
126
- }, children: [_jsx(Trash2, { className: "mr-2 size-4", "aria-hidden": "true" }), pageMessages.actions.deleteItinerary] })] })) : null] })] }), _jsx(CardContent, { className: "flex flex-col gap-3", children: itinerariesQuery.isPending ? (_jsx("div", { className: "flex min-h-24 items-center justify-center", children: _jsx(Loader2, { className: "size-4 animate-spin text-muted-foreground", "aria-hidden": "true" }) })) : itinerariesQuery.isError ? (_jsx("p", { className: "text-sm text-destructive", children: pageMessages.states.loadFailed })) : itineraries.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: pageMessages.states.noItineraries })) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "flex justify-end", children: _jsxs(Button, { type: "button", onClick: () => {
127
- setEditingDay(null);
128
- setDayDialogOpen(true);
129
- }, disabled: !selectedItineraryId, children: [_jsx(Plus, { className: "mr-2 size-4", "aria-hidden": "true" }), pageMessages.actions.addDay] }) }), daysQuery.isPending ? (_jsx("div", { className: "flex min-h-24 items-center justify-center", children: _jsx(Loader2, { className: "size-4 animate-spin text-muted-foreground", "aria-hidden": "true" }) })) : daysQuery.isError ? (_jsx("p", { className: "text-sm text-destructive", children: pageMessages.states.loadFailed })) : days.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: pageMessages.states.noDays })) : (days.map((day) => (_jsx(ProductItineraryDayRow, { productId: productId, day: day, expanded: expandedDayId === day.id, onToggle: () => setExpandedDayId((current) => (current === day.id ? null : day.id)), onEdit: () => {
130
- setEditingDay(day);
131
- setDayDialogOpen(true);
132
- }, onDelete: () => {
133
- if (!confirm(pageMessages.states.deleteDayConfirm.replace("{dayNumber}", String(day.dayNumber)))) {
134
- return;
135
- }
136
- void dayMutation.remove.mutateAsync({
137
- productId,
138
- dayId: day.id,
139
- itineraryId: day.itineraryId,
140
- });
141
- }, onAddService: () => {
142
- setServiceDayId(day.id);
143
- setEditingService(null);
144
- setExpandedDayId(day.id);
145
- setServiceDialogOpen(true);
146
- }, onEditService: (service) => {
147
- setServiceDayId(day.id);
148
- setEditingService(service);
149
- setExpandedDayId(day.id);
150
- setServiceDialogOpen(true);
151
- }, onDeleteService: (service) => {
152
- if (!confirm(pageMessages.states.deleteServiceConfirm.replace("{name}", service.name))) {
153
- return;
154
- }
155
- void serviceMutation.remove.mutateAsync({
156
- productId,
157
- dayId: day.id,
158
- serviceId: service.id,
159
- });
160
- }, renderDayDetails: renderDayDetails, renderServiceActions: renderServiceActions }, day.id))))] })) }), _jsx(ProductItineraryDialog, { open: itineraryDialogOpen, onOpenChange: setItineraryDialogOpen, productId: productId, itinerary: editingItinerary ?? undefined, itineraryCount: itineraries.length, onSuccess: (itineraryId) => setSelectedItineraryId(itineraryId) }), selectedItineraryId ? (_jsx(ProductDayDialog, { open: dayDialogOpen, onOpenChange: setDayDialogOpen, productId: productId, itineraryId: selectedItineraryId, day: editingDay ?? undefined, nextDayNumber: nextDayNumber, onSuccess: (day) => {
161
- setExpandedDayId(day.id);
162
- setEditingDay(null);
163
- } })) : null, serviceDayId ? (_jsx(ProductDayServiceDialog, { open: serviceDialogOpen, onOpenChange: (open) => {
164
- setServiceDialogOpen(open);
165
- if (!open) {
166
- setEditingService(null);
167
- }
168
- }, productId: productId, dayId: serviceDayId, service: editingService ?? undefined, renderSupplierServiceField: renderSupplierServiceField, onSupplierServiceSelected: onSupplierServiceSelected, onSuccess: () => setEditingService(null) })) : null] }));
169
- }
170
75
  function ProductDetailPageLoading({ className }) {
171
76
  const messages = useProductsUiMessagesOrDefault();
172
77
  return (_jsx("div", { "data-slot": "product-detail-page-loading", className: cn("flex min-h-48 items-center justify-center p-6", className), children: _jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [_jsx(Loader2, { className: "size-4 animate-spin", "aria-hidden": "true" }), messages.productDetailPage.states.loading] }) }));
@@ -0,0 +1,16 @@
1
+ import { type ProductDayServiceRecord } from "@voyantjs/products-react";
2
+ import * as React from "react";
3
+ import type { ProductDayServiceFormProps } from "./product-day-service-form.js";
4
+ import { type ProductItineraryDayRowRenderContext } from "./product-itinerary-day-row.js";
5
+ export interface ProductItinerarySectionProps {
6
+ productId: string;
7
+ title?: string;
8
+ description?: string;
9
+ renderDayDetails?: (context: ProductItineraryDayRowRenderContext) => React.ReactNode;
10
+ renderServiceActions?: (service: ProductDayServiceRecord) => React.ReactNode;
11
+ renderSupplierServiceField?: ProductDayServiceFormProps["renderSupplierServiceField"];
12
+ onSupplierServiceSelected?: ProductDayServiceFormProps["onSupplierServiceSelected"];
13
+ className?: string;
14
+ }
15
+ export declare function ProductItinerarySection({ productId, title, description, renderDayDetails, renderServiceActions, renderSupplierServiceField, onSupplierServiceSelected, className, }: ProductItinerarySectionProps): import("react/jsx-runtime").JSX.Element;
16
+ //# sourceMappingURL=product-itinerary-section.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product-itinerary-section.d.ts","sourceRoot":"","sources":["../../src/components/product-itinerary-section.tsx"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,uBAAuB,EAO7B,MAAM,0BAA0B,CAAA;AAiBjC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAK9B,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAA;AAC/E,OAAO,EAEL,KAAK,mCAAmC,EACzC,MAAM,gCAAgC,CAAA;AAGvC,MAAM,WAAW,4BAA4B;IAC3C,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,mCAAmC,KAAK,KAAK,CAAC,SAAS,CAAA;IACpF,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,KAAK,CAAC,SAAS,CAAA;IAC5E,0BAA0B,CAAC,EAAE,0BAA0B,CAAC,4BAA4B,CAAC,CAAA;IACrF,yBAAyB,CAAC,EAAE,0BAA0B,CAAC,2BAA2B,CAAC,CAAA;IACnF,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,uBAAuB,CAAC,EACtC,SAAS,EACT,KAAK,EACL,WAAW,EACX,gBAAgB,EAChB,oBAAoB,EACpB,0BAA0B,EAC1B,yBAAyB,EACzB,SAAS,GACV,EAAE,4BAA4B,2CAuQ9B"}
@@ -0,0 +1,105 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useProductDayMutation, useProductDayServiceMutation, useProductItineraries, useProductItineraryDays, useProductItineraryMutation, } from "@voyantjs/products-react";
4
+ import { Button } from "@voyantjs/ui/components/button";
5
+ import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@voyantjs/ui/components/card";
6
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@voyantjs/ui/components/select";
7
+ import { Edit, Loader2, Plus, Trash2 } from "lucide-react";
8
+ import * as React from "react";
9
+ import { useProductsUiMessagesOrDefault } from "../i18n/provider.js";
10
+ import { ProductDayDialog } from "./product-day-dialog.js";
11
+ import { ProductDayServiceDialog } from "./product-day-service-dialog.js";
12
+ import { ProductItineraryDayRow, } from "./product-itinerary-day-row.js";
13
+ import { ProductItineraryDialog } from "./product-itinerary-dialog.js";
14
+ export function ProductItinerarySection({ productId, title, description, renderDayDetails, renderServiceActions, renderSupplierServiceField, onSupplierServiceSelected, className, }) {
15
+ const messages = useProductsUiMessagesOrDefault();
16
+ const pageMessages = messages.productDetailPage;
17
+ const itinerariesQuery = useProductItineraries(productId);
18
+ const itineraries = React.useMemo(() => (itinerariesQuery.data?.data ?? []).slice().sort((a, b) => a.sortOrder - b.sortOrder), [itinerariesQuery.data?.data]);
19
+ const [selectedItineraryId, setSelectedItineraryId] = React.useState(null);
20
+ const selectedItinerary = itineraries.find((itinerary) => itinerary.id === selectedItineraryId) ?? null;
21
+ const daysQuery = useProductItineraryDays(productId, selectedItineraryId, {
22
+ enabled: Boolean(selectedItineraryId),
23
+ });
24
+ const days = React.useMemo(() => (daysQuery.data?.data ?? []).slice().sort((a, b) => a.dayNumber - b.dayNumber), [daysQuery.data?.data]);
25
+ const itineraryMutation = useProductItineraryMutation();
26
+ const dayMutation = useProductDayMutation();
27
+ const serviceMutation = useProductDayServiceMutation();
28
+ const [itineraryDialogOpen, setItineraryDialogOpen] = React.useState(false);
29
+ const [editingItinerary, setEditingItinerary] = React.useState(null);
30
+ const [dayDialogOpen, setDayDialogOpen] = React.useState(false);
31
+ const [editingDay, setEditingDay] = React.useState(null);
32
+ const [serviceDialogOpen, setServiceDialogOpen] = React.useState(false);
33
+ const [serviceDayId, setServiceDayId] = React.useState(null);
34
+ const [editingService, setEditingService] = React.useState(null);
35
+ const [expandedDayId, setExpandedDayId] = React.useState(null);
36
+ React.useEffect(() => {
37
+ if (itineraries.length === 0) {
38
+ setSelectedItineraryId(null);
39
+ return;
40
+ }
41
+ setSelectedItineraryId((current) => {
42
+ if (current && itineraries.some((itinerary) => itinerary.id === current))
43
+ return current;
44
+ return itineraries.find((itinerary) => itinerary.isDefault)?.id ?? itineraries[0]?.id ?? null;
45
+ });
46
+ }, [itineraries]);
47
+ const nextDayNumber = days.length > 0 ? Math.max(...days.map((day) => day.dayNumber)) + 1 : 1;
48
+ return (_jsxs(Card, { "data-slot": "product-itinerary-section", className: className, children: [_jsxs(CardHeader, { className: "flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between", children: [_jsxs("div", { className: "space-y-1", children: [_jsx(CardTitle, { children: title ?? pageMessages.sections.itinerary.title }), _jsx(CardDescription, { children: description ?? pageMessages.sections.itinerary.description })] }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [itineraries.length > 0 ? (_jsxs(Select, { value: selectedItineraryId ?? undefined, onValueChange: (value) => setSelectedItineraryId(value), children: [_jsx(SelectTrigger, { className: "w-[220px]", children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: itineraries.map((itinerary) => (_jsx(SelectItem, { value: itinerary.id, children: itinerary.name }, itinerary.id))) })] })) : null, _jsxs(Button, { type: "button", variant: "outline", onClick: () => {
49
+ setEditingItinerary(null);
50
+ setItineraryDialogOpen(true);
51
+ }, children: [_jsx(Plus, { className: "mr-2 size-4", "aria-hidden": "true" }), pageMessages.actions.addItinerary] }), selectedItinerary ? (_jsxs(_Fragment, { children: [_jsxs(Button, { type: "button", variant: "outline", onClick: () => {
52
+ setEditingItinerary(selectedItinerary);
53
+ setItineraryDialogOpen(true);
54
+ }, children: [_jsx(Edit, { className: "mr-2 size-4", "aria-hidden": "true" }), pageMessages.actions.editItinerary] }), _jsxs(Button, { type: "button", variant: "outline", onClick: () => {
55
+ if (!confirm(pageMessages.states.deleteItineraryConfirm.replace("{name}", selectedItinerary.name))) {
56
+ return;
57
+ }
58
+ void itineraryMutation.remove.mutateAsync({
59
+ productId,
60
+ itineraryId: selectedItinerary.id,
61
+ });
62
+ }, children: [_jsx(Trash2, { className: "mr-2 size-4", "aria-hidden": "true" }), pageMessages.actions.deleteItinerary] })] })) : null] })] }), _jsx(CardContent, { className: "flex flex-col gap-3", children: itinerariesQuery.isPending ? (_jsx("div", { className: "flex min-h-24 items-center justify-center", children: _jsx(Loader2, { className: "size-4 animate-spin text-muted-foreground", "aria-hidden": "true" }) })) : itinerariesQuery.isError ? (_jsx("p", { className: "text-sm text-destructive", children: pageMessages.states.loadFailed })) : itineraries.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: pageMessages.states.noItineraries })) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "flex justify-end", children: _jsxs(Button, { type: "button", onClick: () => {
63
+ setEditingDay(null);
64
+ setDayDialogOpen(true);
65
+ }, disabled: !selectedItineraryId, children: [_jsx(Plus, { className: "mr-2 size-4", "aria-hidden": "true" }), pageMessages.actions.addDay] }) }), daysQuery.isPending ? (_jsx("div", { className: "flex min-h-24 items-center justify-center", children: _jsx(Loader2, { className: "size-4 animate-spin text-muted-foreground", "aria-hidden": "true" }) })) : daysQuery.isError ? (_jsx("p", { className: "text-sm text-destructive", children: pageMessages.states.loadFailed })) : days.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: pageMessages.states.noDays })) : (days.map((day) => (_jsx(ProductItineraryDayRow, { productId: productId, day: day, expanded: expandedDayId === day.id, onToggle: () => setExpandedDayId((current) => (current === day.id ? null : day.id)), onEdit: () => {
66
+ setEditingDay(day);
67
+ setDayDialogOpen(true);
68
+ }, onDelete: () => {
69
+ if (!confirm(pageMessages.states.deleteDayConfirm.replace("{dayNumber}", String(day.dayNumber)))) {
70
+ return;
71
+ }
72
+ void dayMutation.remove.mutateAsync({
73
+ productId,
74
+ dayId: day.id,
75
+ itineraryId: day.itineraryId,
76
+ });
77
+ }, onAddService: () => {
78
+ setServiceDayId(day.id);
79
+ setEditingService(null);
80
+ setExpandedDayId(day.id);
81
+ setServiceDialogOpen(true);
82
+ }, onEditService: (service) => {
83
+ setServiceDayId(day.id);
84
+ setEditingService(service);
85
+ setExpandedDayId(day.id);
86
+ setServiceDialogOpen(true);
87
+ }, onDeleteService: (service) => {
88
+ if (!confirm(pageMessages.states.deleteServiceConfirm.replace("{name}", service.name))) {
89
+ return;
90
+ }
91
+ void serviceMutation.remove.mutateAsync({
92
+ productId,
93
+ dayId: day.id,
94
+ serviceId: service.id,
95
+ });
96
+ }, renderDayDetails: renderDayDetails, renderServiceActions: renderServiceActions }, day.id))))] })) }), _jsx(ProductItineraryDialog, { open: itineraryDialogOpen, onOpenChange: setItineraryDialogOpen, productId: productId, itinerary: editingItinerary ?? undefined, itineraryCount: itineraries.length, onSuccess: (itineraryId) => setSelectedItineraryId(itineraryId) }), selectedItineraryId ? (_jsx(ProductDayDialog, { open: dayDialogOpen, onOpenChange: setDayDialogOpen, productId: productId, itineraryId: selectedItineraryId, day: editingDay ?? undefined, nextDayNumber: nextDayNumber, onSuccess: (day) => {
97
+ setExpandedDayId(day.id);
98
+ setEditingDay(null);
99
+ } })) : null, serviceDayId ? (_jsx(ProductDayServiceDialog, { open: serviceDialogOpen, onOpenChange: (open) => {
100
+ setServiceDialogOpen(open);
101
+ if (!open) {
102
+ setEditingService(null);
103
+ }
104
+ }, productId: productId, dayId: serviceDayId, service: editingService ?? undefined, renderSupplierServiceField: renderSupplierServiceField, onSupplierServiceSelected: onSupplierServiceSelected, onSuccess: () => setEditingService(null) })) : null] }));
105
+ }
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { OptionUnitDialog, type OptionUnitDialogProps } from "./components/option-unit-dialog.js";
2
2
  export { OptionUnitForm, type OptionUnitFormProps } from "./components/option-unit-form.js";
3
+ export { ProductActionLedgerCard, type ProductActionLedgerCardMessages, type ProductActionLedgerCardProps, } from "./components/product-action-ledger-card.js";
3
4
  export { ProductCategoriesPage, type ProductCategoriesPageProps, } from "./components/product-categories-page.js";
4
5
  export { ProductCategoryCombobox } from "./components/product-category-combobox.js";
5
6
  export { ProductCategoryDialog, type ProductCategoryDialogProps, } from "./components/product-category-dialog.js";
@@ -11,12 +12,13 @@ export { ProductDayForm, type ProductDayFormProps } from "./components/product-d
11
12
  export { ProductDayMediaTray, type ProductDayMediaTrayProps, } from "./components/product-day-media-tray.js";
12
13
  export { ProductDayServiceDialog, type ProductDayServiceDialogProps, } from "./components/product-day-service-dialog.js";
13
14
  export { ProductDayServiceForm, type ProductDayServiceFormHelpers, type ProductDayServiceFormProps, type ProductDayServiceSupplierServiceFieldProps, type ProductDayServiceSupplierServiceOption, } from "./components/product-day-service-form.js";
14
- export { ProductCommercialCard, ProductDetailHeader, type ProductDetailHeaderProps, ProductDetailPage, type ProductDetailPageProps, type ProductDetailPageSlots, ProductDetailSidebar, type ProductDetailSidebarProps, ProductItinerarySection, type ProductItinerarySectionProps, ProductOverviewCard, type ProductOverviewCardProps, } from "./components/product-detail-page.js";
15
+ export { ProductCommercialCard, ProductDetailHeader, type ProductDetailHeaderProps, ProductDetailPage, type ProductDetailPageProps, type ProductDetailPageSlots, ProductDetailSidebar, type ProductDetailSidebarProps, ProductOverviewCard, type ProductOverviewCardProps, } from "./components/product-detail-page.js";
15
16
  export { ProductDialog, type ProductDialogProps } from "./components/product-dialog.js";
16
17
  export { ProductFacilityCombobox } from "./components/product-facility-combobox.js";
17
18
  export { ProductForm, type ProductFormMode, type ProductFormProps, } from "./components/product-form.js";
18
19
  export { ProductItineraryDayRow, type ProductItineraryDayRowProps, type ProductItineraryDayRowRenderContext, } from "./components/product-itinerary-day-row.js";
19
20
  export { ProductItineraryDialog, type ProductItineraryDialogProps, } from "./components/product-itinerary-dialog.js";
21
+ export { ProductItinerarySection, type ProductItinerarySectionProps, } from "./components/product-itinerary-section.js";
20
22
  export { ProductList, type ProductListProps } from "./components/product-list.js";
21
23
  export { ProductMediaDialog, type ProductMediaDialogProps, } from "./components/product-media-dialog.js";
22
24
  export { ProductMediaForm, type ProductMediaFormProps } from "./components/product-media-form.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export { OptionUnitDialog } from "./components/option-unit-dialog.js";
2
2
  export { OptionUnitForm } from "./components/option-unit-form.js";
3
+ export { ProductActionLedgerCard, } from "./components/product-action-ledger-card.js";
3
4
  export { ProductCategoriesPage, } from "./components/product-categories-page.js";
4
5
  export { ProductCategoryCombobox } from "./components/product-category-combobox.js";
5
6
  export { ProductCategoryDialog, } from "./components/product-category-dialog.js";
@@ -11,12 +12,13 @@ export { ProductDayForm } from "./components/product-day-form.js";
11
12
  export { ProductDayMediaTray, } from "./components/product-day-media-tray.js";
12
13
  export { ProductDayServiceDialog, } from "./components/product-day-service-dialog.js";
13
14
  export { ProductDayServiceForm, } from "./components/product-day-service-form.js";
14
- export { ProductCommercialCard, ProductDetailHeader, ProductDetailPage, ProductDetailSidebar, ProductItinerarySection, ProductOverviewCard, } from "./components/product-detail-page.js";
15
+ export { ProductCommercialCard, ProductDetailHeader, ProductDetailPage, ProductDetailSidebar, ProductOverviewCard, } from "./components/product-detail-page.js";
15
16
  export { ProductDialog } from "./components/product-dialog.js";
16
17
  export { ProductFacilityCombobox } from "./components/product-facility-combobox.js";
17
18
  export { ProductForm, } from "./components/product-form.js";
18
19
  export { ProductItineraryDayRow, } from "./components/product-itinerary-day-row.js";
19
20
  export { ProductItineraryDialog, } from "./components/product-itinerary-dialog.js";
21
+ export { ProductItinerarySection, } from "./components/product-itinerary-section.js";
20
22
  export { ProductList } from "./components/product-list.js";
21
23
  export { ProductMediaDialog, } from "./components/product-media-dialog.js";
22
24
  export { ProductMediaForm } from "./components/product-media-form.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voyantjs/products-ui",
3
- "version": "0.52.2",
3
+ "version": "0.52.4",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -45,17 +45,17 @@
45
45
  "react-dom": "^19.0.0",
46
46
  "react-hook-form": "^7.60.0",
47
47
  "zod": "^4.3.6",
48
- "@voyantjs/availability-react": "0.52.2",
49
- "@voyantjs/catalog-react": "0.52.2",
50
- "@voyantjs/finance": "0.52.2",
51
- "@voyantjs/finance-ui": "0.52.2",
52
- "@voyantjs/pricing-react": "0.52.2",
53
- "@voyantjs/products-react": "0.52.2",
54
- "@voyantjs/suppliers-react": "0.52.2",
55
- "@voyantjs/ui": "0.52.2"
48
+ "@voyantjs/availability-react": "0.52.4",
49
+ "@voyantjs/catalog-react": "0.52.4",
50
+ "@voyantjs/finance": "0.52.4",
51
+ "@voyantjs/finance-ui": "0.52.4",
52
+ "@voyantjs/pricing-react": "0.52.4",
53
+ "@voyantjs/products-react": "0.52.4",
54
+ "@voyantjs/suppliers-react": "0.52.4",
55
+ "@voyantjs/ui": "0.52.4"
56
56
  },
57
57
  "dependencies": {
58
- "@voyantjs/i18n": "0.52.2"
58
+ "@voyantjs/i18n": "0.52.4"
59
59
  },
60
60
  "devDependencies": {
61
61
  "@tanstack/react-query": "^5.96.2",
@@ -68,16 +68,16 @@
68
68
  "typescript": "^6.0.2",
69
69
  "vitest": "^4.1.2",
70
70
  "zod": "^4.3.6",
71
- "@voyantjs/availability-react": "0.52.2",
72
- "@voyantjs/catalog-react": "0.52.2",
73
- "@voyantjs/finance": "0.52.2",
74
- "@voyantjs/finance-ui": "0.52.2",
75
- "@voyantjs/i18n": "0.52.2",
76
- "@voyantjs/pricing-react": "0.52.2",
77
- "@voyantjs/products-react": "0.52.2",
78
- "@voyantjs/suppliers-react": "0.52.2",
71
+ "@voyantjs/availability-react": "0.52.4",
72
+ "@voyantjs/catalog-react": "0.52.4",
73
+ "@voyantjs/finance": "0.52.4",
74
+ "@voyantjs/finance-ui": "0.52.4",
75
+ "@voyantjs/i18n": "0.52.4",
76
+ "@voyantjs/pricing-react": "0.52.4",
77
+ "@voyantjs/products-react": "0.52.4",
78
+ "@voyantjs/suppliers-react": "0.52.4",
79
79
  "@voyantjs/voyant-typescript-config": "0.1.0",
80
- "@voyantjs/ui": "0.52.2"
80
+ "@voyantjs/ui": "0.52.4"
81
81
  },
82
82
  "files": [
83
83
  "dist",