1import{r as t,j as e}from"./vendor-motion-CA1YqSI-.js";import{s as G,C as U,b3 as J,b4 as K,b8 as Z,h as q,L as V,V as v,I as X,B as E,d as c,U as ie,b0 as De,b9 as ze,aM as bs,aj as W,b7 as je,dB as Me,dX as Ns,aH as Ae,W as Ge,X as Xe,Y as ce,Z as he,b as ys,bK as ws,S as vs,P as Ss,a9 as ks,aa as Cs,ab as _s,ac as Es,ad as as}from"./index-CAsjarNH.js";import{D as Rs}from"./DashboardLayout-Bx9IeePE.js";import{S as fe}from"./switch-fB6-J_0M.js";import{S as Je}from"./slider-ByOXi8a1.js";import be from"./database-DdqY31HT.js";import Te from"./download-DYCMa43k.js";import rs from"./file-code-BKXJSmCB.js";import{A as le,b as ne,a as oe}from"./alert-CxkCeqpn.js";import Ps from"./clock-D74tcQH2.js";import we from"./info-BeJEYKx9.js";import{S as Ce}from"./scroll-area-Yf4gziaz.js";import Ke from"./hard-drive-DlkI_0XN.js";import ls from"./git-compare-arrows-DsFaecvD.js";import ms from"./folder-sync-B-fVCywq.js";import _e from"./play-EeXuIMJF.js";import Le from"./pause-Cb0kDBnX.js";import $e from"./rotate-ccw-DuhcPpVs.js";import Is from"./file-image-PXNzVwsG.js";import Ve from"./file-text-BjrCTrAX.js";import Ue from"./shield-BhXickTl.js";import Ms from"./server-dTaOA1cD.js";import As from"./folder-plus-D8zxxUd1.js";import Ts from"./chart-line-CDyMDVb4.js";import"./vendor-charts-DeiE-oVq.js";import"./vendor-pdf-BBBLYw70.js";import"./AppHeader-bPQ-1Sj1.js";import"./index-Bld3dpmC.js";import"./authPasswordReset-BgMWz8i7.js";import"./circle-alert-CKMHzB01.js";import"./external-link-DmZvQgPN.js";import"./BrandLogo-BUMSbVI7.js";import"./useOrganizationCredits-BDkTnsiO.js";
1import"./useMarketingSolutionPages-Bb02qdJc.js";import"./shield-check-C4jHCW7j.js";import"./globe-DrdQD8tE.js";import"./layers-CsHVCt3b.js";import"./book-open-BK2Z3OAa.js";import"./OrgBreadcrumb-DxDMdXK-.js";import"./useOnboardingStoreReveal-t_OwkLR8.js";import"./useOnboardingImports-CxYt5jI-.js";import"./onboardingStorePreview-BPQTMSv4.js";import"./OnboardingStoreReadyChip-BJutcceP.js";function Ls(){const[m,u]=t.useState(""),[y,f]=t.useState(""),[C,j]=t.useState(!1),[P,R]=t.useState(!1);t.useEffect(()=>{(async()=>{j(!0);const{data:n}=await G.from("settings").select("key, value").in("key",["ga4_measurement_id","gtm_container_id"]),h=(n||[]).reduce((S,D)=>(S[D.key]=D.value||"",S),{});u(h.ga4_measurement_id||""),f(h.gtm_container_id||""),j(!1)})()},[]);const z=async()=>{R(!0);try{const n=[{key:"ga4_measurement_id",value:m.trim()},{key:"gtm_container_id",value:y.trim()}];for(const h of n){const{error:S}=await G.from("settings").upsert(h,{onConflict:"key"});if(S)throw S}c.success("Analytics settings saved. Refresh to apply.")}catch(n){c.error(n?.message||"Failed to save")}finally{R(!1)}};return e.jsxs(U,{children:[e.jsxs(J,{children:[e.jsx(K,{children:"Analytics Forwarding"}),e.jsx(Z,{children:"Forward platform analytics events to Google Analytics 4 or Google Tag Manager. Organisations and stores can override these IDs from their own settings. Resolution order: store â organisation â platform."})]}),e.jsx(q,{className:"space-y-4",children:C?e.jsx(V,{className:"h-4 w-4 animate-spin"}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{htmlFor:"ga4",children:"GA4 Measurement ID"}),e.jsx(X,{id:"ga4",placeholder:"G-XXXXXXXXXX",value:m,onChange:n=>u(n.target.value)}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Find this in your GA4 property under Admin â Data Streams â Web."})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{htmlFor:"gtm",children:"GTM Container ID (optional)"}),e.jsx(X,{id:"gtm",placeholder:"GTM-XXXXXXX",value:y,onChange:n=>f(n.target.value)}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Pushes the same events to a GTM dataLayer for tag-based routing."})]}),e.jsxs("div",{className:"rounded-md border bg-muted/30 p-3 text-xs space-y-1",children:[e.jsx("p",{className:"font-medium",children:"Custom dimensions sent with events:"}),e.jsxs("p",{className:"text-muted-foreground",children:[e.jsx("code",{children:"store_id"}),", ",e.jsx("code",{children:"org_id"}),", ",e.jsx("code",{children:"ai_function"}),",",e.jsx("code",{children:" device_category"}),", ",e.jsx("code",{children:"is_authenticated"}),", ",e.jsx("code",{children:"page_path"}),",",e.jsx("code",{children:" trace_id"}),", ",e.jsx("code",{children:"session_id"}),". Register these in GA4 â Admin â Custom definitions to filter reports by them."]})]}),e.jsxs(E,{onClick:z,disabled:P,children:[P&&e.jsx(V,{className:"h-4 w-4 mr-2 animate-spin"}),"Save"]})]})})]})}const Re=["20251125093448_remix_migration_from_pg_dump.sql","20251125101532_ccbf9f2c-2538-4290-adda-047bcbe6acf1.sql","20251125102508_a5a9fe1d-82b1-4486-a88d-a4ab90b46e90.sql","20251125112721_74485f35-3a6c-40ce-b10b-61b54ae576f2.sql","20251125113151_88d8c67d-0b58-4746-86da-e475a324fc9f.sql","20251125114111_0a34c21d-44b6-4560-8e7b-b6dd4309e815.sql","20251125121211_9d8bf45b-6b94-45b9-ac14-2bb556f3a3cf.sql","20251125121625_753d1ac3-bcc9-4611-a6ca-1dca982355ea.sql","20251125124401_a5e8d81d-0cf9-4d8a-9afb-9885ea317f3a.sql","20251125124931_64a6f42f-6e02-47c2-a7f6-6c52a3d978e4.sql","20251125174903_484b7844-b9cc-4272-ae1b-8e05e61f208f.sql","20251125201438_02ee8dd4-300d-4214-8e2a-ae2d46764c13.sql","20251126155607_3dd3db58-f979-4e6b-bb24-10177243626e.sql","20251126155645_d39fd339-fffc-4687-99f3-d0686c31a0b3.sql","20251128095745_87950556-c9da-487d-af69-13915345cae0.sql","20251128095819_dd13f5c3-3da1-4c61-87ae-cbe75679de1c.sql","20251128163157_27386dec-1b2a-4de9-bf17-2571a86c6649.sql","20251130205826_7daaf3d4-6cd5-4c52-ba76-6df91b74d328.sql","20251201231259_d562f8a0-6a64-406a-b845-68ee98827eb5.sql","20251205153440_a502acb6-d160-48dc-96f5-d2387115b431.sql","20251205162117_73eb7173-ad65-4665-ac7e-19e734a5ade4.sql","20251205235028_297969bf-95bc-48ca-99a5-7b7c24aa5a76.sql","20251206101808_03d66fc9-6e50-4131-80c5-7f8b9ae75156.sql","20251206104705_b183a948-4600-4338-9867-9a250d08e3a4.sql","20251207134839_5c6b7ca4-9800-4756-9809-00fbd7cdd6b4.sql","20251208101459_08742c56-2ecc-4726-a680-ab252c292a29.sql","20251208123548_2c24424a-ef30-4644-ac5f-38ceea648357.sql","20251208204341_5d0dd992-2a5d-470a-9899-cad00e283f2d.sql","20251208205533_3a4ac03f-b282-4567-afa5-a9d29fd9589a.sql","20251208232950_c701de92
1-6650-44af-8b3f-670b043c6e79.sql","20251209204916_fcc58d7c-d3b9-4550-b23c-59537741cf3b.sql","20251209215117_e4c661b4-a1d6-4c65-a105-a16a2bcab04a.sql","20251209223354_bdfe6d80-94a6-4db6-83d9-7653a1d828e8.sql","20251210082100_651ec270-5615-40e5-bf17-683b8e3d6acf.sql","20251210105741_dbe5f75c-16e5-49f1-a5ae-4987c78ea329.sql","20251212085105_95a23645-75ac-485e-98d3-f87d4780e511.sql","20251212183048_0f6eddcc-bfeb-470d-9f91-53e10a0f9752.sql","20251212185057_5eafda5b-4dfa-4a87-bae0-77b3bcd51f8d.sql","20251212191052_f8550647-d4c1-4584-8fe6-fc6915ddc2e2.sql","20251212231545_619607a3-085b-4817-8a69-14d5d8f66cd0.sql","20251213093328_73f85672-0c54-4d26-ade0-37f888cfa263.sql","20251214090552_08031946-1828-4171-b5aa-67de3e3f3c9d.sql","20251215232942_fdc76cfd-1c62-495d-a347-6515cca884d3.sql","20251216072445_3b80fa7c-30e5-4b6b-98bf-fda453f85efe.sql","20251216134641_9a02af43-f0c2-4e7b-b2b0-259493350ccc.sql","20251216141511_faca5a67-2c04-40fb-95e7-44bbb9a0d61b.sql","20251216172122_8790af35-15d9-4cb2-8e28-b72bd83fe11a.sql","20251217205033_af01c044-1ee9-4af1-a60b-b43ab83239bc.sql","20251217205618_08f9ecef-192a-401a-b1f9-3b728ba3068f.sql","20251217234900_1dd1487e-a99f-4aba-b7e1-da1720a6127e.sql","20251222104107_1e156979-1564-4069-9f98-eb46dd8d48ce.sql","20251222165240_282fed04-cf28-4404-8a52-a9433d4080e2.sql"];function $s(){const[m,u]=t.useState(""),[y,f]=t.useState(!1),[C,j]=t.useState(!1),[P,R]=t.useState(!1),z=async()=>{if(!m.trim()){c.error("Please enter the migration password");return}j(!0);try{const{data:h,error:S}=await G.functions.invoke("database-export",{body:{password:m,includeTruncate:y}});if(S)throw new Error(S.message);if(h.error)throw new Error(h.error);const D=new Blob([h.sql],{type:"text/sql"}),O=URL.createObjectURL(D),o=document.createElement("a");o.href=O,o.download=`Prevamp - Database Export - ${new Date().toISOString().split("T")[0]}.sql`,document.body.appendChild(o),o.click(),document.body.removeChild(o),URL.revokeObjectURL(O),c.success(`Export complete: ${h.stats.tables} tables, ${h.stats.totalRows.toLocaleString()} rows`),u("")}catch(h){const S=h instanceof Error?h.message:"Export failed";c.error(S)}finally{j(!1)}},n=async()=>{R(!0);try{const h=[];h.push("-- Schema Migrations Export"),h.push(`-- Generated: ${new Date().toISOString()}`),h.push(`-- Total migrations: ${Re.length}`),h.push("");for(const p of Re)try{const k=await fetch(`/supabase/migrations/${p}`);if(k.ok){const w=await k.text();h.push("-- ============================================"),h.push(`-- Migration: ${p}`),h.push("-- ============================================"),h.push(w),h.push("")}}catch(k){console.warn(`Could not fetch migration ${p}:`,k)}const S=h.join(` 2`),D=new Blob([S],{type:"text/sql"}),O=URL.createObjectURL(D),o=document.createElement("a");o.href=O,o.download=`Prevamp - Schema Migrations - ${new Date().toISOString().split("T")[0]}.sql`,document.body.appendChild(o),o.click(),document.body.removeChild(o),URL.revokeObjectURL(O),c.success(`Schema export complete: ${Re.length} migration files`)}catch(h){const S=h instanceof Error?h.message:"Schema export failed";c.error(S)}finally{R(!1)}};return e.jsxs("div",{className:"space-y-6",children:[e.jsxs(U,{children:[e.jsxs(J,{children:[e.jsxs(K,{className:"flex items-center gap-2",children:[e.jsx(be,{className:"h-5 w-5"}),"Database Data Export"]}),e.jsx(Z,{children:"Export all database data as SQL INSERT statements for migration or backup"})]}),e.jsxs(q,{className:"space-y-6",children:[e.jsx(U,{className:"bg-amber-500/10 border-amber-500/20",children:e.jsx(q,{className:"pt-4",children:e.jsxs("div",{className:"flex gap-3",children:[e.jsx(ie,{className:"h-5 w-5 text-amber-500 shrink-0 mt-0.5"}),e.jsxs("div",{className:"text-sm",children:[e.jsx("p",{className:"font-medium text-amber-600 dark:text-amber-400",children:"Security Notice"}),e.jsx("p",{className:"text-muted-foreground mt-1",children:"This export contains all database data including sensitive information. Keep the exported file secure and delete it after use."})]})]})})}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{htmlFor:"export-password",children:"Migration Password"}),e.jsx(X,{id:"export-password",type:"password",value:m,onChange:h=>u(h.target.value),placeholder:"Enter DATA_MIGRATION_PASSWORD",disabled:C}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Enter the DATA_MIGRATION_PASSWORD secret to authorise the export"})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(v,{htmlFor:"include-truncate",children:"Include TRUNCATE Statements"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Add TRUNCATE before INSERTs to clear existing data on import"})]}),e.jsx(fe,{id:"include-truncate",checked:y,onCheckedChange:f,disabled:C})]}),e.jsx(E,{onClick:z,disabled:C||!m.trim(),className:"w-full sm:w-auto",children:C?e.jsxs(e.Fragment,{children:[e.jsx(V,{className:"mr-2 h-4 w-4 animate-spin"}),"Exporting..."]}):e.jsxs(e.Fragment,{children:[e.jsx(Te,{className:"mr-2 h-4 w-4"}),"Export Database Data"]})}),e.jsxs("div",{className:"text-sm text-muted-foreground space-y-2 pt-4 border-t",children:[e.jsx("p",{className:"font-medium",children:"Export includes:"}),e.jsxs("ul",{className:"list-disc list-inside space-y-1 ml-2",children:[e.jsx("li",{children:"All public tables in dependency order"}),e.jsx("li",{children:"SQL INSERT statements with ON CONFLICT DO NOTHING"}),e.jsx("li",{children:"Trigger disabling wrapper for safe import"}),e.jsx("li",{children:"Proper escaping for strings, arrays, JSON, and special values"})]})]})]})]}),e.jsxs(U,{children:[e.jsxs(J,{children:[e.jsxs(K,{className:"flex items-center gap-2",children:[e.jsx(rs,{className:"h-5 w-5"}),"Schema Migrations Export"]}),e.jsx(Z,{children:"Export all schema migration files as a combined SQL file"})]}),e.jsxs(q,{className:"space-y-6",children:[e.jsx("div",{className:"text-sm text-muted-foreground",children:e.jsxs("p",{children:["Downloads all ",Re.length," schema migration files comb
2ined into a single SQL file. This contains the DDL statements (CREATE TABLE, ALTER TABLE, etc.) that define the database structure."]})}),e.jsx(E,{onClick:n,disabled:P,variant:"outline",className:"w-full sm:w-auto",children:P?e.jsxs(e.Fragment,{children:[e.jsx(V,{className:"mr-2 h-4 w-4 animate-spin"}),"Exporting Schema..."]}):e.jsxs(e.Fragment,{children:[e.jsx(rs,{className:"mr-2 h-4 w-4"}),"Export Schema Migrations"]})}),e.jsxs("div",{className:"text-sm text-muted-foreground space-y-2 pt-4 border-t",children:[e.jsx("p",{className:"font-medium",children:"Schema export includes:"}),e.jsxs("ul",{className:"list-disc list-inside space-y-1 ml-2",children:[e.jsx("li",{children:"All migration files in chronological order"}),e.jsx("li",{children:"Table definitions, indexes, and constraints"}),e.jsx("li",{children:"RLS policies and security configurations"}),e.jsx("li",{children:"Database functions and triggers"})]})]})]})]})]})}function Ds(){const[m,u]=t.useState(""),[y,f]=t.useState(!1),[C,j]=t.useState(null),P=t.useRef(null),[R,z]=t.useState(""),[n,h]=t.useState(!1),S=o=>{const p=o.target.files?.[0];if(p){if(!p.name.endsWith(".json")){c.error("Please select a JSON file");return}j(p)}},D=async()=>{if(!m.trim()){c.error("Please enter the migration password");return}if(!C){c.error("Please select a storage export file");return}f(!0);try{const o=await C.text(),k=JSON.parse(o).data;if(!k||!k.buckets&&!k.files)throw new Error("Invalid export file format. Missing buckets or files data.");if(k.expiresAt&&new Date(k.expiresAt)<new Date)throw new Error("This export has expired. Signed URLs are no longer valid. Please generate a new export from the source project.");const{data:w,error:g}=await G.functions.invoke("storage-import",{body:{password:m,data:k}});if(g)throw new Error(g.message);if(w.error)throw new Error(w.error);const i=w.results,x=[];i.bucketsCreated>0&&x.push(`${i.bucketsCreated} buckets created`),i.bucketsSkipped>0&&x.push(`${i.bucketsSkipped} buckets skipped`),i.filesUploaded>0&&x.push(`${i.filesUploaded} files uploaded`),i.filesSkipped>0&&x.push(`${i.filesSkipped} files skipped`),i.errors.length>0?(console.error("Import errors:",i.errors),c.warning(`Import completed with ${i.errors.length} errors. Check console for details.`,{description:x.join(", ")})):c.success("Storage import complete",{description:x.join(", ")}),u(""),j(null),P.current&&(P.current.value="")}catch(o){const p=o instanceof Error?o.message:"Import failed";c.error(p)}finally{f(!1)}},O=async()=>{if(!R.trim()){c.error("Please enter the migration password");return}h(!0);try{const{data:o,error:p}=await G.functions.invoke("storage-export",{body:{password:R}});if(p)throw new Error(p.message);if(o.error)throw new Error(o.error);const k=o.data,w=k.skippedFiles||[],g=new Blob([JSON.stringify(o,null,2)],{type:"application/json"}),i=URL.createObjectURL(g),x=document.createElement("a");x.href=i,x.download=`Prevamp - Storage Export - ${new Date().toISOString().split("T")[0]}.json`,document.body.appendChild(x),x.click(),document.body.removeChild(x),URL.revokeObjectURL(i);const F=[`${k.buckets.length} buckets`,`${k.files.length} files with signed URLs`];w.length>0?(console.warn("Skipped files:",w),c.warning(`Export completed with ${w.length} skipped files`,{description:F.join(", ")})):c.success("Storage export complete",{description:F.join(", ")})}catch(o){const p=o instanceof Error?o.message:"Export failed";c.error(p)}finally{h(!1)}};return e.jsxs("div",{className:"space-y-6",children:[e.jsxs(U,{children:[e.jsxs(J,{children:[e.jsxs(K,{className:"flex items-center gap-2",children:[e.jsx(Te,{className:"h-5 w-5"}),"Storage Export"]}),e.jsx(Z,{children:"Export all storage buckets and files with signed URLs for migration"})]}),e.jsxs(q,{className:"space-y-6",children:[e.jsxs(le,{children:[e.jsx(Ps,{className:"h-4 w-4"}),e.jsx(ne,{children:"Signed URLs Valid for 24 Hours"}),e.jsx(oe,{children:"The export contains signed URLs that allow the destination project to download files directly. Import must be completed within 24 hours of export."})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{htmlFor:"export-password",children:"Migration Password"}),e.jsx(X,{id:"export-password",type:"password",value:R,onChange:o=>z(o.target.value),placeholder:"Enter DATA_MIGRATION_PASSWORD",disabled:n})]}),e.jsx(E,{onClick:O,disabled:n||!R.trim(),className:"w-full sm:w-auto",children:n?e.jsxs(e.Fragment,{children:[e.jsx(V,{className:"mr-2 h-4 w-4 animate-spin"}),"Exporting..."]}):e.jsxs(e.Fragment,{children:[e.jsx(Te,{className:"mr-2 h-4 w-4"}),"Export Storage"]})})]})]}),e.jsx(De,{}),e.jsxs(U,{children:[e.jsxs(J,{children:[e.jsxs(K,{className:"flex items-center gap-2",children:[e.jsx(ze,{className:"h-5 w-5"}),"Storage Import"]}),e.jsx(Z,{children:"Import storage buckets and files from an export file"})]}),e.jsxs(q,{className:"space-y-6",children:[e.jsxs(le,{children:[e.jsx(we,{className:"h-4 w-4"}),e.jsx(ne,{children:"Import Process"}),e.jsx(oe,{children:"Files are downloaded from signed URLs and uploaded to this project. Buckets that already exist will be skipped. Existing files are overwritten."})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{htmlFor:"import-password",children:"Migration Password"}),e.jsx(X,{id:"import-password",type:"password",value:m,onChange:o=>u(o.target.value),placeholder:"Enter DATA_MIGRATION_PASSWORD",disabled:y}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Enter the DATA_MIGRATION_PASSWORD secret to authorise the import"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{htmlFor:"storage-file",children:"Storage Export File"}),e.jsx(X,{ref:P,id:"storage-file",type:"file",accept:".json",onChange:S,disabled:y}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Select a storage-export-*.json file from a previous exp
2ort"}),C&&e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Selected: ",C.name," (",(C.size/1024).toFixed(1)," KB)"]})]}),e.jsx(E,{onClick:D,disabled:y||!m.trim()||!C,className:"w-full sm:w-auto",children:y?e.jsxs(e.Fragment,{children:[e.jsx(V,{className:"mr-2 h-4 w-4 animate-spin"}),"Importing..."]}):e.jsxs(e.Fragment,{children:[e.jsx(ze,{className:"mr-2 h-4 w-4"}),"Import Storage"]})}),e.jsxs("div",{className:"text-sm text-muted-foreground space-y-2 pt-4 border-t",children:[e.jsx("p",{className:"font-medium",children:"Import process:"}),e.jsxs("ol",{className:"list-decimal list-inside space-y-1 ml-2",children:[e.jsx("li",{children:"Creates any missing buckets with their original settings"}),e.jsx("li",{children:"Downloads files from signed URLs"}),e.jsx("li",{children:"Uploads files to their respective buckets"}),e.jsx("li",{children:"Reports any errors encountered during import"})]})]})]})]})]})}function Fs(){const[m,u]=t.useState(""),[y,f]=t.useState(!1),[C,j]=t.useState(null),P=t.useRef(null),[R,z]=t.useState(""),[n,h]=t.useState(!1),S=o=>{const p=o.target.files?.[0];if(p){if(!p.name.endsWith(".json")){c.error("Please select a JSON file");return}j(p)}},D=async()=>{if(!R.trim()){c.error("Please enter the migration password");return}h(!0);try{const{data:o,error:p}=await G.functions.invoke("storage-metadata-export",{body:{password:R}});if(p)throw new Error(p.message);if(o.error)throw new Error(o.error);const k=o.data,w=new Blob([JSON.stringify(o,null,2)],{type:"application/json"}),g=URL.createObjectURL(w),i=document.createElement("a");i.href=g,i.download=`Prevamp - Storage Metadata - ${new Date().toISOString().split("T")[0]}.json`,document.body.appendChild(i),i.click(),document.body.removeChild(i),URL.revokeObjectURL(g),c.success("Storage metadata export complete",{description:`${k.objectCount} object records exported`})}catch(o){const p=o instanceof Error?o.message:"Export failed";c.error(p)}finally{h(!1)}},O=async()=>{if(!m.trim()){c.error("Please enter the migration password");return}if(!C){c.error("Please select a storage metadata export file");return}f(!0);try{const o=await C.text(),k=JSON.parse(o).data;if(!k||!k.objects)throw new Error("Invalid export file format. Missing objects data.");const{data:w,error:g}=await G.functions.invoke("storage-metadata-import",{body:{password:m,data:k}});if(g)throw new Error(g.message);if(w.error)throw new Error(w.error);const i=w.results,x=[];i.objectsUpdated>0&&x.push(`${i.objectsUpdated} updated`),i.objectsSkipped>0&&x.push(`${i.objectsSkipped} skipped`),i.errors.length>0?(console.error("Import errors:",i.errors),c.warning(`Import completed with ${i.errors.length} errors`,{description:x.join(", ")})):c.success("Storage metadata import complete",{description:x.join(", ")}),u(""),j(null),P.current&&(P.current.value="")}catch(o){const p=o instanceof Error?o.message:"Import failed";c.error(p)}finally{f(!1)}};return e.jsxs("div",{className:"space-y-6",children:[e.jsxs(U,{children:[e.jsxs(J,{children:[e.jsxs(K,{className:"flex items-center gap-2",children:[e.jsx(be,{className:"h-5 w-5"}),"Storage Metadata Export"]}),e.jsx(Z,{children:"Export storage.objects table metadata (file records, not actual files)"})]}),e.jsxs(q,{className:"space-y-4",children:[e.jsxs(le,{children:[e.jsx(we,{className:"h-4 w-4"}),e.jsx(ne,{children:"Metadata Only"}),e.jsx(oe,{children:"This exports the storage.objects table records (metadata, timestamps, etc). Use the Storage Import/Export for actual file contents."})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{htmlFor:"export-password-meta",children:"Migration Password"}),e.jsx(X,{id:"export-password-meta",type:"password",value:R,onChange:o=>z(o.target.value),placeholder:"Enter DATA_MIGRATION_PASSWORD",disabled:n})]}),e.jsx(E,{onClick:D,disabled:n||!R.trim(),children:n?e.jsxs(e.Fragment,{children:[e.jsx(V,{className:"h-4 w-4 mr-2 animate-spin"}),"Exporting..."]}):e.jsxs(e.Fragment,{children:[e.jsx(Te,{className:"h-4 w-4 mr-2"}),"Export Storage Metadata"]})})]})]}),e.jsx(De,{}),e.jsxs(U,{children:[e.jsxs(J,{children:[e.jsxs(K,{className:"flex items-center gap-2",children:[e.jsx(be,{className:"h-5 w-5"}),"Storage Metadata Import"]}),e.jsx(Z,{children:"Import storage.objects metadata from an export file"})]}),e.jsxs(q,{className:"space-y-4",children:[e.jsxs(le,{children:[e.jsx(we,{className:"h-4 w-4"}),e.jsx(ne,{children:"Import Order"}),e.jsx(oe,{children:"Import actual files first using Storage Import, then import metadata. Metadata for missing files will be skipped."})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{htmlFor:"import-password-meta",children:"Migration Password"}),e.jsx(X,{id:"import-password-meta",type:"password",value:m,onChange:o=>u(o.target.value),placeholder:"Enter DATA_MIGRATION_PASSWORD",disabled:y})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{htmlFor:"import-file-meta",children:"Storage Metadata Export File"}),e.jsx(X,{id:"import-file-meta",type:"file",accept:".json",onChange:S,ref:P,disabled:y}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Select a storage-metadata-export-*.json file"}),C&&e.jsxs("p",{className:"text-sm text-primary",children:["Selected: ",C.name,"
2(",(C.size/1024).toFixed(1)," KB)"]})]}),e.jsx(E,{onClick:O,disabled:y||!m.trim()||!C,children:y?e.jsxs(e.Fragment,{children:[e.jsx(V,{className:"h-4 w-4 mr-2 animate-spin"}),"Importing..."]}):e.jsxs(e.Fragment,{children:[e.jsx(ze,{className:"h-4 w-4 mr-2"}),"Import Storage Metadata"]})})]})]})]})}const H=["product-images","generation-inputs","gallery-images","brand-products"],Bs=10,We="bucket_migration_state";function Os(m){try{localStorage.setItem(We,JSON.stringify(m))}catch{}}function Us(){try{const m=localStorage.getItem(We);return m?JSON.parse(m):null}catch{return null}}function qs(){try{localStorage.removeItem(We)}catch{}}const us={status:"idle",copied:0,skipped:0,failed:0,totalProcessed:0,currentToken:null,currentPrefix:"",folderQueue:[],startedAt:null};function zs(){const m=Us();if(m){for(const u of H)m[u]?.status==="running"&&(m[u].status="paused");return m}return Object.fromEntries(H.map(u=>[u,{...us}]))}function Gs({password:m}){const[u,y]=t.useState(null),[f,C]=t.useState(!1),[j,P]=t.useState(zs),[R,z]=t.useState([]),[n,h]=t.useState(null),[S,D]=t.useState(!1),[O,o]=t.useState({}),[p,k]=t.useState({}),w=t.useRef({}),g=t.useRef(null);t.useEffect(()=>{Os(j)},[j]),t.useEffect(()=>{g.current?.scrollIntoView({behavior:"smooth"})},[R.length]);const i=t.useCallback(async()=>{C(!0);try{const{data:s,error:a}=await G.functions.invoke("migrate-bucket-to-media",{body:{password:m,action:"preflight"}});if(a)throw new Error(a.message);if(s?.error)throw new Error(s.error);y(s),c.success("Status refreshed")}catch(s){c.error("Preflight failed: "+s.message)}finally{C(!1)}},[m]),x=t.useCallback(async(s,a,_)=>{const{data:I,error:B}=await G.functions.invoke("migrate-bucket-to-media",{body:{password:m,action:"copy-batch",sourceBucket:s,continuationToken:a,batchSize:Bs,prefix:_}});if(B)throw new Error(B.message);if(I?.error)throw new Error(I.error);return I},[m]),F=t.useCallback(async s=>{w.current[s]=!1,P($=>({...$,[s]:{...$[s],status:"running",startedAt:$[s].startedAt||Date.now()}}));let a=j[s],_=a.currentToken,I=a.currentPrefix,B=[...a.folderQueue];try{for(;;){if(w.current[s]){P(T=>({...T,[s]:{...T[s],status:"paused",currentToken:_,currentPrefix:I,folderQueue:B}}));return}const $=await x(s,_,I);if($.folders&&$.folders.length>0&&(B=[...B,...$.folders.filter(T=>!B.includes(T))]),$.items&&$.items.length>0){const T=Date.now(),ke=$.items.map((d,l)=>({...d,timestamp:T+l}));z(d=>[...d,...ke].slice(-500))}const ae=$.copied||0,ge=$.skipped||0,Se=$.failed||0,ye=ae+ge+Se;if(P(T=>({...T,[s]:{...T[s],copied:T[s].copied+ae,skipped:T[s].skipped+ge,failed:T[s].failed+Se,totalProcessed:T[s].totalProcessed+ye,currentToken:$.nextToken,currentPrefix:I,folderQueue:B}})),_=$.nextToken,!$.hasMore||ye===0){if(B.length>0){I=B.shift(),_=null,P(T=>({...T,[s]:{...T[s],currentPrefix:I,currentToken:null,folderQueue:B}}));continue}P(T=>({...T,[s]:{...T[s],status:"complete",folderQueue:[]}})),c.success(`${s} copy complete`);return}await new Promise(T=>setTimeout(T,500))}}catch($){P(ae=>({...ae,[s]:{...ae[s],status:"error"}})),c.error(`${s} error: ${$.message}`)}},[j,x]),Y=t.useCallback(async()=>{for(const s of H)if(j[s].status!=="complete"&&(await F(s),w.current[s]))break},[j,F]),Q=t.useCallback(async()=>{D(!0);try{const{data:s,error:a}=await G.functions.invoke("migrate-bucket-to-media",{body:{password:m,action:"rewrite-urls"}});if(a)throw new Error(a.message);if(s?.error)throw new Error(s.error);h(s.results||[]),c.success(`URL rewrite complete: ${s.totalUpdated} rows updated`)}catch(s){c.error("URL rewrite failed: "+s.message)}finally{D(!1)}},[m]),de=t.useCallback(async s=>{k(a=>({...a,[s]:!0}));try{const{data:a,error:_}=await G.functions.invoke("migrate-bucket-to-media",{body:{password:m,action:"diff",sourceBucket:s}});if(_)throw new Error(_.message);if(a?.error)throw new Error(a.error);o(I=>({...I,[s]:a})),c.success(`Diff complete for ${s}`)}catch(a){c.error(`Diff failed for ${s}: ${a.message}`)}finally{k(a=>({...a,[s]:!1}))}},[m]),me=s=>{w.current[s]=!0},N=()=>{P(Object.fromEntries(H.map(s=>[s,{...us}]))),qs(),z([]),h(null)},ee=H.every(s=>j[s].status==="complete"),se=H.some(s=>j[s].status==="running"),ve=H.reduce((s,a)=>s+j[a].copied,0),ue=H.reduce((s,a)=>s+j[a].skipped,0),Ne=H.reduce((s,a)=>s+j[a].failed,0),pe=H.reduce((s,a)=>s+j[a].totalProcessed,0);return e.jsxs("div",{className:"space-y-6",children:[e.jsxs(U,{children:[e.jsxs(J,{children:[e.jsxs(K,{className:"flex items-center gap-2",children:[e.jsx(Ke,{className:"h-5 w-5"}),"Bucket File Counts"]}),e.jsxs(Z,{children:["Files in each source bucket to be copied to ",e.jsx("code",{className:"text-foreground",children:"media/"})]})]}),e.jsxs(q,{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs(E,{variant:"outline",onClick:i,disabled:f||se,children:[f?e.jsx(V,{className:"h-4 w-4 animate-spin mr-2"}):e.jsx(bs,{className:"h-4 w-4 mr-2"}),"Check Status"]}),u&&e.jsxs("span",{className:"text-sm text-muted-foreground",children:["Total: ",e.jsx("strong",{className:"text-foreground",children:u.totalFiles.toLocaleStr
2ing()})," files"]})]}),u&&e.jsx("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-3",children:H.map(s=>e.jsxs("div",{className:"rounded-md border p-3 space-y-1",children:[e.jsx("p",{className:"text-xs font-mono text-muted-foreground",children:s}),(()=>{const a=u.buckets[s];if(a===void 0)return e.jsx("p",{className:"text-lg font-semibold",children:"â"});if(typeof a=="number")return e.jsx("p",{className:"text-lg font-semibold",children:a<0?e.jsx("span",{className:"text-destructive",children:"Error"}):a.toLocaleString()});const _=(a.media||0)+(a.legacy||0);return e.jsxs("div",{children:[e.jsx("p",{className:"text-lg font-semibold",children:_.toLocaleString()}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:[a.media>0&&e.jsxs("span",{className:"mr-2",children:["media: ",a.media.toLocaleString()]}),a.legacy>0&&e.jsxs("span",{children:["legacy: ",a.legacy.toLocaleString()]})]})]})})(),j[s].status==="complete"&&e.jsxs(W,{variant:"default",className:"bg-green-600 text-xs",children:[e.jsx(je,{className:"h-3 w-3 mr-1"})," Copied"]})]},s))})]})]}),e.jsxs(U,{children:[e.jsxs(J,{children:[e.jsxs(K,{className:"flex items-center gap-2",children:[e.jsx(ls,{className:"h-5 w-5"}),"Storage Diff (Lovable Cloud)"]}),e.jsxs(Z,{children:["Compare files in legacy standalone buckets vs unified ",e.jsx("code",{className:"text-foreground",children:"media/"})," bucket"]})]}),e.jsxs(q,{className:"space-y-4",children:[e.jsx("div",{className:"flex items-center gap-2 flex-wrap",children:H.map(s=>e.jsxs(E,{variant:"outline",size:"sm",onClick:()=>de(s),disabled:!!p[s],children:[p[s]?e.jsx(V,{className:"h-3 w-3 animate-spin mr-1"}):e.jsx(ls,{className:"h-3 w-3 mr-1"}),s]},s))}),Object.entries(O).map(([s,a])=>e.jsxs("div",{className:"rounded-md border p-4 space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("h4",{className:"font-mono text-sm font-semibold",children:s}),e.jsxs("div",{className:"flex gap-3 text-xs text-muted-foreground",children:[e.jsxs("span",{children:["Legacy: ",e.jsx("strong",{className:"text-foreground",children:a.legacyTotal})]}),e.jsxs("span",{children:["Media: ",e.jsx("strong",{className:"text-foreground",children:a.mediaTotal})]})]})]}),e.jsxs("div",{className:"grid grid-cols-3 gap-3",children:[e.jsxs("div",{className:"rounded-md border border-yellow-500/30 bg-yellow-500/5 p-3",children:[e.jsxs("p",{className:"text-xs font-medium text-yellow-600 dark:text-yellow-400 mb-1",children:["Only in Legacy (",a.onlyInLegacyCount,")"]}),a.onlyInLegacyCount===0?e.jsx("p",{className:"text-xs text-muted-foreground",children:"None â all migrated â"}):e.jsx(Ce,{className:"h-40",children:e.jsxs("div",{className:"space-y-0.5",children:[a.onlyInLegacy.map((_,I)=>e.jsx("p",{className:"text-xs font-mono text-yellow-700 dark:text-yellow-300 truncate",title:_,children:_},I)),a.onlyInLegacyCount>500&&e.jsxs("p",{className:"text-xs text-muted-foreground italic",children:["â¦and ",a.onlyInLegacyCount-500," more"]})]})})]}),e.jsxs("div",{className:"rounded-md border border-blue-500/30 bg-blue-500/5 p-3",children:[e.jsxs("p",{className:"text-xs font-medium text-blue-600 dark:text-blue-400 mb-1",children:["Only in Media (",a.onlyInMediaCount,")"]}),a.onlyInMediaCount===0?e.jsx("p",{className:"text-xs text-muted-foreground",children:"None"}):e.jsx(Ce,{className:"h-40",children:e.jsxs("div",{className:"space-y-0.5",children:[a.onlyInMedia.map((_,I)=>e.jsx("p",{className:"text-xs font-mono text-blue-700 dark:text-blue-300 truncate",title:_,children:_},I)),a.onlyInMediaCount>500&&e.jsxs("p",{className:"text-xs text-muted-foreground italic",children:["â¦and ",a.onlyInMediaCount-500," more"]})]})})]}),e.jsxs("div",{className:"rounded-md border border-green-500/30 bg-green-500/5 p-3",children:[e.jsxs("p",{className:"text-xs font-medium text-green-600 dark:text-green-400 mb-1",children:["In Both (",a.inBothCount,")"]}),a.inBothCount===0?e.jsx("p",{className:"text-xs text-muted-foreground",children:"None"}):e.jsx(Ce,{className:"h-40",children:e.jsxs("div",{className:"space-y-0.5",children:[a.inBoth.map((_,I)=>e.jsx("p",{className:"text-xs font-mono text-green-700 dark:text-green-300 truncate",title:_,children:_},I)),a.inBothCount>100&&e.jsxs("p",{className:"text-xs text-muted-foreground italic",children:["â¦and ",a.inBothCount-100," more"]})]})})]})]})]},s))]})]}),e.jsxs(U,{children:[e.jsxs(J,{children:[e.jsxs(K,{className:"flex items-center gap-2",children:[e.jsx(ms,{className:"h-5 w-5"}),"File Copy"]}),e.jsxs(Z,{children:["Copy files from source buckets to ",e.jsxs("code",{className:"text-foreground",children:["media/","{bucket}","/"]})]})]}),e.jsxs(q,{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-3 flex-wrap",children:[e.jsxs(E,{onClick:Y,disabled:se||ee||!u,children:[e.jsx(_e,{className:"h-4 w-4 mr-2"}),"Copy All"]}),se&&e.jsxs(E,{variant:"outline",onClick:()=>
2H.forEach(s=>me(s)),children:[e.jsx(Le,{className:"h-4 w-4 mr-2"}),"Pause All"]}),e.jsxs(E,{variant:"ghost",onClick:N,disabled:se,children:[e.jsx($e,{className:"h-4 w-4 mr-2"}),"Reset"]})]}),e.jsx("div",{className:"space-y-3",children:H.map(s=>{const a=j[s],_=u?.buckets[s]||0,I=_>0?Math.min(100,Math.round(a.totalProcessed/_*100)):0;return e.jsxs("div",{className:"rounded-md border p-3 space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"font-mono text-sm",children:s}),e.jsxs(W,{variant:a.status==="complete"?"default":a.status==="running"?"secondary":a.status==="error"?"destructive":a.status==="paused"?"outline":"secondary",className:a.status==="complete"?"bg-green-600":"",children:[a.status==="running"&&e.jsx(V,{className:"h-3 w-3 animate-spin mr-1"}),a.status]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[(a.status==="idle"||a.status==="error")&&e.jsxs(E,{size:"sm",variant:"outline",onClick:()=>F(s),disabled:se||!u,children:[e.jsx(_e,{className:"h-3 w-3 mr-1"}),"Start"]}),a.status==="paused"&&e.jsxs(E,{size:"sm",variant:"outline",onClick:()=>F(s),disabled:se,children:[e.jsx(_e,{className:"h-3 w-3 mr-1"}),"Resume"]}),a.status==="running"&&e.jsxs(E,{size:"sm",variant:"outline",onClick:()=>me(s),children:[e.jsx(Le,{className:"h-3 w-3 mr-1"}),"Pause"]})]})]}),e.jsx(Me,{value:I,className:"h-1.5"}),e.jsxs("div",{className:"flex gap-4 text-xs text-muted-foreground",children:[e.jsxs("span",{children:["Copied: ",e.jsx("span",{className:"text-green-600 font-medium",children:a.copied})]}),e.jsxs("span",{children:["Skipped: ",e.jsx("span",{className:"text-yellow-600 font-medium",children:a.skipped})]}),e.jsxs("span",{children:["Failed: ",e.jsx("span",{className:"text-red-600 font-medium",children:a.failed})]}),e.jsxs("span",{className:"ml-auto",children:[I,"%"]})]})]},s)})}),pe>0&&e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-3 text-sm pt-2",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-muted-foreground",children:"Total Copied"}),e.jsx("p",{className:"text-lg font-semibold text-green-600",children:ve.toLocaleString()})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-muted-foreground",children:"Total Skipped"}),e.jsx("p",{className:"text-lg font-semibold text-yellow-600",children:ue.toLocaleString()})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-muted-foreground",children:"Total Failed"}),e.jsx("p",{className:"text-lg font-semibold text-red-600",children:Ne.toLocaleString()})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-muted-foreground",children:"Total Processed"}),e.jsx("p",{className:"text-lg font-semibold",children:pe.toLocaleString()})]})]})]})]}),e.jsxs(U,{children:[e.jsxs(J,{children:[e.jsxs(K,{className:"flex items-center gap-2",children:[e.jsx(Ns,{className:"h-5 w-5"}),"Database URL Rewrite"]}),e.jsxs(Z,{children:["Update stored URLs from ",e.jsxs("code",{children:["/object/public/","{bucket}","/"]})," to ",e.jsxs("code",{children:["/object/public/media/","{bucket}","/"]})]})]}),e.jsxs(q,{className:"space-y-4",children:[!ee&&e.jsxs(le,{children:[e.jsx(ie,{className:"h-4 w-4"}),e.jsx(ne,{children:"Copy First"}),e.jsx(oe,{children:"Complete the file copy for all buckets before running the URL rewrite."})]}),e.jsxs(E,{onClick:Q,disabled:S,children:[S?e.jsx(V,{className:"h-4 w-4 animate-spin mr-2"}):e.jsx(be,{className:"h-4 w-4 mr-2"}),"Rewrite Database URLs"]}),n&&e.jsxs("div",{className:"space-y-2",children:[e.jsx(De,{}),e.jsx("div",{className:"rounded-md border overflow-hidden",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b bg-muted/50",children:[e.jsx("th",{className:"text-left p-2 font-medium",children:"Table.Column"}),e.jsx("th",{className:"text-left p-2 font-medium",children:"Bucket"}),e.jsx("th",{className:"text-right p-2 font-medium",children:"Rows Updated"}),e.jsx("th",{className:"text-left p-2 font-medium",children:"Status"})]})}),e.jsx("tbody",{children:n.map((s,a)=>e.jsxs("tr",{className:"border-b last:border-b-0",children:[e.jsxs("td",{className:"p-2 font-mono text-xs",children:[s.table,".",s.column]}),e.jsx("td",{className:"p-2 font-mono text-xs",children:s.bucket}),e.jsx("td",{className:"p-2 text-right",children:s.rowsUpdated}),e.jsx("td",{className:"p-2",children:s.status==="updated"?e.jsxs(W,{variant:"default",className:"bg-green-600 text-xs",children:[e.jsx(je,{className:"h-3 w-3 mr-1"})," Done"]}):e.jsxs(W,{variant:"destructive",className:"text-xs",children:[e.jsx(ie,{className:"h-3 w-3 mr-1"})," ",s.error?.slice(0,60)]})})]},a))})]})})]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(v,{className:"text-sm font-medium",children:"Console"}),R.length>0&&e.jsx(E,{variant:"ghost",size:"sm",className:"h-6 text-xs",onClick:()=>z([]),children:"Clear"})]}),e.jsx(Ce,{className:"h-72 rounded-md border bg-black/90",children:e.jsxs("div",{className:"p-3 space-y-0 text-xs font-mono text-green-400 leading-5",children:[R.length===0?e.jsx("div",{className:"text-green-400/40",children:"Waiting for copy to startâ¦"}):R.map((s,a)=>{const _=new Date(s.timestamp).toLocaleTimeString(),I=s.status==="copied"?"â
":s.status==="failed"?"â":"âï¸",B=s.bytes?` | ${(s.bytes/1024).toFixed(0)}
2KB`:"",$=s.error?` | ERROR: ${s.error}`:"",ae=s.reason?` | ${s.reason}`:"",ge=`[${_}] ${I} ${s.status.toUpperCase().padEnd(7)} ${s.sourcePath} â ${s.destPath} | ${s.durationMs}ms${B}${ae}${$}`;return e.jsx("div",{className:`whitespace-pre-wrap break-all ${s.status==="failed"?"text-red-400":s.status==="skipped"?"text-yellow-400/70":""}`,children:ge},`${s.sourcePath}-${a}`)}),e.jsx("div",{ref:g})]})})]})]})}const ns={totalProcessed:0,migrated:0,skipped:0,errors:0,remaining:null,running:!1,logs:[]};function Xs({password:m}){const[u,y]=t.useState(ns),[f,C]=t.useState(10),[j,P]=t.useState(!0),[R,z]=t.useState(!1),[n,h]=t.useState(null),S=t.useRef(!1),D=t.useRef(null);t.useEffect(()=>{D.current?.scrollIntoView({behavior:"smooth"})},[u.logs.length]);const O=t.useCallback(async()=>{z(!0);try{const{data:g,error:i}=await G.functions.invoke("migrate-generation-log-images",{method:"GET",headers:{"Content-Type":"application/json"},body:JSON.stringify({password:m,dry_run:!0,batch_size:0})}),x=await fetch(`https://oqmvtnzznxnynpfsgtdh.supabase.co/functions/v1/migrate-generation-log-images?password=${encodeURIComponent(m)}&dry_run=true&batch_size=1`,{headers:{Authorization:"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Im9xbXZ0bnp6bnhueW5wZnNndGRoIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjQwNTkwMjUsImV4cCI6MjA3OTYzNTAyNX0.qGINeCOXFf0TgELF_-pkex8MpSKTwmsN1gpai3RqGZA"}});if(!x.ok){const Q=await x.text();throw new Error(Q)}const F=await x.json(),Y=(F.remaining??0)+(F.processed??0);h(Y),c.success(`Found ${Y} generation logs to migrate`)}catch(g){c.error(`Preflight failed: ${g.message}`)}finally{z(!1)}},[m]),o=t.useCallback(async()=>{S.current=!1,y(i=>({...i,running:!0}));let g=0;for(;!S.current;)try{const i=await fetch(`https://oqmvtnzznxnynpfsgtdh.supabase.co/functions/v1/migrate-generation-log-images?password=${encodeURIComponent(m)}&dry_run=${j}&batch_size=${j?1e3:f}`,{headers:{Authorization:"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Im9xbXZ0bnp6bnhueW5wZnNndGRoIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjQwNTkwMjUsImV4cCI6MjA3OTYzNTAyNX0.qGINeCOXFf0TgELF_-pkex8MpSKTwmsN1gpai3RqGZA"}});if(!i.ok){const N=await i.text();y(ee=>({...ee,running:!1,logs:[...ee.logs,{id:"error",status:"error",details:N,timestamp:Date.now()}]})),c.error("Migration batch failed");break}const x=await i.json(),F=x.remaining??0;if(!x.results||x.results.length===0){if(g++,g>=2){y(N=>({...N,running:!1,remaining:0,logs:[...N.logs,{id:"done",status:"complete",details:"No more rows to process",timestamp:Date.now()}]})),c.success("Migration complete â no remaining rows");break}continue}g=0;const Y=x.results.map(N=>({id:N.id,status:N.status,details:N.details,timestamp:Date.now()})),Q=x.results.filter(N=>N.status==="migrated"||N.status==="dry_run").length,de=x.results.filter(N=>N.status==="skipped").length,me=x.results.filter(N=>N.status==="update_error"||N.status==="error").length;if(y(N=>({...N,totalProcessed:N.totalProcessed+x.results.length,migrated:N.migrated+Q,skipped:N.skipped+de,errors:N.errors+me,remaining:F,logs:[...N.logs,...Y]})),F===0||j){y(N=>({...N,running:!1})),c.success(j?`Dry run complete â ${x.results.length} rows previewed, ${F} remaining`:"Migration complete!");break}}catch(i){y(x=>({...x,running:!1,logs:[...x.logs,{id:"network-error",status:"error",details:i.message,timestamp:Date.now()}]})),c.error(`Network error: ${i.message}`);break}y(i=>({...i,running:!1}))},[m,j,f]),p=t.useCallback(()=>{S.current=!0,y(g=>({...g,running:!1}))},[]),k=t.useCallback(()=>{y(ns),h(null)},[]),w=n&&n>0?Math.min(100,Math.round(u.totalProcessed/n*100)):0;return e.jsxs("div",{className:"space-y-6",children:[e.jsxs(le,{children:[e.jsx(we,{className:"h-4 w-4"}),e.jsx(ne,{children:"Generation Log Image Migration"}),e.jsxs(oe,{children:["Migrates ",e.jsx("code",{children:"generation_logs"})," rows that have internal-bucket URLs or base64 generated images. Files are copied to the external storage bucket and URLs are rewritten."]})]}),e.jsxs(U,{children:[e.jsxs(J,{children:[e.jsxs(K,{className:"flex items-center gap-2 text-base",children:[e.jsx(Is,{className:"h-5 w-5"}),"Migration Controls"]}
2),e.jsx(Z,{children:"Run a preflight check first, then start the migration."})]}),e.jsxs(q,{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsxs(E,{onClick:O,disabled:R||u.running,variant:"outline",children:[R?e.jsx(V,{className:"h-4 w-4 animate-spin mr-2"}):e.jsx(we,{className:"h-4 w-4 mr-2"}),"Preflight Check"]}),n!==null&&e.jsxs(W,{variant:n===0?"default":"secondary",children:[n," rows to migrate"]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs(v,{children:["Batch Size: ",f]}),e.jsx(Je,{value:[f],onValueChange:([g])=>C(g),min:1,max:50,step:1,disabled:u.running}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Smaller batches are safer for rows with large base64 payloads."})]}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(fe,{id:"dry-run-toggle",checked:j,onCheckedChange:P,disabled:u.running}),e.jsxs(v,{htmlFor:"dry-run-toggle",className:"cursor-pointer",children:["Dry Run ",j?"(preview only â no changes)":"(LIVE â will write changes)"]}),!j&&e.jsxs(W,{variant:"destructive",className:"text-xs",children:[e.jsx(ie,{className:"h-3 w-3 mr-1"}),"Live Mode"]})]}),e.jsxs("div",{className:"flex items-center gap-3",children:[u.running?e.jsxs(E,{onClick:p,variant:"destructive",children:[e.jsx(Le,{className:"h-4 w-4 mr-2"}),"Stop"]}):e.jsxs(E,{onClick:o,disabled:n===null||n===0,children:[e.jsx(_e,{className:"h-4 w-4 mr-2"}),j?"Start Dry Run":"Start Migration"]}),e.jsxs(E,{onClick:k,variant:"ghost",disabled:u.running,children:[e.jsx($e,{className:"h-4 w-4 mr-2"}),"Reset"]})]})]})]}),u.totalProcessed>0&&e.jsx(U,{children:e.jsxs(q,{className:"pt-6 space-y-4",children:[e.jsx(Me,{value:w,className:"h-3"}),e.jsxs("div",{className:"grid grid-cols-2 sm:grid-cols-5 gap-4 text-sm",children:[e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"Processed"}),e.jsx("p",{className:"text-lg font-semibold",children:u.totalProcessed})]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:j?"Would Migrate":"Migrated"}),e.jsx("p",{className:"text-lg font-semibold text-green-600",children:u.migrated})]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"Skipped"}),e.jsx("p",{className:"text-lg font-semibold text-yellow-600",children:u.skipped})]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"Errors"}),e.jsx("p",{className:"text-lg font-semibold text-red-600",children:u.errors})]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"Remaining"}),e.jsx("p",{className:"text-lg font-semibold",children:u.remaining!==null?u.remaining:"â"})]})]}),u.running&&e.jsxs("p",{className:"text-xs text-muted-foreground flex items-center gap-2",children:[e.jsx(V,{className:"h-3 w-3 animate-spin"}),"Processing batchâ¦"]}),!u.running&&u.remaining===0&&e.jsxs("p",{className:"text-sm text-green-600 flex items-center gap-2",children:[e.jsx(je,{className:"h-4 w-4"}),"All rows migrated successfully"]})]})}),u.logs.length>0&&e.jsxs(U,{children:[e.jsx(J,{className:"pb-2",children:e.jsxs(K,{className:"text-sm flex items-center justify-between",children:[e.jsxs("span",{children:["Migration Log (",u.logs.length," entries)"]}),e.jsx(W,{variant:"outline",className:"font-mono text-xs",children:j?"DRY RUN":"LIVE"})]})}),e.jsx(q,{children:e.jsx(Ce,{className:"h-[350px] rounded border bg-muted/30",children:e.jsxs("div",{className:"p-3 font-mono text-xs space-y-0.5",children:[u.logs.map((g,i)=>{const x=new Date(g.timestamp).toLocaleTimeString(),F=g.status==="migrated"||g.status==="dry_run"?"â
":g.status==="skipped"?"âï¸":g.status==="complete"?"ð":"â",Y=g.details?` | ${g.details}`:"",Q=`[${x}] ${F} ${g.status.toUpperCase().padEnd(12)} ${g.id}${Y}`;return e.jsx("div",{className:`whitespace-pre-wrap break-all ${g.status==="error"||g.status==="update_error"?"text-red-400":g.status==="skipped"?"text-yellow-400/70":g.status==="complete"?"text-green-400":""}`,children:Q},`${g.id}-${i}`)}),e.jsx("div",{ref:D})]})})})]})]})}const Pe=5,os=34e5;function Ze(m){return`gallery_migration_state_${m}`}function is(m,u){try{localStorage.setItem(Ze(m),JSON.stringify(u))}catch{}}function cs(m){try{const u=localStorage.getItem(Ze(m));return u?JSON.parse(u):null}catch{return null}}function Ie(m){try{localStorage.removeItem(Ze(m))}catch{}}const qe={status:"idle",totalMigrated:0,totalFailed:0,totalSkipped:0,totalProcessed:0,batchesCompleted:0,errors:[],startedAt:null,currentCursor:null},ds={visualizations:{label:"Gallery Visualisations",icon:Ae,description:"Migrate generated_image_url and original_image_url from the visualizations table.",columns:"generated_image_url, original_image_url â storage URLs + thumbnails"},generation_logs:{label:"Generation Logs",icon:Ve,description:"Migrate generated_image_url from the generation_logs table.",columns:"generated_image_url â storage URL"}},xs=t.forwardRef(function(u,y){const[f,C]=t.useState(()=>sessionStorage.getItem("migration_password")??""),[j,P]=t.useState(!1),[R,z]=t.useState(!1),[n,h]=t.useState(null),[S,D]=t.useState(!1),[O,o]=t.useState(!1),[p,k]=t.useState("visualizations"),[w,g]=t.useState(()=>{const d=cs("visualizations"),l=cs("generation_logs");return{visualizations:d&&(d.status==="paused"||d.totalProcessed>0)?{...d,status:d.status==="running"?"paused":d.status}:qe,generation_logs:l&&(l.status==="paused"||l.totalProcessed>0)?{...l,status:l.status==="running"?"paused":l.status}:qe}}),i=w[p],x=t.useCallback(d=>{g(l=>({...l,[p]:typeof d=="function"?d(l[p]):d}))}
2,[p]),F=t.useRef(!1),Y=t.useRef(!1),Q=t.useRef(1e3),[de,me]=t.useState(1e3),[N,ee]=t.useState([]),se=t.useRef(null);t.useEffect(()=>{w.visualizations.status!=="idle"&&is("visualizations",w.visualizations),w.generation_logs.status!=="idle"&&is("generation_logs",w.generation_logs)},[w]),t.useEffect(()=>{se.current?.scrollIntoView({behavior:"smooth"})},[N.length]);const ve=t.useCallback(async()=>{if(!f){c.error("Enter the migration password first");return}o(!0);try{const{data:d,error:l}=await G.functions.invoke("migrate-gallery-images",{body:{password:f,action:"create-bucket"}});if(l)throw new Error(l.message);if(d?.error)throw new Error(d.error);d?.bucketExists&&(c.success(`Bucket "${d.bucket}" is ready`),ue())}catch(d){c.error("Bucket creation failed: "+d.message)}finally{o(!1)}},[f]),ue=t.useCallback(async()=>{if(!f){c.error("Enter the migration password first");return}D(!0);try{const{data:d,error:l}=await G.functions.invoke("migrate-gallery-images",{body:{password:f,action:"preflight"}});if(l)throw new Error(l.message);if(d?.error)throw new Error(d.error);h(d)}catch(d){c.error("Preflight failed: "+d.message)}finally{D(!1)}},[f]),Ne=t.useCallback(async(d,l)=>{const{data:r,error:A}=await G.functions.invoke("migrate-gallery-images",{body:{password:f,cursor:d,batchSize:Pe,table:l}});if(A)throw new Error(A.message||"Function call failed");if(r?.error)throw new Error(r.error);return r?.result},[f]),pe=t.useCallback(async(d=null)=>{if(!f){c.error("Please enter the migration password");return}const l=p;F.current=!1,Y.current=!1,d===null&&ee([]),x(A=>({...A,status:"running",startedAt:A.startedAt||Date.now(),...d===null?{totalMigrated:0,totalFailed:0,totalSkipped:0,totalProcessed:0,batchesCompleted:0,errors:[]}:{}}));let r=d;try{for(;;){if(Y.current){x(b=>({...b,status:"idle"})),Ie(l);return}if(F.current){x(b=>({...b,status:"paused",currentCursor:r}));return}const A=Date.now(),M=await Ne(r,l);if(!M){x(b=>({...b,status:"complete"})),Ie(l);return}if(M.items){const b=Date.now(),te=M.items.map((re,Fe)=>({id:re.id,status:re.status,error:re.error,storageKey:re.storageKey,bytes:re.bytes,durationMs:re.durationMs,timestamp:b+Fe}));ee(re=>[...re,...te].slice(-500))}if(x(b=>({...b,totalMigrated:b.totalMigrated+M.migrated,totalFailed:b.totalFailed+M.failed,totalSkipped:b.totalSkipped+M.skipped,totalProcessed:b.totalProcessed+M.processed,batchesCompleted:b.batchesCompleted+1,errors:[...b.errors,...M.errors],currentCursor:M.nextCursor})),h(b=>{if(!b)return b;const te=b.tables[l];return{...b,tables:{...b.tables,[l]:{remaining:Math.max(0,te.remaining-M.migrated),migrated:te.migrated+M.migrated}}}}),!M.hasMore){x(b=>({...b,status:"complete"})),Ie(l),await ue(),c.success(`${ds[l].label} migration complete`);return}r=M.nextCursor;const xe=Date.now()-A;ee(b=>[...b,{id:`batch-${M.nextCursor??Date.now()}`,status:"info",message:`Batch of ${M.processed} finished in ${(xe/1e3).toFixed(1)}s. Pausing ${Q.current}ms before the next batch.`,durationMs:xe,timestamp:Date.now()}].slice(-500)),await new Promise(b=>setTimeout(b,Q.current))}}catch(A){x(M=>({...M,status:"error"})),c.error("Migration error: "+A.message)}},[f,p,Ne,ue,x]),s=()=>{F.current=!0},a=()=>{pe(i.currentCursor)},_=()=>{Y.current=!0,x(qe),Ie(p)},I=n?.tables?.[p],B=I?.remaining??0;(I?.migrated??0)+i.totalMigrated;const ae=i.startedAt?Math.floor((Date.now()-i.startedAt)/1e3):0;B>0&&Math.min(100,Math.round(i.totalProcessed/B*100)),i.totalProcessed>0&&B>0&&Math.round((B-i.totalProcessed)/i.totalProcessed*ae),(B*os/1073741824).toFixed(1);const Se=i.status==="running";i.status;const ye=(n?.tables?.visualizations?.remaining??0)+(n?.tables?.generation_logs?.remaining??0),T=(n?.tables?.visualizations?.migrated??0)+(n?.tables?.generation_logs?.migrated??0),ke=t.useCallback(async()=>{if(f){z(!0);try{const{data:d,error:l}=await G.functions.invoke("migrate-gallery-images",{body:{password:f,action:"preflight"}});if(l)throw new Error(l.message);if(d?.error)throw new Error(d.error);h(d),P(!0),sessionStorage.setItem("migration_password",f),c.success("Migration tab unlocked")}catch(d){c.error("Invalid password or preflight failed: "+d.message)}finally{z(!1)}}},[f]);return j?e.jsx("div",{ref:y,children:e.jsxs(Ge,{defaultValue:"base64",className:"space-y-6",children:[e.jsxs(Xe,{className:"grid w-full grid-cols-3",children:[e.jsxs(ce,{value:"base64",className:"gap-2",children:[e.jsx(be,{className:"h-4 w-4"}),"Base64 Migration"]}),e.jsxs(ce,{value:"bucket",className:"gap-2",children:[e.jsx(ms,{className:"h-4 w-4"}),"Bucket Consolidation"]}),e.jsxs(ce,{value:"gen-logs",className:"gap-2",children:[e.jsx(Ve,{className:"h-4 w-4"}),"Gen Log Images"]})]}),e.jsxs(he,{value:"base64",className:"space-y-6",children:[e.jsxs(U,{children:[e.jsx(J,{children:e.jsxs(K,{className:"flex items-center gap-2",children:[e.jsx(we,{className:"h-5 w-5"}),"About This Migration"]})}),e.jsxs(q,{className:"space-y-3 text-sm text-muted-foreground",children:[e.jsx("p",{children:"This tool migrates legacy base64-encoded images stored in the database to dedicated cloud storage, dramatically reducing database size and improving page load performance."}),e.jsxs("p",{children:["Two tables contain base64 image data: ",e.jsx("strong",{className:"text-foreground",children:"visualizations"})," (generated + original images) and ",e.jsx("strong",{className:"text-foreground",children:"generation_logs"})," (generated images only). Each can be migrated independently."]}),e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2",children:[e.jsxs("div",{className:"flex gap-2",children:[e.jsx(Ue,{className:"h-4 w-4 mt-0.5 shrink-0 text-green-600"}),e.jsxs("span",{children:[e.jsx("strong",{className:"text-foreground",children:"Secure:"})," All uploads run server-side. Storage credentials are never sent to the browser."]}
2)]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx($e,{className:"h-4 w-4 mt-0.5 shrink-0 text-blue-600"}),e.jsxs("span",{children:[e.jsx("strong",{className:"text-foreground",children:"Resumable:"})," You can pause, leave the page, and come back later. Progress is saved automatically."]})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(be,{className:"h-4 w-4 mt-0.5 shrink-0 text-amber-600"}),e.jsxs("span",{children:[e.jsx("strong",{className:"text-foreground",children:"Non-destructive:"})," ","Original base64 data is preserved in backup columns until verified."]})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(je,{className:"h-4 w-4 mt-0.5 shrink-0 text-purple-600"}),e.jsxs("span",{children:[e.jsx("strong",{className:"text-foreground",children:"Idempotent:"})," Re-running skips already-migrated records. SHA-256 hashing ensures deduplication."]})]})]})]})]}),e.jsxs(U,{children:[e.jsxs(J,{children:[e.jsxs(K,{className:"flex items-center gap-2",children:[e.jsx(Ms,{className:"h-5 w-5"}),"Storage Destination"]}),e.jsx(Z,{children:"Cloud storage target for migrated images"})]}),e.jsxs(q,{className:"space-y-4",children:[e.jsxs("div",{className:"grid gap-3 text-sm sm:grid-cols-2",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-muted-foreground",children:"Provider"}),e.jsx("p",{className:"font-medium",children:"Supabase Storage (S3-compatible)"})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-muted-foreground",children:"Region"}),e.jsx("p",{className:"font-medium",children:"eu-west-1"})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-muted-foreground",children:"Bucket"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("p",{className:"font-medium font-mono",children:n?.bucket??"media"}),n&&(n.bucketExists?e.jsxs(W,{variant:"default",className:"bg-green-600 text-xs",children:[e.jsx(je,{className:"h-3 w-3 mr-1"})," Exists"]}):e.jsx(W,{variant:"secondary",className:"text-xs",children:"Not created"}))]})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-muted-foreground",children:"Object Paths"}),e.jsxs("div",{className:"font-mono text-xs space-y-0.5",children:[e.jsxs("p",{children:[e.jsx("span",{className:"text-muted-foreground",children:"visualizations/"}),"<type>/<hash[0:2]>/<sha256>.<ext>"]}),e.jsxs("p",{children:[e.jsx("span",{className:"text-muted-foreground",children:"generation-logs/"}),"generated/<hash[0:2]>/<sha256>.<ext>"]})]})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-muted-foreground",children:"Endpoint"}),e.jsx("p",{className:"font-medium font-mono text-xs break-all",children:"https://rwnhbkxrjqbkuoyrtlbc.storage.supabase.co/storage/v1/s3"})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-muted-foreground",children:"External Supabase Credentials"}),n?n.externalCredentialsConfigured?e.jsxs(W,{variant:"default",className:"bg-green-600",children:[e.jsx(je,{className:"h-3 w-3 mr-1"})," Configured"]}):e.jsxs(W,{variant:"destructive",children:[e.jsx(ie,{className:"h-3 w-3 mr-1"})," Missing (EXTERNAL_SUPABASE_URL / KEY)"]}):e.jsx("span",{className:"text-muted-foreground text-sm",children:"Run preflight to check"})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-muted-foreground",children:"S3 Credentials"}),n?n.credentialsConfigured?e.jsxs(W,{variant:"default",className:"bg-green-600",children:[e.jsx(je,{className:"h-3 w-3 mr-1"})," Configured"]}):e.jsxs(W,{variant:"destructive",children:[e.jsx(ie,{className:"h-3 w-3 mr-1"})," Missing"]}):e.jsx("span",{className:"text-muted-foreground text-sm",children:"Run preflight to check"})]}),n?.bucketCheckError&&e.jsxs("div",{children:[e.jsx("p",{className:"text-muted-foreground",children:"Bucket Check Error"}),e.jsxs(W,{variant:"destructive",className:"text-xs",children:[e.jsx(ie,{className:"h-3 w-3 mr-1"})," ",n.bucketCheckError]})]})]}),e.jsxs("div",{className:"pt-2",children:[e.jsxs(E,{variant:"outline",onClick:ve,disabled:O||!f||n?.bucketExists===!0,children:[O?e.jsx(V,{className:"h-4 w-4 animate-spin mr-2"}):e.jsx(As,{className:"h-4 w-4 mr-2"}),n?.bucketExists?"Bucket Ready":"Create Bucket"]}),e.jsxs("p",{className:"text-xs text-muted-foreground mt-1",children:["Creates the ",e.jsx("code",{children:"media"})," bucket with public read access (50 MB file limit) for CDN-friendly image serving."]})]})]})]}),n&&e.jsx(U,{children:e.jsx(q,{className:"pt-6",children:e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-4 text-sm",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-muted-foreground",children:"Total Remaining"}),e.jsx("p",{className:"text-lg font-semibold",children:ye.toLocaleStr
2ing()})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-muted-foreground",children:"Total Migrated"}),e.jsx("p",{className:"text-lg font-semibold text-green-600",children:T.toLocaleString()})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-muted-foreground",children:"Visualisations"}),e.jsxs("p",{className:"text-sm",children:[e.jsx("span",{className:"text-green-600 font-medium",children:n.tables?.visualizations?.migrated??0})," / ",((n.tables?.visualizations?.migrated??0)+(n.tables?.visualizations?.remaining??0)).toLocaleString()]})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-muted-foreground",children:"Generation Logs"}),e.jsxs("p",{className:"text-sm",children:[e.jsx("span",{className:"text-green-600 font-medium",children:n.tables?.generation_logs?.migrated??0})," / ",((n.tables?.generation_logs?.migrated??0)+(n.tables?.generation_logs?.remaining??0)).toLocaleString()]})]})]})})}),e.jsxs(U,{children:[e.jsxs(J,{children:[e.jsxs(K,{className:"flex items-center gap-2",children:[e.jsx(be,{className:"h-5 w-5"}),"Image Migration"]}),e.jsx(Z,{children:"Migrate base64-encoded images to cloud storage. Run each table independently."})]}),e.jsxs(q,{className:"space-y-6",children:[e.jsxs("div",{className:"space-y-3",children:[e.jsx("div",{className:"flex items-center gap-3",children:e.jsxs(E,{variant:"outline",onClick:ue,disabled:S||Se||!f,children:[S?e.jsx(V,{className:"h-4 w-4 animate-spin mr-2"}):e.jsx(Ke,{className:"h-4 w-4 mr-2"}),"Run Preflight Check"]})}),n&&!n.credentialsConfigured&&e.jsxs(le,{variant:"destructive",children:[e.jsx(ie,{className:"h-4 w-4"}),e.jsx(ne,{children:"S3 Credentials Missing"}),e.jsxs(oe,{children:["The ",e.jsx("code",{children:"STORAGE_S3_ACCESS_KEY_ID"})," and"," ",e.jsx("code",{children:"STORAGE_S3_SECRET_ACCESS_KEY"})," secrets must be configured before migration can proceed."]})]}),n&&!n.bucketExists&&e.jsxs(le,{children:[e.jsx(ie,{className:"h-4 w-4"}),e.jsx(ne,{children:"Bucket Not Created"}),e.jsxs(oe,{children:["Create the ",e.jsx("code",{children:"media"})," bucket using the button above before starting migration."]})]})]}),e.jsx(De,{}),e.jsxs(Ge,{value:p,onValueChange:d=>k(d),children:[e.jsxs(Xe,{className:"grid w-full grid-cols-2",children:[e.jsxs(ce,{value:"visualizations",className:"gap-2",children:[e.jsx(Ae,{className:"h-4 w-4"}),"Visualisations",n?.tables?.visualizations&&e.jsx(W,{variant:"secondary",className:"ml-1 text-xs",children:n.tables.visualizations.remaining})]}),e.jsxs(ce,{value:"generation_logs",className:"gap-2",children:[e.jsx(Ve,{className:"h-4 w-4"}),"Generation Logs",n?.tables?.generation_logs&&e.jsx(W,{variant:"secondary",className:"ml-1 text-xs",children:n.tables.generation_logs.remaining})]})]}),["visualizations","generation_logs"].map(d=>{const l=ds[d],r=w[d],A=r.status==="running",M=r.status==="paused",xe=n?.tables?.[d],b=xe?.remaining??0,te=xe?.migrated??0,re=b+te,Fe=te+r.totalMigrated,Ye=re>0?Math.min(100,Math.round(Fe/re*100)):0,Qe=b>0?Math.min(100,Math.round(r.totalProcessed/b*100)):0,Ee=r.startedAt?Math.floor((Date.now()-r.startedAt)/1e3):0,He=Ee>0?`${Math.floor(Ee/60)}m ${Ee%60}s`:"",Be=r.totalProcessed>0&&b>0?Math.round((b-r.totalProcessed)/r.totalProcessed*Ee):null,es=Be?`~${Math.floor(Be/60)}m ${Be%60}s remaining`:"",hs=(b*os/1073741824).toFixed(1);return e.jsxs(he,{value:d,className:"space-y-4 mt-4",children:[e.jsxs("div",{className:"rounded-md border p-4 space-y-2 text-sm",children:[e.jsx("p",{className:"font-medium",children:l.description}),e.jsx("p",{className:"text-muted-foreground text-xs font-mono",children:l.columns})]}),n&&xe&&e.jsxs("div",{className:"rounded-md border p-4",children:[e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-3 text-sm",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-muted-foreground",children:"Already Migrated"}),e.jsx("p",{className:"text-lg font-semibold text-green-600",children:te.toLocaleString()})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-muted-foreground",children:"Remaining"}),e.jsx("p",{className:"text-lg font-semibold",children:b.toLocaleString()})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-muted-foreground",children:"Est. Size"}),e.jsxs("p",{className:"text-lg font-semibold",children:[hs," GB"]})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-muted-foreground",children:"Est. Time"}),e.jsx("p",{className:"text-lg font-semibold",children:b>0?`~${Math.ceil(b/Pe*15/60)} min`:"â"})]})]}),te>0&&r.status==="idle"&&e.jsxs("div",{className:"mt-3 space-y-1",children:[e.jsxs("div",{className:"flex justify-between text-xs text-muted-foreground",children:[e.jsx("span",{children:"Overall progress"}),e.jsxs("span",{children:[Ye,"%"]})]}),e.jsx(Me,{value:Ye,className:"h-1.5"})]})]}),M&&r.totalProcessed>0&&e.jsxs(le,{children:[e.jsx(we,{className:"h-4 w-4"}),e.jsx(ne,{children:"Previous Session"}),e.jsxs(oe,{children:["A previous migration session was paused after processing"," ",r.totalProcessed.toLocaleStr
2ing()," images (",r.totalMigrated.toLocaleString()," migrated). Click Resume to continue from where you left off."]})]}),e.jsxs("div",{className:"flex items-center gap-3",children:[r.status==="idle"||r.status==="error"?e.jsxs(E,{onClick:()=>pe(null),disabled:!f||p!==d||n!==null&&(!n.credentialsConfigured||!n.bucketExists),children:[e.jsx(_e,{className:"h-4 w-4 mr-2"}),"Start Migration"]}):M?e.jsxs(E,{onClick:a,disabled:!f||p!==d,children:[e.jsx(_e,{className:"h-4 w-4 mr-2"}),"Resume"]}):A?e.jsxs(E,{variant:"outline",onClick:s,children:[e.jsx(Le,{className:"h-4 w-4 mr-2"}),"Pause"]}):null,r.status!=="idle"&&e.jsxs(E,{variant:"ghost",onClick:_,disabled:A,children:[e.jsx($e,{className:"h-4 w-4 mr-2"}),"Reset"]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(v,{className:"text-sm",children:"Batch Delay"}),e.jsxs("span",{className:"text-xs font-mono text-muted-foreground",children:[de,"ms"]})]}),e.jsx(Je,{min:0,max:5e3,step:100,value:[de],onValueChange:([L])=>{me(L),Q.current=L}}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Pause after each batch of ",Pe,". Upload and verification time is additional. Adjustable while running."]})]}),r.status!=="idle"&&e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex justify-between text-sm",children:[e.jsxs("span",{className:"text-muted-foreground",children:[A&&e.jsx(V,{className:"inline h-3 w-3 animate-spin mr-1"}),r.status==="complete"?"Complete":M?"Paused":A?"Migratingâ¦":"Error"]}),e.jsxs("span",{className:"text-muted-foreground",children:[Qe,"%",He&&` ⢠${He}`,es&&` ⢠${es}`]})]}),e.jsx(Me,{value:Qe,className:"h-2"})]}),e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-4 text-sm",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx("p",{className:"text-muted-foreground",children:"Processed"}),e.jsx("p",{className:"text-lg font-semibold",children:r.totalProcessed.toLocaleString()})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx("p",{className:"text-muted-foreground",children:"Migrated"}),e.jsx("p",{className:"text-lg font-semibold text-green-600",children:r.totalMigrated.toLocaleString()})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx("p",{className:"text-muted-foreground",children:"Skipped"}),e.jsx("p",{className:"text-lg font-semibold text-yellow-600",children:r.totalSkipped.toLocaleString()})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx("p",{className:"text-muted-foreground",children:"Failed"}),e.jsx("p",{className:"text-lg font-semibold text-red-600",children:r.totalFailed.toLocaleString()})]})]}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Batches completed: ",r.batchesCompleted," ⢠Batch size: ",Pe]})]}),r.status==="complete"&&e.jsxs(le,{children:[e.jsx(je,{className:"h-4 w-4"}),e.jsx(ne,{children:"Migration Complete"}),e.jsxs(oe,{children:[r.totalMigrated," images migrated. Image URLs now point to cloud storage. Original base64 data is retained in backup columns."]})]}),r.errors.length>0&&e.jsxs(le,{variant:"destructive",children:[e.jsx(ie,{className:"h-4 w-4"}),e.jsxs(ne,{children:[r.errors.length," Error(s)"]}),e.jsx(oe,{children:e.jsx("div",{className:"mt-2 max-h-40 overflow-y-auto space-y-1 text-xs font-mono",children:r.errors.map((L,Oe)=>e.jsxs("div",{children:[e.jsxs("span",{className:"opacity-60",children:[L.id.slice(0,8),"â¦"]})," ",L.error]},Oe))})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(v,{className:"text-sm font-medium",children:"Console"}),N.length>0&&e.jsx(E,{variant:"ghost",size:"sm",className:"h-6 text-xs",onClick:()=>ee([]),children:"Clear"})]}),e.jsx(Ce,{className:"h-72 rounded-md border bg-black/90",children:e.jsxs("div",{className:"p-3 space-y-0 text-xs font-mono text-green-400 leading-5",children:[N.length===0?e.jsx("div",{className:"text-green-400/40",children:"Waiting for migration to startâ¦"}):N.map((L,Oe)=>{const ss=new Date(L.timestamp).toLocaleTimeString(),ts=L.status==="migrated"?"â
":L.status==="failed"?"â":L.status==="info"?"â±":"âï¸",ps=L.bytes?` | ${(L.bytes/1024).toFixed(0)}KB`:"",gs=L.storageKey?` â ${L.storageKey}`:"",fs=L.error?` | ERROR: ${L.error}`:"",js=L.status==="info"?`[${ss}] ${ts} ${L.message??""}`:`[${ss}] ${ts} ${L.status.toUpperCase().padEnd(8)} ${L.id} | ${L.durationMs}ms${ps}${gs}${fs}`;return e.jsx("div",{className:`whitespace-pre-wrap break-all ${L.status==="failed"?"text-red-400":L.status==="skipped"?"text-yellow-400/70":L.status==="info"?"text-green-400/50":""}`,children:js},`${L.id}-${Oe}`)}),e.jsx("div",{ref:se})]})})]})]},d)})]})]})]})]}),e.jsx(he,{value:"bucket",className:"space-y-6",children:e.jsx(Gs,{password:f})}),e.jsx(he,{value:"gen-logs",className:"space-y-6",children:e.jsx(Xs,{password:f})})]})}):e.jsx("div",{ref:y,className:"space-y-6",children:e.jsxs(U,{children:[e.jsxs(J,{children:[e.jsxs(K,{className:"flex items-center gap-2",children:[e.jsx(Ue,{className:"h-5 w-5"}),"Migration Access"]}),e.jsx(Z,{children:"Enter the migration password to access storage migration tools."})]}),e.jsxs(q,{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{htmlFor:"migration-password-unlock",children:"Migration Password"}),e.jsx(X,{id:"migration-password-unlock",type:"password",value:f,onChange:d=>C(d.target.value),placeholder:"Enter DATA_MIGRATION_PASSWORD",onKeyDown:d=>d.key==="Enter"&&ke()})]}),e.jsxs(E,{onClick:ke,disabled:R||!f,children:[R?e.jsx(V,{className:"h-4 w-4 animate-spin mr-2"}):e.jsx(Ue,{className:"h-4 w-4 mr-2"}),"Unlock"]})]})]})})});xs.displayName="GalleryMigrationSection";function Lt(){const m=ys(),{hasRole:u,loading:y}=ws(),[f,C]=t.useState(""),[j,P]=t.useState(""),[R,z]=t.useState(null),[n,h]=t.useState("#8B7355"),[S,D]=t.useState("#A67B5B"),[O,o]=t.useState("#E6E6E6"),[p,k]=t.useState("#F5F5F5"),[w,g]=t.useState("#1A1A1A"),[i,x]=t.useState(100),[F,Y]=t.useState(!1),[Q,de]=t.useState(!1),[me,N]=t.useState("photo"),[ee,se]=t.useState(!1),[ve,ue]=t.useState(!1),[Ne,pe]=t.useState(!1),[s,a]=t.useState(""),[_,I]=t.useState(!1),[B,$]=t.useState(!1),[ae,ge]=t.useState(!1);t.useEffect(()=>{y||u("reydar_admin")||(c.error("Access denied"),m("/dashboard"))},[y,m]),t.useEffect(()=>{Se()},[]);const Se=async()=>{try{const{data:l}=await G.from("settings").select("*");l&&l.forEach(r=>{r.key==="platform_name"&&C(r.value),r.key==="platform_tagline"&&P(r.value||""),r.key==="platform_logo"&&z(r.value||null),r.key==="platform_primary_color"&&h(r.value||"#8B7355"),r.key==="platform_accent_color"&&D(r.value||"#A67B5B"),r.key==="platform_background_color"&&o(r.value||"#E6E6E6"),r.key==="platform_card_color"&&k(r.value||"#F5F5F5"),r.key==="platform_foreground_color"&&g(r.value||"#1A1A1A"),r.key==="platform_background_opacity"&&x(parseInt(r.value)||100),r.key==="maintenance_mode"&&Y(r.value==="true"),r.key==="auto_approve_products"&&de(r.value==="true"),r.key==="platform_display_mode"&&N(r.value),r.key==="platform_hover_effect"&&se(r.value==="true"),r.key==="use_composable_configurator"&&ue(r.value==="true"),r.key==="stores_default_composable_configurator"&&pe(r.value==="true"),r.key==="calendly_url"&&a(r.value||""),r.key==="onboarding_v2_enabled"&&I(r.value==="true")})}catch(l){console.error("Error loading settings:",l)}},ye=async(l,r,A=!0)=>{try{const{error:M}=await G.from("settings").upsert({key:l,value:r,updated_at:new Date().toISOString()},{onConflict:"key"});if(M)throw M;return A&&c.success("Setting saved"),!0}catch(M){return c.error("Failed to save setting: "+M.message),!1}},T=async l=>{ge(!0);try{(await Promise.all(l.map(A=>ye(A.key,A.value,!1)))).every(A=>A)&&c.success("Settings saved")}finally{ge(!1)}},ke=async l=>{const r=l.target.files?.[0];if(r){if(!r.type.startsWith("image/")){c.error("Please upload an image file");return}if(r.size>5*1024*1024){c.error("Please upload an image smaller than 5MB");return}$(!0);try{const A=r.name.split(".").pop(),xe=`platform/${`platform-logo-${Date.now()}.${A}`}`,{error:b}=await G.storage.from("media").upload(`product-images/${xe}`,r);if(b)throw b;const{data:{publicUrl:te}}=G.storage.from("media").getPublicUrl(`product-images/${xe}`);z(te),await ye("platform_logo",te),c.success("Platform logo uploaded successfully")}catch(A){console.error("Upload error:",A),c.error("Failed to upload logo: "+A.message)}finally{$(!1)}}},d=()=>{T([{key:"platform_name",value:f},{key:"platform_tagline",value:j},{key:"platform_primary_color",value:n},{key:"platform_accent_color",value:S},{key:"platform_background_color",value:O},{key:"platform_card_color",value:p},{key:"platform_foreground_color",value:w},{key:"platform_background_opacity",value:String(i)},{key:"maintenance_mode",value:String(F)},{key:"auto_approve_products",value:String(Q)},{key:"platform_display_mode",value:me},{key:"platform_hover_effect",value:String(ee)},{key:"use_composable_configurator",value:String(ve)},{key:"stores_default_composable_configurator",value:String(Ne)},{key:"calendly_url",value:s.trim()},{key:"onboarding_v2_enabled",value:String(_)}])};return y||!u("reydar_admin")?null:e.jsx(Rs,{breadcrumbItems:[{label:"Admin Dashboard",href:"/admin/dashboard"},{label:"Platform Settings"}],title:"Platform Settings",children:e.jsxs(Ge,{defaultValue:"general",className:"space-y-6",children:[e.jsxs(Xe,{className:"flex-wrap h-auto gap-1",children:[e.jsxs(ce,{value:"general",children:[e.jsx(vs,{className:"w-4 h-4 mr-2"}),"General"]}),e.jsxs(ce,{value:"database",children:[e.jsx(be,{className:"w-4 h-4 mr-2"}),"Database"]}),e.jsxs(ce,{value:"storage",children:[e.jsx(Ke,{className:"w-4 h-4 mr-2"}),"Storage"]}),e.jsxs(ce,{value:"migration",children:[e.jsx(Ae,{className:"w-4 h-4 mr-2"}),"Migration"]}),e.jsxs(ce,{value:"analytics",children:[e.jsx(Ts,{className:"w-4 h-4 mr-2"}),"Analytics"]})]}),e.jsx(he,{value:"analytics",children:e.jsx(Ls,{})}),e.jsx(he,{value:"general",children:e.jsxs(U,{children:[e.jsxs(J,{children:[e.jsx(K,{children:"General Settings"}),e.jsx(Z,{children:"Configure basic platform settings"})]}),e.jsxs(q,{className:"space-y-6",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{htmlFor:"platformName",children:"Platform Name"}),e.jsx(X,{id:"platformName",value:f,onChange:l=>C(l.target.value),placeholder:"Prevamp"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{htmlFor:"platformTagline",children:"Tagline"}),e.jsx(X,{id:"platformTagline",value:j,onChange:l=>P(l.target.value),placeholder:"No samples. No surprises."}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Shown in the top bar across the site. Leave blank to hide."})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{htmlFor:"platform-logo",children:"Platform Logo"}),e.jsxs("div",{className:"flex items-center gap-4",children:[R&&e.jsx("img",{src:R,alt:"Platform logo preview",className:"w-16 h-16 object-contain rounded-lg border border-border bg-background/50"}),e.jsxs("div",{className:"flex-1",children:[e.jsx(X,{id:"platform-logo",type:"file",accept:"image/*",onChange:ke,disabled:B,className:"cursor-pointer"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"Max 5MB. Recommended: Square image, at least 200x200px"}),B&&e.jsxs("p",{className:"text-xs text-primary mt-1 flex items-center gap-2",children:[e.jsx(V,{className:"h-3 w-3 animate-spin"}),"Uploading..."]})]})]})]}),e.jsx("div",{className:"rounded-md border border-dashed border-border bg-muted/30 px-3 py-2 text-xs text-muted-foreground",children:"These settings only affect the Reydar marketplace. Each store overrides them with its own branding."}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{htmlFor:"primaryColor",children:"Primary Colour"}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("input",{type:"color",id:"primaryColor",value:n,onChange:l=>h(l.target.value),className:"w-12 h-10 rounded border border-border
2cursor-pointer"}),e.jsx(X,{value:n,onChange:l=>h(l.target.value),placeholder:"#8B7355",className:"flex-1"})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Used for main calls to action and admin chrome across the marketplace."})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{htmlFor:"accentColor",children:"Accent Colour"}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("input",{type:"color",id:"accentColor",value:S,onChange:l=>D(l.target.value),className:"w-12 h-10 rounded border border-border cursor-pointer"}),e.jsx(X,{value:S,onChange:l=>D(l.target.value),placeholder:"#A67B5B",className:"flex-1"})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Used for highlights, hover key lines, and badges on the marketplace Visualiser."})]})]}),e.jsxs("div",{className:"space-y-4 pt-4 border-t",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Ss,{className:"h-4 w-4 text-muted-foreground"}),e.jsx(v,{className:"text-sm font-medium",children:"Surface Colours"})]}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-3",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{htmlFor:"backgroundColor",children:"Backgroun
2d Colour"}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("input",{type:"color",id:"backgroundColor",value:O,onChange:l=>o(l.target.value),className:"w-12 h-10 rounded border border-border cursor-pointer"}),e.jsx(X,{value:O,onChange:l=>o(l.target.value),placeholder:"#E6E6E6",className:"flex-1"})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Page background on marketplace pages. Stores override this with their own setting."})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{htmlFor:"cardColor",children:"Card Colour"}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("input",{type:"color",id:"cardColor",value:p,onChange:l=>k(l.target.value),className:"w-12 h-10 rounded border border-border cursor-pointer"}),e.jsx(X,{value:p,onChange:l=>k(l.target.value),placeholder:"#F5F5F5",className:"flex-1"})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Surface colour for marketplace cards and panels."})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{htmlFor:"foregroundColor",children:"Text Colour"}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("input",{type:"color",id:"foregroundColor",value:w,onChange:l=>g(l.target.value),className:"w-12 h-10 rounded border border-border cursor-pointer"}),e.jsx(X,{value:w,onChange:l=>g(l.target.value),placeholder:"#1A1A1A",className:"flex-1"})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Primary text colour on marketplace cards and pages."})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx(v,{htmlFor:"platformBgOpacity",children:"Backgroun
2d Opacity"}),e.jsxs("span",{className:"text-sm text-muted-foreground",children:[i,"%"]})]}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"w-8 h-8 rounded border flex-shrink-0",style:{backgroundColor:O,opacity:i/100}}),e.jsx(Je,{id:"platformBgOpacity",value:[i],onValueChange:([l])=>x(l),min:0,max:100,step:5,className:"flex-1"})]}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"Controls transparency of the marketplace background (0â100%)."})]})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(v,{children:"Maintenance Mode"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Temporarily disable public access"})]}),e.jsx(fe,{checked:F,onCheckedChange:Y})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(v,{children:"Auto-Approve Products"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Automatically approve new product submissions"})]}),e.jsx(fe,{checked:Q,onCheckedChange:de})]}),e.jsxs("div",{className:"space-y-2 pt-4 border-t",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Ae,{className:"h-4 w-4 text-muted-foreground"}),e.jsx(v,{children:"Default Product Display Mode"})]}),e.jsxs(ks,{value:me,onValueChange:l=>N(l),children:[e.jsx(Cs,{className:"w-[200px]",children:e.jsx(_s,{})}),e.jsxs(Es,{children:[e.jsx(as,{value:"photo",children:"Photo (E-commerce)"}),e.jsx(as,{value:"sample",children:"Sample (Swatches)"})]})]}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Platform-wide default for how products are displayed. Stores can override this setting."})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(v,{children:"Enable Thumbnail Hover Effect"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Show alternate view (photo/sample) when hovering over product cards"})]}),e.jsx(fe,{checked:ee,onCheckedChange:se})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(v,{children:"Use Composable Generation Configurator"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Replace the flat AI function dropdown with a multi-section configurator panel (Mode + Quality + Resolution + Aspect Ratio) on the Reydar Marketplace"})]}),e.jsx(fe,{checked:ve,onCheckedChange:ue})]}),e.jsxs("div",{className:"flex items-center justify-between ml-4 pl-4 border-l-2 border-muted",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(v,{children:"Enable for All Stores by Default"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"When enabled, all stores will use the composable configurator unless individually overridden. When off, stores keep the classic dropdown unless they opt in."})]}),e.jsx(fe,{checked:Ne,onCheckedChange:pe})]}),e.jsxs("div",{className:"space-y-2 pt-4 border-t",children:[e.jsx(v,{htmlFor:"calendly-url",children:"Calendly scheduling URL"}),e.jsx(X,{id:"calendly-url",type:"url",placeholder:"https://calendly.com/your-team/discovery-call",value:s,onChange:l=>a(l.target.value)}),e.jsx("p",{className:"text-xs text-muted-foreground",children:'Used by the Discovery Call step in the organisation onboarding wizard. Leave blank to show a "scheduling link coming soon" message instead of an embed.'})]}),e.jsxs("div",{className:"flex items-center justify-between pt-4 border-t",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(v,{children:"Enable new onboarding flow (V2)"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Switch to the scrape-based, self-serve B2B onboarding journey (scrape â review â plan â trial/call/save)"})]}),e.jsx(fe,{checked:_,onCheckedChange:I})]}),e.jsx(E,{onClick:d,disabled:ae,children:"Save General Settings"})]})]})}),e.jsx(he,{value:"database",children:e.jsx($s,{})}),e.jsx(he,{value:"storage",children:e.jsxs("div",{className:"space-y-8",children:[e.jsx(Ds,{}),e.jsx(Fs,{})]})}),e.jsx(he,{value:"migration",children:e.jsx(xs,{})})]})})}export{Lt as default};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.