@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,55 @@
1
+ import { useMutation, 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 { effectiveItineraryResponse, listEnvelope, priceRecordSchema, sailingSingleResponse, } from "../schemas.js";
6
+ const priceListWrapped = listEnvelope(priceRecordSchema);
7
+ export function useSailingMutation() {
8
+ const { baseUrl, fetcher } = useVoyantCruisesContext();
9
+ const client = { baseUrl, fetcher };
10
+ const queryClient = useQueryClient();
11
+ const upsert = useMutation({
12
+ mutationFn: async (input) => {
13
+ const result = await fetchWithValidation("/v1/admin/cruises/sailings", sailingSingleResponse, client, { method: "POST", body: JSON.stringify(input) });
14
+ return result.data;
15
+ },
16
+ onSuccess: () => {
17
+ void queryClient.invalidateQueries({ queryKey: cruisesQueryKeys.sailings() });
18
+ void queryClient.invalidateQueries({ queryKey: cruisesQueryKeys.cruises() });
19
+ },
20
+ });
21
+ const update = useMutation({
22
+ mutationFn: async ({ key, input, }) => {
23
+ const result = await fetchWithValidation(`/v1/admin/cruises/sailings/${encodeURIComponent(key)}`, sailingSingleResponse, client, { method: "PUT", body: JSON.stringify(input) });
24
+ return result.data;
25
+ },
26
+ onSuccess: (data) => {
27
+ void queryClient.invalidateQueries({ queryKey: cruisesQueryKeys.sailings() });
28
+ queryClient.setQueryData(cruisesQueryKeys.sailing(data.id), data);
29
+ },
30
+ });
31
+ const replaceDays = useMutation({
32
+ mutationFn: async ({ key, input, }) => {
33
+ const result = await fetchWithValidation(`/v1/admin/cruises/sailings/${encodeURIComponent(key)}/days/bulk`, effectiveItineraryResponse, client, { method: "PUT", body: JSON.stringify(input) });
34
+ return result.data;
35
+ },
36
+ onSuccess: (_data, vars) => {
37
+ void queryClient.invalidateQueries({
38
+ queryKey: cruisesQueryKeys.sailingItinerary(vars.key),
39
+ });
40
+ void queryClient.invalidateQueries({ queryKey: cruisesQueryKeys.sailings() });
41
+ },
42
+ });
43
+ const replacePricing = useMutation({
44
+ mutationFn: async ({ key, input, }) => {
45
+ const result = await fetchWithValidation(`/v1/admin/cruises/sailings/${encodeURIComponent(key)}/pricing/bulk`, priceListWrapped, client, { method: "PUT", body: JSON.stringify(input) });
46
+ return result.data;
47
+ },
48
+ onSuccess: () => {
49
+ void queryClient.invalidateQueries({ queryKey: cruisesQueryKeys.prices() });
50
+ void queryClient.invalidateQueries({ queryKey: cruisesQueryKeys.sailings() });
51
+ void queryClient.invalidateQueries({ queryKey: cruisesQueryKeys.cruises() });
52
+ },
53
+ });
54
+ return { upsert, update, replaceDays, replacePricing };
55
+ }
@@ -0,0 +1,49 @@
1
+ import type { SailingsListFilters } from "../query-keys.js";
2
+ export interface UseSailingsOptions extends SailingsListFilters {
3
+ enabled?: boolean;
4
+ }
5
+ export declare function useSailings(options?: UseSailingsOptions): import("@tanstack/react-query").UseQueryResult<{
6
+ data: {
7
+ id: string;
8
+ cruiseId: string;
9
+ shipId: string;
10
+ departureDate: string;
11
+ returnDate: string;
12
+ embarkPortFacilityId: string | null;
13
+ disembarkPortFacilityId: string | null;
14
+ direction: "upstream" | "downstream" | "round_trip" | "one_way" | null;
15
+ availabilityNote: string | null;
16
+ isCharter: boolean;
17
+ salesStatus: "open" | "on_request" | "wait_list" | "sold_out" | "closed";
18
+ externalRefs: Record<string, string> | null;
19
+ lastSyncedAt: string | null;
20
+ createdAt: string;
21
+ updatedAt: string;
22
+ }[];
23
+ total: number;
24
+ limit: number;
25
+ offset: number;
26
+ }, Error>;
27
+ export interface UseSailingOptions {
28
+ enabled?: boolean;
29
+ include?: ReadonlyArray<"pricing" | "itinerary">;
30
+ }
31
+ /** Sailing detail by unified key (local TypeID or `<provider>:<ref>`). */
32
+ export declare function useSailing(key: string | null | undefined, options?: UseSailingOptions): import("@tanstack/react-query").UseQueryResult<{
33
+ id: string;
34
+ cruiseId: string;
35
+ shipId: string;
36
+ departureDate: string;
37
+ returnDate: string;
38
+ embarkPortFacilityId: string | null;
39
+ disembarkPortFacilityId: string | null;
40
+ direction: "upstream" | "downstream" | "round_trip" | "one_way" | null;
41
+ availabilityNote: string | null;
42
+ isCharter: boolean;
43
+ salesStatus: "open" | "on_request" | "wait_list" | "sold_out" | "closed";
44
+ externalRefs: Record<string, string> | null;
45
+ lastSyncedAt: string | null;
46
+ createdAt: string;
47
+ updatedAt: string;
48
+ }, Error>;
49
+ //# sourceMappingURL=use-sailings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-sailings.d.ts","sourceRoot":"","sources":["../../src/hooks/use-sailings.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AAG3D,MAAM,WAAW,kBAAmB,SAAQ,mBAAmB;IAC7D,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,wBAAgB,WAAW,CAAC,OAAO,GAAE,kBAAuB;;;;;;;;;;;;;;;;;;;;;UAO3D;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,OAAO,CAAC,EAAE,aAAa,CAAC,SAAS,GAAG,WAAW,CAAC,CAAA;CACjD;AAED,0EAA0E;AAC1E,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,OAAO,GAAE,iBAAsB;;;;;;;;;;;;;;;;UAOzF"}
@@ -0,0 +1,20 @@
1
+ import { useQuery } from "@tanstack/react-query";
2
+ import { useVoyantCruisesContext } from "../provider.js";
3
+ import { getSailingQueryOptions, getSailingsQueryOptions } from "../query-options.js";
4
+ export function useSailings(options = {}) {
5
+ const { baseUrl, fetcher } = useVoyantCruisesContext();
6
+ const { enabled = true, ...filters } = options;
7
+ return useQuery({
8
+ ...getSailingsQueryOptions({ baseUrl, fetcher }, filters),
9
+ enabled,
10
+ });
11
+ }
12
+ /** Sailing detail by unified key (local TypeID or `<provider>:<ref>`). */
13
+ export function useSailing(key, options = {}) {
14
+ const { baseUrl, fetcher } = useVoyantCruisesContext();
15
+ const { enabled = true, include } = options;
16
+ return useQuery({
17
+ ...getSailingQueryOptions({ baseUrl, fetcher }, key ?? "", { include }),
18
+ enabled: enabled && !!key,
19
+ });
20
+ }
@@ -0,0 +1,43 @@
1
+ export interface SearchIndexBulkEntry {
2
+ source: "local" | "external";
3
+ sourceProvider?: string | null;
4
+ sourceRef?: Record<string, unknown> | null;
5
+ localCruiseId?: string | null;
6
+ slug: string;
7
+ name: string;
8
+ cruiseType: "ocean" | "river" | "expedition" | "coastal";
9
+ lineName: string;
10
+ shipName: string;
11
+ nights: number;
12
+ embarkPortName?: string | null;
13
+ disembarkPortName?: string | null;
14
+ regions?: string[];
15
+ themes?: string[];
16
+ earliestDeparture?: string | null;
17
+ latestDeparture?: string | null;
18
+ departureCount?: number | null;
19
+ lowestPriceCents?: number | null;
20
+ lowestPriceCurrency?: string | null;
21
+ salesStatus?: string | null;
22
+ heroImageUrl?: string | null;
23
+ }
24
+ /**
25
+ * Storefront search-index admin actions. Adapters call `bulkUpsert` to push
26
+ * external entries; operators trigger `rebuildAll` to repair drift across
27
+ * both local and external sources.
28
+ */
29
+ export declare function useSearchIndexMutation(): {
30
+ bulkUpsert: import("@tanstack/react-query").UseMutationResult<{
31
+ upserted: number;
32
+ }, Error, SearchIndexBulkEntry[], unknown>;
33
+ remove: import("@tanstack/react-query").UseMutationResult<boolean, Error, string, unknown>;
34
+ rebuildAll: import("@tanstack/react-query").UseMutationResult<{
35
+ localUpserted: number;
36
+ externalUpserted: number;
37
+ externalErrors: {
38
+ adapter: string;
39
+ error: string;
40
+ }[];
41
+ }, Error, void, unknown>;
42
+ };
43
+ //# sourceMappingURL=use-search-index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-search-index.d.ts","sourceRoot":"","sources":["../../src/hooks/use-search-index.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,OAAO,GAAG,UAAU,CAAA;IAC5B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IAC1C,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,OAAO,GAAG,OAAO,GAAG,YAAY,GAAG,SAAS,CAAA;IACxD,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACnC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC7B;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB;;;;;;;;;;;;;EA+CrC"}
@@ -0,0 +1,51 @@
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 { singleEnvelope } from "../schemas.js";
7
+ const bulkResponseSchema = singleEnvelope(z.object({ upserted: z.number().int() }));
8
+ const rebuildResponseSchema = singleEnvelope(z.object({
9
+ localUpserted: z.number().int(),
10
+ externalUpserted: z.number().int(),
11
+ externalErrors: z.array(z.object({ adapter: z.string(), error: z.string() })),
12
+ }));
13
+ /**
14
+ * Storefront search-index admin actions. Adapters call `bulkUpsert` to push
15
+ * external entries; operators trigger `rebuildAll` to repair drift across
16
+ * both local and external sources.
17
+ */
18
+ export function useSearchIndexMutation() {
19
+ const { baseUrl, fetcher } = useVoyantCruisesContext();
20
+ const client = { baseUrl, fetcher };
21
+ const queryClient = useQueryClient();
22
+ const bulkUpsert = useMutation({
23
+ mutationFn: async (entries) => {
24
+ const result = await fetchWithValidation("/v1/admin/cruises/search-index/bulk", bulkResponseSchema, client, { method: "PUT", body: JSON.stringify({ entries }) });
25
+ return result.data;
26
+ },
27
+ onSuccess: () => {
28
+ void queryClient.invalidateQueries({ queryKey: cruisesQueryKeys.storefront() });
29
+ },
30
+ });
31
+ const remove = useMutation({
32
+ mutationFn: async (entryId) => {
33
+ const url = `${baseUrl.replace(/\/$/, "")}/v1/admin/cruises/search-index/${encodeURIComponent(entryId)}`;
34
+ const res = await fetcher(url, { method: "DELETE" });
35
+ return res.ok;
36
+ },
37
+ onSuccess: () => {
38
+ void queryClient.invalidateQueries({ queryKey: cruisesQueryKeys.storefront() });
39
+ },
40
+ });
41
+ const rebuildAll = useMutation({
42
+ mutationFn: async () => {
43
+ const result = await fetchWithValidation("/v1/admin/cruises/search-index/rebuild", rebuildResponseSchema, client, { method: "POST" });
44
+ return result.data;
45
+ },
46
+ onSuccess: () => {
47
+ void queryClient.invalidateQueries({ queryKey: cruisesQueryKeys.storefront() });
48
+ },
49
+ });
50
+ return { bulkUpsert, remove, rebuildAll };
51
+ }
@@ -0,0 +1,186 @@
1
+ export interface CreateShipInput {
2
+ name: string;
3
+ slug: string;
4
+ shipType: "ocean" | "river" | "expedition" | "yacht" | "sailing" | "coastal";
5
+ lineSupplierId?: string | null;
6
+ capacityGuests?: number | null;
7
+ capacityCrew?: number | null;
8
+ cabinCount?: number | null;
9
+ deckCount?: number | null;
10
+ lengthMeters?: string | null;
11
+ cruisingSpeedKnots?: string | null;
12
+ yearBuilt?: number | null;
13
+ yearRefurbished?: number | null;
14
+ imo?: string | null;
15
+ description?: string | null;
16
+ deckPlanUrl?: string | null;
17
+ gallery?: string[];
18
+ amenities?: Record<string, unknown>;
19
+ isActive?: boolean;
20
+ }
21
+ export type UpdateShipInput = Partial<CreateShipInput>;
22
+ export interface UpsertDeckInput {
23
+ name: string;
24
+ level?: number | null;
25
+ planImageUrl?: string | null;
26
+ }
27
+ export interface UpsertCabinCategoryInput {
28
+ shipId: string;
29
+ code: string;
30
+ name: string;
31
+ roomType: "inside" | "oceanview" | "balcony" | "suite" | "penthouse" | "single";
32
+ description?: string | null;
33
+ minOccupancy?: number;
34
+ maxOccupancy: number;
35
+ squareFeet?: string | null;
36
+ wheelchairAccessible?: boolean;
37
+ amenities?: string[];
38
+ images?: string[];
39
+ floorplanImages?: string[];
40
+ gradeCodes?: string[];
41
+ }
42
+ export interface UpsertCabinInput {
43
+ cabinNumber: string;
44
+ deckId?: string | null;
45
+ position?: string | null;
46
+ connectsTo?: string | null;
47
+ notes?: string | null;
48
+ isActive?: boolean;
49
+ }
50
+ export declare function useShipMutation(): {
51
+ create: import("@tanstack/react-query").UseMutationResult<{
52
+ id: string;
53
+ lineSupplierId: string | null;
54
+ name: string;
55
+ slug: string;
56
+ shipType: "ocean" | "river" | "expedition" | "coastal" | "yacht" | "sailing";
57
+ capacityGuests: number | null;
58
+ capacityCrew: number | null;
59
+ cabinCount: number | null;
60
+ deckCount: number | null;
61
+ lengthMeters: string | null;
62
+ cruisingSpeedKnots: string | null;
63
+ yearBuilt: number | null;
64
+ yearRefurbished: number | null;
65
+ imo: string | null;
66
+ description: string | null;
67
+ deckPlanUrl: string | null;
68
+ gallery: string[] | null;
69
+ amenities: Record<string, unknown> | null;
70
+ externalRefs: Record<string, string> | null;
71
+ isActive: boolean;
72
+ createdAt: string;
73
+ updatedAt: string;
74
+ }, Error, CreateShipInput, unknown>;
75
+ update: import("@tanstack/react-query").UseMutationResult<{
76
+ id: string;
77
+ lineSupplierId: string | null;
78
+ name: string;
79
+ slug: string;
80
+ shipType: "ocean" | "river" | "expedition" | "coastal" | "yacht" | "sailing";
81
+ capacityGuests: number | null;
82
+ capacityCrew: number | null;
83
+ cabinCount: number | null;
84
+ deckCount: number | null;
85
+ lengthMeters: string | null;
86
+ cruisingSpeedKnots: string | null;
87
+ yearBuilt: number | null;
88
+ yearRefurbished: number | null;
89
+ imo: string | null;
90
+ description: string | null;
91
+ deckPlanUrl: string | null;
92
+ gallery: string[] | null;
93
+ amenities: Record<string, unknown> | null;
94
+ externalRefs: Record<string, string> | null;
95
+ isActive: boolean;
96
+ createdAt: string;
97
+ updatedAt: string;
98
+ }, Error, {
99
+ key: string;
100
+ input: UpdateShipInput;
101
+ }, unknown>;
102
+ upsertDeck: import("@tanstack/react-query").UseMutationResult<{
103
+ id: string;
104
+ shipId: string;
105
+ name: string;
106
+ level: number | null;
107
+ planImageUrl: string | null;
108
+ createdAt: string;
109
+ updatedAt: string;
110
+ }, Error, {
111
+ key: string;
112
+ input: UpsertDeckInput;
113
+ }, unknown>;
114
+ upsertCabinCategory: import("@tanstack/react-query").UseMutationResult<{
115
+ id: string;
116
+ shipId: string;
117
+ code: string;
118
+ name: string;
119
+ roomType: "inside" | "oceanview" | "balcony" | "suite" | "penthouse" | "single";
120
+ description: string | null;
121
+ minOccupancy: number;
122
+ maxOccupancy: number;
123
+ squareFeet: string | null;
124
+ wheelchairAccessible: boolean;
125
+ amenities: string[] | null;
126
+ images: string[] | null;
127
+ floorplanImages: string[] | null;
128
+ gradeCodes: string[] | null;
129
+ externalRefs: Record<string, string> | null;
130
+ createdAt: string;
131
+ updatedAt: string;
132
+ }, Error, UpsertCabinCategoryInput, unknown>;
133
+ updateCabinCategory: import("@tanstack/react-query").UseMutationResult<{
134
+ id: string;
135
+ shipId: string;
136
+ code: string;
137
+ name: string;
138
+ roomType: "inside" | "oceanview" | "balcony" | "suite" | "penthouse" | "single";
139
+ description: string | null;
140
+ minOccupancy: number;
141
+ maxOccupancy: number;
142
+ squareFeet: string | null;
143
+ wheelchairAccessible: boolean;
144
+ amenities: string[] | null;
145
+ images: string[] | null;
146
+ floorplanImages: string[] | null;
147
+ gradeCodes: string[] | null;
148
+ externalRefs: Record<string, string> | null;
149
+ createdAt: string;
150
+ updatedAt: string;
151
+ }, Error, {
152
+ categoryId: string;
153
+ input: Partial<UpsertCabinCategoryInput>;
154
+ }, unknown>;
155
+ replaceCategoryCabins: import("@tanstack/react-query").UseMutationResult<{
156
+ id: string;
157
+ categoryId: string;
158
+ cabinNumber: string;
159
+ deckId: string | null;
160
+ position: string | null;
161
+ connectsTo: string | null;
162
+ notes: string | null;
163
+ isActive: boolean;
164
+ createdAt: string;
165
+ updatedAt: string;
166
+ }[], Error, {
167
+ categoryId: string;
168
+ cabins: UpsertCabinInput[];
169
+ }, unknown>;
170
+ updateCabin: import("@tanstack/react-query").UseMutationResult<{
171
+ id: string;
172
+ categoryId: string;
173
+ cabinNumber: string;
174
+ deckId: string | null;
175
+ position: string | null;
176
+ connectsTo: string | null;
177
+ notes: string | null;
178
+ isActive: boolean;
179
+ createdAt: string;
180
+ updatedAt: string;
181
+ }, Error, {
182
+ cabinId: string;
183
+ input: Partial<UpsertCabinInput>;
184
+ }, unknown>;
185
+ };
186
+ //# sourceMappingURL=use-ship-mutation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-ship-mutation.d.ts","sourceRoot":"","sources":["../../src/hooks/use-ship-mutation.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,OAAO,GAAG,OAAO,GAAG,YAAY,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,CAAA;IAC5E,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACnC,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAAA;AAEtD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC7B;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,QAAQ,GAAG,WAAW,GAAG,SAAS,GAAG,OAAO,GAAG,WAAW,GAAG,QAAQ,CAAA;IAC/E,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;IAC1B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,wBAAgB,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAyBpB,MAAM;eACJ,eAAe;;;;;;;;;;;aAqBjB,MAAM;eACJ,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBAuCV,MAAM;eACX,OAAO,CAAC,wBAAwB,CAAC;;;;;;;;;;;;;;oBAoB5B,MAAM;gBACV,gBAAgB,EAAE;;;;;;;;;;;;;;iBAsBjB,MAAM;eACR,OAAO,CAAC,gBAAgB,CAAC;;EA0BrC"}
@@ -0,0 +1,92 @@
1
+ import { useMutation, 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 { cabinCategoryListResponse, cabinCategorySingleResponse, cabinListResponse, cabinSingleResponse, deckSingleResponse, shipSingleResponse, } from "../schemas.js";
6
+ export function useShipMutation() {
7
+ const { baseUrl, fetcher } = useVoyantCruisesContext();
8
+ const client = { baseUrl, fetcher };
9
+ const queryClient = useQueryClient();
10
+ const create = useMutation({
11
+ mutationFn: async (input) => {
12
+ const result = await fetchWithValidation("/v1/admin/cruises/ships", shipSingleResponse, client, { method: "POST", body: JSON.stringify(input) });
13
+ return result.data;
14
+ },
15
+ onSuccess: () => {
16
+ void queryClient.invalidateQueries({ queryKey: cruisesQueryKeys.ships() });
17
+ },
18
+ });
19
+ const update = useMutation({
20
+ mutationFn: async ({ key, input, }) => {
21
+ const result = await fetchWithValidation(`/v1/admin/cruises/ships/${encodeURIComponent(key)}`, shipSingleResponse, client, { method: "PUT", body: JSON.stringify(input) });
22
+ return result.data;
23
+ },
24
+ onSuccess: (data) => {
25
+ void queryClient.invalidateQueries({ queryKey: cruisesQueryKeys.ships() });
26
+ queryClient.setQueryData(cruisesQueryKeys.ship(data.id), data);
27
+ },
28
+ });
29
+ const upsertDeck = useMutation({
30
+ mutationFn: async ({ key, input, }) => {
31
+ const result = await fetchWithValidation(`/v1/admin/cruises/ships/${encodeURIComponent(key)}/decks`, deckSingleResponse, client, { method: "POST", body: JSON.stringify(input) });
32
+ return result.data;
33
+ },
34
+ onSuccess: (_data, vars) => {
35
+ void queryClient.invalidateQueries({ queryKey: cruisesQueryKeys.shipDecks(vars.key) });
36
+ },
37
+ });
38
+ const upsertCabinCategory = useMutation({
39
+ mutationFn: async (input) => {
40
+ // The server bulk endpoint expects { categories: [...] }; for a single
41
+ // upsert we POST through the bulk path with one entry.
42
+ const result = await fetchWithValidation(`/v1/admin/cruises/ships/${encodeURIComponent(input.shipId)}/categories/bulk`, cabinCategoryListResponse, client, { method: "PUT", body: JSON.stringify({ categories: [input] }) });
43
+ const first = result.data[0];
44
+ if (!first)
45
+ throw new Error("Server returned no categories from bulk upsert");
46
+ return first;
47
+ },
48
+ onSuccess: (data) => {
49
+ void queryClient.invalidateQueries({ queryKey: cruisesQueryKeys.shipCategories(data.shipId) });
50
+ },
51
+ });
52
+ const updateCabinCategory = useMutation({
53
+ mutationFn: async ({ categoryId, input, }) => {
54
+ const result = await fetchWithValidation(`/v1/admin/cruises/categories/${encodeURIComponent(categoryId)}`, cabinCategorySingleResponse, client, { method: "PUT", body: JSON.stringify(input) });
55
+ return result.data;
56
+ },
57
+ onSuccess: (data) => {
58
+ void queryClient.invalidateQueries({ queryKey: cruisesQueryKeys.shipCategories(data.shipId) });
59
+ },
60
+ });
61
+ const replaceCategoryCabins = useMutation({
62
+ mutationFn: async ({ categoryId, cabins, }) => {
63
+ const result = await fetchWithValidation(`/v1/admin/cruises/categories/${encodeURIComponent(categoryId)}/cabins/bulk`, cabinListResponse, client, { method: "PUT", body: JSON.stringify({ cabins }) });
64
+ return result.data;
65
+ },
66
+ onSuccess: (_data, vars) => {
67
+ void queryClient.invalidateQueries({
68
+ queryKey: cruisesQueryKeys.categoryCabins(vars.categoryId),
69
+ });
70
+ },
71
+ });
72
+ const updateCabin = useMutation({
73
+ mutationFn: async ({ cabinId, input, }) => {
74
+ const result = await fetchWithValidation(`/v1/admin/cruises/cabins/${encodeURIComponent(cabinId)}`, cabinSingleResponse, client, { method: "PUT", body: JSON.stringify(input) });
75
+ return result.data;
76
+ },
77
+ onSuccess: (data) => {
78
+ void queryClient.invalidateQueries({
79
+ queryKey: cruisesQueryKeys.categoryCabins(data.categoryId),
80
+ });
81
+ },
82
+ });
83
+ return {
84
+ create,
85
+ update,
86
+ upsertDeck,
87
+ upsertCabinCategory,
88
+ updateCabinCategory,
89
+ replaceCategoryCabins,
90
+ updateCabin,
91
+ };
92
+ }
@@ -0,0 +1,101 @@
1
+ import type { ShipsListFilters } from "../query-keys.js";
2
+ export interface UseShipsOptions extends ShipsListFilters {
3
+ enabled?: boolean;
4
+ }
5
+ export declare function useShips(options?: UseShipsOptions): import("@tanstack/react-query").UseQueryResult<{
6
+ data: {
7
+ id: string;
8
+ lineSupplierId: string | null;
9
+ name: string;
10
+ slug: string;
11
+ shipType: "ocean" | "river" | "expedition" | "coastal" | "yacht" | "sailing";
12
+ capacityGuests: number | null;
13
+ capacityCrew: number | null;
14
+ cabinCount: number | null;
15
+ deckCount: number | null;
16
+ lengthMeters: string | null;
17
+ cruisingSpeedKnots: string | null;
18
+ yearBuilt: number | null;
19
+ yearRefurbished: number | null;
20
+ imo: string | null;
21
+ description: string | null;
22
+ deckPlanUrl: string | null;
23
+ gallery: string[] | null;
24
+ amenities: Record<string, unknown> | null;
25
+ externalRefs: Record<string, string> | null;
26
+ isActive: boolean;
27
+ createdAt: string;
28
+ updatedAt: string;
29
+ }[];
30
+ total: number;
31
+ limit: number;
32
+ offset: number;
33
+ }, Error>;
34
+ export interface UseShipOptions {
35
+ enabled?: boolean;
36
+ }
37
+ export declare function useShip(key: string | null | undefined, options?: UseShipOptions): import("@tanstack/react-query").UseQueryResult<{
38
+ id: string;
39
+ lineSupplierId: string | null;
40
+ name: string;
41
+ slug: string;
42
+ shipType: "ocean" | "river" | "expedition" | "coastal" | "yacht" | "sailing";
43
+ capacityGuests: number | null;
44
+ capacityCrew: number | null;
45
+ cabinCount: number | null;
46
+ deckCount: number | null;
47
+ lengthMeters: string | null;
48
+ cruisingSpeedKnots: string | null;
49
+ yearBuilt: number | null;
50
+ yearRefurbished: number | null;
51
+ imo: string | null;
52
+ description: string | null;
53
+ deckPlanUrl: string | null;
54
+ gallery: string[] | null;
55
+ amenities: Record<string, unknown> | null;
56
+ externalRefs: Record<string, string> | null;
57
+ isActive: boolean;
58
+ createdAt: string;
59
+ updatedAt: string;
60
+ }, Error>;
61
+ export declare function useShipDecks(key: string | null | undefined, options?: UseShipOptions): import("@tanstack/react-query").UseQueryResult<{
62
+ id: string;
63
+ shipId: string;
64
+ name: string;
65
+ level: number | null;
66
+ planImageUrl: string | null;
67
+ createdAt: string;
68
+ updatedAt: string;
69
+ }[], Error>;
70
+ export declare function useShipCategories(key: string | null | undefined, options?: UseShipOptions): import("@tanstack/react-query").UseQueryResult<{
71
+ id: string;
72
+ shipId: string;
73
+ code: string;
74
+ name: string;
75
+ roomType: "inside" | "oceanview" | "balcony" | "suite" | "penthouse" | "single";
76
+ description: string | null;
77
+ minOccupancy: number;
78
+ maxOccupancy: number;
79
+ squareFeet: string | null;
80
+ wheelchairAccessible: boolean;
81
+ amenities: string[] | null;
82
+ images: string[] | null;
83
+ floorplanImages: string[] | null;
84
+ gradeCodes: string[] | null;
85
+ externalRefs: Record<string, string> | null;
86
+ createdAt: string;
87
+ updatedAt: string;
88
+ }[], Error>;
89
+ export declare function useCategoryCabins(categoryId: string | null | undefined, options?: UseShipOptions): import("@tanstack/react-query").UseQueryResult<{
90
+ id: string;
91
+ categoryId: string;
92
+ cabinNumber: string;
93
+ deckId: string | null;
94
+ position: string | null;
95
+ connectsTo: string | null;
96
+ notes: string | null;
97
+ isActive: boolean;
98
+ createdAt: string;
99
+ updatedAt: string;
100
+ }[], Error>;
101
+ //# sourceMappingURL=use-ships.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-ships.d.ts","sourceRoot":"","sources":["../../src/hooks/use-ships.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AASxD,MAAM,WAAW,eAAgB,SAAQ,gBAAgB;IACvD,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,wBAAgB,QAAQ,CAAC,OAAO,GAAE,eAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAOrD;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,OAAO,GAAE,cAAmB;;;;;;;;;;;;;;;;;;;;;;;UAOnF;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,OAAO,GAAE,cAAmB;;;;;;;;YAOxF;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,OAAO,GAAE,cAAmB;;;;;;;;;;;;;;;;;;YAO7F;AAED,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACrC,OAAO,GAAE,cAAmB;;;;;;;;;;;YAQ7B"}
@@ -0,0 +1,43 @@
1
+ import { useQuery } from "@tanstack/react-query";
2
+ import { useVoyantCruisesContext } from "../provider.js";
3
+ import { getCategoryCabinsQueryOptions, getShipCategoriesQueryOptions, getShipDecksQueryOptions, getShipQueryOptions, getShipsQueryOptions, } from "../query-options.js";
4
+ export function useShips(options = {}) {
5
+ const { baseUrl, fetcher } = useVoyantCruisesContext();
6
+ const { enabled = true, ...filters } = options;
7
+ return useQuery({
8
+ ...getShipsQueryOptions({ baseUrl, fetcher }, filters),
9
+ enabled,
10
+ });
11
+ }
12
+ export function useShip(key, options = {}) {
13
+ const { baseUrl, fetcher } = useVoyantCruisesContext();
14
+ const { enabled = true } = options;
15
+ return useQuery({
16
+ ...getShipQueryOptions({ baseUrl, fetcher }, key ?? ""),
17
+ enabled: enabled && !!key,
18
+ });
19
+ }
20
+ export function useShipDecks(key, options = {}) {
21
+ const { baseUrl, fetcher } = useVoyantCruisesContext();
22
+ const { enabled = true } = options;
23
+ return useQuery({
24
+ ...getShipDecksQueryOptions({ baseUrl, fetcher }, key ?? ""),
25
+ enabled: enabled && !!key,
26
+ });
27
+ }
28
+ export function useShipCategories(key, options = {}) {
29
+ const { baseUrl, fetcher } = useVoyantCruisesContext();
30
+ const { enabled = true } = options;
31
+ return useQuery({
32
+ ...getShipCategoriesQueryOptions({ baseUrl, fetcher }, key ?? ""),
33
+ enabled: enabled && !!key,
34
+ });
35
+ }
36
+ export function useCategoryCabins(categoryId, options = {}) {
37
+ const { baseUrl, fetcher } = useVoyantCruisesContext();
38
+ const { enabled = true } = options;
39
+ return useQuery({
40
+ ...getCategoryCabinsQueryOptions({ baseUrl, fetcher }, categoryId ?? ""),
41
+ enabled: enabled && !!categoryId,
42
+ });
43
+ }