@fluid-app/portal-sdk 0.1.74 → 0.1.76

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 (47) hide show
  1. package/dist/{ContactsScreen-fNFKA1nn.cjs → ContactsScreen-B45I4fsu.cjs} +2 -2
  2. package/dist/{ContactsScreen-fNFKA1nn.cjs.map → ContactsScreen-B45I4fsu.cjs.map} +1 -1
  3. package/dist/{ContactsScreen-pCkw9htG.cjs → ContactsScreen-BY_bV9hD.cjs} +2 -2
  4. package/dist/{ContactsScreen-CzvfANNV.mjs → ContactsScreen-fv44z4G1.mjs} +2 -2
  5. package/dist/{ContactsScreen-CzvfANNV.mjs.map → ContactsScreen-fv44z4G1.mjs.map} +1 -1
  6. package/dist/{MySiteScreen-CqeZTwj9.mjs → MySiteScreen-BfYDwE3C.mjs} +12 -11
  7. package/dist/MySiteScreen-BfYDwE3C.mjs.map +1 -0
  8. package/dist/{MySiteScreen-BhFE_jmk.cjs → MySiteScreen-CEb9L0vp.cjs} +1 -1
  9. package/dist/{MySiteScreen-Ci2rLGQc.cjs → MySiteScreen-DY7PSqP6.cjs} +11 -10
  10. package/dist/MySiteScreen-DY7PSqP6.cjs.map +1 -0
  11. package/dist/{OrdersScreen-Bkdrj8I1.cjs → OrdersScreen-CB_VOlRI.cjs} +2 -2
  12. package/dist/{OrdersScreen-Bkdrj8I1.cjs.map → OrdersScreen-CB_VOlRI.cjs.map} +1 -1
  13. package/dist/{OrdersScreen-DOI-Rl_H.mjs → OrdersScreen-CuQTI5f9.mjs} +2 -2
  14. package/dist/{OrdersScreen-DOI-Rl_H.mjs.map → OrdersScreen-CuQTI5f9.mjs.map} +1 -1
  15. package/dist/{OrdersScreen-GlJc86ai.cjs → OrdersScreen-D5_PtRCp.cjs} +2 -2
  16. package/dist/{ProductsScreen-xjbHMcvT.cjs → ProductsScreen-D1hLP4qn.cjs} +2 -2
  17. package/dist/{ProductsScreen-xjbHMcvT.cjs.map → ProductsScreen-D1hLP4qn.cjs.map} +1 -1
  18. package/dist/{ProductsScreen-BvpKx6qj.cjs → ProductsScreen-DD07WW44.cjs} +2 -2
  19. package/dist/{ProductsScreen-hvPMLQ9W.mjs → ProductsScreen-KLajmCLk.mjs} +2 -2
  20. package/dist/{ProductsScreen-hvPMLQ9W.mjs.map → ProductsScreen-KLajmCLk.mjs.map} +1 -1
  21. package/dist/{ProductsScreen-CI4XIK-8.mjs → ProductsScreen-SExV06P8.mjs} +2 -5
  22. package/dist/{ShareablesScreen-DdwtbkpR.cjs → ShareablesScreen-BKidUZz_.cjs} +2 -2
  23. package/dist/{ShareablesScreen-Cvo2ujdv.cjs → ShareablesScreen-CA8sm7n_.cjs} +2 -2
  24. package/dist/{ShareablesScreen-Cvo2ujdv.cjs.map → ShareablesScreen-CA8sm7n_.cjs.map} +1 -1
  25. package/dist/{ShareablesScreen-Bry6-PII.mjs → ShareablesScreen-CTruUco1.mjs} +2 -2
  26. package/dist/{ShareablesScreen-Bry6-PII.mjs.map → ShareablesScreen-CTruUco1.mjs.map} +1 -1
  27. package/dist/{ShareablesScreen-htQIO4oW.mjs → ShareablesScreen-C_aJXryA.mjs} +2 -5
  28. package/dist/{SubscriptionsScreen-C2n-qh9n.mjs → SubscriptionsScreen-CBoAwhKQ.mjs} +2 -2
  29. package/dist/{SubscriptionsScreen-C2n-qh9n.mjs.map → SubscriptionsScreen-CBoAwhKQ.mjs.map} +1 -1
  30. package/dist/{SubscriptionsScreen-Lvd76SAc.cjs → SubscriptionsScreen-D5oQ8bt1.cjs} +2 -2
  31. package/dist/{SubscriptionsScreen-Lvd76SAc.cjs.map → SubscriptionsScreen-D5oQ8bt1.cjs.map} +1 -1
  32. package/dist/{SubscriptionsScreen-B_RaW9A9.cjs → SubscriptionsScreen-DxYZJ0k6.cjs} +2 -2
  33. package/dist/index.cjs +20 -20
  34. package/dist/index.mjs +20 -20
  35. package/dist/{order-detail-LrdeXs2m.cjs → order-detail-65Ln2EUO.cjs} +25 -38
  36. package/dist/{order-detail-LrdeXs2m.cjs.map → order-detail-65Ln2EUO.cjs.map} +1 -1
  37. package/dist/{order-detail--h20GcWg.mjs → order-detail-o-C0YhaZ.mjs} +25 -38
  38. package/dist/{order-detail--h20GcWg.mjs.map → order-detail-o-C0YhaZ.mjs.map} +1 -1
  39. package/dist/{src-2yiesCJi.cjs → src-B-aQFEbA.cjs} +17 -5
  40. package/dist/src-B-aQFEbA.cjs.map +1 -0
  41. package/dist/{src-CghkSQGd.mjs → src-CvQ9ezCI.mjs} +17 -5
  42. package/dist/src-CvQ9ezCI.mjs.map +1 -0
  43. package/package.json +14 -14
  44. package/dist/MySiteScreen-Ci2rLGQc.cjs.map +0 -1
  45. package/dist/MySiteScreen-CqeZTwj9.mjs.map +0 -1
  46. package/dist/src-2yiesCJi.cjs.map +0 -1
  47. package/dist/src-CghkSQGd.mjs.map +0 -1
@@ -8,7 +8,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
8
8
  import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
9
9
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
10
10
  import { z } from "zod";
11
- import { ArrowLeft, Camera, Check, ChevronRight, Copy, Eye, GripVertical, LayoutGrid, Link2, Palette, Pencil, Plus, Trash2, User, Users } from "lucide-react";
11
+ import { ArrowLeft, Camera, Check, ChevronRight, Copy, Eye, GripVertical, LayoutGrid, Link2, LoaderCircle, Palette, Pencil, Plus, Trash2, User, Users } from "lucide-react";
12
12
  //#region src/mysite/use-mysite-config.ts
13
13
  /**
14
14
  * Hook that derives a FetchClient from the portal SDK's FluidProvider context.
@@ -551,7 +551,7 @@ function MySiteLinkCard({ mysiteUrl, displayUrl, onUpdateSlug, onToast }) {
551
551
  }
552
552
  //#endregion
553
553
  //#region ../../mysite/ui/src/portal/components/PhonePreview.tsx
554
- function MySitePhonePreview({ mysiteUrl, themeName, selectedThemeId, previewKey, onPreview }) {
554
+ function MySitePhonePreview({ mysiteUrl, themeName, previewKey, isUpdating, onPreview }) {
555
555
  return /* @__PURE__ */ jsxs(Card, {
556
556
  className: "items-center gap-4 py-5",
557
557
  children: [/* @__PURE__ */ jsxs(CardHeader, {
@@ -586,11 +586,15 @@ function MySitePhonePreview({ mysiteUrl, themeName, selectedThemeId, previewKey,
586
586
  }), /* @__PURE__ */ jsx("div", {
587
587
  className: "relative h-[600px] overflow-y-auto bg-[#ffffff]",
588
588
  style: { scrollbarWidth: "none" },
589
- children: mysiteUrl ? /* @__PURE__ */ jsx("iframe", {
589
+ "aria-busy": isUpdating,
590
+ children: mysiteUrl ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("iframe", {
590
591
  className: "h-full w-full origin-top-left bg-[#ffffff]",
591
592
  src: `${mysiteUrl}?preview=true`,
592
593
  title: "MySite Preview"
593
- }, `${selectedThemeId}-${previewKey}`) : /* @__PURE__ */ jsx("div", {
594
+ }, previewKey), isUpdating && /* @__PURE__ */ jsx("div", {
595
+ className: "absolute inset-0 flex items-center justify-center bg-white/60",
596
+ children: /* @__PURE__ */ jsx(LoaderCircle, { className: "text-muted-foreground h-6 w-6 animate-spin" })
597
+ })] }) : /* @__PURE__ */ jsx("div", {
594
598
  className: "flex h-full items-center justify-center",
595
599
  children: /* @__PURE__ */ jsx("p", {
596
600
  className: "text-muted-foreground text-sm",
@@ -641,11 +645,8 @@ function MySiteThemeEditor({ themes, selectedThemeId, onSelectTheme, isPending,
641
645
  loading: "lazy",
642
646
  className: "absolute inset-0 h-full w-full object-cover"
643
647
  }) : /* @__PURE__ */ jsx("div", {
644
- className: "text-muted-foreground flex h-full w-full items-center justify-center",
645
- children: /* @__PURE__ */ jsx("span", {
646
- className: "text-xs",
647
- children: "No preview"
648
- })
648
+ className: "text-muted-foreground/50 flex h-full w-full items-center justify-center",
649
+ children: /* @__PURE__ */ jsx(Palette, { className: "h-8 w-8" })
649
650
  }),
650
651
  isSelected && /* @__PURE__ */ jsx("div", {
651
652
  className: "bg-primary/20 absolute inset-0 flex items-center justify-center",
@@ -1727,8 +1728,8 @@ function MySiteMainView({ client }) {
1727
1728
  children: /* @__PURE__ */ jsx(MySitePhonePreview, {
1728
1729
  mysiteUrl,
1729
1730
  themeName,
1730
- selectedThemeId: resolvedThemeId,
1731
1731
  previewKey,
1732
+ isUpdating: updateMySiteMutation.isPending,
1732
1733
  onPreview: handlePreview
1733
1734
  })
1734
1735
  })]
@@ -1793,4 +1794,4 @@ const mySiteScreenPropertySchema = {
1793
1794
  //#endregion
1794
1795
  export { MySiteScreen_exports as n, mySiteScreenPropertySchema as r, MySiteScreen as t };
1795
1796
 
1796
- //# sourceMappingURL=MySiteScreen-CqeZTwj9.mjs.map
1797
+ //# sourceMappingURL=MySiteScreen-BfYDwE3C.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MySiteScreen-BfYDwE3C.mjs","names":["updateMySiteApi","updateProfileApi","defaultToast"],"sources":["../src/mysite/use-mysite-config.ts","../../../mysite/ui/src/shared/query-keys.ts","../../../mysite/ui/src/shared/schemas/mysite.schema.ts","../../../mysite/ui/src/admin/networking/mysite.api.ts","../../../mysite/ui/src/shared/schemas/mysite-theme.schema.ts","../../../mysite/ui/src/admin/networking/mysite-theme.api.ts","../../../mysite/ui/src/admin/hooks/use-mysite.ts","../../../mysite/ui/src/portal/components/animation-utils.ts","../../../mysite/ui/src/portal/components/VisitorDetailsCard.tsx","../../../mysite/ui/src/portal/components/MySiteLinkCard.tsx","../../../mysite/ui/src/portal/components/PhonePreview.tsx","../../../mysite/ui/src/portal/components/ThemeEditor.tsx","../../../mysite/ui/src/shared/utils.ts","../../../mysite/ui/src/portal/components/ButtonsEditor.tsx","../../../mysite/ui/src/portal/components/FavoritesEditor.tsx","../../../mysite/ui/src/portal/components/MySiteProfileForm.tsx","../src/screens/MySiteScreen/MySiteMainView.tsx","../src/screens/MySiteScreen/MySiteProfileView.tsx","../src/screens/MySiteScreen/index.tsx"],"sourcesContent":["/**\n * Hook that derives a FetchClient from the portal SDK's FluidProvider context.\n *\n * Maps FluidSDKConfig fields to a FetchClient suitable for MySite API endpoints.\n * Follows the same pattern as useContactsConfig.\n */\n\nimport { useMemo } from \"react\";\nimport { createFetchClient } from \"@fluid-app/api-client-core\";\nimport type { FetchClient } from \"@fluid-app/api-client-core\";\nimport { useFluidContext } from \"../providers/FluidProvider\";\n\nexport function useMySiteConfig(): { client: FetchClient } {\n const { config } = useFluidContext();\n\n const client = useMemo(() => {\n // Keep /api in the baseUrl — mysite-ui hooks use paths like /me.json,\n // /mysite.json, /users/{id}/links.json which need the /api prefix.\n // The baseUrl from FluidProvider already includes /api.\n const baseUrl = config.baseUrl.replace(/\\/+$/, \"\");\n\n return createFetchClient({\n baseUrl,\n getAuthToken: config.getAuthToken,\n onAuthError: config.onAuthError,\n defaultHeaders: config.defaultHeaders,\n });\n }, [\n config.baseUrl,\n config.getAuthToken,\n config.onAuthError,\n config.defaultHeaders,\n ]);\n\n return { client };\n}\n","export const MYSITE_KEYS = {\n links: (userId: number) => [\"mysite\", \"links\", userId] as const,\n favorites: (affiliateId: number) =>\n [\"mysite\", \"favorites\", affiliateId] as const,\n themes: () => [\"mysite\", \"themes\"] as const,\n defaultMySite: () => [\"mysite\", \"default\"] as const,\n defaultMySiteFavorites: () => [\"mysite\", \"default\", \"favorites\"] as const,\n};\n","import { z } from \"zod\";\n\n// User Links (Buttons)\nexport const linkSchema = z.object({\n id: z.number(),\n url: z.string(),\n text: z.string(),\n order: z.number(),\n clicks: z.number().optional().default(0),\n});\n\nexport const linksResponseSchema = z.array(linkSchema);\n\nexport type MySiteLink = z.infer<typeof linkSchema>;\n\n// Favorites\nexport const favoriteableSchema = z\n .object({\n id: z.number(),\n title: z.string().nullable().optional(),\n name: z.string().nullable().optional(),\n image_url: z.string().nullable().optional(),\n type: z.string().optional(),\n })\n .passthrough();\n\nexport const favoriteSchema = z\n .object({\n id: z.number(),\n favoriteable_id: z.number().optional(),\n favoriteable_type: z.string(),\n order: z.number(),\n user_company_id: z.number().optional(),\n created_at: z.string().optional(),\n favoriteable: favoriteableSchema.nullable(),\n })\n .passthrough();\n\nexport const favoritesResponseSchema = z.array(favoriteSchema);\n\nexport type MySiteFavorite = z.infer<typeof favoriteSchema>;\n\n// MySite Update\nexport const mysiteUpdateResponseSchema = z\n .object({\n id: z.number(),\n })\n .passthrough();\n\n// User Profile Update\nexport const profileUpdateResponseSchema = z.object({\n id: z.number(),\n bio: z.string().nullable(),\n facebook: z.string().nullable(),\n twitter: z.string().nullable(),\n instagram: z.string().nullable(),\n youtube: z.string().nullable(),\n pinterest: z.string().nullable(),\n tiktok: z.string().nullable(),\n linkedin: z.string().nullable(),\n whatsapp: z.string().nullable(),\n wechat: z.string().nullable(),\n image_url: z.string().nullable(),\n});\n\nexport type ProfileUpdateResponse = z.infer<typeof profileUpdateResponseSchema>;\n","import type { FetchClient } from \"./types\";\nimport {\n linksResponseSchema,\n linkSchema,\n favoritesResponseSchema,\n favoriteSchema,\n mysiteUpdateResponseSchema,\n profileUpdateResponseSchema,\n} from \"../../shared/schemas/mysite.schema\";\n\nexport async function getUserLinks(client: FetchClient, userId: number) {\n const response = await client.get(`/users/${userId}/links.json`);\n return linksResponseSchema.parse(response);\n}\n\nexport async function createUserLink(\n client: FetchClient,\n userId: number,\n data: { url: string; text: string },\n) {\n const response = await client.post(`/users/${userId}/links.json`, data);\n const result = linkSchema.safeParse(response);\n return result.success ? result.data : response;\n}\n\nexport async function updateUserLink(\n client: FetchClient,\n userId: number,\n linkId: number,\n data: { url: string; text: string },\n) {\n const response = await client.put(\n `/users/${userId}/links/${linkId}.json`,\n data,\n );\n const result = linkSchema.safeParse(response);\n return result.success ? result.data : response;\n}\n\nexport async function deleteUserLink(\n client: FetchClient,\n userId: number,\n linkId: number,\n) {\n return client.delete(`/users/${userId}/links/${linkId}.json`);\n}\n\nexport async function reorderUserLinks(\n client: FetchClient,\n userId: number,\n links: Array<{ id: number; order: number }>,\n) {\n const response = await client.patch(\n `/users/${userId}/links/bulk_reorder.json`,\n { links },\n );\n const reorderResult = linksResponseSchema.safeParse(response);\n return reorderResult.success ? reorderResult.data : response;\n}\n\nexport async function getUserFavorites(\n client: FetchClient,\n affiliateId: number,\n) {\n const response = await client.get(\n `/user_companies/${affiliateId}/favorites.json`,\n );\n return favoritesResponseSchema.parse(response);\n}\n\nexport async function deleteFavorite(\n client: FetchClient,\n affiliateId: number,\n favoriteId: number,\n) {\n return client.delete(\n `/user_companies/${affiliateId}/favorites/${favoriteId}.json`,\n );\n}\n\nexport async function reorderFavorites(\n client: FetchClient,\n affiliateId: number,\n favorites: Array<{ id: number; order: number }>,\n countryId?: number,\n languageIso?: string,\n) {\n const response = await client.patch(\n `/user_companies/${affiliateId}/favorites/bulk_reorder.json`,\n {\n favorites,\n country_id: countryId,\n language_iso: languageIso,\n },\n );\n const reorderFavResult = favoritesResponseSchema.safeParse(response);\n return reorderFavResult.success ? reorderFavResult.data : response;\n}\n\nexport async function updateMySite(\n client: FetchClient,\n data: {\n theme_id?: number;\n username?: string;\n },\n) {\n const response = await client.put(\"/mysite.json\", { user_company: data });\n const mysiteResult = mysiteUpdateResponseSchema.safeParse(response);\n return mysiteResult.success ? mysiteResult.data : response;\n}\n\nexport async function updateProfile(\n client: FetchClient,\n data: {\n bio?: string;\n facebook?: string;\n twitter?: string;\n instagram?: string;\n youtube?: string;\n pinterest?: string;\n tiktok?: string;\n linkedin?: string;\n whatsapp?: string;\n wechat?: string;\n image_url?: string;\n },\n) {\n const response = await client.put(\"/me.json\", data);\n const profileResult = profileUpdateResponseSchema.safeParse(response);\n return profileResult.success ? profileResult.data : response;\n}\n\nexport async function addFavorite(\n client: FetchClient,\n affiliateId: number,\n data: {\n favoriteable_id: number;\n favoriteable_type: string;\n },\n countryId?: number,\n) {\n const response = await client.post(\n `/user_companies/${affiliateId}/favorites.json`,\n {\n favorite: data,\n country_id: countryId,\n },\n );\n const favResult = favoriteSchema.safeParse(response);\n return favResult.success ? favResult.data : response;\n}\n","import { z } from \"zod\";\n\nexport interface MysiteTheme {\n id: number;\n name: string;\n description: string | null;\n public: boolean;\n company_id: number | null;\n created_at: string;\n updated_at: string;\n image_url: string | null;\n application_theme_template_id: number | null;\n}\n\nexport const themeSchema: z.ZodType<MysiteTheme> = z.object({\n id: z.number(),\n name: z.string(),\n description: z.string().nullable(),\n public: z.boolean(),\n company_id: z.number().nullable(),\n created_at: z.string().datetime(),\n updated_at: z.string().datetime(),\n image_url: z.string().nullable(),\n application_theme_template_id: z.number().nullable(),\n});\n\nexport const mysiteThemesSchema: z.ZodType<MysiteTheme[]> =\n z.array(themeSchema);\n\n// --- Legacy Theme (for creating themes via /legacy_themes endpoint) ---\n\ninterface LegacyThemeTemplate {\n id: number;\n name: string;\n content: string | null;\n stylesheet: string | null;\n head: string | null;\n status: string;\n}\n\nconst legacyThemeTemplateSchema: z.ZodType<LegacyThemeTemplate> = z.object({\n id: z.number(),\n name: z.string(),\n content: z.string().nullable(),\n stylesheet: z.string().nullable(),\n head: z.string().nullable(),\n status: z.string(),\n});\n\nexport interface LegacyThemeResponse {\n data: {\n legacy_theme: {\n id: number;\n name: string;\n description: string | null;\n image_url: string | null;\n public: boolean;\n company_id: number | null;\n template: LegacyThemeTemplate;\n };\n };\n}\n\nconst legacyThemeResponseSchema: z.ZodType<LegacyThemeResponse> = z.object({\n data: z.object({\n legacy_theme: z.object({\n id: z.number(),\n name: z.string(),\n description: z.string().nullable(),\n image_url: z.string().nullable(),\n public: z.boolean(),\n company_id: z.number().nullable(),\n template: legacyThemeTemplateSchema,\n }),\n }),\n});\n\nexport { legacyThemeResponseSchema };\n\nexport interface CreateLegacyThemeInput {\n name: string;\n description?: string;\n image_url?: string;\n public?: boolean;\n template?: {\n content?: string;\n stylesheet?: string;\n head?: string;\n };\n}\n","import type { FetchClient } from \"./types\";\nimport {\n mysiteThemesSchema,\n legacyThemeResponseSchema,\n type MysiteTheme,\n type CreateLegacyThemeInput,\n} from \"../../shared/schemas/mysite-theme.schema\";\n\nexport async function getMysiteThemes(\n client: FetchClient,\n): Promise<MysiteTheme[]> {\n const response = await client.get(\"/mysite/themes\");\n return mysiteThemesSchema.parse(response);\n}\n\nexport async function createLegacyTheme(\n client: FetchClient,\n input: CreateLegacyThemeInput,\n) {\n const response = await client.post(\"/legacy_themes\", {\n legacy_theme: input,\n });\n const result = legacyThemeResponseSchema.safeParse(response);\n return result.success ? result.data : response;\n}\n","\"use client\";\nimport { useQuery, useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { MYSITE_KEYS } from \"../../shared/query-keys\";\nimport {\n getUserLinks,\n createUserLink,\n updateUserLink,\n deleteUserLink,\n reorderUserLinks,\n getUserFavorites,\n addFavorite,\n deleteFavorite,\n reorderFavorites,\n updateMySite as updateMySiteApi,\n updateProfile as updateProfileApi,\n} from \"../networking/mysite.api\";\nimport {\n getMysiteThemes,\n createLegacyTheme,\n} from \"../networking/mysite-theme.api\";\nimport type { CreateLegacyThemeInput } from \"../../shared/schemas/mysite-theme.schema\";\nimport type {\n MySiteLink,\n MySiteFavorite,\n} from \"../../shared/schemas/mysite.schema\";\nimport type { FetchClient } from \"../networking/types\";\n\n// === LINKS HOOKS ===\n\nexport function useUserLinks(\n client: FetchClient,\n userId: number | null | undefined,\n) {\n return useQuery({\n queryKey: MYSITE_KEYS.links(userId ?? 0),\n queryFn: () => getUserLinks(client, userId!),\n enabled: !!userId,\n });\n}\n\nexport function useCreateLink(\n client: FetchClient,\n userId: number | null | undefined,\n) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: (data: { url: string; text: string }) => {\n if (!userId) return Promise.reject(new Error(\"User not loaded\"));\n return createUserLink(client, userId, data);\n },\n onSuccess: () => {\n if (userId)\n queryClient.invalidateQueries({ queryKey: MYSITE_KEYS.links(userId) });\n },\n });\n}\n\nexport function useUpdateLink(\n client: FetchClient,\n userId: number | null | undefined,\n) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: ({\n linkId,\n data,\n }: {\n linkId: number;\n data: { url: string; text: string };\n }) => {\n if (!userId) return Promise.reject(new Error(\"User not loaded\"));\n return updateUserLink(client, userId, linkId, data);\n },\n onSuccess: () => {\n if (userId)\n queryClient.invalidateQueries({ queryKey: MYSITE_KEYS.links(userId) });\n },\n });\n}\n\nexport function useDeleteLink(\n client: FetchClient,\n userId: number | null | undefined,\n) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: (linkId: number) => {\n if (!userId) return Promise.reject(new Error(\"User not loaded\"));\n return deleteUserLink(client, userId, linkId);\n },\n onSuccess: () => {\n if (userId)\n queryClient.invalidateQueries({ queryKey: MYSITE_KEYS.links(userId) });\n },\n });\n}\n\nexport function useReorderLinks(\n client: FetchClient,\n userId: number | null | undefined,\n) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: ({\n payload,\n }: {\n payload: Array<{ id: number; order: number }>;\n optimisticItems: MySiteLink[];\n }) => {\n if (!userId) return Promise.reject(new Error(\"User not loaded\"));\n return reorderUserLinks(client, userId, payload);\n },\n onMutate: async ({ optimisticItems }) => {\n if (!userId) return;\n await queryClient.cancelQueries({\n queryKey: MYSITE_KEYS.links(userId),\n });\n const previousData = queryClient.getQueryData<MySiteLink[]>(\n MYSITE_KEYS.links(userId),\n );\n queryClient.setQueryData(MYSITE_KEYS.links(userId), optimisticItems);\n return { previousData };\n },\n onError: (_err, _vars, context) => {\n if (userId && context?.previousData) {\n queryClient.setQueryData(\n MYSITE_KEYS.links(userId),\n context.previousData,\n );\n }\n },\n onSettled: () => {\n if (userId)\n queryClient.invalidateQueries({ queryKey: MYSITE_KEYS.links(userId) });\n },\n });\n}\n\n// === FAVORITES HOOKS ===\n\nexport function useUserFavorites(\n client: FetchClient,\n affiliateId: number | null | undefined,\n) {\n return useQuery({\n queryKey: MYSITE_KEYS.favorites(affiliateId ?? 0),\n queryFn: () => getUserFavorites(client, affiliateId!),\n enabled: !!affiliateId,\n });\n}\n\nexport function useAddFavorite(\n client: FetchClient,\n affiliateId: number | null | undefined,\n) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: (data: {\n favoriteable_id: number;\n favoriteable_type: string;\n country_id?: number;\n }) => {\n if (!affiliateId) return Promise.reject(new Error(\"User not loaded\"));\n return addFavorite(\n client,\n affiliateId,\n {\n favoriteable_id: data.favoriteable_id,\n favoriteable_type: data.favoriteable_type,\n },\n data.country_id,\n );\n },\n onSuccess: () => {\n if (affiliateId)\n queryClient.invalidateQueries({\n queryKey: MYSITE_KEYS.favorites(affiliateId),\n });\n },\n });\n}\n\nexport function useDeleteFavorite(\n client: FetchClient,\n affiliateId: number | null | undefined,\n) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: (favoriteId: number) => {\n if (!affiliateId) return Promise.reject(new Error(\"User not loaded\"));\n return deleteFavorite(client, affiliateId, favoriteId);\n },\n onSuccess: () => {\n if (affiliateId)\n queryClient.invalidateQueries({\n queryKey: MYSITE_KEYS.favorites(affiliateId),\n });\n },\n });\n}\n\nexport function useReorderFavorites(\n client: FetchClient,\n affiliateId: number | null | undefined,\n) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: ({\n payload,\n }: {\n payload: Array<{ id: number; order: number }>;\n optimisticItems: MySiteFavorite[];\n }) => {\n if (!affiliateId) return Promise.reject(new Error(\"User not loaded\"));\n return reorderFavorites(client, affiliateId, payload);\n },\n onMutate: async ({ optimisticItems }) => {\n if (!affiliateId) return;\n await queryClient.cancelQueries({\n queryKey: MYSITE_KEYS.favorites(affiliateId),\n });\n const previousData = queryClient.getQueryData<MySiteFavorite[]>(\n MYSITE_KEYS.favorites(affiliateId),\n );\n queryClient.setQueryData(\n MYSITE_KEYS.favorites(affiliateId),\n optimisticItems,\n );\n return { previousData };\n },\n onError: (_err, _vars, context) => {\n if (affiliateId && context?.previousData) {\n queryClient.setQueryData(\n MYSITE_KEYS.favorites(affiliateId),\n context.previousData,\n );\n }\n },\n onSettled: () => {\n if (affiliateId)\n queryClient.invalidateQueries({\n queryKey: MYSITE_KEYS.favorites(affiliateId),\n });\n },\n });\n}\n\n// === THEMES HOOK ===\n\nexport function useMySiteThemes(client: FetchClient) {\n return useQuery({\n queryKey: MYSITE_KEYS.themes(),\n queryFn: () => getMysiteThemes(client),\n });\n}\n\n// === CREATE LEGACY THEME HOOK ===\n\nexport function useCreateLegacyTheme(client: FetchClient) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: (data: CreateLegacyThemeInput) =>\n createLegacyTheme(client, data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: MYSITE_KEYS.themes() });\n },\n });\n}\n\n// === MYSITE SETTINGS HOOK ===\n\nexport function useUpdateMySite(\n client: FetchClient,\n options?: { onProfileRefetch?: () => void },\n) {\n return useMutation({\n mutationFn: (data: Parameters<typeof updateMySiteApi>[1]) =>\n updateMySiteApi(client, data),\n onSuccess: () => options?.onProfileRefetch?.(),\n });\n}\n\n// === PROFILE HOOK ===\n\nexport function useUpdateProfile(\n client: FetchClient,\n options?: { onProfileRefetch?: () => void },\n) {\n return useMutation({\n mutationFn: (data: Parameters<typeof updateProfileApi>[1]) =>\n updateProfileApi(client, data),\n onSuccess: () => options?.onProfileRefetch?.(),\n });\n}\n","import { FADE_MS, SLIDE_MS, type AnimPhase } from \"./types\";\n\nexport function getContentStyle(phase: AnimPhase): React.CSSProperties {\n switch (phase) {\n case \"idle\":\n return { transform: \"translateX(0)\", opacity: 1, transition: \"none\" };\n case \"fade-out\":\n return {\n transform: \"translateX(0)\",\n opacity: 0,\n transition: `opacity ${FADE_MS}ms ease-in-out`,\n };\n case \"slide\":\n return {\n transform: \"translateX(50%)\",\n opacity: 0,\n transition: `transform ${SLIDE_MS}ms ease-in-out`,\n };\n case \"fade-in\":\n return {\n transform: \"translateX(50%)\",\n opacity: 1,\n transition: `opacity ${FADE_MS}ms ease-in-out`,\n };\n case \"editing\":\n return { transform: \"translateX(50%)\", opacity: 1, transition: \"none\" };\n case \"exit-fade-out\":\n return {\n transform: \"translateX(50%)\",\n opacity: 0,\n transition: `opacity ${FADE_MS}ms ease-in-out`,\n };\n case \"exit-slide\":\n return {\n transform: \"translateX(0)\",\n opacity: 0,\n transition: `transform ${SLIDE_MS}ms ease-in-out`,\n };\n case \"exit-fade-in\":\n return {\n transform: \"translateX(0)\",\n opacity: 1,\n transition: `opacity ${FADE_MS}ms ease-in-out`,\n };\n }\n}\n\nexport function getPreviewStyle(phase: AnimPhase): React.CSSProperties {\n switch (phase) {\n case \"idle\":\n case \"fade-out\":\n case \"exit-fade-in\":\n return { transform: \"translateX(0)\", transition: \"none\" };\n case \"slide\":\n return {\n transform: \"translateX(-200%)\",\n transition: `transform ${SLIDE_MS}ms ease-in-out`,\n };\n case \"fade-in\":\n case \"editing\":\n case \"exit-fade-out\":\n return { transform: \"translateX(-200%)\", transition: \"none\" };\n case \"exit-slide\":\n return {\n transform: \"translateX(0)\",\n transition: `transform ${SLIDE_MS}ms ease-in-out`,\n };\n }\n}\n","import { Eye, Users } from \"lucide-react\";\nimport {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Separator,\n} from \"@fluid-app/ui-primitives\";\n\nexport function MySiteVisitorDetailsCard({\n views,\n leads,\n}: {\n views: number;\n leads: number;\n}): React.JSX.Element {\n return (\n <Card className=\"h-auto gap-0 py-0 shadow-none\">\n <CardHeader className=\"p-4 pb-3\">\n <CardTitle className=\"text-sm\">Visitor Details</CardTitle>\n </CardHeader>\n <CardContent className=\"flex px-4 pb-4\">\n <div className=\"flex-1\">\n <div className=\"mb-2 flex items-center gap-1.5\">\n <Eye className=\"text-muted-foreground h-3.5 w-3.5\" />\n <span className=\"text-muted-foreground text-sm\">Views</span>\n </div>\n <p className=\"text-foreground text-2xl font-bold\">\n {views.toLocaleString()}\n </p>\n </div>\n <Separator orientation=\"vertical\" className=\"bg-border mx-4 h-auto\" />\n <div className=\"flex-1\">\n <div className=\"mb-2 flex items-center gap-1.5\">\n <Users className=\"text-muted-foreground h-3.5 w-3.5\" />\n <span className=\"text-muted-foreground text-sm\">Leads</span>\n </div>\n <p className=\"text-foreground text-2xl font-bold\">\n {leads.toLocaleString()}\n </p>\n </div>\n </CardContent>\n </Card>\n );\n}\n","import { useCallback, useState } from \"react\";\nimport { Copy } from \"lucide-react\";\nimport {\n Button,\n Card,\n CardAction,\n CardContent,\n CardHeader,\n CardTitle,\n} from \"@fluid-app/ui-primitives\";\n\nexport function MySiteLinkCard({\n mysiteUrl,\n displayUrl,\n onUpdateSlug,\n onToast,\n}: {\n mysiteUrl: string;\n displayUrl: string;\n onUpdateSlug?: (slug: string) => Promise<void>;\n onToast?: (message: string, type: \"success\" | \"error\") => void;\n}): React.JSX.Element {\n const lastSlashIndex = displayUrl.lastIndexOf(\"/\");\n const urlPrefix =\n lastSlashIndex >= 0 ? displayUrl.slice(0, lastSlashIndex + 1) : \"\";\n const currentSlug =\n lastSlashIndex >= 0 ? displayUrl.slice(lastSlashIndex + 1) : displayUrl;\n\n const [isEditingLink, setIsEditingLink] = useState(false);\n const [linkSlugInput, setLinkSlugInput] = useState(currentSlug);\n const [isSaving, setIsSaving] = useState(false);\n\n const handleEditLink = useCallback(() => {\n setLinkSlugInput(currentSlug);\n setIsEditingLink(true);\n }, [currentSlug]);\n\n const handleCancelEditLink = useCallback(() => {\n setIsEditingLink(false);\n setLinkSlugInput(currentSlug);\n }, [currentSlug]);\n\n const handleSaveLink = useCallback(async () => {\n const trimmed = linkSlugInput.trim();\n if (!trimmed) {\n onToast?.(\"Slug cannot be empty\", \"error\");\n return;\n }\n if (trimmed === currentSlug) {\n setIsEditingLink(false);\n return;\n }\n if (!onUpdateSlug) return;\n setIsSaving(true);\n try {\n await onUpdateSlug(trimmed);\n onToast?.(\"MySite link updated\", \"success\");\n setIsEditingLink(false);\n } catch {\n onToast?.(\"Failed to update link\", \"error\");\n } finally {\n setIsSaving(false);\n }\n }, [linkSlugInput, currentSlug, onUpdateSlug, onToast]);\n\n const handleCopyLink = useCallback(async () => {\n if (!mysiteUrl) return;\n try {\n await navigator.clipboard.writeText(mysiteUrl);\n onToast?.(\"Link copied to clipboard\", \"success\");\n } catch {\n onToast?.(\"Failed to copy link\", \"error\");\n }\n }, [mysiteUrl, onToast]);\n\n return (\n <Card className=\"h-auto gap-0 py-0 shadow-none\">\n <CardHeader className=\"items-center p-4\">\n <CardTitle className=\"text-sm\">Your MySite Link</CardTitle>\n {!isEditingLink && onUpdateSlug && (\n <CardAction>\n <Button variant=\"link\" size=\"sm\" onClick={handleEditLink}>\n Edit Link\n </Button>\n </CardAction>\n )}\n </CardHeader>\n <CardContent className=\"px-4 pb-4\">\n <div\n className=\"flex items-center gap-2 rounded-lg border px-3 py-2.5\"\n style={{\n background:\n \"linear-gradient(90deg, #d4edda 0%, #fce4ec 50%, #fff3e0 100%)\",\n }}\n >\n {isEditingLink ? (\n <>\n <span className=\"text-foreground shrink-0 text-sm\">\n {urlPrefix}\n </span>\n <input\n type=\"text\"\n value={linkSlugInput}\n onChange={(e) => setLinkSlugInput(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && !isSaving) handleSaveLink();\n if (e.key === \"Escape\") handleCancelEditLink();\n }}\n className=\"text-foreground border-input focus:ring-primary min-w-0 flex-1 rounded-md border bg-white/60 px-2 py-1 text-sm font-medium outline-none focus:ring-1\"\n autoFocus\n />\n </>\n ) : (\n <span\n className=\"min-w-0 flex-1 truncate text-sm\"\n style={{ color: \"black\" }}\n >\n {displayUrl || \"Not configured\"}\n </span>\n )}\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={handleCopyLink}\n disabled={!mysiteUrl}\n >\n <Copy className=\"h-4 w-4\" />\n </Button>\n </div>\n\n <div\n className=\"grid transition-all duration-300 ease-in-out\"\n style={{\n gridTemplateRows: isEditingLink ? \"1fr\" : \"0fr\",\n opacity: isEditingLink ? 1 : 0,\n marginTop: isEditingLink ? 12 : 0,\n }}\n >\n <div className=\"overflow-hidden\">\n <div className=\"flex justify-end gap-2\">\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={handleCancelEditLink}\n >\n Cancel\n </Button>\n <Button size=\"sm\" onClick={handleSaveLink} disabled={isSaving}>\n {isSaving ? \"Saving...\" : \"Save\"}\n </Button>\n </div>\n </div>\n </div>\n </CardContent>\n </Card>\n );\n}\n","import { LoaderCircle } from \"lucide-react\";\nimport {\n Button,\n Card,\n CardContent,\n CardHeader,\n} from \"@fluid-app/ui-primitives\";\n\nexport function MySitePhonePreview({\n mysiteUrl,\n themeName,\n previewKey,\n isUpdating,\n onPreview,\n}: {\n mysiteUrl: string;\n themeName: string;\n previewKey: number;\n isUpdating: boolean;\n onPreview: () => void;\n}): React.JSX.Element {\n return (\n <Card className=\"items-center gap-4 py-5\">\n <CardHeader className=\"w-full items-center px-5\">\n <div>\n <p className=\"text-muted-foreground text-xs\">Current Theme</p>\n <p className=\"text-foreground text-sm font-semibold\">{themeName}</p>\n </div>\n <Button\n className=\"col-start-2 row-span-2 row-start-1 self-center justify-self-end\"\n variant=\"secondary\"\n size=\"sm\"\n onClick={onPreview}\n disabled={!mysiteUrl}\n >\n Preview\n </Button>\n </CardHeader>\n\n <CardContent className=\"relative mx-auto my-auto w-[320px] px-0\">\n <div className=\"overflow-hidden rounded-[40px] border-[8px] border-[#1e2939] bg-[#1e2939] shadow-xl\">\n <div className=\"flex items-center justify-between bg-[#101828] px-6 py-1.5\">\n <span className=\"text-[11px] font-medium text-[#ffffff]\">9:41</span>\n <div className=\"flex items-center gap-1\">\n <div className=\"h-2.5 w-2.5 rounded-full bg-[#ffffff60]\" />\n <div className=\"h-2.5 w-4 rounded-sm bg-[#ffffff60]\" />\n </div>\n </div>\n\n <div\n className=\"relative h-[600px] overflow-y-auto bg-[#ffffff]\"\n style={{ scrollbarWidth: \"none\" }}\n aria-busy={isUpdating}\n >\n {mysiteUrl ? (\n <>\n <iframe\n key={previewKey}\n className=\"h-full w-full origin-top-left bg-[#ffffff]\"\n src={`${mysiteUrl}?preview=true`}\n title=\"MySite Preview\"\n />\n {isUpdating && (\n <div className=\"absolute inset-0 flex items-center justify-center bg-white/60\">\n <LoaderCircle className=\"text-muted-foreground h-6 w-6 animate-spin\" />\n </div>\n )}\n </>\n ) : (\n <div className=\"flex h-full items-center justify-center\">\n <p className=\"text-muted-foreground text-sm\">\n No site configured\n </p>\n </div>\n )}\n </div>\n </div>\n\n <div className=\"absolute bottom-2 left-1/2 h-1 w-28 -translate-x-1/2 rounded-full bg-white\" />\n </CardContent>\n </Card>\n );\n}\n","import { ArrowLeft, Check, Palette } from \"lucide-react\";\nimport { Button, Card, CardContent, cn } from \"@fluid-app/ui-primitives\";\nimport type { MysiteTheme } from \"../../shared/schemas/mysite-theme.schema\";\n\nexport function MySiteThemeEditor({\n themes,\n selectedThemeId,\n onSelectTheme,\n isPending,\n onBack,\n}: {\n themes: MysiteTheme[];\n selectedThemeId: number | null;\n onSelectTheme: (theme: MysiteTheme) => void;\n isPending: boolean;\n onBack: () => void;\n}): React.JSX.Element {\n return (\n <>\n <div className=\"flex items-center gap-3\">\n <Button variant=\"ghost\" size=\"icon\" onClick={onBack}>\n <ArrowLeft className=\"h-4 w-4\" />\n </Button>\n <h1 className=\"text-foreground text-xl font-bold\">Choose a Theme</h1>\n </div>\n\n {themes.length === 0 ? (\n <Card>\n <CardContent className=\"py-8 text-center\">\n <p className=\"text-muted-foreground\">No themes available</p>\n </CardContent>\n </Card>\n ) : (\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-3\">\n {themes.map((theme) => {\n const isSelected = theme.id === selectedThemeId;\n return (\n <button\n key={theme.id}\n type=\"button\"\n onClick={() => onSelectTheme(theme)}\n className={cn(\n \"group focus:ring-primary relative overflow-hidden rounded-lg border-2 transition-all focus:ring-2 focus:ring-offset-2 focus:outline-none\",\n isSelected\n ? \"border-primary ring-primary ring-2\"\n : \"border-border hover:border-muted-foreground/50\",\n )}\n aria-pressed={isSelected}\n disabled={isPending}\n >\n <div className=\"bg-muted relative aspect-[4/3] w-full\">\n {theme.image_url ? (\n <img\n src={theme.image_url}\n alt={theme.name}\n loading=\"lazy\"\n className=\"absolute inset-0 h-full w-full object-cover\"\n />\n ) : (\n <div className=\"text-muted-foreground/50 flex h-full w-full items-center justify-center\">\n <Palette className=\"h-8 w-8\" />\n </div>\n )}\n {isSelected && (\n <div className=\"bg-primary/20 absolute inset-0 flex items-center justify-center\">\n <div className=\"bg-primary text-primary-foreground flex h-8 w-8 items-center justify-center rounded-full\">\n <Check className=\"h-5 w-5\" />\n </div>\n </div>\n )}\n {!isSelected && (\n <div className=\"absolute inset-0 bg-black/0 transition-colors group-hover:bg-black/10 dark:group-hover:bg-white/10\" />\n )}\n </div>\n <div className=\"bg-card p-2\">\n <p\n className={cn(\n \"truncate text-sm font-medium\",\n isSelected ? \"text-primary\" : \"text-foreground\",\n )}\n >\n {theme.name}\n </p>\n </div>\n </button>\n );\n })}\n </div>\n )}\n </>\n );\n}\n","export const sortByOrder = <T extends { order: number }>(items: T[]): T[] => {\n return [...items].sort((a, b) => a.order - b.order);\n};\n\nexport const updateOrders = <T extends { id: number | string; order: number }>(\n items: T[],\n): T[] => {\n return items.map((item, index) => ({\n ...item,\n order: index + 1,\n }));\n};\n\nexport const generateTempId = (): string => {\n return `temp_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;\n};\n\nexport function normalizeUrl(value: string): string {\n const trimmed = value.trim();\n if (!trimmed) return \"\";\n if (/^https?:\\/\\//i.test(trimmed)) return trimmed;\n return `https://${trimmed}`;\n}\n","\"use client\";\nimport { useCallback, useState } from \"react\";\nimport { ArrowLeft, Plus, GripVertical, Pencil, Trash2 } from \"lucide-react\";\nimport {\n Button,\n Badge,\n Card,\n Dialog,\n Skeleton,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogFooter,\n Input,\n Label,\n useZodForm,\n} from \"@fluid-app/ui-primitives\";\nimport {\n DndContext,\n closestCenter,\n KeyboardSensor,\n PointerSensor,\n useSensor,\n useSensors,\n type DragEndEvent,\n} from \"@dnd-kit/core\";\nimport {\n arrayMove,\n SortableContext,\n sortableKeyboardCoordinates,\n useSortable,\n verticalListSortingStrategy,\n} from \"@dnd-kit/sortable\";\nimport { CSS } from \"@dnd-kit/utilities\";\nimport { z } from \"zod\";\nimport {\n useUserLinks,\n useCreateLink,\n useUpdateLink,\n useDeleteLink,\n useReorderLinks,\n} from \"../../admin/hooks/use-mysite\";\nimport type { FetchClient } from \"@fluid-app/api-client-core\";\nimport type { MySiteLink } from \"../../shared/schemas/mysite.schema\";\nimport { normalizeUrl } from \"../../shared/utils\";\n\nconst buttonSchema = z.object({\n text: z.string().min(1, \"Button text is required\"),\n url: z\n .string()\n .transform(normalizeUrl)\n .pipe(z.string().url(\"Must be a valid URL\")),\n});\n\ntype ButtonFormData = z.infer<typeof buttonSchema>;\n\nfunction SortableButtonCard({\n link,\n onEdit,\n onDelete,\n}: {\n link: MySiteLink;\n onEdit: (link: MySiteLink) => void;\n onDelete: (link: MySiteLink) => void;\n}) {\n const {\n attributes,\n listeners,\n setNodeRef,\n transform,\n transition,\n isDragging,\n } = useSortable({ id: link.id });\n\n const style = {\n transform: CSS.Transform.toString(transform),\n transition,\n };\n\n const truncatedUrl =\n link.url.length > 40 ? `${link.url.substring(0, 40)}...` : link.url;\n\n return (\n <div\n ref={setNodeRef}\n style={style}\n className={`border-border bg-card flex items-center gap-3 rounded-lg border p-3 sm:p-4 ${\n isDragging ? \"opacity-50 shadow-lg\" : \"\"\n }`}\n >\n <button\n type=\"button\"\n className=\"text-muted-foreground hover:text-foreground cursor-grab touch-none\"\n aria-label=\"Drag to reorder\"\n {...attributes}\n {...listeners}\n >\n <GripVertical className=\"h-5 w-5\" />\n </button>\n\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-foreground truncate font-medium\">{link.text}</p>\n <p className=\"text-muted-foreground truncate text-sm\">{truncatedUrl}</p>\n </div>\n\n <Badge variant=\"secondary\" className=\"hidden shrink-0 sm:inline-flex\">\n {link.clicks ?? 0} clicks\n </Badge>\n\n <div className=\"flex shrink-0 items-center gap-1\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"text-muted-foreground hover:text-foreground\"\n onClick={() => onEdit(link)}\n aria-label=\"Edit button\"\n >\n <Pencil className=\"h-4 w-4\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"text-muted-foreground hover:text-destructive\"\n onClick={() => onDelete(link)}\n aria-label=\"Delete button\"\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n );\n}\n\nexport function MySiteButtonsEditor({\n onBack,\n onRefreshPreview,\n client,\n userId,\n onToast,\n}: {\n onBack: () => void;\n onRefreshPreview?: () => void;\n client: FetchClient;\n userId: number | null | undefined;\n onToast?: (message: string, type: \"success\" | \"error\") => void;\n}): React.JSX.Element {\n \"use no memo\";\n const { data: links = [], isLoading } = useUserLinks(client, userId);\n const createLinkMutation = useCreateLink(client, userId);\n const updateLinkMutation = useUpdateLink(client, userId);\n const deleteLinkMutation = useDeleteLink(client, userId);\n const reorderLinksMutation = useReorderLinks(client, userId);\n\n const [isAddEditDialogOpen, setIsAddEditDialogOpen] = useState(false);\n const [editingLink, setEditingLink] = useState<MySiteLink | null>(null);\n const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false);\n const [deletingLink, setDeletingLink] = useState<MySiteLink | null>(null);\n\n const {\n register,\n handleSubmit: handleButtonSubmit,\n reset: resetButtonForm,\n formState: { errors: buttonErrors, isSubmitting: isButtonSubmitting },\n } = useZodForm<ButtonFormData>(buttonSchema, {\n defaultValues: { text: \"\", url: \"\" },\n });\n\n const sensors = useSensors(\n useSensor(PointerSensor),\n useSensor(KeyboardSensor, {\n coordinateGetter: sortableKeyboardCoordinates,\n }),\n );\n\n const handleOpenAddDialog = useCallback(() => {\n setEditingLink(null);\n resetButtonForm({ text: \"\", url: \"\" });\n setIsAddEditDialogOpen(true);\n }, [resetButtonForm]);\n\n const handleOpenEditDialog = useCallback(\n (link: MySiteLink) => {\n setEditingLink(link);\n resetButtonForm({ text: link.text, url: link.url });\n setIsAddEditDialogOpen(true);\n },\n [resetButtonForm],\n );\n\n const handleCloseAddEditDialog = useCallback(() => {\n setIsAddEditDialogOpen(false);\n setEditingLink(null);\n resetButtonForm({ text: \"\", url: \"\" });\n }, [resetButtonForm]);\n\n const onButtonSubmit = useCallback(\n (data: ButtonFormData) => {\n if (editingLink) {\n updateLinkMutation.mutate(\n { linkId: editingLink.id, data },\n {\n onSuccess: () => {\n onToast?.(\"Button updated\", \"success\");\n handleCloseAddEditDialog();\n onRefreshPreview?.();\n },\n onError: () => {\n onToast?.(\"Failed to update button\", \"error\");\n },\n },\n );\n } else {\n createLinkMutation.mutate(data, {\n onSuccess: () => {\n onToast?.(\"Button created\", \"success\");\n handleCloseAddEditDialog();\n onRefreshPreview?.();\n },\n onError: () => {\n onToast?.(\"Failed to create button\", \"error\");\n },\n });\n }\n },\n [\n editingLink,\n createLinkMutation,\n updateLinkMutation,\n handleCloseAddEditDialog,\n onRefreshPreview,\n onToast,\n ],\n );\n\n const handleOpenDeleteDialog = useCallback((link: MySiteLink) => {\n setDeletingLink(link);\n setIsDeleteDialogOpen(true);\n }, []);\n\n const handleCloseDeleteDialog = useCallback(() => {\n setIsDeleteDialogOpen(false);\n setDeletingLink(null);\n }, []);\n\n const handleConfirmDelete = useCallback(() => {\n if (deletingLink) {\n deleteLinkMutation.mutate(deletingLink.id, {\n onSuccess: () => {\n onToast?.(\"Button deleted\", \"success\");\n handleCloseDeleteDialog();\n onRefreshPreview?.();\n },\n onError: () => {\n onToast?.(\"Failed to delete button\", \"error\");\n },\n });\n }\n }, [\n deletingLink,\n deleteLinkMutation,\n handleCloseDeleteDialog,\n onRefreshPreview,\n onToast,\n ]);\n\n const handleDragEnd = useCallback(\n (event: DragEndEvent) => {\n const { active, over } = event;\n if (over && active.id !== over.id) {\n const oldIndex = links.findIndex((l) => l.id === active.id);\n const newIndex = links.findIndex((l) => l.id === over.id);\n const reordered = arrayMove(links, oldIndex, newIndex);\n const payload = reordered.map((link, index) => ({\n id: link.id,\n order: index + 1,\n }));\n reorderLinksMutation.mutate(\n { payload, optimisticItems: reordered },\n {\n onSuccess: () => {\n onRefreshPreview?.();\n },\n onError: () => {\n onToast?.(\"Failed to reorder buttons\", \"error\");\n },\n },\n );\n }\n },\n [links, reorderLinksMutation, onRefreshPreview, onToast],\n );\n\n return (\n <>\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n <Button variant=\"ghost\" size=\"icon\" onClick={onBack}>\n <ArrowLeft className=\"h-4 w-4\" />\n </Button>\n <h1 className=\"text-foreground text-xl font-bold\">Buttons</h1>\n </div>\n <Button size=\"sm\" onClick={handleOpenAddDialog}>\n <Plus className=\"mr-1 h-4 w-4\" />\n Add Button\n </Button>\n </div>\n\n {isLoading ? (\n <div className=\"space-y-2\">\n {Array.from({ length: 3 }).map((_, i) => (\n <div\n key={i}\n className=\"border-border bg-card flex items-center gap-3 rounded-lg border p-3 sm:p-4\"\n >\n <Skeleton className=\"h-5 w-5\" />\n <div className=\"min-w-0 flex-1 space-y-2\">\n <Skeleton className=\"h-4 w-32\" />\n <Skeleton className=\"h-3 w-48\" />\n </div>\n <Skeleton className=\"hidden h-5 w-16 sm:block\" />\n <div className=\"flex gap-1\">\n <Skeleton className=\"h-8 w-8\" />\n <Skeleton className=\"h-8 w-8\" />\n </div>\n </div>\n ))}\n </div>\n ) : links.length === 0 ? (\n <Card className=\"p-6 text-center sm:p-8\">\n <p className=\"text-muted-foreground mb-4\">\n No buttons yet. Add custom link buttons to display on your MySite.\n </p>\n <Button size=\"sm\" onClick={handleOpenAddDialog}>\n <Plus className=\"mr-1 h-4 w-4\" />\n Add Button\n </Button>\n </Card>\n ) : (\n <DndContext\n sensors={sensors}\n collisionDetection={closestCenter}\n onDragEnd={handleDragEnd}\n >\n <SortableContext\n items={links.map((l) => l.id)}\n strategy={verticalListSortingStrategy}\n >\n <div className=\"space-y-2\">\n {links.map((link) => (\n <SortableButtonCard\n key={link.id}\n link={link}\n onEdit={handleOpenEditDialog}\n onDelete={handleOpenDeleteDialog}\n />\n ))}\n </div>\n </SortableContext>\n </DndContext>\n )}\n\n {/* Add/Edit Dialog */}\n <Dialog open={isAddEditDialogOpen} onOpenChange={setIsAddEditDialogOpen}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>\n {editingLink ? \"Edit Button\" : \"Add Button\"}\n </DialogTitle>\n </DialogHeader>\n <form\n onSubmit={handleButtonSubmit(onButtonSubmit)}\n className=\"space-y-4\"\n >\n <div className=\"space-y-2\">\n <Label htmlFor=\"text\">Button Text</Label>\n <Input\n id=\"text\"\n placeholder=\"Enter button text...\"\n {...register(\"text\")}\n className={buttonErrors.text ? \"border-destructive\" : \"\"}\n />\n {buttonErrors.text && (\n <p className=\"text-destructive text-sm\">\n {buttonErrors.text.message}\n </p>\n )}\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"url\">URL</Label>\n <Input\n id=\"url\"\n placeholder=\"https://example.com\"\n {...register(\"url\")}\n className={buttonErrors.url ? \"border-destructive\" : \"\"}\n />\n {buttonErrors.url && (\n <p className=\"text-destructive text-sm\">\n {buttonErrors.url.message}\n </p>\n )}\n </div>\n <DialogFooter className=\"flex justify-between\">\n {editingLink ? (\n <Button\n type=\"button\"\n variant=\"destructive\"\n onClick={() => {\n handleCloseAddEditDialog();\n handleOpenDeleteDialog(editingLink);\n }}\n >\n <Trash2 className=\"mr-1 h-4 w-4\" />\n Delete\n </Button>\n ) : (\n <div />\n )}\n <div className=\"flex gap-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={handleCloseAddEditDialog}\n >\n Cancel\n </Button>\n <Button\n type=\"submit\"\n disabled={\n isButtonSubmitting ||\n createLinkMutation.isPending ||\n updateLinkMutation.isPending\n }\n >\n {isButtonSubmitting ||\n createLinkMutation.isPending ||\n updateLinkMutation.isPending\n ? \"Saving...\"\n : \"Save\"}\n </Button>\n </div>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n\n {/* Delete Confirmation Dialog */}\n <Dialog open={isDeleteDialogOpen} onOpenChange={setIsDeleteDialogOpen}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Delete Button</DialogTitle>\n </DialogHeader>\n <p className=\"text-muted-foreground\">\n Are you sure you want to delete the button &quot;\n {deletingLink?.text}&quot;? This action cannot be undone.\n </p>\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={handleCloseDeleteDialog}\n >\n Cancel\n </Button>\n <Button\n type=\"button\"\n variant=\"destructive\"\n onClick={handleConfirmDelete}\n disabled={deleteLinkMutation.isPending}\n >\n {deleteLinkMutation.isPending ? \"Deleting...\" : \"Delete\"}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </>\n );\n}\n","\"use client\";\nimport { useCallback, useState } from \"react\";\nimport { ArrowLeft, GripVertical, Trash2 } from \"lucide-react\";\nimport {\n Button,\n Card,\n Dialog,\n Skeleton,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogFooter,\n} from \"@fluid-app/ui-primitives\";\nimport {\n DndContext,\n closestCenter,\n KeyboardSensor,\n PointerSensor,\n useSensor,\n useSensors,\n type DragEndEvent,\n} from \"@dnd-kit/core\";\nimport {\n arrayMove,\n SortableContext,\n sortableKeyboardCoordinates,\n useSortable,\n verticalListSortingStrategy,\n} from \"@dnd-kit/sortable\";\nimport { CSS } from \"@dnd-kit/utilities\";\nimport {\n useUserFavorites,\n useDeleteFavorite,\n useReorderFavorites,\n} from \"../../admin/hooks/use-mysite\";\nimport type { FetchClient } from \"@fluid-app/api-client-core\";\nimport type { MySiteFavorite } from \"../../shared/schemas/mysite.schema\";\n\nfunction SortableFavoriteCard({\n favorite,\n onDelete,\n}: {\n favorite: MySiteFavorite;\n onDelete: (favorite: MySiteFavorite) => void;\n}) {\n const {\n attributes,\n listeners,\n setNodeRef,\n transform,\n transition,\n isDragging,\n } = useSortable({ id: favorite.id });\n\n const style = {\n transform: CSS.Transform.toString(transform),\n transition,\n };\n\n const title =\n favorite.favoriteable?.title ?? favorite.favoriteable?.name ?? \"Untitled\";\n const imageUrl = favorite.favoriteable?.image_url;\n const type = favorite.favoriteable_type.replace(/([A-Z])/g, \" $1\").trim();\n\n return (\n <div\n ref={setNodeRef}\n style={style}\n className={`border-border bg-card flex items-center gap-3 rounded-lg border p-3 sm:p-4 ${\n isDragging ? \"opacity-50 shadow-lg\" : \"\"\n }`}\n >\n <button\n type=\"button\"\n className=\"text-muted-foreground hover:text-foreground cursor-grab touch-none\"\n aria-label=\"Drag to reorder\"\n {...attributes}\n {...listeners}\n >\n <GripVertical className=\"h-5 w-5\" />\n </button>\n\n <div className=\"bg-muted h-10 w-10 shrink-0 overflow-hidden rounded-md\">\n {imageUrl ? (\n <img\n src={imageUrl}\n alt={title}\n loading=\"lazy\"\n width={40}\n height={40}\n className=\"h-full w-full object-cover\"\n />\n ) : (\n <div className=\"text-muted-foreground flex h-full w-full items-center justify-center text-xs\">\n N/A\n </div>\n )}\n </div>\n\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-foreground truncate font-medium\">{title}</p>\n <p className=\"text-muted-foreground truncate text-sm\">{type}</p>\n </div>\n\n <div className=\"flex shrink-0 items-center gap-1\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"text-muted-foreground hover:text-destructive\"\n onClick={() => onDelete(favorite)}\n aria-label=\"Remove favorite\"\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n );\n}\n\nexport function MySiteFavoritesEditor({\n onBack,\n onRefreshPreview,\n client,\n affiliateId,\n onToast,\n}: {\n onBack: () => void;\n onRefreshPreview?: () => void;\n client: FetchClient;\n affiliateId: number | null | undefined;\n onToast?: (message: string, type: \"success\" | \"error\") => void;\n}): React.JSX.Element {\n const { data: favorites = [], isLoading } = useUserFavorites(\n client,\n affiliateId,\n );\n const deleteFavoriteMutation = useDeleteFavorite(client, affiliateId);\n const reorderFavoritesMutation = useReorderFavorites(client, affiliateId);\n\n const [isDeleteFavoriteDialogOpen, setIsDeleteFavoriteDialogOpen] =\n useState(false);\n const [deletingFavorite, setDeletingFavorite] =\n useState<MySiteFavorite | null>(null);\n\n const sensors = useSensors(\n useSensor(PointerSensor),\n useSensor(KeyboardSensor, {\n coordinateGetter: sortableKeyboardCoordinates,\n }),\n );\n\n const handleOpenDeleteFavoriteDialog = useCallback(\n (favorite: MySiteFavorite) => {\n setDeletingFavorite(favorite);\n setIsDeleteFavoriteDialogOpen(true);\n },\n [],\n );\n\n const handleCloseDeleteFavoriteDialog = useCallback(() => {\n setIsDeleteFavoriteDialogOpen(false);\n setDeletingFavorite(null);\n }, []);\n\n const handleConfirmDeleteFavorite = useCallback(() => {\n if (deletingFavorite) {\n deleteFavoriteMutation.mutate(deletingFavorite.id, {\n onSuccess: () => {\n onToast?.(\"Content removed\", \"success\");\n handleCloseDeleteFavoriteDialog();\n onRefreshPreview?.();\n },\n onError: () => {\n onToast?.(\"Failed to remove content\", \"error\");\n },\n });\n }\n }, [\n deletingFavorite,\n deleteFavoriteMutation,\n handleCloseDeleteFavoriteDialog,\n onRefreshPreview,\n onToast,\n ]);\n\n const handleFavoriteDragEnd = useCallback(\n (event: DragEndEvent) => {\n const { active, over } = event;\n if (over && active.id !== over.id) {\n const oldIndex = favorites.findIndex((f) => f.id === active.id);\n const newIndex = favorites.findIndex((f) => f.id === over.id);\n const reordered = arrayMove(favorites, oldIndex, newIndex);\n const payload = reordered.map((fav, index) => ({\n id: fav.id,\n order: index + 1,\n }));\n reorderFavoritesMutation.mutate(\n { payload, optimisticItems: reordered },\n {\n onSuccess: () => {\n onRefreshPreview?.();\n },\n onError: () => {\n onToast?.(\"Failed to reorder content\", \"error\");\n },\n },\n );\n }\n },\n [favorites, reorderFavoritesMutation, onRefreshPreview, onToast],\n );\n\n return (\n <>\n <div className=\"flex items-center gap-3\">\n <Button variant=\"ghost\" size=\"icon\" onClick={onBack}>\n <ArrowLeft className=\"h-4 w-4\" />\n </Button>\n <h1 className=\"text-foreground text-xl font-bold\">MySite Content</h1>\n </div>\n\n {isLoading ? (\n <div className=\"space-y-2\">\n {Array.from({ length: 3 }).map((_, i) => (\n <div\n key={i}\n className=\"border-border bg-card flex items-center gap-3 rounded-lg border p-3 sm:p-4\"\n >\n <Skeleton className=\"h-5 w-5\" />\n <Skeleton className=\"h-10 w-10 rounded-md\" />\n <div className=\"min-w-0 flex-1 space-y-2\">\n <Skeleton className=\"h-4 w-32\" />\n <Skeleton className=\"h-3 w-20\" />\n </div>\n <Skeleton className=\"h-8 w-8\" />\n </div>\n ))}\n </div>\n ) : favorites.length === 0 ? (\n <Card className=\"p-6 text-center sm:p-8\">\n <p className=\"text-muted-foreground\">\n No featured content yet. Favorite products, media, or pages to\n display on your MySite.\n </p>\n </Card>\n ) : (\n <DndContext\n sensors={sensors}\n collisionDetection={closestCenter}\n onDragEnd={handleFavoriteDragEnd}\n >\n <SortableContext\n items={favorites.map((f) => f.id)}\n strategy={verticalListSortingStrategy}\n >\n <div className=\"space-y-2\">\n {favorites.map((fav) => (\n <SortableFavoriteCard\n key={fav.id}\n favorite={fav}\n onDelete={handleOpenDeleteFavoriteDialog}\n />\n ))}\n </div>\n </SortableContext>\n </DndContext>\n )}\n\n {/* Delete Favorite Confirmation Dialog */}\n <Dialog\n open={isDeleteFavoriteDialogOpen}\n onOpenChange={setIsDeleteFavoriteDialogOpen}\n >\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Remove Content</DialogTitle>\n </DialogHeader>\n <p className=\"text-muted-foreground\">\n Are you sure you want to remove &quot;\n {deletingFavorite?.favoriteable?.title ??\n deletingFavorite?.favoriteable?.name ??\n \"this item\"}\n &quot; from your MySite? This action cannot be undone.\n </p>\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={handleCloseDeleteFavoriteDialog}\n >\n Cancel\n </Button>\n <Button\n type=\"button\"\n variant=\"destructive\"\n onClick={handleConfirmDeleteFavorite}\n disabled={deleteFavoriteMutation.isPending}\n >\n {deleteFavoriteMutation.isPending ? \"Removing...\" : \"Remove\"}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </>\n );\n}\n","\"use client\";\nimport { useState, useCallback, useMemo, useEffect, useRef } from \"react\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport type { FetchClient } from \"@fluid-app/api-client-core\";\nimport { ArrowLeft, Camera } from \"lucide-react\";\nimport { Button, Card, Input, Label, Textarea } from \"@fluid-app/ui-primitives\";\nimport { useUpdateProfile } from \"../../admin/hooks/use-mysite\";\nimport type { MeProfile } from \"./types\";\n\nconst socialFields = [\n {\n name: \"linkedin\" as const,\n label: \"LinkedIn\",\n placeholder: \"https://linkedin.com/in/username\",\n },\n {\n name: \"facebook\" as const,\n label: \"Facebook\",\n placeholder: \"https://facebook.com/username\",\n },\n {\n name: \"twitter\" as const,\n label: \"X (Twitter)\",\n placeholder: \"https://x.com/username\",\n },\n {\n name: \"instagram\" as const,\n label: \"Instagram\",\n placeholder: \"https://instagram.com/username\",\n },\n {\n name: \"youtube\" as const,\n label: \"YouTube\",\n placeholder: \"https://youtube.com/@channel\",\n },\n {\n name: \"pinterest\" as const,\n label: \"Pinterest\",\n placeholder: \"https://pinterest.com/username\",\n },\n {\n name: \"tiktok\" as const,\n label: \"TikTok\",\n placeholder: \"https://tiktok.com/@username\",\n },\n {\n name: \"whatsapp\" as const,\n label: \"WhatsApp\",\n placeholder: \"Phone number or link\",\n },\n { name: \"wechat\" as const, label: \"WeChat\", placeholder: \"WeChat ID\" },\n] as const;\n\ntype SocialFieldName = (typeof socialFields)[number][\"name\"];\n\ntype ProfileFormState = {\n bio: string;\n} & Record<SocialFieldName, string>;\n\nexport function MySiteProfileForm({\n client,\n onBack,\n onToast,\n onUploadPhoto,\n avatarUrl,\n userName,\n userInitial,\n}: {\n client: FetchClient;\n onBack: () => void;\n onToast?: (message: string, type: \"success\" | \"error\") => void;\n onUploadPhoto?: (file: File) => Promise<string>;\n avatarUrl?: string | null;\n userName?: string | null;\n userInitial?: string | null;\n}): React.JSX.Element {\n const queryClient = useQueryClient();\n const { data: meProfile, isLoading: isProfileLoading } = useQuery<MeProfile>({\n queryKey: [\"sdk-mysite\", \"me\"],\n queryFn: () => client.get<MeProfile>(\"/me.json\"),\n });\n\n const updateProfileMutation = useUpdateProfile(client);\n\n const initialFormState = useMemo<ProfileFormState>(\n () => ({\n bio: meProfile?.bio ?? \"\",\n linkedin: meProfile?.linkedin ?? \"\",\n facebook: meProfile?.facebook ?? \"\",\n twitter: meProfile?.twitter ?? \"\",\n instagram: meProfile?.instagram ?? \"\",\n youtube: meProfile?.youtube ?? \"\",\n pinterest: meProfile?.pinterest ?? \"\",\n tiktok: meProfile?.tiktok ?? \"\",\n whatsapp: meProfile?.whatsapp ?? \"\",\n wechat: meProfile?.wechat ?? \"\",\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [meProfile?.id],\n );\n\n const [formState, setFormState] = useState<ProfileFormState>(\n () => initialFormState,\n );\n\n const profileSyncedRef = useRef(false);\n useEffect(() => {\n if (meProfile && !profileSyncedRef.current) {\n profileSyncedRef.current = true;\n setFormState({\n bio: meProfile.bio ?? \"\",\n linkedin: meProfile.linkedin ?? \"\",\n facebook: meProfile.facebook ?? \"\",\n twitter: meProfile.twitter ?? \"\",\n instagram: meProfile.instagram ?? \"\",\n youtube: meProfile.youtube ?? \"\",\n pinterest: meProfile.pinterest ?? \"\",\n tiktok: meProfile.tiktok ?? \"\",\n whatsapp: meProfile.whatsapp ?? \"\",\n wechat: meProfile.wechat ?? \"\",\n });\n }\n }, [meProfile]);\n\n const isDirty =\n formState.bio !== initialFormState.bio ||\n formState.linkedin !== initialFormState.linkedin ||\n formState.facebook !== initialFormState.facebook ||\n formState.twitter !== initialFormState.twitter ||\n formState.instagram !== initialFormState.instagram ||\n formState.youtube !== initialFormState.youtube ||\n formState.pinterest !== initialFormState.pinterest ||\n formState.tiktok !== initialFormState.tiktok ||\n formState.whatsapp !== initialFormState.whatsapp ||\n formState.wechat !== initialFormState.wechat;\n\n const handleFieldChange = useCallback(\n (field: keyof ProfileFormState, value: string) => {\n setFormState((s) => ({ ...s, [field]: value }));\n },\n [],\n );\n\n const handleSave = useCallback(() => {\n updateProfileMutation.mutate(\n {\n bio: formState.bio,\n linkedin: formState.linkedin,\n facebook: formState.facebook,\n twitter: formState.twitter,\n instagram: formState.instagram,\n youtube: formState.youtube,\n pinterest: formState.pinterest,\n tiktok: formState.tiktok,\n whatsapp: formState.whatsapp,\n wechat: formState.wechat,\n },\n {\n onSuccess: () => {\n profileSyncedRef.current = false;\n queryClient.invalidateQueries({ queryKey: [\"sdk-mysite\", \"me\"] });\n onToast?.(\"Profile updated successfully\", \"success\");\n },\n onError: () => {\n onToast?.(\"Failed to update profile\", \"error\");\n },\n },\n );\n }, [formState, updateProfileMutation, queryClient, onToast]);\n\n // Avatar upload handling\n const fileInputRef = useRef<HTMLInputElement>(null);\n const [isUploadingPhoto, setIsUploadingPhoto] = useState(false);\n const [previewUrl, setPreviewUrl] = useState<string | null>(null);\n\n useEffect(() => {\n return () => {\n if (previewUrl) URL.revokeObjectURL(previewUrl);\n };\n }, [previewUrl]);\n\n const handleFileSelected = useCallback(\n async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file || !onUploadPhoto) return;\n\n if (!file.type.startsWith(\"image/\")) {\n onToast?.(\"Please select an image file\", \"error\");\n return;\n }\n\n setPreviewUrl(URL.createObjectURL(file));\n setIsUploadingPhoto(true);\n\n try {\n const imageUrl = await onUploadPhoto(file);\n updateProfileMutation.mutate(\n { image_url: imageUrl },\n {\n onSuccess: () => {\n onToast?.(\"Profile photo updated\", \"success\");\n },\n onError: () => {\n setPreviewUrl(null);\n onToast?.(\"Failed to save profile photo\", \"error\");\n },\n },\n );\n } catch {\n setPreviewUrl(null);\n onToast?.(\"Failed to upload photo\", \"error\");\n } finally {\n setIsUploadingPhoto(false);\n if (fileInputRef.current) fileInputRef.current.value = \"\";\n }\n },\n [onUploadPhoto, updateProfileMutation, onToast],\n );\n\n if (isProfileLoading) {\n return (\n <div className=\"flex h-full items-center justify-center\">\n <div className=\"text-muted-foreground animate-pulse\">Loading...</div>\n </div>\n );\n }\n\n const displayAvatarUrl = previewUrl || avatarUrl;\n\n return (\n <div className=\"space-y-4 p-4 sm:space-y-6 sm:p-6\">\n {/* Header */}\n <div className=\"flex items-center gap-3\">\n <button\n type=\"button\"\n onClick={onBack}\n className=\"text-muted-foreground hover:bg-muted hover:text-foreground flex h-10 w-10 items-center justify-center rounded-full transition-colors\"\n aria-label=\"Go back\"\n >\n <ArrowLeft className=\"h-5 w-5\" />\n </button>\n <h1 className=\"text-foreground text-xl font-bold sm:text-2xl\">\n Profile\n </h1>\n </div>\n\n {/* Avatar Section (optional) */}\n {onUploadPhoto && (\n <Card className=\"p-4 sm:p-6\">\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/*\"\n className=\"hidden\"\n onChange={handleFileSelected}\n />\n <div className=\"flex flex-col items-center gap-3 sm:flex-row sm:gap-4\">\n <div className=\"relative h-[120px] w-[120px] shrink-0 overflow-hidden rounded-full bg-gray-200\">\n {displayAvatarUrl ? (\n <img\n src={displayAvatarUrl}\n alt={userName || \"Profile\"}\n className=\"h-full w-full object-cover\"\n />\n ) : (\n <div className=\"bg-background text-foreground flex h-full w-full items-center justify-center text-xl font-semibold\">\n {userInitial || \"U\"}\n </div>\n )}\n {isUploadingPhoto && (\n <div className=\"absolute inset-0 flex items-center justify-center rounded-full bg-black/40\">\n <div className=\"border-t-primary h-6 w-6 animate-spin rounded-full border-2 border-white\" />\n </div>\n )}\n </div>\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => fileInputRef.current?.click()}\n disabled={isUploadingPhoto}\n >\n <Camera className=\"mr-1 h-4 w-4\" />\n {isUploadingPhoto ? \"Uploading...\" : \"Change Photo\"}\n </Button>\n </div>\n </Card>\n )}\n\n {/* Bio Section */}\n <Card className=\"p-4 sm:p-6\">\n <h2 className=\"text-foreground mb-4 text-base font-semibold sm:text-lg\">\n Bio\n </h2>\n <div className=\"space-y-2\">\n <Label htmlFor=\"profile-bio\">About you</Label>\n <Textarea\n id=\"profile-bio\"\n rows={4}\n value={formState.bio}\n onChange={(e) => handleFieldChange(\"bio\", e.target.value)}\n placeholder=\"Tell people a little about yourself...\"\n />\n </div>\n </Card>\n\n {/* Social Media Links Section */}\n <Card className=\"p-4 sm:p-6\">\n <h2 className=\"text-foreground mb-4 text-base font-semibold sm:text-lg\">\n Social Media Links\n </h2>\n <div className=\"space-y-4\">\n {socialFields.map((field) => (\n <div key={field.name} className=\"space-y-2\">\n <Label htmlFor={`profile-${field.name}`}>{field.label}</Label>\n <Input\n id={`profile-${field.name}`}\n type=\"text\"\n value={formState[field.name]}\n onChange={(e) => handleFieldChange(field.name, e.target.value)}\n placeholder={field.placeholder}\n />\n </div>\n ))}\n </div>\n </Card>\n\n {/* Save Button */}\n <div className=\"flex justify-end\">\n <Button\n onClick={handleSave}\n disabled={!isDirty || updateProfileMutation.isPending}\n className=\"w-full sm:w-auto\"\n >\n {updateProfileMutation.isPending ? \"Saving...\" : \"Save Changes\"}\n </Button>\n </div>\n </div>\n );\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport type { FetchClient } from \"@fluid-app/api-client-core\";\nimport {\n useMySiteThemes,\n useUpdateMySite,\n} from \"@fluid-app/mysite-ui/admin/hooks/use-mysite\";\nimport type { MysiteTheme } from \"@fluid-app/mysite-ui/shared/schemas/mysite-theme.schema\";\nimport {\n type AnimPhase,\n type EditingSection,\n FADE_MS,\n SLIDE_MS,\n getContentStyle,\n getPreviewStyle,\n MySiteVisitorDetailsCard,\n MySitePhonePreview,\n MySiteLinkCard,\n MySiteThemeEditor,\n MySiteButtonsEditor,\n MySiteFavoritesEditor,\n} from \"@fluid-app/mysite-ui/portal/components\";\nimport type { MeProfile } from \"@fluid-app/mysite-ui/portal/components\";\nimport { ChevronRight, User, Link2, Palette, LayoutGrid } from \"lucide-react\";\nimport { useAppNavigation } from \"../../shell/AppNavigationContext\";\n\ntype NavLinkItem = {\n label: string;\n slug: string;\n icon: typeof User;\n};\ntype NavActionItem = {\n label: string;\n key: \"theme\" | \"buttons\" | \"content\";\n icon: typeof User;\n};\ntype NavItem = NavLinkItem | NavActionItem;\n\nconst navigationItems: NavItem[] = [\n { label: \"Profile\", slug: \"my-site/profile\", icon: User },\n { label: \"Theme\", key: \"theme\", icon: Palette },\n { label: \"MySite Content\", key: \"content\", icon: LayoutGrid },\n { label: \"Buttons\", key: \"buttons\", icon: Link2 },\n];\n\nfunction defaultToast(message: string, type: \"success\" | \"error\") {\n if (type === \"error\") console.warn(\"[MySite]\", message);\n else console.info(\"[MySite]\", message);\n}\n\nexport function MySiteMainView({\n client,\n}: {\n client: FetchClient;\n}): React.JSX.Element {\n const { navigate } = useAppNavigation();\n\n const [animPhase, setAnimPhase] = useState<AnimPhase>(\"idle\");\n const [editingSection, setEditingSection] = useState<EditingSection>(null);\n const timeoutsRef = useRef<ReturnType<typeof setTimeout>[]>([]);\n\n useEffect(() => {\n const ref = timeoutsRef;\n return () => ref.current.forEach(clearTimeout);\n }, []);\n\n const cancelScheduled = useCallback(() => {\n timeoutsRef.current.forEach(clearTimeout);\n timeoutsRef.current = [];\n }, []);\n\n const schedule = useCallback((phase: AnimPhase, delay: number) => {\n const id = setTimeout(() => setAnimPhase(phase), delay);\n timeoutsRef.current.push(id);\n }, []);\n\n const showEditContent = [\n \"slide\",\n \"fade-in\",\n \"editing\",\n \"exit-fade-out\",\n \"exit-slide\",\n ].includes(animPhase);\n\n // Data fetching\n const { data: meProfile, isLoading: isUserLoading } = useQuery<MeProfile>({\n queryKey: [\"sdk-mysite\", \"me\"],\n queryFn: () => client.get<MeProfile>(\"/me.json\"),\n });\n\n const { data: themes = [] } = useMySiteThemes(client);\n const updateMySiteMutation = useUpdateMySite(client);\n\n const [previewKey, setPreviewKey] = useState(0);\n const refreshPreview = useCallback(() => setPreviewKey((k) => k + 1), []);\n\n const [selectedThemeId, setSelectedThemeId] = useState<number | null>(null);\n\n const resolvedThemeId =\n selectedThemeId ??\n meProfile?.mysite_theme_id ??\n meProfile?.mysite_theme?.id ??\n themes.find((t) => t.name === \"Default\")?.id ??\n themes[0]?.id ??\n null;\n\n const currentTheme = themes.find((t) => t.id === resolvedThemeId);\n const themeName = currentTheme?.name ?? \"Default\";\n\n const mysiteUrl = meProfile?.mysite_url ?? \"\";\n const displayUrl = mysiteUrl ? mysiteUrl.replace(/^https?:\\/\\//, \"\") : \"\";\n const views = meProfile?.mysite_views ?? 0;\n const leads = meProfile?.mysite_leads ?? 0;\n\n const handleSelectTheme = useCallback(\n (theme: MysiteTheme) => {\n if (theme.id === resolvedThemeId) return;\n const previousThemeId = selectedThemeId;\n setSelectedThemeId(theme.id);\n updateMySiteMutation.mutate(\n { theme_id: theme.id },\n {\n onSuccess: () => {\n defaultToast(`Theme changed to \"${theme.name}\"`, \"success\");\n refreshPreview();\n },\n onError: () => {\n setSelectedThemeId(previousThemeId);\n defaultToast(\"Failed to update theme\", \"error\");\n },\n },\n );\n },\n [resolvedThemeId, selectedThemeId, updateMySiteMutation, refreshPreview],\n );\n\n const handleUpdateSlug = useCallback(\n async (slug: string) => {\n await new Promise<void>((resolve, reject) => {\n updateMySiteMutation.mutate(\n { username: slug },\n {\n onSuccess: () => resolve(),\n onError: () => reject(new Error(\"Failed\")),\n },\n );\n });\n },\n [updateMySiteMutation],\n );\n\n const handleEditSection = useCallback(\n (section: EditingSection) => {\n cancelScheduled();\n setEditingSection(section);\n setAnimPhase(\"fade-out\");\n schedule(\"slide\", FADE_MS);\n schedule(\"fade-in\", FADE_MS + SLIDE_MS);\n schedule(\"editing\", FADE_MS + SLIDE_MS + FADE_MS);\n },\n [cancelScheduled, schedule],\n );\n\n const handleBackClick = useCallback(() => {\n cancelScheduled();\n setAnimPhase(\"exit-fade-out\");\n schedule(\"exit-slide\", FADE_MS);\n schedule(\"exit-fade-in\", FADE_MS + SLIDE_MS);\n const id = setTimeout(\n () => {\n setAnimPhase(\"idle\");\n setEditingSection(null);\n },\n FADE_MS + SLIDE_MS + FADE_MS,\n );\n timeoutsRef.current.push(id);\n }, [cancelScheduled, schedule]);\n\n const handlePreview = useCallback(() => {\n if (mysiteUrl) window.open(`${mysiteUrl}?preview=true`, \"_blank\");\n }, [mysiteUrl]);\n\n const sectionLabel = useMemo(() => {\n if (editingSection === \"theme\") return \"Theme\";\n if (editingSection === \"buttons\") return \"Buttons\";\n if (editingSection === \"content\") return \"MySite Content\";\n return \"\";\n }, [editingSection]);\n\n if (isUserLoading) {\n return (\n <div className=\"flex h-full overflow-hidden px-2 py-6\">\n <div className=\"w-full px-4 2xl:w-2/3 2xl:shrink-0\">\n <div className=\"flex flex-col gap-5\">\n <div className=\"bg-muted h-7 w-32 animate-pulse rounded-md\" />\n <div className=\"bg-muted h-20 w-full animate-pulse rounded-lg\" />\n <div className=\"bg-muted h-16 w-full animate-pulse rounded-lg\" />\n <div className=\"bg-muted h-40 w-full animate-pulse rounded-lg\" />\n </div>\n </div>\n <div className=\"hidden w-1/3 shrink-0 overflow-y-hidden px-4 2xl:block\">\n <div className=\"bg-muted flex h-full flex-col items-center gap-4 rounded-xl p-5\">\n <div className=\"flex w-full items-center justify-between\">\n <div className=\"space-y-1\">\n <div className=\"bg-background/50 h-3 w-24 animate-pulse rounded\" />\n <div className=\"bg-background/50 h-4 w-28 animate-pulse rounded\" />\n </div>\n <div className=\"bg-background/50 h-8 w-20 animate-pulse rounded-md\" />\n </div>\n <div className=\"bg-background/50 h-[580px] w-[280px] animate-pulse rounded-[36px]\" />\n </div>\n </div>\n </div>\n );\n }\n\n const contentStyle = getContentStyle(animPhase);\n const previewStyle = getPreviewStyle(animPhase);\n\n return (\n <div className=\"flex h-full overflow-hidden px-2 py-6\">\n {/* Content column */}\n <div className=\"w-full px-4 2xl:w-2/3 2xl:shrink-0\" style={contentStyle}>\n <div className=\"flex h-full min-w-0 flex-col gap-5 overflow-y-auto\">\n {showEditContent && editingSection === \"theme\" ? (\n <MySiteThemeEditor\n themes={themes}\n selectedThemeId={resolvedThemeId}\n onSelectTheme={handleSelectTheme}\n isPending={updateMySiteMutation.isPending}\n onBack={handleBackClick}\n />\n ) : showEditContent && editingSection === \"buttons\" ? (\n <MySiteButtonsEditor\n onBack={handleBackClick}\n onRefreshPreview={refreshPreview}\n client={client}\n userId={meProfile?.id}\n onToast={defaultToast}\n />\n ) : showEditContent && editingSection === \"content\" ? (\n <MySiteFavoritesEditor\n onBack={handleBackClick}\n onRefreshPreview={refreshPreview}\n client={client}\n affiliateId={meProfile?.affiliate_id}\n onToast={defaultToast}\n />\n ) : (\n <>\n {/* Header with optional back-to-section label */}\n <div className=\"flex items-center gap-2\">\n <h1 className=\"text-foreground text-xl font-bold\">MySite</h1>\n {animPhase !== \"idle\" && sectionLabel && (\n <>\n <ChevronRight className=\"text-muted-foreground h-4 w-4\" />\n <span className=\"text-foreground text-xl font-bold\">\n {sectionLabel}\n </span>\n </>\n )}\n </div>\n\n <MySiteVisitorDetailsCard views={views} leads={leads} />\n\n <MySiteLinkCard\n mysiteUrl={mysiteUrl}\n displayUrl={displayUrl}\n onUpdateSlug={handleUpdateSlug}\n onToast={defaultToast}\n />\n\n <div className=\"border-border bg-card divide-border divide-y overflow-hidden rounded-lg border\">\n {navigationItems.map((item) => {\n const Icon = item.icon;\n const rowClassName =\n \"group hover:bg-muted flex w-full items-center gap-2.5 px-3 py-2.5 transition-colors text-left cursor-pointer\";\n\n return (\n <button\n key={item.label}\n type=\"button\"\n onClick={() => {\n if (\"key\" in item) handleEditSection(item.key);\n else navigate(item.slug);\n }}\n className={rowClassName}\n >\n <div className=\"bg-muted text-foreground flex h-7 w-7 shrink-0 items-center justify-center rounded-full\">\n <Icon className=\"h-3.5 w-3.5\" />\n </div>\n <span className=\"text-foreground flex-1 text-sm font-medium\">\n {item.label}\n </span>\n <ChevronRight className=\"text-muted-foreground h-3 w-3 shrink-0 transition-transform group-hover:translate-x-0.5\" />\n </button>\n );\n })}\n </div>\n </>\n )}\n </div>\n </div>\n\n {/* Preview column */}\n <div\n className=\"hidden w-1/3 shrink-0 overflow-y-hidden px-4 2xl:block\"\n style={previewStyle}\n >\n <MySitePhonePreview\n mysiteUrl={mysiteUrl}\n themeName={themeName}\n previewKey={previewKey}\n isUpdating={updateMySiteMutation.isPending}\n onPreview={handlePreview}\n />\n </div>\n </div>\n );\n}\n","import type { FetchClient } from \"@fluid-app/api-client-core\";\nimport { MySiteProfileForm } from \"@fluid-app/mysite-ui/portal/components\";\nimport { useAppNavigation } from \"../../shell/AppNavigationContext\";\n\nfunction defaultToast(message: string, type: \"success\" | \"error\") {\n if (type === \"error\") console.warn(\"[MySite]\", message);\n else console.info(\"[MySite]\", message);\n}\n\nexport function MySiteProfileView({\n client,\n}: {\n client: FetchClient;\n}): React.JSX.Element {\n const { navigate } = useAppNavigation();\n return (\n <MySiteProfileForm\n client={client}\n onBack={() => navigate(\"my-site\")}\n onToast={defaultToast}\n />\n );\n}\n","import React, { useMemo } from \"react\";\nimport {\n Breadcrumb,\n BreadcrumbList,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from \"@fluid-app/ui-primitives\";\nimport { useScreenHeaderBreadcrumbs } from \"@fluid-app/portal-react/shell/ScreenHeaderContext\";\nimport type { WidgetPropertySchema } from \"../../registries/property-schema-types\";\nimport { useMySiteConfig } from \"../../mysite/use-mysite-config\";\nimport { useAppNavigation } from \"../../shell/AppNavigationContext\";\nimport { MySiteMainView } from \"./MySiteMainView\";\nimport { MySiteProfileView } from \"./MySiteProfileView\";\nimport type { MySiteScreenProps } from \"./types\";\n\nexport type { MySiteScreenProps } from \"./types\";\nexport type { MeProfile } from \"./types\";\n\nexport function MySiteScreen({\n /* eslint-disable @typescript-eslint/no-unused-vars -- destructured to exclude from divProps spread */\n background,\n textColor,\n accentColor,\n padding,\n borderRadius,\n /* eslint-enable @typescript-eslint/no-unused-vars */\n ...divProps\n}: MySiteScreenProps): React.JSX.Element {\n const { client } = useMySiteConfig();\n const { currentSlug, navigate } = useAppNavigation();\n const subRoute = currentSlug.split(\"/\")[1] ?? null;\n const isProfileView = subRoute === \"profile\";\n\n const headerBreadcrumbs = useMemo(\n () => (\n <Breadcrumb>\n <BreadcrumbList className=\"text-lg\">\n <BreadcrumbItem>\n {isProfileView ? (\n <BreadcrumbLink\n href=\"#\"\n onClick={(e: React.MouseEvent) => {\n e.preventDefault();\n navigate(\"my-site\");\n }}\n >\n My Site\n </BreadcrumbLink>\n ) : (\n <BreadcrumbPage className=\"font-semibold\">My Site</BreadcrumbPage>\n )}\n </BreadcrumbItem>\n {isProfileView && (\n <>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbPage className=\"font-semibold\">\n Profile\n </BreadcrumbPage>\n </BreadcrumbItem>\n </>\n )}\n </BreadcrumbList>\n </Breadcrumb>\n ),\n [isProfileView, navigate],\n );\n useScreenHeaderBreadcrumbs(headerBreadcrumbs);\n\n return (\n <div {...divProps} className={`h-full ${divProps.className ?? \"\"}`}>\n {isProfileView ? (\n <MySiteProfileView client={client} />\n ) : (\n <MySiteMainView client={client} />\n )}\n </div>\n );\n}\n\nexport const mySiteScreenPropertySchema: WidgetPropertySchema = {\n widgetType: \"MySiteScreen\",\n displayName: \"My Site Screen\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":"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"}
@@ -35,6 +35,6 @@ require("./ToDoWidget-eGB9cfou.cjs");
35
35
  require("./VideoWidget-C22_tAkf.cjs");
36
36
  require("./ScreenHeaderContext-wrJlkhgN.cjs");
37
37
  require("./dist-lO2OG0T5.cjs");
38
- const require_MySiteScreen = require("./MySiteScreen-Ci2rLGQc.cjs");
38
+ const require_MySiteScreen = require("./MySiteScreen-DY7PSqP6.cjs");
39
39
  exports.MySiteScreen = require_MySiteScreen.MySiteScreen;
40
40
  exports.mySiteScreenPropertySchema = require_MySiteScreen.mySiteScreenPropertySchema;
@@ -552,7 +552,7 @@ function MySiteLinkCard({ mysiteUrl, displayUrl, onUpdateSlug, onToast }) {
552
552
  }
553
553
  //#endregion
554
554
  //#region ../../mysite/ui/src/portal/components/PhonePreview.tsx
555
- function MySitePhonePreview({ mysiteUrl, themeName, selectedThemeId, previewKey, onPreview }) {
555
+ function MySitePhonePreview({ mysiteUrl, themeName, previewKey, isUpdating, onPreview }) {
556
556
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Card, {
557
557
  className: "items-center gap-4 py-5",
558
558
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.CardHeader, {
@@ -587,11 +587,15 @@ function MySitePhonePreview({ mysiteUrl, themeName, selectedThemeId, previewKey,
587
587
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
588
588
  className: "relative h-[600px] overflow-y-auto bg-[#ffffff]",
589
589
  style: { scrollbarWidth: "none" },
590
- children: mysiteUrl ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("iframe", {
590
+ "aria-busy": isUpdating,
591
+ children: mysiteUrl ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("iframe", {
591
592
  className: "h-full w-full origin-top-left bg-[#ffffff]",
592
593
  src: `${mysiteUrl}?preview=true`,
593
594
  title: "MySite Preview"
594
- }, `${selectedThemeId}-${previewKey}`) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
595
+ }, previewKey), isUpdating && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
596
+ className: "absolute inset-0 flex items-center justify-center bg-white/60",
597
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.LoaderCircle, { className: "text-muted-foreground h-6 w-6 animate-spin" })
598
+ })] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
595
599
  className: "flex h-full items-center justify-center",
596
600
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
597
601
  className: "text-muted-foreground text-sm",
@@ -642,11 +646,8 @@ function MySiteThemeEditor({ themes, selectedThemeId, onSelectTheme, isPending,
642
646
  loading: "lazy",
643
647
  className: "absolute inset-0 h-full w-full object-cover"
644
648
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
645
- className: "text-muted-foreground flex h-full w-full items-center justify-center",
646
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
647
- className: "text-xs",
648
- children: "No preview"
649
- })
649
+ className: "text-muted-foreground/50 flex h-full w-full items-center justify-center",
650
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Palette, { className: "h-8 w-8" })
650
651
  }),
651
652
  isSelected && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
652
653
  className: "bg-primary/20 absolute inset-0 flex items-center justify-center",
@@ -1731,8 +1732,8 @@ function MySiteMainView({ client }) {
1731
1732
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MySitePhonePreview, {
1732
1733
  mysiteUrl,
1733
1734
  themeName,
1734
- selectedThemeId: resolvedThemeId,
1735
1735
  previewKey,
1736
+ isUpdating: updateMySiteMutation.isPending,
1736
1737
  onPreview: handlePreview
1737
1738
  })
1738
1739
  })]
@@ -1804,4 +1805,4 @@ Object.defineProperty(exports, "mySiteScreenPropertySchema", {
1804
1805
  }
1805
1806
  });
1806
1807
 
1807
- //# sourceMappingURL=MySiteScreen-Ci2rLGQc.cjs.map
1808
+ //# sourceMappingURL=MySiteScreen-DY7PSqP6.cjs.map