@voyant-travel/cruises-react 0.118.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 (100) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +70 -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/cruise-catalog-card.d.ts +13 -0
  7. package/dist/components/cruise-catalog-card.d.ts.map +1 -0
  8. package/dist/components/cruise-catalog-card.js +58 -0
  9. package/dist/components/enrichment-program-list.d.ts +13 -0
  10. package/dist/components/enrichment-program-list.d.ts.map +1 -0
  11. package/dist/components/enrichment-program-list.js +45 -0
  12. package/dist/components/external-badge.d.ts +14 -0
  13. package/dist/components/external-badge.d.ts.map +1 -0
  14. package/dist/components/external-badge.js +17 -0
  15. package/dist/components/pricing-grid.d.ts +21 -0
  16. package/dist/components/pricing-grid.d.ts.map +1 -0
  17. package/dist/components/pricing-grid.js +81 -0
  18. package/dist/components/quote-display.d.ts +14 -0
  19. package/dist/components/quote-display.d.ts.map +1 -0
  20. package/dist/components/quote-display.js +61 -0
  21. package/dist/hooks/index.d.ts +15 -0
  22. package/dist/hooks/index.d.ts.map +1 -0
  23. package/dist/hooks/index.js +14 -0
  24. package/dist/hooks/use-cruise-booking.d.ts +205 -0
  25. package/dist/hooks/use-cruise-booking.d.ts.map +1 -0
  26. package/dist/hooks/use-cruise-booking.js +56 -0
  27. package/dist/hooks/use-cruise-mutation.d.ts +144 -0
  28. package/dist/hooks/use-cruise-mutation.d.ts.map +1 -0
  29. package/dist/hooks/use-cruise-mutation.js +58 -0
  30. package/dist/hooks/use-cruise.d.ts +38 -0
  31. package/dist/hooks/use-cruise.d.ts.map +1 -0
  32. package/dist/hooks/use-cruise.js +16 -0
  33. package/dist/hooks/use-cruises.d.ts +61 -0
  34. package/dist/hooks/use-cruises.d.ts.map +1 -0
  35. package/dist/hooks/use-cruises.js +16 -0
  36. package/dist/hooks/use-effective-itinerary.d.ts +27 -0
  37. package/dist/hooks/use-effective-itinerary.d.ts.map +1 -0
  38. package/dist/hooks/use-effective-itinerary.js +16 -0
  39. package/dist/hooks/use-enrichment.d.ts +72 -0
  40. package/dist/hooks/use-enrichment.d.ts.map +1 -0
  41. package/dist/hooks/use-enrichment.js +64 -0
  42. package/dist/hooks/use-external-actions.d.ts +43 -0
  43. package/dist/hooks/use-external-actions.d.ts.map +1 -0
  44. package/dist/hooks/use-external-actions.js +45 -0
  45. package/dist/hooks/use-pricing.d.ts +65 -0
  46. package/dist/hooks/use-pricing.d.ts.map +1 -0
  47. package/dist/hooks/use-pricing.js +28 -0
  48. package/dist/hooks/use-sailing-mutation.d.ts +147 -0
  49. package/dist/hooks/use-sailing-mutation.d.ts.map +1 -0
  50. package/dist/hooks/use-sailing-mutation.js +55 -0
  51. package/dist/hooks/use-sailings.d.ts +49 -0
  52. package/dist/hooks/use-sailings.d.ts.map +1 -0
  53. package/dist/hooks/use-sailings.js +20 -0
  54. package/dist/hooks/use-search-index.d.ts +43 -0
  55. package/dist/hooks/use-search-index.d.ts.map +1 -0
  56. package/dist/hooks/use-search-index.js +51 -0
  57. package/dist/hooks/use-ship-mutation.d.ts +186 -0
  58. package/dist/hooks/use-ship-mutation.d.ts.map +1 -0
  59. package/dist/hooks/use-ship-mutation.js +92 -0
  60. package/dist/hooks/use-ships.d.ts +101 -0
  61. package/dist/hooks/use-ships.d.ts.map +1 -0
  62. package/dist/hooks/use-ships.js +43 -0
  63. package/dist/hooks/use-storefront.d.ts +230 -0
  64. package/dist/hooks/use-storefront.d.ts.map +1 -0
  65. package/dist/hooks/use-storefront.js +62 -0
  66. package/dist/i18n/en.d.ts +3 -0
  67. package/dist/i18n/en.d.ts.map +1 -0
  68. package/dist/i18n/en.js +79 -0
  69. package/dist/i18n/index.d.ts +5 -0
  70. package/dist/i18n/index.d.ts.map +1 -0
  71. package/dist/i18n/index.js +3 -0
  72. package/dist/i18n/messages.d.ts +62 -0
  73. package/dist/i18n/messages.d.ts.map +1 -0
  74. package/dist/i18n/messages.js +1 -0
  75. package/dist/i18n/provider.d.ts +26 -0
  76. package/dist/i18n/provider.d.ts.map +1 -0
  77. package/dist/i18n/provider.js +44 -0
  78. package/dist/i18n/ro.d.ts +3 -0
  79. package/dist/i18n/ro.d.ts.map +1 -0
  80. package/dist/i18n/ro.js +79 -0
  81. package/dist/index.d.ts +7 -0
  82. package/dist/index.d.ts.map +1 -0
  83. package/dist/index.js +6 -0
  84. package/dist/provider.d.ts +2 -0
  85. package/dist/provider.d.ts.map +1 -0
  86. package/dist/provider.js +1 -0
  87. package/dist/query-keys.d.ts +82 -0
  88. package/dist/query-keys.d.ts.map +1 -0
  89. package/dist/query-keys.js +39 -0
  90. package/dist/query-options.d.ts +1272 -0
  91. package/dist/query-options.d.ts.map +1 -0
  92. package/dist/query-options.js +136 -0
  93. package/dist/schemas.d.ts +1061 -0
  94. package/dist/schemas.d.ts.map +1 -0
  95. package/dist/schemas.js +339 -0
  96. package/dist/ui.d.ts +6 -0
  97. package/dist/ui.d.ts.map +1 -0
  98. package/dist/ui.js +5 -0
  99. package/package.json +121 -0
  100. package/src/styles.css +11 -0
@@ -0,0 +1,61 @@
1
+ import type { CruisesListFilters } from "../query-keys.js";
2
+ export interface UseCruisesOptions extends CruisesListFilters {
3
+ enabled?: boolean;
4
+ }
5
+ /**
6
+ * Admin list of cruises — interleaves self-managed local rows with summaries
7
+ * from every registered adapter. Returns the unified envelope shape
8
+ * (`{ data, total, localTotal, adapterCount, adapterErrors? }`).
9
+ */
10
+ export declare function useCruises(options?: UseCruisesOptions): import("@tanstack/react-query").UseQueryResult<{
11
+ data: ({
12
+ source: "local";
13
+ sourceProvider: null;
14
+ sourceRef: null;
15
+ key: string;
16
+ cruise: {
17
+ id: string;
18
+ slug: string;
19
+ name: string;
20
+ cruiseType: "ocean" | "river" | "expedition" | "coastal";
21
+ lineSupplierId: string | null;
22
+ defaultShipId: string | null;
23
+ nights: number;
24
+ embarkPortFacilityId: string | null;
25
+ disembarkPortFacilityId: string | null;
26
+ description: string | null;
27
+ shortDescription: string | null;
28
+ highlights: string[] | null;
29
+ inclusionsHtml: string | null;
30
+ exclusionsHtml: string | null;
31
+ regions: string[] | null;
32
+ themes: string[] | null;
33
+ heroImageUrl: string | null;
34
+ mapImageUrl: string | null;
35
+ status: "draft" | "awaiting_review" | "live" | "archived";
36
+ lowestPriceCached: string | null;
37
+ lowestPriceCurrencyCached: string | null;
38
+ earliestDepartureCached: string | null;
39
+ latestDepartureCached: string | null;
40
+ externalRefs: Record<string, string> | null;
41
+ createdAt: string;
42
+ updatedAt: string;
43
+ };
44
+ } | {
45
+ source: "external";
46
+ sourceProvider: string;
47
+ sourceRef: Record<string, unknown>;
48
+ key: string;
49
+ cruise: unknown;
50
+ })[];
51
+ total: number;
52
+ localTotal: number;
53
+ adapterCount: number;
54
+ limit: number;
55
+ offset: number;
56
+ adapterErrors?: {
57
+ adapter: string;
58
+ error: string;
59
+ }[] | undefined;
60
+ }, Error>;
61
+ //# sourceMappingURL=use-cruises.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-cruises.d.ts","sourceRoot":"","sources":["../../src/hooks/use-cruises.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAG1D,MAAM,WAAW,iBAAkB,SAAQ,kBAAkB;IAC3D,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,OAAO,GAAE,iBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAOzD"}
@@ -0,0 +1,16 @@
1
+ import { useQuery } from "@tanstack/react-query";
2
+ import { useVoyantCruisesContext } from "../provider.js";
3
+ import { getCruisesQueryOptions } from "../query-options.js";
4
+ /**
5
+ * Admin list of cruises — interleaves self-managed local rows with summaries
6
+ * from every registered adapter. Returns the unified envelope shape
7
+ * (`{ data, total, localTotal, adapterCount, adapterErrors? }`).
8
+ */
9
+ export function useCruises(options = {}) {
10
+ const { baseUrl, fetcher } = useVoyantCruisesContext();
11
+ const { enabled = true, ...filters } = options;
12
+ return useQuery({
13
+ ...getCruisesQueryOptions({ baseUrl, fetcher }, filters),
14
+ enabled,
15
+ });
16
+ }
@@ -0,0 +1,27 @@
1
+ export interface UseEffectiveItineraryOptions {
2
+ enabled?: boolean;
3
+ }
4
+ /**
5
+ * Effective itinerary days for a sailing — returns the merged result of the
6
+ * cruise's day template plus per-sailing overrides (skipped ports, alternate
7
+ * times, ship swaps).
8
+ */
9
+ export declare function useEffectiveItinerary(sailingKey: string | null | undefined, options?: UseEffectiveItineraryOptions): import("@tanstack/react-query").UseQueryResult<{
10
+ dayNumber: number;
11
+ title: string | null;
12
+ description: string | null;
13
+ portFacilityId: string | null;
14
+ arrivalTime: string | null;
15
+ departureTime: string | null;
16
+ isOvernight: boolean;
17
+ isSeaDay: boolean;
18
+ isExpeditionLanding: boolean;
19
+ isSkipped: boolean;
20
+ hasOverride: boolean;
21
+ meals?: {
22
+ breakfast?: boolean | undefined;
23
+ lunch?: boolean | undefined;
24
+ dinner?: boolean | undefined;
25
+ } | undefined;
26
+ }[], Error>;
27
+ //# sourceMappingURL=use-effective-itinerary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-effective-itinerary.d.ts","sourceRoot":"","sources":["../../src/hooks/use-effective-itinerary.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,4BAA4B;IAC3C,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACrC,OAAO,GAAE,4BAAiC;;;;;;;;;;;;;;;;;YAQ3C"}
@@ -0,0 +1,16 @@
1
+ import { useQuery } from "@tanstack/react-query";
2
+ import { useVoyantCruisesContext } from "../provider.js";
3
+ import { getEffectiveItineraryQueryOptions } from "../query-options.js";
4
+ /**
5
+ * Effective itinerary days for a sailing — returns the merged result of the
6
+ * cruise's day template plus per-sailing overrides (skipped ports, alternate
7
+ * times, ship swaps).
8
+ */
9
+ export function useEffectiveItinerary(sailingKey, options = {}) {
10
+ const { baseUrl, fetcher } = useVoyantCruisesContext();
11
+ const { enabled = true } = options;
12
+ return useQuery({
13
+ ...getEffectiveItineraryQueryOptions({ baseUrl, fetcher }, sailingKey ?? ""),
14
+ enabled: enabled && !!sailingKey,
15
+ });
16
+ }
@@ -0,0 +1,72 @@
1
+ export interface UseEnrichmentProgramsOptions {
2
+ enabled?: boolean;
3
+ }
4
+ export declare function useEnrichmentPrograms(cruiseKey: string | null | undefined, options?: UseEnrichmentProgramsOptions): import("@tanstack/react-query").UseQueryResult<{
5
+ id: string;
6
+ cruiseId: string;
7
+ kind: "naturalist" | "historian" | "photographer" | "lecturer" | "expert" | "other";
8
+ name: string;
9
+ title: string | null;
10
+ description: string | null;
11
+ bioImageUrl: string | null;
12
+ sortOrder: number;
13
+ createdAt: string;
14
+ updatedAt: string;
15
+ }[], Error>;
16
+ export interface UpsertEnrichmentProgramInput {
17
+ kind: "naturalist" | "historian" | "photographer" | "lecturer" | "expert" | "other";
18
+ name: string;
19
+ title?: string | null;
20
+ description?: string | null;
21
+ bioImageUrl?: string | null;
22
+ sortOrder?: number;
23
+ }
24
+ export declare function useEnrichmentMutation(): {
25
+ create: import("@tanstack/react-query").UseMutationResult<{
26
+ id: string;
27
+ cruiseId: string;
28
+ kind: "naturalist" | "historian" | "photographer" | "lecturer" | "expert" | "other";
29
+ name: string;
30
+ title: string | null;
31
+ description: string | null;
32
+ bioImageUrl: string | null;
33
+ sortOrder: number;
34
+ createdAt: string;
35
+ updatedAt: string;
36
+ }, Error, {
37
+ cruiseKey: string;
38
+ input: UpsertEnrichmentProgramInput;
39
+ }, unknown>;
40
+ replaceAll: import("@tanstack/react-query").UseMutationResult<{
41
+ id: string;
42
+ cruiseId: string;
43
+ kind: "naturalist" | "historian" | "photographer" | "lecturer" | "expert" | "other";
44
+ name: string;
45
+ title: string | null;
46
+ description: string | null;
47
+ bioImageUrl: string | null;
48
+ sortOrder: number;
49
+ createdAt: string;
50
+ updatedAt: string;
51
+ }[], Error, {
52
+ cruiseKey: string;
53
+ programs: UpsertEnrichmentProgramInput[];
54
+ }, unknown>;
55
+ update: import("@tanstack/react-query").UseMutationResult<{
56
+ id: string;
57
+ cruiseId: string;
58
+ kind: "naturalist" | "historian" | "photographer" | "lecturer" | "expert" | "other";
59
+ name: string;
60
+ title: string | null;
61
+ description: string | null;
62
+ bioImageUrl: string | null;
63
+ sortOrder: number;
64
+ createdAt: string;
65
+ updatedAt: string;
66
+ }, Error, {
67
+ programId: string;
68
+ input: Partial<UpsertEnrichmentProgramInput>;
69
+ }, unknown>;
70
+ remove: import("@tanstack/react-query").UseMutationResult<boolean, Error, string, unknown>;
71
+ };
72
+ //# sourceMappingURL=use-enrichment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-enrichment.d.ts","sourceRoot":"","sources":["../../src/hooks/use-enrichment.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,4BAA4B;IAC3C,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACpC,OAAO,GAAE,4BAAiC;;;;;;;;;;;YAQ3C;AAED,MAAM,WAAW,4BAA4B;IAC3C,IAAI,EAAE,YAAY,GAAG,WAAW,GAAG,cAAc,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,CAAA;IACnF,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,qBAAqB;;;;;;;;;;;;;mBAUpB,MAAM;eACV,4BAA4B;;;;;;;;;;;;;;mBAoBxB,MAAM;kBACP,4BAA4B,EAAE;;;;;;;;;;;;;;mBAoB7B,MAAM;eACV,OAAO,CAAC,4BAA4B,CAAC;;;EAkCjD"}
@@ -0,0 +1,64 @@
1
+ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
2
+ import { fetchWithValidation } from "../client.js";
3
+ import { useVoyantCruisesContext } from "../provider.js";
4
+ import { cruisesQueryKeys } from "../query-keys.js";
5
+ import { getEnrichmentProgramsQueryOptions } from "../query-options.js";
6
+ import { enrichmentListResponse, enrichmentSingleResponse, } from "../schemas.js";
7
+ export function useEnrichmentPrograms(cruiseKey, options = {}) {
8
+ const { baseUrl, fetcher } = useVoyantCruisesContext();
9
+ const { enabled = true } = options;
10
+ return useQuery({
11
+ ...getEnrichmentProgramsQueryOptions({ baseUrl, fetcher }, cruiseKey ?? ""),
12
+ enabled: enabled && !!cruiseKey,
13
+ });
14
+ }
15
+ export function useEnrichmentMutation() {
16
+ const { baseUrl, fetcher } = useVoyantCruisesContext();
17
+ const client = { baseUrl, fetcher };
18
+ const queryClient = useQueryClient();
19
+ const create = useMutation({
20
+ mutationFn: async ({ cruiseKey, input, }) => {
21
+ const result = await fetchWithValidation(`/v1/admin/cruises/${encodeURIComponent(cruiseKey)}/enrichment`, enrichmentSingleResponse, client, { method: "POST", body: JSON.stringify(input) });
22
+ return result.data;
23
+ },
24
+ onSuccess: (_data, vars) => {
25
+ void queryClient.invalidateQueries({ queryKey: cruisesQueryKeys.enrichment(vars.cruiseKey) });
26
+ },
27
+ });
28
+ const replaceAll = useMutation({
29
+ mutationFn: async ({ cruiseKey, programs, }) => {
30
+ const result = await fetchWithValidation(`/v1/admin/cruises/${encodeURIComponent(cruiseKey)}/enrichment/bulk`, enrichmentListResponse, client, { method: "PUT", body: JSON.stringify({ programs }) });
31
+ return result.data;
32
+ },
33
+ onSuccess: (_data, vars) => {
34
+ void queryClient.invalidateQueries({ queryKey: cruisesQueryKeys.enrichment(vars.cruiseKey) });
35
+ },
36
+ });
37
+ const update = useMutation({
38
+ mutationFn: async ({ programId, input, }) => {
39
+ const result = await fetchWithValidation(`/v1/admin/cruises/enrichment/${encodeURIComponent(programId)}`, enrichmentSingleResponse, client, { method: "PUT", body: JSON.stringify(input) });
40
+ return result.data;
41
+ },
42
+ onSuccess: (data) => {
43
+ // We don't know the parent cruise key from the server response alone;
44
+ // invalidate broadly. Templates with hot lists can pass cruiseKey via
45
+ // mutation context if they want a tighter invalidation.
46
+ void queryClient.invalidateQueries({ queryKey: cruisesQueryKeys.cruises() });
47
+ void queryClient.invalidateQueries({
48
+ queryKey: cruisesQueryKeys.enrichment(data.cruiseId),
49
+ });
50
+ },
51
+ });
52
+ const remove = useMutation({
53
+ mutationFn: async (programId) => {
54
+ const headers = new Headers();
55
+ const url = `${baseUrl.replace(/\/$/, "")}/v1/admin/cruises/enrichment/${encodeURIComponent(programId)}`;
56
+ const res = await fetcher(url, { method: "DELETE", headers });
57
+ return res.ok;
58
+ },
59
+ onSuccess: () => {
60
+ void queryClient.invalidateQueries({ queryKey: cruisesQueryKeys.cruises() });
61
+ },
62
+ });
63
+ return { create, replaceAll, update, remove };
64
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * External-source admin actions: refresh re-fetches the cruise from the
3
+ * adapter; detach takes a one-way snapshot, creating a local cruise (with
4
+ * ship + categories + sailings + day overrides) and severing the link.
5
+ */
6
+ export declare function useExternalCruiseActions(): {
7
+ refresh: import("@tanstack/react-query").UseMutationResult<{
8
+ source: "external";
9
+ sourceProvider: string;
10
+ sourceRef: Record<string, unknown>;
11
+ cruise: unknown;
12
+ refreshedAt: string;
13
+ }, Error, string, unknown>;
14
+ detach: import("@tanstack/react-query").UseMutationResult<{
15
+ id: string;
16
+ slug: string;
17
+ name: string;
18
+ cruiseType: "ocean" | "river" | "expedition" | "coastal";
19
+ lineSupplierId: string | null;
20
+ defaultShipId: string | null;
21
+ nights: number;
22
+ embarkPortFacilityId: string | null;
23
+ disembarkPortFacilityId: string | null;
24
+ description: string | null;
25
+ shortDescription: string | null;
26
+ highlights: string[] | null;
27
+ inclusionsHtml: string | null;
28
+ exclusionsHtml: string | null;
29
+ regions: string[] | null;
30
+ themes: string[] | null;
31
+ heroImageUrl: string | null;
32
+ mapImageUrl: string | null;
33
+ status: "draft" | "awaiting_review" | "live" | "archived";
34
+ lowestPriceCached: string | null;
35
+ lowestPriceCurrencyCached: string | null;
36
+ earliestDepartureCached: string | null;
37
+ latestDepartureCached: string | null;
38
+ externalRefs: Record<string, string> | null;
39
+ createdAt: string;
40
+ updatedAt: string;
41
+ }, Error, string, unknown>;
42
+ };
43
+ //# sourceMappingURL=use-external-actions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-external-actions.d.ts","sourceRoot":"","sources":["../../src/hooks/use-external-actions.ts"],"names":[],"mappings":"AAoBA;;;;GAIG;AACH,wBAAgB,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsCvC"}
@@ -0,0 +1,45 @@
1
+ import { useMutation, useQueryClient } from "@tanstack/react-query";
2
+ import { z } from "zod";
3
+ import { fetchWithValidation } from "../client.js";
4
+ import { useVoyantCruisesContext } from "../provider.js";
5
+ import { cruisesQueryKeys } from "../query-keys.js";
6
+ import { cruiseRecordSchema, singleEnvelope } from "../schemas.js";
7
+ const refreshResponseSchema = singleEnvelope(z.object({
8
+ source: z.literal("external"),
9
+ sourceProvider: z.string(),
10
+ sourceRef: z.record(z.string(), z.unknown()),
11
+ cruise: z.unknown(),
12
+ refreshedAt: z.string(),
13
+ }));
14
+ const detachResponseSchema = singleEnvelope(cruiseRecordSchema);
15
+ /**
16
+ * External-source admin actions: refresh re-fetches the cruise from the
17
+ * adapter; detach takes a one-way snapshot, creating a local cruise (with
18
+ * ship + categories + sailings + day overrides) and severing the link.
19
+ */
20
+ export function useExternalCruiseActions() {
21
+ const { baseUrl, fetcher } = useVoyantCruisesContext();
22
+ const client = { baseUrl, fetcher };
23
+ const queryClient = useQueryClient();
24
+ const refresh = useMutation({
25
+ mutationFn: async (key) => {
26
+ const result = await fetchWithValidation(`/v1/admin/cruises/${encodeURIComponent(key)}/refresh`, refreshResponseSchema, client, { method: "POST" });
27
+ return result.data;
28
+ },
29
+ onSuccess: (_data, key) => {
30
+ void queryClient.invalidateQueries({ queryKey: cruisesQueryKeys.cruise(key) });
31
+ },
32
+ });
33
+ const detach = useMutation({
34
+ mutationFn: async (key) => {
35
+ const result = await fetchWithValidation(`/v1/admin/cruises/${encodeURIComponent(key)}/detach`, detachResponseSchema, client, { method: "POST" });
36
+ return result.data;
37
+ },
38
+ onSuccess: () => {
39
+ void queryClient.invalidateQueries({ queryKey: cruisesQueryKeys.cruises() });
40
+ void queryClient.invalidateQueries({ queryKey: cruisesQueryKeys.ships() });
41
+ void queryClient.invalidateQueries({ queryKey: cruisesQueryKeys.sailings() });
42
+ },
43
+ });
44
+ return { refresh, detach };
45
+ }
@@ -0,0 +1,65 @@
1
+ import type { PricesListFilters } from "../query-keys.js";
2
+ export interface UsePricesOptions extends PricesListFilters {
3
+ enabled?: boolean;
4
+ }
5
+ export declare function usePrices(options?: UsePricesOptions): import("@tanstack/react-query").UseQueryResult<{
6
+ data: {
7
+ id: string;
8
+ sailingId: string;
9
+ cabinCategoryId: string;
10
+ occupancy: number;
11
+ fareCode: string | null;
12
+ fareCodeName: string | null;
13
+ currency: string;
14
+ pricePerPerson: string;
15
+ secondGuestPricePerPerson: string | null;
16
+ singleSupplementPercent: string | null;
17
+ availability: "on_request" | "wait_list" | "sold_out" | "available" | "limited";
18
+ availabilityCount: number | null;
19
+ priceCatalogId: string | null;
20
+ priceScheduleId: string | null;
21
+ bookingDeadline: string | null;
22
+ requiresRequest: boolean;
23
+ notes: string | null;
24
+ externalRefs: Record<string, string> | null;
25
+ lastSyncedAt: string | null;
26
+ createdAt: string;
27
+ updatedAt: string;
28
+ }[];
29
+ total: number;
30
+ limit: number;
31
+ offset: number;
32
+ }, Error>;
33
+ export interface QuoteRequestInput {
34
+ cabinCategoryId: string;
35
+ occupancy: number;
36
+ guestCount: number;
37
+ fareCode?: string | null;
38
+ }
39
+ /**
40
+ * Quote a cabin against a sailing. Mutation rather than query because the
41
+ * server validates inputs and runs the composeQuote pipeline — caching by
42
+ * input is the caller's choice (template's React Query config).
43
+ */
44
+ export declare function useQuote(): import("@tanstack/react-query").UseMutationResult<{
45
+ fareCode: string | null;
46
+ fareCodeName: string | null;
47
+ currency: string;
48
+ occupancy: number;
49
+ guestCount: number;
50
+ basePerPerson: string;
51
+ components: {
52
+ kind: "gratuity" | "onboard_credit" | "port_charge" | "tax" | "ncf" | "airfare" | "transfer" | "insurance";
53
+ label: string | null;
54
+ amount: string;
55
+ currency: string;
56
+ direction: "addition" | "inclusion" | "credit";
57
+ perPerson: boolean;
58
+ }[];
59
+ totalPerPerson: string;
60
+ totalForCabin: string;
61
+ }, Error, {
62
+ sailingKey: string;
63
+ input: QuoteRequestInput;
64
+ }, unknown>;
65
+ //# sourceMappingURL=use-pricing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-pricing.d.ts","sourceRoot":"","sources":["../../src/hooks/use-pricing.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAIzD,MAAM,WAAW,gBAAiB,SAAQ,iBAAiB;IACzD,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,wBAAgB,SAAS,CAAC,OAAO,GAAE,gBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;UAOvD;AAED,MAAM,WAAW,iBAAiB;IAChC,eAAe,EAAE,MAAM,CAAA;IACvB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACzB;AAED;;;;GAIG;AACH,wBAAgB,QAAQ;;;;;;;;;;;;;;;;;;gBAQN,MAAM;WACX,iBAAiB;YAW7B"}
@@ -0,0 +1,28 @@
1
+ import { useMutation, useQuery } from "@tanstack/react-query";
2
+ import { fetchWithValidation } from "../client.js";
3
+ import { useVoyantCruisesContext } from "../provider.js";
4
+ import { getPricesQueryOptions } from "../query-options.js";
5
+ import { quoteResponse } from "../schemas.js";
6
+ export function usePrices(options = {}) {
7
+ const { baseUrl, fetcher } = useVoyantCruisesContext();
8
+ const { enabled = true, ...filters } = options;
9
+ return useQuery({
10
+ ...getPricesQueryOptions({ baseUrl, fetcher }, filters),
11
+ enabled,
12
+ });
13
+ }
14
+ /**
15
+ * Quote a cabin against a sailing. Mutation rather than query because the
16
+ * server validates inputs and runs the composeQuote pipeline — caching by
17
+ * input is the caller's choice (template's React Query config).
18
+ */
19
+ export function useQuote() {
20
+ const { baseUrl, fetcher } = useVoyantCruisesContext();
21
+ const client = { baseUrl, fetcher };
22
+ return useMutation({
23
+ mutationFn: async ({ sailingKey, input, }) => {
24
+ const result = await fetchWithValidation(`/v1/admin/cruises/sailings/${encodeURIComponent(sailingKey)}/quote`, quoteResponse, client, { method: "POST", body: JSON.stringify(input) });
25
+ return result.data;
26
+ },
27
+ });
28
+ }
@@ -0,0 +1,147 @@
1
+ export interface UpsertSailingInput {
2
+ cruiseId: string;
3
+ shipId: string;
4
+ departureDate: string;
5
+ returnDate: string;
6
+ embarkPortFacilityId?: string | null;
7
+ disembarkPortFacilityId?: string | null;
8
+ direction?: "upstream" | "downstream" | "round_trip" | "one_way" | null;
9
+ availabilityNote?: string | null;
10
+ isCharter?: boolean;
11
+ salesStatus?: "open" | "on_request" | "wait_list" | "sold_out" | "closed";
12
+ externalRefs?: Record<string, string>;
13
+ }
14
+ export type UpdateSailingInput = Partial<UpsertSailingInput>;
15
+ export interface ReplaceSailingDaysInput {
16
+ days: Array<{
17
+ dayNumber: number;
18
+ title?: string | null;
19
+ description?: string | null;
20
+ portFacilityId?: string | null;
21
+ arrivalTime?: string | null;
22
+ departureTime?: string | null;
23
+ isOvernight?: boolean | null;
24
+ isSeaDay?: boolean | null;
25
+ isExpeditionLanding?: boolean | null;
26
+ isSkipped?: boolean;
27
+ meals?: {
28
+ breakfast?: boolean;
29
+ lunch?: boolean;
30
+ dinner?: boolean;
31
+ } | null;
32
+ }>;
33
+ }
34
+ export interface ReplaceSailingPricingInput {
35
+ prices: Array<{
36
+ cabinCategoryId: string;
37
+ occupancy: number;
38
+ fareCode?: string | null;
39
+ fareCodeName?: string | null;
40
+ currency: string;
41
+ pricePerPerson: string;
42
+ secondGuestPricePerPerson?: string | null;
43
+ singleSupplementPercent?: string | null;
44
+ availability?: "available" | "limited" | "on_request" | "wait_list" | "sold_out";
45
+ availabilityCount?: number | null;
46
+ priceCatalogId?: string | null;
47
+ priceScheduleId?: string | null;
48
+ bookingDeadline?: string | null;
49
+ requiresRequest?: boolean;
50
+ notes?: string | null;
51
+ components?: Array<{
52
+ kind: "gratuity" | "onboard_credit" | "port_charge" | "tax" | "ncf" | "airfare" | "transfer" | "insurance";
53
+ label?: string | null;
54
+ amount: string;
55
+ currency: string;
56
+ direction: "addition" | "inclusion" | "credit";
57
+ perPerson: boolean;
58
+ }>;
59
+ }>;
60
+ }
61
+ export declare function useSailingMutation(): {
62
+ upsert: import("@tanstack/react-query").UseMutationResult<{
63
+ id: string;
64
+ cruiseId: string;
65
+ shipId: string;
66
+ departureDate: string;
67
+ returnDate: string;
68
+ embarkPortFacilityId: string | null;
69
+ disembarkPortFacilityId: string | null;
70
+ direction: "upstream" | "downstream" | "round_trip" | "one_way" | null;
71
+ availabilityNote: string | null;
72
+ isCharter: boolean;
73
+ salesStatus: "open" | "on_request" | "wait_list" | "sold_out" | "closed";
74
+ externalRefs: Record<string, string> | null;
75
+ lastSyncedAt: string | null;
76
+ createdAt: string;
77
+ updatedAt: string;
78
+ }, Error, UpsertSailingInput, unknown>;
79
+ update: import("@tanstack/react-query").UseMutationResult<{
80
+ id: string;
81
+ cruiseId: string;
82
+ shipId: string;
83
+ departureDate: string;
84
+ returnDate: string;
85
+ embarkPortFacilityId: string | null;
86
+ disembarkPortFacilityId: string | null;
87
+ direction: "upstream" | "downstream" | "round_trip" | "one_way" | null;
88
+ availabilityNote: string | null;
89
+ isCharter: boolean;
90
+ salesStatus: "open" | "on_request" | "wait_list" | "sold_out" | "closed";
91
+ externalRefs: Record<string, string> | null;
92
+ lastSyncedAt: string | null;
93
+ createdAt: string;
94
+ updatedAt: string;
95
+ }, Error, {
96
+ key: string;
97
+ input: UpdateSailingInput;
98
+ }, unknown>;
99
+ replaceDays: import("@tanstack/react-query").UseMutationResult<{
100
+ dayNumber: number;
101
+ title: string | null;
102
+ description: string | null;
103
+ portFacilityId: string | null;
104
+ arrivalTime: string | null;
105
+ departureTime: string | null;
106
+ isOvernight: boolean;
107
+ isSeaDay: boolean;
108
+ isExpeditionLanding: boolean;
109
+ isSkipped: boolean;
110
+ hasOverride: boolean;
111
+ meals?: {
112
+ breakfast?: boolean | undefined;
113
+ lunch?: boolean | undefined;
114
+ dinner?: boolean | undefined;
115
+ } | undefined;
116
+ }[], Error, {
117
+ key: string;
118
+ input: ReplaceSailingDaysInput;
119
+ }, unknown>;
120
+ replacePricing: import("@tanstack/react-query").UseMutationResult<{
121
+ id: string;
122
+ sailingId: string;
123
+ cabinCategoryId: string;
124
+ occupancy: number;
125
+ fareCode: string | null;
126
+ fareCodeName: string | null;
127
+ currency: string;
128
+ pricePerPerson: string;
129
+ secondGuestPricePerPerson: string | null;
130
+ singleSupplementPercent: string | null;
131
+ availability: "on_request" | "wait_list" | "sold_out" | "available" | "limited";
132
+ availabilityCount: number | null;
133
+ priceCatalogId: string | null;
134
+ priceScheduleId: string | null;
135
+ bookingDeadline: string | null;
136
+ requiresRequest: boolean;
137
+ notes: string | null;
138
+ externalRefs: Record<string, string> | null;
139
+ lastSyncedAt: string | null;
140
+ createdAt: string;
141
+ updatedAt: string;
142
+ }[], Error, {
143
+ key: string;
144
+ input: ReplaceSailingPricingInput;
145
+ }, unknown>;
146
+ };
147
+ //# sourceMappingURL=use-sailing-mutation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-sailing-mutation.d.ts","sourceRoot":"","sources":["../../src/hooks/use-sailing-mutation.ts"],"names":[],"mappings":"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"}