@voyant-travel/charters-react 0.117.2

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.
Files changed (85) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +40 -0
  3. package/dist/client.d.ts +14 -0
  4. package/dist/client.d.ts.map +1 -0
  5. package/dist/client.js +59 -0
  6. package/dist/components/apa-tracker.d.ts +18 -0
  7. package/dist/components/apa-tracker.d.ts.map +1 -0
  8. package/dist/components/apa-tracker.js +69 -0
  9. package/dist/components/charter-catalog-card.d.ts +13 -0
  10. package/dist/components/charter-catalog-card.d.ts.map +1 -0
  11. package/dist/components/charter-catalog-card.js +58 -0
  12. package/dist/components/external-badge.d.ts +13 -0
  13. package/dist/components/external-badge.d.ts.map +1 -0
  14. package/dist/components/external-badge.js +16 -0
  15. package/dist/components/voyage-suite-grid.d.ts +26 -0
  16. package/dist/components/voyage-suite-grid.d.ts.map +1 -0
  17. package/dist/components/voyage-suite-grid.js +77 -0
  18. package/dist/components/whole-yacht-quote-card.d.ts +21 -0
  19. package/dist/components/whole-yacht-quote-card.d.ts.map +1 -0
  20. package/dist/components/whole-yacht-quote-card.js +46 -0
  21. package/dist/hooks/index.d.ts +10 -0
  22. package/dist/hooks/index.d.ts.map +1 -0
  23. package/dist/hooks/index.js +9 -0
  24. package/dist/hooks/use-apa.d.ts +130 -0
  25. package/dist/hooks/use-apa.d.ts.map +1 -0
  26. package/dist/hooks/use-apa.js +60 -0
  27. package/dist/hooks/use-charter-booking.d.ts +175 -0
  28. package/dist/hooks/use-charter-booking.d.ts.map +1 -0
  29. package/dist/hooks/use-charter-booking.js +39 -0
  30. package/dist/hooks/use-charter-product-mutation.d.ts +124 -0
  31. package/dist/hooks/use-charter-product-mutation.d.ts.map +1 -0
  32. package/dist/hooks/use-charter-product-mutation.js +55 -0
  33. package/dist/hooks/use-charter-products.d.ts +150 -0
  34. package/dist/hooks/use-charter-products.d.ts.map +1 -0
  35. package/dist/hooks/use-charter-products.js +29 -0
  36. package/dist/hooks/use-charter-public.d.ts +232 -0
  37. package/dist/hooks/use-charter-public.d.ts.map +1 -0
  38. package/dist/hooks/use-charter-public.js +41 -0
  39. package/dist/hooks/use-charter-quote.d.ts +42 -0
  40. package/dist/hooks/use-charter-quote.d.ts.map +1 -0
  41. package/dist/hooks/use-charter-quote.js +30 -0
  42. package/dist/hooks/use-charter-voyages.d.ts +111 -0
  43. package/dist/hooks/use-charter-voyages.d.ts.map +1 -0
  44. package/dist/hooks/use-charter-voyages.js +19 -0
  45. package/dist/hooks/use-charter-yachts.d.ts +72 -0
  46. package/dist/hooks/use-charter-yachts.d.ts.map +1 -0
  47. package/dist/hooks/use-charter-yachts.js +19 -0
  48. package/dist/hooks/use-myba-contract.d.ts +28 -0
  49. package/dist/hooks/use-myba-contract.d.ts.map +1 -0
  50. package/dist/hooks/use-myba-contract.js +31 -0
  51. package/dist/i18n/en.d.ts +3 -0
  52. package/dist/i18n/en.d.ts.map +1 -0
  53. package/dist/i18n/en.js +78 -0
  54. package/dist/i18n/index.d.ts +5 -0
  55. package/dist/i18n/index.d.ts.map +1 -0
  56. package/dist/i18n/index.js +3 -0
  57. package/dist/i18n/messages.d.ts +70 -0
  58. package/dist/i18n/messages.d.ts.map +1 -0
  59. package/dist/i18n/messages.js +1 -0
  60. package/dist/i18n/provider.d.ts +26 -0
  61. package/dist/i18n/provider.d.ts.map +1 -0
  62. package/dist/i18n/provider.js +44 -0
  63. package/dist/i18n/ro.d.ts +3 -0
  64. package/dist/i18n/ro.d.ts.map +1 -0
  65. package/dist/i18n/ro.js +78 -0
  66. package/dist/index.d.ts +7 -0
  67. package/dist/index.d.ts.map +1 -0
  68. package/dist/index.js +6 -0
  69. package/dist/provider.d.ts +2 -0
  70. package/dist/provider.d.ts.map +1 -0
  71. package/dist/provider.js +1 -0
  72. package/dist/query-keys.d.ts +61 -0
  73. package/dist/query-keys.d.ts.map +1 -0
  74. package/dist/query-keys.js +31 -0
  75. package/dist/query-options.d.ts +2108 -0
  76. package/dist/query-options.d.ts.map +1 -0
  77. package/dist/query-options.js +110 -0
  78. package/dist/schemas.d.ts +1066 -0
  79. package/dist/schemas.d.ts.map +1 -0
  80. package/dist/schemas.js +323 -0
  81. package/dist/ui.d.ts +6 -0
  82. package/dist/ui.d.ts.map +1 -0
  83. package/dist/ui.js +5 -0
  84. package/package.json +121 -0
  85. package/src/styles.css +11 -0
@@ -0,0 +1,21 @@
1
+ import { Card } from "@voyant-travel/ui/components/card";
2
+ import type * as React from "react";
3
+ import type { PerSuiteQuote, WholeYachtQuote } from "../index.js";
4
+ export interface WholeYachtQuoteCardProps extends React.ComponentPropsWithoutRef<typeof Card> {
5
+ quote: WholeYachtQuote;
6
+ formatPrice?: (amount: string, currency: string) => string;
7
+ }
8
+ export interface PerSuiteQuoteCardProps extends React.ComponentPropsWithoutRef<typeof Card> {
9
+ quote: PerSuiteQuote;
10
+ formatPrice?: (amount: string, currency: string) => string;
11
+ }
12
+ /**
13
+ * Itemised display of a whole-yacht charter quote: charter fee + APA
14
+ * (% of fee, computed amount) + total. APA explanatory copy is intentional —
15
+ * even seasoned brokers occasionally have charterers who don't know what an
16
+ * APA is. Mirrors what `composeWholeYachtQuote` returns server-side.
17
+ */
18
+ export declare function WholeYachtQuoteCard({ quote, formatPrice, className, ...props }: WholeYachtQuoteCardProps): import("react/jsx-runtime").JSX.Element;
19
+ /** Sibling component: simpler per-suite quote (suite price + optional port fee). */
20
+ export declare function PerSuiteQuoteCard({ quote, formatPrice, className, ...props }: PerSuiteQuoteCardProps): import("react/jsx-runtime").JSX.Element;
21
+ //# sourceMappingURL=whole-yacht-quote-card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whole-yacht-quote-card.d.ts","sourceRoot":"","sources":["../../src/components/whole-yacht-quote-card.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,IAAI,EAA2B,MAAM,mCAAmC,CAAA;AAEjF,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAA;AAEnC,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAEjE,MAAM,WAAW,wBAAyB,SAAQ,KAAK,CAAC,wBAAwB,CAAC,OAAO,IAAI,CAAC;IAC3F,KAAK,EAAE,eAAe,CAAA;IACtB,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAA;CAC3D;AAED,MAAM,WAAW,sBAAuB,SAAQ,KAAK,CAAC,wBAAwB,CAAC,OAAO,IAAI,CAAC;IACzF,KAAK,EAAE,aAAa,CAAA;IACpB,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAA;CAC3D;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,KAAK,EACL,WAAW,EACX,SAAS,EACT,GAAG,KAAK,EACT,EAAE,wBAAwB,2CA4C1B;AAED,oFAAoF;AACpF,wBAAgB,iBAAiB,CAAC,EAChC,KAAK,EACL,WAAW,EACX,SAAS,EACT,GAAG,KAAK,EACT,EAAE,sBAAsB,2CA0CxB"}
@@ -0,0 +1,46 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { formatMessage } from "@voyant-travel/i18n";
4
+ import { Card, CardContent, CardHeader } from "@voyant-travel/ui/components/card";
5
+ import { cn } from "@voyant-travel/ui/lib/utils";
6
+ import { useChartersUiI18nOrDefault } from "../i18n/index.js";
7
+ /**
8
+ * Itemised display of a whole-yacht charter quote: charter fee + APA
9
+ * (% of fee, computed amount) + total. APA explanatory copy is intentional —
10
+ * even seasoned brokers occasionally have charterers who don't know what an
11
+ * APA is. Mirrors what `composeWholeYachtQuote` returns server-side.
12
+ */
13
+ export function WholeYachtQuoteCard({ quote, formatPrice, className, ...props }) {
14
+ const i18n = useChartersUiI18nOrDefault();
15
+ const m = i18n.messages.wholeYachtQuoteCard.wholeYacht;
16
+ const formatPriceValue = formatPrice ??
17
+ ((amount, currency) => formatCharterPrice(amount, currency, {
18
+ fallbackCurrencyAmount: i18n.messages.common.fallbackCurrencyAmount,
19
+ formatCurrency: i18n.formatCurrency,
20
+ }));
21
+ return (_jsxs(Card, { "data-slot": "whole-yacht-quote-card", className: cn(className), ...props, children: [_jsx(CardHeader, { children: _jsxs("div", { className: "flex items-baseline justify-between", children: [_jsxs("div", { children: [_jsx("h3", { className: "text-base font-semibold", children: m.heading }), _jsx("p", { className: "text-sm text-muted-foreground", children: m.summary })] }), _jsxs("div", { className: "text-right", children: [_jsx("div", { className: "text-2xl font-bold", children: formatPriceValue(quote.total, quote.currency) }), _jsx("div", { className: "text-xs text-muted-foreground", children: m.dueBeforeEmbarkation })] })] }) }), _jsxs(CardContent, { className: "space-y-3 text-sm", children: [_jsx(Row, { label: m.charterFee, amount: formatPriceValue(quote.charterFee, quote.currency) }), _jsx(Row, { label: formatMessage(m.apaLabel, { percent: quote.apaPercent }), amount: formatPriceValue(quote.apaAmount, quote.currency) }), _jsx("div", { className: "border-t pt-3", children: _jsx(Row, { label: m.totalDue, amount: formatPriceValue(quote.total, quote.currency), amountClassName: "font-bold text-base" }) }), _jsx("p", { className: "text-xs text-muted-foreground", children: m.explanation })] })] }));
22
+ }
23
+ /** Sibling component: simpler per-suite quote (suite price + optional port fee). */
24
+ export function PerSuiteQuoteCard({ quote, formatPrice, className, ...props }) {
25
+ const i18n = useChartersUiI18nOrDefault();
26
+ const m = i18n.messages.wholeYachtQuoteCard.perSuite;
27
+ const formatPriceValue = formatPrice ??
28
+ ((amount, currency) => formatCharterPrice(amount, currency, {
29
+ fallbackCurrencyAmount: i18n.messages.common.fallbackCurrencyAmount,
30
+ formatCurrency: i18n.formatCurrency,
31
+ }));
32
+ return (_jsxs(Card, { "data-slot": "per-suite-quote-card", className: cn(className), ...props, children: [_jsx(CardHeader, { children: _jsxs("div", { className: "flex items-baseline justify-between", children: [_jsxs("div", { children: [_jsx("h3", { className: "text-base font-semibold", children: quote.suiteName }), _jsx("p", { className: "text-sm text-muted-foreground", children: m.summary })] }), _jsxs("div", { className: "text-right", children: [_jsx("div", { className: "text-2xl font-bold", children: formatPriceValue(quote.total, quote.currency) }), _jsx("div", { className: "text-xs text-muted-foreground", children: m.allInForSuite })] })] }) }), _jsxs(CardContent, { className: "space-y-3 text-sm", children: [_jsx(Row, { label: m.suitePrice, amount: formatPriceValue(quote.suitePrice, quote.currency) }), quote.portFee ? (_jsx(Row, { label: m.portFee, amount: formatPriceValue(quote.portFee, quote.currency) })) : null, _jsx("div", { className: "border-t pt-3", children: _jsx(Row, { label: m.total, amount: formatPriceValue(quote.total, quote.currency), amountClassName: "font-bold text-base" }) })] })] }));
33
+ }
34
+ function Row({ label, amount, amountClassName, }) {
35
+ return (_jsxs("div", { className: "flex items-baseline justify-between gap-4", children: [_jsx("span", { className: "text-muted-foreground", children: label }), amount ? _jsx("span", { className: cn("tabular-nums", amountClassName), children: amount }) : null] }));
36
+ }
37
+ function formatCharterPrice(amount, currency, options) {
38
+ const value = Number(amount);
39
+ if (!Number.isFinite(value)) {
40
+ return formatMessage(options.fallbackCurrencyAmount, { amount, currency });
41
+ }
42
+ return options.formatCurrency(value, currency, {
43
+ minimumFractionDigits: 2,
44
+ maximumFractionDigits: 2,
45
+ });
46
+ }
@@ -0,0 +1,10 @@
1
+ export * from "./use-apa.js";
2
+ export * from "./use-charter-booking.js";
3
+ export * from "./use-charter-product-mutation.js";
4
+ export * from "./use-charter-products.js";
5
+ export * from "./use-charter-public.js";
6
+ export * from "./use-charter-quote.js";
7
+ export * from "./use-charter-voyages.js";
8
+ export * from "./use-charter-yachts.js";
9
+ export * from "./use-myba-contract.js";
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAA;AAC5B,cAAc,0BAA0B,CAAA;AACxC,cAAc,mCAAmC,CAAA;AACjD,cAAc,2BAA2B,CAAA;AACzC,cAAc,yBAAyB,CAAA;AACvC,cAAc,wBAAwB,CAAA;AACtC,cAAc,0BAA0B,CAAA;AACxC,cAAc,yBAAyB,CAAA;AACvC,cAAc,wBAAwB,CAAA"}
@@ -0,0 +1,9 @@
1
+ export * from "./use-apa.js";
2
+ export * from "./use-charter-booking.js";
3
+ export * from "./use-charter-product-mutation.js";
4
+ export * from "./use-charter-products.js";
5
+ export * from "./use-charter-public.js";
6
+ export * from "./use-charter-quote.js";
7
+ export * from "./use-charter-voyages.js";
8
+ export * from "./use-charter-yachts.js";
9
+ export * from "./use-myba-contract.js";
@@ -0,0 +1,130 @@
1
+ export interface ApaPaymentInput {
2
+ amount: string;
3
+ note?: string | null;
4
+ }
5
+ export interface ApaReconcileInput {
6
+ spentAmount?: string;
7
+ refundAmount?: string;
8
+ settle?: boolean;
9
+ note?: string | null;
10
+ }
11
+ /**
12
+ * Fetch the booking_charter_details row for a charter booking. Used by
13
+ * APA UI to show paid / spent / refund balances + settled timestamp.
14
+ */
15
+ export declare function useCharterDetails(bookingId: string | null | undefined, options?: {
16
+ enabled?: boolean;
17
+ }): import("@tanstack/react-query").UseQueryResult<{
18
+ bookingId: string;
19
+ bookingMode: "per_suite" | "whole_yacht";
20
+ source: "local" | "external";
21
+ sourceProvider: string | null;
22
+ sourceRef: Record<string, unknown> | null;
23
+ voyageId: string | null;
24
+ suiteId: string | null;
25
+ yachtId: string | null;
26
+ voyageDisplayName: string | null;
27
+ suiteDisplayName: string | null;
28
+ yachtName: string | null;
29
+ charterAreaSnapshot: string | null;
30
+ guestCount: number;
31
+ quotedCurrency: string;
32
+ quotedSuitePrice: string | null;
33
+ quotedPortFee: string | null;
34
+ quotedCharterFee: string | null;
35
+ apaPercent: string | null;
36
+ apaAmount: string | null;
37
+ quotedTotal: string;
38
+ mybaTemplateIdSnapshot: string | null;
39
+ mybaContractId: string | null;
40
+ apaPaidAmount: string | null;
41
+ apaSpentAmount: string | null;
42
+ apaRefundAmount: string | null;
43
+ apaSettledAt: string | null;
44
+ connectorBookingRef: string | null;
45
+ connectorStatus: string | null;
46
+ notes: string | null;
47
+ createdAt: string;
48
+ updatedAt: string;
49
+ }, Error>;
50
+ /**
51
+ * Record an APA payment for a whole-yacht booking. Adds to apaPaidAmount.
52
+ * Per-suite bookings reject with 400 (server-side guard).
53
+ */
54
+ export declare function useRecordApaPayment(): import("@tanstack/react-query").UseMutationResult<{
55
+ bookingId: string;
56
+ bookingMode: "per_suite" | "whole_yacht";
57
+ source: "local" | "external";
58
+ sourceProvider: string | null;
59
+ sourceRef: Record<string, unknown> | null;
60
+ voyageId: string | null;
61
+ suiteId: string | null;
62
+ yachtId: string | null;
63
+ voyageDisplayName: string | null;
64
+ suiteDisplayName: string | null;
65
+ yachtName: string | null;
66
+ charterAreaSnapshot: string | null;
67
+ guestCount: number;
68
+ quotedCurrency: string;
69
+ quotedSuitePrice: string | null;
70
+ quotedPortFee: string | null;
71
+ quotedCharterFee: string | null;
72
+ apaPercent: string | null;
73
+ apaAmount: string | null;
74
+ quotedTotal: string;
75
+ mybaTemplateIdSnapshot: string | null;
76
+ mybaContractId: string | null;
77
+ apaPaidAmount: string | null;
78
+ apaSpentAmount: string | null;
79
+ apaRefundAmount: string | null;
80
+ apaSettledAt: string | null;
81
+ connectorBookingRef: string | null;
82
+ connectorStatus: string | null;
83
+ notes: string | null;
84
+ createdAt: string;
85
+ updatedAt: string;
86
+ }, Error, {
87
+ bookingId: string;
88
+ input: ApaPaymentInput;
89
+ }, unknown>;
90
+ /**
91
+ * Post-charter APA reconciliation. Records what was actually spent on
92
+ * board + any refund due back to the charterer; optionally settles.
93
+ */
94
+ export declare function useReconcileApa(): import("@tanstack/react-query").UseMutationResult<{
95
+ bookingId: string;
96
+ bookingMode: "per_suite" | "whole_yacht";
97
+ source: "local" | "external";
98
+ sourceProvider: string | null;
99
+ sourceRef: Record<string, unknown> | null;
100
+ voyageId: string | null;
101
+ suiteId: string | null;
102
+ yachtId: string | null;
103
+ voyageDisplayName: string | null;
104
+ suiteDisplayName: string | null;
105
+ yachtName: string | null;
106
+ charterAreaSnapshot: string | null;
107
+ guestCount: number;
108
+ quotedCurrency: string;
109
+ quotedSuitePrice: string | null;
110
+ quotedPortFee: string | null;
111
+ quotedCharterFee: string | null;
112
+ apaPercent: string | null;
113
+ apaAmount: string | null;
114
+ quotedTotal: string;
115
+ mybaTemplateIdSnapshot: string | null;
116
+ mybaContractId: string | null;
117
+ apaPaidAmount: string | null;
118
+ apaSpentAmount: string | null;
119
+ apaRefundAmount: string | null;
120
+ apaSettledAt: string | null;
121
+ connectorBookingRef: string | null;
122
+ connectorStatus: string | null;
123
+ notes: string | null;
124
+ createdAt: string;
125
+ updatedAt: string;
126
+ }, Error, {
127
+ bookingId: string;
128
+ input: ApaReconcileInput;
129
+ }, unknown>;
130
+ //# sourceMappingURL=use-apa.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-apa.d.ts","sourceRoot":"","sources":["../../src/hooks/use-apa.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACrB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACpC,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAiBpC;AAED;;;GAGG;AACH,wBAAgB,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAUlB,MAAM;WACV,eAAe;YAkB3B;AAED;;;GAGG;AACH,wBAAgB,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAUd,MAAM;WACV,iBAAiB;YAkB7B"}
@@ -0,0 +1,60 @@
1
+ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
2
+ import { fetchWithValidation } from "../client.js";
3
+ import { useVoyantChartersContext } from "../provider.js";
4
+ import { chartersQueryKeys } from "../query-keys.js";
5
+ import { charterDetailResponse } from "../schemas.js";
6
+ /**
7
+ * Fetch the booking_charter_details row for a charter booking. Used by
8
+ * APA UI to show paid / spent / refund balances + settled timestamp.
9
+ */
10
+ export function useCharterDetails(bookingId, options = {}) {
11
+ const { baseUrl, fetcher } = useVoyantChartersContext();
12
+ const client = { baseUrl, fetcher };
13
+ const { enabled = true } = options;
14
+ return useQuery({
15
+ queryKey: ["voyant", "charters", "booking-details", bookingId ?? ""],
16
+ enabled: enabled && !!bookingId,
17
+ queryFn: async () => {
18
+ const result = await fetchWithValidation(`/v1/admin/bookings/${encodeURIComponent(bookingId ?? "")}/charter-details`, charterDetailResponse, client);
19
+ return result.data;
20
+ },
21
+ });
22
+ }
23
+ /**
24
+ * Record an APA payment for a whole-yacht booking. Adds to apaPaidAmount.
25
+ * Per-suite bookings reject with 400 (server-side guard).
26
+ */
27
+ export function useRecordApaPayment() {
28
+ const { baseUrl, fetcher } = useVoyantChartersContext();
29
+ const client = { baseUrl, fetcher };
30
+ const queryClient = useQueryClient();
31
+ return useMutation({
32
+ mutationFn: async ({ bookingId, input, }) => {
33
+ const result = await fetchWithValidation(`/v1/admin/bookings/${encodeURIComponent(bookingId)}/charter-details/apa/payment`, charterDetailResponse, client, { method: "POST", body: JSON.stringify(input) });
34
+ return result.data;
35
+ },
36
+ onSuccess: (data) => {
37
+ queryClient.setQueryData(["voyant", "charters", "booking-details", data.bookingId], data);
38
+ void queryClient.invalidateQueries({ queryKey: chartersQueryKeys.all });
39
+ },
40
+ });
41
+ }
42
+ /**
43
+ * Post-charter APA reconciliation. Records what was actually spent on
44
+ * board + any refund due back to the charterer; optionally settles.
45
+ */
46
+ export function useReconcileApa() {
47
+ const { baseUrl, fetcher } = useVoyantChartersContext();
48
+ const client = { baseUrl, fetcher };
49
+ const queryClient = useQueryClient();
50
+ return useMutation({
51
+ mutationFn: async ({ bookingId, input, }) => {
52
+ const result = await fetchWithValidation(`/v1/admin/bookings/${encodeURIComponent(bookingId)}/charter-details/apa/reconcile`, charterDetailResponse, client, { method: "POST", body: JSON.stringify(input) });
53
+ return result.data;
54
+ },
55
+ onSuccess: (data) => {
56
+ queryClient.setQueryData(["voyant", "charters", "booking-details", data.bookingId], data);
57
+ void queryClient.invalidateQueries({ queryKey: chartersQueryKeys.all });
58
+ },
59
+ });
60
+ }
@@ -0,0 +1,175 @@
1
+ import type { z } from "zod";
2
+ import { createBookingResponse } from "../schemas.js";
3
+ export interface CharterGuestInput {
4
+ firstName: string;
5
+ lastName: string;
6
+ email?: string | null;
7
+ phone?: string | null;
8
+ travelerCategory?: "adult" | "child" | "infant" | "senior" | "other" | null;
9
+ preferredLanguage?: string | null;
10
+ specialRequests?: string | null;
11
+ isPrimary?: boolean;
12
+ notes?: string | null;
13
+ }
14
+ export interface CharterContactInput {
15
+ firstName: string;
16
+ lastName: string;
17
+ email?: string | null;
18
+ phone?: string | null;
19
+ language?: string | null;
20
+ country?: string | null;
21
+ region?: string | null;
22
+ city?: string | null;
23
+ address?: string | null;
24
+ postalCode?: string | null;
25
+ }
26
+ export interface CreatePerSuiteBookingInput {
27
+ voyageId: string;
28
+ suiteId: string;
29
+ /** ISO-4217 currency code. The server resolves it against the voyage/suite price map. */
30
+ currency: string;
31
+ personId?: string | null;
32
+ organizationId?: string | null;
33
+ contact: CharterContactInput;
34
+ guests: CharterGuestInput[];
35
+ notes?: string | null;
36
+ }
37
+ export interface CreateWholeYachtBookingInput {
38
+ voyageId: string;
39
+ /** ISO-4217 currency code. The server resolves it against the voyage/suite price map. */
40
+ currency: string;
41
+ personId?: string | null;
42
+ organizationId?: string | null;
43
+ contact: CharterContactInput;
44
+ guests?: CharterGuestInput[];
45
+ notes?: string | null;
46
+ }
47
+ export type CreateCharterBookingResult = z.infer<typeof createBookingResponse>["data"];
48
+ /**
49
+ * Booking mutation set. The route layer detects local vs external voyages
50
+ * from the unified key and dispatches accordingly — this hook doesn't
51
+ * branch on provenance.
52
+ */
53
+ export declare function useCharterBookingMutation(): {
54
+ createPerSuite: import("@tanstack/react-query").UseMutationResult<{
55
+ bookingId: string;
56
+ bookingNumber: string;
57
+ charterDetails: {
58
+ bookingId: string;
59
+ bookingMode: "per_suite" | "whole_yacht";
60
+ source: "local" | "external";
61
+ sourceProvider: string | null;
62
+ sourceRef: Record<string, unknown> | null;
63
+ voyageId: string | null;
64
+ suiteId: string | null;
65
+ yachtId: string | null;
66
+ voyageDisplayName: string | null;
67
+ suiteDisplayName: string | null;
68
+ yachtName: string | null;
69
+ charterAreaSnapshot: string | null;
70
+ guestCount: number;
71
+ quotedCurrency: string;
72
+ quotedSuitePrice: string | null;
73
+ quotedPortFee: string | null;
74
+ quotedCharterFee: string | null;
75
+ apaPercent: string | null;
76
+ apaAmount: string | null;
77
+ quotedTotal: string;
78
+ mybaTemplateIdSnapshot: string | null;
79
+ mybaContractId: string | null;
80
+ apaPaidAmount: string | null;
81
+ apaSpentAmount: string | null;
82
+ apaRefundAmount: string | null;
83
+ apaSettledAt: string | null;
84
+ connectorBookingRef: string | null;
85
+ connectorStatus: string | null;
86
+ notes: string | null;
87
+ createdAt: string;
88
+ updatedAt: string;
89
+ };
90
+ quote: {
91
+ mode: "whole_yacht";
92
+ voyageId: string;
93
+ currency: string;
94
+ charterFee: string;
95
+ apaPercent: string;
96
+ apaAmount: string;
97
+ total: string;
98
+ } | {
99
+ mode: "per_suite";
100
+ voyageId: string;
101
+ suiteId: string;
102
+ suiteName: string;
103
+ currency: string;
104
+ suitePrice: string;
105
+ portFee: string | null;
106
+ total: string;
107
+ };
108
+ sourceProvider?: string | undefined;
109
+ sourceRef?: Record<string, unknown> | undefined;
110
+ }, Error, {
111
+ voyageKey: string;
112
+ input: CreatePerSuiteBookingInput;
113
+ }, unknown>;
114
+ createWholeYacht: import("@tanstack/react-query").UseMutationResult<{
115
+ bookingId: string;
116
+ bookingNumber: string;
117
+ charterDetails: {
118
+ bookingId: string;
119
+ bookingMode: "per_suite" | "whole_yacht";
120
+ source: "local" | "external";
121
+ sourceProvider: string | null;
122
+ sourceRef: Record<string, unknown> | null;
123
+ voyageId: string | null;
124
+ suiteId: string | null;
125
+ yachtId: string | null;
126
+ voyageDisplayName: string | null;
127
+ suiteDisplayName: string | null;
128
+ yachtName: string | null;
129
+ charterAreaSnapshot: string | null;
130
+ guestCount: number;
131
+ quotedCurrency: string;
132
+ quotedSuitePrice: string | null;
133
+ quotedPortFee: string | null;
134
+ quotedCharterFee: string | null;
135
+ apaPercent: string | null;
136
+ apaAmount: string | null;
137
+ quotedTotal: string;
138
+ mybaTemplateIdSnapshot: string | null;
139
+ mybaContractId: string | null;
140
+ apaPaidAmount: string | null;
141
+ apaSpentAmount: string | null;
142
+ apaRefundAmount: string | null;
143
+ apaSettledAt: string | null;
144
+ connectorBookingRef: string | null;
145
+ connectorStatus: string | null;
146
+ notes: string | null;
147
+ createdAt: string;
148
+ updatedAt: string;
149
+ };
150
+ quote: {
151
+ mode: "whole_yacht";
152
+ voyageId: string;
153
+ currency: string;
154
+ charterFee: string;
155
+ apaPercent: string;
156
+ apaAmount: string;
157
+ total: string;
158
+ } | {
159
+ mode: "per_suite";
160
+ voyageId: string;
161
+ suiteId: string;
162
+ suiteName: string;
163
+ currency: string;
164
+ suitePrice: string;
165
+ portFee: string | null;
166
+ total: string;
167
+ };
168
+ sourceProvider?: string | undefined;
169
+ sourceRef?: Record<string, unknown> | undefined;
170
+ }, Error, {
171
+ voyageKey: string;
172
+ input: CreateWholeYachtBookingInput;
173
+ }, unknown>;
174
+ };
175
+ //# sourceMappingURL=use-charter-booking.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-charter-booking.d.ts","sourceRoot":"","sources":["../../src/hooks/use-charter-booking.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAK5B,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAA;AAIrD,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,gBAAgB,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,IAAI,CAAA;IAC3E,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC3B;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,yFAAyF;IACzF,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,OAAO,EAAE,mBAAmB,CAAA;IAC5B,MAAM,EAAE,iBAAiB,EAAE,CAAA;IAC3B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACtB;AAED,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,EAAE,MAAM,CAAA;IAChB,yFAAyF;IACzF,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,OAAO,EAAE,mBAAmB,CAAA;IAC5B,MAAM,CAAC,EAAE,iBAAiB,EAAE,CAAA;IAC5B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACtB;AAED,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAA;AAEtF;;;;GAIG;AACH,wBAAgB,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAUxB,MAAM;eACV,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAuBtB,MAAM;eACV,4BAA4B;;EAkBxC"}
@@ -0,0 +1,39 @@
1
+ import { useMutation, useQueryClient } from "@tanstack/react-query";
2
+ import { fetchWithValidation } from "../client.js";
3
+ import { useVoyantChartersContext } from "../provider.js";
4
+ import { chartersQueryKeys } from "../query-keys.js";
5
+ import { createBookingResponse } from "../schemas.js";
6
+ /**
7
+ * Booking mutation set. The route layer detects local vs external voyages
8
+ * from the unified key and dispatches accordingly — this hook doesn't
9
+ * branch on provenance.
10
+ */
11
+ export function useCharterBookingMutation() {
12
+ const { baseUrl, fetcher } = useVoyantChartersContext();
13
+ const client = { baseUrl, fetcher };
14
+ const queryClient = useQueryClient();
15
+ const createPerSuite = useMutation({
16
+ mutationFn: async ({ voyageKey, input, }) => {
17
+ const result = await fetchWithValidation(`/v1/admin/charters/voyages/${encodeURIComponent(voyageKey)}/bookings/per-suite`, createBookingResponse, client, { method: "POST", body: JSON.stringify(input) });
18
+ return result.data;
19
+ },
20
+ onSuccess: () => {
21
+ // Suite availability may have changed; invalidate voyage detail to
22
+ // pull fresh suites.
23
+ void queryClient.invalidateQueries({ queryKey: chartersQueryKeys.voyages() });
24
+ void queryClient.invalidateQueries({ queryKey: chartersQueryKeys.products() });
25
+ },
26
+ });
27
+ const createWholeYacht = useMutation({
28
+ mutationFn: async ({ voyageKey, input, }) => {
29
+ const result = await fetchWithValidation(`/v1/admin/charters/voyages/${encodeURIComponent(voyageKey)}/bookings/whole-yacht`, createBookingResponse, client, { method: "POST", body: JSON.stringify(input) });
30
+ return result.data;
31
+ },
32
+ onSuccess: () => {
33
+ // Whole-yacht booking takes the entire voyage out of inventory.
34
+ void queryClient.invalidateQueries({ queryKey: chartersQueryKeys.voyages() });
35
+ void queryClient.invalidateQueries({ queryKey: chartersQueryKeys.products() });
36
+ },
37
+ });
38
+ return { createPerSuite, createWholeYacht };
39
+ }
@@ -0,0 +1,124 @@
1
+ export interface CreateCharterProductInput {
2
+ slug: string;
3
+ name: string;
4
+ lineSupplierId?: string | null;
5
+ defaultYachtId?: string | null;
6
+ description?: string | null;
7
+ shortDescription?: string | null;
8
+ heroImageUrl?: string | null;
9
+ mapImageUrl?: string | null;
10
+ regions?: string[];
11
+ themes?: string[];
12
+ status?: "draft" | "awaiting_review" | "live" | "archived";
13
+ defaultBookingModes?: Array<"per_suite" | "whole_yacht">;
14
+ defaultMybaTemplateId?: string | null;
15
+ defaultApaPercent?: string | null;
16
+ }
17
+ export type UpdateCharterProductInput = Partial<CreateCharterProductInput>;
18
+ /**
19
+ * Mutation set for self-managed charter products: create / update / archive /
20
+ * recompute aggregates. Writes against external products return 409 from
21
+ * the server; this hook surfaces those as VoyantApiError.
22
+ */
23
+ export declare function useCharterProductMutation(): {
24
+ create: import("@tanstack/react-query").UseMutationResult<{
25
+ id: string;
26
+ slug: string;
27
+ name: string;
28
+ lineSupplierId: string | null;
29
+ defaultYachtId: string | null;
30
+ description: string | null;
31
+ shortDescription: string | null;
32
+ heroImageUrl: string | null;
33
+ mapImageUrl: string | null;
34
+ regions: string[] | null;
35
+ themes: string[] | null;
36
+ status: "draft" | "awaiting_review" | "live" | "archived";
37
+ defaultBookingModes: ("per_suite" | "whole_yacht")[] | null;
38
+ defaultMybaTemplateId: string | null;
39
+ defaultApaPercent: string | null;
40
+ lowestPriceCachedAmount: string | null;
41
+ lowestPriceCachedCurrency: string | null;
42
+ earliestVoyageCached: string | null;
43
+ latestVoyageCached: string | null;
44
+ externalRefs: Record<string, string> | null;
45
+ createdAt: string;
46
+ updatedAt: string;
47
+ }, Error, CreateCharterProductInput, unknown>;
48
+ update: import("@tanstack/react-query").UseMutationResult<{
49
+ id: string;
50
+ slug: string;
51
+ name: string;
52
+ lineSupplierId: string | null;
53
+ defaultYachtId: string | null;
54
+ description: string | null;
55
+ shortDescription: string | null;
56
+ heroImageUrl: string | null;
57
+ mapImageUrl: string | null;
58
+ regions: string[] | null;
59
+ themes: string[] | null;
60
+ status: "draft" | "awaiting_review" | "live" | "archived";
61
+ defaultBookingModes: ("per_suite" | "whole_yacht")[] | null;
62
+ defaultMybaTemplateId: string | null;
63
+ defaultApaPercent: string | null;
64
+ lowestPriceCachedAmount: string | null;
65
+ lowestPriceCachedCurrency: string | null;
66
+ earliestVoyageCached: string | null;
67
+ latestVoyageCached: string | null;
68
+ externalRefs: Record<string, string> | null;
69
+ createdAt: string;
70
+ updatedAt: string;
71
+ }, Error, {
72
+ key: string;
73
+ input: UpdateCharterProductInput;
74
+ }, unknown>;
75
+ archive: import("@tanstack/react-query").UseMutationResult<{
76
+ id: string;
77
+ slug: string;
78
+ name: string;
79
+ lineSupplierId: string | null;
80
+ defaultYachtId: string | null;
81
+ description: string | null;
82
+ shortDescription: string | null;
83
+ heroImageUrl: string | null;
84
+ mapImageUrl: string | null;
85
+ regions: string[] | null;
86
+ themes: string[] | null;
87
+ status: "draft" | "awaiting_review" | "live" | "archived";
88
+ defaultBookingModes: ("per_suite" | "whole_yacht")[] | null;
89
+ defaultMybaTemplateId: string | null;
90
+ defaultApaPercent: string | null;
91
+ lowestPriceCachedAmount: string | null;
92
+ lowestPriceCachedCurrency: string | null;
93
+ earliestVoyageCached: string | null;
94
+ latestVoyageCached: string | null;
95
+ externalRefs: Record<string, string> | null;
96
+ createdAt: string;
97
+ updatedAt: string;
98
+ }, Error, string, unknown>;
99
+ recomputeAggregates: import("@tanstack/react-query").UseMutationResult<{
100
+ id: string;
101
+ slug: string;
102
+ name: string;
103
+ lineSupplierId: string | null;
104
+ defaultYachtId: string | null;
105
+ description: string | null;
106
+ shortDescription: string | null;
107
+ heroImageUrl: string | null;
108
+ mapImageUrl: string | null;
109
+ regions: string[] | null;
110
+ themes: string[] | null;
111
+ status: "draft" | "awaiting_review" | "live" | "archived";
112
+ defaultBookingModes: ("per_suite" | "whole_yacht")[] | null;
113
+ defaultMybaTemplateId: string | null;
114
+ defaultApaPercent: string | null;
115
+ lowestPriceCachedAmount: string | null;
116
+ lowestPriceCachedCurrency: string | null;
117
+ earliestVoyageCached: string | null;
118
+ latestVoyageCached: string | null;
119
+ externalRefs: Record<string, string> | null;
120
+ createdAt: string;
121
+ updatedAt: string;
122
+ }, Error, string, unknown>;
123
+ };
124
+ //# sourceMappingURL=use-charter-product-mutation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-charter-product-mutation.d.ts","sourceRoot":"","sources":["../../src/hooks/use-charter-product-mutation.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,MAAM,CAAC,EAAE,OAAO,GAAG,iBAAiB,GAAG,MAAM,GAAG,UAAU,CAAA;IAC1D,mBAAmB,CAAC,EAAE,KAAK,CAAC,WAAW,GAAG,aAAa,CAAC,CAAA;IACxD,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrC,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAClC;AAED,MAAM,MAAM,yBAAyB,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAA;AAE1E;;;;GAIG;AACH,wBAAgB,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAyB9B,MAAM;eACJ,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiDrC"}