@cmdoss/walrus-site-builder-react 2.4.0 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -4,10 +4,10 @@ import { ALLOWED_METADATA, SuinsClient, SuinsTransaction, mainPackage as mainPac
4
4
  import { MAINNET_WALRUS_PACKAGE_CONFIG, TESTNET_WALRUS_PACKAGE_CONFIG } from "@mysten/walrus";
5
5
  import { useStore } from "@nanostores/react";
6
6
  import { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from "react";
7
- import { useQueries, useQuery } from "@tanstack/react-query";
7
+ import { useMutation, useQueries, useQuery } from "@tanstack/react-query";
8
8
  import { atom, computed } from "nanostores";
9
9
  import * as Dialog from "@radix-ui/react-dialog";
10
- import { AlertCircle, AlertTriangle, Calendar, CalendarClock, CheckCircle, CheckCircle2, Clock, ExternalLink, Globe2, Info, Link2, Loader2, Pencil, Search, Upload, X, XCircle } from "lucide-react";
10
+ import { AlertCircle, AlertTriangle, Calendar, CalendarClock, CheckCircle, CheckCircle2, Clock, DollarSign, ExternalLink, Globe2, Info, Link2, Loader2, Pencil, Search, Upload, X, XCircle } from "lucide-react";
11
11
  import { AggregatorClient, Env } from "@cetusprotocol/aggregator-sdk";
12
12
  import BN from "bn.js";
13
13
  import { ZenFsFileManager } from "@cmdoss/file-manager";
@@ -85,8 +85,8 @@ function useSuiNsDomainsQuery(currentAccount, clients) {
85
85
  });
86
86
  console.log("response", response);
87
87
  const domains$1 = response.data.filter((obj) => obj.data?.content?.dataType === "moveObject").map((obj) => {
88
- const content$5 = obj.data?.content;
89
- const fields = content$5 && "fields" in content$5 ? content$5.fields : {};
88
+ const content$6 = obj.data?.content;
89
+ const fields = content$6 && "fields" in content$6 ? content$6.fields : {};
90
90
  return {
91
91
  name: fields?.domain_name || "",
92
92
  objectId: obj.data?.objectId || "",
@@ -315,12 +315,12 @@ function useZenfsFilesQuery(fm, clients) {
315
315
  const files = await fm.listFiles();
316
316
  const assets = [];
317
317
  for (const path of files) {
318
- const content$5 = await fm?.readFile(path);
319
- if (!content$5) continue;
320
- const hashU256 = sha256ToU256(await getSHA256Hash(content$5));
318
+ const content$6 = await fm?.readFile(path);
319
+ if (!content$6) continue;
320
+ const hashU256 = sha256ToU256(await getSHA256Hash(content$6));
321
321
  assets.push({
322
322
  path,
323
- content: content$5,
323
+ content: content$6,
324
324
  hashU256
325
325
  });
326
326
  }
@@ -337,6 +337,7 @@ const isDomainDialogOpen = atom(false);
337
337
  const isAssigningDomain = atom(false);
338
338
  const isRegisterSuiNSDomainDialogOpen = atom(false);
339
339
  const isExtendTimeDialogOpen = atom(false);
340
+ const isUpdateMetadataModalOpen = atom(false);
340
341
 
341
342
  //#endregion
342
343
  //#region src/stores/site-metadata.store.ts
@@ -374,7 +375,7 @@ var SiteMetadata = class {
374
375
  this.originalProjectUrl,
375
376
  this.originalEpochs,
376
377
  this.originalSuiNSUrl
377
- ], (title$5, description$5, iconUrl, link$3, projectUrl, epochs, suiNSUrl, originalTitle, originalDescription, originalIcon, originalLink, originalProjectUrl, originalEpochs, originalSuiNSUrl) => title$5 !== originalTitle || description$5 !== originalDescription || (iconUrl ?? null) !== (originalIcon ?? null) || link$3 !== originalLink || projectUrl !== originalProjectUrl || epochs !== originalEpochs || JSON.stringify(suiNSUrl.sort((a, b) => a.nftId.localeCompare(b.nftId))) !== JSON.stringify(originalSuiNSUrl.sort((a, b) => a.nftId.localeCompare(b.nftId))));
378
+ ], (title$6, description$6, iconUrl, link$3, projectUrl, epochs, suiNSUrl, originalTitle, originalDescription, originalIcon, originalLink, originalProjectUrl, originalEpochs, originalSuiNSUrl) => title$6 !== originalTitle || description$6 !== originalDescription || (iconUrl ?? null) !== (originalIcon ?? null) || link$3 !== originalLink || projectUrl !== originalProjectUrl || epochs !== originalEpochs || JSON.stringify(suiNSUrl.sort((a, b) => a.nftId.localeCompare(b.nftId))) !== JSON.stringify(originalSuiNSUrl.sort((a, b) => a.nftId.localeCompare(b.nftId))));
378
379
  /**
379
380
  * Computed URL for displaying the image preview
380
381
  */
@@ -634,10 +635,10 @@ function useSitePublishing({ siteId, assets, onUpdateSiteMetadata, onAssociatedD
634
635
  const deployStatusText = useStore(sitePublishingStore.deployStatusText);
635
636
  const deployStepIndex = useStore(sitePublishingStore.deploymentStepIndex);
636
637
  const epochs = useStore(siteMetadataStore.epochs);
637
- const title$5 = useStore(siteMetadataStore.title);
638
+ const title$6 = useStore(siteMetadataStore.title);
638
639
  const imageUrl = useStore(siteMetadataStore.imageUrl);
639
640
  const link$3 = useStore(siteMetadataStore.link);
640
- const description$5 = useStore(siteMetadataStore.description);
641
+ const description$6 = useStore(siteMetadataStore.description);
641
642
  const isEditingSiteMetadata = useStore(siteMetadataStore.isDirty);
642
643
  const isSavingSiteMetadata = useStore(siteMetadataStore.loading);
643
644
  const isAssigning = useStore(isAssigningDomain);
@@ -666,8 +667,8 @@ function useSitePublishing({ siteId, assets, onUpdateSiteMetadata, onAssociatedD
666
667
  if (imageUrl instanceof File) return onError?.("Please upload image first.");
667
668
  const siteMetadata = {
668
669
  id: siteId,
669
- title: title$5,
670
- description: description$5,
670
+ title: title$6,
671
+ description: description$6,
671
672
  imageUrl: imageUrl ?? void 0,
672
673
  link: siteMetadataStore.link.get() ?? void 0,
673
674
  projectUrl: siteMetadataStore.projectUrl.get() ?? void 0
@@ -838,9 +839,9 @@ function useSitePublishing({ siteId, assets, onUpdateSiteMetadata, onAssociatedD
838
839
  isWorking,
839
840
  certifiedBlobs,
840
841
  epochs,
841
- title: title$5,
842
+ title: title$6,
842
843
  iconUrl: imageUrl,
843
- description: description$5,
844
+ description: description$6,
844
845
  link: link$3,
845
846
  isEditingSiteMetadata,
846
847
  deployStatus,
@@ -1337,6 +1338,43 @@ function useSuiNsRegistration({ currentAccount, clients: { suiClient, queryClien
1337
1338
  };
1338
1339
  }
1339
1340
 
1341
+ //#endregion
1342
+ //#region src/hooks/useUpdateSiteMetadata.ts
1343
+ function useUpdateSiteMetadata({ siteId, clients: { suiClient, queryClient, walrusClient }, currentAccount, signAndExecuteTransaction, sponsorConfig }) {
1344
+ const network = suiClient.network;
1345
+ const sdk = useMemo(() => {
1346
+ if (!currentAccount || !suiClient || !walrusClient) return null;
1347
+ return new WalrusSiteBuilderSdk(walrusClient, suiClient, currentAccount.address, signAndExecuteTransaction, sponsorConfig);
1348
+ }, [
1349
+ currentAccount,
1350
+ suiClient,
1351
+ walrusClient,
1352
+ signAndExecuteTransaction,
1353
+ sponsorConfig
1354
+ ]);
1355
+ const mutation = useMutation({
1356
+ mutationFn: async ({ siteName, metadata }) => {
1357
+ if (!sdk) throw new Error("SDK not initialized");
1358
+ return await sdk.updateSiteMetadata(siteId, siteName, metadata);
1359
+ },
1360
+ onSuccess: (digest) => {
1361
+ queryClient.invalidateQueries({ queryKey: queryKeys.walrusSite(siteId) });
1362
+ if (currentAccount?.address) queryClient.invalidateQueries({ queryKey: queryKeys.walrusSites(currentAccount.address, network) });
1363
+ console.log("✅ Site metadata updated successfully:", digest);
1364
+ },
1365
+ onError: (error) => {
1366
+ console.error("❌ Failed to update site metadata:", error);
1367
+ }
1368
+ }, queryClient);
1369
+ return {
1370
+ updateSiteMetadata: mutation.mutateAsync,
1371
+ isUpdating: mutation.isPending,
1372
+ error: mutation.error,
1373
+ isSuccess: mutation.isSuccess,
1374
+ data: mutation.data
1375
+ };
1376
+ }
1377
+
1340
1378
  //#endregion
1341
1379
  //#region src/hooks/useZenFsWorkspace.ts
1342
1380
  function useZenFsWorkspace(workspaceDir = "/workspace", mountDir = "/workspace", queryClient) {
@@ -1361,6 +1399,27 @@ function useZenFsWorkspace(workspaceDir = "/workspace", mountDir = "/workspace",
1361
1399
  };
1362
1400
  }
1363
1401
 
1402
+ //#endregion
1403
+ //#region src/queries/storage-cost.query.ts
1404
+ function useStorageCostQuery(fileSize, epochs, clients) {
1405
+ const { walrusClient, queryClient } = clients;
1406
+ return useQuery({
1407
+ queryKey: queryKeys.storageCost(fileSize, epochs),
1408
+ queryFn: async () => {
1409
+ if (!walrusClient) throw new Error("Walrus client not available");
1410
+ if (fileSize === null) throw new Error("Invalid file size");
1411
+ const storageCost = await walrusClient.storageCost(fileSize, epochs);
1412
+ return {
1413
+ storageCost: storageCost.storageCost.toString(),
1414
+ writeCost: storageCost.writeCost.toString(),
1415
+ totalCost: storageCost.totalCost.toString()
1416
+ };
1417
+ },
1418
+ enabled: !!walrusClient && fileSize !== null && fileSize > 0 && epochs > 0,
1419
+ staleTime: 300 * 1e3
1420
+ }, queryClient);
1421
+ }
1422
+
1364
1423
  //#endregion
1365
1424
  //#region ../../node_modules/.pnpm/@vanilla-extract+recipes@0.5.7_@vanilla-extract+css@1.18.0/node_modules/@vanilla-extract/recipes/dist/createRuntimeFn-166334d7.cjs.prod.js
1366
1425
  var require_createRuntimeFn_166334d7_cjs_prod = /* @__PURE__ */ __commonJSMin(((exports) => {
@@ -1585,7 +1644,7 @@ var banner = (0, import_vanilla_extract_recipes_createRuntimeFn_cjs.createRuntim
1585
1644
  defaultVariants: { variant: "info" },
1586
1645
  compoundVariants: []
1587
1646
  });
1588
- var closeButton$1 = (0, import_vanilla_extract_recipes_createRuntimeFn_cjs.createRuntimeFn)({
1647
+ var closeButton$2 = (0, import_vanilla_extract_recipes_createRuntimeFn_cjs.createRuntimeFn)({
1589
1648
  defaultClassName: "Banner_closeButton__z4crwgx",
1590
1649
  variantClassNames: { variant: {
1591
1650
  info: "Banner_closeButton_variant_info__z4crwgy",
@@ -1598,8 +1657,8 @@ var closeButton$1 = (0, import_vanilla_extract_recipes_createRuntimeFn_cjs.creat
1598
1657
  compoundVariants: []
1599
1658
  });
1600
1659
  var closeIcon = "Banner_closeIcon__z4crwg13";
1601
- var content$4 = "Banner_content__z4crwg7";
1602
- var description$4 = (0, import_vanilla_extract_recipes_createRuntimeFn_cjs.createRuntimeFn)({
1660
+ var content$5 = "Banner_content__z4crwg7";
1661
+ var description$5 = (0, import_vanilla_extract_recipes_createRuntimeFn_cjs.createRuntimeFn)({
1603
1662
  defaultClassName: "Banner_description__z4crwgr",
1604
1663
  variantClassNames: { variant: {
1605
1664
  info: "Banner_description_variant_info__z4crwgs",
@@ -1649,7 +1708,7 @@ var link$2 = (0, import_vanilla_extract_recipes_createRuntimeFn_cjs.createRuntim
1649
1708
  compoundVariants: []
1650
1709
  });
1651
1710
  var textContainer = "Banner_textContainer__z4crwgk";
1652
- var title$4 = (0, import_vanilla_extract_recipes_createRuntimeFn_cjs.createRuntimeFn)({
1711
+ var title$5 = (0, import_vanilla_extract_recipes_createRuntimeFn_cjs.createRuntimeFn)({
1653
1712
  defaultClassName: "Banner_title__z4crwgl",
1654
1713
  variantClassNames: { variant: {
1655
1714
  info: "Banner_title_variant_info__z4crwgm",
@@ -1731,7 +1790,7 @@ const Banner = ({ title: titleText, description: descriptionText, icon: customIc
1731
1790
  })]
1732
1791
  }),
1733
1792
  /* @__PURE__ */ jsxs("div", {
1734
- className: content$4,
1793
+ className: content$5,
1735
1794
  children: [showIcon && /* @__PURE__ */ jsx("div", {
1736
1795
  className: iconContainer({ variant }),
1737
1796
  children: /* @__PURE__ */ jsx("div", {
@@ -1741,10 +1800,10 @@ const Banner = ({ title: titleText, description: descriptionText, icon: customIc
1741
1800
  }), /* @__PURE__ */ jsxs("div", {
1742
1801
  className: textContainer,
1743
1802
  children: [/* @__PURE__ */ jsx("h3", {
1744
- className: title$4({ variant }),
1803
+ className: title$5({ variant }),
1745
1804
  children: titleText
1746
1805
  }), descriptionText && /* @__PURE__ */ jsxs("p", {
1747
- className: description$4({ variant }),
1806
+ className: description$5({ variant }),
1748
1807
  children: [descriptionText, url && urlName && /* @__PURE__ */ jsxs(Fragment, { children: [" ", /* @__PURE__ */ jsx("a", {
1749
1808
  href: url,
1750
1809
  target: "_blank",
@@ -1758,7 +1817,7 @@ const Banner = ({ title: titleText, description: descriptionText, icon: customIc
1758
1817
  onClose && /* @__PURE__ */ jsx("button", {
1759
1818
  type: "button",
1760
1819
  onClick: onClose,
1761
- className: closeButton$1({ variant }),
1820
+ className: closeButton$2({ variant }),
1762
1821
  "aria-label": "Close banner",
1763
1822
  children: /* @__PURE__ */ jsx("svg", {
1764
1823
  className: closeIcon,
@@ -1998,7 +2057,7 @@ var stepperWrapper = "Stepper_stepperWrapper__e4qgi2";
1998
2057
 
1999
2058
  //#endregion
2000
2059
  //#region src/components/ui/Stepper.tsx
2001
- const Step = ({ title: title$5, isLoading, isCompleted, isActive, isLast }) => {
2060
+ const Step = ({ title: title$6, isLoading, isCompleted, isActive, isLast }) => {
2002
2061
  return /* @__PURE__ */ jsxs("div", {
2003
2062
  className: stepContainer,
2004
2063
  children: [
@@ -2021,7 +2080,7 @@ const Step = ({ title: title$5, isLoading, isCompleted, isActive, isLast }) => {
2021
2080
  !isLast && /* @__PURE__ */ jsx("div", { className: `${stepLine} ${isCompleted ? stepLineCompleted : stepLinePending}` }),
2022
2081
  /* @__PURE__ */ jsx("span", {
2023
2082
  className: `${stepLabel} ${isActive || isCompleted ? stepLabelActive : stepLabelInactive}`,
2024
- children: title$5
2083
+ children: title$6
2025
2084
  })
2026
2085
  ]
2027
2086
  });
@@ -2045,22 +2104,33 @@ const Stepper = ({ steps, currentStep, isLoading }) => {
2045
2104
 
2046
2105
  //#endregion
2047
2106
  //#region src/components/extend-time-dialog/ExtendTimeDialog.css.ts
2048
- var body$1 = "ExtendTimeDialog_body__1augvc0a";
2049
- var closeButton = "ExtendTimeDialog_closeButton__1augvc09";
2050
- var content$3 = "ExtendTimeDialog_content__1augvc02";
2107
+ var body$2 = "ExtendTimeDialog_body__1augvc0a";
2108
+ var closeButton$1 = "ExtendTimeDialog_closeButton__1augvc09";
2109
+ var content$4 = "ExtendTimeDialog_content__1augvc02";
2110
+ var costContent = "ExtendTimeDialog_costContent__1augvc0u";
2111
+ var costDivider = "ExtendTimeDialog_costDivider__1augvc011";
2112
+ var costError = "ExtendTimeDialog_costError__1augvc0z";
2113
+ var costHeader = "ExtendTimeDialog_costHeader__1augvc0t";
2114
+ var costLabel = "ExtendTimeDialog_costLabel__1augvc0w";
2115
+ var costLoading = "ExtendTimeDialog_costLoading__1augvc0y";
2116
+ var costRow = "ExtendTimeDialog_costRow__1augvc0v";
2117
+ var costSection = "ExtendTimeDialog_costSection__1augvc0s";
2118
+ var costValue = "ExtendTimeDialog_costValue__1augvc0x";
2119
+ var costWarning = "ExtendTimeDialog_costWarning__1augvc010";
2051
2120
  var dateInputWrapper = "ExtendTimeDialog_dateInputWrapper__1augvc0d";
2052
- var description$3 = "ExtendTimeDialog_description__1augvc08";
2053
- var errorText = "ExtendTimeDialog_errorText__1augvc0h";
2121
+ var description$4 = "ExtendTimeDialog_description__1augvc08";
2122
+ var errorText$1 = "ExtendTimeDialog_errorText__1augvc0h";
2123
+ var estimatedBadge = "ExtendTimeDialog_estimatedBadge__1augvc015";
2054
2124
  var fieldGroup = "ExtendTimeDialog_fieldGroup__1augvc0c";
2055
- var footer$1 = "ExtendTimeDialog_footer__1augvc0r";
2125
+ var footer$2 = "ExtendTimeDialog_footer__1augvc0r";
2056
2126
  var formSection = "ExtendTimeDialog_formSection__1augvc0b";
2057
- var header$2 = "ExtendTimeDialog_header__1augvc06";
2127
+ var header$3 = "ExtendTimeDialog_header__1augvc06";
2058
2128
  var infoText = "ExtendTimeDialog_infoText__1augvc0g";
2059
2129
  var inputError = "ExtendTimeDialog_inputError__1augvc0f";
2060
2130
  var loadingContent = "ExtendTimeDialog_loadingContent__1augvc04";
2061
2131
  var loadingOverlay = "ExtendTimeDialog_loadingOverlay__1augvc03";
2062
- var overlay$2 = "ExtendTimeDialog_overlay__1augvc01";
2063
- var spinner$1 = "ExtendTimeDialog_spinner__1augvc05";
2132
+ var overlay$3 = "ExtendTimeDialog_overlay__1augvc01";
2133
+ var spinner$2 = "ExtendTimeDialog_spinner__1augvc05";
2064
2134
  var summaryCard = "ExtendTimeDialog_summaryCard__1augvc0j";
2065
2135
  var summaryContent = "ExtendTimeDialog_summaryContent__1augvc0l";
2066
2136
  var summaryError = "ExtendTimeDialog_summaryError__1augvc0o";
@@ -2068,7 +2138,7 @@ var summaryGrid = "ExtendTimeDialog_summaryGrid__1augvc0i";
2068
2138
  var summaryHeader = "ExtendTimeDialog_summaryHeader__1augvc0k";
2069
2139
  var summarySubtext = "ExtendTimeDialog_summarySubtext__1augvc0n";
2070
2140
  var summaryValue = "ExtendTimeDialog_summaryValue__1augvc0m";
2071
- var title$3 = "ExtendTimeDialog_title__1augvc07";
2141
+ var title$4 = "ExtendTimeDialog_title__1augvc07";
2072
2142
 
2073
2143
  //#endregion
2074
2144
  //#region src/components/extend-time-dialog/ExtendTimeDialog.tsx
@@ -2080,6 +2150,7 @@ const ExtendTimeDialog = ({ siteId, currentAccount, clients: { suiClient, queryC
2080
2150
  const [dateError, setDateError] = useState(null);
2081
2151
  const [currentEpochsRemaining, setCurrentEpochsRemaining] = useState(null);
2082
2152
  const [expirationDates, setExpirationDates] = useState(/* @__PURE__ */ new Map());
2153
+ const [totalFileSize, setTotalFileSize] = useState(null);
2083
2154
  const { epochDurationMs, formatDate } = useEpochDuration(walrusClient);
2084
2155
  const txExecutor = useTransactionExecutor({
2085
2156
  suiClient,
@@ -2096,6 +2167,7 @@ const ExtendTimeDialog = ({ siteId, currentAccount, clients: { suiClient, queryC
2096
2167
  try {
2097
2168
  const blobType = await walrusClient.getBlobType();
2098
2169
  const datesMap = /* @__PURE__ */ new Map();
2170
+ let totalSize = 0;
2099
2171
  const stakingState = await walrusClient.stakingState();
2100
2172
  const currentEpoch = Number(stakingState.epoch);
2101
2173
  const epochDuration = Number(stakingState.epoch_duration);
@@ -2120,6 +2192,11 @@ const ExtendTimeDialog = ({ siteId, currentAccount, clients: { suiClient, queryC
2120
2192
  const remainingEpochs = Number(storage.fields.end_epoch) - currentEpoch;
2121
2193
  const expirationTime = Date.now() + remainingEpochs * epochDuration;
2122
2194
  datesMap.set(blobId, new Date(expirationTime));
2195
+ const sizeField = fields.size;
2196
+ if (sizeField !== void 0) {
2197
+ const size = typeof sizeField === "string" ? Number(sizeField) : Number(sizeField);
2198
+ if (!Number.isNaN(size) && size > 0) totalSize += size;
2199
+ }
2123
2200
  break;
2124
2201
  }
2125
2202
  }
@@ -2130,6 +2207,7 @@ const ExtendTimeDialog = ({ siteId, currentAccount, clients: { suiClient, queryC
2130
2207
  cursor = ownedObjects.nextCursor;
2131
2208
  }
2132
2209
  setExpirationDates(datesMap);
2210
+ setTotalFileSize(totalSize > 0 ? totalSize : null);
2133
2211
  } catch (error) {
2134
2212
  console.error("Error fetching expiration dates:", error);
2135
2213
  }
@@ -2140,6 +2218,40 @@ const ExtendTimeDialog = ({ siteId, currentAccount, clients: { suiClient, queryC
2140
2218
  suiClient,
2141
2219
  siteData
2142
2220
  ]);
2221
+ const { data: storageCostData, isLoading: isStorageCostLoading, error: storageCostError } = useStorageCostQuery(totalFileSize, epochs, {
2222
+ queryClient,
2223
+ walrusClient
2224
+ });
2225
+ const estimatedFileSize = useMemo(() => {
2226
+ if (totalFileSize !== null) return null;
2227
+ if (!siteData?.resources) return null;
2228
+ return siteData.resources.length * 10 * 1024;
2229
+ }, [totalFileSize, siteData?.resources]);
2230
+ const { data: estimatedCostData, isLoading: isEstimatedCostLoading } = useStorageCostQuery(estimatedFileSize, epochs, {
2231
+ queryClient,
2232
+ walrusClient
2233
+ });
2234
+ const formatFileSize = useCallback((bytes) => {
2235
+ if (bytes === null || bytes === 0) return "Unknown";
2236
+ const units = [
2237
+ "B",
2238
+ "KB",
2239
+ "MB",
2240
+ "GB"
2241
+ ];
2242
+ let size = bytes;
2243
+ let unitIndex = 0;
2244
+ while (size >= 1024 && unitIndex < units.length - 1) {
2245
+ size /= 1024;
2246
+ unitIndex++;
2247
+ }
2248
+ return `${size.toFixed(2)} ${units[unitIndex]}`;
2249
+ }, []);
2250
+ const formatWalAmount = useCallback((amount) => {
2251
+ if (!amount) return "—";
2252
+ const num = BigInt(amount);
2253
+ return (Number(num) / 1e9).toFixed(6);
2254
+ }, []);
2143
2255
  useEffect(() => {
2144
2256
  if (isOpen && siteId) fetchExpirationDates();
2145
2257
  }, [
@@ -2334,39 +2446,39 @@ const ExtendTimeDialog = ({ siteId, currentAccount, clients: { suiClient, queryC
2334
2446
  return /* @__PURE__ */ jsx(Dialog.Root, {
2335
2447
  open: isOpen,
2336
2448
  onOpenChange: (open) => !open && handleClose(),
2337
- children: /* @__PURE__ */ jsxs(Dialog.Portal, { children: [/* @__PURE__ */ jsx(Dialog.Overlay, { className: overlay$2 }), /* @__PURE__ */ jsxs(Dialog.Content, {
2338
- className: content$3,
2449
+ children: /* @__PURE__ */ jsxs(Dialog.Portal, { children: [/* @__PURE__ */ jsx(Dialog.Overlay, { className: overlay$3 }), /* @__PURE__ */ jsxs(Dialog.Content, {
2450
+ className: content$4,
2339
2451
  children: [
2340
2452
  isExtending && /* @__PURE__ */ jsx("div", {
2341
2453
  className: loadingOverlay,
2342
2454
  children: /* @__PURE__ */ jsxs("div", {
2343
2455
  className: loadingContent,
2344
- children: [/* @__PURE__ */ jsx(Loader2, { className: spinner$1 }), /* @__PURE__ */ jsx("p", { children: "Extending storage time..." })]
2456
+ children: [/* @__PURE__ */ jsx(Loader2, { className: spinner$2 }), /* @__PURE__ */ jsx("p", { children: "Extending storage time..." })]
2345
2457
  })
2346
2458
  }),
2347
2459
  /* @__PURE__ */ jsxs("div", {
2348
- className: header$2,
2460
+ className: header$3,
2349
2461
  children: [
2350
2462
  /* @__PURE__ */ jsxs(Dialog.Title, {
2351
- className: title$3,
2463
+ className: title$4,
2352
2464
  children: ["Extend Time for ", siteData.name]
2353
2465
  }),
2354
2466
  /* @__PURE__ */ jsx(Dialog.Description, {
2355
- className: description$3,
2467
+ className: description$4,
2356
2468
  children: "Add epochs to extend the storage time for blobs in this site. Epochs will be added to the current expiration time."
2357
2469
  }),
2358
2470
  /* @__PURE__ */ jsx(Dialog.Close, {
2359
2471
  asChild: true,
2360
2472
  children: /* @__PURE__ */ jsx("button", {
2361
2473
  type: "button",
2362
- className: closeButton,
2474
+ className: closeButton$1,
2363
2475
  children: /* @__PURE__ */ jsx(X, { size: 20 })
2364
2476
  })
2365
2477
  })
2366
2478
  ]
2367
2479
  }),
2368
2480
  /* @__PURE__ */ jsxs("div", {
2369
- className: body$1,
2481
+ className: body$2,
2370
2482
  children: [
2371
2483
  currentEpochsRemaining === 0 && /* @__PURE__ */ jsx(Banner, {
2372
2484
  title: "Site Expired",
@@ -2380,109 +2492,196 @@ const ExtendTimeDialog = ({ siteId, currentAccount, clients: { suiClient, queryC
2380
2492
  }),
2381
2493
  /* @__PURE__ */ jsxs("div", {
2382
2494
  className: formSection,
2383
- children: [/* @__PURE__ */ jsxs("div", {
2384
- className: fieldGroup,
2385
- children: [
2386
- /* @__PURE__ */ jsx(Label, {
2387
- htmlFor: "expiration-date",
2388
- children: "Target Expiration Date"
2389
- }),
2390
- /* @__PURE__ */ jsx("div", {
2391
- className: dateInputWrapper,
2392
- children: /* @__PURE__ */ jsx(Input, {
2393
- id: "expiration-date",
2394
- type: "date",
2395
- value: selectedDate,
2396
- min: minDate,
2397
- max: maxDate,
2398
- onChange: handleDateChange,
2399
- disabled: currentEpochsRemaining === 0 || isExtending,
2400
- className: dateError ? inputError : ""
2495
+ children: [
2496
+ /* @__PURE__ */ jsxs("div", {
2497
+ className: fieldGroup,
2498
+ children: [
2499
+ /* @__PURE__ */ jsx(Label, {
2500
+ htmlFor: "expiration-date",
2501
+ children: "Target Expiration Date"
2502
+ }),
2503
+ /* @__PURE__ */ jsx("div", {
2504
+ className: dateInputWrapper,
2505
+ children: /* @__PURE__ */ jsx(Input, {
2506
+ id: "expiration-date",
2507
+ type: "date",
2508
+ value: selectedDate,
2509
+ min: minDate,
2510
+ max: maxDate,
2511
+ onChange: handleDateChange,
2512
+ disabled: currentEpochsRemaining === 0 || isExtending,
2513
+ className: dateError ? inputError : ""
2514
+ })
2515
+ }),
2516
+ epochDurationMs && /* @__PURE__ */ jsxs("div", {
2517
+ className: infoText,
2518
+ children: [/* @__PURE__ */ jsx(Info, { size: 14 }), /* @__PURE__ */ jsxs("span", { children: [
2519
+ "1 epoch ≈",
2520
+ " ",
2521
+ (epochDurationMs / (1e3 * 60 * 60 * 24)).toFixed(1),
2522
+ " ",
2523
+ "days • Duration rounded up. Maximum 365 epochs per extend."
2524
+ ] })]
2525
+ }),
2526
+ dateError && /* @__PURE__ */ jsx("p", {
2527
+ className: errorText$1,
2528
+ children: dateError
2401
2529
  })
2402
- }),
2403
- epochDurationMs && /* @__PURE__ */ jsxs("div", {
2404
- className: infoText,
2405
- children: [/* @__PURE__ */ jsx(Info, { size: 14 }), /* @__PURE__ */ jsxs("span", { children: [
2406
- "1 epoch ≈",
2407
- " ",
2408
- (epochDurationMs / (1e3 * 60 * 60 * 24)).toFixed(1),
2409
- " ",
2410
- "days • Duration rounded up. Maximum 365 epochs per extend."
2411
- ] })]
2412
- }),
2413
- dateError && /* @__PURE__ */ jsx("p", {
2414
- className: errorText,
2415
- children: dateError
2416
- })
2417
- ]
2418
- }), /* @__PURE__ */ jsxs("div", {
2419
- className: summaryGrid,
2420
- children: [/* @__PURE__ */ jsxs("div", {
2421
- className: summaryCard,
2530
+ ]
2531
+ }),
2532
+ /* @__PURE__ */ jsxs("div", {
2533
+ className: summaryGrid,
2422
2534
  children: [/* @__PURE__ */ jsxs("div", {
2423
- className: summaryHeader,
2424
- children: [/* @__PURE__ */ jsx(Calendar, { size: 14 }), /* @__PURE__ */ jsx("span", { children: "Current Expiration" })]
2425
- }), currentExpiredDateMemo ? /* @__PURE__ */ jsxs("div", {
2426
- className: summaryContent,
2427
- children: [
2428
- /* @__PURE__ */ jsx("div", {
2535
+ className: summaryCard,
2536
+ children: [/* @__PURE__ */ jsxs("div", {
2537
+ className: summaryHeader,
2538
+ children: [/* @__PURE__ */ jsx(Calendar, { size: 14 }), /* @__PURE__ */ jsx("span", { children: "Current Expiration" })]
2539
+ }), currentExpiredDateMemo ? /* @__PURE__ */ jsxs("div", {
2540
+ className: summaryContent,
2541
+ children: [
2542
+ /* @__PURE__ */ jsx("div", {
2543
+ className: summaryValue,
2544
+ children: formatDate(currentExpiredDateMemo)
2545
+ }),
2546
+ currentEpochsRemaining !== null && currentEpochsRemaining > 0 && /* @__PURE__ */ jsxs("div", {
2547
+ className: summarySubtext,
2548
+ children: [
2549
+ currentEpochsRemaining,
2550
+ " epoch",
2551
+ currentEpochsRemaining !== 1 ? "s" : "",
2552
+ " remaining"
2553
+ ]
2554
+ }),
2555
+ currentEpochsRemaining === 0 && /* @__PURE__ */ jsx("div", {
2556
+ className: summaryError,
2557
+ children: "Expired"
2558
+ })
2559
+ ]
2560
+ }) : /* @__PURE__ */ jsx("div", {
2561
+ className: summaryValue,
2562
+ children: "Unavailable"
2563
+ })]
2564
+ }), /* @__PURE__ */ jsxs("div", {
2565
+ className: summaryCard,
2566
+ children: [/* @__PURE__ */ jsxs("div", {
2567
+ className: summaryHeader,
2568
+ children: [/* @__PURE__ */ jsx(Clock, { size: 14 }), /* @__PURE__ */ jsx("span", { children: "New Expiration Date" })]
2569
+ }), projectedDate ? /* @__PURE__ */ jsxs("div", {
2570
+ className: summaryContent,
2571
+ children: [/* @__PURE__ */ jsx("div", {
2429
2572
  className: summaryValue,
2430
- children: formatDate(currentExpiredDateMemo)
2431
- }),
2432
- currentEpochsRemaining !== null && currentEpochsRemaining > 0 && /* @__PURE__ */ jsxs("div", {
2573
+ children: formatDate(projectedDate)
2574
+ }), currentEpochsRemaining !== null && /* @__PURE__ */ jsxs("div", {
2433
2575
  className: summarySubtext,
2434
2576
  children: [
2435
2577
  currentEpochsRemaining,
2436
- " epoch",
2437
- currentEpochsRemaining !== 1 ? "s" : "",
2438
- " remaining"
2578
+ " ",
2579
+ " ",
2580
+ currentEpochsRemaining + epochs,
2581
+ " epochs (+",
2582
+ epochs,
2583
+ " ",
2584
+ "epoch",
2585
+ epochs !== 1 ? "s" : "",
2586
+ ")"
2439
2587
  ]
2588
+ })]
2589
+ }) : /* @__PURE__ */ jsx("div", {
2590
+ className: summaryValue,
2591
+ children: "Select a date"
2592
+ })]
2593
+ })]
2594
+ }),
2595
+ /* @__PURE__ */ jsxs("div", {
2596
+ className: costSection,
2597
+ children: [/* @__PURE__ */ jsxs("div", {
2598
+ className: costHeader,
2599
+ children: [
2600
+ /* @__PURE__ */ jsx(DollarSign, { size: 16 }),
2601
+ /* @__PURE__ */ jsx("span", { children: "Storage Cost" }),
2602
+ totalFileSize === null && estimatedFileSize !== null && /* @__PURE__ */ jsx("span", {
2603
+ className: estimatedBadge,
2604
+ children: "Estimated"
2605
+ })
2606
+ ]
2607
+ }), /* @__PURE__ */ jsxs("div", {
2608
+ className: costContent,
2609
+ children: [
2610
+ /* @__PURE__ */ jsxs("div", {
2611
+ className: costRow,
2612
+ children: [/* @__PURE__ */ jsx("span", {
2613
+ className: costLabel,
2614
+ children: "Size:"
2615
+ }), /* @__PURE__ */ jsx("span", {
2616
+ className: costValue,
2617
+ children: totalFileSize !== null ? formatFileSize(totalFileSize) : estimatedFileSize !== null ? formatFileSize(estimatedFileSize) : "Unknown"
2618
+ })]
2440
2619
  }),
2441
- currentEpochsRemaining === 0 && /* @__PURE__ */ jsx("div", {
2442
- className: summaryError,
2443
- children: "Expired"
2620
+ /* @__PURE__ */ jsxs("div", {
2621
+ className: costRow,
2622
+ children: [/* @__PURE__ */ jsx("span", {
2623
+ className: costLabel,
2624
+ children: "Resources:"
2625
+ }), /* @__PURE__ */ jsxs("span", {
2626
+ className: costValue,
2627
+ children: [
2628
+ siteData?.resources?.length || 0,
2629
+ " resources • ",
2630
+ epochs,
2631
+ " ",
2632
+ "epoch",
2633
+ epochs !== 1 ? "s" : ""
2634
+ ]
2635
+ })]
2636
+ }),
2637
+ isStorageCostLoading || isEstimatedCostLoading ? /* @__PURE__ */ jsxs("div", {
2638
+ className: costLoading,
2639
+ children: [/* @__PURE__ */ jsx(Loader2, {
2640
+ size: 14,
2641
+ className: spinner$2
2642
+ }), /* @__PURE__ */ jsx("span", { children: "Calculating cost..." })]
2643
+ }) : storageCostData || estimatedCostData ? /* @__PURE__ */ jsxs(Fragment, { children: [
2644
+ totalFileSize === null && estimatedFileSize !== null && /* @__PURE__ */ jsxs("div", {
2645
+ className: costWarning,
2646
+ children: [/* @__PURE__ */ jsx(Info, { size: 12 }), /* @__PURE__ */ jsxs("span", { children: [
2647
+ "Estimated cost based on",
2648
+ " ",
2649
+ siteData?.resources?.length || 0,
2650
+ " resource",
2651
+ siteData?.resources?.length !== 1 ? "s" : ""
2652
+ ] })]
2653
+ }),
2654
+ /* @__PURE__ */ jsx("div", { className: costDivider }),
2655
+ /* @__PURE__ */ jsxs("div", {
2656
+ className: costRow,
2657
+ children: [/* @__PURE__ */ jsx("span", {
2658
+ className: costLabel,
2659
+ children: "Storage Cost:"
2660
+ }), /* @__PURE__ */ jsxs("span", {
2661
+ className: costValue,
2662
+ children: [
2663
+ formatWalAmount(storageCostData?.storageCost || estimatedCostData?.storageCost),
2664
+ " ",
2665
+ "WAL"
2666
+ ]
2667
+ })]
2668
+ })
2669
+ ] }) : storageCostError ? /* @__PURE__ */ jsxs("div", {
2670
+ className: costError,
2671
+ children: [/* @__PURE__ */ jsx(Info, { size: 14 }), /* @__PURE__ */ jsx("span", { children: "Unable to calculate cost. Please ensure you have sufficient WAL balance." })]
2672
+ }) : /* @__PURE__ */ jsxs("div", {
2673
+ className: costError,
2674
+ children: [/* @__PURE__ */ jsx(Info, { size: 14 }), /* @__PURE__ */ jsx("span", { children: "Unable to calculate cost" })]
2444
2675
  })
2445
2676
  ]
2446
- }) : /* @__PURE__ */ jsx("div", {
2447
- className: summaryValue,
2448
- children: "Unavailable"
2449
- })]
2450
- }), /* @__PURE__ */ jsxs("div", {
2451
- className: summaryCard,
2452
- children: [/* @__PURE__ */ jsxs("div", {
2453
- className: summaryHeader,
2454
- children: [/* @__PURE__ */ jsx(Clock, { size: 14 }), /* @__PURE__ */ jsx("span", { children: "New Expiration Date" })]
2455
- }), projectedDate ? /* @__PURE__ */ jsxs("div", {
2456
- className: summaryContent,
2457
- children: [/* @__PURE__ */ jsx("div", {
2458
- className: summaryValue,
2459
- children: formatDate(projectedDate)
2460
- }), currentEpochsRemaining !== null && /* @__PURE__ */ jsxs("div", {
2461
- className: summarySubtext,
2462
- children: [
2463
- currentEpochsRemaining,
2464
- " →",
2465
- " ",
2466
- currentEpochsRemaining + epochs,
2467
- " epochs (+",
2468
- epochs,
2469
- " ",
2470
- "epoch",
2471
- epochs !== 1 ? "s" : "",
2472
- ")"
2473
- ]
2474
- })]
2475
- }) : /* @__PURE__ */ jsx("div", {
2476
- className: summaryValue,
2477
- children: "Select a date"
2478
2677
  })]
2479
- })]
2480
- })]
2678
+ })
2679
+ ]
2481
2680
  })
2482
2681
  ]
2483
2682
  }),
2484
2683
  /* @__PURE__ */ jsxs("div", {
2485
- className: footer$1,
2684
+ className: footer$2,
2486
2685
  children: [/* @__PURE__ */ jsx(Button, {
2487
2686
  variant: "outline",
2488
2687
  onClick: handleClose,
@@ -2503,14 +2702,14 @@ var ExtendTimeDialog_default = ExtendTimeDialog;
2503
2702
  //#endregion
2504
2703
  //#region src/components/publish-menu/PublishMenu.css.ts
2505
2704
  var buttonGroup$1 = "PublishMenu_buttonGroup__13o2p6d7";
2506
- var content$2 = "PublishMenu_content__13o2p6d0";
2507
- var description$2 = "PublishMenu_description__13o2p6d4";
2508
- var footer = "PublishMenu_footer__13o2p6d6";
2509
- var header$1 = "PublishMenu_header__13o2p6d2";
2705
+ var content$3 = "PublishMenu_content__13o2p6d0";
2706
+ var description$3 = "PublishMenu_description__13o2p6d4";
2707
+ var footer$1 = "PublishMenu_footer__13o2p6d6";
2708
+ var header$2 = "PublishMenu_header__13o2p6d2";
2510
2709
  var item = "PublishMenu_item__13o2p6d1";
2511
2710
  var link$1 = "PublishMenu_link__13o2p6d5";
2512
2711
  var separator = "PublishMenu_separator__13o2p6d8";
2513
- var title$2 = "PublishMenu_title__13o2p6d3";
2712
+ var title$3 = "PublishMenu_title__13o2p6d3";
2514
2713
 
2515
2714
  //#endregion
2516
2715
  //#region src/components/publish-menu/PublishMenu.tsx
@@ -2528,15 +2727,15 @@ const PublishMenu = ({ children, siteId, onPublishClick, onDomainClick, portalDo
2528
2727
  asChild: true,
2529
2728
  children
2530
2729
  }), /* @__PURE__ */ jsx(DropdownMenu.Portal, { children: /* @__PURE__ */ jsxs(DropdownMenu.Content, {
2531
- className: content$2,
2730
+ className: content$3,
2532
2731
  children: [
2533
2732
  /* @__PURE__ */ jsxs("div", {
2534
- className: header$1,
2733
+ className: header$2,
2535
2734
  children: [/* @__PURE__ */ jsx("h4", {
2536
- className: title$2,
2735
+ className: title$3,
2537
2736
  children: isDeployed ? "Update your Site" : "Publish your Site"
2538
2737
  }), isDeployed && walrusSiteUrl ? associatedDomains.length > 0 && suiNSUrl ? /* @__PURE__ */ jsxs("p", {
2539
- className: description$2,
2738
+ className: description$3,
2540
2739
  children: [
2541
2740
  "Your site is live at",
2542
2741
  " ",
@@ -2550,7 +2749,7 @@ const PublishMenu = ({ children, siteId, onPublishClick, onDomainClick, portalDo
2550
2749
  ". You can update your site to reflect the latest changes."
2551
2750
  ]
2552
2751
  }) : /* @__PURE__ */ jsxs("p", {
2553
- className: description$2,
2752
+ className: description$3,
2554
2753
  children: [
2555
2754
  "Your site is live at",
2556
2755
  " ",
@@ -2569,7 +2768,7 @@ const PublishMenu = ({ children, siteId, onPublishClick, onDomainClick, portalDo
2569
2768
  ". You can link SuiNS domains to view your site in the portal."
2570
2769
  ]
2571
2770
  }) : /* @__PURE__ */ jsxs("p", {
2572
- className: description$2,
2771
+ className: description$3,
2573
2772
  children: [
2574
2773
  "Deploy your app to",
2575
2774
  " ",
@@ -2633,7 +2832,7 @@ const PublishMenu = ({ children, siteId, onPublishClick, onDomainClick, portalDo
2633
2832
  }),
2634
2833
  /* @__PURE__ */ jsx(DropdownMenu.Separator, { className: separator }),
2635
2834
  /* @__PURE__ */ jsxs("div", {
2636
- className: footer,
2835
+ className: footer$1,
2637
2836
  children: [isDeployed && walrusSiteUrl ? /* @__PURE__ */ jsxs("div", {
2638
2837
  className: buttonGroup$1,
2639
2838
  children: [suiNSUrl ? /* @__PURE__ */ jsx(DropdownMenu.Item, {
@@ -2685,33 +2884,12 @@ const PublishMenu = ({ children, siteId, onPublishClick, onDomainClick, portalDo
2685
2884
  };
2686
2885
  var PublishMenu_default = PublishMenu;
2687
2886
 
2688
- //#endregion
2689
- //#region src/queries/storage-cost.query.ts
2690
- function useStorageCostQuery(fileSize, epochs, clients) {
2691
- const { walrusClient, queryClient } = clients;
2692
- return useQuery({
2693
- queryKey: queryKeys.storageCost(fileSize, epochs),
2694
- queryFn: async () => {
2695
- if (!walrusClient) throw new Error("Walrus client not available");
2696
- if (fileSize === null) throw new Error("Invalid file size");
2697
- const storageCost = await walrusClient.storageCost(fileSize, epochs);
2698
- return {
2699
- storageCost: storageCost.storageCost.toString(),
2700
- writeCost: storageCost.writeCost.toString(),
2701
- totalCost: storageCost.totalCost.toString()
2702
- };
2703
- },
2704
- enabled: !!walrusClient && fileSize !== null && fileSize > 0 && epochs > 0,
2705
- staleTime: 300 * 1e3
2706
- }, queryClient);
2707
- }
2708
-
2709
2887
  //#endregion
2710
2888
  //#region src/components/publish-modal/PublishModal.css.ts
2711
2889
  var buttonGroup = "PublishModal_buttonGroup__m8gxhre";
2712
- var charCount = "PublishModal_charCount__m8gxhr11";
2713
- var content$1 = "PublishModal_content__m8gxhr2";
2714
- var description$1 = "PublishModal_description__m8gxhr4";
2890
+ var charCount$1 = "PublishModal_charCount__m8gxhr11";
2891
+ var content$2 = "PublishModal_content__m8gxhr2";
2892
+ var description$2 = "PublishModal_description__m8gxhr4";
2715
2893
  var dialogBodyTwoColumn = "PublishModal_dialogBodyTwoColumn__m8gxhru";
2716
2894
  var dialogContent = "PublishModal_dialogContent__m8gxhrr";
2717
2895
  var dialogFooter = "PublishModal_dialogFooter__m8gxhrw";
@@ -2719,30 +2897,30 @@ var dialogHeader = "PublishModal_dialogHeader__m8gxhrs";
2719
2897
  var dialogOverlay = "PublishModal_dialogOverlay__m8gxhrq";
2720
2898
  var dialogRightColumn = "PublishModal_dialogRightColumn__m8gxhrv";
2721
2899
  var editButton = "PublishModal_editButton__m8gxhro";
2722
- var fieldLabel = "PublishModal_fieldLabel__m8gxhr10";
2900
+ var fieldLabel$1 = "PublishModal_fieldLabel__m8gxhr10";
2723
2901
  var flickeringGrid = "PublishModal_flickeringGrid__m8gxhri";
2724
2902
  var leftColumn = "PublishModal_leftColumn__m8gxhr8";
2725
2903
  var maskLayer = "PublishModal_maskLayer__m8gxhrj";
2726
2904
  var metadataFields = "PublishModal_metadataFields__m8gxhra";
2727
- var overlay$1 = "PublishModal_overlay__m8gxhr1";
2905
+ var overlay$2 = "PublishModal_overlay__m8gxhr1";
2728
2906
  var placeholderContent = "PublishModal_placeholderContent__m8gxhrk";
2729
2907
  var placeholderIcon = "PublishModal_placeholderIcon__m8gxhrn";
2730
2908
  var previewArea = "PublishModal_previewArea__m8gxhrh";
2731
2909
  var previewContainer = "PublishModal_previewContainer__m8gxhrg";
2732
- var previewImage = "PublishModal_previewImage__m8gxhrm";
2910
+ var previewImage$1 = "PublishModal_previewImage__m8gxhrm";
2733
2911
  var previewImageWrapper = "PublishModal_previewImageWrapper__m8gxhrl";
2734
2912
  var rightColumn = "PublishModal_rightColumn__m8gxhr9";
2735
2913
  var section$1 = "PublishModal_section__m8gxhr6";
2736
- var spinner = "PublishModal_spinner__m8gxhr1e";
2914
+ var spinner$1 = "PublishModal_spinner__m8gxhr1e";
2737
2915
  var storageCostLabel = "PublishModal_storageCostLabel__m8gxhr1a";
2738
2916
  var storageCostSection = "PublishModal_storageCostSection__m8gxhr18";
2739
2917
  var storageCostSummary = "PublishModal_storageCostSummary__m8gxhr19";
2740
2918
  var storageCostValue = "PublishModal_storageCostValue__m8gxhr1b";
2741
2919
  var storageDetailsBox = "PublishModal_storageDetailsBox__m8gxhr1d";
2742
- var title$1 = "PublishModal_title__m8gxhr3";
2920
+ var title$2 = "PublishModal_title__m8gxhr3";
2743
2921
  var twoColumnSection = "PublishModal_twoColumnSection__m8gxhr7";
2744
2922
  var uploadAreaSquare = "PublishModal_uploadAreaSquare__m8gxhry";
2745
- var uploadPlaceholder = "PublishModal_uploadPlaceholder__m8gxhrz";
2923
+ var uploadPlaceholder$1 = "PublishModal_uploadPlaceholder__m8gxhrz";
2746
2924
 
2747
2925
  //#endregion
2748
2926
  //#region src/components/publish-modal/PublishModal.tsx
@@ -2761,8 +2939,8 @@ const PublishModal = ({ siteId, assets, onDeploy, onSaveMetadata, onExtendBlobs,
2761
2939
  const epochs = useStore(siteMetadataStore.epochs);
2762
2940
  const isDirty = useStore(siteMetadataStore.isDirty);
2763
2941
  const isLoading = useStore(siteMetadataStore.loading);
2764
- const title$5 = useStore(siteMetadataStore.title);
2765
- const description$5 = useStore(siteMetadataStore.description);
2942
+ const title$6 = useStore(siteMetadataStore.title);
2943
+ const description$6 = useStore(siteMetadataStore.description);
2766
2944
  const { epochDurationMs, getExpirationDate } = useEpochDuration(walrusClient);
2767
2945
  useEffect(() => {
2768
2946
  if (siteId && epochs && previousEpochs === 0) setPreviousEpochs(epochs);
@@ -2852,15 +3030,15 @@ const PublishModal = ({ siteId, assets, onDeploy, onSaveMetadata, onExtendBlobs,
2852
3030
  return /* @__PURE__ */ jsxs(Dialog.Root, {
2853
3031
  open: isOpen,
2854
3032
  onOpenChange: sitePublishingStore.closePublishDialog,
2855
- children: [/* @__PURE__ */ jsxs(Dialog.Portal, { children: [/* @__PURE__ */ jsx(Dialog.Overlay, { className: overlay$1 }), /* @__PURE__ */ jsxs(Dialog.Content, {
2856
- className: content$1,
3033
+ children: [/* @__PURE__ */ jsxs(Dialog.Portal, { children: [/* @__PURE__ */ jsx(Dialog.Overlay, { className: overlay$2 }), /* @__PURE__ */ jsxs(Dialog.Content, {
3034
+ className: content$2,
2857
3035
  children: [
2858
3036
  /* @__PURE__ */ jsx(Dialog.Title, {
2859
- className: title$1,
3037
+ className: title$2,
2860
3038
  children: siteId ? "Edit Site" : "Publish New Site"
2861
3039
  }),
2862
3040
  /* @__PURE__ */ jsx(Dialog.Description, {
2863
- className: description$1,
3041
+ className: description$2,
2864
3042
  children: "Make your project live in the Walrus network."
2865
3043
  }),
2866
3044
  /* @__PURE__ */ jsx(Stepper, {
@@ -2882,7 +3060,7 @@ const PublishModal = ({ siteId, assets, onDeploy, onSaveMetadata, onExtendBlobs,
2882
3060
  /* @__PURE__ */ jsx("img", {
2883
3061
  src: imageDisplayUrl,
2884
3062
  alt: "Site preview",
2885
- className: previewImage
3063
+ className: previewImage$1
2886
3064
  }),
2887
3065
  /* @__PURE__ */ jsx("div", { style: {
2888
3066
  position: "absolute",
@@ -2890,7 +3068,7 @@ const PublishModal = ({ siteId, assets, onDeploy, onSaveMetadata, onExtendBlobs,
2890
3068
  background: "linear-gradient(to bottom, transparent 0%, transparent 50%, rgba(0, 0, 0, 0.7) 100%)",
2891
3069
  pointerEvents: "none"
2892
3070
  } }),
2893
- (title$5 || description$5) && /* @__PURE__ */ jsxs("div", {
3071
+ (title$6 || description$6) && /* @__PURE__ */ jsxs("div", {
2894
3072
  style: {
2895
3073
  position: "absolute",
2896
3074
  bottom: 0,
@@ -2900,7 +3078,7 @@ const PublishModal = ({ siteId, assets, onDeploy, onSaveMetadata, onExtendBlobs,
2900
3078
  color: "white",
2901
3079
  pointerEvents: "none"
2902
3080
  },
2903
- children: [title$5 && /* @__PURE__ */ jsx("h3", {
3081
+ children: [title$6 && /* @__PURE__ */ jsx("h3", {
2904
3082
  style: {
2905
3083
  fontSize: "0.875rem",
2906
3084
  fontWeight: 600,
@@ -2912,8 +3090,8 @@ const PublishModal = ({ siteId, assets, onDeploy, onSaveMetadata, onExtendBlobs,
2912
3090
  WebkitLineClamp: 2,
2913
3091
  WebkitBoxOrient: "vertical"
2914
3092
  },
2915
- children: title$5
2916
- }), description$5 && /* @__PURE__ */ jsx("p", {
3093
+ children: title$6
3094
+ }), description$6 && /* @__PURE__ */ jsx("p", {
2917
3095
  style: {
2918
3096
  fontSize: "0.75rem",
2919
3097
  opacity: .9,
@@ -2924,7 +3102,7 @@ const PublishModal = ({ siteId, assets, onDeploy, onSaveMetadata, onExtendBlobs,
2924
3102
  WebkitLineClamp: 2,
2925
3103
  WebkitBoxOrient: "vertical"
2926
3104
  },
2927
- children: description$5
3105
+ children: description$6
2928
3106
  })]
2929
3107
  })
2930
3108
  ]
@@ -3134,9 +3312,9 @@ const PublishModal = ({ siteId, assets, onDeploy, onSaveMetadata, onExtendBlobs,
3134
3312
  className: dialogRightColumn,
3135
3313
  children: [
3136
3314
  /* @__PURE__ */ jsxs("fieldset", { children: [/* @__PURE__ */ jsxs("div", {
3137
- className: fieldLabel,
3315
+ className: fieldLabel$1,
3138
3316
  children: [/* @__PURE__ */ jsx(Label, { children: "Title" }), /* @__PURE__ */ jsxs("span", {
3139
- className: charCount,
3317
+ className: charCount$1,
3140
3318
  children: [siteMetadataStore.title.get().length, "/120"]
3141
3319
  })]
3142
3320
  }), /* @__PURE__ */ jsx(Input, {
@@ -3145,9 +3323,9 @@ const PublishModal = ({ siteId, assets, onDeploy, onSaveMetadata, onExtendBlobs,
3145
3323
  placeholder: "Add a title..."
3146
3324
  })] }),
3147
3325
  /* @__PURE__ */ jsxs("fieldset", { children: [/* @__PURE__ */ jsxs("div", {
3148
- className: fieldLabel,
3326
+ className: fieldLabel$1,
3149
3327
  children: [/* @__PURE__ */ jsx(Label, { children: "Description" }), /* @__PURE__ */ jsxs("span", {
3150
- className: charCount,
3328
+ className: charCount$1,
3151
3329
  children: [siteMetadataStore.description.get().length, "/150"]
3152
3330
  })]
3153
3331
  }), /* @__PURE__ */ jsx(Textarea, {
@@ -3169,7 +3347,7 @@ const PublishModal = ({ siteId, assets, onDeploy, onSaveMetadata, onExtendBlobs,
3169
3347
  })] }),
3170
3348
  !siteId && /* @__PURE__ */ jsxs("fieldset", { children: [
3171
3349
  /* @__PURE__ */ jsxs("div", {
3172
- className: fieldLabel,
3350
+ className: fieldLabel$1,
3173
3351
  children: [/* @__PURE__ */ jsx(Label, { children: "Storage Duration" }), epochs > 0 && /* @__PURE__ */ jsxs("span", {
3174
3352
  style: {
3175
3353
  fontSize: "0.75rem",
@@ -3262,7 +3440,7 @@ const PublishModal = ({ siteId, assets, onDeploy, onSaveMetadata, onExtendBlobs,
3262
3440
  disabled: isLoading || isExtending,
3263
3441
  children: isLoading || isExtending ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Loader2, {
3264
3442
  size: 16,
3265
- className: spinner
3443
+ className: spinner$1
3266
3444
  }), isExtending ? "Extending Storage..." : "Saving..."] }) : "Save"
3267
3445
  })]
3268
3446
  })
@@ -3283,7 +3461,7 @@ const PublishModal = ({ siteId, assets, onDeploy, onSaveMetadata, onExtendBlobs,
3283
3461
  disabled: isWorking,
3284
3462
  children: [isWorking && /* @__PURE__ */ jsx(Loader2, {
3285
3463
  size: 16,
3286
- className: spinner
3464
+ className: spinner$1
3287
3465
  }), deployStatusText]
3288
3466
  })
3289
3467
  }), /* @__PURE__ */ jsx(Banner, {
@@ -3385,7 +3563,7 @@ function MetadataEditDialog({ isOpen, onClose }) {
3385
3563
  className: dialogBodyTwoColumn,
3386
3564
  children: /* @__PURE__ */ jsxs("div", { children: [
3387
3565
  /* @__PURE__ */ jsxs("div", {
3388
- className: fieldLabel,
3566
+ className: fieldLabel$1,
3389
3567
  children: [/* @__PURE__ */ jsx(Label, { children: "Preview Image" }), /* @__PURE__ */ jsx("span", {
3390
3568
  style: {
3391
3569
  fontSize: "0.75rem",
@@ -3454,7 +3632,7 @@ function MetadataEditDialog({ isOpen, onClose }) {
3454
3632
  opacity: isLoading ? .6 : 1
3455
3633
  },
3456
3634
  children: isLoading ? /* @__PURE__ */ jsxs("div", {
3457
- className: uploadPlaceholder,
3635
+ className: uploadPlaceholder$1,
3458
3636
  children: [/* @__PURE__ */ jsx("div", { style: {
3459
3637
  width: "32px",
3460
3638
  height: "32px",
@@ -3481,7 +3659,7 @@ function MetadataEditDialog({ isOpen, onClose }) {
3481
3659
  borderRadius: "0.5rem"
3482
3660
  }
3483
3661
  }) : /* @__PURE__ */ jsxs("div", {
3484
- className: uploadPlaceholder,
3662
+ className: uploadPlaceholder$1,
3485
3663
  children: [
3486
3664
  /* @__PURE__ */ jsx(Upload, {
3487
3665
  size: 32,
@@ -4452,9 +4630,9 @@ var DomainCardSvg_default = DomainCardSvg;
4452
4630
 
4453
4631
  //#endregion
4454
4632
  //#region src/components/suins-modal/SuiNsModal.css.ts
4455
- var body = "SuiNsModal_body__lh8k8k5";
4456
- var content = "SuiNsModal_content__lh8k8k1";
4457
- var description = "SuiNsModal_description__lh8k8k4";
4633
+ var body$1 = "SuiNsModal_body__lh8k8k5";
4634
+ var content$1 = "SuiNsModal_content__lh8k8k1";
4635
+ var description$1 = "SuiNsModal_description__lh8k8k4";
4458
4636
  var domainCard = "SuiNsModal_domainCard__lh8k8kb";
4459
4637
  var domainCardBg = "SuiNsModal_domainCardBg__lh8k8kc";
4460
4638
  var domainCardGrid = "SuiNsModal_domainCardGrid__lh8k8ka";
@@ -4462,13 +4640,13 @@ var domainExpiry = "SuiNsModal_domainExpiry__lh8k8ke";
4462
4640
  var domainItem = "SuiNsModal_domainItem__lh8k8k9";
4463
4641
  var domainList = "SuiNsModal_domainList__lh8k8k8";
4464
4642
  var domainName = "SuiNsModal_domainName__lh8k8kd";
4465
- var header = "SuiNsModal_header__lh8k8k2";
4643
+ var header$1 = "SuiNsModal_header__lh8k8k2";
4466
4644
  var link = "SuiNsModal_link__lh8k8kg";
4467
4645
  var loadingSpinner = "SuiNsModal_loadingSpinner__lh8k8kh";
4468
- var overlay = "SuiNsModal_overlay__lh8k8k0";
4646
+ var overlay$1 = "SuiNsModal_overlay__lh8k8k0";
4469
4647
  var section = "SuiNsModal_section__lh8k8k6";
4470
4648
  var sectionTitle = "SuiNsModal_sectionTitle__lh8k8k7";
4471
- var title = "SuiNsModal_title__lh8k8k3";
4649
+ var title$1 = "SuiNsModal_title__lh8k8k3";
4472
4650
 
4473
4651
  //#endregion
4474
4652
  //#region src/components/suins-modal/RegisterSuiNsDialog.tsx
@@ -4499,13 +4677,13 @@ const RegisterSuiNsDialog = ({ isOpen, onClose, onRegistered, currentAccount, cl
4499
4677
  open: isOpen,
4500
4678
  onOpenChange: (open) => !open && handleClose(),
4501
4679
  children: /* @__PURE__ */ jsxs(Dialog.Portal, { children: [/* @__PURE__ */ jsx(Dialog.Overlay, {
4502
- className: overlay,
4680
+ className: overlay$1,
4503
4681
  style: {
4504
4682
  zIndex: 51,
4505
4683
  backgroundColor: "rgba(0, 0, 0, 0.7)"
4506
4684
  }
4507
4685
  }), /* @__PURE__ */ jsxs(Dialog.Content, {
4508
- className: content,
4686
+ className: content$1,
4509
4687
  style: {
4510
4688
  maxWidth: "32rem",
4511
4689
  zIndex: 52
@@ -4545,14 +4723,14 @@ const RegisterSuiNsDialog = ({ isOpen, onClose, onRegistered, currentAccount, cl
4545
4723
  })
4546
4724
  }),
4547
4725
  /* @__PURE__ */ jsxs("div", {
4548
- className: header,
4726
+ className: header$1,
4549
4727
  children: [
4550
4728
  /* @__PURE__ */ jsx(Dialog.Title, {
4551
- className: title,
4729
+ className: title$1,
4552
4730
  children: "Register SuiNS Domain"
4553
4731
  }),
4554
4732
  /* @__PURE__ */ jsx(Dialog.Description, {
4555
- className: description,
4733
+ className: description$1,
4556
4734
  children: "Search and register a new .sui domain name"
4557
4735
  }),
4558
4736
  /* @__PURE__ */ jsx(Dialog.Close, {
@@ -4583,7 +4761,7 @@ const RegisterSuiNsDialog = ({ isOpen, onClose, onRegistered, currentAccount, cl
4583
4761
  ]
4584
4762
  }),
4585
4763
  /* @__PURE__ */ jsxs("div", {
4586
- className: body,
4764
+ className: body$1,
4587
4765
  children: [
4588
4766
  /* @__PURE__ */ jsxs("div", {
4589
4767
  style: { marginBottom: "1rem" },
@@ -4959,8 +5137,8 @@ const SuiNsModal = ({ siteId, onAssociateDomain, currentAccount, portalDomain, p
4959
5137
  return /* @__PURE__ */ jsxs(Dialog.Root, {
4960
5138
  open: isOpen,
4961
5139
  onOpenChange: isDomainDialogOpen.set,
4962
- children: [/* @__PURE__ */ jsxs(Dialog.Portal, { children: [/* @__PURE__ */ jsx(Dialog.Overlay, { className: overlay }), /* @__PURE__ */ jsxs(Dialog.Content, {
4963
- className: content,
5140
+ children: [/* @__PURE__ */ jsxs(Dialog.Portal, { children: [/* @__PURE__ */ jsx(Dialog.Overlay, { className: overlay$1 }), /* @__PURE__ */ jsxs(Dialog.Content, {
5141
+ className: content$1,
4964
5142
  children: [
4965
5143
  isAssigning && /* @__PURE__ */ jsx("div", {
4966
5144
  style: {
@@ -4996,17 +5174,17 @@ const SuiNsModal = ({ siteId, onAssociateDomain, currentAccount, portalDomain, p
4996
5174
  })
4997
5175
  }),
4998
5176
  /* @__PURE__ */ jsxs("div", {
4999
- className: header,
5177
+ className: header$1,
5000
5178
  children: [/* @__PURE__ */ jsx(Dialog.Title, {
5001
- className: title,
5179
+ className: title$1,
5002
5180
  children: "Customize Domain"
5003
5181
  }), /* @__PURE__ */ jsx(Dialog.Description, {
5004
- className: description,
5182
+ className: description$1,
5005
5183
  children: "Associate your website with a SuiNS domain for easy access"
5006
5184
  })]
5007
5185
  }),
5008
5186
  /* @__PURE__ */ jsxs("div", {
5009
- className: body,
5187
+ className: body$1,
5010
5188
  children: [
5011
5189
  /* @__PURE__ */ jsxs("div", {
5012
5190
  className: section,
@@ -5252,5 +5430,392 @@ const PublishButton = ({ children, siteId, assets, onUpdateSiteMetadata, onAssoc
5252
5430
  var PublishButton_default = PublishButton;
5253
5431
 
5254
5432
  //#endregion
5255
- export { Banner, Button, DeploySteps, DeploymentStatus, FlickeringGrid, Input, Label, PublishButton_default as PublishButton, PublishMenu_default as PublishMenu, PublishModal_default as PublishModal, Stepper, SuiNsModal_default as SuiNsModal, Textarea, isAssigningDomain, isDomainDialogOpen, isExtendTimeDialogOpen, isRegisterSuiNSDomainDialogOpen, siteMetadataStore, sitePublishingStore, useEpochDuration, useSitePublishing, useSuiNsDomainsQuery, useSuiNsRegistration, useTransactionExecutor, useWalrusSiteQuery, useWalrusSitesQuery, useZenFsWorkspace, useZenfsFilesQuery };
5433
+ //#region src/components/update-metadata-modal/UpdateMetadataModal.css.ts
5434
+ var body = "UpdateMetadataModal_body__1b8g8dv7";
5435
+ var charCount = "UpdateMetadataModal_charCount__1b8g8dvb";
5436
+ var closeButton = "UpdateMetadataModal_closeButton__1b8g8dv6";
5437
+ var content = "UpdateMetadataModal_content__1b8g8dv2";
5438
+ var description = "UpdateMetadataModal_description__1b8g8dv5";
5439
+ var errorBanner = "UpdateMetadataModal_errorBanner__1b8g8dvo";
5440
+ var errorText = "UpdateMetadataModal_errorText__1b8g8dvn";
5441
+ var fieldLabel = "UpdateMetadataModal_fieldLabel__1b8g8dva";
5442
+ var footer = "UpdateMetadataModal_footer__1b8g8dv9";
5443
+ var header = "UpdateMetadataModal_header__1b8g8dv3";
5444
+ var imagePreview = "UpdateMetadataModal_imagePreview__1b8g8dvl";
5445
+ var loadingContainer = "UpdateMetadataModal_loadingContainer__1b8g8dv8";
5446
+ var optionalLabel = "UpdateMetadataModal_optionalLabel__1b8g8dvc";
5447
+ var overlay = "UpdateMetadataModal_overlay__1b8g8dv1";
5448
+ var previewImage = "UpdateMetadataModal_previewImage__1b8g8dvj";
5449
+ var spinner = "UpdateMetadataModal_spinner__1b8g8dvq";
5450
+ var title = "UpdateMetadataModal_title__1b8g8dv4";
5451
+ var uploadArea = "UpdateMetadataModal_uploadArea__1b8g8dvg";
5452
+ var uploadHint = "UpdateMetadataModal_uploadHint__1b8g8dvi";
5453
+ var uploadModeButton = "UpdateMetadataModal_uploadModeButton__1b8g8dve";
5454
+ var uploadModeButtonActive = "UpdateMetadataModal_uploadModeButtonActive__1b8g8dvf";
5455
+ var uploadModeToggle = "UpdateMetadataModal_uploadModeToggle__1b8g8dvd";
5456
+ var uploadPlaceholder = "UpdateMetadataModal_uploadPlaceholder__1b8g8dvh";
5457
+ var urlInputContainer = "UpdateMetadataModal_urlInputContainer__1b8g8dvk";
5458
+ var urlInputWrapper = "UpdateMetadataModal_urlInputWrapper__1b8g8dvm";
5459
+ var warningBanner = "UpdateMetadataModal_warningBanner__1b8g8dvp";
5460
+
5461
+ //#endregion
5462
+ //#region src/components/update-metadata-modal/UpdateMetadataModal.tsx
5463
+ /**
5464
+ * UpdateMetadataModal Component
5465
+ *
5466
+ * A modal dialog component for updating metadata (name, description, project URL, preview image)
5467
+ * of an existing Walrus site on the Sui blockchain.
5468
+ *
5469
+ * ## Features
5470
+ * - Updates site name (max 120 chars), description (max 150 chars), project URL, and preview image
5471
+ * - Supports image upload (max 5MB) or URL input
5472
+ * - Validates wallet connection before allowing submission
5473
+ * - Automatically loads current site metadata when opened
5474
+ * - Shows loading states and error messages
5475
+ *
5476
+ * ## Usage
5477
+ *
5478
+ * ```tsx
5479
+ * import { UpdateMetadataModal, isUpdateMetadataModalOpen } from '@cmdoss/walrus-site-builder-react'
5480
+ * import { useStore } from '@nanostores/react'
5481
+ *
5482
+ * function MyComponent() {
5483
+ * const isOpen = useStore(isUpdateMetadataModalOpen)
5484
+ *
5485
+ * return (
5486
+ * <UpdateMetadataModal
5487
+ * siteId="0x123..."
5488
+ * isOpen={isOpen}
5489
+ * onOpenChange={isUpdateMetadataModalOpen.set}
5490
+ * onSuccess={(digest) => console.log('Updated:', digest)}
5491
+ * clients={{ suiClient, queryClient, walrusClient }}
5492
+ * currentAccount={currentAccount}
5493
+ * signAndExecuteTransaction={signAndExecuteTransaction}
5494
+ * />
5495
+ * )
5496
+ * }
5497
+ * ```
5498
+ *
5499
+ * ## State Management
5500
+ *
5501
+ * The modal visibility is typically controlled via the `isUpdateMetadataModalOpen` atom:
5502
+ *
5503
+ * ```tsx
5504
+ * import { isUpdateMetadataModalOpen } from '@cmdoss/walrus-site-builder-react'
5505
+ *
5506
+ * // Open modal
5507
+ * isUpdateMetadataModalOpen.set(true)
5508
+ *
5509
+ * // Close modal
5510
+ * isUpdateMetadataModalOpen.set(false)
5511
+ * ```
5512
+ *
5513
+ * @see {@link useUpdateSiteMetadata} - The hook used internally for metadata updates
5514
+ * @see {@link useWalrusSiteQuery} - Used to fetch current site data
5515
+ */
5516
+ const UpdateMetadataModal = ({ siteId, isOpen, onOpenChange, onSuccess, onError, clients: { suiClient, queryClient, walrusClient }, currentAccount, signAndExecuteTransaction, sponsorConfig }) => {
5517
+ const [siteName, setSiteName] = useState("");
5518
+ const [description$6, setDescription] = useState("");
5519
+ const [projectUrl, setProjectUrl] = useState("");
5520
+ const [imageUrl, setImageUrl] = useState("");
5521
+ const [uploadMode, setUploadMode] = useState("url");
5522
+ const [urlInput, setUrlInput] = useState("");
5523
+ const [urlError, setUrlError] = useState("");
5524
+ const [fileSizeError, setFileSizeError] = useState("");
5525
+ const fileInputRef = useRef(null);
5526
+ const MAX_FILE_SIZE = 5 * 1024 * 1024;
5527
+ const { data: siteData, isLoading: isLoadingSite } = useWalrusSiteQuery(siteId, {
5528
+ suiClient,
5529
+ queryClient
5530
+ });
5531
+ const { updateSiteMetadata, isUpdating, error } = useUpdateSiteMetadata({
5532
+ siteId,
5533
+ clients: {
5534
+ suiClient,
5535
+ queryClient,
5536
+ walrusClient
5537
+ },
5538
+ currentAccount,
5539
+ signAndExecuteTransaction,
5540
+ sponsorConfig
5541
+ });
5542
+ const isSdkReady = !!currentAccount && !!suiClient && !!walrusClient;
5543
+ useEffect(() => {
5544
+ if (siteData && isOpen) {
5545
+ setSiteName(siteData.name || "");
5546
+ setDescription(siteData.description || "");
5547
+ setProjectUrl(siteData.project_url || "");
5548
+ setImageUrl(siteData.image_url || "");
5549
+ setUrlInput(siteData.image_url || "");
5550
+ }
5551
+ }, [siteData, isOpen]);
5552
+ useEffect(() => {
5553
+ if (!isOpen) {
5554
+ setUrlError("");
5555
+ setFileSizeError("");
5556
+ setUploadMode("url");
5557
+ }
5558
+ }, [isOpen]);
5559
+ const handleImageChange = (e) => {
5560
+ const file = e.target.files?.[0];
5561
+ if (!file) return;
5562
+ if (file.size > MAX_FILE_SIZE) {
5563
+ setFileSizeError(`File size exceeds 5MB limit (${(file.size / 1024 / 1024).toFixed(2)}MB)`);
5564
+ e.target.value = "";
5565
+ return;
5566
+ }
5567
+ setFileSizeError("");
5568
+ const reader = new FileReader();
5569
+ reader.onload = (e$1) => {
5570
+ const result = e$1.target?.result;
5571
+ if (typeof result === "string") setImageUrl(result);
5572
+ };
5573
+ reader.readAsDataURL(file);
5574
+ };
5575
+ const handleUrlSubmit = () => {
5576
+ if (!urlInput.trim()) {
5577
+ setUrlError("Please enter a valid URL");
5578
+ return;
5579
+ }
5580
+ try {
5581
+ new URL(urlInput);
5582
+ setImageUrl(urlInput);
5583
+ setUrlError("");
5584
+ } catch {
5585
+ setUrlError("Please enter a valid URL");
5586
+ }
5587
+ };
5588
+ const handleSubmit = async () => {
5589
+ if (!isSdkReady) {
5590
+ onError?.(/* @__PURE__ */ new Error("Wallet not connected. Please connect your wallet first."));
5591
+ return;
5592
+ }
5593
+ try {
5594
+ const digest = await updateSiteMetadata({
5595
+ siteName,
5596
+ metadata: {
5597
+ description: description$6 || void 0,
5598
+ project_url: projectUrl || void 0,
5599
+ image_url: imageUrl || void 0
5600
+ }
5601
+ });
5602
+ onSuccess?.(digest);
5603
+ onOpenChange(false);
5604
+ } catch (err) {
5605
+ const error$1 = err instanceof Error ? err : /* @__PURE__ */ new Error("Unknown error");
5606
+ onError?.(error$1);
5607
+ }
5608
+ };
5609
+ const hasChanges = siteName !== (siteData?.name || "") || description$6 !== (siteData?.description || "") || projectUrl !== (siteData?.project_url || "") || imageUrl !== (siteData?.image_url || "");
5610
+ const isLoading = isLoadingSite || isUpdating;
5611
+ return /* @__PURE__ */ jsx(Dialog.Root, {
5612
+ open: isOpen,
5613
+ onOpenChange,
5614
+ children: /* @__PURE__ */ jsxs(Dialog.Portal, { children: [/* @__PURE__ */ jsx(Dialog.Overlay, { className: overlay }), /* @__PURE__ */ jsxs(Dialog.Content, {
5615
+ className: content,
5616
+ children: [
5617
+ /* @__PURE__ */ jsxs("div", {
5618
+ className: header,
5619
+ children: [
5620
+ /* @__PURE__ */ jsx(Dialog.Title, {
5621
+ className: title,
5622
+ children: "Update Site Metadata"
5623
+ }),
5624
+ /* @__PURE__ */ jsx(Dialog.Description, {
5625
+ className: description,
5626
+ children: "Update the metadata for your site"
5627
+ }),
5628
+ /* @__PURE__ */ jsx(Dialog.Close, {
5629
+ asChild: true,
5630
+ children: /* @__PURE__ */ jsx("button", {
5631
+ type: "button",
5632
+ className: closeButton,
5633
+ children: /* @__PURE__ */ jsx(X, { size: 20 })
5634
+ })
5635
+ })
5636
+ ]
5637
+ }),
5638
+ isLoadingSite ? /* @__PURE__ */ jsxs("div", {
5639
+ className: loadingContainer,
5640
+ children: [/* @__PURE__ */ jsx(Loader2, {
5641
+ size: 24,
5642
+ className: spinner
5643
+ }), /* @__PURE__ */ jsx("p", { children: "Loading site data..." })]
5644
+ }) : /* @__PURE__ */ jsxs("div", {
5645
+ className: body,
5646
+ children: [
5647
+ /* @__PURE__ */ jsxs("fieldset", { children: [
5648
+ /* @__PURE__ */ jsxs("div", {
5649
+ className: fieldLabel,
5650
+ children: [/* @__PURE__ */ jsx(Label, { children: "Preview Image" }), /* @__PURE__ */ jsx("span", {
5651
+ className: optionalLabel,
5652
+ children: "Max 5MB"
5653
+ })]
5654
+ }),
5655
+ /* @__PURE__ */ jsxs("div", {
5656
+ className: uploadModeToggle,
5657
+ children: [/* @__PURE__ */ jsx("button", {
5658
+ type: "button",
5659
+ onClick: () => {
5660
+ setUploadMode("file");
5661
+ setUrlError("");
5662
+ },
5663
+ className: uploadMode === "file" ? uploadModeButtonActive : uploadModeButton,
5664
+ children: "Upload File"
5665
+ }), /* @__PURE__ */ jsx("button", {
5666
+ type: "button",
5667
+ onClick: () => {
5668
+ setUploadMode("url");
5669
+ setFileSizeError("");
5670
+ },
5671
+ className: uploadMode === "url" ? uploadModeButtonActive : uploadModeButton,
5672
+ children: "From URL"
5673
+ })]
5674
+ }),
5675
+ uploadMode === "file" ? /* @__PURE__ */ jsxs(Fragment, { children: [
5676
+ /* @__PURE__ */ jsx("div", {
5677
+ className: uploadArea,
5678
+ onClick: () => !isUpdating && fileInputRef.current?.click(),
5679
+ style: {
5680
+ cursor: isUpdating ? "wait" : "pointer",
5681
+ opacity: isUpdating ? .6 : 1
5682
+ },
5683
+ children: imageUrl ? /* @__PURE__ */ jsx("img", {
5684
+ src: imageUrl,
5685
+ alt: "Preview",
5686
+ className: previewImage
5687
+ }) : /* @__PURE__ */ jsxs("div", {
5688
+ className: uploadPlaceholder,
5689
+ children: [
5690
+ /* @__PURE__ */ jsx(Upload, { size: 32 }),
5691
+ /* @__PURE__ */ jsx("p", { children: "Click to upload" }),
5692
+ /* @__PURE__ */ jsx("p", {
5693
+ className: uploadHint,
5694
+ children: "Square image recommended"
5695
+ })
5696
+ ]
5697
+ })
5698
+ }),
5699
+ /* @__PURE__ */ jsx("input", {
5700
+ ref: fileInputRef,
5701
+ type: "file",
5702
+ accept: "image/*",
5703
+ onChange: handleImageChange,
5704
+ style: { display: "none" }
5705
+ }),
5706
+ fileSizeError && /* @__PURE__ */ jsxs("p", {
5707
+ className: errorText,
5708
+ children: [/* @__PURE__ */ jsx(Info, { size: 14 }), fileSizeError]
5709
+ })
5710
+ ] }) : /* @__PURE__ */ jsxs("div", {
5711
+ className: urlInputContainer,
5712
+ children: [
5713
+ imageUrl && /* @__PURE__ */ jsx("div", {
5714
+ className: imagePreview,
5715
+ children: /* @__PURE__ */ jsx("img", {
5716
+ src: imageUrl,
5717
+ alt: "Preview",
5718
+ className: previewImage
5719
+ })
5720
+ }),
5721
+ /* @__PURE__ */ jsxs("div", {
5722
+ className: urlInputWrapper,
5723
+ children: [/* @__PURE__ */ jsx(Input, {
5724
+ value: urlInput,
5725
+ onChange: (e) => {
5726
+ setUrlInput(e.target.value);
5727
+ setUrlError("");
5728
+ },
5729
+ onKeyDown: (e) => {
5730
+ if (e.key === "Enter") handleUrlSubmit();
5731
+ },
5732
+ placeholder: "https://example.com/image.png",
5733
+ disabled: isUpdating
5734
+ }), /* @__PURE__ */ jsx(Button, {
5735
+ onClick: handleUrlSubmit,
5736
+ disabled: isUpdating,
5737
+ style: { flexShrink: 0 },
5738
+ children: "Apply"
5739
+ })]
5740
+ }),
5741
+ urlError && /* @__PURE__ */ jsxs("p", {
5742
+ className: errorText,
5743
+ children: [/* @__PURE__ */ jsx(Info, { size: 14 }), urlError]
5744
+ })
5745
+ ]
5746
+ })
5747
+ ] }),
5748
+ /* @__PURE__ */ jsxs("fieldset", { children: [/* @__PURE__ */ jsxs("div", {
5749
+ className: fieldLabel,
5750
+ children: [/* @__PURE__ */ jsx(Label, { children: "Site Name" }), /* @__PURE__ */ jsxs("span", {
5751
+ className: charCount,
5752
+ children: [siteName.length, "/120"]
5753
+ })]
5754
+ }), /* @__PURE__ */ jsx(Input, {
5755
+ value: siteName,
5756
+ onChange: (e) => setSiteName(e.target.value.slice(0, 120)),
5757
+ placeholder: "Enter site name...",
5758
+ disabled: isUpdating
5759
+ })] }),
5760
+ /* @__PURE__ */ jsxs("fieldset", { children: [/* @__PURE__ */ jsxs("div", {
5761
+ className: fieldLabel,
5762
+ children: [/* @__PURE__ */ jsx(Label, { children: "Description" }), /* @__PURE__ */ jsxs("span", {
5763
+ className: charCount,
5764
+ children: [description$6.length, "/150"]
5765
+ })]
5766
+ }), /* @__PURE__ */ jsx(Textarea, {
5767
+ value: description$6,
5768
+ onChange: (e) => setDescription(e.target.value.slice(0, 150)),
5769
+ placeholder: "Enter description...",
5770
+ rows: 4,
5771
+ disabled: isUpdating
5772
+ })] }),
5773
+ /* @__PURE__ */ jsxs("fieldset", { children: [/* @__PURE__ */ jsxs(Label, { children: ["Project URL", /* @__PURE__ */ jsx("span", {
5774
+ className: optionalLabel,
5775
+ children: " (Optional)"
5776
+ })] }), /* @__PURE__ */ jsx(Input, {
5777
+ value: projectUrl,
5778
+ onChange: (e) => setProjectUrl(e.target.value),
5779
+ placeholder: "https://github.com/username/project",
5780
+ disabled: isUpdating
5781
+ })] }),
5782
+ !isSdkReady && /* @__PURE__ */ jsxs("div", {
5783
+ className: warningBanner,
5784
+ children: [/* @__PURE__ */ jsx(Info, { size: 16 }), /* @__PURE__ */ jsx("span", { children: "Please connect your wallet to update metadata" })]
5785
+ }),
5786
+ error && /* @__PURE__ */ jsxs("div", {
5787
+ className: errorBanner,
5788
+ children: [/* @__PURE__ */ jsx(Info, { size: 16 }), /* @__PURE__ */ jsxs("span", { children: ["Failed to update metadata: ", error.message] })]
5789
+ })
5790
+ ]
5791
+ }),
5792
+ /* @__PURE__ */ jsxs("div", {
5793
+ className: footer,
5794
+ children: [/* @__PURE__ */ jsx(Button, {
5795
+ variant: "outline",
5796
+ onClick: () => onOpenChange(false),
5797
+ disabled: isUpdating,
5798
+ children: "Cancel"
5799
+ }), /* @__PURE__ */ jsxs(Button, {
5800
+ onClick: handleSubmit,
5801
+ disabled: !hasChanges || isLoading || !isSdkReady,
5802
+ style: {
5803
+ display: "flex",
5804
+ alignItems: "center",
5805
+ gap: "0.5rem"
5806
+ },
5807
+ children: [isUpdating && /* @__PURE__ */ jsx(Loader2, {
5808
+ size: 16,
5809
+ className: spinner
5810
+ }), isUpdating ? "Updating..." : !isSdkReady ? "Connect Wallet" : "Update Metadata"]
5811
+ })]
5812
+ })
5813
+ ]
5814
+ })] })
5815
+ });
5816
+ };
5817
+ var UpdateMetadataModal_default = UpdateMetadataModal;
5818
+
5819
+ //#endregion
5820
+ export { Banner, Button, DeploySteps, DeploymentStatus, FlickeringGrid, Input, Label, PublishButton_default as PublishButton, PublishMenu_default as PublishMenu, PublishModal_default as PublishModal, Stepper, SuiNsModal_default as SuiNsModal, Textarea, UpdateMetadataModal_default as UpdateMetadataModal, isAssigningDomain, isDomainDialogOpen, isExtendTimeDialogOpen, isRegisterSuiNSDomainDialogOpen, isUpdateMetadataModalOpen, siteMetadataStore, sitePublishingStore, useEpochDuration, useSitePublishing, useSuiNsDomainsQuery, useSuiNsRegistration, useTransactionExecutor, useUpdateSiteMetadata, useWalrusSiteQuery, useWalrusSitesQuery, useZenFsWorkspace, useZenfsFilesQuery };
5256
5821
  //# sourceMappingURL=index.js.map