@fluid-app/portal-sdk 0.1.13 → 0.1.14

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 (45) hide show
  1. package/dist/AccountScreen-BH7hueZP.cjs +789 -0
  2. package/dist/AccountScreen-BH7hueZP.cjs.map +1 -0
  3. package/dist/AccountScreen-CPHYsITD.mjs +750 -0
  4. package/dist/AccountScreen-CPHYsITD.mjs.map +1 -0
  5. package/dist/AccountScreen-CjnAbct9.mjs +2 -0
  6. package/dist/{ContactsScreen-CB6l0Lf1.mjs → ContactsScreen-CHLFZX_N.mjs} +2 -2
  7. package/dist/{ContactsScreen-CB6l0Lf1.mjs.map → ContactsScreen-CHLFZX_N.mjs.map} +1 -1
  8. package/dist/{ContactsScreen-Dwn5onLu.cjs → ContactsScreen-CjnCemeI.cjs} +4 -4
  9. package/dist/{ContactsScreen-Dwn5onLu.cjs.map → ContactsScreen-CjnCemeI.cjs.map} +1 -1
  10. package/dist/{CoreScreenPlaceholder-Bw8YOPwv.cjs → CoreScreenPlaceholder-C9lBkcyc.cjs} +2 -2
  11. package/dist/{CoreScreenPlaceholder-Bw8YOPwv.cjs.map → CoreScreenPlaceholder-C9lBkcyc.cjs.map} +1 -1
  12. package/dist/{CoreScreenPlaceholder-D93ZYKt2.mjs → CoreScreenPlaceholder-DCJ1hFvJ.mjs} +1 -1
  13. package/dist/{CoreScreenPlaceholder-D93ZYKt2.mjs.map → CoreScreenPlaceholder-DCJ1hFvJ.mjs.map} +1 -1
  14. package/dist/{CustomersScreen-gQb6cWL5.cjs → CustomersScreen-CqwRJogV.cjs} +4 -4
  15. package/dist/{CustomersScreen-gQb6cWL5.cjs.map → CustomersScreen-CqwRJogV.cjs.map} +1 -1
  16. package/dist/{CustomersScreen-BEar6Leg.mjs → CustomersScreen-DBicCB3o.mjs} +2 -2
  17. package/dist/{CustomersScreen-BEar6Leg.mjs.map → CustomersScreen-DBicCB3o.mjs.map} +1 -1
  18. package/dist/{MessagingScreen-YyzXdr95.mjs → FluidProvider-BafZw8PJ.mjs} +6 -503
  19. package/dist/FluidProvider-BafZw8PJ.mjs.map +1 -0
  20. package/dist/{MessagingScreen-Ca22FObh.cjs → FluidProvider-C6SCZDjX.cjs} +3 -542
  21. package/dist/FluidProvider-C6SCZDjX.cjs.map +1 -0
  22. package/dist/MessagingScreen-Bd-1_J9q.cjs +369 -0
  23. package/dist/MessagingScreen-Bd-1_J9q.cjs.map +1 -0
  24. package/dist/MessagingScreen-D8W8V2TW.mjs +2 -0
  25. package/dist/MessagingScreen-DCS0mtbd.mjs +324 -0
  26. package/dist/MessagingScreen-DCS0mtbd.mjs.map +1 -0
  27. package/dist/{OrdersScreen-DB1v051q.mjs → OrdersScreen-B6JCMBY5.mjs} +2 -2
  28. package/dist/{OrdersScreen-DB1v051q.mjs.map → OrdersScreen-B6JCMBY5.mjs.map} +1 -1
  29. package/dist/{OrdersScreen-DbON-kBA.cjs → OrdersScreen-DBxpXgZ9.cjs} +4 -4
  30. package/dist/{OrdersScreen-DbON-kBA.cjs.map → OrdersScreen-DBxpXgZ9.cjs.map} +1 -1
  31. package/dist/{ProductsScreen-CMDGGvE2.cjs → ProductsScreen-BK8cz_MN.cjs} +4 -4
  32. package/dist/{ProductsScreen-CMDGGvE2.cjs.map → ProductsScreen-BK8cz_MN.cjs.map} +1 -1
  33. package/dist/{ProductsScreen-nVDsY6kf.mjs → ProductsScreen-DafsauTY.mjs} +2 -2
  34. package/dist/{ProductsScreen-nVDsY6kf.mjs.map → ProductsScreen-DafsauTY.mjs.map} +1 -1
  35. package/dist/index.cjs +66 -107
  36. package/dist/index.cjs.map +1 -1
  37. package/dist/index.d.cts +29 -22
  38. package/dist/index.d.cts.map +1 -1
  39. package/dist/index.d.mts +29 -22
  40. package/dist/index.d.mts.map +1 -1
  41. package/dist/index.mjs +42 -85
  42. package/dist/index.mjs.map +1 -1
  43. package/package.json +17 -7
  44. package/dist/MessagingScreen-Ca22FObh.cjs.map +0 -1
  45. package/dist/MessagingScreen-YyzXdr95.mjs.map +0 -1
@@ -0,0 +1,750 @@
1
+ import { a as useFluidAuthContext, n as useFluidContext } from "./FluidProvider-BafZw8PJ.mjs";
2
+ import { createContext, useContext, useMemo } from "react";
3
+ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
4
+ import { createFetchClient } from "@fluid-app/api-client-core";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ import { addressesApi, createFetchClient as createFetchClient$1, customersApi, paymentMethodsApi } from "@fluid-app/fluid-pay-api-client";
7
+ import { createFetchClient as createFetchClient$2 } from "@fluid-app/orders-api-client";
8
+ import { createFetchClient as createFetchClient$3 } from "@fluid-app/subscriptions-api-client";
9
+ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
10
+ import { faUser } from "@fortawesome/pro-regular-svg-icons/faUser";
11
+ import { faBoxOpen } from "@fortawesome/pro-regular-svg-icons/faBoxOpen";
12
+ import { faArrowsRepeat } from "@fortawesome/pro-regular-svg-icons/faArrowsRepeat";
13
+ import { useController } from "react-hook-form";
14
+ import { ProfileUIProvider } from "@fluid-app/profile-core";
15
+ import { AddressFormDialog, CreditCardFormDialog, Profile } from "@fluid-app/profile-ui";
16
+ import { OrdersCoreProvider } from "@fluid-app/orders-core";
17
+ import { OrderDetail, OrdersList } from "@fluid-app/orders-ui";
18
+ import { SubscriptionsCoreProvider } from "@fluid-app/subscriptions-core";
19
+ import { SubscriptionDetail, SubscriptionsList } from "@fluid-app/subscriptions-ui";
20
+ //#region src/hooks/use-fluid-auth.ts
21
+ /**
22
+ * useFluidAuth Hook
23
+ *
24
+ * Provides access to authentication state and utilities.
25
+ * This is the primary hook for interacting with auth in components.
26
+ */
27
+ /**
28
+ * Hook to access authentication state and utilities.
29
+ *
30
+ * Must be used within a `FluidAuthProvider`.
31
+ *
32
+ * @returns Authentication context with user info, loading state, and utilities
33
+ * @throws Error if used outside FluidAuthProvider
34
+ *
35
+ * @example
36
+ * ```tsx
37
+ * function UserProfile() {
38
+ * const { isAuthenticated, isLoading, user, clearAuth } = useFluidAuth();
39
+ *
40
+ * if (isLoading) {
41
+ * return <Spinner />;
42
+ * }
43
+ *
44
+ * if (!isAuthenticated) {
45
+ * return <p>Please log in</p>;
46
+ * }
47
+ *
48
+ * return (
49
+ * <div>
50
+ * <p>Welcome, {user.full_name}!</p>
51
+ * <button onClick={clearAuth}>Log out</button>
52
+ * </div>
53
+ * );
54
+ * }
55
+ * ```
56
+ */
57
+ function useFluidAuth() {
58
+ return useFluidAuthContext();
59
+ }
60
+ //#endregion
61
+ //#region src/account/use-account-clients.ts
62
+ /** API version prefix for versioned endpoints (e.g. points ledger) */
63
+ const API_VERSION = "/v202506";
64
+ function useOrdersClient() {
65
+ const { config } = useFluidContext();
66
+ const { token } = useFluidAuth();
67
+ return useMemo(() => createFetchClient$2({
68
+ baseUrl: config.baseUrl,
69
+ getAuthToken: () => token,
70
+ onAuthError: config.onAuthError
71
+ }), [
72
+ config.baseUrl,
73
+ config.onAuthError,
74
+ token
75
+ ]);
76
+ }
77
+ function useSubscriptionsClient() {
78
+ const { config } = useFluidContext();
79
+ const { token } = useFluidAuth();
80
+ return useMemo(() => createFetchClient$3({
81
+ baseUrl: config.baseUrl,
82
+ getAuthToken: () => token,
83
+ onAuthError: config.onAuthError
84
+ }), [
85
+ config.baseUrl,
86
+ config.onAuthError,
87
+ token
88
+ ]);
89
+ }
90
+ function useFluidPayClient() {
91
+ const { config } = useFluidContext();
92
+ const { token } = useFluidAuth();
93
+ return useMemo(() => createFetchClient$1({
94
+ baseUrl: config.baseUrl,
95
+ getAuthToken: () => token,
96
+ onAuthError: config.onAuthError
97
+ }), [
98
+ config.baseUrl,
99
+ config.onAuthError,
100
+ token
101
+ ]);
102
+ }
103
+ /**
104
+ * Generic SDK fetch client for endpoints not covered by domain-specific clients
105
+ * (e.g. /countries, /v202506/customers/:id/points_ledgers).
106
+ * Uses the same auth/baseUrl/error handling as the domain clients.
107
+ */
108
+ function useSdkClient() {
109
+ const { config } = useFluidContext();
110
+ const { token } = useFluidAuth();
111
+ return useMemo(() => createFetchClient({
112
+ baseUrl: config.baseUrl,
113
+ getAuthToken: () => token,
114
+ onAuthError: config.onAuthError
115
+ }), [
116
+ config.baseUrl,
117
+ config.onAuthError,
118
+ token
119
+ ]);
120
+ }
121
+ //#endregion
122
+ //#region src/shell/AppNavigationContext.tsx
123
+ const AppNavigationContext = createContext(null);
124
+ function AppNavigationProvider({ currentSlug, basePath, navigate, children }) {
125
+ const buildHref = useMemo(() => {
126
+ return (slug) => {
127
+ if (basePath === "/") return `/${slug}`;
128
+ return `${basePath}/${slug}`;
129
+ };
130
+ }, [basePath]);
131
+ const value = useMemo(() => ({
132
+ currentSlug,
133
+ basePath,
134
+ navigate,
135
+ buildHref
136
+ }), [
137
+ currentSlug,
138
+ basePath,
139
+ navigate,
140
+ buildHref
141
+ ]);
142
+ return /* @__PURE__ */ jsx(AppNavigationContext.Provider, {
143
+ value,
144
+ children
145
+ });
146
+ }
147
+ function useAppNavigation() {
148
+ const ctx = useContext(AppNavigationContext);
149
+ if (!ctx) throw new Error("useAppNavigation must be used within an <AppShell> or <AppNavigationProvider>");
150
+ return ctx;
151
+ }
152
+ //#endregion
153
+ //#region src/account/AccountManageLayout.tsx
154
+ const NAV_ITEMS = [
155
+ {
156
+ key: "profile",
157
+ label: "Profile",
158
+ slug: "account/profile",
159
+ icon: faUser
160
+ },
161
+ {
162
+ key: "orders",
163
+ label: "Orders",
164
+ slug: "account/orders",
165
+ icon: faBoxOpen
166
+ },
167
+ {
168
+ key: "subscriptions",
169
+ label: "Subscriptions",
170
+ slug: "account/subscriptions",
171
+ icon: faArrowsRepeat
172
+ }
173
+ ];
174
+ function getActiveTab(slug) {
175
+ const sub = slug.split("/")[1];
176
+ if (sub === "orders") return "orders";
177
+ if (sub === "subscriptions") return "subscriptions";
178
+ return "profile";
179
+ }
180
+ function AccountManageLayout({ children }) {
181
+ const { currentSlug, navigate } = useAppNavigation();
182
+ const activeTab = getActiveTab(currentSlug);
183
+ return /* @__PURE__ */ jsxs("div", {
184
+ className: "flex flex-col md:flex-row",
185
+ children: [
186
+ /* @__PURE__ */ jsx("nav", {
187
+ className: "flex gap-1 overflow-x-auto border-b px-4 py-2 md:hidden",
188
+ children: NAV_ITEMS.map((item) => /* @__PURE__ */ jsxs("button", {
189
+ type: "button",
190
+ onClick: () => navigate(item.slug),
191
+ className: `flex items-center gap-2 rounded-md px-3 py-2 text-sm font-medium whitespace-nowrap ${activeTab === item.key ? "bg-sidebar-primary text-sidebar-primary-foreground" : "hover:bg-sidebar-primary hover:text-sidebar-primary-foreground"}`,
192
+ children: [/* @__PURE__ */ jsx(FontAwesomeIcon, {
193
+ icon: item.icon,
194
+ className: "h-4 w-4"
195
+ }), item.label]
196
+ }, item.key))
197
+ }),
198
+ /* @__PURE__ */ jsx("nav", {
199
+ className: "hidden w-48 shrink-0 flex-col gap-1 p-4 md:flex",
200
+ children: NAV_ITEMS.map((item) => /* @__PURE__ */ jsxs("button", {
201
+ type: "button",
202
+ onClick: () => navigate(item.slug),
203
+ className: `flex items-center gap-2 rounded-md px-3 py-2 text-left text-sm font-medium ${activeTab === item.key ? "bg-sidebar-primary text-sidebar-primary-foreground" : "hover:bg-sidebar-primary hover:text-sidebar-primary-foreground"}`,
204
+ children: [/* @__PURE__ */ jsx(FontAwesomeIcon, {
205
+ icon: item.icon,
206
+ className: "h-4 w-4"
207
+ }), item.label]
208
+ }, item.key))
209
+ }),
210
+ /* @__PURE__ */ jsx("div", {
211
+ className: "min-w-0 flex-1",
212
+ children
213
+ })
214
+ ]
215
+ });
216
+ }
217
+ //#endregion
218
+ //#region src/screens/AccountProfileScreen.tsx
219
+ const translations$2 = {
220
+ edit_profile: "Edit Profile",
221
+ first_name: "First Name",
222
+ last_name: "Last Name",
223
+ phone_number: "Phone Number",
224
+ language: "Language",
225
+ first_name_is_required: "First name is required",
226
+ last_name_is_required: "Last name is required",
227
+ language_is_required: "Language is required",
228
+ saving: "Saving...",
229
+ save_changes: "Save Changes",
230
+ select_an_option: "Select an option",
231
+ points_history: "Points History",
232
+ points_available: "Points Available",
233
+ points_awarded: "Points Awarded",
234
+ points_redeemed: "Points Redeemed",
235
+ transaction: "Transaction",
236
+ no_points_history_found: "No points history found",
237
+ shipping_addresses: "Shipping Addresses",
238
+ add_an_address: "Add an Address",
239
+ delete_address: "Delete Address",
240
+ delete_address_message: "Are you sure you want to delete this address? This action cannot be undone.",
241
+ delete: "Delete",
242
+ add_address: "Add Address",
243
+ edit_address: "Edit Address",
244
+ set_as_default_address: "Set as default address",
245
+ save_address: "Save Address",
246
+ card_number: "Card Number",
247
+ expiration_date: "Expiration (MM / YY)",
248
+ cvc: "CVC",
249
+ cardholder_name: "Cardholder Name",
250
+ add_credit_card: "Add Credit Card",
251
+ save_card: "Save Card",
252
+ securing: "Loading secure form...",
253
+ payment_methods: "Payment Methods",
254
+ add_payment_method: "Add Payment Method",
255
+ delete_credit_card: "Delete Credit Card",
256
+ delete_credit_card_message: "Are you sure you want to delete this payment method? This action cannot be undone.",
257
+ edit_card: "Card Details",
258
+ billing_address: "Billing Address",
259
+ country: "Country",
260
+ name: "Name",
261
+ address_line_1: "Address Line 1",
262
+ address_line_2: "Address Line 2",
263
+ city: "City",
264
+ state: "State",
265
+ province: "Province",
266
+ zip_code: "Zip Code",
267
+ postal_code: "Postal Code",
268
+ select_state: "Select state",
269
+ set_as_default_payment_method: "Set as default payment method",
270
+ cancel: "Cancel",
271
+ save: "Save",
272
+ close: "Close",
273
+ edit: "Edit",
274
+ default: "Default",
275
+ card_expires: "Expires",
276
+ no_billing_address: "No billing address on file",
277
+ default_payment_method_updated: "Payment method updated",
278
+ failed_to_set_default_payment_method: "Failed to update payment method"
279
+ };
280
+ function t(key) {
281
+ if (translations$2[key]) return translations$2[key];
282
+ return key.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
283
+ }
284
+ function adaptPointsLedger(entry) {
285
+ return {
286
+ id: entry.id,
287
+ amount: entry.amount,
288
+ company_id: 0,
289
+ created_at: entry.created_at,
290
+ customer_id: entry.customer_id,
291
+ metadata: {
292
+ transaction_type: entry.metadata?.transaction_type ?? void 0,
293
+ source: entry.metadata?.source ?? void 0
294
+ },
295
+ total_balance: entry.total_balance ?? 0,
296
+ updated_at: entry.created_at
297
+ };
298
+ }
299
+ function AccountProfileScreen({ onToast, countryIso }) {
300
+ const { token, user } = useFluidAuth();
301
+ const client = useFluidPayClient();
302
+ const sdkClient = useSdkClient();
303
+ const queryClient = useQueryClient();
304
+ const jwt = token ?? "";
305
+ const userId = user?.id;
306
+ const { data: accountData, isLoading: isLoadingAccount, isError: isAccountError } = useQuery({
307
+ queryKey: ["fluidPayAccount", userId],
308
+ queryFn: () => customersApi.fetchCustomerAccount(client, jwt),
309
+ enabled: !!jwt
310
+ });
311
+ const { data: addressesData, isLoading: isLoadingAddresses } = useQuery({
312
+ queryKey: ["fluidPayAddresses", userId],
313
+ queryFn: () => addressesApi.fetchCustomerAddresses(client, jwt),
314
+ enabled: !!jwt
315
+ });
316
+ const { data: paymentMethodsData, isLoading: isLoadingPaymentMethods } = useQuery({
317
+ queryKey: [
318
+ "fluidPayPaymentMethods",
319
+ userId,
320
+ countryIso
321
+ ],
322
+ queryFn: () => paymentMethodsApi.fetchCustomerPaymentMethods(client, jwt, countryIso),
323
+ enabled: !!jwt
324
+ });
325
+ const { data: countriesData } = useQuery({
326
+ queryKey: ["sdk-countries"],
327
+ queryFn: () => sdkClient.get("/countries"),
328
+ initialData: []
329
+ });
330
+ const customerId = accountData?.customer?.id;
331
+ const { data: pointsLedgerData, isLoading: isLoadingPointsLedger } = useQuery({
332
+ queryKey: ["customer-points-ledger", customerId],
333
+ queryFn: () => sdkClient.get(`${API_VERSION}/customers/${customerId}/points_ledgers`),
334
+ enabled: !!customerId
335
+ });
336
+ const updateCustomerMutation = useMutation({
337
+ mutationFn: (data) => {
338
+ const languageIso = adaptedLanguages?.find((l) => l.name === data.language)?.iso ?? "en";
339
+ return customersApi.updateCustomer(client, jwt, {
340
+ first_name: data.first_name,
341
+ last_name: data.last_name,
342
+ phone: data.phone_number,
343
+ language_iso: languageIso
344
+ });
345
+ },
346
+ onSuccess: () => {
347
+ queryClient.invalidateQueries({ queryKey: ["fluidPayAccount", userId] });
348
+ onToast("Profile updated", "success");
349
+ },
350
+ onError: () => {
351
+ onToast("Failed to update profile", "error");
352
+ }
353
+ });
354
+ const deleteAddressMutation = useMutation({
355
+ mutationFn: (addressId) => addressesApi.deleteCustomerAddress(client, jwt, addressId),
356
+ onSuccess: () => {
357
+ queryClient.invalidateQueries({ queryKey: ["fluidPayAddresses", userId] });
358
+ }
359
+ });
360
+ const deletePaymentMethodMutation = useMutation({
361
+ mutationFn: (paymentMethodId) => paymentMethodsApi.deleteCustomerPaymentMethod(client, jwt, paymentMethodId),
362
+ onSuccess: () => {
363
+ queryClient.invalidateQueries({ queryKey: [
364
+ "fluidPayPaymentMethods",
365
+ userId,
366
+ countryIso
367
+ ] });
368
+ }
369
+ });
370
+ const updatePaymentMethodMutation = useMutation({
371
+ mutationFn: ({ paymentMethodId, data }) => paymentMethodsApi.updatePaymentMethod(client, jwt, paymentMethodId, {
372
+ set_as_default: data.set_as_default,
373
+ billing_address: data.billing_address
374
+ }),
375
+ onSuccess: () => {
376
+ queryClient.invalidateQueries({ queryKey: [
377
+ "fluidPayPaymentMethods",
378
+ userId,
379
+ countryIso
380
+ ] });
381
+ }
382
+ });
383
+ const createAddressMutation = useMutation({
384
+ mutationFn: (body) => addressesApi.createCustomerAddress(client, jwt, body),
385
+ onSuccess: () => {
386
+ queryClient.invalidateQueries({ queryKey: ["fluidPayAddresses", userId] });
387
+ onToast("Address created", "success");
388
+ },
389
+ onError: () => {
390
+ onToast("Failed to create address", "error");
391
+ }
392
+ });
393
+ const updateAddressMutation = useMutation({
394
+ mutationFn: ({ addressId, body }) => addressesApi.updateCustomerAddress(client, jwt, addressId, body),
395
+ onSuccess: () => {
396
+ queryClient.invalidateQueries({ queryKey: ["fluidPayAddresses", userId] });
397
+ onToast("Address updated", "success");
398
+ },
399
+ onError: () => {
400
+ onToast("Failed to update address", "error");
401
+ }
402
+ });
403
+ const addCreditCardMutation = useMutation({
404
+ mutationFn: (data) => paymentMethodsApi.addCreditCardToCustomer(client, jwt, data),
405
+ onSuccess: () => {
406
+ queryClient.invalidateQueries({ queryKey: [
407
+ "fluidPayPaymentMethods",
408
+ userId,
409
+ countryIso
410
+ ] });
411
+ onToast("Payment method added", "success");
412
+ },
413
+ onError: () => {
414
+ onToast("Failed to add payment method", "error");
415
+ }
416
+ });
417
+ const addresses = addressesData?.addresses ?? [];
418
+ const paymentMethods = paymentMethodsData?.payment_methods ?? [];
419
+ const adaptedPointsLedger = pointsLedgerData?.points_ledgers?.map(adaptPointsLedger) ?? [];
420
+ const adaptedLanguages = [{
421
+ id: 0,
422
+ name: "English",
423
+ iso: "en"
424
+ }];
425
+ const countryOptions = useMemo(() => [...countriesData].map((c) => ({
426
+ iso: c.iso,
427
+ name: c.name
428
+ })).sort((a, b) => a.name.localeCompare(b.name)), [countriesData]);
429
+ if (!token) return /* @__PURE__ */ jsx("div", {
430
+ className: "px-4 py-8 sm:px-9",
431
+ children: /* @__PURE__ */ jsx("div", {
432
+ className: "rounded-lg border p-4 text-center",
433
+ children: "Login Required"
434
+ })
435
+ });
436
+ if (isAccountError && !isLoadingAccount) return /* @__PURE__ */ jsx("div", {
437
+ className: "px-4 py-8 sm:px-9",
438
+ children: /* @__PURE__ */ jsx("div", {
439
+ className: "text-muted-foreground text-center text-sm",
440
+ children: "Unable to load account data. Please try again later."
441
+ })
442
+ });
443
+ if (isLoadingAccount || !accountData) return /* @__PURE__ */ jsx("div", {
444
+ className: "px-4 pt-4 sm:px-9 md:pt-8",
445
+ children: /* @__PURE__ */ jsxs("div", {
446
+ className: "space-y-4",
447
+ children: [
448
+ /* @__PURE__ */ jsx("div", { className: "bg-muted h-16 animate-pulse rounded" }),
449
+ /* @__PURE__ */ jsx("div", { className: "bg-muted h-32 animate-pulse rounded" }),
450
+ /* @__PURE__ */ jsx("div", { className: "bg-muted h-32 animate-pulse rounded" })
451
+ ]
452
+ })
453
+ });
454
+ return /* @__PURE__ */ jsx("div", {
455
+ className: "px-4 pt-4 sm:px-9 md:pt-8",
456
+ children: /* @__PURE__ */ jsx(ProfileUIProvider, {
457
+ t,
458
+ children: /* @__PURE__ */ jsx(Profile, {
459
+ customerAccount: accountData,
460
+ languages: adaptedLanguages,
461
+ onUpdateCustomer: async (data) => {
462
+ await updateCustomerMutation.mutateAsync(data);
463
+ },
464
+ isUpdatingCustomer: updateCustomerMutation.isPending,
465
+ rewardsPointsEnabled: adaptedPointsLedger.length > 0,
466
+ pointsLedger: adaptedPointsLedger,
467
+ isLoadingPointsLedger,
468
+ addresses,
469
+ isLoadingAddresses,
470
+ onDeleteAddress: async (addressId) => {
471
+ await deleteAddressMutation.mutateAsync(addressId);
472
+ },
473
+ isDeletingAddress: deleteAddressMutation.isPending,
474
+ paymentMethods,
475
+ isLoadingPaymentMethods,
476
+ onDeletePaymentMethod: async (paymentMethodId) => {
477
+ await deletePaymentMethodMutation.mutateAsync(paymentMethodId);
478
+ },
479
+ isDeletingPaymentMethod: deletePaymentMethodMutation.isPending,
480
+ onUpdatePaymentMethod: async (paymentMethodId, data) => {
481
+ await updatePaymentMethodMutation.mutateAsync({
482
+ paymentMethodId,
483
+ data
484
+ });
485
+ },
486
+ isUpdatingPaymentMethod: updatePaymentMethodMutation.isPending,
487
+ getBillingAddress: (pm) => pm.billing_address ?? null,
488
+ countries: countryOptions,
489
+ renderAddressDialog: ({ isOpen, onClose, selectedAddress }) => /* @__PURE__ */ jsx(AddressFormDialog, {
490
+ isOpen,
491
+ onClose,
492
+ selectedAddress,
493
+ t,
494
+ onSubmit: async (formData) => {
495
+ if (selectedAddress) await updateAddressMutation.mutateAsync({
496
+ addressId: selectedAddress.id,
497
+ body: formData
498
+ });
499
+ else await createAddressMutation.mutateAsync(formData);
500
+ onClose();
501
+ },
502
+ isSubmitting: createAddressMutation.isPending || updateAddressMutation.isPending,
503
+ countries: countryOptions,
504
+ renderAddressAutocomplete: ({ control, setValue: _setValue }) => /* @__PURE__ */ jsx(PlainAddressInput, {
505
+ control,
506
+ name: "address1"
507
+ })
508
+ }),
509
+ renderCreditCardDialog: ({ isOpen, onClose }) => /* @__PURE__ */ jsx(CreditCardFormDialog, {
510
+ isOpen,
511
+ onClose,
512
+ t,
513
+ onSubmit: async (data) => {
514
+ await addCreditCardMutation.mutateAsync(data);
515
+ onClose();
516
+ },
517
+ isSubmitting: addCreditCardMutation.isPending,
518
+ countries: countryOptions,
519
+ jwt,
520
+ client,
521
+ renderAddressAutocomplete: ({ control, setValue: _setValue }) => /* @__PURE__ */ jsx(PlainAddressInput, {
522
+ control,
523
+ name: "address1"
524
+ })
525
+ })
526
+ })
527
+ })
528
+ });
529
+ }
530
+ /**
531
+ * Plain text input fallback for address autocomplete.
532
+ * The SDK doesn't have Google Places integration.
533
+ */
534
+ function PlainAddressInput({ control, name }) {
535
+ const { field } = useController({
536
+ control,
537
+ name
538
+ });
539
+ return /* @__PURE__ */ jsx("input", {
540
+ type: "text",
541
+ value: field.value ?? "",
542
+ placeholder: "Address Line 1",
543
+ className: "border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex h-10 w-full rounded-md border px-3 py-2 text-sm file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50",
544
+ onChange: field.onChange
545
+ });
546
+ }
547
+ //#endregion
548
+ //#region src/screens/AccountOrdersScreen.tsx
549
+ const translations$1 = {
550
+ search_orders: "Search orders...",
551
+ order_number: "Order #",
552
+ date: "Date",
553
+ status: "Status",
554
+ product: "Product",
555
+ no_orders_found: "No orders found",
556
+ no_matching_orders: "No matching orders",
557
+ no_image_available: "No image available",
558
+ this_product_no_longer_exists: "This product no longer exists",
559
+ subscription: "Subscription",
560
+ view_subscription: "View Subscription",
561
+ total: "Total",
562
+ results: "results",
563
+ previous: "Previous",
564
+ next: "Next",
565
+ pagination: "Pagination"
566
+ };
567
+ function AccountOrdersScreen({ customerId, isLoadingCustomer }) {
568
+ const ordersClient = useOrdersClient();
569
+ const { navigate } = useAppNavigation();
570
+ const handleOrderClick = (order) => {
571
+ navigate(`account/orders/${order.token}`);
572
+ };
573
+ const handleSubscriptionClick = (subscriptionToken) => {
574
+ navigate(`account/subscriptions/${subscriptionToken}`);
575
+ };
576
+ if (isLoadingCustomer) return /* @__PURE__ */ jsx("div", {
577
+ className: "mx-auto max-w-7xl px-4 py-4 sm:px-6 sm:py-6 lg:px-10 lg:py-8",
578
+ children: /* @__PURE__ */ jsxs("div", {
579
+ className: "space-y-3",
580
+ children: [/* @__PURE__ */ jsx("div", { className: "bg-muted h-10 animate-pulse rounded" }), /* @__PURE__ */ jsx("div", { className: "bg-muted h-64 animate-pulse rounded" })]
581
+ })
582
+ });
583
+ return /* @__PURE__ */ jsx(OrdersCoreProvider, {
584
+ client: ordersClient,
585
+ children: /* @__PURE__ */ jsx("div", {
586
+ className: "mx-auto max-w-7xl px-4 py-4 sm:px-6 sm:py-6 lg:px-10 lg:py-8",
587
+ children: /* @__PURE__ */ jsx(OrdersList, {
588
+ customerId,
589
+ onOrderClick: handleOrderClick,
590
+ onSubscriptionClick: handleSubscriptionClick,
591
+ t: (key) => translations$1[key] ?? key
592
+ })
593
+ })
594
+ });
595
+ }
596
+ //#endregion
597
+ //#region src/screens/AccountOrderDetailScreen.tsx
598
+ function AccountOrderDetailScreen({ token, onToast }) {
599
+ const client = useOrdersClient();
600
+ const { navigate } = useAppNavigation();
601
+ return /* @__PURE__ */ jsx(OrdersCoreProvider, {
602
+ client,
603
+ children: /* @__PURE__ */ jsx("div", {
604
+ className: "mx-auto max-w-7xl px-4 py-4 sm:px-6 sm:py-6 lg:px-10 lg:py-8",
605
+ children: /* @__PURE__ */ jsx(OrderDetail, {
606
+ token,
607
+ onNotFound: () => {
608
+ onToast("Order not found", "warning");
609
+ navigate("account/orders");
610
+ },
611
+ onError: (err) => {
612
+ onToast(`Failed to load order: ${err instanceof Error ? err.message : "An error occurred"}`, "error");
613
+ }
614
+ })
615
+ })
616
+ });
617
+ }
618
+ //#endregion
619
+ //#region src/screens/AccountSubscriptionsScreen.tsx
620
+ const translations = {
621
+ all: "All",
622
+ active: "Active",
623
+ inactive: "Inactive",
624
+ search: "Search",
625
+ subscriptions: "Search subscriptions...",
626
+ product: "Product",
627
+ next_bill_date: "Next Bill Date",
628
+ price: "Price",
629
+ status: "Status",
630
+ no_subscriptions_found: "No subscriptions found",
631
+ unknown_status: "Unknown",
632
+ total: "Total",
633
+ results: "results",
634
+ previous: "Previous",
635
+ next: "Next",
636
+ pagination: "Pagination"
637
+ };
638
+ function AccountSubscriptionsScreen({ customerId, isLoadingCustomer }) {
639
+ const subscriptionsClient = useSubscriptionsClient();
640
+ const { navigate } = useAppNavigation();
641
+ if (isLoadingCustomer) return /* @__PURE__ */ jsx("div", {
642
+ className: "mx-auto max-w-7xl px-4 py-4 sm:px-6 sm:py-6 lg:px-10 lg:py-8",
643
+ children: /* @__PURE__ */ jsxs("div", {
644
+ className: "space-y-3",
645
+ children: [/* @__PURE__ */ jsx("div", { className: "bg-muted h-10 animate-pulse rounded" }), /* @__PURE__ */ jsx("div", { className: "bg-muted h-64 animate-pulse rounded" })]
646
+ })
647
+ });
648
+ return /* @__PURE__ */ jsx(SubscriptionsCoreProvider, {
649
+ client: subscriptionsClient,
650
+ children: /* @__PURE__ */ jsx("div", {
651
+ className: "mx-auto max-w-7xl px-4 py-4 sm:px-6 sm:py-6 lg:px-10 lg:py-8",
652
+ children: /* @__PURE__ */ jsx(SubscriptionsList, {
653
+ customerId,
654
+ onSubscriptionClick: (subscriptionToken) => navigate(`account/subscriptions/${subscriptionToken}`),
655
+ t: (key) => translations[key] ?? key
656
+ })
657
+ })
658
+ });
659
+ }
660
+ //#endregion
661
+ //#region src/screens/AccountSubscriptionDetailScreen.tsx
662
+ function AccountSubscriptionDetailScreen({ token, onToast }) {
663
+ const client = useSubscriptionsClient();
664
+ const { navigate } = useAppNavigation();
665
+ return /* @__PURE__ */ jsx(SubscriptionsCoreProvider, {
666
+ client,
667
+ children: /* @__PURE__ */ jsx("div", {
668
+ className: "mx-auto max-w-7xl px-4 py-4 sm:px-6 sm:py-6 lg:px-10 lg:py-8",
669
+ children: /* @__PURE__ */ jsx(SubscriptionDetail, {
670
+ token,
671
+ onNotFound: () => {
672
+ onToast("Subscription not found", "warning");
673
+ navigate("account/subscriptions");
674
+ },
675
+ onError: (err) => {
676
+ onToast(`Failed to load subscription: ${err instanceof Error ? err.message : "An error occurred"}`, "error");
677
+ },
678
+ onSuccess: (message) => {
679
+ onToast(message, "success");
680
+ },
681
+ onMutationError: (message, err) => {
682
+ onToast(`${message}: ${err instanceof Error ? err.message : "An error occurred"}`, "error");
683
+ }
684
+ })
685
+ })
686
+ });
687
+ }
688
+ //#endregion
689
+ //#region src/screens/AccountScreen.tsx
690
+ function defaultToast(message, type) {
691
+ if (type === "error" || type === "warning") console.warn("[Account]", message);
692
+ else console.info("[Account]", message);
693
+ }
694
+ function AccountScreen({ onToast, background, textColor, accentColor, padding, borderRadius, ...divProps }) {
695
+ const { currentSlug } = useAppNavigation();
696
+ const { config } = useFluidContext();
697
+ const effectiveToast = onToast ?? defaultToast;
698
+ const { token, user } = useFluidAuth();
699
+ const fluidPayClient = useFluidPayClient();
700
+ const jwt = token ?? "";
701
+ const { data: customerData, isLoading: isLoadingCustomer, isError: isCustomerError } = useQuery({
702
+ queryKey: ["fluidPayAccount", user?.id],
703
+ queryFn: () => customersApi.fetchCustomerAccount(fluidPayClient, jwt),
704
+ enabled: !!jwt
705
+ });
706
+ const customerId = customerData?.customer?.id;
707
+ const countryIso = config.countryIso ?? "US";
708
+ const parts = currentSlug.split("/");
709
+ const subRoute = parts[1];
710
+ const detailToken = parts[2];
711
+ if ((subRoute === "orders" && !detailToken || subRoute === "subscriptions" && !detailToken) && isCustomerError && !isLoadingCustomer) return /* @__PURE__ */ jsx("div", {
712
+ ...divProps,
713
+ children: /* @__PURE__ */ jsx(AccountManageLayout, { children: /* @__PURE__ */ jsx("div", {
714
+ className: "text-muted-foreground px-4 py-8 text-center text-sm",
715
+ children: "Unable to load account data. Please try again later."
716
+ }) })
717
+ });
718
+ return /* @__PURE__ */ jsx("div", {
719
+ ...divProps,
720
+ children: /* @__PURE__ */ jsx(AccountManageLayout, { children: subRoute === "orders" && detailToken ? /* @__PURE__ */ jsx(AccountOrderDetailScreen, {
721
+ token: detailToken,
722
+ onToast: effectiveToast
723
+ }) : subRoute === "orders" ? /* @__PURE__ */ jsx(AccountOrdersScreen, {
724
+ customerId,
725
+ isLoadingCustomer
726
+ }) : subRoute === "subscriptions" && detailToken ? /* @__PURE__ */ jsx(AccountSubscriptionDetailScreen, {
727
+ token: detailToken,
728
+ onToast: effectiveToast
729
+ }) : subRoute === "subscriptions" ? /* @__PURE__ */ jsx(AccountSubscriptionsScreen, {
730
+ customerId,
731
+ isLoadingCustomer
732
+ }) : /* @__PURE__ */ jsx(AccountProfileScreen, {
733
+ onToast: effectiveToast,
734
+ countryIso
735
+ }) })
736
+ });
737
+ }
738
+ const accountScreenPropertySchema = {
739
+ widgetType: "AccountScreen",
740
+ displayName: "Account Screen",
741
+ tabsConfig: [{
742
+ id: "styling",
743
+ label: "Styling"
744
+ }],
745
+ fields: []
746
+ };
747
+ //#endregion
748
+ export { useFluidAuth as a, useAppNavigation as i, accountScreenPropertySchema as n, AppNavigationProvider as r, AccountScreen as t };
749
+
750
+ //# sourceMappingURL=AccountScreen-CPHYsITD.mjs.map