@travories/frontend-sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -0
- package/README.md +193 -0
- package/dist/index.d.mts +633 -0
- package/dist/index.d.ts +633 -0
- package/dist/index.js +2406 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2373 -0
- package/dist/index.mjs.map +1 -0
- package/dist/styles.css +2 -0
- package/package.json +95 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,633 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import React, { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
interface HttpRequestOptions {
|
|
5
|
+
method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
6
|
+
headers?: Record<string, string>;
|
|
7
|
+
body?: unknown;
|
|
8
|
+
signal?: AbortSignal;
|
|
9
|
+
silent?: boolean;
|
|
10
|
+
}
|
|
11
|
+
interface HttpClientConfig {
|
|
12
|
+
baseUrl: string;
|
|
13
|
+
apiKey?: string;
|
|
14
|
+
authToken?: string | (() => string | Promise<string | undefined> | undefined);
|
|
15
|
+
defaultHeaders?: Record<string, string>;
|
|
16
|
+
fetchImpl?: typeof fetch;
|
|
17
|
+
}
|
|
18
|
+
declare class TravoriesApiError extends Error {
|
|
19
|
+
status: number;
|
|
20
|
+
url: string;
|
|
21
|
+
body: string;
|
|
22
|
+
constructor(message: string, status: number, url: string, body: string);
|
|
23
|
+
}
|
|
24
|
+
declare class HttpClient {
|
|
25
|
+
private baseUrl;
|
|
26
|
+
private apiKey?;
|
|
27
|
+
private authToken?;
|
|
28
|
+
private defaultHeaders;
|
|
29
|
+
private fetchImpl;
|
|
30
|
+
constructor(config: HttpClientConfig);
|
|
31
|
+
private resolveAuthToken;
|
|
32
|
+
request<T>(path: string, options?: HttpRequestOptions): Promise<T | null>;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
interface TravoriesImageUrls {
|
|
36
|
+
original?: string | null;
|
|
37
|
+
hero?: string | null;
|
|
38
|
+
hero_fit?: string | null;
|
|
39
|
+
section?: string | null;
|
|
40
|
+
portrait?: string | null;
|
|
41
|
+
general?: string | null;
|
|
42
|
+
jpeg?: string | null;
|
|
43
|
+
}
|
|
44
|
+
interface TravoriesImage {
|
|
45
|
+
id: string;
|
|
46
|
+
key: string;
|
|
47
|
+
type: string;
|
|
48
|
+
alt: string;
|
|
49
|
+
preview: string | null;
|
|
50
|
+
url: TravoriesImageUrls;
|
|
51
|
+
}
|
|
52
|
+
interface PackageDayLocation {
|
|
53
|
+
sequence: number;
|
|
54
|
+
coord: [number, number];
|
|
55
|
+
displayName: string;
|
|
56
|
+
}
|
|
57
|
+
interface PackageDay {
|
|
58
|
+
id: string;
|
|
59
|
+
dayNumber: number;
|
|
60
|
+
description: string;
|
|
61
|
+
activities: {
|
|
62
|
+
activityName: string;
|
|
63
|
+
}[];
|
|
64
|
+
locations: PackageDayLocation[];
|
|
65
|
+
travelDuration: string;
|
|
66
|
+
difficulty: string;
|
|
67
|
+
foodService: string[];
|
|
68
|
+
transportation: string[];
|
|
69
|
+
accommodation: string;
|
|
70
|
+
}
|
|
71
|
+
interface PackagePriceTier {
|
|
72
|
+
groupSizeMin: number;
|
|
73
|
+
groupSizeMax: number;
|
|
74
|
+
pricePerPerson: number;
|
|
75
|
+
isNegotiable: boolean;
|
|
76
|
+
}
|
|
77
|
+
interface PackageDiscount {
|
|
78
|
+
ageMin: number;
|
|
79
|
+
ageMax: number;
|
|
80
|
+
discountPercentage: number;
|
|
81
|
+
}
|
|
82
|
+
interface TravoriesPackage {
|
|
83
|
+
id: string;
|
|
84
|
+
title: string;
|
|
85
|
+
packageSlug: string;
|
|
86
|
+
slug: string;
|
|
87
|
+
packageType: string;
|
|
88
|
+
description: string;
|
|
89
|
+
difficulty: string;
|
|
90
|
+
packageFlexibility: boolean;
|
|
91
|
+
packageCategory: string;
|
|
92
|
+
totalDays: number;
|
|
93
|
+
media: TravoriesImage[];
|
|
94
|
+
thumbnail: TravoriesImage | null;
|
|
95
|
+
days: PackageDay[];
|
|
96
|
+
prices: PackagePriceTier[];
|
|
97
|
+
discounts: PackageDiscount[];
|
|
98
|
+
thingsIncluded: string[];
|
|
99
|
+
thingsExcluded: string[];
|
|
100
|
+
thingsToPack: string[];
|
|
101
|
+
rating: number;
|
|
102
|
+
maxAllowedPeople: number;
|
|
103
|
+
minAllowedPeople: number;
|
|
104
|
+
}
|
|
105
|
+
interface PackageHost {
|
|
106
|
+
userId: string;
|
|
107
|
+
username: string;
|
|
108
|
+
agencyCreatedDate: string;
|
|
109
|
+
rating: number;
|
|
110
|
+
review: number;
|
|
111
|
+
description: string;
|
|
112
|
+
logo: TravoriesImage | null;
|
|
113
|
+
slug: string;
|
|
114
|
+
}
|
|
115
|
+
interface PackageHostResponse {
|
|
116
|
+
success: boolean;
|
|
117
|
+
message: string;
|
|
118
|
+
host: PackageHost;
|
|
119
|
+
}
|
|
120
|
+
interface MajorAttractionItem {
|
|
121
|
+
id?: string;
|
|
122
|
+
name?: string;
|
|
123
|
+
description?: string;
|
|
124
|
+
image?: TravoriesImage | null;
|
|
125
|
+
[key: string]: unknown;
|
|
126
|
+
}
|
|
127
|
+
interface MajorAttractionsResponse {
|
|
128
|
+
data: MajorAttractionItem[];
|
|
129
|
+
success?: boolean;
|
|
130
|
+
message?: string;
|
|
131
|
+
}
|
|
132
|
+
interface PackageRouteGeometry {
|
|
133
|
+
type: "LineString";
|
|
134
|
+
coordinates: [number, number][];
|
|
135
|
+
}
|
|
136
|
+
interface PackageRoute {
|
|
137
|
+
id?: string;
|
|
138
|
+
fromSegmentId?: string;
|
|
139
|
+
toSegmentId?: string;
|
|
140
|
+
travelMode?: string;
|
|
141
|
+
distanceMeters?: number;
|
|
142
|
+
durationSeconds?: number;
|
|
143
|
+
geometryType?: string;
|
|
144
|
+
geometry: PackageRouteGeometry | string;
|
|
145
|
+
}
|
|
146
|
+
interface PackageRoutesDay {
|
|
147
|
+
dayId?: string;
|
|
148
|
+
dayNumber: number;
|
|
149
|
+
routes: PackageRoute[];
|
|
150
|
+
}
|
|
151
|
+
interface PackageRoutesResponse {
|
|
152
|
+
success: boolean;
|
|
153
|
+
message?: string;
|
|
154
|
+
packageSlug: string;
|
|
155
|
+
days: PackageRoutesDay[];
|
|
156
|
+
}
|
|
157
|
+
interface PackageBundle {
|
|
158
|
+
pkg: TravoriesPackage;
|
|
159
|
+
host: PackageHost | null;
|
|
160
|
+
attractions: MajorAttractionItem[];
|
|
161
|
+
routes: PackageRoutesDay[];
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Compact card shape used by home/list sections. Returned by
|
|
165
|
+
* `client.packages.getHomeSections()`. Doesn't include full details — only
|
|
166
|
+
* what a card UI needs.
|
|
167
|
+
*/
|
|
168
|
+
interface HomePackageCard {
|
|
169
|
+
id: string;
|
|
170
|
+
title: string;
|
|
171
|
+
slug: string;
|
|
172
|
+
agencySlug: string;
|
|
173
|
+
totalDays: number;
|
|
174
|
+
minPrice: number;
|
|
175
|
+
maxPrice: number;
|
|
176
|
+
rating: number;
|
|
177
|
+
packageCategory: string;
|
|
178
|
+
thumbnail: TravoriesImage;
|
|
179
|
+
}
|
|
180
|
+
interface HomeSectionsResponse {
|
|
181
|
+
popular: HomePackageCard[];
|
|
182
|
+
topRated: HomePackageCard[];
|
|
183
|
+
trending: HomePackageCard[];
|
|
184
|
+
moreToExplore: HomePackageCard[];
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
declare class PackagesResource {
|
|
188
|
+
private http;
|
|
189
|
+
constructor(http: HttpClient);
|
|
190
|
+
/** Fetch a single package by its public slug. Returns null on 404 / network error in silent mode. */
|
|
191
|
+
getBySlug(slug: string, options?: HttpRequestOptions): Promise<TravoriesPackage | null>;
|
|
192
|
+
/** Fetch host (agency) information for the package. */
|
|
193
|
+
getHost(slug: string, options?: HttpRequestOptions): Promise<PackageHostResponse | null>;
|
|
194
|
+
/** Fetch major attractions tied to the package. */
|
|
195
|
+
getMajorAttractions(slug: string, options?: HttpRequestOptions): Promise<MajorAttractionsResponse | null>;
|
|
196
|
+
/**
|
|
197
|
+
* Fetch the four home/landing sections in one request:
|
|
198
|
+
* popular, topRated, trending, moreToExplore.
|
|
199
|
+
* Each item is a compact card (id, title, slug, thumbnail, price range, rating).
|
|
200
|
+
*/
|
|
201
|
+
getHomeSections(options?: HttpRequestOptions): Promise<HomeSectionsResponse | null>;
|
|
202
|
+
/**
|
|
203
|
+
* Fetch per-day GeoJSON routes for the package. Used by the map on the
|
|
204
|
+
* itinerary section to draw actual road/trail paths between stops.
|
|
205
|
+
*/
|
|
206
|
+
getRoutes(slug: string, options?: HttpRequestOptions): Promise<PackageRoutesResponse | null>;
|
|
207
|
+
/**
|
|
208
|
+
* Convenience: fetch the package + host + attractions + per-day routes in
|
|
209
|
+
* parallel. This is the payload `<PackageDetailView />` consumes.
|
|
210
|
+
*/
|
|
211
|
+
getBundle(slug: string, options?: HttpRequestOptions): Promise<PackageBundle | null>;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
interface TravoriesClientConfig extends HttpClientConfig {
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Main entry point for the Travories SDK.
|
|
218
|
+
*
|
|
219
|
+
* @example
|
|
220
|
+
* ```ts
|
|
221
|
+
* const travories = new TravoriesClient({
|
|
222
|
+
* baseUrl: "https://api.travories.com",
|
|
223
|
+
* });
|
|
224
|
+
*
|
|
225
|
+
* const pkg = await travories.packages.getBySlug("everest-base-camp");
|
|
226
|
+
* ```
|
|
227
|
+
*/
|
|
228
|
+
declare class TravoriesClient {
|
|
229
|
+
private http;
|
|
230
|
+
packages: PackagesResource;
|
|
231
|
+
constructor(config: TravoriesClientConfig);
|
|
232
|
+
/** Shortcut for `client.packages.getBySlug(slug)`. */
|
|
233
|
+
getPackageBySlug: (slug: string) => Promise<TravoriesPackage | null>;
|
|
234
|
+
/** Shortcut for `client.packages.getBundle(slug)` — package + host + attractions in one call. */
|
|
235
|
+
getPackageBundle: (slug: string) => Promise<PackageBundle | null>;
|
|
236
|
+
}
|
|
237
|
+
/** Factory form, in case you prefer a function over `new`. */
|
|
238
|
+
declare function createTravoriesClient(config: TravoriesClientConfig): TravoriesClient;
|
|
239
|
+
|
|
240
|
+
interface UsePackageBySlugResult {
|
|
241
|
+
data: TravoriesPackage | null;
|
|
242
|
+
loading: boolean;
|
|
243
|
+
error: Error | null;
|
|
244
|
+
refetch: () => void;
|
|
245
|
+
}
|
|
246
|
+
interface UsePackageBundleResult {
|
|
247
|
+
data: PackageBundle | null;
|
|
248
|
+
loading: boolean;
|
|
249
|
+
error: Error | null;
|
|
250
|
+
refetch: () => void;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Fetch a single package by slug. Re-runs when `slug` or `client` changes.
|
|
254
|
+
*
|
|
255
|
+
* Aborts the in-flight request when the component unmounts or the inputs change,
|
|
256
|
+
* so React strict-mode double-renders don't leak responses.
|
|
257
|
+
*/
|
|
258
|
+
declare function usePackageBySlug(client: TravoriesClient, slug: string | null | undefined): UsePackageBySlugResult;
|
|
259
|
+
/**
|
|
260
|
+
* Same as `usePackageBySlug` but fetches the full bundle (package + host + attractions).
|
|
261
|
+
*/
|
|
262
|
+
declare function usePackageBundle(client: TravoriesClient, slug: string | null | undefined): UsePackageBundleResult;
|
|
263
|
+
|
|
264
|
+
interface UseHomeSectionsResult {
|
|
265
|
+
data: HomeSectionsResponse | null;
|
|
266
|
+
loading: boolean;
|
|
267
|
+
error: Error | null;
|
|
268
|
+
refetch: () => void;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Fetch the four home/landing sections (popular, topRated, trending,
|
|
272
|
+
* moreToExplore) in one request. Re-runs when `client` changes.
|
|
273
|
+
*
|
|
274
|
+
* Pass `null` to skip fetching (useful when the consumer already has the data
|
|
275
|
+
* via SSR / `initialSections` and only needs to satisfy rules-of-hooks).
|
|
276
|
+
*/
|
|
277
|
+
declare function useHomeSections(client: TravoriesClient | null): UseHomeSectionsResult;
|
|
278
|
+
|
|
279
|
+
interface HomeSectionsProps {
|
|
280
|
+
/** Required when `initialSections` is not provided. */
|
|
281
|
+
client?: TravoriesClient;
|
|
282
|
+
/** Pre-fetched home sections (SSR pattern). When set, skips the client-side fetch. */
|
|
283
|
+
initialSections?: HomeSectionsResponse | null;
|
|
284
|
+
currency?: string;
|
|
285
|
+
/** Called when the user clicks any package card across any section. */
|
|
286
|
+
onSelect?: (pkg: HomePackageCard) => void;
|
|
287
|
+
/** When set, cards render as <a href=hrefFor(pkg)> instead of buttons. */
|
|
288
|
+
hrefFor?: (pkg: HomePackageCard) => string;
|
|
289
|
+
/** Open each card in a new tab. Requires `hrefFor`. */
|
|
290
|
+
openInNewTab?: boolean;
|
|
291
|
+
/** Optional override for section titles (defaults match the frontend's labels). */
|
|
292
|
+
titles?: {
|
|
293
|
+
popular?: string;
|
|
294
|
+
trending?: string;
|
|
295
|
+
topRated?: string;
|
|
296
|
+
moreToExplore?: string;
|
|
297
|
+
};
|
|
298
|
+
/** Section order (default: popular, trending, topRated, moreToExplore). */
|
|
299
|
+
order?: Array<"popular" | "trending" | "topRated" | "moreToExplore">;
|
|
300
|
+
className?: string;
|
|
301
|
+
renderLoading?: () => React.ReactNode;
|
|
302
|
+
renderError?: (err: Error) => React.ReactNode;
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Drop-in landing-page block that renders all four home sections. Same dual
|
|
306
|
+
* usage as `<PackageDetailView />`: pass `client` to let the SDK fetch, OR pass
|
|
307
|
+
* `initialSections` if you've already fetched (Next.js server component, etc.).
|
|
308
|
+
*/
|
|
309
|
+
declare function HomeSections({ client, initialSections, currency, onSelect, hrefFor, openInNewTab, titles, order, className, renderLoading, renderError, }: HomeSectionsProps): react_jsx_runtime.JSX.Element | null;
|
|
310
|
+
|
|
311
|
+
interface HomeSectionsContextValue {
|
|
312
|
+
data: HomeSectionsResponse | null;
|
|
313
|
+
loading: boolean;
|
|
314
|
+
error: Error | null;
|
|
315
|
+
refetch: () => void;
|
|
316
|
+
}
|
|
317
|
+
interface HomeSectionsProviderProps {
|
|
318
|
+
/** Required if `initialSections` is not provided. */
|
|
319
|
+
client?: TravoriesClient;
|
|
320
|
+
/** Pre-fetched data (SSR). When set, no client-side fetch runs. */
|
|
321
|
+
initialSections?: HomeSectionsResponse | null;
|
|
322
|
+
children: ReactNode;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* One-shot data fetcher for the four home sections. Drop anywhere in your tree
|
|
326
|
+
* and place any number of `<PackagesSection>` (or custom consumers via
|
|
327
|
+
* `useHomeSectionsContext`) inside — they all share the same fetched payload.
|
|
328
|
+
*
|
|
329
|
+
* <HomeSectionsProvider client={client}>
|
|
330
|
+
* <Hero />
|
|
331
|
+
* <PackagesSection section="trending" onSelect={goTo} />
|
|
332
|
+
* <YourFAQ />
|
|
333
|
+
* <PackagesSection section="moreToExplore" onSelect={goTo} />
|
|
334
|
+
* </HomeSectionsProvider>
|
|
335
|
+
*/
|
|
336
|
+
declare function HomeSectionsProvider({ client, initialSections, children, }: HomeSectionsProviderProps): react_jsx_runtime.JSX.Element;
|
|
337
|
+
/** Hook for any custom consumer (e.g., a stats badge) that wants the raw payload. */
|
|
338
|
+
declare function useHomeSectionsContext(): HomeSectionsContextValue;
|
|
339
|
+
|
|
340
|
+
type HomeSectionKey = "popular" | "trending" | "topRated" | "moreToExplore";
|
|
341
|
+
interface PackagesSectionProps {
|
|
342
|
+
/** Which section to render. */
|
|
343
|
+
section: HomeSectionKey;
|
|
344
|
+
/** Override the default title for this section. */
|
|
345
|
+
title?: string;
|
|
346
|
+
subtitle?: string;
|
|
347
|
+
currency?: string;
|
|
348
|
+
onSelect?: (pkg: HomePackageCard) => void;
|
|
349
|
+
hrefFor?: (pkg: HomePackageCard) => string;
|
|
350
|
+
/** Open each card in a new tab. Requires `hrefFor`. */
|
|
351
|
+
openInNewTab?: boolean;
|
|
352
|
+
/** Hide the whole block while loading (default: show a skeleton). */
|
|
353
|
+
hideWhenLoading?: boolean;
|
|
354
|
+
/** Hide when there are no packages for this section (default true). */
|
|
355
|
+
hideWhenEmpty?: boolean;
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* One independent home section, designed to live anywhere inside a
|
|
359
|
+
* `<HomeSectionsProvider>`. Multiple of these share one fetch.
|
|
360
|
+
*
|
|
361
|
+
* <HomeSectionsProvider client={client}>
|
|
362
|
+
* <PackagesSection section="popular" onSelect={goTo} />
|
|
363
|
+
* <YourCustomBlock />
|
|
364
|
+
* <PackagesSection section="trending" title="Hot picks" onSelect={goTo} />
|
|
365
|
+
* </HomeSectionsProvider>
|
|
366
|
+
*/
|
|
367
|
+
declare const PackagesSection: React.FC<PackagesSectionProps>;
|
|
368
|
+
|
|
369
|
+
interface PackagesCarouselProps {
|
|
370
|
+
title: string;
|
|
371
|
+
subtitle?: string;
|
|
372
|
+
packages: HomePackageCard[];
|
|
373
|
+
currency?: string;
|
|
374
|
+
onSelect?: (pkg: HomePackageCard) => void;
|
|
375
|
+
/** When a package is rendered as a link instead of a button. */
|
|
376
|
+
hrefFor?: (pkg: HomePackageCard) => string;
|
|
377
|
+
/** Open each card in a new tab. Requires `hrefFor` to be set. */
|
|
378
|
+
openInNewTab?: boolean;
|
|
379
|
+
/** Render nothing when the list is empty (default true). */
|
|
380
|
+
hideWhenEmpty?: boolean;
|
|
381
|
+
}
|
|
382
|
+
declare const PackagesCarousel: React.FC<PackagesCarouselProps>;
|
|
383
|
+
|
|
384
|
+
interface PackageCardProps {
|
|
385
|
+
pkg: HomePackageCard;
|
|
386
|
+
currency?: string;
|
|
387
|
+
onSelect?: (pkg: HomePackageCard) => void;
|
|
388
|
+
/** Renders as <a href> so cmd/ctrl-click opens the package in a new tab. */
|
|
389
|
+
href?: string;
|
|
390
|
+
/** When true, the anchor gets `target="_blank"` so a plain click also opens
|
|
391
|
+
* in a new tab. Requires `href`. `onSelect` is NOT called on a normal click
|
|
392
|
+
* in this mode — the browser handles navigation. */
|
|
393
|
+
openInNewTab?: boolean;
|
|
394
|
+
/** When true, show the heart (wishlist) icon. Default true. */
|
|
395
|
+
showHeart?: boolean;
|
|
396
|
+
/** Initial wishlist state. */
|
|
397
|
+
liked?: boolean;
|
|
398
|
+
/** Called when the user toggles the heart. Receives the new state. */
|
|
399
|
+
onLike?: (pkg: HomePackageCard, liked: boolean) => void;
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Ported from frontend `Tourist/Package/PackageCard.tsx`.
|
|
403
|
+
* - Bordered image box with a frosted category badge top-left and an optional
|
|
404
|
+
* wishlist heart top-right.
|
|
405
|
+
* - Title, duration · stars, "Starting from $X" sit on the page background
|
|
406
|
+
* (no surrounding card frame — same as the frontend).
|
|
407
|
+
* - Card-level click handled via an absolutely-positioned anchor overlay so
|
|
408
|
+
* browser open-in-new-tab works naturally.
|
|
409
|
+
*/
|
|
410
|
+
declare const PackageCard: React.FC<PackageCardProps>;
|
|
411
|
+
|
|
412
|
+
interface PackageDetailViewProps {
|
|
413
|
+
/** Travories SDK client. Required when using `slug`. */
|
|
414
|
+
client?: TravoriesClient;
|
|
415
|
+
/** Public package slug. */
|
|
416
|
+
slug?: string;
|
|
417
|
+
/** Pre-fetched bundle. When provided, no fetch runs. Use for SSR. */
|
|
418
|
+
initialBundle?: PackageBundle | null;
|
|
419
|
+
/** Currency code for prices (default "USD"). */
|
|
420
|
+
currency?: string;
|
|
421
|
+
/** Called when the user hits Reserve. If omitted, the button shows a disabled state. */
|
|
422
|
+
onReserve?: (pkg: TravoriesPackage) => void;
|
|
423
|
+
/** Optional extra class on the root wrapper. */
|
|
424
|
+
className?: string;
|
|
425
|
+
/** Loading state override. */
|
|
426
|
+
renderLoading?: () => React.ReactNode;
|
|
427
|
+
/** Not-found state override. */
|
|
428
|
+
renderNotFound?: () => React.ReactNode;
|
|
429
|
+
}
|
|
430
|
+
declare function PackageDetailView({ client, slug, initialBundle, currency, onReserve, className, renderLoading, renderNotFound, }: PackageDetailViewProps): react_jsx_runtime.JSX.Element;
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Legacy view-model types — identical shape to frontend's `types/package.ts`.
|
|
434
|
+
* The SDK consumes the unified API response and projects it into these shapes
|
|
435
|
+
* because the ported frontend components were written against them.
|
|
436
|
+
*/
|
|
437
|
+
interface ThingItem {
|
|
438
|
+
category: string;
|
|
439
|
+
items: string[];
|
|
440
|
+
}
|
|
441
|
+
interface MediaItem {
|
|
442
|
+
url: string;
|
|
443
|
+
previewUrl?: string;
|
|
444
|
+
alt?: string;
|
|
445
|
+
}
|
|
446
|
+
interface TopData {
|
|
447
|
+
id: string;
|
|
448
|
+
slug?: string;
|
|
449
|
+
AgencyName?: string;
|
|
450
|
+
AgencySlug?: string;
|
|
451
|
+
Rating: number;
|
|
452
|
+
ReviewCount: number;
|
|
453
|
+
AgencyPackageMedias: MediaItem[];
|
|
454
|
+
PackageTitle: string;
|
|
455
|
+
PackageType: string;
|
|
456
|
+
TotalDays: number;
|
|
457
|
+
PackageCategory: string;
|
|
458
|
+
Difficulty?: string;
|
|
459
|
+
MaxAllowedPeople?: number;
|
|
460
|
+
thingsToDo?: ThingItem[];
|
|
461
|
+
thingsExcluded?: ThingItem[];
|
|
462
|
+
thingsToPack?: ThingItem[];
|
|
463
|
+
}
|
|
464
|
+
interface DescriptionData {
|
|
465
|
+
id?: string;
|
|
466
|
+
Description: string;
|
|
467
|
+
Price: Array<{
|
|
468
|
+
groupSizeMin: number;
|
|
469
|
+
groupSizeMax: number;
|
|
470
|
+
pricePerPerson: number;
|
|
471
|
+
isNegotiable: boolean;
|
|
472
|
+
}>;
|
|
473
|
+
Discounts?: Array<{
|
|
474
|
+
ageMin: number;
|
|
475
|
+
ageMax: number;
|
|
476
|
+
discountPercentage: number;
|
|
477
|
+
}>;
|
|
478
|
+
TotalDays: number;
|
|
479
|
+
MaxAllowedPeople: number;
|
|
480
|
+
MinAllowedPeople: number;
|
|
481
|
+
Days: Array<{
|
|
482
|
+
id?: string;
|
|
483
|
+
dayNumber: number;
|
|
484
|
+
DayNumber?: number;
|
|
485
|
+
description: string;
|
|
486
|
+
activities?: {
|
|
487
|
+
activityName: string;
|
|
488
|
+
}[];
|
|
489
|
+
locations?: Array<{
|
|
490
|
+
sequence?: number;
|
|
491
|
+
coord?: [number, number];
|
|
492
|
+
lat?: number;
|
|
493
|
+
lng?: number;
|
|
494
|
+
displayName?: string;
|
|
495
|
+
name?: string;
|
|
496
|
+
Sequence?: number;
|
|
497
|
+
position?: number;
|
|
498
|
+
}>;
|
|
499
|
+
travelDuration?: string | number;
|
|
500
|
+
travelDurationHours?: string | number;
|
|
501
|
+
difficulty?: string;
|
|
502
|
+
foodService?: string[];
|
|
503
|
+
transportation?: string[];
|
|
504
|
+
accommodation?: string;
|
|
505
|
+
coverImage?: string;
|
|
506
|
+
previewCoverImage?: string;
|
|
507
|
+
nCoverImage?: {
|
|
508
|
+
original?: string;
|
|
509
|
+
preview?: string;
|
|
510
|
+
};
|
|
511
|
+
}>;
|
|
512
|
+
thingsToDo?: ThingItem[];
|
|
513
|
+
thingsExcluded?: ThingItem[];
|
|
514
|
+
thingsToPack?: ThingItem[];
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
declare const TopSection: ({ topData }: {
|
|
518
|
+
topData: TopData;
|
|
519
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
520
|
+
|
|
521
|
+
interface GallerySectionProps {
|
|
522
|
+
media: MediaItem[];
|
|
523
|
+
packageTitle: string;
|
|
524
|
+
}
|
|
525
|
+
declare const GallerySection: React.FC<GallerySectionProps>;
|
|
526
|
+
|
|
527
|
+
interface PackageOverviewProps {
|
|
528
|
+
description: string;
|
|
529
|
+
isMobile: boolean;
|
|
530
|
+
topData: TopData;
|
|
531
|
+
}
|
|
532
|
+
declare const PackageOverview: React.FC<PackageOverviewProps>;
|
|
533
|
+
|
|
534
|
+
interface DescriptionSectionProps {
|
|
535
|
+
DescriptionData: DescriptionData;
|
|
536
|
+
topData: TopData;
|
|
537
|
+
currency?: string;
|
|
538
|
+
onReserve?: (pkg: TravoriesPackage) => void;
|
|
539
|
+
pkg: TravoriesPackage;
|
|
540
|
+
routes?: PackageRoutesDay[];
|
|
541
|
+
}
|
|
542
|
+
declare const DescriptionSection: React.FC<DescriptionSectionProps>;
|
|
543
|
+
|
|
544
|
+
declare const Itinerary: React.FC<{
|
|
545
|
+
Description: DescriptionData;
|
|
546
|
+
routes?: PackageRoutesDay[];
|
|
547
|
+
currency?: string;
|
|
548
|
+
/** Called from the sticky bar's Reserve button. Typically scrolls to BookingCardLite. */
|
|
549
|
+
onReserveClick?: () => void;
|
|
550
|
+
}>;
|
|
551
|
+
|
|
552
|
+
interface PackageMapLocation {
|
|
553
|
+
coord: [number, number];
|
|
554
|
+
displayName: string;
|
|
555
|
+
sequence?: number;
|
|
556
|
+
}
|
|
557
|
+
interface PackageMapProps {
|
|
558
|
+
locations: PackageMapLocation[];
|
|
559
|
+
dayNumber?: number;
|
|
560
|
+
/** Real driving/trail polylines for this day, already flipped to [lat, lng]. */
|
|
561
|
+
routes?: Array<[number, number][]>;
|
|
562
|
+
className?: string;
|
|
563
|
+
}
|
|
564
|
+
/**
|
|
565
|
+
* Lazy Leaflet wrapper. Renders nothing on the server. On the client, dynamically
|
|
566
|
+
* imports react-leaflet + leaflet so consumers without SSR setup don't blow up.
|
|
567
|
+
*/
|
|
568
|
+
declare function PackageMap({ locations, dayNumber, routes, className, }: PackageMapProps): react_jsx_runtime.JSX.Element;
|
|
569
|
+
|
|
570
|
+
interface PackageIncludedProps {
|
|
571
|
+
thingsToDo: ThingItem[] | unknown[];
|
|
572
|
+
}
|
|
573
|
+
declare const PackageIncluded: React.FC<PackageIncludedProps>;
|
|
574
|
+
|
|
575
|
+
interface PackageExcludedAndToPackProps {
|
|
576
|
+
thingsExcluded: ThingItem[] | Record<string, string[]> | unknown[];
|
|
577
|
+
thingsToPack: ThingItem[] | Record<string, string[]> | unknown[];
|
|
578
|
+
}
|
|
579
|
+
declare const PackageExcludedAndToPack: React.FC<PackageExcludedAndToPackProps>;
|
|
580
|
+
|
|
581
|
+
interface HostCardProps {
|
|
582
|
+
hostData: PackageHost;
|
|
583
|
+
className?: string;
|
|
584
|
+
}
|
|
585
|
+
declare const HostCard: React.FC<HostCardProps>;
|
|
586
|
+
|
|
587
|
+
interface HostAboutProps {
|
|
588
|
+
hostName: string;
|
|
589
|
+
description?: string;
|
|
590
|
+
className?: string;
|
|
591
|
+
}
|
|
592
|
+
declare const HostAbout: React.FC<HostAboutProps>;
|
|
593
|
+
|
|
594
|
+
type TravelerOption = {
|
|
595
|
+
id: "Adult" | "Senior Citizen" | "Children" | "Infant";
|
|
596
|
+
name: string;
|
|
597
|
+
count: number;
|
|
598
|
+
ageRange?: {
|
|
599
|
+
min: number;
|
|
600
|
+
max: number;
|
|
601
|
+
};
|
|
602
|
+
countInTotal: boolean;
|
|
603
|
+
};
|
|
604
|
+
interface BookingCardLiteProps {
|
|
605
|
+
DescriptionData: DescriptionData;
|
|
606
|
+
currency?: string;
|
|
607
|
+
/** Called when user clicks Book/Reserve. Receives the picked values so the
|
|
608
|
+
* consumer can wire their own booking flow. */
|
|
609
|
+
onReserve?: (payload: {
|
|
610
|
+
arrival: string;
|
|
611
|
+
departure: string;
|
|
612
|
+
travelers: TravelerOption[];
|
|
613
|
+
totalCost: number;
|
|
614
|
+
pricePerPerson: number;
|
|
615
|
+
}) => void;
|
|
616
|
+
}
|
|
617
|
+
/**
|
|
618
|
+
* High-fidelity port of frontend `BookingForm.tsx` — visual only.
|
|
619
|
+
* Submission, validation, auth, and the booking API are intentionally left to
|
|
620
|
+
* the consumer (called via `onReserve`) so the SDK stays auth/Redux-free.
|
|
621
|
+
*/
|
|
622
|
+
declare const BookingCardLite: React.FC<BookingCardLiteProps>;
|
|
623
|
+
|
|
624
|
+
declare const buildGalleryMedia: (pkg: TravoriesPackage) => MediaItem[];
|
|
625
|
+
declare const buildTopData: (pkg: TravoriesPackage, host: PackageHost | null) => TopData;
|
|
626
|
+
declare const buildDescriptionData: (pkg: TravoriesPackage) => DescriptionData;
|
|
627
|
+
|
|
628
|
+
declare function pickImageUrl(img: TravoriesImage | null | undefined): string;
|
|
629
|
+
declare function startingPrice(prices: PackagePriceTier[] | undefined): number;
|
|
630
|
+
declare function formatCurrency(amount: number, currency?: string): string;
|
|
631
|
+
declare function formatRating(rating: number | undefined): string;
|
|
632
|
+
|
|
633
|
+
export { BookingCardLite, type DescriptionData, DescriptionSection, GallerySection, type HomePackageCard, type HomeSectionKey, HomeSections, type HomeSectionsContextValue, type HomeSectionsProps, HomeSectionsProvider, type HomeSectionsProviderProps, type HomeSectionsResponse, HostAbout, HostCard, type HttpClientConfig, type HttpRequestOptions, Itinerary, type MajorAttractionItem, type MajorAttractionsResponse, type MediaItem, type PackageBundle, PackageCard, type PackageDay, type PackageDayLocation, PackageDetailView, type PackageDetailViewProps, type PackageDiscount, PackageExcludedAndToPack, type PackageHost, type PackageHostResponse, PackageIncluded, PackageMap, PackageOverview, type PackagePriceTier, type PackageRoute, type PackageRouteGeometry, type PackageRoutesDay, type PackageRoutesResponse, PackagesCarousel, PackagesResource, PackagesSection, type PackagesSectionProps, type ThingItem, type TopData, TopSection, TravoriesApiError, TravoriesClient, type TravoriesClientConfig, type TravoriesImage, type TravoriesImageUrls, type TravoriesPackage, type UseHomeSectionsResult, type UsePackageBundleResult, type UsePackageBySlugResult, buildDescriptionData, buildGalleryMedia, buildTopData, createTravoriesClient, formatCurrency, formatRating, pickImageUrl, startingPrice, useHomeSections, useHomeSectionsContext, usePackageBundle, usePackageBySlug };
|