@neowhale/storefront 0.2.4 → 0.2.7

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.
@@ -1,17 +1,20 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as react from 'react';
3
3
  import { ReactNode } from 'react';
4
- import { m as WhaleStorefrontConfig, i as Product, P as PaymentData, O as Order, a as CartItem, T as TaxBreakdown, W as WhaleClient, c as Customer, E as EventType, d as CustomerAnalytics } from '../client-y0V1x0px.cjs';
4
+ import { D as WhaleStorefrontConfig, r as Product, P as PaymentData, O as Order, a as CartItem, T as TaxBreakdown, W as WhaleClient, f as Customer, E as EventType, g as CustomerAnalytics, d as CheckoutSession, A as Address, b as Category, c as CategoryTreeNode, l as LoyaltyAccount, m as LoyaltyReward, n as LoyaltyTransaction, v as Review, w as ReviewSummary, F as WishlistItem, R as Recommendation, k as Location, x as ShippingMethod, y as ShippingRate, e as CouponValidation, C as Cart, Q as QRLandingData, i as LandingSection, h as LandingPageRenderData } from '../client-KHvDGThs.cjs';
5
+ import { ThemeTokens } from '@neowhale/ui';
5
6
  import * as zustand_middleware from 'zustand/middleware';
6
7
  import * as zustand from 'zustand';
7
- import { P as PixelManager } from '../pixel-manager-Db6Czwr2.cjs';
8
+ import { P as PixelManager } from '../pixel-manager-CQaginxZ.cjs';
8
9
 
9
10
  interface WhaleProviderProps extends WhaleStorefrontConfig {
10
11
  children: ReactNode;
11
12
  /** Server-fetched products passed to client for hooks */
12
13
  products?: Product[];
14
+ /** Manual theme overrides — merged with store theme fetched from storefront config */
15
+ theme?: Partial<ThemeTokens>;
13
16
  }
14
- declare function WhaleProvider({ children, products, storeId, apiKey, gatewayUrl, proxyPath, mediaSigningSecret, supabaseHost, storagePrefix, sessionTtl, debug, trackingEnabled, recordingRate, }: WhaleProviderProps): react_jsx_runtime.JSX.Element;
17
+ declare function WhaleProvider({ children, products, theme: themeProp, storeId, apiKey, gatewayUrl, proxyPath, mediaSigningSecret, supabaseHost, storagePrefix, sessionTtl, debug, trackingEnabled, recordingRate, }: WhaleProviderProps): react_jsx_runtime.JSX.Element;
15
18
 
16
19
  interface CartState {
17
20
  cartId: string | null;
@@ -229,6 +232,199 @@ declare function useCustomerAnalytics(): {
229
232
  loading: boolean;
230
233
  };
231
234
 
235
+ declare function useCheckout(): {
236
+ session: CheckoutSession | null;
237
+ loading: boolean;
238
+ error: Error | null;
239
+ createSession: (params: {
240
+ cart_id: string;
241
+ customer_email?: string;
242
+ shipping_address?: Address;
243
+ billing_address?: Address;
244
+ shipping_method_id?: string;
245
+ coupon_code?: string;
246
+ }) => Promise<CheckoutSession>;
247
+ updateSession: (params: {
248
+ customer_email?: string;
249
+ shipping_address?: Address;
250
+ billing_address?: Address;
251
+ shipping_method_id?: string;
252
+ coupon_code?: string;
253
+ }) => Promise<CheckoutSession>;
254
+ complete: (payment?: PaymentData) => Promise<Order>;
255
+ reset: () => void;
256
+ };
257
+
258
+ interface SearchParams {
259
+ query: string;
260
+ category_id?: string;
261
+ min_price?: number;
262
+ max_price?: number;
263
+ sort_by?: string;
264
+ sort_order?: 'asc' | 'desc';
265
+ limit?: number;
266
+ }
267
+ declare function useSearch(): {
268
+ results: Product[];
269
+ hasMore: boolean;
270
+ loading: boolean;
271
+ error: Error | null;
272
+ search: (params: SearchParams) => Promise<void>;
273
+ loadMore: (params: SearchParams) => Promise<void>;
274
+ clear: () => void;
275
+ };
276
+
277
+ declare function useCategories(): {
278
+ categories: Category[];
279
+ tree: CategoryTreeNode[];
280
+ loading: boolean;
281
+ error: Error | null;
282
+ refresh: () => Promise<void>;
283
+ getCategory: (id: string) => Promise<Category>;
284
+ };
285
+
286
+ declare function useLoyalty(): {
287
+ account: LoyaltyAccount | null;
288
+ rewards: LoyaltyReward[];
289
+ transactions: LoyaltyTransaction[];
290
+ loading: boolean;
291
+ error: Error | null;
292
+ refresh: () => Promise<void>;
293
+ redeemReward: (rewardId: string) => Promise<{
294
+ success: boolean;
295
+ points_remaining: number;
296
+ }>;
297
+ };
298
+
299
+ declare function useReviews(productId: string | null | undefined): {
300
+ reviews: Review[];
301
+ summary: ReviewSummary | null;
302
+ hasMore: boolean;
303
+ loading: boolean;
304
+ error: Error | null;
305
+ refresh: () => Promise<void>;
306
+ loadMore: () => Promise<void>;
307
+ submit: (data: {
308
+ rating: number;
309
+ title?: string;
310
+ body?: string;
311
+ customer_name?: string;
312
+ }) => Promise<Review>;
313
+ };
314
+
315
+ declare function useWishlist(): {
316
+ items: WishlistItem[];
317
+ loading: boolean;
318
+ error: Error | null;
319
+ refresh: () => Promise<void>;
320
+ add: (productId: string) => Promise<WishlistItem>;
321
+ remove: (productId: string) => Promise<void>;
322
+ has: (productId: string) => boolean;
323
+ toggle: (productId: string) => Promise<void>;
324
+ };
325
+
326
+ declare function useRecommendations(params?: {
327
+ product_id?: string;
328
+ customer_id?: string;
329
+ limit?: number;
330
+ type?: 'similar' | 'frequently_bought_together' | 'personalized';
331
+ }): {
332
+ recommendations: Recommendation[];
333
+ loading: boolean;
334
+ error: Error | null;
335
+ refresh: () => Promise<void>;
336
+ };
337
+
338
+ declare function useLocations(): {
339
+ locations: Location[];
340
+ loading: boolean;
341
+ error: Error | null;
342
+ refresh: () => Promise<void>;
343
+ getLocation: (id: string) => Promise<Location>;
344
+ };
345
+
346
+ declare function useShipping(): {
347
+ methods: ShippingMethod[];
348
+ rates: ShippingRate[];
349
+ loading: boolean;
350
+ error: Error | null;
351
+ refreshMethods: () => Promise<void>;
352
+ calculateRates: (params: {
353
+ cart_id: string;
354
+ shipping_address: Address;
355
+ }) => Promise<ShippingRate[]>;
356
+ };
357
+
358
+ declare function useCoupons(): {
359
+ validation: CouponValidation | null;
360
+ loading: boolean;
361
+ error: Error | null;
362
+ validate: (code: string, cartId?: string) => Promise<CouponValidation>;
363
+ apply: (cartId: string, code: string) => Promise<Cart>;
364
+ remove: (cartId: string) => Promise<Cart>;
365
+ clear: () => void;
366
+ };
367
+
368
+ interface QRLandingPageProps {
369
+ /** QR code string (from URL param) */
370
+ code: string;
371
+ /** Gateway URL — defaults to https://whale-gateway.fly.dev */
372
+ gatewayUrl?: string;
373
+ /** Custom component for product display */
374
+ renderProduct?: (data: QRLandingData) => React.ReactNode;
375
+ /** Custom component for COA/lab results */
376
+ renderCOA?: (data: QRLandingData) => React.ReactNode;
377
+ /** Custom component for the full page (overrides default layout) */
378
+ renderPage?: (data: QRLandingData) => React.ReactNode;
379
+ /** Called when data is loaded */
380
+ onDataLoaded?: (data: QRLandingData) => void;
381
+ /** Called on error */
382
+ onError?: (error: Error) => void;
383
+ }
384
+ /**
385
+ * QR Landing Page — drop-in component that renders a branded landing page
386
+ * for any QR code. Fetches data from the gateway's public endpoint.
387
+ *
388
+ * Usage:
389
+ * ```tsx
390
+ * // In app/qr/[code]/page.tsx:
391
+ * import { QRLandingPage } from '@neowhale/storefront/react'
392
+ * export default function Page({ params }: { params: { code: string } }) {
393
+ * return <QRLandingPage code={params.code} />
394
+ * }
395
+ * ```
396
+ */
397
+ declare function QRLandingPage({ code, gatewayUrl, renderProduct, renderCOA, renderPage, onDataLoaded, onError, }: QRLandingPageProps): react_jsx_runtime.JSX.Element | null;
398
+
399
+ interface LandingPageProps {
400
+ /** Landing page slug */
401
+ slug: string;
402
+ /** Gateway URL — defaults to https://whale-gateway.fly.dev */
403
+ gatewayUrl?: string;
404
+ /**
405
+ * Override rendering for any section type.
406
+ * Return the custom element, or call defaultRenderer() for the built-in output.
407
+ */
408
+ renderSection?: (section: LandingSection, defaultRenderer: () => React.ReactNode) => React.ReactNode;
409
+ /** Called when data is loaded */
410
+ onDataLoaded?: (data: LandingPageRenderData) => void;
411
+ /** Called on error */
412
+ onError?: (error: Error) => void;
413
+ }
414
+ /**
415
+ * LandingPage — drop-in component that renders a configurable landing page
416
+ * fetched from the gateway's public endpoint.
417
+ *
418
+ * Usage:
419
+ * ```tsx
420
+ * import { LandingPage } from '@neowhale/storefront/react'
421
+ * export default function Page({ params }: { params: { slug: string } }) {
422
+ * return <LandingPage slug={params.slug} />
423
+ * }
424
+ * ```
425
+ */
426
+ declare function LandingPage({ slug, gatewayUrl, renderSection, onDataLoaded, onError, }: LandingPageProps): react_jsx_runtime.JSX.Element | null;
427
+
232
428
  /**
233
429
  * Auto-tracks page views on pathname change and links customer sessions.
234
430
  * Rendered internally by WhaleProvider — storefronts don't need to add this manually.
@@ -253,13 +449,16 @@ declare function CartInitializer(): null;
253
449
  */
254
450
  declare function AuthInitializer(): null;
255
451
 
452
+ interface PixelInitializerProps {
453
+ onReady: (manager: PixelManager) => void;
454
+ onTheme?: (theme: Record<string, unknown>) => void;
455
+ }
256
456
  /**
257
- * Fetches storefront pixel config on mount and initializes pixel providers.
457
+ * Fetches storefront config on mount and initializes pixel providers + theme.
258
458
  * Sets pixelManager on context so useAnalytics can dispatch events to it.
459
+ * If the config includes a `theme` field, calls onTheme so the provider can apply it.
259
460
  * Rendered internally by WhaleProvider — storefronts don't need to add this manually.
260
461
  */
261
- declare function PixelInitializer({ onReady }: {
262
- onReady: (manager: PixelManager) => void;
263
- }): null;
462
+ declare function PixelInitializer({ onReady, onTheme }: PixelInitializerProps): null;
264
463
 
265
- export { AnalyticsTracker, type AuthActions, AuthInitializer, type AuthState, type AuthStore, type CartActions, CartInitializer, type CartState, type CartStore, PixelInitializer, WhaleContext, type WhaleContextValue, WhaleProvider, type WhaleProviderProps, useAnalytics, useAuth, useCart, useCartItemCount, useCartTotal, useCustomerAnalytics, useCustomerOrders, useProduct, useProducts, useWhaleClient };
464
+ export { AnalyticsTracker, type AuthActions, AuthInitializer, type AuthState, type AuthStore, type CartActions, CartInitializer, type CartState, type CartStore, LandingPage, type LandingPageProps, PixelInitializer, QRLandingPage, type QRLandingPageProps, type SearchParams, WhaleContext, type WhaleContextValue, WhaleProvider, type WhaleProviderProps, useAnalytics, useAuth, useCart, useCartItemCount, useCartTotal, useCategories, useCheckout, useCoupons, useCustomerAnalytics, useCustomerOrders, useLocations, useLoyalty, useProduct, useProducts, useRecommendations, useReviews, useSearch, useShipping, useWhaleClient, useWishlist };
@@ -1,17 +1,20 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as react from 'react';
3
3
  import { ReactNode } from 'react';
4
- import { m as WhaleStorefrontConfig, i as Product, P as PaymentData, O as Order, a as CartItem, T as TaxBreakdown, W as WhaleClient, c as Customer, E as EventType, d as CustomerAnalytics } from '../client-y0V1x0px.js';
4
+ import { D as WhaleStorefrontConfig, r as Product, P as PaymentData, O as Order, a as CartItem, T as TaxBreakdown, W as WhaleClient, f as Customer, E as EventType, g as CustomerAnalytics, d as CheckoutSession, A as Address, b as Category, c as CategoryTreeNode, l as LoyaltyAccount, m as LoyaltyReward, n as LoyaltyTransaction, v as Review, w as ReviewSummary, F as WishlistItem, R as Recommendation, k as Location, x as ShippingMethod, y as ShippingRate, e as CouponValidation, C as Cart, Q as QRLandingData, i as LandingSection, h as LandingPageRenderData } from '../client-KHvDGThs.js';
5
+ import { ThemeTokens } from '@neowhale/ui';
5
6
  import * as zustand_middleware from 'zustand/middleware';
6
7
  import * as zustand from 'zustand';
7
- import { P as PixelManager } from '../pixel-manager-CYtRIGo0.js';
8
+ import { P as PixelManager } from '../pixel-manager-Djp4Mh9L.js';
8
9
 
9
10
  interface WhaleProviderProps extends WhaleStorefrontConfig {
10
11
  children: ReactNode;
11
12
  /** Server-fetched products passed to client for hooks */
12
13
  products?: Product[];
14
+ /** Manual theme overrides — merged with store theme fetched from storefront config */
15
+ theme?: Partial<ThemeTokens>;
13
16
  }
14
- declare function WhaleProvider({ children, products, storeId, apiKey, gatewayUrl, proxyPath, mediaSigningSecret, supabaseHost, storagePrefix, sessionTtl, debug, trackingEnabled, recordingRate, }: WhaleProviderProps): react_jsx_runtime.JSX.Element;
17
+ declare function WhaleProvider({ children, products, theme: themeProp, storeId, apiKey, gatewayUrl, proxyPath, mediaSigningSecret, supabaseHost, storagePrefix, sessionTtl, debug, trackingEnabled, recordingRate, }: WhaleProviderProps): react_jsx_runtime.JSX.Element;
15
18
 
16
19
  interface CartState {
17
20
  cartId: string | null;
@@ -229,6 +232,199 @@ declare function useCustomerAnalytics(): {
229
232
  loading: boolean;
230
233
  };
231
234
 
235
+ declare function useCheckout(): {
236
+ session: CheckoutSession | null;
237
+ loading: boolean;
238
+ error: Error | null;
239
+ createSession: (params: {
240
+ cart_id: string;
241
+ customer_email?: string;
242
+ shipping_address?: Address;
243
+ billing_address?: Address;
244
+ shipping_method_id?: string;
245
+ coupon_code?: string;
246
+ }) => Promise<CheckoutSession>;
247
+ updateSession: (params: {
248
+ customer_email?: string;
249
+ shipping_address?: Address;
250
+ billing_address?: Address;
251
+ shipping_method_id?: string;
252
+ coupon_code?: string;
253
+ }) => Promise<CheckoutSession>;
254
+ complete: (payment?: PaymentData) => Promise<Order>;
255
+ reset: () => void;
256
+ };
257
+
258
+ interface SearchParams {
259
+ query: string;
260
+ category_id?: string;
261
+ min_price?: number;
262
+ max_price?: number;
263
+ sort_by?: string;
264
+ sort_order?: 'asc' | 'desc';
265
+ limit?: number;
266
+ }
267
+ declare function useSearch(): {
268
+ results: Product[];
269
+ hasMore: boolean;
270
+ loading: boolean;
271
+ error: Error | null;
272
+ search: (params: SearchParams) => Promise<void>;
273
+ loadMore: (params: SearchParams) => Promise<void>;
274
+ clear: () => void;
275
+ };
276
+
277
+ declare function useCategories(): {
278
+ categories: Category[];
279
+ tree: CategoryTreeNode[];
280
+ loading: boolean;
281
+ error: Error | null;
282
+ refresh: () => Promise<void>;
283
+ getCategory: (id: string) => Promise<Category>;
284
+ };
285
+
286
+ declare function useLoyalty(): {
287
+ account: LoyaltyAccount | null;
288
+ rewards: LoyaltyReward[];
289
+ transactions: LoyaltyTransaction[];
290
+ loading: boolean;
291
+ error: Error | null;
292
+ refresh: () => Promise<void>;
293
+ redeemReward: (rewardId: string) => Promise<{
294
+ success: boolean;
295
+ points_remaining: number;
296
+ }>;
297
+ };
298
+
299
+ declare function useReviews(productId: string | null | undefined): {
300
+ reviews: Review[];
301
+ summary: ReviewSummary | null;
302
+ hasMore: boolean;
303
+ loading: boolean;
304
+ error: Error | null;
305
+ refresh: () => Promise<void>;
306
+ loadMore: () => Promise<void>;
307
+ submit: (data: {
308
+ rating: number;
309
+ title?: string;
310
+ body?: string;
311
+ customer_name?: string;
312
+ }) => Promise<Review>;
313
+ };
314
+
315
+ declare function useWishlist(): {
316
+ items: WishlistItem[];
317
+ loading: boolean;
318
+ error: Error | null;
319
+ refresh: () => Promise<void>;
320
+ add: (productId: string) => Promise<WishlistItem>;
321
+ remove: (productId: string) => Promise<void>;
322
+ has: (productId: string) => boolean;
323
+ toggle: (productId: string) => Promise<void>;
324
+ };
325
+
326
+ declare function useRecommendations(params?: {
327
+ product_id?: string;
328
+ customer_id?: string;
329
+ limit?: number;
330
+ type?: 'similar' | 'frequently_bought_together' | 'personalized';
331
+ }): {
332
+ recommendations: Recommendation[];
333
+ loading: boolean;
334
+ error: Error | null;
335
+ refresh: () => Promise<void>;
336
+ };
337
+
338
+ declare function useLocations(): {
339
+ locations: Location[];
340
+ loading: boolean;
341
+ error: Error | null;
342
+ refresh: () => Promise<void>;
343
+ getLocation: (id: string) => Promise<Location>;
344
+ };
345
+
346
+ declare function useShipping(): {
347
+ methods: ShippingMethod[];
348
+ rates: ShippingRate[];
349
+ loading: boolean;
350
+ error: Error | null;
351
+ refreshMethods: () => Promise<void>;
352
+ calculateRates: (params: {
353
+ cart_id: string;
354
+ shipping_address: Address;
355
+ }) => Promise<ShippingRate[]>;
356
+ };
357
+
358
+ declare function useCoupons(): {
359
+ validation: CouponValidation | null;
360
+ loading: boolean;
361
+ error: Error | null;
362
+ validate: (code: string, cartId?: string) => Promise<CouponValidation>;
363
+ apply: (cartId: string, code: string) => Promise<Cart>;
364
+ remove: (cartId: string) => Promise<Cart>;
365
+ clear: () => void;
366
+ };
367
+
368
+ interface QRLandingPageProps {
369
+ /** QR code string (from URL param) */
370
+ code: string;
371
+ /** Gateway URL — defaults to https://whale-gateway.fly.dev */
372
+ gatewayUrl?: string;
373
+ /** Custom component for product display */
374
+ renderProduct?: (data: QRLandingData) => React.ReactNode;
375
+ /** Custom component for COA/lab results */
376
+ renderCOA?: (data: QRLandingData) => React.ReactNode;
377
+ /** Custom component for the full page (overrides default layout) */
378
+ renderPage?: (data: QRLandingData) => React.ReactNode;
379
+ /** Called when data is loaded */
380
+ onDataLoaded?: (data: QRLandingData) => void;
381
+ /** Called on error */
382
+ onError?: (error: Error) => void;
383
+ }
384
+ /**
385
+ * QR Landing Page — drop-in component that renders a branded landing page
386
+ * for any QR code. Fetches data from the gateway's public endpoint.
387
+ *
388
+ * Usage:
389
+ * ```tsx
390
+ * // In app/qr/[code]/page.tsx:
391
+ * import { QRLandingPage } from '@neowhale/storefront/react'
392
+ * export default function Page({ params }: { params: { code: string } }) {
393
+ * return <QRLandingPage code={params.code} />
394
+ * }
395
+ * ```
396
+ */
397
+ declare function QRLandingPage({ code, gatewayUrl, renderProduct, renderCOA, renderPage, onDataLoaded, onError, }: QRLandingPageProps): react_jsx_runtime.JSX.Element | null;
398
+
399
+ interface LandingPageProps {
400
+ /** Landing page slug */
401
+ slug: string;
402
+ /** Gateway URL — defaults to https://whale-gateway.fly.dev */
403
+ gatewayUrl?: string;
404
+ /**
405
+ * Override rendering for any section type.
406
+ * Return the custom element, or call defaultRenderer() for the built-in output.
407
+ */
408
+ renderSection?: (section: LandingSection, defaultRenderer: () => React.ReactNode) => React.ReactNode;
409
+ /** Called when data is loaded */
410
+ onDataLoaded?: (data: LandingPageRenderData) => void;
411
+ /** Called on error */
412
+ onError?: (error: Error) => void;
413
+ }
414
+ /**
415
+ * LandingPage — drop-in component that renders a configurable landing page
416
+ * fetched from the gateway's public endpoint.
417
+ *
418
+ * Usage:
419
+ * ```tsx
420
+ * import { LandingPage } from '@neowhale/storefront/react'
421
+ * export default function Page({ params }: { params: { slug: string } }) {
422
+ * return <LandingPage slug={params.slug} />
423
+ * }
424
+ * ```
425
+ */
426
+ declare function LandingPage({ slug, gatewayUrl, renderSection, onDataLoaded, onError, }: LandingPageProps): react_jsx_runtime.JSX.Element | null;
427
+
232
428
  /**
233
429
  * Auto-tracks page views on pathname change and links customer sessions.
234
430
  * Rendered internally by WhaleProvider — storefronts don't need to add this manually.
@@ -253,13 +449,16 @@ declare function CartInitializer(): null;
253
449
  */
254
450
  declare function AuthInitializer(): null;
255
451
 
452
+ interface PixelInitializerProps {
453
+ onReady: (manager: PixelManager) => void;
454
+ onTheme?: (theme: Record<string, unknown>) => void;
455
+ }
256
456
  /**
257
- * Fetches storefront pixel config on mount and initializes pixel providers.
457
+ * Fetches storefront config on mount and initializes pixel providers + theme.
258
458
  * Sets pixelManager on context so useAnalytics can dispatch events to it.
459
+ * If the config includes a `theme` field, calls onTheme so the provider can apply it.
259
460
  * Rendered internally by WhaleProvider — storefronts don't need to add this manually.
260
461
  */
261
- declare function PixelInitializer({ onReady }: {
262
- onReady: (manager: PixelManager) => void;
263
- }): null;
462
+ declare function PixelInitializer({ onReady, onTheme }: PixelInitializerProps): null;
264
463
 
265
- export { AnalyticsTracker, type AuthActions, AuthInitializer, type AuthState, type AuthStore, type CartActions, CartInitializer, type CartState, type CartStore, PixelInitializer, WhaleContext, type WhaleContextValue, WhaleProvider, type WhaleProviderProps, useAnalytics, useAuth, useCart, useCartItemCount, useCartTotal, useCustomerAnalytics, useCustomerOrders, useProduct, useProducts, useWhaleClient };
464
+ export { AnalyticsTracker, type AuthActions, AuthInitializer, type AuthState, type AuthStore, type CartActions, CartInitializer, type CartState, type CartStore, LandingPage, type LandingPageProps, PixelInitializer, QRLandingPage, type QRLandingPageProps, type SearchParams, WhaleContext, type WhaleContextValue, WhaleProvider, type WhaleProviderProps, useAnalytics, useAuth, useCart, useCartItemCount, useCartTotal, useCategories, useCheckout, useCoupons, useCustomerAnalytics, useCustomerOrders, useLocations, useLoyalty, useProduct, useProducts, useRecommendations, useReviews, useSearch, useShipping, useWhaleClient, useWishlist };