1const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/ListingAnalyticsTrendChart-B51nvYci.js","assets/react-vendor-DV5ktuDV.js","assets/index-Ddmjp9wg.js","assets/supabase-CwJNLV8D.js","assets/radix-ui-DWvHXyxJ.js","assets/ui-utils-B2rm_Apj.js","assets/framer-motion-ahggqEuq.js","assets/react-markdown-eG3dqjFT.js","assets/index-Bz-fdbHd.css","assets/recharts-DiQFEk-9.js","assets/subDays-DEP_z_34.js"])))=>i.map(i=>d[i]); 2import{j as e,r as c}from"./react-vendor-DV5ktuDV.js";import{C as q,aG as Z,aJ as ee,aW as he,c as J,b as M,be as st,aI as Ds,by as Fa,B as _,a as X,aV as We,a2 as D,Q as ie,bd as Le,a3 as je,bz as ma,X as ze,bi as Ge,bg as ve,aQ as _t,a6 as ys,a7 as Ns,a8 as ws,a9 as _s,aa as ua,aE as ks,ad as gt,ab as W,I as Y,bA as ps,bB as xa,b4 as Ps,bC as tt,bD as at,bE as rt,bF as Ie,br as Ws,aD as ft,A as Ve,bG as kt,S as Ct,bH as qa,aU as St,bp as Cs,r as $a,s as Ma,bI as At,n as za,t as Ia,ac as rs,bJ as jt,bK as Ke,av as ns,F as is,G as ls,H as os,J as cs,K as ke,N as ss,aN as be,a1 as Ss,W as ae,g as Me,aY as Be,bL as ha,bM as Ua,b9 as Gs,bN as ts,bO as Oa,bv as Dt,k as Ks,bw as pa,bP as zt,bQ as It,bR as Ut,bS as Ot,bq as Ba,m as Va,bT as Ya,bU as Ha,bV as Wa,bh as Ga,ax as Qs,bW as Ye,aR as As,aH as Ka,aK as Js,a0 as Pt,bk as Qa,af as ga,aZ as fa,b2 as Ja,bX as Xa,bY as Za,an as er,bZ as sr,ao as tr,ap as ar,aq as rr,ar as nr,as as ir,at as lr,au as or,b_ as cr,ae as Bs,bc as dr,b$ as ja,L as mr,c0 as ur,c1 as xr,bj as vs,aC as bs,$ as hr,c2 as pr,c3 as mt,c4 as gr,c5 as fr,c6 as jr,c7 as vr,d as br,f as yr,Z as Bt,_ as Nr,ay as wr,az as _r,aA as Vt,aB as Yt,c8 as kr}from"./index-Ddmjp9wg.js";import{u as fe}from"./useMutation-T0VP7vfa.js";import{l as Cr}from"./listingSaveError-Bev7r2dx.js";import{a as Sr,w as Ar}from"./listingStatus-5Utfwmsd.js";import{g as Dr}from"./listingCompleteness-CCGK4my4.js";import{P as Pr}from"./pencil-line-RSpiwXmV.js";import{f as Tr}from"./listingAccess-DQB03B7q.js";import{S as va}from"./ShareQrCode-CotbyItj.js";import{T as vt,a as bt,b as es,c as ye,d as yt,e as Ne}from"./table-_g4t-3iO.js";import{A as gs,a as Vs,b as fs}from"./alert-DE_MUCV1.js";import{formatBytes as Ht,prepareImageForUpload as Lr}from"./imageUpload-CBpMc4S4.js";import{I as Er}from"./image-plus-DvINcQEI.js";import{r as js}from"./checkoutRedirect-Bo2qwz6F.js";import{c as ba,f as Rr}from"./videoEmbed-BLDbvgy5.js";import{F as Fr,a as qr}from"./file-video-DbOp96QE.js";import{L as $r}from"./link-2-qyt1klj_.js";import{C as Wt}from"./circle-play-BuBhWHBW.js";import{C as He}from"./checkbox-BQTsa23J.js";import{h as Mr,c as zr,r as Ir}from"./videoUpload-Bvwq3UEG.js";import{V as Gt}from"./video-b-3q0p_m.js";import{L as Ur}from"./lock-CVgIt4BD.js";import{R as Or}from"./rotate-cw-DvcyktcB.js";import{U as Xs}from"./upload-PrG7lCWY.js";import{S as De}from"./switch-rkvCF5tM.js";import{Q as ds}from"./index-CEiJAe33.js";import{E as Ts}from"./jspdf.es.min-Dl_wbsAQ.js";import Qe from"./html2canvas.esm-CBrSDip1.js";import{d as Tt,a as Br}from"./printExport-DMiuusS2.js";import{i as Zs,B as Kt,f as Vr,a as Yr}from"./logoFile-B3g3GUlW.js";import{P as Lt}from"./printer-Bo0ECXq2.js";import{I as ms}from"./image-Cr8oGzXn.js";import{P as ya}from"./palette-CpEKTw8w.js";import{M as nt}from"./mail-BKMnyOGu.js";import{f as Hr,a as ut,O as qs}from"./outreachMetrics-612Tx5Jx.js";import{M as Na}from"./megaphone-BTrQf3VI.js";import{_ as Wr}from"./supabase-CwJNLV8D.js";import{p as Gr,f as Kr}from"./treasurePartnerTracking-C22Nqr7Y.js";import{I as Ys}from"./inbox-YUugI8QG.js";import{C as xt}from"./circle-check-big-DIs_Lbo1.js";import{F as wa}from"./filter-D_vZrcEK.js";import{E as Qt}from"./eye-off-CnEo1DlB.js";import{f as as}from"./formatDistanceToNow-CllKNVVk.js";import{P as Qr,C as Jr,a as Xr}from"./ContractorCardSkeleton-SlD6ldxk.js";import{Q as Zr}from"./QuickUpgradeDialog-zrcMYEe6.js";import{u as en}from"./useBusinessPlan-D7g1t1rq.js";import{a as sn}from"./useReviewStats-DQGpGehF.js";import{u as tn}from"./useFavorites-ahziS-kh.js";import{u as an}from"./useReferral-DZN_RUEP.js";import{R as _a,a as Nt}from"./radio-group-CF6D1QfJ.js";import{S as ka}from"./scale-B5MDM9cw.js";import{S as Et}from"./square-pen-DGJGB0Mq.js";import{B as rn}from"./bell-ring-BrunCzxb.js";import{B as Jt}from"./bell-off-CG0Z4V0F.js";import{G as nn}from"./graduation-cap-B6YOQKWP.js";import{V as ln}from"./vote-DL5v5UVU.js";import{F as on}from"./file-spreadsheet-CZ10G6Xn.js";import{C as Ca}from"./circle-x-DrlftcGL.js";import{R as wt}from"./rocket-BAwY6d_R.js";import{g as et}from"./townScore-dWEq1Ye-.js";import{U as Xt}from"./undo-2-CsnRoSLl.js";import{T as cn}from"./trending-down-DY5HyPot.js";import{R as Zt}from"./receipt-BMMWsOW-.js";import"./radix-ui-DWvHXyxJ.js";import"./ui-utils-B2rm_Apj.js";import"./framer-motion-ahggqEuq.js";import"./react-markdown-eG3dqjFT.js";import"./qr-code-BDlznMCC.js";import"./differenceInCalendarMonths-Bg0gFuxP.js";import"./endOfDay-C_c36miO.js";import"./endOfMonth-CE2bTK5P.js";import"./externalLink-CoHKrutX.js";import"./reportTelemetryFailure-CWRvBsy8.js";import"./FavoriteButton-CEU7Mz1J.js";import"./Linkify-B1ju_w8T.js";import"./CommunityPartnerBadge-CJCxDHkw.js";import"./church-BXGiM1QC.js";import"./heart-handshake-DFI_Urc7.js";import"./scissors-COTJe3zb.js";import"./BusinessLogo-2KWrMpTm.js";import"./logoHealth-5jCseH3H.js";import"./PlansVsSponsorshipsExplainer-B-YVyzbA.js";import"./layers-BQm4FwTA.js";import"./award-D8mIfha0.js";import"./accordion-VQcJ_0-2.js";import"./VoiceSubmitButton-CejaHO4k.js";import"./planToolMatrix-mIYbTRj5.js";const dn=({listing:s,onEdit:t})=>{const{items:i,completed:d,total:a,percent:m,readyToPublish:n}=Dr(s);return m===100?null:e.jsxs(q,{className:"mb-6 border-primary/30","data-testid":"listing-finish-checklist",children:[e.jsx(Z,{className:"pb-3",children:e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2",children:[e.jsxs("div",{children:[e.jsx(ee,{className:"text-lg",children:"Finish your listing"}),e.jsx(he,{children:n?"The essentials are done â these last touches make it stand out.":"A few details left before neighbors can find you easily."})]}),e.jsxs(J,{variant:n?"default":"secondary",className:"shrink-0",children:[d," of ",a," done"]})]})}),e.jsxs(M,{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx(st,{value:m,className:"h-2","aria-label":`Listing completeness: ${m}%`}),e.jsxs("p",{className:"text-xs text-muted-foreground mt-1.5",children:[m,"% complete"]})]}),e.jsx("ul",{className:"space-y-2",children:i.map(p=>e.jsxs("li",{className:"flex items-start gap-2.5",children:[p.done?e.jsx(Ds,{className:"h-4 w-4 mt-0.5 shrink-0 text-primary","aria-hidden":"true"}):e.jsx(Fa,{className:"h-4 w-4 mt-0.5 shrink-0 text-muted-foreground","aria-hidden":"true"}),e.jsxs("div",{className:"min-w-0",children:[e.jsxs("p",{className:p.done?"text-sm text-muted-foreground line-through":"text-sm font-medium text-foreground",children:[p.label,!p.required&&!p.done&&e.jsx("span",{className:"ml-2 text-xs font-normal text-muted-foreground",children:"Optional"}),e.jsx("span",{className:"sr-only",children:p.done?" â completed":" â still needed"})]}),!p.done&&e.jsx("p",{className:"text-xs text-muted-foreground",children:p.hint})]})]}
2,p.id))}),e.jsxs("div",{className:"flex flex-wrap gap-2 pt-1",children:[e.jsx(_,{size:"sm",onClick:t,className:"min-h-[44px]",children:"Finish my listing"}),e.jsx(_,{asChild:!0,size:"sm",variant:"outline",className:"min-h-[44px]",children:e.jsxs(X,{to:"/quickstart",children:[e.jsx(We,{className:"h-4 w-4 mr-1.5","aria-hidden":"true"}),"Send a photo and we'll do it"]})})]})]})]})},mn=s=>{const t=(s??"").toLowerCase();return t==="approved"||t==="completed"||t==="published"?"approved":t==="needs_edits"||t==="changes_requested"||t==="rejected"?"needs_edits":"awaiting_review"},un={approved:{label:"Approved",description:"You approved this draft â it's live on your listing.",icon:e.jsx(Ds,{className:"h-4 w-4 text-primary","aria-hidden":"true"}),variant:"default"},needs_edits:{label:"Needs edits",description:"You asked for changes. We'll update the draft and send it back.",icon:e.jsx(Pr,{className:"h-4 w-4 text-destructive","aria-hidden":"true"}),variant:"destructive"},awaiting_review:{label:"Awaiting your review",description:"We prepared a draft from your materials. Review it and approve or tweak anything.",icon:e.jsx(Le,{className:"h-4 w-4 text-muted-foreground","aria-hidden":"true"}),variant:"secondary"}},xn=s=>s?new Date(s).toLocaleString(void 0,{month:"short",day:"numeric",hour:"numeric",minute:"2-digit"}):"â",hn=({onEdit:s})=>{const[t,i]=c.useState(!0),[d,a]=c.useState(null);if(c.useEffect(()=>{let N=!0;return(async()=>{const{data:C}=await D.from("quickstart_submissions").select("id,status,updated_at,reviewed_at,admin_notes").order("updated_at",{ascending:!1}).limit(1);N&&(a((C==null?void 0:C[0])??null),i(!1))})(),()=>{N=!1}},[]),t)return e.jsx(q,{className:"mb-6","data-testid":"listing-draft-status-loading",children:e.jsxs(M,{className:"flex items-center gap-2 py-4 text-sm text-muted-foreground",children:[e.jsx(ie,{className:"h-4 w-4 animate-spin","aria-hidden":"true"}),"Checking your listing draftâ¦"]})});if(!d)return null;const m=mn(d.status),n=un[m],p=d.reviewed_at??d.updated_at;return e.jsxs(q,{className:"mb-6 border-primary/30","data-testid":"listing-draft-status",children:[e.jsx(Z,{className:"pb-3",children:e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2",children:[e.jsxs("div",{children:[e.jsxs(ee,{className:"text-lg flex items-center gap-2",children:[n.icon,"Your listing draft"]}),e.jsx(he,{children:n.description})]}),e.jsx(J,{variant:n.variant,className:"shrink-0","data-testid":"listing-draft-status-badge",children:n.label})]})}),e.jsxs(M,{className:"space-y-3",children:[e.jsxs("p",{className:"text-xs text-muted-foreground","data-testid":"listing-draft-updated",children:["Last updated ",xn(p)]}),m!=="approved"&&e.jsx(_,{size:"sm",onClick:s,className:"min-h-[44px]",children:"Review and approve"})]})]})};function ea(s){const t=(s??"").trim();return t?t.split(/[\s_-]+/).map(i=>i.charAt(0).toUpperCase()+i.slice(1).toLowerCase()).join(" "):"Pending"}function pn(s,t,i){return i||!s||s.length===0?null:s.find(d=>d.id===t)??s[0]??null}function gn(s,t,i){var a;return!s||s.length===0||i||t&&s.some(m=>m.id===t)?null:((a=s[0])==null?void 0:a.id)??null}function fn(s){return s?`townsy:dashboard:activeContractor:${s}`:""}function jn({contractorId:s,userId:t,photos:i,onPhotosChange:d}){const[a,m]=c.useState(!1),[n,p]=c.useState(0),[N,C]=c.useState(""),[u,g]=c.useState([]),w=c.useRef(new Set),b=c.useRef(null),{toast:A}=je(),x=f=>{w.current.add(f),g(h=>h.map(P=>P.id===f&&(P.status==="pending"||P.status==="preparing"||P.status==="uploading")?{...P,status:"cancelled"}:P))},j=(f,h)=>{g(P=>P.map(k=>k.id===f?{...k,...h}:k))},v=async f=>{m(!0),p(0),w.current=new Set;const h=Array.from(f).map($=>({id:`${Date.now()}-${Math.random().toString(36).slice(2)}`,name:$.name,originalSize:$.size,status:"pending"}));g(h);const P=[],k=f.length,H=Array.from(f);try{for(let $=0;$<H.length;$++){const re=H[$],E=h[$];if(w.current.has(E.id))continue;j(E.id,{status:"preparing"}),C(`Preparing ${re.name} (${$+1}/${k})â¦`);let U;try{U=await Lr(re)}catch(O){j(E.id,{status:"error",error:O.message});continue}if(w.current.has(E.id))continue;j(E.id,{finalSize:U.file.size,status:"uploading"}),C(`Uploading ${re.name} (${$+1}/${k})â¦`);const L=U.file.name.split(".").pop(),R=`${t}/${s}/${Date.now()}-${Math.random().toString(36).slice(2)}.${L}`,{error:me}=await D.storage.from("contractor-images").upload(R,U.file);if(me){j(E.id,{status:"error",error:me.message});continue}if(w.current.has(E.id)){await D.storage.from("contractor-images").remove([R]).catch(()=>{});continue}const{data:K}=D.storage.from("contractor-images").getPublicUrl(R);P.push(K.publicUrl),j(E.id,{status:"done"}),p(Math.round(($+1)/k*100))}if(P.length>0){const $=[...i,...P],{error:re}=await D.from("contractors").update({photos:$}).eq("id",s);if(re)throw re;d($),A({title:"Uploaded!",description:`${P.length} photo(s) added.`})}}catch($){A({title:"Upload failed",description:$.message,variant:"destructive"})}finally{m(!1),p(0),C(""),b.current&&(b.current.value="")}},l=async f=>{try{const h=f.split("/contractor-images/");h[1]&&await D.storage.from("contractor-images").remove([decodeURIComponent(h[1])]);const P=i.filter(H=>H!==f),{error:k}=await D.from("contractors").update({photos:P}).eq("id",s);if(k)throw k;d(P),A({title:"Removed",description:"Photo deleted."})}catch(h){A({title:"Error",description:h.message,variant:"destructive"})}};return e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("h3",{className:"text-sm font-medium",children:["Photos (",i.length,")"]}),e.jsxs(_,{type:"button",variant:"outline",size:"sm",disabled:a,onClick:()=>{var f;return(f=b.current)==null?void 0:f.click()},children:[a?e.jsx(ie,{className:"h-4 w-4 animate-spin mr-1"}):e.jsx(Er,{className:"h-4 w-4 mr-1"}),a?"Uploadingâ¦":"Add Photos"]}),e.jsx("input",{ref:b,type:"file",accept:"image/*",multiple:!0,className:"hidden",onChange:f=>f.target.files&&v(f.target.files)})]}),a&&e.jsxs("div",{className:"space-y-1",children:[e.jsx(st,{value:n,className:"h-2"}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:[N," ",n,"%"]})]}),u.length>0&&e.jsx("ul",{className:"space-y-1 rounded-md border bg-muted/30 p-2 text-xs",children:u.map(f=>{const h=f.finalSize!==void 0&&f.finalSize!==f.originalSize;return e.jsxs("li",{className:"flex items-center justify-between gap-2",children:[e.jsxs("span",{className:"flex items-center gap-1.5 min-w-0 flex-1",children:[f.status==="done"&&e.jsx(Ds,{className:"h-3.5 w-3.5 text-primary shrink-0"}),f.status==="error"&&e.jsx(ma,{className:"h-3.5 w-3.5 text-destructive shrink-0"}),(f.status==="preparing"||f.status==="uploading")&&e.jsx(ie,{className:"h-3.5 w-3.5 animate-spin shrink-0"}),e.jsx("span",{className:"truncate",children:f.name}),e.jsxs("span",{className:"text-muted-foreground whitespace-nowrap",children:[Ht(f.originalSize),h&&` â ${Ht(f.finalSize)}`]})]}),e.jsxs("span",{className:"flex items-center gap-2 shrink-0",children:[f.status==="error"&&e.jsx("span",{className:"text-destructive truncate max-w-[140px]",title:f.error,children:f.error}),f.status==="cancelled"&&e.jsx("span",{className:"text-muted-foreground",children:"Cancelled"}),(f.status==="pending"||f.status==="preparing"||f.status==="uploading")&&e.jsx("button",{type:"button",onClick:()=>x(f.id),className:"text-muted-foreground hover:text-destructive","aria-label":`Cancel ${f.name}`,children:e.jsx(ze,{className:"h-3.5 w-3.5"})})]})]},f.id)})}),i.length>0&&e.jsx("div",{className:"grid grid-cols-3 sm:grid-cols-4 gap-2",children:i.map((f,h)=>e.jsxs("div",{className:"relative group aspect-square rounded-lg overflow-hidden bg-muted",children:[e.jsx("img",{src:f,alt:`Photo ${h+1}`,className:"h-full w-full object-cover"}),e.jsx("button",{type:"button",onClick:()=>l(f),className:"absolute top-1 right-1 bg-destructive text-destructive-foreground rounded-full p-1 opacity-0 group-hover:opacity-100 transition-opacity",children:e.jsx(Ge,{className:"h-3 w-3"})})]},h))})]})}function Sa({url:s}){const t=ba(s),[i,d]=c.useState(null),[a,m]=c.useState(!1);if(c.useEffect(()=>{if(d(null),t.kind!=="embed")return;const N=new AbortController;m(!0);const C=setTimeout(()=>{Rr(s,N.signal).then(u=>d(u)).finally(()=>m(!1))},400);return()=>{clearTimeout(C),N.abort(),m(!1)}},[s,t.kind]),t.kind==="invalid")return null;const n=(i==null?void 0:i.thumbnailUrl)??t.thumbnailUrl??null,p=(i==null?void 0:i.title)??(t.kind==="file"?"Direct video file":t.kind==="link"?"External video page":"Video");return e.jsxs("div",{className:"flex items-center gap-3 rounded-xl border bg-muted/30 p-3",children:[e.jsxs("div",{className:"relative h-16 w-28 shrink-0 overflow-hidden rounded-lg bg-muted",children:[n?e.jsx("img",{src:n,alt:`Thumbnail for ${p}`,loading:"lazy",className:"h-full w-full object-cover"}):e.jsx("div",{className:"flex h-full w-full items-center justify-center text-muted-foreground",children:t.kind==="file"?e.jsx(Fr,{className:"h-6 w-6"}):t.kind==="link"?e.jsx($r,{className:"h-6 w-6"}):e.jsx(Wt,{className:"h-6 w-6"})}),t.kind==="embed"&&n&&e.jsx(Wt,{className:"absolute inset-0 m-auto h-8 w-8 text-white/90 drop-shadow"})]}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("p",{className:"truncate text-sm font-medium",children:a&&!i?e.jsxs("span",{className:"inline-flex items-center gap-1.5 text-muted-foreground",children:[e.jsx(ie,{className:"h-3.5 w-3.5 animate-spin"})," Loading previewâ¦"]}):p}),e.jsxs("p",{className:"truncate text-xs text-muted-foreground",children:[i!=null&&i.providerName?`${i.providerName} · `:"",t.host]})]})]})}function vn({contractorId:s,userId:t,videoUrl:i,videoFileUrl:d}){const{toast:a}=je(),m=ve(),[n,p]=c.useState([]),[N,C]=c.useState({}),[u,g]=c.useState(!1),[w,b]=c.useState(!0),[A,x]=c.useState(!1),[j,v]=c.useState([]),l=!!(i||d);if(c.useEffect(()=>{let E=!0;return(async()=>{const{data:U}=await D.from("contractors").select("id, business_name, video_url, video_file_url").eq("user_id",t).neq("id",s).order("business_name");if(!E)return;const L=U??[];p(L),C(Object.fromEntries(L.map(R=>[R.id,!0]))),b(!1)})(),()=>{E=!1}},[t,s]),w||n.length===0||!l)return null;const h=n.filter(E=>N[E.id]).map(E=>E.id),P=n.filter(E=>j.includes(E.id)),k=P.filter(E=>N[E.id]).map(E=>E.id),H=P.filter(E=>N[E.id]&&(E.video_url||E.video_file_url)).length,$=async()=>
2{if(k.length!==0){g(!0);try{const{error:E}=await D.from("contractors").update({video_url:i,video_file_url:d}).in("id",k).eq("user_id",t);if(E)throw E;m.invalidateQueries({queryKey:["my-contractors"]}),p(U=>U.map(L=>k.includes(L.id)?{...L,video_url:i,video_file_url:d}:L)),a({title:"Video applied",description:`Added to ${k.length} other listing${k.length===1?"":"s"}.`}),x(!1)}catch(E){a({title:"Couldn't apply video",description:E.message,variant:"destructive"})}finally{g(!1)}}},re=h.length===n.length;return e.jsxs("div",{className:"rounded-lg border bg-muted/20 p-3 space-y-3",children:[e.jsxs("div",{className:"flex items-start justify-between gap-2",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-medium",children:"Use this video on your other listings"}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["You have ",n.length," other listing",n.length===1?"":"s",". Apply the same video to all of them at once."]})]}),e.jsx(_,{variant:"ghost",size:"sm",className:"shrink-0 min-h-[44px]",onClick:()=>C(Object.fromEntries(n.map(E=>[E.id,!re]))),children:re?"Clear all":"Select all"})]}),e.jsx("ul",{className:"space-y-1",children:n.map(E=>e.jsx("li",{children:e.jsxs("label",{className:"flex items-center gap-3 rounded-md px-2 py-2 min-h-[44px] cursor-pointer hover:bg-muted/50",children:[e.jsx(He,{checked:!!N[E.id],onCheckedChange:U=>C(L=>({...L,[E.id]:!!U}))}),e.jsx("span",{className:"text-sm truncate",children:E.business_name}),(E.video_url||E.video_file_url)&&e.jsx("span",{className:"ml-auto text-[11px] text-muted-foreground shrink-0",children:"has video"})]})},E.id))}),e.jsxs(_,{onClick:()=>{v(h),x(!0)},disabled:h.length===0,className:"w-full min-h-[44px]",children:[e.jsx(_t,{className:"h-4 w-4 mr-2"})," Preview & apply to ",h.length," listing",h.length===1?"":"s"]}),e.jsx(ys,{open:A,onOpenChange:E=>!u&&x(E),children:e.jsxs(Ns,{className:"max-w-lg max-h-[85vh] overflow-y-auto",children:[e.jsxs(ws,{children:[e.jsx(_s,{children:"Review before applying"}),e.jsxs(ua,{children:["This video will be attached to the ",k.length," ticked listing",k.length===1?"":"s"," below. Untick any you want to skip â nothing changes until you confirm."]})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-xs font-medium uppercase tracking-wide text-muted-foreground",children:"Video being applied"}),i?e.jsx(Sa,{url:i}):e.jsxs("p",{className:"text-sm text-muted-foreground break-all",children:["Uploaded video file",d?` â ${d.split("/").pop()}`:""]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-xs font-medium uppercase tracking-wide text-muted-foreground",children:"Listings that will be updated â untick any to exclude"}),e.jsx("ul",{className:"space-y-1",children:P.map(E=>{const U=!!(E.video_url||E.video_file_url),L=!!N[E.id];return e.jsx("li",{children:e.jsxs("label",{className:`flex items-start gap-3 rounded-md border px-3 py-2 text-sm min-h-[44px] cursor-pointer hover:bg-muted/50 ${L?"":"opacity-50"}`,children:[e.jsx(He,{className:"mt-0.5",checked:L,disabled:u,onCheckedChange:R=>C(me=>({...me,[E.id]:!!R}))}),U?e.jsx(ks,{className:"h-4 w-4 mt-0.5 shrink-0 text-amber-500"}):e.jsx(Ds,{className:"h-4 w-4 mt-0.5 shrink-0 text-primary"}),e.jsxs("span",{className:"min-w-0",children:[e.jsx("span",{className:"block truncate font-medium",children:E.business_name}),e.jsx("span",{className:"text-xs text-muted-foreground",children:L?U?"Already has a video â it will be replaced":"No video yet â this will be added":"Excluded â won't be changed"})]})]})},E.id)})}),H>0&&e.jsxs("p",{className:"text-xs text-amber-600 dark:text-amber-400",children:[H," existing video",H===1?"":"s"," will be overwritten."]})]})]}),e.jsxs(gt,{className:"gap-2 sm:gap-2",children:[e.jsx(_,{variant:"outline",className:"min-h-[44px]",onClick:()=>x(!1),disabled:u,children:"Back"}),e.jsx(_,{onClick:$,disabled:u||k.length===0,className:"min-h-[44px]",children:u?e.jsxs(e.Fragment,{children:[e.jsx(ie,{className:"h-4 w-4 mr-2 animate-spin"})," Applyingâ¦"]}):e.jsxs(e.Fragment,{children:["Confirm & apply to ",k.length]})})]})]})})]})}const ht=200;function bn({contractorId:s,userId:t,hasVideoAddon:i,videoUrl:d,videoFileUrl:a}){const{toast:m}=je(),n=ve(),[p,N]=c.useState(!1),[C,u]=c.useState(!1),[g,w]=c.useState(!1),[b,A]=c.useState(null),[x,j]=c.useState(d||""),[v,l]=c.useState(d),[f,h]=c.useState(a),{kind:P,host:k}=ba(x),H=c.useRef(null),$=c.useRef(null),re=async()=>{N(!0);try{const{data:K,error:O}=await D.functions.invoke("create-checkout",{body:{contractorId:s,type:"video-addon",gaClientId:ps()}});if(O)throw O;K!=null&&K.url&&js(K.url)}catch(K){m({title:"Error",description:K.message,variant:"destructive"})}finally{N(!1)}},E=async()=>{u(!0);try{const{error:K}=await D.from("contractors").update({video_url:x.trim()||null}).eq("id",s);if(K)throw K;l(x.trim()||null),n.invalidateQueries({queryKey:["my-contractors"]}),m({title:"Video URL saved!"})}catch(K){m({title:"Error",description:K.message,variant:"destructive"})}finally{u(!1)}},U=async K=>{var B;const O=(B=K.target.files)==null?void 0:B[0];if(O){if(O.size>ht*1024*1024){m({title:"File too large",description:`Video must be under ${ht}MB.`,variant:"destructive"});return}w(!0),A({phase:"compressing",loaded:0,total:O.size,percent:0,message:"Preparing videoâ¦"});try{await Mr(O)&&m({title:"Resuming upload",description:"Picking up where the previous upload left off."});const se=await zr(O,xe=>A(xe)),ue=(se.name.split(".").pop()||"mp4").toLowerCase(),pe=`${t}/video-${Date.now()}.${ue}`,de=await Ir("contractor-images",pe,se,xe=>A(xe));H.current=de;const we=await de.promise;A({phase:"finalizing",loaded:se.size,total:se.size,percent:100,message:"Finalizingâ¦"});const{error:ce}=await D.from("contractors").update({video_file_url:we}).eq("id",s);if(ce)throw ce;h(we),n.invalidateQueries({queryKey:["my-contractors"]}),m({title:"Video uploaded!"})}catch(G){(G==null?void 0:G.message)==="upload_cancelled"?m({title:"Upload cancelled"}):m({title:"Upload failed",description:(G==null?void 0:G.message)??"
2Unknown error",variant:"destructive"})}finally{H.current=null,w(!1),A(null),$.current&&($.current.value="")}}},L=()=>{var K;(K=H.current)==null||K.cancel()},R=async K=>{try{const{error:O}=await D.from("contractors").update({[K]:null}).eq("id",s);if(O)throw O;K==="video_url"?(j(""),l(null)):h(null),n.invalidateQueries({queryKey:["my-contractors"]}),m({title:"Video removed"})}catch(O){m({title:"Error",description:O.message,variant:"destructive"})}};if(!i)return e.jsx(q,{className:"border-accent/40 bg-accent/5",children:e.jsx(M,{className:"p-6",children:e.jsxs("div",{className:"flex items-start gap-4",children:[e.jsx("div",{className:"flex h-12 w-12 shrink-0 items-center justify-center rounded-xl bg-accent/10 text-accent",children:e.jsx(Gt,{className:"h-6 w-6"})}),e.jsxs("div",{className:"flex-1",children:[e.jsxs("h3",{className:"font-heading font-semibold text-lg flex items-center gap-2",children:["Video Embed Add-on ",e.jsx(Ur,{className:"h-4 w-4 text-muted-foreground"})]}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:"Showcase your business with a promotional video on your profile. Embed YouTube/Vimeo or upload your own video file."}),e.jsxs("div",{className:"mt-4 flex items-center gap-3",children:[e.jsx("p",{className:"text-2xl font-bold font-heading",children:"$29.99"}),e.jsx(_,{onClick:re,disabled:p,children:p?e.jsxs(e.Fragment,{children:[e.jsx(ie,{className:"h-4 w-4 mr-2 animate-spin"})," Processing..."]}):"Purchase Video Add-on"})]})]})]})})});const me=(b==null?void 0:b.phase)==="compressing"?e.jsx(Or,{className:"h-4 w-4 animate-spin text-primary"}):e.jsx(ie,{className:"h-4 w-4 animate-spin text-primary"});return e.jsxs(q,{children:[e.jsxs(Z,{children:[e.jsxs(ee,{className:"flex items-center gap-2 text-lg",children:[e.jsx(Gt,{className:"h-5 w-5 text-primary"})," Video Embed",e.jsx(J,{variant:"secondary",className:"text-xs",children:"Active"})]}),e.jsxs(he,{children:["Embed a YouTube/Vimeo link or upload a video file (up to ",ht,"MB â large files are compressed and resumed automatically if the connection drops)"]})]}),e.jsxs(M,{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(W,{children:"Video link"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(Y,{value:x,onChange:K=>j(K.target.value),placeholder:"https://youtube.com/watch?v=..."}),e.jsx(_,{variant:"outline",onClick:E,disabled:C,children:C?e.jsx(ie,{className:"h-4 w-4 animate-spin"}):"Save"}),d&&e.jsx(_,{variant:"ghost",size:"icon",onClick:()=>R("video_url"),children:e.jsx(Ge,{className:"h-4 w-4 text-destructive"})})]}),x.trim()!==""&&P!=="invalid"&&e.jsx(Sa,{url:x.trim()}),P==="embed"&&e.jsx("p",{className:"text-xs text-muted-foreground",children:"â This plays inline on your listing page."}),P==="file"&&e.jsx("p",{className:"text-xs text-muted-foreground",children:"â Direct video file â plays inline on your listing page."}),P==="link"&&e.jsxs("p",{className:"text-xs text-muted-foreground",children:[`This page can't be embedded, so your listing will show a "Watch video" button that opens `,k," in a new tab. For an inline player, paste the YouTube or Vimeo link itself, or upload the video file below."]}),P==="invalid"&&x.trim()!==""&&e.jsx("p",{className:"text-xs text-destructive",children:"Enter a full URL starting with https://"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(W,{children:"Or Upload Video File"}),e.jsxs("div",{className:"flex items-center gap-3 flex-wrap",children:[e.jsxs("label",{className:"cursor-pointer",children:[e.jsx(_,{variant:"outline",asChild:!0,disabled:g,children:e.jsx("span",{children:g?e.jsxs(e.Fragment,{children:[e.jsx(ie,{className:"h-4 w-4 mr-2 animate-spin"})," Workingâ¦"]}):e.jsxs(e.Fragment,{children:[e.jsx(Xs,{className:"h-4 w-4 mr-2"})," Choose File"]})})}),e.jsx("input",{ref:$,type:"file",accept:"video/*",className:"hidden",onChange:U,disabled:g})]}),a&&!g&&e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"text-sm text-muted-foreground truncate max-w-[200px]",children:"Video uploaded â"}),e.jsx(_,{variant:"ghost",size:"icon",onClick:()=>R("video_file_url"),children:e.jsx(Ge,{className:"h-4 w-4 text-destructive"})})]})]}),g&&b&&e.jsxs("div",{className:"mt-3 rounded-lg border bg-muted/30 p-3 space-y-2",role:"status","aria-live":"polite",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[me,e.jsx("span",{className:"text-sm font-medium truncate",children:b.message})]}),e.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[e.jsxs("span",{className:"text-xs tabular-nums text-muted-foreground",children:[b.percent,"%"]}),b.phase==="uploading"&&e.jsxs(_,{variant:"ghost",size:"sm",className:"h-7 px-2",onClick:L,children:[e.jsx(ze,{className:"h-3.5 w-3.5 mr-1"})," Cancel"]})]})]}),e.jsx(st,{value:b.percent,className:"h-2"}),e.jsxs("p",{className:"text-[11px] text-muted-foreground",children:[b.phase==="compressing"&&"
2Shrinking your file in the browser so it uploads faster â no quality loss on the visible content.",b.phase==="uploading"&&"Uploading in chunks â if your connection drops, we'll resume from where you left off.",b.phase==="finalizing"&&"Saving your video to your profileâ¦"]})]})]}),e.jsx(vn,{contractorId:s,userId:t,videoUrl:v,videoFileUrl:f})]})]})}const yn={LAUNCH50:50,LAUNCH40:40,LAUNCH30:30,LAUNCH25:25,LAUNCH20:20,MOMENTUMINVESTOR:25,MOMENTUM26:25,MOMENTUM15:15,MOMENTUMWINNER:100};function Nn(s){const t=(s??"").trim();if(!t)return{status:"missing",code:null,percent:0};const i=t.toUpperCase(),d=yn[i];return d?{status:"matched",code:i,percent:d,label:`${d}% off your first annual renewal (one-time, first renewal only)`}:{status:"unrecognized",code:i,percent:0}}const sa=[{name:"Charcoal",accent:"#1f2937",watermark:"rgba(31,41,55,0.05)"},{name:"Ocean",accent:"#0369a1",watermark:"rgba(3,105,161,0.05)"},{name:"Forest",accent:"#15803d",watermark:"rgba(21,128,61,0.05)"},{name:"Berry",accent:"#9333ea",watermark:"rgba(147,51,234,0.05)"},{name:"Rust",accent:"#c2410c",watermark:"rgba(194,65,12,0.05)"},{name:"Slate",accent:"#475569",watermark:"rgba(71,85,105,0.05)"}];function wn({businessName:s,slug:t,phone:i,email:d,website:a,serviceArea:m,categoryName:n,logoUrl:p,description:N}){const[C,u]=c.useState(!1),[g,w]=c.useState(!0),[b,A]=c.useState(0),[x,j]=c.useState(""),[v,l]=c.useState(!1),f=c.useRef(null),h=c.useRef(null),P=xa(`${window.location.origin}/contractor/${t}`,"business_card","qr_code","print"),k=Zs(p)?null:p,H=/^#[0-9a-fA-F]{6}$/.test(x),$=c.useMemo(()=>{if(v&&H){const U=parseInt(x.slice(1,3),16),L=parseInt(x.slice(3,5),16),R=parseInt(x.slice(5,7),16);return{name:"Custom",accent:x,watermark:`rgba(${U},${L},${R},0.05)`}}return sa[b]},[v,H,x,b]),re=c.useCallback(async()=>{if(f.current){u(!0);try{const U={scale:4,useCORS:!0,backgroundColor:"#ffffff"},L=await Qe(f.current,U),R=.125,me=3.5,K=2,O=me+R*2,B=K+R*2,G=new Ts({unit:"in",format:[O,B],orientation:"landscape"});G.addImage(L.toDataURL("image/png"),"PNG",R,R,me,K);const se=.1;if(G.setDrawColor(0),G.setLineWidth(.003),G.line(R,0,R,se),G.line(0,R,se,R),G.line(O-R,0,O-R,se),G.line(O,R,O-se,R),G.line(R,B,R,B-se),G.line(0,B-R,se,B-R),G.line(O-R,B,O-R,B-se),G.line(O,B-R,O-se,B-R),g&&h.current){const ue=await Qe(h.current,U);G.addPage([O,B],"landscape"),G.addImage(ue.toDataURL("image/png"),"PNG",R,R,me,K),G.setDrawColor(0),G.setLineWidth(.003),G.line(R,0,R,se),G.line(0,R,se,R),G.line(O-R,0,O-R,se),G.line(O,R,O-se,R),G.line(R,B,R,B-se),G.line(0,B-R,se,B-R),G.line(O-R,B,O-R,B-se),G.line(O,B-R,O-se,B-R)}G.save(`${s.replace(/\s+/g,"-").toLowerCase()}-business-card.pdf`)}finally{u(!1)}}},[s,g]),E=c.useCallback(async U=>{if(f.current){u(!0);try{const L=s.replace(/\s+/g,"-").toLowerCase();await Tt(f.current,g?h.current:null,`${L}-business-card`,U)}finally{u(!1)}}},[s,g]);return e.jsx(q,{className:"mb-6",children:e.jsxs(M,{className:"p-4",children:[e.jsxs("div",{className:"flex items-start justify-between gap-4 flex-wrap",children:[e.jsxs("div",{children:[e.jsxs("p",{className:"font-semibold text-sm flex items-center gap-2",children:[e.jsx(Lt,{className:"h-4 w-4 text-primary"}),"Printable Business Card"]}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"Download a professional business card with your QR code. Perfect for handing out or printing."})]}),e.jsxs("div",{className:"flex items-center gap-4 shrink-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(De,{id:"double-sided",checked:g,onCheckedChange:w}),e.jsx(W,{htmlFor:"double-sided",className:"text-xs whitespace-nowrap cursor-pointer",children:"Double-sided"})]}),e.jsxs(_,{onClick:re,disabled:C,size:"sm",className:"gap-1.5 shrink-0",children:[e.jsx(Ps,{className:"h-3.5 w-3.5"}),C?"Generatingâ¦":"PDF"]}),e.jsxs(tt,{children:[e.jsx(at,{asChild:!0,children:e.jsxs(_,{variant:"outline",size:"sm",disabled:C,className:"gap-1.5 shrink-0",children:[e.jsx(ms,{className:"h-3.5 w-3.5"})," Image"]})}),e.jsxs(rt,{children:[e.jsx(Ie,{onClick:()=>E("png"),children:"Download PNG"}),e.jsx(Ie,{onClick:()=>E("jpeg"),children:"Download JPEG"})]})]})]})]}),e.jsxs("div",{className:"mt-3 flex items-center gap-2 flex-wrap",children:[e.jsx(ya,{className:"h-3.5 w-3.5 text-muted-foreground shrink-0"}),e.jsx("span",{className:"text-xs text-muted-foreground mr-1",children:"Theme:"}),sa.map((U,L)=>e.jsx("button",{type:"button",title:U.name,onClick:()=>{A(L),l(!1)},className:`h-6 w-6 rounded-full border-2 transition-all shrink-0 ${!v&&L===b?"border-foreground scale-110 ring-2 ring-ring ring-offset-1 ring-offset-background":"border-transparent hover:border-muted-foreground
2/40"}`,style:{backgroundColor:U.accent}},U.name)),e.jsxs("div",{className:"flex items-center gap-1.5 ml-1",children:[e.jsx(Y,{type:"text",placeholder:"#4f46e5",maxLength:7,value:x,onChange:U=>{let L=U.target.value;L&&!L.startsWith("#")&&(L="#"+L),L=L.slice(0,1)+L.slice(1).replace(/[^0-9a-fA-F]/g,""),j(L.slice(0,7)),/^#[0-9a-fA-F]{6}$/.test(L.slice(0,7))&&l(!0)},className:`h-7 w-20 text-xs font-mono px-2 ${v&&H?"ring-2 ring-ring border-foreground":""}`}),v&&H&&e.jsx("div",{className:"h-6 w-6 rounded-full border-2 border-foreground shrink-0",style:{backgroundColor:x}})]})]}),e.jsxs("div",{ref:f,className:"mt-4 rounded-lg border-2 border-border bg-white p-5 flex items-stretch gap-4 max-w-md shadow-sm",style:{width:420,minHeight:240},children:[e.jsx("div",{className:"w-1.5 rounded-full shrink-0",style:{backgroundColor:$.accent}}),e.jsxs("div",{className:"flex-1 min-w-0 flex flex-col justify-between py-0.5",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-3 mb-3",children:[k?e.jsx("img",{src:k,alt:s,className:"h-11 w-11 rounded object-cover",crossOrigin:"anonymous"}):e.jsx("div",{className:"h-11 w-11 rounded flex items-center justify-center text-lg font-bold text-white",style:{backgroundColor:$.accent},children:s.charAt(0)}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"font-heading font-bold text-sm text-gray-900 truncate leading-tight",children:s}),n&&e.jsx("p",{className:"text-[10px] uppercase tracking-wide mt-0.5",style:{color:$.accent},children:n})]})]}),e.jsx("hr",{className:"border-gray-200 mb-2.5"}),e.jsxs("div",{className:"space-y-2 text-xs text-gray-700",children:[i&&e.jsxs("p",{className:"flex items-center gap-2",children:[e.jsx(Ws,{className:"h-3 w-3 text-gray-400 shrink-0"}),i]}),d&&e.jsxs("p",{className:"flex items-center gap-2 truncate",children:[e.jsx(nt,{className:"h-3 w-3 text-gray-400 shrink-0"}),d]}),a&&e.jsxs("p",{className:"flex items-center gap-2 truncate",children:[e.jsx(ft,{className:"h-3 w-3 text-gray-400 shrink-0"}),a.replace(/^https?:\/\//,"")]}),m&&e.jsxs("p",{className:"flex items-center gap-2",children:[e.jsx(Ve,{className:"h-3 w-3 text-gray-400 shrink-0"}),m]})]})]}),e.jsx("p",{className:"text-[9px] text-gray-300 mt-2.5",children:"townsy.app"})]}),e.jsxs("div",{className:"shrink-0 flex flex-col items-center justify-center gap-1.5",children:[e.jsx("div",{className:"rounded border border-gray-200 bg-white p-2",children:e.jsx(ds,{value:P,size:72,level:"M",fgColor:$.accent})}),e.jsx("span",{className:"text-[9px] text-gray-400",children:"Scan to view"})]})]}),g&&e.jsxs("div",{ref:h,className:"mt-4 rounded-lg border-2 border-border bg-white p-5 max-w-md shadow-sm relative overflow-hidden",style:{width:420,minHeight:240},children:[e.jsx("div",{className:"absolute inset-0 flex items-center justify-center pointer-events-none select-none","aria-hidden":"true",children:e.jsx("span",{className:"text-[72px] font-heading font-black tracking-widest uppercase",style:{color:$.watermark,transform:"rotate(-18deg)"},children:"TOWNSY"})}),e.jsx("div",{className:"w-full h-1 rounded-full mb-4",style:{backgroundColor:$.accent}}),e.jsxs("div",{className:"relative z-10 space-y-3",children:[e.jsxs("p",{className:"font-heading font-bold text-xs text-gray-900 uppercase tracking-wide",children:["About ",s]}),e.jsx("p",{className:"text-[11px] leading-relaxed text-gray-600 line-clamp-5",children:N||"Professional services you can trust. Visit our profile to learn more about our work and see reviews from satisfied customers."}),e.jsx("hr",{className:"border-gray-200"}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ft,{className:"h-3 w-3",style:{color:$.accent}}),e.jsxs("span",{className:"text-[10px] text-gray-500",children:["townsy.app/",t]})]}),e.jsx("span",{className:"text-[9px] text-gray-300 italic",children:"Your Local Business Directory"})]})]})]})]})})}const _n="https://townsy.ai",kn="[email protected]";function Cn(){const[s,t]=c.useState(!1),[i,d]=c.useState(!0),a=c.useRef(null),m=c.useRef(null),n=c.useCallback(async()=>
2{if(a.current){t(!0);try{const N={scale:4,useCORS:!0,backgroundColor:"#ffffff"},C=await Qe(a.current,N),u=.125,g=3.5+u*2,w=2+u*2,b=new Ts({unit:"in",format:[g,w],orientation:"landscape"});b.addImage(C.toDataURL("image/png"),"PNG",u,u,3.5,2);const A=.1;if(b.setDrawColor(0),b.setLineWidth(.003),b.line(u,0,u,A),b.line(0,u,A,u),b.line(g-u,0,g-u,A),b.line(g,u,g-A,u),b.line(u,w,u,w-A),b.line(0,w-u,A,w-u),b.line(g-u,w,g-u,w-A),b.line(g,w-u,g-A,w-u),i&&m.current){const x=await Qe(m.current,N);b.addPage([g,w],"landscape"),b.addImage(x.toDataURL("image/png"),"PNG",u,u,3.5,2),b.setDrawColor(0),b.setLineWidth(.003),b.line(u,0,u,A),b.line(0,u,A,u),b.line(g-u,0,g-u,A),b.line(g,u,g-A,u),b.line(u,w,u,w-A),b.line(0,w-u,A,w-u),b.line(g-u,w,g-u,w-A),b.line(g,w-u,g-A,w-u)}b.save("townsy-business-card.pdf")}finally{t(!1)}}},[i]),p=c.useCallback(async N=>{if(a.current){t(!0);try{await Tt(a.current,i?m.current:null,"townsy-business-card",N)}finally{t(!1)}}},[i]);return e.jsx(q,{className:"mb-6",children:e.jsxs(M,{className:"p-4",children:[e.jsxs("div",{className:"flex items-start justify-between gap-4 flex-wrap",children:[e.jsxs("div",{children:[e.jsxs("p",{className:"font-semibold text-sm flex items-center gap-2",children:[e.jsx(Lt,{className:"h-4 w-4 text-primary"}),"Townsy⢠Business Card"]}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"Download a branded Townsy⢠business card to hand out at events and meetings."})]}),e.jsxs("div",{className:"flex items-center gap-4 shrink-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(De,{id:"townsy-double",checked:i,onCheckedChange:d}),e.jsx(W,{htmlFor:"townsy-double",className:"text-xs whitespace-nowrap cursor-pointer",children:"Double-sided"})]}),e.jsxs(_,{onClick:n,disabled:s,size:"sm",className:"gap-1.5 shrink-0",children:[e.jsx(Ps,{className:"h-3.5 w-3.5"}),s?"Generatingâ¦":"PDF"]}),e.jsxs(tt,{children:[e.jsx(at,{asChild:!0,children:e.jsxs(_,{variant:"outline",size:"sm",disabled:s,className:"gap-1.5 shrink-0",children:[e.jsx(ms,{className:"h-3.5 w-3.5"})," Image"]})}),e.jsxs(rt,{children:[e.jsx(Ie,{onClick:()=>p("png"),children:"Download PNG"}),e.jsx(Ie,{onClick:()=>p("jpeg"),children:"Download JPEG"})]})]})]})]}),e.jsxs("div",{ref:a,className:"mt-4 rounded-lg border-2 border-border bg-white overflow-hidden max-w-md shadow-sm",style:{width:420,minHeight:240},children:[e.jsx("div",{className:"h-2.5",style:{background:"linear-gradient(90deg, #f97316, #eab308, #22c55e, #3b82f6, #8b5cf6, #ec4899)"}}),e.jsxs("div",{className:"p-4 space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("img",{src:"/townsy-logo.png",alt:"Townsy",className:"h-14 w-14 rounded object-contain",crossOrigin:"anonymous"}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"font-heading font-bold text-xl text-gray-900 tracking-tight leading-none",children:"Townsyâ¢"}),e.jsx("p",{className:"text-[10px] uppercase tracking-widest text-gray-500 mt-0.5",children:"Local Business Directory"})]})]}),e.jsxs("div",{className:"shrink-0 flex flex-col items-center gap-1",children:[e.jsx("div",{className:"rounded-lg border border-gray-200 bg-white p-1.5",children:e.jsx(ds,{value:_n,size:64,level:"M",fgColor:"#1f2937"})}),e.jsx("span",{className:"text-[8px] text-gray-400 font-medium",children:"Scan to visit"})]})]}),e.jsx("hr",{className:"border-gray-200"}),e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs("p",{className:"flex items-center gap-1.5 text-xs font-semibold text-gray-800",children:[e.jsx(kt,{className:"h-3.5 w-3.5 text-gray-400"}),"Elliott R. Lynch â Community Consultant"]}),e.jsxs("p",{className:"flex items-center gap-1.5 text-xs text-gray-700",children:[e.jsx(Ws,{className:"h-3.5 w-3.5 text-gray-400"}),"(336) 693-4459"]}),e.jsxs("p",{className:"flex items-center gap-1.5 text-xs text-gray-700",children:[e.jsx(nt,{className:"h-3.5 w-3.5 text-gray-400"}),kn]})]}),e.jsxs("div",{className:"space-y-1.5 text-right",children:[e.jsxs("p",{className:"flex items-center justify-end gap-1.5 text-xs font-medium text-gray-700",children:[e.jsx(ft,{className:"h-3.5 w-3.5 text-gray-400"}),"townsy.ai"]}),e.jsxs("p",{className:"flex items-center justify-end gap-1.5 text-xs text-gray-700",children:[e.jsx(Ve,{className:"h-3.5 w-3.5 text-gray-400"}),"North Carolina"]})]})]}),e.jsx("p",{className:"text-center text-[11px] font-bold text-gray-800 italic tracking-wide",children:"Your Town. Your People. Your Deals."})]})]}),i&&e.jsxs("div",{ref:m,className:"mt-4 rounded-lg border-2 border-border bg-white p-5 max-w-md
2shadow-sm relative overflow-hidden",style:{width:420,minHeight:240},children:[e.jsx("div",{className:"absolute inset-0 flex items-center justify-center pointer-events-none select-none","aria-hidden":"true",children:e.jsx("span",{className:"text-[72px] font-heading font-black tracking-widest uppercase",style:{color:"rgba(31,41,55,0.04)",transform:"rotate(-18deg)"},children:"TOWNSY"})}),e.jsx("div",{className:"w-full h-1.5 rounded-full mb-3",style:{background:"linear-gradient(90deg, #f97316, #eab308, #22c55e, #3b82f6, #8b5cf6, #ec4899)"}}),e.jsxs("div",{className:"relative z-10 space-y-3",children:[e.jsx("p",{className:"font-heading font-bold text-sm text-gray-900 uppercase tracking-wide",children:"About Townsyâ¢"}),e.jsx("p",{className:"text-[11px] leading-relaxed text-gray-600",children:"Townsy⢠connects communities with trusted local businesses, events, deals, and classifieds â all in one place. Whether you're searching for a plumber, a nearby restaurant, or weekend events, Townsy⢠makes it easy to discover and support local."}),e.jsx("hr",{className:"border-gray-200"}),e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{className:"flex items-center gap-3 text-[10px] text-gray-500",children:[e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(Ct,{className:"h-3 w-3 text-gray-400"})," Businesses"]}),e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(qa,{className:"h-3 w-3 text-gray-400"})," Events"]}),e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(St,{className:"h-3 w-3 text-gray-400"})," Deals"]})]}),e.jsx("div",{className:"text-right",children:e.jsx("p",{className:"text-[11px] font-bold text-gray-700",children:"townsy.ai"})})]}),e.jsx("p",{className:"text-center text-[11px] font-semibold italic text-gray-500 tracking-wide mt-2",children:"Your Community Growth Engine â Let's Grow Together!"})]})]})]})})}const Aa="https://townsy.ai",Da="https://townsy.ai/advertise",ta=420,aa=660,$s=[{id:"rainbow",name:"Townsy Rainbow",bandGradient:"linear-gradient(90deg, #f97316, #eab308, #22c55e, #3b82f6, #8b5cf6, #ec4899)",watermark:"rgba(31,41,55,0.04)",accentBg:"#fff7ed",accentBorder:"#fdba74",accentText:"#c2410c",qrColor:"#0f172a"},{id:"sunset",name:"Sunset",bandGradient:"linear-gradient(90deg, #f97316, #ef4444, #ec4899)",watermark:"rgba(234,88,12,0.05)",accentBg:"#fff1f2",accentBorder:"#fda4af",accentText:"#be123c",qrColor:"#7c2d12"},{id:"ocean",name:"Ocean",bandGradient:"linear-gradient(90deg, #06b6d4, #3b82f6, #6366f1)",watermark:"rgba(30,58,138,0.05)",accentBg:"#eff6ff",accentBorder:"#93c5fd",accentText:"#1d4ed8",qrColor:"#0c4a6e"},{id:"forest",name:"Forest",bandGradient:"linear-gradient(90deg, #16a34a, #15803d, #0f766e)",watermark:"rgba(20,83,45,0.05)",accentBg:"#f0fdf4",accentBorder:"#86efac",accentText:"#15803d",qrColor:"#14532d"},{id:"mono",name:"Mono",bandGradient:"linear-gradient(90deg, #111827, #374151, #6b7280)",watermark:"rgba(17,24,39,0.05)",accentBg:"#f3f4f6",accentBorder:"#9ca3af",accentText:"#111827",qrColor:"#111827"}],ra={brand:"TOWNSY",tagline:"Your Town. Your People. Your Deals.",discoverList:`Local Businesses 3Restaurants 4Events 5Deals & Coupons 6Community Resources`,stat1Value:ut(qs.listingCount),stat1Label:"Local Businesses",stat2Value:ut(qs.impressions),stat2Label:"Impressions",stat3Value:ut(qs.interactions),stat3Label:"Interactions",stat4Value:Hr(qs.avgSessionMinutes),stat4Label:"Avg Session",frontQrUrl:Aa,frontQrCaption:"Scan to Explore Townsy",backHeadline:"Own a Local Business?",backSubhead:"Get discovered by customers already searching locally.",backFeatures:`Business Listings 7Events 8Deals & Coupons 9Community Feed 10Push Notifications 11Self-Service Dashboard`,promoHeadline:"Launch Promotions End September 1",promoSub:"Claim your free founding listing before pricing changes.",ctaLabel:"Claim Your Listing",ctaUrl:"Townsy.ai/advertise",backQrUrl:Da,backQrCaption:"Scan to get started"};function Sn(){const[s,t]=c.useState(!1),[i,d]=c.useState(!0),[a,m]=c.useState($s[0].id),[n,p]=c.useState(ra),[N,C]=c.useState(!1),u=c.useRef(null),g=c.useRef(null),w=c.useMemo(()=>$s.find(l=>l.id===a)??$s[0],[a]),b=c.useMemo(()=>n.discoverList.split(` 12`).map(l=>
12l.trim()).filter(Boolean),[n.discoverList]),A=c.useMemo(()=>n.backFeatures.split(` 13`).map(l=>l.trim()).filter(Boolean),[n.backFeatures]),x=(l,f)=>p(h=>({...h,[l]:f})),j=c.useCallback(async l=>{if(u.current){t(!0);try{await Tt(u.current,i?g.current:null,"townsy-palm-card-3.5x5.5",l,4)}finally{t(!1)}}},[i]),v=c.useCallback(async()=>{if(u.current){t(!0);try{const l={scale:4,useCORS:!0,backgroundColor:"#ffffff"},f=.125,h=3.5,P=5.5,k=h+f*2,H=P+f*2,$=new Ts({unit:"in",format:[k,H],orientation:"portrait"}),re=()=>{$.setDrawColor(0),$.setLineWidth(.003),$.line(f,0,f,.1),$.line(0,f,.1,f),$.line(k-f,0,k-f,.1),$.line(k,f,k-.1,f),$.line(f,H,f,H-.1),$.line(0,H-f,.1,H-f),$.line(k-f,H,k-f,H-.1),$.line(k,H-f,k-.1,H-f)},E=await Qe(u.current,l);if($.addImage(E.toDataURL("image/png"),"PNG",f,f,h,P),re(),i&&g.current){const U=await Qe(g.current,l);$.addPage([k,H],"portrait"),$.addImage(U.toDataURL("image/png"),"PNG",f,f,h,P),re()}$.save("townsy-palm-card-3.5x5.5.pdf")}finally{t(!1)}}},[i]);return e.jsx(q,{className:"mb-6",children:e.jsxs(M,{className:"p-4",children:[e.jsxs("div",{className:"flex items-start justify-between gap-4 flex-wrap",children:[e.jsxs("div",{children:[e.jsxs("p",{className:"font-semibold text-sm flex items-center gap-2",children:[e.jsx(Lt,{className:"h-4 w-4 text-primary"}),'Townsy⢠Palm Card â 3.5" à 5.5"']}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"Pocket-sized mini-postcard. Editable copy, brand templates, print-ready PDF."})]}),e.jsxs("div",{className:"flex items-center gap-2 shrink-0 flex-wrap",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(De,{id:"palm-double",checked:i,onCheckedChange:d}),e.jsx(W,{htmlFor:"palm-double",className:"text-xs whitespace-nowrap cursor-pointer",children:"Double-sided"})]}),e.jsxs(_,{onClick:v,disabled:s,size:"sm",className:"gap-1.5",children:[e.jsx(Cs,{className:"h-3.5 w-3.5"}),s?"Generatingâ¦":"PDF"]}),e.jsxs(tt,{children:[e.jsx(at,{asChild:!0,children:e.jsxs(_,{variant:"outline",size:"sm",disabled:s,className:"gap-1.5",children:[e.jsx(ms,{className:"h-3.5 w-3.5"})," Image"]})}),e.jsxs(rt,{children:[e.jsx(Ie,{onClick:()=>j("png"),children:"Download PNG"}),e.jsx(Ie,{onClick:()=>j("jpeg"),children:"Download JPEG"})]})]})]})]}),e.jsxs("div",{className:"mt-4",children:[e.jsx("p",{className:"text-[11px] uppercase tracking-wider font-semibold text-muted-foreground mb-2",children:"Brand template"}),e.jsx("div",{className:"flex flex-wrap gap-2",children:$s.map(l=>{const f=l.id===a;return e.jsxs("button",{type:"button",onClick:()=>m(l.id),className:`flex items-center gap-2 rounded-md border px-2.5 py-1.5 text-xs transition ${f?"border-primary ring-2 ring-primary/30 bg-primary/5":"border-border hover:bg-muted"}`,"aria-pressed":f,children:[e.jsx("span",{className:"inline-block h-4 w-8 rounded-sm",style:{background:l.bandGradient},"aria-hidden":"true"}),e.jsx("span",{className:"font-medium",children:l.name})]},l.id)})})]}),e.jsxs($a,{open:N,onOpenChange:C,className:"mt-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(Ma,{asChild:!0,children:e.jsxs(_,{variant:"ghost",size:"sm",className:"gap-1.5 px-2 -ml-2",children:[e.jsx(At,{className:"h-3.5 w-3.5"}),"Edit copy",e.jsx(za,{className:`h-3.5 w-3.5 transition-transform ${N?"rotate-180":""}`})]})}),N&&e.jsx(_,{variant:"ghost",size:"sm",className:"text-xs text-muted-foreground",onClick:()=>p(ra),children:"Reset to defaults"})]}),e.jsx(Ia,{className:"mt-3 rounded-md border bg-muted/30 p-3",children:e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsxs("fieldset",{className:"space-y-2",children:[e.jsx("legend",{className:"text-[11px] font-bold uppercase tracking-wider text-muted-foreground px-1",children:"Front"}),e.jsx(oe,{label:"Brand",children:e.jsx(Y,{value:n.brand,onChange:l=>x("brand",l.target.value)})}),e.jsx(oe,{label:"Tagline",children:e.jsx(Y,{value:n.tagline,onChange:l=>x("tagline",l.target.value)})}),e.jsx(oe,{label:"Discover list (one per line)",children:e.jsx(rs,{rows:4,value:n.discoverList,onChange:l=>x("discoverList",l.target.value)})}),e.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[e.jsx(oe,{label:"Stat 1 value",children:e.jsx(Y,{value:n.stat1Value,onChange:l=>x("stat1Value",l.target.value)})}),e.jsx(oe,{label:"Stat 1 label",children:e.jsx(Y,{value:n.stat1Label,onChange:l=>x("stat1Label",l.target.value)})}),e.jsx(oe,{label:"Stat 2 value",children:e.jsx(Y,{value:n.stat2Value,onChange:l=>x("stat2Value",l.target.value)})}),e.jsx(oe,{label:"Stat 2 label",children:e.jsx(Y,{value:n.stat2Label,onChange:l=>x("stat2Label",l.target.value)})}),e.jsx(oe,{label:"Stat 3 value",children:e.jsx(Y,{value:n.stat3Value,onChange:l=>x("stat3Value",l.target.value)})}),e.jsx(oe,{label:"Stat 3 label",children:e.jsx(Y,{value:n.stat3Label,onChange:l=>x("stat3Label",l.target.value)})}),e.jsx(oe,{label:"Stat 4 value",children:e.jsx(Y,{value:n.stat4Value,onChange:l=>x("stat4Value",l.target.value)})}),e.jsx(oe,{label:"Stat 4 label",children:e.jsx(Y,{value:n.stat4Label,onChange:l=>x("stat4Label",l.target.value)})})]}),e.jsx(oe,{label:"Front QR URL",children:e.jsx(Y,{value:n.frontQrUrl,onChange:l=>x("frontQrUrl",l.target.value)})}),e.jsx(oe,{label:"Front QR caption",children:e.jsx(Y,{value:n.frontQrCaption,onChange:l=>x("frontQrCaption",l.target.value)})})]}),e.jsxs("fieldset",{className:"space-y-2",children:[e.jsx("legend",{className:"text-[11px] font-bold uppercase tracking-wider text-muted-foreground px-1",children:"Back"}),e.jsx(oe,{label:"Headline",children:e.jsx(Y,{value:n.backHeadline,onChange:l=>x("backHeadline",l.target.value)})}),e.jsx(oe,{label:"Subhead",children:e.jsx(Y,{value:n.backSubhead,onChange:l=>x("backSubhead",l.target.value)})}),e.jsx(oe,{label:"Features (one per line)",children:e.jsx(rs,{rows:6,value:n.backFeatures,onChange:l=>x("backFeatures",l.target.value)})}),e.jsx(oe,{label:"Promo headline",children:e.jsx(Y,{value:n.promoHeadline,onChange:l=>x("promoHeadline",l.target.value)})}),e.jsx(oe,{label:"Promo sub",children:e.jsx(Y,{value:n.promoSub,onChange:l=>x("promoSub",l.target.value)})}),e.jsx(oe,{label:"CTA label",children:e.jsx(Y,{value:n.ctaLabel,onChange:l=>x("ctaLabel",l.target.value)})}),e.jsx(oe,{label:"CTA URL (display)",children:e.jsx(Y,{value:n.ctaUrl,onChange:l=>x("ctaUrl",l.target.value)})}),e.jsx(oe,{label:"Back QR URL",children:e.jsx(Y,{value:n.backQrUrl,onChange:l=>x("backQrUrl",l.target.value)})}),e.jsx(oe,{label:"Back QR caption",children:e.jsx(Y,{value:n.backQrCaption,onChange:l=>x("backQrCaption",l.target.value)})})]})]})})]}),e.jsxs("div",{className:"mt-4 flex flex-wrap gap-6",children:[e.jsxs("div",{ref:u,className:"rounded-xl border-2 border-border bg-white overflow-hidden shadow-sm relative",style:{width:ta,height:aa},children:[e.jsx("div",{className:"h-3",style:{background:w.bandGradient}}),e.jsxs("div",{className:"px-6 pt-5 pb-6 flex flex-col h-[calc(100%-12px)]",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("img",{src:"/townsy-logo.png",alt:"Townsy",className:"h-12 w-12 rounded object-contain",crossOrigin:"anonymous"}),e.jsxs("div",{children:[e.jsx("p",{className:"font-heading font-black text-3xl text-gray-900 tracking-tight leading-none",children:n.brand}),e.jsx("p",{className:"text-[10px] uppercase tracking-[0.18em] text-gray-500 mt-1",children:"townsy.ai"})]})]}),e.jsx("p",{className:"mt-3 text-[12px] font-semibold italic text-gray-700 tracking-wide",children:n.tagline}),e.jsxs("div",{className:"mt-4",children:[e.jsx("p",{className:"text-[10px] uppercase tracking-[0.15em] text-gray-500 font-bold mb-1.5",children:"Discover"}),e.jsx("div",{className:"grid grid-cols-2 gap-x-3 gap-y-1 text-[11px] text-gray-800",children:b.map((l,f)=>e.jsxs("span",{className:f===b.length-1&&b.length%2===1?"col-span-2":"",children:["⢠",l]},f))})]}),e.jsxs("div",{className:"mt-4 grid grid-cols-2 gap-2",children:[e.jsx(Ms,{icon:e.jsx(jt,{className:"h-3.5 w-3.5"}),value:n.stat1Value,label:n.stat1Label}),e.jsx(Ms,{icon:e.jsx(Ke,{className:"h-3.5 w-3.5"}),value:n.stat2Value,label:n.stat2Label}),e.jsx(Ms,{icon:e.jsx(ns,{className:"h-3.5 w-3.5"}),value:n.stat3Value,label:n.stat3Label}),e.jsx(Ms,{icon:e.jsx(Le,{className:"h-3.5 w-3.5"}),value:n.stat4Value,label:n.stat4Label})]}),e.jsxs("div",{className:"mt-auto pt-3 flex flex-col items-center",children:[e.jsx("div",{className:"rounded-lg border border-gray-200 bg-white p-2 shadow-sm",children:e.jsx(ds,{value:n.frontQrUrl||Aa,size:140,level:"M",fgColor:w.qrColor})}),e.jsx("p",{className:"mt-2 text-[11px] font-bold text-gray-800 uppercase tracking-[0.18em] text-center",children:n.frontQrCaption})]})]})]}),i&&e.jsxs("div",{ref:g,className:"rounded-xl border-2 border-border bg-white overflow-hidden shadow-sm relative",style:{width:ta,height:aa},children:[e.jsx("div",{className:"absolute inset-0 flex items-center justify-center pointer-events-none select-none","aria-hidden":"true",children:e.jsx("span",{className:"text-[96px] font-heading font-black tracking-widest uppercase",style:{color:w.watermark,transform:"rotate(-22deg)"},children:n.brand})}),e.jsx("div",{className:"h-3",style:{background:w.bandGradient}}),e.jsxs("div",{className:"relative z-10 px-6 pt-5 pb-6 flex flex-col h-[calc(100%-12px)]",children:[e.jsx("p",{className:"font-heading font-black text-2xl text-gray-900 leading-tight",children:n.backHeadline}),e.jsx("p",{className:"mt-2 text-[12px] text-gray-700 leading-relaxed",children:n.backSubhead}),e.jsx("ul",{className:"mt-4 space-y-1.5 text-[12px] text-gray-800",children:A.map(l=>e.jsxs("li",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"inline-flex items-center justify-center h-4 w-4 roun
13ded-full bg-green-100 text-green-700 text-[10px] font-bold",children:"â"}),l]},l))}),e.jsxs("div",{className:"mt-4 rounded-lg border-2 px-3 py-2 flex items-start gap-2",style:{background:w.accentBg,borderColor:w.accentBorder},children:[e.jsx(Na,{className:"h-4 w-4 mt-0.5 shrink-0",style:{color:w.accentText}}),e.jsxs("div",{children:[e.jsx("p",{className:"text-[11px] font-black uppercase tracking-wide",style:{color:w.accentText},children:n.promoHeadline}),e.jsx("p",{className:"text-[10px] mt-0.5",style:{color:w.accentText,opacity:.8},children:n.promoSub})]})]}),e.jsxs("div",{className:"mt-auto pt-3 flex items-center gap-3",children:[e.jsx("div",{className:"rounded-lg border border-gray-200 bg-white p-1.5",children:e.jsx(ds,{value:n.backQrUrl||Da,size:92,level:"M",fgColor:w.qrColor})}),e.jsxs("div",{className:"flex-1",children:[e.jsx("div",{className:"inline-block rounded-md bg-gray-900 text-white px-3 py-2 text-[12px] font-bold uppercase tracking-wide",children:n.ctaLabel}),e.jsx("p",{className:"mt-2 text-[12px] font-bold text-gray-900",children:n.ctaUrl}),e.jsx("p",{className:"text-[10px] text-gray-500 mt-0.5",children:n.backQrCaption})]})]})]})]})]}),e.jsx("p",{className:"mt-3 text-[11px] text-muted-foreground",children:'PDF exp
13orts at 3.5" à 5.5" with 0.125" bleed and trim marks â ready for any commercial printer.'})]})})}function oe({label:s,children:t}){return e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"text-[10px] uppercase tracking-wider font-semibold text-muted-foreground",children:s}),e.jsx("div",{className:"mt-1",children:t})]})}function Ms({icon:s,value:t,label:i}){return e.jsxs("div",{className:"rounded-md border border-gray-200 bg-gray-50/60 px-2.5 py-1.5",children:[e.jsxs("div",{className:"flex items-center gap-1.5 text-gray-500",children:[s,e.jsx("span",{className:"text-[9px] uppercase tracking-wider font-semibold",children:i})]}),e.jsx("p",{className:"text-[15px] font-black text-gray-900 leading-tight mt-0.5",children:t})]})}const na=[{name:"Charcoal",accent:"#1f2937"},{name:"Ocean",accent:"#0369a1"},{name:"Forest",accent:"#15803d"},{name:"Berry",accent:"#9333ea"},{name:"Rust",accent:"#c2410c"},{name:"Slate",accent:"#475569"}];function An({businessName:s,slug:t,categoryName:i,logoUrl:d,couponText:a}){const[m,n]=c.useState(!1),[p,N]=c.useState("letter"),[C,u]=c.useState("profile"),[g,w]=c.useState(0),[b,A]=c.useState(""),[x,j]=c.useState(!1),v=c.useRef(null),l=xa(`${window.location.origin}/contractor/${t}`,"store_flyer","qr_code","print"),f=Zs(d)?null:d,h=/^#[0-9a-fA-F]{6}$/.test(b),P=c.useMemo(()=>x&&h?b:na[g].accent,[x,h,b,g]),k=p==="letter",H=k?612:396,$=k?792:612,re=c.useCallback(async()=>{if(v.current){n(!0);try{const U=await Qe(v.current,{scale:4,useCORS:!0,backgroundColor:"#ffffff"}),L=.125,R=k?8.5:5.5,me=k?11:8.5,K=R+L*2,O=me+L*2,B=new Ts({unit:"in",format:[K,O],orientation:"portrait"});B.addImage(U.toDataURL("image/png"),"PNG",L,L,R,me);const G=.15;B.setDrawColor(0),B.setLineWidth(.003),B.line(L,0,L,G),B.line(0,L,G,L),B.line(K-L,0,K-L,G),B.line(K,L,K-G,L),B.line(L,O,L,O-G),B.line(0,O-L,G,O-L),B.line(K-L,O,K-L,O-G),B.line(K,O-L,K-G,O-L),B.save(`${s.replace(/\s+/g,"-").toLowerCase()}-store-printable.pdf`)}finally{n(!1)}}},[s,k]),E=c.useCallback(async U=>{if(v.current){n(!0);try{const L=s.replace(/\s+/g,"-").toLowerCase();await Br({element:v.current,filename:`${L}-store-printable`,format:U})}finally{n(!1)}}},[s]);return e.jsx(q,{className:"mb-6",children:e.jsxs(M,{className:"p-4",children:[e.jsxs("div",{className:"flex items-start justify-between gap-4 flex-wrap",children:[e.jsxs("div",{children:[e.jsxs("p",{className:"font-semibold text-sm flex items-center gap-2",children:[e.jsx(jt,{className:"h-4 w-4 text-primary"}),"In-Store QR Printable"]}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"Download a printable flyer with your QR code to display at your business."})]}),e.jsxs("div",{className:"flex items-center gap-3 shrink-0 flex-wrap",children:[e.jsxs(is,{value:C,onValueChange:U=>u(U),children:[e.jsx(ls,{className:"h-8 w-[150px] text-xs",children:e.jsx(os,{})}),e.jsxs(cs,{children:[e.jsx(ke,{value:"profile",children:e.jsxs("span",{className:"flex items-center gap-1.5",children:[e.jsx(jt,{className:"h-3 w-3"})," Find Us"]})}),e.jsx(ke,{value:"review",children:e.jsxs("span",{className:"flex items-center gap-1.5",children:[e.jsx(ss,{className:"h-3 w-3"})," Review Us"]})})]})]}),e.jsxs(is,{value:p,onValueChange:U=>N(U),children:[e.jsx(ls,{className:"h-8 w-[130px] text-xs",children:e.jsx(os,{})}),e.jsxs(cs,{children:[e.jsx(ke,{value:"letter",children:e.jsxs("span",{className:"flex items-center gap-1.5",children:[e.jsx(Cs,{className:"h-3 w-3"})," Full Page"]})}),e.jsx(ke,{value:"half",children:e.jsxs("span",{className:"flex items-center gap-1.5",children:[e.jsx(Cs,{className:"h-3 w-3"})," Half Page"]})})]})]}),e.jsxs(_,{onClick:re,disabled:m,size:"sm",className:"gap-1.5 shrink-0",children:[e.jsx(Ps,{className:"h-3.5 w-3.5"}),m?"Generatingâ¦":"PDF"]}),e.jsxs(tt,{children:[e.jsx(at,{asChild:!0,children:e.jsxs(_,{variant:"outline",size:"sm",disabled:m,className:"gap-1.5 shrink-0",children:[e.jsx(ms,{className:"h-3.5 w-3.5"})," Image"]})}),e.jsxs(rt,{children:[e.jsx(Ie,{onClick:()=>E("png"),children:"Download PNG"}),e.jsx(Ie,{onClick:()=>E("jpeg"),children:"Download JPEG"})]})]})]})]}),e.jsxs("div",{className:"mt-3 flex items-center gap-2 flex-wrap",children:[e.jsx(ya,{className:"h-3.5 w-3.5 text-muted-foreground shrink-0"}),e.jsx("span",{className:"text-xs text-muted-foreground mr-1",children:"Theme:"}),na.map((U,L)=>e.jsx("button",{type:"button",title:U.name,onClick:()=>{w(L),j(!1)},className:`h-6 w-6 rounded-full border-2 transition-all shrink-0 ${!x&&L===g?"border-foreground scale-110 ring-2 ring-ring ring-offset-1 ring-offset-background":"border-transparent hover:border-muted-foreground
13/40"}`,style:{backgroundColor:U.accent}},U.name)),e.jsxs("div",{className:"flex items-center gap-1.5 ml-1",children:[e.jsx(Y,{type:"text",placeholder:"#4f46e5",maxLength:7,value:b,onChange:U=>{let L=U.target.value;L&&!L.startsWith("#")&&(L="#"+L),L=L.slice(0,1)+L.slice(1).replace(/[^0-9a-fA-F]/g,""),A(L.slice(0,7)),/^#[0-9a-fA-F]{6}$/.test(L.slice(0,7))&&j(!0)},className:`h-7 w-20 text-xs font-mono px-2 ${x&&h?"ring-2 ring-ring border-foreground":""}`}),x&&h&&e.jsx("div",{className:"h-6 w-6 rounded-full border-2 border-foreground shrink-0",style:{backgroundColor:b}})]})]}),e.jsx("div",{className:"mt-4 flex justify-center",children:e.jsxs("div",{ref:v,className:"rounded-lg border-2 border-border bg-white shadow-sm overflow-hidden",style:{width:H*.55,height:$*.55,padding:k?32:24,display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"space-between"},children:[e.jsxs("div",{style:{width:"100%",textAlign:"center",borderBottom:`3px solid ${P}`,paddingBottom:k?14:10},children:[e.jsx("p",{style:{fontSize:k?11:9,color:"#9ca3af",letterSpacing:"0.15em",textTransform:"uppercase",margin:0},children:C==="review"?"We'd Love Your Feedback On":"Proudly Listed On"}),e.jsx("p",{style:{fontSize:k?28:20,fontWeight:900,color:P,margin:"4px 0 0",letterSpacing:"-0.02em"},children:"TOWNSY"})]}),e.jsxs("div",{style:{textAlign:"center",flex:1,display:"flex",flexDirection:"column",justifyContent:"center",gap:k?8:4},children:[f?e.jsx("img",{src:f,alt:s,crossOrigin:"anonymous",style:{width:k?56:40,height:k?56:40,borderRadius:8,objectFit:"cover",margin:"0 auto"}}):e.jsx("div",{style:{width:k?56:40,height:k?56:40,borderRadius:8,backgroundColor:P,color:"#fff",fontSize:k?24:18,fontWeight:700,display:"flex",alignItems:"center",justifyContent:"center",margin:"0 auto"},children:s.charAt(0)}),e.jsx("p",{style:{fontSize:k?22:16,fontWeight:800,color:"#111827",margin:0,lineHeight:1.2},children:s}),i&&e.jsx("p",{style:{fontSize:k?11:9,color:P,textTransform:"uppercase",letterSpacing:"0.1em",margin:0},children:i}),C==="review"?e.jsxs("div",{style:{marginTop:k?8:4,padding:k?"10px 16px":"8px 12px",backgroundColor:"#fef9c3",border:`2px solid ${P}30`,borderRadius:8,textAlign:"center"},children:[e.jsx("p",{style:{fontSize:k?20:15,margin:"0 0 4px",letterSpacing:"0.1em"},children:"âââââ"}),e.jsx("p",{style:{fontSize:k?14:11,fontWeight:800,color:P,margin:0},children:"Leave us a review!"}),e.jsx("p",{style:{fontSize:k?10:8,color:"#6b7280",margin:"4px 0 0"},children:"Your feedback helps our community"})]}):a?e.jsx("div",{style:{marginTop:k?8:4,padding:k?"8px 16px":"6px 12px",backgroundColor:"#fef3c7",border:"2px dashed #f59e0b",borderRadius:8,textAlign:"center"},children:e.jsxs("p",{style:{fontSize:k?13:10,fontWeight:700,color:"#92400e",margin:0},children:["ð ",a]})}):null]}),e.jsxs("div",{style:{textAlign:"center"},children:[e.jsx("div",{style:{display:"inline-block",padding:k?10:6,border:`2px solid ${P}20`,borderRadius:12,backgroundColor:"#fff"},children:e.jsx(ds,{value:l,size:k?110:80,level:"H",fgColor:P})}),e.jsx("p",{style:{fontSize:k?14:11,fontWeight:700,color:P,marginTop:k?10:6,marginBottom:0},children:C==="review"?"Scan to leave us a review on Townsyâ¢!":"Scan to view our profile, reviews & deals!"}),e.jsxs("p",{style:{fontSize:k?10:8,color:"#9ca3af",marginTop:4,marginBottom:0},children:["townsy.app/",t]})]}),e.jsx("div",{style:{width:"100%",borderTop:`2px solid ${P}15`,paddingTop:k?8:6,textAlign:"center"},children:e.jsx("p",{style:{fontSize:k?9:7,color:"#d1d5db",margin:0},children:"Your Town. Your People. Your Deals. â townsy.app"})})]})})]})})}function Dn({contractorId:s}){const{user:t}=be(),i=ve(),[d,a]=c.useState(""),[m,n]=c.useState(""),[p,N]=c.useState(""),[C,u]=c.useState(Ss(new Date,"yyyy-MM")),{data:g}=ae({queryKey:["my-gift-donations",t==null?void 0:t.id],queryFn:async()=>{const{data:x}=await D.from("gift_certificate_donations").select("*").eq("user_id",t.id).order("created_at",{ascending:!1}).limit(10);return x??[]},enabled:!!t}),{data:w}=ae({queryKey:["my-credit-balance",t==null?void 0:t.id],queryFn:async()=>{const{data:x}=await D.from("account_credits").select("amount_cents").eq("user_id",t.id);return(x??[]).reduce((j,v)=>j+v.amount_cents,0)},enabled:!!t}),b=fe({mutationFn:async()=>{const x=Math.round(parseFloat(m)*100);if(!x||x<=0)throw new Error("Enter a valid value");if(!d.trim())throw new Error("Enter a description");const{error:j}=await D.from("gift_certificate_donations").insert({user_id:t.id,contractor_id:s,description:d.trim(),value_cents:x,terms:p.trim()||null,prize_month:C});if(j)throw j},onSuccess:()=>{i.invalidateQueries({queryKey:["my-gift-donations"]}),Me.success("Gift certificate submitted for review!"),a(""),n(""),N("")},onError:x=>Me.error(x.message)}),A=x=>x==="approved"?"default":x==="rejected"?"destructive":"secondary";return e.jsxs(q,{children:[e.jsx(Z,{className:"pb-3",children:e.jsxs(ee,{className:"text-base flex items-center gap-2",children:[e.jsx(Be,{className:"h-4 w-4 text-primary"}),"Donate Gift Certificates for Prizes"]})}),e.jsxs(M,{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-2 rounded-lg border p-3 bg-primary/5",children:[e.jsx(ha,{className:"h-4 w-4 text-primary"}),e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-medium",children:"Account Credit Balance"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Applied to your next listing renewal"})]}),e.jsxs("span",{className:"ml-auto text-lg font-bold text-primary",children:["$",((w??0)/100).toFixed(2)]})]}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Donate a gift certificate for your goods or services as a monthly referral prize. You'll earn a ",e.jsx("strong",{children:"1:1 account credit"})," toward your next listing renewal."]}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(W,{children:"Gift Certificate Description *"}),e.jsx(Y,{placeholder:"e.g. $25 off any plumbing service",value:d,onChange:x=>a(x.target.value),maxLength:200})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(W,{children:"Value ($) *"}),e.jsxs("div",{className:"relative",children:[e.jsx(Ua,{className:"absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground"}),e.jsx(Y,{type:"number",min:"1",step:"0.01",placeholder:"25.00",value:m,onChange:x=>n(x.target.value),className:"pl-8"})]})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(W,{children:"Prize Month"}),e.jsx(Y,{type:"month",value:C,onChange:x=>u(x.target.value)})]})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(W,{children:"Terms / Conditions"}),e.jsx(rs,{placeholder:"e.g. Valid for 90 days, one per customer",value:p,onChange:x=>N(x.target.value),className:"h-16 resize-none",maxLength:500})]}),e.jsxs(_,{className:"w-full gap-2",disabled:!d.trim()||!m||b.isPending,onClick:()=>b.mutate(),children:[e.jsx(Gs,{className:"h-4 w-4"}),b.isPending?"Submittingâ¦":"Submit Gift Certificate"]})]}),g&&g.length>0&&e.jsxs("div",{className:"space-y-2 pt-2 border-t",children:[e.jsx("p",{className:"text-xs font-medium text-muted-foreground",children:"Your Submissions"}),g.map(x=>e.jsxs("div",{className:"flex items-center justify-between rounded-lg border p-2.5 text-sm",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"font-medium truncate",children:x.description}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["$",(x.value_cents/100).toFixed(2)," · ",x.prize_month]})]}),e.jsx(J,{variant:A(x.status),className:"text-xs shrink-0 ml-2",children:x.status})]},x.id))]})]})]})}const Pn=c.lazy(()=>Wr(()=>import("./ListingAnalyticsTrendChart-B51nvYci.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10])));function Tn({contractorIds:s,tier:t="basic"}){const i=t==="pro"||t==="premium",d=t==="premium",{data:a}=ae({queryKey:["listing-analytics",s],queryFn:async()=>
13{if(s.length===0)return{views:0,contacts:0,clicks:0,impressions:0};const{data:u}=await D.from("listing_analytics").select("event_type").in("contractor_id",s),g=u??[],w={views:0,contacts:0,clicks:0,impressions:0};for(const b of g)b.event_type==="view"?w.views++:b.event_type==="contact"?w.contacts++:b.event_type==="click"?w.clicks++:b.event_type==="impression"&&w.impressions++;return w},enabled:s.length>0});if(t==="free")return e.jsxs("div",{className:"mb-6 rounded-lg border border-dashed border-muted-foreground/30 p-6 text-center",children:[e.jsx(ts,{className:"h-5 w-5 mx-auto mb-2 text-muted-foreground"}),e.jsx("p",{className:"text-sm font-medium text-foreground",children:"Listing Analytics"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"Upgrade to Basic or higher to see how your listing is performing."})]});if(!a)return null;const m=[{label:"Profile Views",value:a.views,icon:Ke,color:"text-blue-500"},{label:"Contact Submissions",value:a.contacts,icon:Gs,color:"text-green-500"}],n=a.views>0?(a.contacts/a.views*100).toFixed(1):"0.0",p=[...m,{label:"Click-throughs",value:a.clicks,icon:Oa,color:"text-orange-500"},{label:"Conversion Rate",value:`${n}%`,icon:ts,color:"text-emerald-500"}],N=[...p,{label:"Search Impressions",value:a.impressions,icon:Ct,color:"text-purple-500"}],C=d?N:i?p:m;return e.jsxs("div",{className:"mb-6 space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ts,{className:"h-4 w-4 text-primary"}),e.jsxs("h3",{className:"font-heading text-sm font-semibold text-foreground",children:["Listing Analytics",!d&&e.jsx("span",{className:"ml-2 text-xs font-normal text-muted-foreground",children:t==="basic"?"Upgrade to Pro for click tracking & conversion rates":i?"Upgrade to Premium for full analytics":""})]})]}),e.jsx("div",{className:`grid gap-4 ${d?"grid-cols-2 sm:grid-cols-5":i?"grid-cols-2 sm:grid-cols-4":"grid-cols-2"}`,children:C.map(u=>e.jsx(q,{children:e.jsxs(M,{className:"p-4 text-center",children:[e.jsx(u.icon,{className:`h-5 w-5 mx-auto mb-1 ${u.color}`}),e.jsx("p",{className:"text-2xl font-bold",children:u.value}),e.jsx("p",{className:"text-xs text-muted-foreground",children:u.label})]})},u.label))}),d&&e.jsx(c.Suspense,{fallback:e.jsx("div",{className:"h-48 rounded-lg bg-muted/30 animate-pulse"}),children:e.jsx(Pn,{contractorIds:s})})]})}async function Ln(s){const t=[];for(const i of s){const{data:d}=await D.rpc("treasure_partner_for_contractor",{_slug:i}),a=d;a!=null&&a.participant_id&&t.push(a)}return t}const En=[["partner_impressions","Times shown on the Hunt"],["discover_clicks","Discover clicks"],["profile_views","Business page views"],["website_clicks","Website clicks"],["contact_clicks","Contact clicks"],["phone_clicks","Phone clicks"],["directions_clicks","Directions clicks"],["favorites","Saved as a favorite"],["deal_views","Deal views"],["deal_saves","Deal saves"],["deal_redemptions","Deal redemptions"],["qr_scans","Treasure Stop scans"]];function Rn({slugs:s}){const{data:t}=ae({queryKey:["treasure-partner-refs",s.join(",")],queryFn:()=>Ln(s),enabled:s.length>0}),i=(t??[]).map(a=>a.participant_id),{data:d}=ae({queryKey:["treasure-partner-results",i.join(",")],queryFn:async()=>(await Promise.all(i.map(m=>Kr(m)))).flat(),enabled:i.length>0});return!t||t.length===0?null:e.jsxs(q,{className:"mb-6 border-primary/30 bg-primary/5",children:[e.jsx(Z,{className:"pb-3",children:e.jsxs(ee,{className:"flex items-center gap-2 text-base",children:[e.jsx(Dt,{className:"h-4 w-4 text-primary"}),"2026 Townsy Treasure Hunt"]})}),e.jsxs(M,{className:"space-y-6",children:[t.map(a=>{const m=(d??[]).find(n=>n.participant_id===a.participant_id);return e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:"font-semibold",children:a.business_name}),e.jsx(J,{variant:"secondary",className:"capitalize",children:a.status.replace(/_/g," ")})]}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Treasure contributed: ",a.prize_description||"â",a.prize_value?` · $${Number(a.prize_value).toLocaleStr
13ing()}`:""]}),e.jsx("div",{className:"grid grid-cols-2 gap-2 sm:grid-cols-3",children:En.map(([n,p])=>e.jsxs("div",{className:"rounded-lg border bg-background p-2.5",children:[e.jsx("p",{className:"text-lg font-bold",children:m?Number(m[n]??0):0}),e.jsx("p",{className:"text-[11px] leading-tight text-muted-foreground",children:p})]},n))}),a.share_slug&&e.jsxs("div",{className:"flex items-center gap-3 rounded-lg border bg-background p-3",children:[e.jsx(ds,{value:Gr(a.share_slug),size:84,level:"Q"}),e.jsxs("div",{className:"text-xs text-muted-foreground",children:[e.jsx("p",{className:"font-medium text-foreground",children:"Your Treasure Stop QR code"}),e.jsx("p",{className:"mt-1",children:"Print it for your counter. Each hunter who scans it earns a bonus entry and lands on your business page."})]})]})]},a.participant_id)}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Repeat taps from the same visitor within 30 minutes are counted once, so these numbers reflect real interest."})]})]})}function Fn({contractorIds:s}){const t=ve(),[i,d]=c.useState(null),[a,m]=c.useState(""),[n,p]=c.useState("all"),{data:N,isLoading:C}=ae({queryKey:["contact-submissions",s],queryFn:async()=>{const{data:j}=await D.from("contact_submissions").select("*").in("contractor_id",s).order("created_at",{ascending:!1});return j??[]},enabled:s.length>0}),u=fe({mutationFn:async({id:j,is_read:v})=>{await D.from("contact_submissions").update({is_read:v}).eq("id",j)},onSuccess:()=>t.invalidateQueries({queryKey:["contact-submissions"]})}),g=fe({mutationFn:async j=>{await D.from("contact_submissions").delete().eq("id",j)},onSuccess:()=>{t.invalidateQueries({queryKey:["contact-submissions"]}),d(null),Me.success("Lead deleted")}}),w=fe({mutationFn:async()=>{const j=(N??[]).filter(v=>!v.is_read).map(v=>v.id);j.length!==0&&await D.from("contact_submissions").update({is_read:!0}).in("id",j)},onSuccess:()=>{t.invalidateQueries({queryKey:["contact-submissions"]}),Me.success("All leads marked as read")}}),b=c.useMemo(()=>{if(!N)return{total:0,unread:0,read:0,thisWeek:0};const j=new Date,v=new Date(j.getTime()-7*24*60*60*1e3);return{total:N.length,unread:N.filter(l=>!l.is_read).length,read:N.filter(l=>l.is_read).length,thisWeek:N.filter(l=>new Date(l.created_at)>=v).length}},[N]),A=c.useMemo(()=>{if(!N)return[];let j=N;if(n==="unread"&&(j=j.filter(v=>!v.is_read)),n==="read"&&(j=j.filter(v=>v.is_read)),a.trim()){const v=a.toLowerCase();j=j.filter(l=>{var f,h,P;return((f=l.name)==null?void 0:f.toLowerCase().includes(v))||((h=l.email)==null?void 0:h.toLowerCase().includes(v))||((P=l.message)==null?void 0:P.toLowerCase().includes(v))})}return j},[N,n,a]);if(C)return null;if(!(N!=null&&N.length)&&!C)return e.jsx(q,{className:"mb-6",children:e.jsxs(M,{className:"p-8 text-center",children:[e.jsx(Ys,{className:"h-10 w-10 mx-auto text-muted-foreground/40 mb-3"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"No customer inquiries yet."}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"When customers contact you through your listing, their messages will appear here."})]})});const x=[{label:"All",value:"all",icon:e.jsx(Ys,{className:"h-3.5 w-3.5"}),count:b.total},{label:"Unread",value:"unread",icon:e.jsx(Le,{className:"h-3.5 w-3.5"}),count:b.unread},{label:"Read",value:"read",icon:e.jsx(xt,{className:"h-3.5 w-3.5"}),count:b.read}];return e.jsxs("div",{className:"mb-6 space-y-4",children:[e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-3",children:[e.jsx(q,{children:e.jsxs(M,{className:"p-4 flex items-center gap-3",children:[e.jsx("div",{className:"p-2 rounded-lg bg-primary/10",children:e.jsx(Ys,{className:"h-4 w-4 text-primary"})}),e.jsxs("div",{children:[e.jsx("p",{className:"text-2xl font-bold",children:b.total}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Total Leads"})]})]})}),e.jsx(q,{children:e.jsxs(M,{className:"p-4 flex items-center gap-3",children:[e.jsx("div",{className:"p-2 rounded-lg bg-destructive/10",children:e.jsx(ns,{className:"h-4 w-4 text-destructive"})}),e.jsxs("div",{children:[e.jsx("p",{className:"text-2xl font-bold",children:b.unread}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Unread"})]})]})}),e.jsx(q,{children:e.jsxs(M,{className:"p-4 flex items-center gap-3",children:[e.jsx("div",{className:"p-2 rounded-lg bg-muted",children:e.jsx(xt,{className:"h-4 w-4 text-primary"})}),e.jsxs("div",{children:[e.jsx("p",{className:"text-2xl font-bold",children:b.read}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Reviewed"})]})]})}),e.jsx(q,{children:e.jsxs(M,{className:"p-4 flex items-center gap-3",children:[e.jsx("div",{className:"p-2 rounded-lg bg-accent",children:e.jsx(ts,{className:"h-4 w-4 text-accent-foreground"})}),e.jsxs("div",{children:[e.jsx("p",{className:"text-2xl font-bold",children:b.thisWeek}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"This Week"})]})]})})]}),e.jsxs(q,{children:[e.jsxs(Z,{className:"pb-3",children:[e.jsxs("div",{className:"flex items-center justify-between flex-wrap gap-2",children:[e.jsxs(ee,{className:"text-base font-semibold flex items-center gap-2",children:[e.jsx(ns,{className:"h-4 w-4 text-primary"}),"Lead Inbox",b.unread>0&&e.jsxs(J,{variant:"destructive",className:"text-[10px] px-1.5 py-0",children:[b.unread," new"]})]}),b.unread>0&&e.jsxs(_,{variant:"ghost",size:"sm",className:"text-xs gap-1.5",onClick:()=>w.mutate(),disabled:w.isPending,children:[e.jsx(xt,{className:"h-3.5 w-3.5"}),"Mark all read"]})]}),e.jsxs("div",{className:"flex items-center gap-2 mt-3 flex-wrap",children:[e.jsxs("div",{className:"relative flex-1 min-w-[180px]",children:[e.jsx(Ct,{className:"absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground"}),e.jsx(Y,{placeholder:"Search leads...",value:a,onChange:j=>m(j.target.value),className:"pl-8 h-8 text-sm"})]}),e.jsx("div",{className:"flex gap-1",children:x.map(j=>e.jsxs(_,{variant:n===j.value?"default":"outline",size:"sm",className:"text-xs gap-1.5 h-8",onClick:()=>
13p(j.value),children:[j.icon,j.label,e.jsxs("span",{className:"text-[10px] opacity-70",children:["(",j.count,")"]})]},j.value))})]})]}),e.jsx(M,{className:"space-y-2 max-h-[400px] overflow-y-auto",children:A.length===0?e.jsxs("div",{className:"text-center py-6",children:[e.jsx(wa,{className:"h-8 w-8 mx-auto text-muted-foreground/40 mb-2"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"No leads match your filters."})]}):A.map(j=>e.jsxs("div",{className:`flex items-start justify-between gap-3 p-3 rounded-lg border cursor-pointer transition-colors hover:bg-muted/50 ${j.is_read?"":"bg-primary/5 border-primary/20"}`,onClick:()=>{d(j),j.is_read||u.mutate({id:j.id,is_read:!0})},children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"font-medium text-sm truncate",children:j.name}),!j.is_read&&e.jsx("span",{className:"h-2 w-2 rounded-full bg-primary shrink-0"})]}),e.jsx("p",{className:"text-xs text-muted-foreground truncate",children:j.message}),e.jsxs("div",{className:"flex items-center gap-2 mt-1",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:as(new Date(j.created_at),{addSuffix:!0})}),j.phone&&e.jsxs(J,{variant:"outline",className:"text-[10px] px-1.5 py-0",children:[e.jsx(Ws,{className:"h-2.5 w-2.5 mr-0.5"})," Phone"]})]})]}),e.jsx("div",{className:"flex gap-1 shrink-0",children:e.jsx(_,{variant:"ghost",size:"icon",className:"h-7 w-7",onClick:v=>{v.stopPropagation(),u.mutate({id:j.id,is_read:!j.is_read})},children:j.is_read?e.jsx(Qt,{className:"h-3.5 w-3.5"}):e.jsx(Ke,{className:"h-3.5 w-3.5"})})})]},j.id))})]}),e.jsx(ys,{open:!!i,onOpenChange:j=>!j&&d(null),children:e.jsx(Ns,{className:"sm:max-w-md",children:i&&e.jsxs(e.Fragment,{children:[e.jsx(ws,{children:e.jsxs(_s,{className:"font-heading",children:["Lead from ",i.name]})}),e.jsxs("div",{className:"space-y-3 mt-2",children:[e.jsxs("div",{className:"flex flex-wrap gap-3 text-sm",children:[e.jsxs("a",{href:`mailto:${i.email}`,className:"flex items-center gap-1.5 text-primary hover:underline",children:[e.jsx(nt,{className:"h-4 w-4"})," ",i.email]}),i.phone&&e.jsxs("a",{href:`tel:${i.phone}`,className:"flex items-center gap-1.5 text-primary hover:underline",children:[e.jsx(Ws,{className:"h-4 w-4"})," ",i.phone]})]}),e.jsx("div",{className:"rounded-lg border p-3",children:e.jsx("p",{className:"text-sm whitespace-pre-wrap",children:i.message})}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Received ",Ss(new Date(i.created_at),"PPP 'at' p")," â¢"," ",as(new Date(i.created_at),{addSuffix:!0})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsxs(_,{variant:"outline",size:"sm",className:"gap-1.5 text-xs",onClick:()=>{const j=!i.is_read;u.mutate({id:i.id,is_read:j}),d({...i,is_read:j})},children:[i.is_read?e.jsx(Qt,{className:"h-3.5 w-3.5"}):e.jsx(Ke,{className:"h-3.5 w-3.5"}),i.is_read?"Mark unread":"Mark read"]}),e.jsxs(_,{variant:"destructive",size:"sm",className:"gap-1.5 text-xs",onClick:()=>g.mutate(i.id),children:[e.jsx(Ge,{className:"h-3.5 w-3.5"})," Delete"]})]})]})]})})})]})}function qn({contractorId:s,businessName:t,slug:i,categoryName:d,currentCoupon:a}){const m=(a||"").replace(/^\[SAMPLE\]\s*/i,""),[n,p]=c.useState(!1),[N,C]=c.useState(m),[u,g]=c.useState(!1),{toast:w}=je(),b=ve(),{data:A}=ae({queryKey:["coupon-pending-edit",s],queryFn:async()=>{const{data:f}=await D.from("coupon_pending_edits").select("id, status, proposed_text, admin_note, action, created_at, reviewed_at").eq("contractor_id",s).order("created_at",{ascending:!1}).limit(1).maybeSingle();return f}}),x=(A==null?void 0:A.status)==="pending",j=fe({mutationFn:async f=>{const{data:h}=await D.auth.getUser();if(!h.user)throw new Error("Not signed in");const P=f.trim(),k=P?m?"update":"create":"remove",{error:H}=await D.from("coupon_pending_edits").insert({contractor_id:s,submitted_by:h.user.id,action:k,proposed_text:P||null,previous_text:m||null,status:"pending",promotion_consent:P?u:!1,promotion_consent_version:P&&u?"coupon_promo_v1":null});if(H)throw H},onSuccess:()=>{w({title:"Submitted for review",description:"An admin will approve your coupon shortly. You'll see it live once approved."}),b.invalidateQueries({queryKey:["coupon-pending-edit",s]}),p(!1)},onError:f=>{w({title:"Error",description:f.message,variant:"destructive"})}}),v=()=>j.mutate(N),l=()=>{confirm("Submit a request to remove this coupon? An admin will review it.")&&j.mutate("")};return e.jsxs(q,{className:"mb-6 border-accent/30",children:[e.jsxs(Z,{className:"pb-3",children:[e.jsxs(ee,{className:"text-lg flex items-center gap-2",children:[e.jsx(Ks,{className:"h-5 w-5 text-accent"}),"Coupon Builder",e.jsx("span",{className:"ml-auto text-xs font-normal text-muted-foreground",children:"Admin-approved"})]}),e.jsx(he,{children:"Create a special offer that appears on your listing and the Local Coupons page. All coupon changes are reviewed by an admin before going live."})]}),e.jsxs(M,{className:"space-y-4",children:[x&&e.jsxs("div",{className:"rounded-md border border-amber-500/40 bg-amber-500/5 px-3 py-2 flex items-start gap-2",children:[e.jsx(Le,{className:"h-4 w-4 text-amber-600 mt-0.5 shrink-0"}),e.jsxs("div",{className:"text-xs",children:[e.jsx("div",{className:"font-medium text-amber-700 dark:text-amber-400",children:"Pending admin a
13pproval"}),e.jsxs("div",{className:"text-muted-foreground mt-0.5",children:["Proposed: ",e.jsx("span",{className:"font-medium",children:(A==null?void 0:A.proposed_text)||"(remove coupon)"})]})]})]}),(A==null?void 0:A.status)==="rejected"&&(A==null?void 0:A.admin_note)&&e.jsxs("div",{className:"rounded-md border border-destructive/40 bg-destructive/5 px-3 py-2 flex items-start gap-2",children:[e.jsx(ma,{className:"h-4 w-4 text-destructive mt-0.5 shrink-0"}),e.jsxs("div",{className:"text-xs",children:[e.jsx("div",{className:"font-medium text-destructive",children:"Last submission rejected"}),e.jsxs("div",{className:"text-muted-foreground mt-0.5",children:[e.jsx("span",{className:"font-medium",children:"Reason:"})," ",A.admin_note]})]})]}),n?e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(W,{htmlFor:"coupon-text",children:"Offer Text"}),e.jsx(Y,{id:"coupon-text",value:N,onChange:f=>C(f.target.value),placeholder:"e.g. 10% off first visit â mention Townsyâ¢!",maxLength:120,disabled:x}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:[N.length,"/120 characters"]})]}),N.trim()&&e.jsxs("label",{htmlFor:"coupon-promo-consent",className:"flex items-start gap-2 rounded-md border border-border p-2 text-xs cursor-pointer",children:[e.jsx(He,{id:"coupon-promo-consent",checked:u,onCheckedChange:f=>g(f===!0),className:"mt-0.5"}),e.jsx("span",{className:"text-muted-foreground",children:"I authorize Townsy to display and promote this offer, with my business name and logo, on Townsy's website, app, email, text alerts, social media and other Townsy promotional channels during the offer period. Townsy won't change the offer's terms."})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(_,{size:"sm",onClick:v,disabled:j.isPending||x||!!N.trim()&&!u,className:"gap-1.5",children:[e.jsx(pa,{className:"h-3.5 w-3.5"})," ",j.isPending?"Submittingâ¦":"Submit for Review"]}),e.jsxs(_,{size:"sm",variant:"outline",onClick:()=>{p(!1),C(m)},className:"gap-1.5",children:[e.jsx(ze,{className:"h-3.5 w-3.5"})," Cancel"]})]})]}):m?e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"rounded-lg bg-accent/5 border border-accent/20 px-4 py-3",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx(Ke,{className:"h-3.5 w-3.5 text-accent"}),e.jsx("span",{className:"text-xs font-medium text-muted-foreground",children:"Live Preview"}),e.jsx(J,{variant:"outline",className:"ml-auto text-[10px]",children:"Approved"})]}),e.jsx("p",{className:"font-semibold text-accent",children:m})]}),e.jsxs("div",{className:"flex gap-2 flex-wrap",children:[e.jsxs(_,{size:"sm",variant:"outline",onClick:()=>p(!0),disabled:x,className:"gap-1.5",children:[e.jsx(At,{className:"h-3.5 w-3.5"})," Edit Coupon"]}),e.jsx(Qr,{businessName:t,couponText:m,slug:i,categoryName:d}),e.jsxs(_,{size:"sm",variant:"ghost",className:"gap-1.5 text-destructive hover:text-destructive",onClick:l,disabled:x,children:[e.jsx(ze,{className:"h-3.5 w-3.5"})," Request Removal"]})]})]}):e.jsxs("div",{className:"text-center py-4",children:[e.jsx("p",{className:"text-sm text-muted-foreground mb-3",children:"You haven't created a coupon yet. Submit one and we'll review it for approval."}),e.jsxs(_,{size:"sm",onClick:()=>p(!0),disabled:x,className:"gap-1.5",children:[e.jsx(Ks,{className:"h-3.5 w-3.5"})," Create Your Free Coupon"]})]})]})]})}function $n(){var b,A;const{user:s}=be(),{toast:t}=je(),i=ve(),[d,a]=c.useState(!1),[m,n]=c.useState(!1),{data:p,isLoading:N}=ae({queryKey:["my-profile",s==null?void 0:s.id],queryFn:async()=>{const{data:x,error:j}=await D.from("profiles").select("*").eq("user_id",s.id).maybeSingle();if(j)throw j;return x},enabled:!!s}),C=fe({mutationFn:async x=>{if(!s)throw new Error("Not authenticated");const{error:j}=await D.from("profiles").update({full_name:x.full_name||null,phone:x.phone||null}).eq("user_id",s.id);if(j)throw j},onSuccess:()=>{t({title:"Profile updated!"}),i.invalidateQueries({queryKey:["my-profile"]}),a(!1)},onError:x=>{t({title:"Error",description:x.message,variant:"destructive"})}}),u=async x=>{var v;const j=(v=x.target.files)==null?void 0:v[0];
13if(!(!j||!s)){if(j.size>10*1024*1024){t({title:"File too large",description:"Avatar must be under 10MB.",variant:"destructive"});return}n(!0);try{const l=j.name.split(".").pop(),f=`${s.id}/avatar-${Date.now()}.${l}`,{error:h}=await D.storage.from("contractor-images").upload(f,j,{upsert:!0});if(h)throw h;const{data:P}=D.storage.from("contractor-images").getPublicUrl(f),{error:k}=await D.from("profiles").update({avatar_url:P.publicUrl}).eq("user_id",s.id);if(k)throw k;i.invalidateQueries({queryKey:["my-profile"]}),t({title:"Avatar updated!"})}catch(l){t({title:"Upload failed",description:l.message,variant:"destructive"})}finally{n(!1)}}},g=x=>{x.preventDefault();const j=new FormData(x.currentTarget);C.mutate({full_name:j.get("full_name").trim(),phone:j.get("phone").trim()})};if(N)return e.jsx(q,{className:"mb-6",children:e.jsx(M,{className:"p-6",children:e.jsx("div",{className:"h-20 bg-muted rounded animate-pulse"})})});const w=p!=null&&p.full_name?p.full_name.split(" ").map(x=>x[0]).join("").toUpperCase().slice(0,2):((A=(b=s==null?void 0:s.email)==null?void 0:b[0])==null?void 0:A.toUpperCase())??"?";return e.jsxs(q,{className:"mb-6",children:[e.jsxs(Z,{className:"pb-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(kt,{className:"h-5 w-5 text-primary"}),e.jsx(ee,{className:"text-lg",children:"My Information"})]}),!d&&e.jsxs(_,{variant:"outline",size:"sm",onClick:()=>a(!0),children:[e.jsx(At,{className:"h-4 w-4 mr-1"})," Edit"]})]}),e.jsx(he,{children:"Your personal account details"})]}),e.jsx(M,{"data-clarity-mask":"true",children:d?e.jsxs("form",{onSubmit:g,className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-4 mb-2",children:[e.jsxs("label",{className:"relative cursor-pointer group/avatar",children:[e.jsxs(zt,{className:"h-16 w-16 border-2 border-border",children:[e.jsx(It,{src:(p==null?void 0:p.avatar_url)??void 0}),e.jsx(Ut,{className:"bg-primary/10 text-primary font-bold",children:w})]}),e.jsx("div",{className:"absolute inset-0 rounded-full bg-black/50 flex items-center justify-center opacity-0 group-hover/avatar:opacity-100 transition-opacity",children:m?e.jsx(ie,{className:"h-4 w-4 text-white animate-spin"}):e.jsx(Ot,{className:"h-4 w-4 text-white"})}),e.jsx("input",{type:"file",accept:"image/*",className:"hidden",onChange:u,disabled:m})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Click avatar to change photo"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(W,{htmlFor:"full_name",children:"Full Name"}),e.jsx(Y,{id:"full_name",name:"full_name",defaultValue:(p==null?void 0:p.full_name)??"",placeholder:"Your full name",maxLength:100})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(W,{htmlFor:"profile_phone",children:"Phone Number"}),e.jsx(Y,{id:"profile_phone",name:"phone",type:"tel",defaultValue:(p==null?void 0:p.phone)??"",placeholder:"(555) 123-4567",maxLength:20})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(W,{children:"Email"}),e.jsx(Y,{value:(s==null?void 0:s.email)??"",disabled:!0,className:"bg-muted"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Email cannot be changed here"})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(_,{type:"submit",disabled:C.isPending,children:C.isPending?e.jsxs(e.Fragment,{children:[e.jsx(ie,{className:"h-4 w-4 mr-1 animate-spin"})," Saving..."]}):"Save Changes"}),e.jsx(_,{type:"button",variant:"outline",onClick:()=>a(!1),children:"Cancel"})]})]}):e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsxs("label",{className:"relative cursor-pointer group/avatar",children:[e.jsxs(zt,{className:"h-16 w-16 border-2 border-border",children:[e.jsx(It,{src:(p==null?void 0:p.avatar_url)??void 0}),e.jsx(Ut,{className:"bg-primary/10 text-primary font-bold",children:w})]}),e.jsx("div",{className:"absolute inset-0 rounded-full bg-black/50 flex items-center justify-center opacity-0 group-hover/avatar:opacity-100 transition-opacity",children:m?e.jsx(ie,{className:"h-4 w-4 text-white animate-spin"}):e.jsx(Ot,{className:"h-4 w-4 text-white"})}),e.jsx("input",{type:"file",accept:"image/*",className:"hidden",onChange:u,disabled:m})]}),e.jsxs("div",{className:"space-y-0.5",children:[e.jsx("p",{className:"font-semibold",children:(p==null?void 0:p.full_name)||"No name set"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:s==null?void 0:s.email}),(p==null?void 0:p.phone)&&e.jsx("p",{className:"text-sm text-muted-foreground",children:p.phone})]})]})})]})}function Mn(){const{favorites:s,isLoading:t}=tn("contractor"),i=s.map(n=>n.item_id).slice(0,3),{data:d,isLoading:a}=ae({queryKey:["dash-fav-contractors",i],queryFn:async()=>
13{if(i.length===0)return[];const{data:n}=await D.from("contractors_public").select("*, categories(*)").in("id",i).eq("status","active");return n??[]},enabled:i.length>0}),{data:m}=sn(i);return t||s.length===0?null:e.jsxs(q,{className:"mb-6",children:[e.jsx(Z,{className:"pb-3",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs(ee,{className:"flex items-center gap-2 text-lg",children:[e.jsx(St,{className:"h-4 w-4 text-destructive fill-destructive"})," Saved Businesses"]}),e.jsx(X,{to:"/favorites",children:e.jsx(_,{variant:"ghost",size:"sm",className:"text-xs",children:"View all â"})})]})}),e.jsx(M,{children:a?e.jsx("div",{className:"grid gap-4 sm:grid-cols-3",children:Array.from({length:Math.min(3,i.length)}).map((n,p)=>e.jsx(Jr,{},p))}):d&&d.length>0?e.jsx("div",{className:"grid gap-4 sm:grid-cols-3",children:d.map(n=>e.jsx(Xr,{contractor:n,reviewStats:m==null?void 0:m[n.id]},n.id))}):e.jsx("p",{className:"text-sm text-muted-foreground text-center py-4",children:"Your saved businesses will appear here."})})]})}function zn(){const{getReferralUrl:s,totalPoints:t,referralCount:i}=an(),[d,a]=c.useState(!1),m=s(),n=async()=>{m&&(await navigator.clipboard.writeText(m),a(!0),Me.success("Referral link copied!"),setTimeout(()=>a(!1),2e3))};return e.jsxs(q,{children:[e.jsx(Z,{className:"pb-3",children:e.jsxs(ee,{className:"text-base flex items-center gap-2",children:[e.jsx(Be,{className:"h-4 w-4 text-primary"}),"Refer & Earn"]})}),e.jsxs(M,{className:"space-y-3",children:[e.jsxs("div",{className:"flex gap-4",children:[e.jsxs("div",{className:"text-center",children:[e.jsx("p",{className:"text-xl font-bold text-primary",children:t}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Points"})]}),e.jsxs("div",{className:"text-center",children:[e.jsx("p",{className:"text-xl font-bold text-primary",children:i}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Referrals"})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx(Y,{value:m,readOnly:!0,className:"text-xs h-8 flex-1 min-w-0"}),e.jsx(_,{variant:"outline",size:"sm",className:"shrink-0 gap-1 h-8",onClick:n,children:d?e.jsx(pa,{className:"h-3 w-3"}):e.jsx(_t,{className:"h-3 w-3"})}),m&&e.jsxs(e.Fragment,{children:[e.jsx(va,{url:m,title:"Scan to join via referral",triggerSize:"sm",triggerVariant:"outline"}),e.jsx(Ba,{url:m,title:"Join Townsy⢠with my referral link!"})]})]}),e.jsx(X,{to:"/refer-a-friend",className:"block",children:e.jsxs(_,{variant:"link",size:"sm",className:"px-0 text-xs gap-1",children:[e.jsx(Dt,{className:"h-3 w-3"})," Learn more about prizes"]})})]})]})}function In(){const s=Va(),t=Ya(),[i,d]=Ha(),{toast:a}=je();if(!s||!t)return null;const m=n=>{d(n),a({title:`Swipe navigation ${n?"enabled":"disabled"}`,description:n?"Swipe left or right to switch between Home, Deals, Events, Community, and My Townsy.":"Horizontal swipes will no longer change pages."})};return e.jsxs(q,{children:[e.jsxs(Z,{children:[e.jsxs(ee,{className:"text-lg flex items-center gap-2",children:[e.jsx(Wa,{className:"h-5 w-5 text-primary"}),"Swipe Navigation"]}),e.jsx(he,{children:"Swipe left or right between the main tabs â like Instagram or Facebook."})]}),e.jsx(M,{children:e.jsxs("div",{className:"flex items-center justify-between gap-4 rounded-lg border border-border/60 p-3",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx(W,{htmlFor:"swipe-nav-toggle",className:"font-medium cursor-pointer",children:"Enable swipe navigation"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"Your preference is saved on this device."})]}),e.jsx(De,{id:"swipe-nav-toggle",checked:i,onCheckedChange:m,"aria-label":"Toggle swipe navigation"})]})})]})}const Un=[{value:"genuine_review",label:"My review was genuine",description:"The review accurately reflects my experience"},{value:"misunderstanding",label:"Misunderstanding",description:"The report was based on a misunderstanding of my review"},{value:"policy_compliant",label:"Policy compliant",description:"My review doesn't violate the Review & Rating Policy"},{value:"other",label:"Other reason",description:"I have another reason to appeal"}];function On({deletedReviewId:s,contractorId:t,contractorName:i,onSuccess:d}){const{user:a}=be(),{toast:m}=je(),n=ve(),[p,N]=c.useState(!1),[C,u]=c.useState(""),[g,w]=c.useState(""),b=fe({mutationFn:async()=>
13{if(!a||!C)throw new Error("Please select a reason");const{error:A}=await D.from("review_appeals").insert({deleted_review_id:s,user_id:a.id,contractor_id:t,reason:C,details:g.trim()||null});if(A)throw A},onSuccess:()=>{m({title:"Appeal submitted",description:"We'll review your appeal and get back to you."}),n.invalidateQueries({queryKey:["my-deleted-reviews"]}),N(!1),u(""),w(""),d==null||d()},onError:A=>{m({title:"Error",description:A.message,variant:"destructive"})}});return e.jsxs(ys,{open:p,onOpenChange:N,children:[e.jsx(Ga,{asChild:!0,children:e.jsxs(_,{variant:"outline",size:"sm",className:"gap-1.5",children:[e.jsx(ka,{className:"h-3.5 w-3.5"})," Appeal"]})}),e.jsxs(Ns,{className:"sm:max-w-md",children:[e.jsxs(ws,{children:[e.jsx(_s,{children:"Appeal Review Removal"}),e.jsxs(ua,{children:["Your review on ",e.jsx("strong",{children:i})," was removed. Tell us why you think it should be restored."]})]}),e.jsxs("div",{className:"space-y-4 pt-2",children:[e.jsxs("div",{className:"space-y-3",children:[e.jsx(W,{className:"font-medium",children:"Why should this review be restored?"}),e.jsx(_a,{value:C,onValueChange:u,children:Un.map(A=>e.jsxs("div",{className:"flex items-start gap-3 rounded-lg border p-3",children:[e.jsx(Nt,{value:A.value,id:A.value,className:"mt-0.5"}),e.jsxs("label",{htmlFor:A.value,className:"cursor-pointer",children:[e.jsx("p",{className:"text-sm font-medium",children:A.label}),e.jsx("p",{className:"text-xs text-muted-foreground",children:A.description})]})]},A.value))})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(W,{children:"Additional details (optional)"}),e.jsx(rs,{value:g,onChange:A=>w(A.target.value),placeholder:"Provide any additional context...",rows:3,maxLength:500})]}),e.jsx(_,{onClick:()=>b.mutate(),disabled:!C||b.isPending,className:"w-full",children:b.isPending?"Submitting...":"Submit Appeal"})]})]})]})}function Bn(){const{user:s}=be(),{data:t,isLoading:i}=ae({queryKey:["my-deleted-reviews",s==null?void 0:s.id],queryFn:async()=>{const{data:a}=await D.from("deleted_reviews").select("*").eq("user_id",s.id).eq("restored",!1).order("deleted_at",{ascending:!1});if(!(a!=null&&a.length))return[];const m=[...new Set(a.map(g=>g.contractor_id))],{data:n}=await D.from("contractors").select("id, business_name").in("id",m),p=new Map((n??[]).map(g=>[g.id,g.business_name])),N=a.map(g=>g.id),{data:C}=await D.from("review_appeals").select("deleted_review_id, status, created_at").in("deleted_review_id",N),u=new Map((C??[]).map(g=>[g.deleted_review_id,g]));return a.map(g=>({...g,contractor_name:p.get(g.contractor_id)??"Unknown Business",appeal:u.get(g.id)??null}))},enabled:!!s});if(i)return e.jsx("div",{className:"h-16 bg-muted rounded-lg animate-pulse"});if(!(t!=null&&t.length))return null;const d=30*24*60*60*1e3;return e.jsxs(q,{className:"border-destructive/20",children:[e.jsxs(Z,{children:[e.jsxs(ee,{className:"flex items-center gap-2 text-lg",children:[e.jsx(ka,{className:"h-5 w-5 text-destructive"}),"Removed Reviews"]}),e.jsx(he,{children:"Reviews removed by moderation. You can appeal within 30 days."})]}),e.jsx(M,{className:"space-y-3",children:t.map(a=>{const m=new Date(a.deleted_at),n=new Date(m.getTime()+d),p=!a.appeal&&n>new Date,N=Math.max(0,Math.ceil((n.getTime()-Date.now())/(1e3*60*60*24))),C=a.appeal?e.jsxs(J,{variant:a.appeal.status==="approved"?"default":a.appeal.status==="rejected"?"destructive":"secondary",children:["Appeal ",a.appeal.status]}):p?e.jsxs(J,{variant:"outline",className:"gap-1",children:[e.jsx(Le,{className:"h-3 w-3"})," ",N,"d to appeal"]}):e.jsx(J,{variant:"secondary",children:"Expired"});return e.jsxs("div",{className:"rounded-lg border p-4 space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-medium",children:a.contractor_name}),e.jsxs("div",{className:"flex items-center gap-2 mt-1",children:[e.jsx("div",{className:"flex",children:[1,2,3,4,5].map(u=>e.jsx(ss,{className:`h-3 w-3 ${u<=a.rating?"fill-amber-400 text-amber-400":"text-muted-foreground/30"}`},u))}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:["Removed ",as(m,{addSuffix:!0})]})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[C,p&&e.jsx(On,{deletedReviewId:a.id,contractorId:a.contractor_id,contractorName:a.contractor_name})]})]}),a.comment&&e.jsx("p",{className:"text-sm text-muted-foreground line-clamp-2",children:a.comment})]},a.id)})})]})}function Vn(){const{user:s}=be(),{toast:t}=je(),i=ve(),[d,a]=c.useState({open:!1,ad:null}),[m,n]=c.useState({open:!1,id:"",title:""}),[p,N]=c.useState(!1),[C,u]=c.useState({title:"",description:"",price_asked:"",contact_email:"",contact_phone:""}),{data:g,isLoading:w}=ae({queryKey:["my-classifieds",s==null?void 0:s.id],queryFn:async()=>{const{data:v,error:l}=await D.from("classifieds").select("*, classified_subcategories(name)").eq("user_id",s.id).order("created_at",{ascending:!1});if(l)throw l;return v},enabled:!!s}),{data:b}=ae({queryKey:["classified-subcategories"],queryFn:async()=>{const{data:v}=await D.from("classified_subcategories").select("*").eq("is_active",!0).order("sort_order");return v??[]}}),A=v=>
13{u({title:v.title,description:v.description||"",price_asked:v.price_asked||"",contact_email:v.contact_email||"",contact_phone:v.contact_phone||""}),a({open:!0,ad:v})},x=async()=>{if(d.ad){N(!0);try{const{error:v}=await D.from("classifieds").update({title:C.title,description:C.description||null,price_asked:C.price_asked||null,contact_email:C.contact_email||null,contact_phone:C.contact_phone||null}).eq("id",d.ad.id);if(v)throw v;t({title:"Ad updated!"}),i.invalidateQueries({queryKey:["my-classifieds"]}),a({open:!1,ad:null})}catch(v){t({title:"Error",description:v.message,variant:"destructive"})}finally{N(!1)}}},j=async()=>{try{const{error:v}=await D.from("classifieds").delete().eq("id",m.id);if(v)throw v;t({title:"Ad deleted"}),i.invalidateQueries({queryKey:["my-classifieds"]}),n({open:!1,id:"",title:""})}catch(v){t({title:"Error",description:v.message,variant:"destructive"})}};return!(g!=null&&g.length)&&!w?e.jsx(q,{children:e.jsxs(M,{className:"py-8 text-center",children:[e.jsx(Qs,{className:"h-10 w-10 mx-auto text-muted-foreground mb-3"}),e.jsx("p",{className:"text-muted-foreground mb-3",children:"You haven't posted any classified ads yet."}),e.jsx(X,{to:"/classifieds/new",children:e.jsxs(_,{size:"sm",children:[e.jsx(Ye,{className:"h-4 w-4 mr-1"})," Post a Free Ad"]})})]})}):w?null:e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("h2",{className:"font-heading text-xl font-bold flex items-center gap-2",children:[e.jsx(Qs,{className:"h-5 w-5"})," My Classifieds"]}),e.jsx(X,{to:"/classifieds/new",children:e.jsxs(_,{size:"sm",variant:"outline",children:[e.jsx(Ye,{className:"h-4 w-4 mr-1"})," New Ad"]})})]}),g==null?void 0:g.map(v=>{var h;const l=new Date(v.expires_at)<new Date,f=v.status==="removed";return e.jsx(q,{className:f?"opacity-60":"",children:e.jsx(M,{className:"p-4",children:e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 flex-wrap mb-1",children:[e.jsx("h3",{className:"font-semibold text-foreground truncate",children:v.title}),f?e.jsx(J,{variant:"destructive",className:"text-xs",children:"Removed"}):l?e.jsxs(J,{variant:"outline",className:"text-xs text-muted-foreground",children:[e.jsx(Le,{className:"h-3 w-3 mr-0.5"}),"Expired"]}):e.jsx(J,{variant:"secondary",className:"text-xs",children:"Active"}),e.jsx(J,{variant:v.listing_type==="commercial"?"outline":"secondary",className:"text-xs",children:v.listing_type})]}),e.jsx("p",{className:"text-sm text-muted-foreground line-clamp-1",children:v.description}),e.jsxs("div",{className:"flex items-center gap-3 mt-1 text-xs text-muted-foreground",children:[e.jsx("span",{children:((h=v.classified_subcategories)==null?void 0:h.name)??"General"}),e.jsxs("span",{children:["Posted ",Ss(new Date(v.created_at),"MMM d, yyyy")]}),e.jsxs("span",{children:["Expires ",Ss(new Date(v.expires_at),"MMM d, yyyy")]}),v.price_asked&&e.jsx("span",{className:"text-primary font-medium",children:v.price_asked})]})]}),e.jsxs("div",{className:"flex gap-1 shrink-0",children:[e.jsx(_,{variant:"ghost",size:"sm",asChild:!0,children:e.jsx(X,{to:`/classifieds/${v.id}`,children:e.jsx(Ke,{className:"h-3.5 w-3.5"})})}),!f&&e.jsx(_,{variant:"ghost",size:"sm",onClick:()=>A(v),children:e.jsx(Et,{className:"h-3.5 w-3.5"})}),e.jsx(_,{variant:"ghost",size:"sm",className:"text-destructive hover:text-destructive",onClick:()=>n({open:!0,id:v.id,title:v.title}),children:e.jsx(Ge,{className:"h-3.5 w-3.5"})})]})]})})},v.id)}),e.jsx(ys,{open:d.open,onOpenChange:v=>{v||a({open:!1,ad:null})},children:e.jsxs(Ns,{className:"sm:max-w-md",children:[e.jsx(ws,{children:e.jsx(_s,{children:"Edit Classified Ad"})}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(W,{children:"Title"}),e.jsx(Y,{value:C.title,onChange:v=>u(l=>({...l,title:v.target.value})),maxLength:120})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(W,{children:"Description"}),e.jsx(rs,{value:C.description,onChange:v=>u(l=>({...l,description:v.target.value})),rows:4})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(W,{children:"Asking Price"}),e.jsx(Y,{value:C.price_asked,onChange:v=>u(l=>({...l,price_asked:v.target.value})),placeholder:"e.g. $50, Free, OBO"})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(W,{children:"Email"}),e.jsx(Y,{type:"email",value:C.contact_email,onChange:v=>u(l=>({...l,contact_email:v.target.value}))})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(W,{children:"Phone"}),e.jsx(Y,{type:"tel",value:C.contact_phone,onChange:v=>u(l=>({...l,contact_phone:v.target.value}))})]})]})]}),e.jsxs(gt,{children:[e.jsx(_,{variant:"outline",onClick:()=>a({open:!1,ad:null}),children:"Cancel"}),e.jsx(_,{onClick:x,disabled:p||!C.title.trim(),children:p?"Savingâ¦":"Save Changes"})]})]})}),e.jsx(ys,{open:m.open,onOpenChange:v=>{v||n({open:!1,id:"",title:""})},children:e.jsxs(Ns,{children:[e.jsx(ws,{children:e.jsx(_s,{children:"Delete Classified Ad"})}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Are you sure you want to permanently delete ",e.jsxs("strong",{children:['"',m.title,'"']}),"? This cannot be undone."]}),e.jsxs(gt,{children:[e.jsx(_,{variant:"outline",onClick:()=>n({open:!1,id:"",title:""}),children:"Cancel"}),e.jsx(_,{variant:"destructive",onClick:j,children:"Delete"})]})]})})]})}function Yn(){const{user:s}=be(),{toast:t}=je(),i=ve(),{data:d,isLoading:a}=ae({queryKey:["my-events",s==null?void 0:s.id],enabled:!!s,queryFn:async()=>{const{data:n}=await D.from("events").select("id, title, event_date, status, c
13ategory").eq("user_id",s.id).order("event_date",{ascending:!1});return n??[]}}),m=fe({mutationFn:async n=>{const{error:p}=await D.from("events").delete().eq("id",n);if(p)throw p},onSuccess:()=>{i.invalidateQueries({queryKey:["my-events"]}),t({title:"Event deleted"})},onError:n=>t({title:"Error",description:n.message,variant:"destructive"})});return a?e.jsx("p",{className:"text-sm text-muted-foreground py-4",children:"Loading your events..."}):!d||d.length===0?e.jsxs("div",{className:"text-center py-6 space-y-2",children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"You haven't posted any events yet."}),e.jsx(X,{to:"/events/new",children:e.jsxs(_,{size:"sm",children:[e.jsx(Ye,{className:"h-4 w-4 mr-2"})," Post an Event"]})})]}):e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("p",{className:"text-sm text-muted-foreground",children:[d.length," event",d.length!==1?"s":""]}),e.jsx(X,{to:"/events/new",children:e.jsxs(_,{size:"sm",children:[e.jsx(Ye,{className:"h-4 w-4 mr-2"})," New Event"]})})]}),e.jsx("div",{className:"rounded-lg border overflow-x-auto",children:e.jsxs(vt,{children:[e.jsx(bt,{children:e.jsxs(es,{children:[e.jsx(ye,{children:"Title"}),e.jsx(ye,{children:"Date"}),e.jsx(ye,{children:"Status"}),e.jsx(ye,{className:"text-right",children:"Actions"})]})}),e.jsx(yt,{children:d.map(n=>e.jsxs(es,{children:[e.jsx(Ne,{className:"font-medium max-w-[200px] truncate",children:n.title}),e.jsx(Ne,{className:"text-sm whitespace-nowrap",children:Ss(new Date(n.event_date),"MMM d, yyyy")}),e.jsx(Ne,{children:e.jsx(J,{variant:n.status==="active"?"default":"secondary",className:"text-xs",children:n.status})}),e.jsx(Ne,{className:"text-right",children:e.jsxs("div",{className:"flex items-center justify-end gap-1",children:[e.jsx(X,{to:`/events/${n.id}/edit`,children:e.jsx(_,{variant:"ghost",size:"sm",title:n.status==="expired"?"Edit & reactivate":"Edit",children:n.status==="expired"?e.jsx(As,{className:"h-4 w-4"}):e.jsx(Et,{className:"h-4 w-4"})})}),e.jsx(_,{variant:"ghost",size:"sm",className:"text-destructive hover:text-destructive",onClick:()=>{confirm("Delete this event?")&&m.mutate(n.id)},disabled:m.isPending,children:e.jsx(Ge,{className:"h-4 w-4"})})]})})]},n.id))})]})})]})}function Hn(){const{user:s}=be(),{toast:t}=je(),[i,d]=c.useState(!1),[a,m]=c.useState("email"),[n,p]=c.useState(""),[N,C]=c.useState(!1),[u,g]=c.useState(!0),[w,b]=c.useState(!1);c.useEffect(()=>{s&&(D.from("two_factor_settings").select("is_enabled, preferred_method, sms_backup_enabled").eq("user_id",s.id).maybeSingle().then(({data:l})=>{d((l==null?void 0:l.is_enabled)??!1),m((l==null?void 0:l.preferred_method)==="sms"?"sms":"email"),C((l==null?void 0:l.sms_backup_enabled)===!0),g(!1)}),D.from("notification_preferences").select("sms_phone").eq("user_id",s.id).maybeSingle().then(({data:l})=>{l!=null&&l.sms_phone&&p(l.sms_phone)}))},[s]);const A=async l=>{if(s){if(l&&!n.trim()){t({title:"Phone required",description:"Save your mobile number below before turning on SMS backup.",variant:"destructive"});return}C(l),await D.from("two_factor_settings").update({sms_backup_enabled:l}).eq("user_id",s.id),t({title:l?"SMS backup on":"SMS backup off",description:l?"You'll also get your login code as a text if your email is slow.":"Codes will only be sent via your primary method."})}},x=async l=>{if(!s)return;if(l&&a==="sms"&&!n.trim()){t({title:"Phone required",description:"Please enter your mobile number for SMS verification.",variant:"destructive"});return}b(!0);const{error:f}=l?await D.from("two_factor_settings").upsert({user_id:s.id,is_enabled:!0,preferred_method:a,enabled_at:new Date().toISOString()},{onConflict:"user_id"}):await D.from("two_factor_settings").update({is_enabled:!1}).eq("user_id",s.id);b(!1),f?t({title:"Error",description:"Failed to update 2FA settings.",variant:"destructive"}):(d(l),t({title:l?"2FA Enabled":"2FA Disabled",description:l?`You'll receive a verification code via ${a==="sms"?"text message":"email"} on each login.`:"Two-step verification has been turned off."}))},j=async l=>{const f=l;if(f==="sms"&&!n.trim()){m(f);return}m(f),!(!s||!i)&&(await D.from("two_factor_settings").update({preferred_method:f}).eq("user_id",s.id),t({title:"Method updated",description:`Verification codes will be sent via ${f==="sms"?"text message":"email"}.`}))},v=async()=>{!s||!n.trim()||(await D.from("notification_preferences").upsert({user_id:s.id,sms_phone:n.trim()},{onConflict:"user_id"}),i&&await D.from("two_factor_settings").update({preferred_method:"sms"}).eq("user_id",s.id),t({title:"Phone saved",description:"Your mobile number has been saved for SMS verification."}))};return u?e.jsx(q,{children:e.jsx(M,{className:"flex items-center justify-center py-8",children:e.jsx(ie,{className:"h-5 w-5 animate-spin text-muted-foreground"})})}):e.jsxs(q,{children:[e.jsxs(Z,{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Ka,{className:"h-5 w-5 text-primary"}),e.jsx(ee,{className:"text-lg",children:"Two-Step Verification"})]}),e.jsx(he,{children:"Add an extra layer of security by requiring a verification code each time you sign in."})]}),e.jsxs(M,{className:"space-y-5",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs(W,{htmlFor:"2fa-toggle",className:"flex flex-col gap-1",children:[e.jsx("span",{className:"font-medium",children:"Enable two-step verification"}),e.jsx("span",{className:"text-xs text-muted-foreground",children:i?`A 6-digit code will be sent via ${a==="sms"?"text":"email"} on every login`:"Currently disabled"})]}),e.jsx(De,{id:"2fa-toggle",checked:i,onCheckedChange:x,disabled:w})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsx(W,{className:"text-sm font-medium",children:"Delivery method"}),e.jsxs(_a,{value:a,onValueChange:j,className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-3 rounded-lg border border-border p-3",children:[e.jsx(Nt,{value:"email",id:"method-email"}),e.jsx(nt,{className:"h-4 w-4 text-muted-foreground"}),e.jsxs(W,{htmlFor:"method-email",className:"flex-1 cursor-pointer",children:[e.jsx("span",{className:"font-medium",children:"Email"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Code sent to your login email address"})]})]}),e.jsxs("div",{className:"flex items-center gap-3 rounded-lg border border-border p-3",children:[e.jsx(Nt,{value:"sms",id:"method-sms"}),e.jsx(Js,{className:"h-4 w-4 text-muted-foreground"}),e.jsxs(W,{htmlFor:"method-sms",className:"flex-1 cursor-pointer",children:[e.jsx("span",{className:"font-medium",children:"Text message (SMS)"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Code sent to your mobile phone"})]})]})]})]}),(a==="sms"||N)&&e.jsxs("div",{className:"space-y-2 pl-1",children:[e.jsx(W,{htmlFor:"2fa-phone",className:"text-sm",children:"Mobile phone number"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(Y,{id:"2fa-phone",type:"tel",placeholder:"+1 (555) 123-4567",value:n,onChange:l=>p(l.target.value),className:"flex-1"}),e.jsx("button",{type:"button",onClick:v,disabled:!n.trim(),className:"px-4 py-2 text-sm font-medium rounded-md bg-primary text-primary-foreground hover:bg-primary/90 disabled:opacity-50 transition-colors",children:"Save"})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Enter your number in international format (e.g. +1 for US)"})]}),i&&a==="email"&&e.jsxs("div",{className:"flex items-start justify-between gap-3 rounded-lg border border-border p-3",children:[e.jsxs(W,{htmlFor:"2fa-sms-backup",className:"flex flex-1 flex-col gap-1 cursor-pointer",children:[e.jsxs("span",{className:"font-medium flex items-center gap-2",children:[e.jsx(Js,{className:"h-4 w-4 text-muted-foreground"}),"Also send code by text (backup)"]}),e.jsx("span",{className:"text-xs text-muted-foreground",children:"Recommended if your email provider is slow or filters codes. Your code will be sent to both your email and ph
13one at the same time."})]}),e.jsx(De,{id:"2fa-sms-backup",checked:N,onCheckedChange:A})]})]})]})}const Wn={sms_enabled:!1,sms_phone:null,sms_events:!0,sms_deal_of_day:!0,sms_new_coupons:!0,sms_community_updates:!0,sms_contest_alerts:!0};function Gn(){const{user:s}=be(),{toast:t}=je(),i=ve(),[d,a]=c.useState(""),{data:m,isLoading:n}=ae({queryKey:["sms-prefs",s==null?void 0:s.id],queryFn:async()=>{const{data:u}=await D.from("notification_preferences").select("sms_enabled, sms_phone, sms_events, sms_deal_of_day, sms_new_coupons, sms_community_updates, sms_contest_alerts").eq("user_id",s.id).maybeSingle();return u!=null&&u.sms_phone&&a(u.sms_phone),u??null},enabled:!!s}),p=m??Wn,N=fe({mutationFn:async u=>{const g={...p,...u};if(m){const{error:w}=await D.from("notification_preferences").update(g).eq("user_id",s.id);if(w)throw w}else{const{error:w}=await D.from("notification_preferences").insert({user_id:s.id,...g});if(w)throw w}},onSuccess:()=>{t({title:"Text notification preferences saved"}),i.invalidateQueries({queryKey:["sms-prefs",s==null?void 0:s.id]})},onError:u=>{t({title:"Error",description:u.message,variant:"destructive"})}}),C=[{key:"sms_events",icon:Pt,title:"Events in your area",desc:"Get texts about new local events near you"},{key:"sms_deal_of_day",icon:Ks,title:"Deal of the Day",desc:"Daily deal alerts from local businesses"}
13,{key:"sms_new_coupons",icon:Qa,title:"New coupons",desc:"Alerts when businesses post new coupons"},{key:"sms_community_updates",icon:ns,title:"Community updates",desc:"My Town discussions and local news"},{key:"sms_contest_alerts",icon:Dt,title:"Contest & giveaway alerts",desc:"Never miss a chance to win prizes"}];return n?e.jsx(q,{children:e.jsx(M,{className:"py-8",children:e.jsx("div",{className:"h-32 bg-muted rounded animate-pulse"})})}):e.jsxs(q,{children:[e.jsxs(Z,{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Js,{className:"h-5 w-5 text-primary"}),e.jsx(ee,{className:"text-lg",children:"Text Notifications"})]}),e.jsx(he,{children:"Get text message alerts for deals, events, and more in your area."})]}),e.jsxs(M,{className:"space-y-5",children:[e.jsxs("div",{className:"flex items-center justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx(W,{className:"text-sm font-medium",children:"Enable text notifications"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-0.5",children:"Turn on to receive SMS alerts"})]}),e.jsx(De,{checked:p.sms_enabled,onCheckedChange:u=>N.mutate({sms_enabled:u}),disabled:N.isPending})]}),p.sms_enabled&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(W,{className:"text-sm font-medium",children:"Mobile phone number"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(Y,{type:"tel",placeholder:"+1 (555) 555-5555",value:d,onChange:u=>a(u.target.value),className:"flex-1"}),e.jsx(_,{size:"sm",onClick:()=>N.mutate({sms_phone:d}),disabled:N.isPending||!d.trim(),children:"Save"})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Standard message and data rates may apply."})]}),C.map(u=>e.jsxs("div",{className:"flex items-center justify-between gap-4",children:[e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(u.icon,{className:"h-5 w-5 text-muted-foreground mt-0.5 shrink-0"}),e.jsxs("div",{children:[e.jsx(W,{className:"text-sm font-medium",children:u.title}),e.jsx("p",{className:"text-xs text-muted-foreground mt-0.5",children:u.desc})]})]}),e.jsx(De,{checked:!!p[u.key],onCheckedChange:g=>N.mutate({[u.key]:g}),disabled:N.isPending})]},u.key))]})]})]})}const Kn={deals:"deal_alerts_v1",treasure_hunt:"hunt_alerts_v1"},pt={deals:"Yes, text me Townsy local deal alerts at this number. Up to 1 text per day, only when there's a worthwhile deal. Consent is not a condition of purchase. Msg & data rates may apply. Reply STOP to opt out, HELP for help.",treasure_hunt:"Yes, text me Townsy Treasure Hunt updates at this number. Occasional texts during the Hunt only. Consent is not a condition of purchase. Msg & data rates may apply. Reply STOP to opt out, HELP for help."},Qn=s=>{const t=s.replace(/\D/g,"");return t.length===10?`+1${t}`:t.length===11&&t.startsWith("1")?`+${t}`:null};function Jn(){const{user:s,isAdmin:t}=be(),[i,d]=c.useState(!1),[a,m]=c.useState(""),[n,p]=c.useState({}),[N,C]=c.useState({deals:!1,treasure_hunt:!1}),[u,g]=c.useState(!1),w=async()=>{if(!s)return;const[{data:l},{data:f}]=await Promise.all([D.rpc("sms_public_enrollment_open"),D.from("sms_alert_preferences").select("topic, phone, revoked_at").eq("user_id",s.id)]);d(l===!0||t);const h={};(f??[]).forEach(P=>{P.revoked_at||(h[P.topic]=!0),P.phone&&!a&&m(P.phone)}),p(h)};if(c.useEffect(()=>{w()},[s==null?void 0:s.id,t]),!s||!i)return null;const b=Qn(a),A=N.deals||N.treasure_hunt,x=async()=>{if(!b||!A)return;g(!0);const l=Object.keys(N).filter(h=>N[h]).map(h=>({user_id:s.id,topic:h,phone:b,consented_at:new Date().toISOString(),consent_text:pt[h],consent_version:Kn[h],source:"my_townsy",revoked_at:null,revoked_reason:null})),{error:f}=await D.from("sms_alert_preferences").upsert(l,{onConflict:"user_id,topic"});if(g(!1),f)return Me.error("Couldn't save. Please try again");Me.success("Text alerts turned on"),C({deals:!1,treasure_hunt:!1}),w()},j=async l=>{await D.from("sms_alert_preferences").update({revoked_at:new Date().toISOString(),revoked_reason:"member_turned_off"}).eq("user_id",s.id).eq("topic",l),Me.success("Turned off"),w()}
13,v={deals:"Townsy Deal Alerts",treasure_hunt:"Treasure Hunt"};return e.jsxs(q,{children:[e.jsx(Z,{children:e.jsx(ee,{className:"text-lg",children:"Text Alerts"})}),e.jsxs(M,{className:"space-y-4",children:[Object.keys(n).length>0&&e.jsx("div",{className:"space-y-2",children:Object.keys(n).map(l=>e.jsxs("div",{className:"flex items-center justify-between rounded-md border border-border p-2 text-sm",children:[e.jsxs("span",{children:[v[l]??l,": on"]}),e.jsx(_,{size:"sm",variant:"ghost",onClick:()=>j(l),children:"Turn off"})]},l))}),e.jsxs("div",{className:"space-y-1",children:[e.jsx("label",{className:"text-sm font-medium",htmlFor:"ta-phone",children:"Mobile number"}),e.jsx(Y,{id:"ta-phone",type:"tel",inputMode:"tel",placeholder:"(336) 555-0123",value:a,onChange:l=>m(l.target.value)})]}),Object.keys(pt).filter(l=>!n[l]).map(l=>e.jsxs("label",{className:"flex items-start gap-3 text-sm",children:[e.jsx(He,{checked:N[l],onCheckedChange:f=>C(h=>({...h,[l]:f===!0})),className:"mt-0.5"}),e.jsxs("span",{children:[e.jsxs("strong",{children:[v[l],"."]})," ",pt[l]]})]},l)),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Events alerts are coming soon. See our ",e.jsx(X,{to:"/privacy",className:"underline",children:"Privacy Policy"})," and ",e.jsx(X,{to:"/terms",className:"underline",children:"Terms"})]}),e.jsx(_,{className:"w-full",disabled:!b||!A||u,onClick:x,children:"Turn on text alerts"})]})]})}function Xn(s){const t=s??"";return/[",\n\r]/.test(t)?`"${t.replace(/"/g,'""')}"`:t}const Zn=["timestamp","status","status_code","attempts","topic","title","body","endpoint","error"];function ia(s,t){const i=t?[`# exported_at: ${t.exported_at}`,`# source: ${t.source}`,`# row_count: ${t.row_count}`,`# filter_status: ${t.status}`,`# filter_search: ${t.search||"(none)"}`]:[],d=s.map(a=>[a.created_at,a.status??"",a.status_code??"",a.attempts??"",a.topic??"",a.title??"",a.body??"",a.endpoint??"",a.error??""].map(m=>Xn(String(m))).join(","));return[...i,Zn.join(","),...d].join(` 14`)}function la(s,t){return JSON.stringify({meta:t??null,rows:s},null,2)}function oa(s){const t=[];let i="",d=!1;for(let a=0;a<s.length;a++){const m=s[a];d?m==='"'?s[a+1]==='"'?(i+='"',a++):d=!1:i+=m:m==='"'?d=!0:m===","?(t.push(i),i=""):i+=m}return t.push(i),t}function ei(s,t){const i=s.trim();if(!i)return"empty";const d=(t||"").toLowerCase();return d.endsWith(".json")?"json":d.endsWith(".csv")?"csv":i.startsWith("{")||i.startsWith("[")?"json":"csv"}function si(s,t=Date.now()){if(s.freq==="off")return!1;const i=s.lastRun?new Date(s.lastRun).getTime():0;if(!Number.isFinite(i))return!0;const d=s.freq==="daily"?864e5:7*864e5;return t-i>=d}function ti(s,t,i={}){const d=ei(s,t),a=[];if(d==="empty")return{rows:[],skipped:0,format:d,issues:a};const m=g=>g.length>160?`${g.slice(0,157)}â¦`:g;if(d==="json"){const g=JSON.parse(s.trim()),w=Array.isArray(g)?g:g==null?void 0:g.rows;if(!Array.isArray(w))throw new Error("JSON must be an array of rows or { rows: [...] }.");let b=0;const A=[];return w.forEach((x,j)=>{if(!x||typeof x!="object"){const v=`Entry ${j} is ${x===null?"null":typeof x}, expected an object.`;if(i.strict)throw new Error(v);b++,a.push({line:j+1,reason:v,raw:m(JSON.stringify(x))});return}A.push(ai(x,j))}),{rows:A,skipped:b,format:d,issues:a}}const n=s.split(/\r?\n/),p=[];if(n.forEach((g,w)=>{g&&!g.startsWith("#")&&p.push({text:g,line:w+1})}),p.length<2)return{rows:[],skipped:0,format:d,issues:a};const N=oa(p[0].text).map(g=>g.trim());let C=0;const u=[];return p.slice(1).forEach(({text:g,line:w},b)=>{const A=oa(g);if(A.length===1&&A[0]===""){C++,a.push({line:w,reason:"Blank row.",raw:m(g)});return}if(A.length!==N.length){const l=`Column count ${A.length} â header (${N.length}).`;if(i.strict)throw new Error(`Line ${w}: ${l}`);C++,a.push({line:w,reason:l,raw:m(g)});return}const x=l=>{const f=N.indexOf(l);return f>=0?A[f]:""},j=x("status_code"),v=x("attempts");u.push({id:`imp-${b}`,endpoint:x("endpoint")||null,topic:x("topic")||null,title:x("title")||null,body:x("body")||null,status:x("status")||null,status_code:j?Number(j):null,error:x("error")||null,attempts:v?Number(v):null,created_at:x("timestamp")||new Date().toISOString()})}),{rows:u,skipped:C,format:d,issues:a}}function ai(s,t){const i=d=>
14{if(d==null||d==="")return null;const a=Number(d);return Number.isFinite(a)?a:null};return{id:s.id??`imp-${t}`,endpoint:s.endpoint??null,topic:s.topic??null,title:s.title??null,body:s.body??null,status:s.status??null,status_code:i(s.status_code),error:s.error??null,attempts:i(s.attempts),created_at:s.created_at??new Date().toISOString()}}function ri(s){const t={total:s.length,sent:0,failed:0,other:0,successRate:0,avgAttempts:0,topics:{},errors:{},firstAt:null,lastAt:null};if(!s.length)return t;let i=0,d=0;for(const a of s)a.status==="sent"?t.sent++:a.status==="failed"?t.failed++:t.other++,a.topic&&(t.topics[a.topic]=(t.topics[a.topic]??0)+1),a.error&&(t.errors[a.error]=(t.errors[a.error]??0)+1),typeof a.attempts=="number"&&Number.isFinite(a.attempts)&&(i+=a.attempts,d++),a.created_at&&((!t.firstAt||a.created_at<t.firstAt)&&(t.firstAt=a.created_at),(!t.lastAt||a.created_at>t.lastAt)&&(t.lastAt=a.created_at));return t.successRate=t.total>0?t.sent/t.total:0,t.avgAttempts=d>0?i/d:0,t}function ni({issues:s,filename:t,onDismiss:i}){return s.length?e.jsxs("div",{role:"region","aria-label":"Malformed import rows","data-testid":"malformed-import-rows",className:"rounded-md border border-destructive/40 bg-destructive/5 p-3 text-xs space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsxs("div",{className:"flex items-center gap-2 font-medium text-destructive",children:[e.jsx(ks,{className:"h-3.5 w-3.5"}),e.jsxs("span",{children:[s.length," row",s.length===1?"":"s"," skipped",t?` from ${t}`:""]})]}),i&&e.jsxs(_,{variant:"ghost",size:"sm",onClick:i,className:"h-6 px-2 text-xs","aria-label":"Dismiss malformed row report",children:[e.jsx(ze,{className:"h-3 w-3 mr-1"})," Dismiss"]})]}),e.jsx("ul",{className:"space-y-1 max-h-40 overflow-auto font-mono",children:s.map((d,a)=>e.jsxs("li",{"data-testid":"malformed-import-row",className:"border-b border-destructive/20 pb-1 last:border-0",children:[e.jsxs("div",{className:"flex flex-wrap gap-x-2",children:[e.jsxs("span",{className:"text-muted-foreground",children:["Line ",d.line,":"]}),e.jsx("span",{className:"text-foreground",children:d.reason})]}),d.raw&&e.jsx("div",{className:"text-muted-foreground truncate",title:d.raw,children:d.raw})]},`${d.line}-${a}`))})]}):null}const ii={push_enabled:!1,push_deals:!0,push_events:!0,push_reviews:!0,push_local_deals:!0,push_restaurants:!0,push_community_news:!0,push_home_services:!1,push_nonprofits_schools:!1,push_polls:!0,push_featured_businesses:!1,push_emergency:!0,push_metro_area:null,push_frequency:"realtime"};let hs;async function li(){if(hs!==void 0)return hs;try{const{data:s,error:t}=await D.functions.invoke("get-push-config");if(t)throw t;hs=(s==null?void 0:s.publicKey)||null}catch(s){console.warn("[push] failed to fetch VAPID public key",s),hs=null}return hs}function oi(s){const t="=".repeat((4-s.length%4)%4),i=(s+t).replace(/-/g,"+").replace(/_/g,"/"),d=atob(i);return Uint8Array.from([...d].map(a=>a.charCodeAt(0)))}function Hs(){return typeof window<"u"&&"Notification"in window&&"serviceWorker"in navigator&&"PushManager"in window}async function Rt(){if(!("serviceWorker"in navigator))return null;try{const s=await navigator.serviceWorker.getRegistration("/push-sw.js");if(s)return s;const t=await navigator.serviceWorker.register("/push-sw.js",{scope:"/"});return(t.installing||t.waiting)&&await new Promise(i=>{const d=t.installing||t.waiting;if(!d)return i();d.addEventListener("statechange",()=>{d.state==="activated"&&i()})}),await navigator.serviceWorker.ready,t}catch(s){return console.warn("[push] service worker registration failed",s),null}}async function zs(s){var d,a;if(!Hs())return{ok:!1,reason:"Browser doesn't support push notifications."};const t=await li();if(!t)return{ok:!1,reason:"Push server is not configured. Please try again later."};const i=await Rt();if(!i)return{ok:!1,reason:"Service worker not ready. Reload the page and try again."};try{const n=await i.pushManager.getSubscription()??await i.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:oi(t)}),p=n.toJSON(),{error:N}=await D.from("push_subscriptions").upsert({user_id:s,endpoint:n.endpoint,p256dh:((d=p.
14keys)==null?void 0:d.p256dh)??"",auth:((a=p.keys)==null?void 0:a.auth)??""},{onConflict:"endpoint"});return N?{ok:!1,reason:N.message}:{ok:!0,sub:n}}catch(m){return console.warn("[push] subscribe failed",m),{ok:!1,reason:(m==null?void 0:m.message)??"Failed to subscribe."}}}async function Is(){const s=await Rt();if(!s)return{ok:!0};try{const t=await s.pushManager.getSubscription();if(!t)return{ok:!0};const i=t.endpoint;return await t.unsubscribe(),await D.from("push_subscriptions").delete().eq("endpoint",i),{ok:!0,endpoint:i}}catch(t){return{ok:!1,reason:(t==null?void 0:t.message)??"Failed to unsubscribe."}}}function ci(s){try{const t=new URL(s).host;return t.includes("fcm.googleapis")||t.includes("android.googleapis")?"Google (Chrome/Android)":t.includes("mozilla")?"Mozilla (Firefox)":t.includes("windows.com")||t.includes("notify.windows")?"Microsoft (Edge)":t.includes("push.apple")?"Apple (Safari)":t}catch{return"Unknown"}}function Us(s,t,i){const d=new Blob([t],{type:i}),a=URL.createObjectURL(d),m=document.createElement("a");m.href=a,m.download=s,m.style.display="none",document.body.appendChild(m),m.click(),m.remove(),URL.revokeObjectURL(a)}function di(){var Fe,Ze,o;const{user:s}=be(),{toast:t}=je(),i=ve(),{data:d}=ga(),[a,m]=c.useState(Hs()?Notification.permission:"unsupported"),[n,p]=c.useState(null),[N,C]=c.useState(null),[u,g]=c.useState(!1),[w,b]=c.useState(!1),[A,x]=c.useState(!1),[j,v]=c.useState(!1),[l,f]=c.useState(""),[h,P]=c.useState("all"),[k,H]=c.useState(null),[$,re]=c.useState(null),[E,U]=c.useState([]),[L,R]=c.useState({freq:"off",format:"csv",lastRun:null}),me=c.useRef(null),K=c.useRef(!1),O=c.useRef(!1),B=c.useCallback(async()=>{if(!Hs())return p(null),null;const y=await Rt(),V=y?await y.pushManager.getSubscription():null;return p(V),V},[]);c.useEffect(()=>{Hs()&&m(Notification.permission),B()},[B]),c.useEffect(()=>{if(!s||!("serviceWorker"in navigator))return;const y=async V=>{const I=V.data;if(!(!I||I.type!=="push-subscription-changed"))try{I.oldEndpoint&&await D.from("push_subscriptions").delete().eq("endpoint",I.oldEndpoint),await D.from("push_subscriptions").upsert({user_id:s.id,endpoint:I.subscription.endpoint,p256dh:I.subscription.p256dh,auth:I.subscription.auth},{onConflict:"endpoint"}),await B(),t({title:"Push subscription refreshed",description:"Your device got a new push token automatically."})}catch(ne){console.warn("[push] failed to update rotated subscription",ne)}};return navigator.serviceWorker.addEventListener("message",y),()=>navigator.serviceWorker.removeEventListener("message",y)},[s,B,t]);const{data:G,isLoading:se}=ae({queryKey:["push-prefs",s==null?void 0:s.id],queryFn:async()=>{const{data:y}=await D.from("notification_preferences").select("push_enabled, push_deals, push_events, push_reviews, push_local_deals, push_restaurants, push_community_news, push_home_services, push_nonprofits_schools, push_polls, push_featured_businesses, push_emergency, push_metro_area, push_frequency").eq("user_id",s.id).maybeSingle();return y??null},enabled:!!s}),ue=G??ii,pe=fe({mutationFn:async y=>{const V={...ue,...y};if(G){const{error:I}=await D.from("notification_preferences").update(V).eq("user_id",s.id);if(I)throw I}else{const{error:I}=await D.from("notification_preferences").insert({user_id:s.id,...V});if(I)throw I}},onSuccess:()=>{i.invalidateQueries({queryKey:["push-prefs",s==null?void 0:s.id]})},onError:y=>{t({title:"Couldn't save preference",description:y.message??String(y),variant:"destructive"})}}),{data:de,refetch:we}=ae({queryKey:["push-delivery-log",s==null?void 0:s.id],queryFn:async()=>{const{data:y}=await D.from("push_delivery_log").select("id, endpoint, topic, title, body, status, status_code, error, attempts, created_at").eq("user_id",s.id).order("created_at",{ascending:!1}).limit(200);return y??[]},enabled:!!s&&A}),ce=c.useMemo(()=>{const y=k??de;if(!y)return[];let V=y;if(h!=="all"&&(V=V.filter(I=>I.status===h)),l.trim()){const I=l.trim().toLowerCase();V=V.filter(ne=>[ne.topic,ne.title,ne.body,ne.status,ne.error,ne.endpoint,String(ne.status_code)].filter(Boolean).join(" ").toLowerCase().includes(I))}return V},[de,k,h,l]),xe=c.useMemo(()=>ri(ce),[ce]),Ee=c.useMemo(()=>{const y=Object.entries(xe.topics);return y.length?y.sort((V,I)=>I[1]-V[1])[0]:null},[xe]),Je=c.useMemo(()=>{const y=Object.entries(xe.errors);return y.length?y.sort((V,I)=>I[1]-V[1])[0]:null},[xe]),Xe=c.useCallback(y=>({search:l.trim(),status:h,exported_at:new Date().toISOString(),row_count:y,source:k?"imported":"live"}),[l,h,k]),Ls=()=>
14{if(!ce.length){t({title:"Nothing to export",description:"Delivery log is empty."});return}const y=ia(ce,Xe(ce.length));Us(`push-delivery-log-${new Date().toISOString().slice(0,10)}.csv`,y,"text/csv"),t({title:"CSV exported",description:`${ce.length} rows saved with active filters.`})},it=()=>{if(!ce.length){t({title:"Nothing to export",description:"Delivery log is empty."});return}const y=la(ce,Xe(ce.length));Us(`push-delivery-log-${new Date().toISOString().slice(0,10)}.json`,y,"application/json"),t({title:"JSON exported",description:`${ce.length} rows saved with active filters.`})},lt=async y=>{try{const V=await y.text(),I=ti(V,y.name);if(U(I.issues),!I.rows.length){I.issues.length?(H([]),re(y.name),x(!0),t({title:"Import had no valid rows",description:`${I.issues.length} malformed rows are listed below.`,variant:"destructive"})):t({title:"Empty import",description:"File parsed but contained no rows.",variant:"destructive"});return}H(I.rows),re(y.name),x(!0);const ne=I.issues.length?` (${I.issues.length} skipped)`:"";t({title:"Imported",description:`Loaded ${I.rows.length} rows from ${y.name}${ne}.`})}catch(V){U([]),t({title:"Import failed",description:(V==null?void 0:V.message)??"Could not parse file.",variant:"destructive"})}},Es=()=>{H(null),re(null),U([])};c.useEffect(()=>{if(s)try{const y=localStorage.getItem(`push-export-schedule:${s.id}`);y&&R(JSON.parse(y))}catch{}},[s]),c.useEffect(()=>{if(s)try{localStorage.setItem(`push-export-schedule:${s.id}`,JSON.stringify(L))}catch{}},[s,L]),c.useEffect(()=>{if(!s||O.current||!de||!de.length||!si(L))return;O.current=!0;const y={search:"",status:"all",exported_at:new Date().toISOString(),row_count:de.length,source:"live"},V=new Date().toISOString().slice(0,10);L.format==="csv"?Us(`push-delivery-scheduled-${V}.csv`,ia(de,y),"text/csv"):Us(`push-delivery-scheduled-${V}.json`,la(de,y),"application/json"),R(I=>({...I,lastRun:new Date().toISOString()})),t({title:"Scheduled export ready",description:`${L.freq} ${L.format.toUpperCase()} downloaded.`})},[s,L,de,t]);const us=async()=>{if(n)try{await navigator.clipboard.writeText(n.endpoint),t({title:"Endpoint copied",description:"Push endpoint copied to clipboard."})}catch(y){t({title:"Copy failed",description:(y==null?void 0:y.message)??"Clipboard unavailable",variant:"destructive"})}},ot=async()=>{if(s){v(!0);try{await Is();const{error:y}=await D.from("push_subscriptions").delete().eq("user_id",s.id);if(y)throw y;pe.mutate({push_enabled:!1}),await B(),t({title:"Subscription revoked",description:"All stored push records cleared."})}catch(y){t({title:"Revoke failed",description:(y==null?void 0:y.message)??String(y),variant:"destructive"})}finally{v(!1)}}};c.useEffect(()=>{!s||K.current||!ue.push_enabled||a!=="granted"||n===null&&(K.current=!0,(async()=>(await zs(s.id)).ok&&(await B(),t({title:"Push re-subscribed",description:"We restored your push token on this device."})))())},[s,ue.push_enabled,a,n,B,t]);const Pe=async y=>{if(!s)return;if(!y){const ne=await Is();ne.ok||t({title:"Couldn't unsubscribe fully",description:ne.reason,variant:"destructive"}),pe.mutate({push_enabled:!1}),await B(),t({title:"Push notifications turned off"});return}if(a==="unsupported"){t({title:"Not supported",description:"Your browser doesn't support push notifications. Try installing the Townsy app.",variant:"destructive"});return}let V=a;if(V!=="granted"){try{V=await Notification.requestPermission()}catch(ne){t({title:"Permission error",description:(ne==null?void 0:ne.message)??"Couldn't request permission.",variant:"destructive"});return}m(V)}if(V!=="granted"){t({title:"Permission denied",description:"Enable notifications in your browser settings to receive alerts.",variant:"destructive"});return}const I=await zs(s.id);if(!I.ok){t({title:"Couldn't enable push",description:I.reason,variant:"destructive"});return}pe.mutate({push_enabled:!0}),await B(),t({title:"Push notifications enabled",description:"You'll get alerts for your favorite topics."})},Q=async()=>{if(s){g(!0);try{await Is();const y=await zs(s.id);y.ok?t({title:"Subscription refreshed",description:"You're set to receive push alerts again."}):t({title:"Re-subscribe failed",description:y.reason,variant:"destructive"}),await B()}finally{g(!1)}}},Rs=async y=>{C(y??"default");try{const{data:I,error:ne}=await D.functions.invoke("send-test-push",{body:y?{topic:y}:{}});if(ne)throw ne;const Ae=(I==null?void 0:I.sent)??0;Ae===0?(t({title:"No push delivered",description:"Your subscription may have expired. Auto-resyncingâ¦",variant:"destructive"}),s&&(await Is(),await zs(s.id),await B())):t({title:"Test push sent",description:`Delivered to ${Ae} device${Ae===1?"":"s"}.`})}catch(I){t({title:"Test push failed",description:(I==null?void 0:I.message)??"
14Unknown error",variant:"destructive"})}finally{C(null)}},Re=[{key:"push_local_deals",topic:"deals",icon:Ks,title:"Local Deals",desc:"Coupons, flash deals, and Deal of the Day"},{key:"push_restaurants",icon:Ja,title:"Restaurants & Food",desc:"New menus, openings, and specials"},{key:"push_events",topic:"events",icon:Pt,title:"Events",desc:"Reminders and new event alerts near you"},{key:"push_community_news",icon:Qs,title:"Community News",desc:"Town updates, polls, and local notices"},{key:"push_home_services",icon:Xa,title:"Home Services",desc:"Contractor highlights and seasonal tips"},{key:"push_nonprofits_schools",icon:nn,title:"Nonprofits & Schools",desc:"Fundraisers, drives, and school announcements"},{key:"push_polls",icon:ln,title:"Town Polls",desc:"Vote in local polls and see results"},{key:"push_featured_businesses",icon:We,title:"Featured Businesses",desc:"Sponsored spotlights from local partners"},{key:"push_emergency",icon:ks,title:"Emergency / Local Alerts",desc:"Important community safety notices"}];if(!s)return null;if(se)return e.jsx(q,{children:e.jsx(M,{className:"py-8",children:e.jsx("div",{className:"h-32 bg-muted rounded animate-pulse"})})});const Te=ue.push_enabled&&a==="granted",xs=Te&&n===null,ge=n==null?void 0:n.toJSON();return e.jsxs(q,{children:[e.jsxs(Z,{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(rn,{className:"h-5 w-5 text-primary"}),e.jsx(ee,{className:"text-lg",children:"Push Notifications"})]}),e.jsx(he,{children:"Get instant alerts on your phone or browser â no SMS or email needed."})]}),e.jsxs(M,{className:"space-y-5",children:[e.jsxs("div",{className:"flex items-center justify-between gap-4",children:[e.jsxs("div",{className:"flex items-start gap-3",children:[Te?e.jsx(fa,{className:"h-5 w-5 text-primary mt-0.5"}):e.jsx(Jt,{className:"h-5 w-5 text-muted-foreground mt-0.5"}),e.jsxs("div",{children:[e.jsx(W,{className:"text-sm font-medium",children:"Enable push notifications"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-0.5",children:a==="unsupported"?"Not supported in this browser. Install the Townsy app for push.":a==="denied"?"Blocked. Allow notifications in your browser settings.":Te?"On â you'll receive alerts on this device":"Turn on to receive instant alerts"})]})]}),e.jsx(De,{checked:Te,onCheckedChange:Pe,disabled:pe.isPending||a==="unsupported"||a==="denied","aria-label":"Enable push notifications"})]}),xs&&e.jsxs("div",{className:"rounded-md border border-destructive/30 bg-destructive/5 p-3 text-xs",children:[e.jsx("p",{className:"font-medium text-destructive mb-1",children:"Subscription out of sync"}),e.jsx("p",{className:"text-muted-foreground",children:"Your browser no longer has an active push subscription. We'll try to refresh it automatically â or tap Refresh below."})]}),Te&&e.jsxs("div",{className:"space-y-4 pt-2 border-t",children:[e.jsxs("div",{className:"grid sm:grid-cols-2 gap-3",children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs(W,{className:"text-xs font-medium flex items-center gap-1.5",children:[e.jsx(Ve,{className:"h-3.5 w-3.5 text-muted-foreground"})," Metro area"]}),e.jsxs(is,{value:ue.push_metro_area??"__all__",onValueChange:y=>pe.mutate({push_metro_area:y==="__all__"?null:y}),children:[e.jsx(ls,{className:"h-9 text-sm",children:e.jsx(os,{placeholder:"All metros"})}),e.jsxs(cs,{children:[e.jsx(ke,{value:"__all__",children:"All metros"}),(d??[]).map(y=>e.jsx(ke,{value:y.slug,children:y.label},y.slug))]})]}),e.jsx("p",{className:"text-[11px] text-muted-foreground",children:"Only get pushes for this area."})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs(W,{className:"text-xs font-medium flex items-center gap-1.5",children:[e.jsx(Le,{className:"h-3.5 w-3.5 text-muted-foreground"})," Frequency"]}),e.jsxs(is,{value:ue.push_frequency,onValueChange:y=>pe.mutate({push_frequency:y}),children:[e.jsx(ls,{className:"h-9 text-sm",children:e.jsx(os,{})}),e.jsxs(cs,{children:[e.jsx(ke,{value:"realtime",children:"Real-time"}),e.jsx(ke,{value:"daily",children:"Daily digest"}),e.jsx(ke,{value:"weekly",children:"Weekly digest"})]})]}),e.jsx("p",{className:"text-[11px] text-muted-foreground",children:"Emergency alerts always send real-time."})]})]}),e.jsxs("div",{className:"space-y-3 pt-2 border-t",children:[e.jsx("p",{className:"text-xs font-semibold uppercase tracking-wide text-muted-foreground",children:"Categories"}),Re.map(y=>{const V=!!ue[y.key];return e.jsxs("div",{className:"flex items-center justify-between gap-4",children:[e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(y.icon,{className:"h-5 w-5 text-muted-foreground mt-0.5 shrink-0"}),e.jsxs("div",{children:[e.jsx(W,{className:"text-sm font-medium",children:y.title}),e.jsx("p",{className:"text-xs text-muted-foreground mt-0.5",children:y.desc})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(_,{variant:"ghost",size:"sm",onClick:()=>Rs(y.topic),disabled:!V||N!==null||xs,"aria-label":`Send test ${y.title}`,className:"h-8 px-2 gap-1 text-xs text-muted-foreground",children:[N===y.topic?e.jsx(ie,{className:"h-3.5 w-3.5 animate-spin"}):e.jsx(Gs,{className:"h-3.5 w-3.5"}),"Test"]}),e.jsx(De,{checked:V,onCheckedChange:I=>pe.mutate({[y.key]:I}),disabled:pe.isPending,"aria-label":y.title})]})]},y.key)})]}),e.jsxs("div",{className:"flex flex-wrap gap-2 pt-2 border-t",children:[e.jsxs(_,{variant:"outline",size:"sm",onClick:()=>Rs(),disabled:N!==null||xs,className:"gap-2",children:[N==="default"?e.jsx(ie,{className:"h-4 w-4 animate-spin"}):e.jsx(Gs,{className:"h-4 w-4"}),"Send test push"]}),e.jsxs(_,{variant:"outline",size:"sm",onClick:Q,disabled:u,className:"gap-2",children:[u?e.jsx(ie,{className:"h-4 w-4 animate-spin"}):e.jsx(As,{className:"h-4 w-4"}),"Refresh subscription"]}),e.jsxs(_,{variant:"outline",size:"sm",onClick:us,disabled:!n,className:"gap-2",children:[e.jsx(_t,{className:"h-4 w-4"}),"Copy endpoint"]}),e.jsxs(_,{variant:"ghost",size:"sm",onClick:()=>b(y=>!y),className:"gap-2 text-muted-foreground",children:[e.jsx(Za,{className:"h-4 w-4"}),w?"Hide details":"Subscription details"]}
14),e.jsxs(_,{variant:"ghost",size:"sm",onClick:()=>{x(y=>!y),A||we()},className:"gap-2 text-muted-foreground",children:[e.jsx(Le,{className:"h-4 w-4"}),A?"Hide delivery log":"Delivery log"]}),e.jsxs(_,{variant:"ghost",size:"sm",onClick:()=>Pe(!1),disabled:pe.isPending,className:"gap-2 text-muted-foreground",children:[e.jsx(Jt,{className:"h-4 w-4"}),"Unsubscribe"]}),e.jsxs(er,{children:[e.jsx(sr,{asChild:!0,children:e.jsxs(_,{variant:"ghost",size:"sm",disabled:j,className:"gap-2 text-destructive hover:text-destructive",children:[j?e.jsx(ie,{className:"h-4 w-4 animate-spin"}):e.jsx(Ge,{className:"h-4 w-4"}),"Revoke & clear records"]})}),e.jsxs(tr,{children:[e.jsxs(ar,{children:[e.jsx(rr,{children:"Revoke push notifications?"}),e.jsx(nr,{children:"This will unsubscribe your current device and permanently delete all stored push subscription records from your account. You can re-subscribe anytime."})]}),e.jsxs(ir,{children:[e.jsx(lr,{children:"Cancel"}),e.jsx(or,{onClick:ot,className:"bg-destructive text-destructive-foreground hover:bg-destructive/90",children:"Revoke & clear"})]})]})]})]}),w&&e.jsx("div",{className:"rounded-md border bg-muted/30 p-3 text-xs space-y-1 font-mono break-all",children:n?e.jsxs(e.Fragment,{children:[e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"Service:"})," ",ci(n.endpoint)]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"Endpoint:"})," ",n.endpoint.slice(0,80),n.endpoint.length>80?"â¦":""]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"Expires:"})," ",n.expirationTime?new Date(n.expirationTime).toLocaleString():"Never (or browser-managed)"]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"p256dh:"})," ",(((Fe=ge==null?void 0:ge.keys)==null?void 0:Fe.p256dh)??"").slice(0,24),"â¦"]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"auth:"})," ",(((Ze=ge==null?void 0:ge.keys)==null?void 0:Ze.auth)??"").slice(0,12),"â¦"]})]}):e.jsx("div",{className:"text-muted-foreground",children:"No active browser subscription on this device."})}),A&&e.jsxs("div",{className:"rounded-md border bg-muted/30 p-3 text-xs space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2 flex-wrap",children:[e.jsx("p",{className:"font-medium",children:k?`Imported deliveries (${$})`:"Recent push deliveries"}),e.jsxs("div",{className:"flex items-center gap-1",children:[k&&e.jsxs(_,{variant:"ghost",size:"sm",onClick:Es,className:"h-6 px-2 text-xs",children:[e.jsx(ze,{className:"h-3 w-3 mr-1"})," Clear import"]}),e.jsxs(_,{variant:"ghost",size:"sm",onClick:()=>we(),className:"h-6 px-2 text-xs",disabled:!!k,children:[e.jsx(As,{className:"h-3 w-3 mr-1"})," Refresh"]})]})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsxs("div",{className:"relative flex-1 min-w-[12rem]",children:[e.jsx(wa,{className:"absolute left-2 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground"}),e.jsx(Y,{placeholder:"Search topic, title, errorâ¦",value:l,onChange:y=>f(y.target.value),className:"h-8 pl-7 text-xs"})]}),e.jsxs("select",{value:h,onChange:y=>P(y.target.value),className:"h-8 rounded-md border bg-background px-2 text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-ring","aria-label":"Filter by status",children:[e.jsx("option",{value:"all",children:"All statuses"}),e.jsx("option",{value:"sent",children:"Sent"}),e.jsx("option",{value:"failed",children:"Failed"})]}),e.jsxs(_,{variant:"ghost",size:"sm",onClick:Ls,disabled:!ce.length,className:"h-8 px-2 text-xs gap-1",children:[e.jsx(on,{className:"h-3.5 w-3.5"})," CSV"]}),e.jsxs(_,{variant:"ghost",size:"sm",onClick:it,disabled:!ce.length,className:"h-8 px-2 text-xs gap-1",children:[e.jsx(qr,{className:"h-3.5 w-3.5"})," JSON"]}),e.jsx("input",{ref:me,type:"file",accept:".csv,.json,text/csv,application/json",className:"hidden",onChange:y=>{var I;const V=(I=y.target.files)==null?void 0:I[0];V&<(V),y.target.value=""}}),e.jsxs(_,{variant:"ghost",size:"sm",onClick:()=>{var y;return(y=me.current)==null?void 0:y.click()},className:"h-8 px-2 text-xs gap-1",children:[e.jsx(Xs,{className:"h-3.5 w-3.5"})," Import"]})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2 rounded border border-border/60 bg-background/60 px-2 py-1.5",children:[e.jsx(cr,{className:"h-3.5 w-3.5 text-muted-foreground"}),e.jsx("span",{className:"text-muted-foreground",children:"Auto-export:"}),e.jsxs("select",{value:L.freq,onChange:y=>R(V=>({...V,freq:y.target.value})),className:"h-7 rounded-md border bg-background px-1.5 text-xs","aria-label":"Export frequency",children:[e.jsx("option",{value:"off",children:"Off"}),e.jsx("option",{value:"daily",children:"Daily"}),e.jsx("option",{value:"weekly",children:"Weekly"})]}),e.jsxs("select",{value:L.format,onChange:y=>R(V=>({...V,format:y.target.value})),className:"h-7 rounded-md border bg-background px-1.5 text-xs","aria-label":"Export format",disabled:L.freq==="off",children:[e.jsx("option",{value:"csv",children:"CSV"}),e.jsx("option",{value:"json",children:"JSON"})]}),e.jsx("span",{className:"text-muted-foreground ml-auto",children:L.freq==="off"?"Disabled":L.lastRun?`Last run ${as(new Date(L.lastRun),{addSuffix:!0})}`:"Will run on next visit"})]}),k&&e.jsx("p",{className:"text-[11px] text-muted-foreground",children:"Viewing imported file â live data hidden. Exports below will use these rows + active filters."}),e.jsx(ni,{issues:E,filename:$,onDismiss:()=>U([])}),ce.length>0&&e.jsxs("div",{className:"rounded border border-border/60 bg-background/60 p-2 text-[11px]",children:[e.jsxs("div",{className:"grid grid-cols-2 sm:grid-cols-4 gap-2",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-muted-foreground",children:"Total"}),e.jsx("div",{className:"font-semibold text-sm",children:xe.total})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-muted-foreground",children:"Sent / Failed"}),e.jsxs("div",{className:"font-semibold text-sm",children:[e.jsx("span",{className:"text-green-600",children:xe.sent}),e.jsx("span",{className:"text-muted-foreground",children:" / "}),e.jsx("span",{className:"text-destructive",children:xe.failed})]})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-muted-foreground",children:"Success rate"}),e.jsxs("div",{className:"font-semibold text-sm",children:[(xe.successRate*100).toFixed(1),"%"]})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-muted-foreground",children:"Avg attempts"}),e.jsx("div",{className:"font-semibold text-sm",children:xe.avgAttempts.toFixed(2)})]})]}),(Ee||Je)&&e.jsxs("div",{className:"mt-2 pt-2 border-t border-border/40 flex flex-wrap gap-x-4 gap-y-1 text-muted-foreground",children:[Ee&&e.jsxs("span",{children:["Top topic: ",e.jsxs("span",{className:"text-foreground",children:[Ee[0]," (",Ee[1],")"]})]}),Je&&e.jsxs("span",{children:["Top error: ",e.jsxs("span",{className:"text-foreground",children:[Je[0]," (",Je[1],")"]})]}),xe.lastAt&&e.jsxs("span",{className:"ml-auto",children:["Last ",as(new Date(xe.lastAt),{addSuffix:!0})]})]})]}),((o=k??de)==null?void 0:o.length)===0||!k&&!de?e.jsx("p",{className:"text-muted-foreground",children:"No deliveries logged yet. Send a test push to populate this list."}):ce.length===0?e.jsx("p",{className:"text-muted-foreground",children:"No rows match your filter. Try clearing the search or changing the status filter."}):e.jsx("ul",{className:"space-y-1.5 max-h-80 overflow-auto",children:ce.map(y=>{const V=y.status==="sent";return e.jsxs("li",{className:"flex items-start gap-2 border-b border-border/40 pb-1.5 last:border-0",children:[V?e.jsx(Ds,{className:"h-3.5 w-3.5 text-green-600 mt-0.5 shrink-0"}):e.jsx(Ca,{className:"h-3.5 w-3.5 text-destructive mt-0.5 shrink-0"}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsx("span",{className:"font-medium truncate",children:y.title||y.topic||"Push"}),e.jsxs("span",{className:"text-muted-foreground",children:["· ",y.status,y.status_code?` (${y.status_code})`:""]}),(y.attempts??1)>1&&e.jsxs("span",{className:"text-muted-foreground",children:["· ",y.attempts," attempts"]})]}),e.jsxs("div",{className:"text-muted-foreground",children:[as(new Date(y.created_at),{addSuffix:!0}),y.error&&e.jsxs("span",{className:"ml-2 truncate inline-block max-w-full align-bottom",children:["â ",String(y.error).slice(0,120)]})]})]})]},y.id)})})]})]}),a==="denied"&&e.jsx(_,{variant:"outline",size:"sm",asChild:!0,children:e.jsx("a",{href:"https://support.google.com/chrome/answer/3220216",target:"_blank",rel:"noreferrer",children:"How to unblock notifications"})})]})]})}function mi(){const{user:s,isContractor:t}=be(),{primaryListing:i,signedAgreement:d,plan:a}=en(),m=t&&!i,n=t&&!!i&&!d;return e.jsxs("div",{className:"space-y-6",children:[m&&e.jsx(X,{to:"/business/start",className:"block",children:e.jsx(q,{className:"border-primary/40 bg-primary/5 hover:bg-primary/10 transition",children:e.jsxs("div",{className:"flex items-center gap-4 p-4",children:[e.jsx("div",{className:"rounded-xl bg-primary/15 p-3 shrink-0",children:e.jsx(wt,{className:"h-6 w-6 text-primary"})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"font-heading font-semibold text-base",children:"Finish setting up your business (5 min)"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Add listing details, pick a plan, and accept the agreement to unlock enhancement tools."})]}),e.jsx(Bs,{className:"h-5 w-5 text-primary shrink-0"})]})})}),n&&e.jsx(X,{to:"/business/tools",className:"block",children:e.jsx(q,{className:"border-amber-500/50 bg-amber-500/10 hover:bg-amber-500/15 transition",children:e.jsxs("div",{className:"flex items-center gap-4 p-4",children:[e.jsx("div",{className:"rounded-xl bg-amber-500/20 p-3 shrink-0",children:e.jsx(dr,{className:"h-6 w-6 text-amber-600"})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"font-heading font-semibold text-base",children:"Accept the Listing Agreement"}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Required to publish coupons, request campaigns, or use Grow Copilot publisher. Plan: ",e.jsx("span",{className:"capitalize",children:a}),"."]})]}),e.jsx(Bs,{className:"h-5 w-5 text-amber-600 shrink-0"})]})})}),t&&e.jsx(X,{to:"/dashboard?view=business",className:"block",children:e.jsx(q,{className:"bg-gradient-to-r from-accent/15 via-primary/10 to-accent/15 border-accent/40 hover:border-accent/70 transition-all hover:shadow-md",children:e.jsxs("div",{className:"flex items-center gap-4 p-4",children:[e.jsx("div",{className:"rounded-xl bg-accent/20 p-3 shrink-0",children:e.jsx(ja,{className:"h-6 w-6 text-accent-foreground"})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"font-heading font-semibold text-base",children:"Switch to My Townsy"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Manage your listing, leads, analytics, c
14oupons & more"})]}),e.jsx(Bs,{className:"h-5 w-5 text-accent-foreground shrink-0"})]})})}),e.jsx(X,{to:"/install",className:"block",children:e.jsx(q,{className:"bg-gradient-to-r from-primary/10 via-accent/10 to-primary/10 border-primary/30 hover:border-primary/60 transition-all hover:shadow-md",children:e.jsxs("div",{className:"flex items-center gap-4 p-4",children:[e.jsx("div",{className:"rounded-xl bg-primary/15 p-3 shrink-0",children:e.jsx(Js,{className:"h-6 w-6 text-primary"})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"font-heading font-semibold text-base",children:"Get the Townsy⢠App"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Install on your phone or desktop â works offline & loads instantly"})]}),e.jsx(Ps,{className:"h-5 w-5 text-primary shrink-0"})]})})}),e.jsx($n,{}),e.jsx(Hn,{}),e.jsx(In,{}),e.jsx(di,{}),e.jsx(Gn,{}),e.jsx(Jn,{}),e.jsxs(q,{children:[e.jsxs(Z,{children:[e.jsx(ee,{className:"text-lg",children:"Quick Actions"}),e.jsx(he,{children:"Things you can do as a community member"})]}),e.jsx(M,{children:e.jsxs("div",{className:"grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-3",children:[e.jsx(X,{to:"/my-town",onClick:()=>ur("dashboard_quick_action"),children:e.jsxs(_,{variant:"outline",className:"w-full h-auto flex-col gap-2 py-4 border-amber-500/30 hover:border-amber-500/60 hover:bg-amber-500/5",children:[e.jsx(mr,{className:"h-5 w-5 text-amber-500"}),e.jsx("span",{className:"text-xs",children:"My Town"})]})}),e.jsx(X,{to:"/community",children:e.jsxs(_,{variant:"outline",className:"w-full h-auto flex-col gap-2 py-4",children:[e.jsx(ns,{className:"h-5 w-5 text-primary"}),e.jsx("span",{className:"text-xs",children:"Discussions"})]})}),e.jsx(X,{to:"/events",children:e.jsxs(_,{variant:"outline",className:"w-full h-auto flex-col gap-2 py-4",children:[e.jsx(Pt,{className:"h-5 w-5 text-primary"}),e.jsx("span",{className:"text-xs",children:"Events"})]})}),e.jsx(X,{to:"/classifieds",children:e.jsxs(_,{variant:"outline",className:"w-full h-auto flex-col gap-2 py-4",children:[e.jsx(Qs,{className:"h-5 w-5 text-primary"}),e.jsx("span",{className:"text-xs",children:"Classifieds"})]})}),e.jsx(X,{to:"/favorites",children:e.jsxs(_,{variant:"outline",className:"w-full h-auto flex-col gap-2 py-4",children:[e.jsx(St,{className:"h-5 w-5 text-primary"}),e.jsx("span",{className:"text-xs",children:"Favorites"})]})}),e.jsx(X,{to:"/browse",children:e.jsxs(_,{variant:"outline",className:"w-full h-auto flex-col gap-2 py-4",children:[e.jsx(ss,{className:"h-5 w-5 text-primary"}),e.jsx("span",{className:"text-xs",children:"Review Businesses"})]})}),e.jsx(X,{to:"/near-me",children:e.jsxs(_,{variant:"outline",className:"w-full h-auto flex-col gap-2 py-4",children:[e.jsx(Ve,{className:"h-5 w-5 text-primary"}),e.jsx("span",{className:"text-xs",children:"Near Me"})]})})]})})]}),e.jsx(zn,{}),e.jsx(Mn,{}),e.jsxs(q,{children:[e.jsxs(Z,{children:[e.jsx(ee,{className:"text-lg",children:"My Events"}),e.jsx(he,{children:"Events you've posted to the community"})]}),e.jsx(M,{children:e.jsx(Yn,{})})]}),e.jsx(Vn,{}),e.jsx(Bn,{}),e.jsx("div",{className:"pt-4 flex justify-center",children:e.jsx(xr,{})})]})}const ui={high:"bg-orange-500/15 text-orange-600 border-orange-500/30 dark:text-orange-400",medium:"bg-blue-500/15 text-blue-600 border-blue-500/30 dark:text-blue-400",low:"bg-muted text-muted-foreground border-border"};function xi(s){return et(s).className}function hi({contractorId:s}){const[t,i]=c.useState(null),[d,a]=c.useState(null),[m,n]=c.useState(!0),[p,N]=c.useState(!1),[C,u]=c.useState(null),g=c.useCallback(async(w=!1)=>{u(null),w?N(!0):n(!0);try{const{data:b,error:A}=await D.functions.invoke("growth-score",{body:{contractor_id:s}});if(A)throw A;if(b!=null&&b.error)throw new Error(b.error);const x=b;if(!x||typeof x.score!="number"||!Array.isArray(x.pillars))throw new Error("Could not load Growth Score");i({...x,pillars:x.pillars??[],recommendations:Array.isArray(x.recommendations)?x.recommendations:[]}),vs("growth_score_view",{meta:{score:b.score,contractor_id:s}});const j=new Date(Date.now()-7*24*3600*1e3).toISOString(),{data:v}=await D.from("growth_scores").select("score, computed_at").eq("contractor_id",s).lte("computed_at",j).order("computed_at",{ascending:!1}).limit(1).maybeSingle();a(v?b.score-v.score:null)}catch(b){console.error("growth-score load failed",b),u((b==null?void 0:b.message)??"Could not load Growth Score")}finally{n(!1),N(!1)}},[s]);return c.useEffect(()=>{s&&g(!1)},[s,g]),m?e.jsxs(q,{className:"mb-6",children:[e.jsx(Z,{className:"pb-3",children:e.jsxs(ee,{className:"text-base flex items-center gap-2",children:[e.jsx(We,{className:"h-4 w-4 text-primary"})," TownScoreâ¢"]})}),e.jsxs(M,{children:[e.jsx(bs,{className:"h-24 w-full mb-3"}),e.jsx(bs,{className:"h-4 w-3/4 mb-2"}),e.jsx(bs,{className:"h-4 w-1/2"})]})]}):C||!t?e.jsx(q,{className:"mb-6 border-dashed",children:e.jsxs(M,{className:"p-4 text-sm text-muted-foreground flex items-center justify-between",children:[e.jsxs("span",{children:["TownScore⢠unavailable: ",C??"no data"]}),e.jsx(_,{size:"sm",variant:"ghost",onClick:()=>g(!0),children:e.jsx(As,{className:"h-3.5 w-3.5"})})]})}):e.jsxs(q,{className:"mb-6 border-primary/20",children:[e.jsx(Z,{className:"pb-3",children:e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsxs(ee,{className:"text-base flex items-center gap-2",children:[e.jsx(We,{className:"h-4 w-4 text-primary"})," TownScoreâ¢"]}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(_,{asChild:!0,size:"sm",variant:"ghost",className:"h-7 px-2 text-xs",children:e.jsx(X,{to:"/dashboard/growth-briefs",children:"Monday briefs"})}),e.jsx(_,{asChild:!0,size:"sm",variant:"ghost",className:"h-7 px-2 text-xs",children:e.jsx(X,{to:"/dashboard/leads",children:"Leads"})}),e.jsx(_,{size:"sm",variant:"ghost",onClick:()=>g(!0),disabled:p,"aria-label":"Recompute score",className:"h-7 w-7 p-0",children:p?e.jsx(ie,{className:"h-3.5 w-3.5 animate-spin"}):e.jsx(As,{className:"h-3.5 w-3.5"})})]})]})}),e.jsxs(M,{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsx("div",{className:`text-5xl font-bold tabular-nums ${xi(t.score)}`,children:t.score}),e.jsxs("div",{className:"flex-1",children:[e.jsx("div",{className:"text-xs text-muted-foreground",children:"out of 100"}),e.jsx("div",{className:"mt-0.5",children:e.jsx(J,{variant:"outline",className:`text-[10px] py-0 px-1.5 ${et(t.score).badgeClass}`,children:et(t.score).label})}),d!==null&&e.jsxs("div",{className:`text-xs flex items-center gap-1 mt-1 ${d>=0?"text-green-600":"text-orange-500"}`,children:[e.jsx(ts,{className:`h-3 w-3 ${d<0?"rotate-180":""}`}),d>=0?"+":"",d," vs last week"]})]})]}),e.jsx("div",{className:"space-y-2",children:t.pillars.map(w=>{const b=Math.round(w.score/w.max*100);return e.jsxs("div",{className:"space-y-1",children:[e.jsxs("div",{className:"flex items-center justify-between text-xs",children:[e.jsx("span",{className:"font-medium",children:w.label}),e.jsxs("span",{className:"text-muted-foreground tabular-nums",children:[w.score,"/",w.max]})]}),e.jsx(st,{value:b,className:"h-1.5"})]},w.key)})}),t.recommendations.length>0&&e.jsxs("div",{className:"pt-2 border-t",children:[e.jsx("div",{className:"text-xs font-semibold uppercase tracking-wide text-muted-foreground mb-2",children:"Next best actions"}),e.jsx("ul",{className:"space-y-1.5",children:t.recommendations.slice(0,3).map(w=>e.jsx("li",{children:e.jsxs(X,{to:`/advisor?action=${encodeURIComponent(w.id)}&listing=${encodeURIComponent(t.contractor.id)}`,className:"flex items-center gap-2 p-2 -mx-2 rounded-md hover:bg-muted/60 transition-colors text-sm group",onClick:()=>vs("growth_score_action_click",{meta:{rec_id:w.id,pillar:w.pillar}}),children:[e.jsx(J,{variant:"outline",className:`text-[10px] py-0 px-1.5 ${ui[w.impact]}`,children:w.impact}),e.jsx("span",{className:"flex-1 truncate",children:w.title}),e.jsx(hr,{className:"h-3.5 w-3.5 text-muted-foreground group-hover:text-foreground"})]})},w.id))})]})]})]})}const Pa="growth-nudges:recently-dismissed:v1";function ca(s){try{const t=sessionStorage.getItem(`${Pa}:${s}`);if(!t)return[];const i=JSON.parse(t);return Array.isArray(i)?i.slice(0,5):[]}catch{return[]}}function pi(s,t){try{sessionStorage.setItem(`${Pa}:${s}`,JSON.stringify(t))}catch{}}function gi({userId:s,contractorIds:t,limit:i=3}){const d=ve(),a=c.useRef(null),m=c.useRef(null),[n,p]=c.useState(""),[N,C]=c.useState(()=>typeof window>"u"?[]:ca(s));c.useEffect(()=>{C(ca(s))},[s]),c.useEffect(()=>{pi(s,N)},[s,N]);const{data:u,isLoading:g}=ae({queryKey:["growth-nudges",s,t],queryFn:async()=>{let h=D.from("growth_nudges").select("id, contractor_id, nudge_type, priority, title, body, cta_label, cta_action, read_at, created_at").eq("user_id",s).is("dismissed_at",null).order("priority",{ascending:!1}).order("created_at",{ascending:!1}).limit(i);t&&t.length>0&&(h=h.in("contractor_id",t));const{data:P,error:k}=await h;if(k)throw k;return P??[]},enabled:!!s}),w=fe({mutationFn:async h=>{const{error:P}=await D.from("growth_nudges").update({dismissed_at:new Date().toISOString()}).eq("id",h.id);if(P)throw P},onMutate:h=>
14{vs("growth_nudge_dismiss",{meta:{id:h.id,title:h.title,nudge_type:h.nudge_type,priority:h.priority}}),C(P=>[{id:h.id,title:h.title},...P.filter(k=>k.id!==h.id)].slice(0,5)),a.current={kind:"undo",id:h.id}},onSuccess:()=>d.invalidateQueries({queryKey:["growth-nudges",s]})}),b=fe({mutationFn:async h=>{const{error:P}=await D.from("growth_nudges").update({dismissed_at:null}).eq("id",h);if(P)throw P},onMutate:h=>{const P=N.find(k=>k.id===h);vs("growth_nudge_undo",{meta:{id:h,title:(P==null?void 0:P.title)??null}}),C(k=>k.filter(H=>H.id!==h)),a.current={kind:"card",id:h}},onSuccess:()=>d.invalidateQueries({queryKey:["growth-nudges",s]})}),A=async()=>{const h=N.map(k=>k.id),P=N.map(k=>k.title);vs("growth_nudge_restore_all",{meta:{count:h.length,ids:h,titles:P}}),C([]),a.current={kind:"heading"};for(const k of h)await D.from("growth_nudges").update({dismissed_at:null}).eq("id",k);d.invalidateQueries({queryKey:["growth-nudges",s]})},x=c.useRef(null),j=h=>{var H;const P=Array.from(((H=x.current)==null?void 0:H.querySelectorAll("button[data-undo-item]"))??[]);if(P.length===0)return;const k=P.indexOf(document.activeElement);k!==-1&&(h.key==="ArrowRight"?(h.preventDefault(),P[(k+1)%P.length].focus()):h.key==="ArrowLeft"?(h.preventDefault(),P[(k-1+P.length)%P.length].focus()):h.key==="Home"?(h.preventDefault(),P[0].focus()):h.key==="End"&&(h.preventDefault(),P[P.length-1].focus()))},v=!!u&&u.length>0,l=N.length>0,f=!g&&!v;return c.useEffect(()=>{if(g)return;const h=a.current;f&&l&&p(`All growth opportunities dismissed. ${N.length} can be restored.`),h&&(a.current=null,requestAnimationFrame(()=>{var P,k,H;if(h.kind==="undo"){const $=(P=x.current)==null?void 0:P.querySelector(`button[data-undo-item][data-undo-id="${h.id}"]`);$==null||$.focus()}else h.kind==="card"?(k=document.querySelector(`button[data-nudge-dismiss="${h.id}"]`)??m.current)==null||k.focus():h.kind==="heading"&&((H=m.current)==null||H.focus())}))},[u,N,f,l,g]),g||f&&!l?null:e.jsxs("section",{"aria-label":"Growth opportunities",className:"mb-6 space-y-3",children:[e.jsx("span",{className:"sr-only",role:"status","aria-live":"polite",children:n}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(We,{className:"h-4 w-4 text-primary","aria-hidden":"true"}),e.jsx("h3",{ref:m,tabIndex:-1,className:"font-heading text-sm font-semibold text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 rounded",children:"Townsy Grow⢠â This week's opportunities"}),v&&e.jsxs(J,{variant:"secondary",className:"ml-auto gap-1 text-xs",children:[e.jsx(fa,{className:"h-3 w-3","aria-hidden":"true"}),u.length]})]}),v&&e.jsx("div",{className:"grid gap-3 md:grid-cols-3",children:u.map(h=>e.jsx(q,{className:"relative border-primary/20 bg-gradient-to-br from-primary/5 to-transparent",children:e.jsxs(M,{className:"p-4",children:[e.jsx("button",{type:"button","data-nudge-dismiss":h.id,onClick:()=>w.mutate(h),className:"absolute right-1 top-1 flex h-11 w-11 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 md:h-8 md:w-8","aria-label":`Dismiss nudge: ${h.title}`,title:"Dismiss",children:e.jsx(ze,{className:"h-4 w-4","aria-hidden":"true"})}),e.jsx("p",{className:"pr-12 text-sm font-semibold text-foreground",children:h.title}),e.jsx("p",{className:"mt-1 text-xs leading-relaxed text-muted-foreground",children:h.body}),h.cta_action&&e.jsx(_,{asChild:!0,size:"sm",variant:"ghost",className:"mt-2 h-7 gap-1 px-2 text-xs text-primary",children:e.jsxs(X,{to:h.cta_action,children:[h.cta_label??"Open",e.jsx(Bs,{className:"h-3 w-3","aria-hidden":"true"})]})})]})},h.id))}),f&&l&&e.jsx(q,{role:"status","aria-live":"polite",className:"border-dashed border-primary/30 bg-muted/30",children:e.jsxs(M,{className:"flex flex-col items-start gap-2 p-4 sm:flex-row sm:items-center sm:justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Ys,{className:"h-5 w-5 text-muted-foreground","aria-hidden":"true"}),e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-semibold text-foreground",children:"You're all caught up"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"All growth opportunities dismissed. Restore any you didn't mean to clear."})]})]}),e.jsxs(_,{type:"button",variant:"outline",size:"sm",onClick:A,className:"h-8 gap-1 text-xs","aria-label":"Restore all recently dismissed nudges",children:[e.jsx(Xt,{className:"h-3 w-3","aria-hidden":"true"}),"Restore all (",N.length,")"]})]})}),l&&e.jsxs("div",{ref:x,role:"toolbar","aria-label":"Recently dismissed nudges","aria-live":"polite",onKeyDown:j,className:"flex flex-wrap items-center gap-2 rounded-md border border-border bg-muted/40 px-3 py-2 text-xs text-muted-foreground",children:[e.jsx("span",{className:"font-medium text-foreground",children:"Recently dismissed:"}),N.map(h=>e.jsxs(_,{type:"button",variant:"ghost",size:"sm","data-undo-item":!0,"data-undo-id":h.id,onClick:()=>b.mutate(h.id),className:"h-7 gap-1 px-2 text-xs","aria-label":`Restore dismissed nudge: ${h.title}`,children:[e.jsx(Xt,{className:"h-3 w-3","aria-hidden":"true"}),'Undo "',h.title.length>24?h.title.slice(0,24)+"â¦":h.title,'"']},h.id))]})]})}const Os=24*60*60*1e3;
14function fi(s){const t=(s??[]).filter(Boolean);return ae({queryKey:["grow-dashboard",t],enabled:t.length>0,staleTime:6e4,queryFn:async()=>{const i=Date.now();new Date(i-7*Os).toISOString();const d=new Date(i-14*Os).toISOString(),[a,m]=await Promise.all([D.from("growth_scores").select("score, computed_at, contractor_id").in("contractor_id",t).gte("computed_at",d).order("computed_at",{ascending:!1}).limit(200),D.from("listing_analytics").select("created_at, contractor_id").in("contractor_id",t).eq("event_type","view").gte("created_at",d).limit(5e3)]),n=new Map,p=new Map;for(const j of a.data??[]){const v=new Date(j.computed_at).getTime();if(v>=i-7*Os){const l=n.get(j.contractor_id);(!l||v>l.t)&&n.set(j.contractor_id,{score:j.score,t:v})}else{const l=p.get(j.contractor_id);(!l||v>l.t)&&p.set(j.contractor_id,{score:j.score,t:v})}}const N=j=>j.length?j.reduce((v,l)=>v+l,0)/j.length:null,C=N(Array.from(n.values()).map(j=>j.score)),u=N(Array.from(p.values()).map(j=>j.score)),g=C!=null&&u!=null?Math.round(C-u):null;let w=0,b=0;const A=i-7*Os;for(const j of m.data??[])new Date(j.created_at).getTime()>=A?w++:b++;const x=b>0?(w-b)/b:w>0?1:null;return{score:C!=null?Math.round(C):null,scoreDelta:g,viewsThisWeek:w,viewsPriorWeek:b,viewsDeltaPct:x}}})}function ji(s=new Date){const t=s.getHours();return t<12?"Good morning":t<18?"Good afternoon":"Good evening"}function vi({contractorIds:s}){const{user:t}=be(),[i,d]=c.useState(""),{data:a,isLoading:m}=fi(s);c.useEffect(()=>{t&&(async()=>{const{data:g}=await D.from("profiles").select("full_name").eq("id",t.id).maybeSingle(),w=((g==null?void 0:g.full_name)??"").trim().split(/\s+/)[0]??"";d(w)})()},[t]);const n=new Date().toLocaleDateString(void 0,{weekday:"long",month:"long",day:"numeric"}),p=(a==null?void 0:a.score)!=null?et(a.score):null,N=a==null?void 0:a.viewsDeltaPct,C=N==null?"flat":N>.02?"up":N<-.02?"down":"flat",u=(a==null?void 0:a.scoreDelta)==null?"flat":a.scoreDelta>0?"up":a.scoreDelta<0?"down":"flat";return e.jsx(q,{className:"mb-4 overflow-hidden border-primary/20 bg-gradient-to-br from-primary/10 via-background to-background",children:e.jsxs(M,{className:"p-4 sm:p-5",children:[e.jsx("div",{className:"flex items-start justify-between gap-3 mb-3",children:e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"text-xs uppercase tracking-wide text-muted-foreground",children:n}),e.jsxs("h2",{className:"text-lg sm:text-xl font-heading font-semibold leading-tight",children:[ji(),i?`, ${i}`:"","."]}),e.jsxs("p",{className:"text-xs sm:text-sm text-muted-foreground mt-0.5 flex items-center gap-1",children:[e.jsx(We,{className:"h-3.5 w-3.5 text-primary","aria-hidden":"true"}),"Here's how your business is doing this week."]})]})}),m?e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsx(bs,{className:"h-20"}),e.jsx(bs,{className:"h-20"})]}):e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs("div",{className:"rounded-lg border bg-background/60 p-3",children:[e.jsx("p",{className:"text-[11px] uppercase tracking-wide text-muted-foreground",children:"TownScoreâ¢"}),e.jsxs("div",{className:"flex items-baseline gap-2 mt-1",children:[e.jsx("span",{className:`text-2xl sm:text-3xl font-bold ${(p==null?void 0:p.className)??"text-muted-foreground"}`,children:(a==null?void 0:a.score)??"â"}),p&&e.jsx(J,{variant:"outline",className:`text-[10px] ${p.badgeClass}`,children:p.label})]}),e.jsxs("div",{className:"mt-1 text-[11px] text-muted-foreground flex items-center gap-1",children:[e.jsx(da,{dir:u}),e.jsx("span",{children:(a==null?void 0:a.scoreDelta)==null?"Building baseline":a.scoreDelta===0?"Flat vs last week":`${a.scoreDelta>0?"+":""}${a.scoreDelta} pts vs last week`})]})]}),e.jsxs("div",{className:"rounded-lg border bg-background/60 p-3",children:[e.jsx("p",{className:"text-[11px] uppercase tracking-wide text-muted-foreground",children:"Views (7d)"}),e.jsx("div",{className:"flex items-baseline gap-2 mt-1",children:e.jsx("span",{className:"text-2xl sm:text-3xl font-bold text-foreground",children:(a==null?void 0:a.viewsThisWeek)??0})}),e.jsxs("div",{className:"mt-1 text-[11px] text-muted-foreground flex items-center gap-1",children:[e.jsx(da,{dir:C}),e.jsx("span",{children:N==null?"No prior week data":C==="flat"?"Flat vs last week":`${N>0?"+":""}${Math.round(N*100)}% vs last week`})]})]})]}),e.jsx("p",{className:"mt-3 text-[10px] leading-snug text-muted-foreground
14/80",children:"TownScore⢠and trend insights are AI-generated estimates based on your listing data. Verify before making business decisions."})]})})}function da({dir:s}){return s==="up"?e.jsx(ts,{className:"h-3 w-3 text-green-600","aria-hidden":"true"}):s==="down"?e.jsx(cn,{className:"h-3 w-3 text-orange-500","aria-hidden":"true"}):e.jsx(pr,{className:"h-3 w-3 text-muted-foreground","aria-hidden":"true"})}function bi(){const{user:s}=be(),[t,i]=c.useState(null),[d,a]=c.useState(void 0),[m,n]=c.useState(!0);c.useEffect(()=>{s&&!t&&i(crypto.randomUUID())},[s,t]);const p=()=>{i(crypto.randomUUID()),a(void 0)},N=async C=>{const u=await vr(C);a(u),i(C)};return e.jsxs(q,{children:[e.jsxs(Z,{className:"pb-3 flex flex-row items-start justify-between",children:[e.jsxs("div",{children:[e.jsxs(ee,{className:"text-base flex items-center gap-2",children:[e.jsx(We,{className:"h-4 w-4 text-primary"})," ",mt.brand]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:mt.tagline})]}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(_,{asChild:!0,size:"sm",variant:"outline",className:"gap-1",children:e.jsxs(X,{to:"/request-campaign",children:[e.jsx(Na,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:"Request campaign"})]})}),s&&e.jsxs(_,{size:"sm",variant:"ghost",onClick:()=>n(C=>!C),className:"gap-1",children:[e.jsx(gr,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:"History"})]})]})]}),e.jsx(M,{className:"pt-0",children:e.jsxs("div",{className:"h-[60vh] flex border rounded-md overflow-hidden",children:[s&&m&&e.jsx(fr,{persona:"grow",activeThreadId:t,onSelect:C=>void N(C),onNew:p,className:"w-56 shrink-0"}),e.jsx("div",{className:"flex-1 px-3 py-2 overflow-hidden",children:e.jsx(jr,{persona:mt,threadId:t??"grow-pending",persistent:!!s,initialMessages:d},t??"grow-pending")})]})})]})}function yi(){const{toast:s}=je(),t=ve(),{data:i}=ae({queryKey:["promo-expiration-alerts"],queryFn:async()=>{const{data:a}=await D.from("promo_expiration_alerts").select("id, promo_code, expires_at, expiration_source, days_until_expiry").is("dismissed_at",null).order("expires_at",{ascending:!0});return a??[]},staleTime:6e4}),d=fe({mutationFn:async a=>{const{error:m}=await D.from("promo_expiration_alerts").update({dismissed_at:new Date().toISOString()}).eq("id",a);if(m)throw m},onSuccess:()=>{t.invalidateQueries({queryKey:["promo-expiration-alerts"]}),s({title:"Reminder dismissed"})}});return i!=null&&i.length?e.jsx("div",{className:"space-y-3 mb-6",children:i.map(a=>{const n=a.days_until_expiry<=7?"border-destructive/50 bg-destructive/10":"border-amber-500/50 bg-amber-50 dark:bg-amber-950/20",p=new Date(a.expires_at).toLocaleDateString(void 0,{month:"long",day:"numeric",year:"numeric"}),N=a.expiration_source==="promo_ends_at"?"the promo itself expires":"your current listing expires";return e.jsxs(gs,{className:n,children:[e.jsx(Le,{className:"h-4 w-4"}),e.jsxs(Vs,{className:"flex items-center justify-between gap-3 flex-wrap",children:[e.jsxs("span",{children:["Your promo ",e.jsx("span",{className:"font-mono",children:a.promo_code})," expires in"," ",a.days_until_expiry," day",a.days_until_expiry===1?"":"s"]}),e.jsx(_,{variant:"ghost",size:"sm",className:"h-7",onClick:()=>d.mutate(a.id),disabled:d.isPending,"aria-label":"Dismiss reminder",children:e.jsx(ze,{className:"h-3.5 w-3.5"})})]}),e.jsxs(fs,{children:["On ",e.jsx("strong",{children:p})," ",N,", after which standard pricing applies."," ",e.jsx(X,{to:"/plans",className:"underline font-semibold",children:"Review plans"})," ","or ",e.jsx(X,{to:"/dashboard",className:"underline font-semibold",children:"renew now"})," to lock in your rate."]})]},a.id)})}):null}function so(){var Ft,qt,$t,Mt;const{user:s,loading:t,sessionHydrated:i}=be(),d=br(),{toast:a}=je(),m=ve(),[n,p]=c.useState(!1),[N,C]=c.useState([]),[u,g]=c.useState(null),[w,b]=c.useState(null),[A,x]=c.useState(!1),[j,v]=c.useState(!1),[l,f]=c.useState(""),[h,P]=c.useState([]),[k,H]=c.useState(!1),[$,re]=c.useState(0),[E,U]=c.useState(!1),[L,R]=c.useState(!1),[me,K]=c.useState(!1),[O,B]=c.useState(""),[G,se]=c.useState(null),ue=c.useRef(null),pe=c.useRef(!1),de=c.useCallback(r=>{B(""),requestAnimationFrame(()=>B(r))},[]),we=c.useCallback(()=>{ue.current=null,se(null),pe.current=!1},[]);c.useEffect(()=>{if(E&&ue.current){const r=ue.current,T=()=>{r.focus(),r.scrollIntoView({behavior:"smooth",block:"center"}),de("Agreement accepted. Focus returned to the upgrade button."),we()},F=requestAnimationFrame(()=>{r.disabled?requestAnimationFrame(T):T()});return()=>cancelAnimationFrame(F)}},[E,de,we]);const ce=r=>{if(r.key!=="Escape")return;if(pe.current){r.preventDefault();return}pe.current=!0;const T=ue.current,F=L;if(F&&R(!1),!T||!document.contains(T)){F&&de("Agreement highlight cleared."),we();return}r.preventDefault();try{T.focus(),T.scrollIntoView({behavior:"smooth",block:"center"}),de("Cancelled. Focus returned to the upgrade button. Agreement still not accepted.")}catch{}finally{we()}},xe=r=>{const T=ue.current;if(!T||E)return;const F=document.getElementById("listing-agreement-section"),S=r.relatedTarget;if(!(S&&F&&F.contains(S))){if(!document.contains(T)){we();return}T.focus(),T.scrollIntoView({behavior:"smooth",block:"center"}),de("Focus returned to the upgrade button. Agreement still not accepted."),we()}},Ee=r=>{r>
140&&a({title:"ð° Account Credit Applied!",description:`$${(r/100).toFixed(2)} in credits has been applied to reduce your checkout total.`})},Je=async()=>{!s||!o||await D.from("listing_agreements").insert({user_id:s.id,contractor_id:o.id,agreement_version:"1.0",user_agent:navigator.userAgent})},Xe=async(r,T="annual",F={})=>{if(!o){a({title:"Create a listing first",variant:"destructive"});return}if(!F.skipAgreementGate&&!E){a({title:"â ï¸ Listing Agreement required",description:"Step 1: Check the agreement box highlighted above the plans. Step 2: Click the upgrade button again to continue to checkout.",variant:"destructive",duration:7e3});const S=document.getElementById("listing-agreement-section");S&&S.scrollIntoView({behavior:"smooth",block:"center"}),R(!0),setTimeout(()=>R(!1),3e3);return}g(r);try{await Je();const S={planId:r,contractorId:o.id,billingInterval:T,gaClientId:ps()};l.trim()&&(S.promoCode=l.trim());const{data:z,error:le}=await D.functions.invoke("create-checkout",{body:S});if(le)throw le;if(z!=null&&z.activated&&(z!=null&&z.free_promo)){a({title:"Plan updated",description:`Your ${z.promo_code} promo covers this plan â no payment needed.`}),m.invalidateQueries({queryKey:["my-contractors"]}),K(!1);return}Ee((z==null?void 0:z.credits_applied)??0),z!=null&&z.url&&(js(z.url),K(!1))}catch(S){a({title:"Error",description:S.message,variant:"destructive"})}finally{g(null)}},Ls=async r=>{if(!o){a({title:"Create a listing first",variant:"destructive"});return}b(r);try{const{data:T,error:F}=await D.functions.invoke("create-checkout",{body:{planId:r,contractorId:o.id,type:"sponsorship",gaClientId:ps()}});if(F)throw F;Ee((T==null?void 0:T.credits_applied)??0),T!=null&&T.url&&js(T.url)}catch(T){a({title:"Error",description:T.message,variant:"destructive"})}finally{b(null)}},it=async()=>{if(!(!o||!l.trim())){v(!0);try{const{data:r,error:T}=await D.functions.invoke("create-checkout",{body:{contractorId:o.id,type:"promo",promoCode:l.trim(),gaClientId:ps()}});if(T)throw T;r!=null&&r.activated?(a({title:"Promo Activated!",description:`Your promo code has been applied.${r.free_days?` ${r.free_days} free days added!`:""}`}
14),m.invalidateQueries({queryKey:["my-contractors"]})):(Ee((r==null?void 0:r.credits_applied)??0),r!=null&&r.url&&js(r.url))}catch(r){a({title:"Error",description:r.message,variant:"destructive"})}finally{v(!1)}}},lt=async r=>{if(!(!Q||Q.length===0)){H(!0);try{const T=Q.map(z=>z.id),{data:F,error:S}=await D.functions.invoke("create-checkout",{body:{planId:r,contractorIds:T,type:"multi-listing",gaClientId:ps()}});if(S)throw S;F!=null&&F.url&&js(F.url)}catch(T){a({title:"Error",description:T.message,variant:"destructive"})}finally{H(!1)}}},Es=async r=>{var S;const T=(S=r.target.files)==null?void 0:S[0];if(!T||!o||!s)return;const F=await Vr();if(!Yr(T,F)){a({title:"Unsupported file",description:`Allowed types: ${F.allowed_extensions.join(", ")}`,variant:"destructive"});return}if(T.size>F.max_bytes){const z=Math.round(F.max_bytes/1048576);a({title:"File too large",description:`Logo must be under ${z}MB.`,variant:"destructive"});return}x(!0);try{const z=new FormData;z.append("file",T,T.name),z.append("contractor_id",o.id);const{data:le,error:Ce}=await D.functions.invoke("upload-business-logo",{body:z});if(Ce)throw Ce;if(!(le!=null&&le.ok))throw new Error((le==null?void 0:le.error)??"Upload failed");m.invalidateQueries({queryKey:["my-contractors"]}),a({title:"Logo updated!"})}catch(z){a({title:"Upload failed",description:z.message,variant:"destructive"})}finally{x(!1)}};c.useEffect(()=>{let r=!0;return!i||t||s?()=>{r=!1}:((async()=>{const F=Date.now();for(;r&&Date.now()-F<2500;){const{data:{session:S}}=await D.auth.getSession();if(S!=null&&S.user)return;await new Promise(z=>setTimeout(z,150))}r&&d("/auth",{replace:!0})})(),()=>{r=!1})},[s,i,t,d]);const{data:us}=yr(),{data:ot}=ga(),Pe=(ot??[]).map(r=>({value:r.slug,label:r.label})),{data:Q,isLoading:Rs}=ae({queryKey:["my-contractors",s==null?void 0:s.id],queryFn:async()=>{var z;const{data:r}=await D.from("profiles").select("preferences").eq("user_id",s.id).maybeSingle(),T=(z=r==null?void 0:r.preferences)==null?void 0:z.hub_listing_ids;let F=D.from("contractors").select("*, categories(*)").eq("user_id",s.id);Array.isArray(T)&&T.length>0&&(F=F.in("id",T));const{data:S}=await F.order("created_at");return Tr(S??[],{userId:s.id})},enabled:!!s}),Re=fn(s==null?void 0:s.id),[Te,xs]=c.useState(()=>typeof window>"u"||!Re?null:localStorage.getItem(Re)),[ge,Fe]=c.useState(!1),Ze=c.useCallback(r=>{xs(r),Re&&(r?localStorage.setItem(Re,r):localStorage.removeItem(Re))},[Re]),o=pn(Q,Te,ge);c.useEffect(()=>{const r=gn(Q,Te,ge);r&&Ze(r)},[Q,Te,ge,Ze]),c.useEffect(()=>{if(o!=null&&o.photos){const r=Array.isArray(o.photos)?o.photos.filter(T=>typeof T=="string"&&T.length>0):[];C(r)}},[o]);const{data:y}=ae({queryKey:["listing-plans"],queryFn:async()=>{const{data:r}=await D.from("listing_plans").select("*").eq("is_active",!0).order("sort_order");return r??[]}}),{data:V}=ae({queryKey:["sponsorship-packages"],queryFn:async()=>{const{data:r}=await D.from("sponsorship_packages").select("*").eq("is_active",!0).order("price_cents");return r??[]}}),{data:I}=ae({queryKey:["my-payments",o==null?void 0:o.id],queryFn:async()=>{const{data:r}=await D.from("payments").select("*").eq("contractor_id",o.id).order("created_at",{ascending:!1});return r??[]},enabled:!!o}),{data:ne}=ae({queryKey:["account-credit-balance",s==null?void 0:s.id],queryFn:async()=>{const{data:r}=await D.from("account_credits").select("amount_cents").eq("user_id",s.id);return(r??[]).reduce((F,S)=>F+S.amount_cents,0)},enabled:!!s}),{data:Ae}=ae({queryKey:["account-credit-transactions",s==null?void 0:s.id],queryFn:async()=>{const{data:r}=await D.from("account_credits").select("*").eq("user_id",s.id).order("created_at",{ascending:!1});return r??[]},enabled:!!s}),{data:Ue}=ae({queryKey:["my-review-stats",o==null?void 0:o.id],queryFn:async()=>{const{data:r}=await D.from("reviews").select("rating").eq("contractor_id",o.id),T=r??[],F=T.length>0?T.reduce((S,z)=>S+z.rating,0)/T.length:0;return{count:T.length,avg:F}},enabled:!!o}),ct=fe({mutationFn:async r=>{var z;const T=r.get("business_name"),F=T.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")+"-"+Date.now().toString(36),S={user_id:s.id,business_name:T,description:r.get("description")||null,phone:r.get("phone")||null,email:r.get("email")||null,website:r.get("website")||null,whatsapp:r.get("whatsapp")||null,service_area:r.get("service_area")||null,category_id:r.get("category_id")||null,coupon_text:r.get("coupon_text")||null};if(o){const{coupon_text:le,...Ce}=S,Se={...Ce,slug:o.slug};Sr(Se);const{error:_e}
14=await D.from("contractors").update(Se).eq("id",o.id);if(_e)throw _e}else{if(h.length===0)throw new Error("Please select at least one listing area");const{data:le}=await D.from("listing_plans").select("id, duration_days").eq("price_cents",0).eq("is_active",!0).order("sort_order").limit(1).maybeSingle(),Ce=le?new Date(Date.now()+le.duration_days*24*60*60*1e3).toISOString():null,Se=h.map((qe,$e)=>Ar({...S,slug:h.length>1?`${F}-${qe}`:F,metro_area:qe,plan_id:(le==null?void 0:le.id)||null,listing_expires_at:Ce})),{data:_e,error:te}=await D.from("contractors").insert(Se).select("id");if(te)throw te;await D.from("user_roles").insert({user_id:s.id,role:"contractor"});const Oe=sessionStorage.getItem("pendingPromoCode"),Fs=sessionStorage.getItem("promoSource");if(Oe&&((z=_e==null?void 0:_e[0])!=null&&z.id)){const{data:qe}=await D.from("promotions").select("id").eq("code",Oe).eq("is_active",!0).maybeSingle();await D.from("promo_redemptions").insert({user_id:s.id,contractor_id:_e[0].id,promo_code:Oe,source:Fs||"direct",promotion_id:(qe==null?void 0:qe.id)||null}),await D.from("contractors").update({promo_code:Oe,promo_redeemed_at:new Date().toISOString()}).eq("id",_e[0].id),sessionStorage.removeItem("pendingPromoCode"),sessionStorage.removeItem("promoSource")}}},onSuccess:()=>{a({title:"Saved!",description:"Your listing has been updated."}
14),m.invalidateQueries({queryKey:["my-contractors"]}),p(!1),Fe(!1)},onError:r=>{a({title:"Error",description:Cr(r),variant:"destructive"})}}),Ta=r=>{r.preventDefault(),ct.mutate(new FormData(r.currentTarget))},La=c.useCallback(async(r,T,F)=>{const S=new Ts,z=new Date(r.created_at).toLocaleDateString(),le=`$${(r.amount_cents/100).toFixed(2)}`,Ce=(o==null?void 0:o.business_name)??"N/A",Se=o==null?void 0:o.logo_url,_e=`INV-${String(F-T).padStart(4,"0")}`;S.setFillColor(34,34,34),S.rect(0,0,210,44,"F"),S.setTextColor(255),S.setFontSize(22),S.text("Townsyâ¢",20,22),S.setFontSize(9),S.text("Local Services Marketplace",20,30),S.text("[email protected] ⢠townsy.app",20,37),S.setFontSize(16),S.text(_e,190,22,{align:"right"}),S.setFontSize(10),S.text(z,190,30,{align:"right"});let te=58,Oe=!1;if(Se)try{const $e=new Image;$e.crossOrigin="anonymous",await new Promise((dt,Ra)=>{$e.onload=()=>dt(),$e.onerror=()=>Ra(),$e.src=Se}),S.addImage($e,"PNG",20,te-4,18,18),Oe=!0}catch{}const Fs=Oe?42:20;S.setTextColor(120),S.setFontSize(9),S.text("BILL TO",Fs,te),S.setTextColor(0),S.setFontSize(13),S.text(Ce,Fs,te+8),S.setTextColor(120),S.setFontSize(9),S.text("DOCUMENT",140,te),S.setTextColor(0),S.setFontSize(13),S.text("Payment Receipt",140,te+8),te=80,S.setDrawColor(220),S.line(20,te,190,te),te=90,S.setFontSize(11);const qe=[["Invoice #",_e],["Date",z],["Payment Type",r.payment_type.replace(/_/g," ")],["Payment Method",r.payment_method],["Status",r.status.charAt(0).toUpperCase()+r.status.slice(1)]];for(const[$e,dt]of qe)S.setTextColor(120),S.text($e,20,te),S.setTextColor(0),S.text(dt,80,te),te+=9;r.notes&&(te+=2,S.setTextColor(120),S.text("Notes",20,te),S.setTextColor(0),S.text(r.notes,80,te),te+=9),te+=6,S.setDrawColor(220),S.line(20,te,190,te),te+=10,S.setFillColor(245,245,245),S.roundedRect(120,te-6,70,18,3,3,"F"),S.setFontSize(10),S.setTextColor(120),S.text("Total Paid",126,te+2),S.setFontSize(16),S.setTextColor(0),S.text(le,126,te+12),S.setFontSize(8),S.setTextColor(160),S.text("Thank you for your business. This receipt was generated automatically.",105,280,{align:"center"}),S.text(`© ${new Date().getFullYear()} Townsy⢠â All rights reserved`,105,286,{align:"center"}),S.save(`${_e}.pdf`)},[o==null?void 0:o.business_name,o==null?void 0:o.logo_url]);if(!i||t||Rs)return e.jsx(Bt,{children:e.jsx("div",{className:"container py-16",children:e.jsx("div",{className:"h-64 bg-muted rounded-xl animate-pulse"})})});const Ea=!o||n;return e.jsxs(Bt,{children:[e.jsx(Nr,{title:"Dashboard â Townsyâ¢",description:"Manage your Townsy⢠business listing, classifieds, events, and analytics.",image:"https://townsy.ai/og-image.jpg",noindex:!0}),e.jsxs("div",{className:"container py-4 sm:py-8 max-w-3xl px-3 sm:px-4",children:[e.jsx("h1",{className:"font-heading text-xl sm:text-3xl font-bold mb-1",children:"My Dashboard"}),e.jsx("p",{className:"text-xs sm:text-base text-muted-foreground mb-2",children:"Manage your personal account and business listings"}),e.jsxs(wr,{defaultValue:"business",className:"mb-6",children:[e.jsxs(_r,{className:"grid w-full grid-cols-2 mb-4 sticky top-14 sm:static z-30 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/70",children:[e.jsxs(Vt,{value:"personal",className:"flex items-center gap-2",children:[e.jsx(kt,{className:"h-4 w-4"})," Personal"]}),e.jsxs(Vt,{value:"business",className:"flex items-center gap-2",children:[e.jsx(ja,{className:"h-4 w-4"})," Business"]})]}),e.jsx(Yt,{value:"personal",children:e.jsx(mi,{})}),e.jsxs(Yt,{value:"business",children:[e.jsx("div",{className:"mb-4",children:e.jsx(bi,{})}),Q&&(Q.length>1||ge)&&e.jsx(q,{className:"mb-4 border-primary/30 bg-primary/5",children:e.jsxs(M,{className:"p-3 flex flex-col sm:flex-row sm:items-center gap-3",children:[e.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[e.jsx(kr,{className:"h-4 w-4 text-primary"}),e.jsx(W,{className:"text-xs font-semibold uppercase tracking-wide text-muted-foreground",children:"Active business"})]}),e.jsx("div",{className:"flex-1 min-w-0",children:e.jsxs(is,{value:ge?"__new__":(o==null?void 0:o.id)??"",onValueChange:r=>{r==="__new__"?(Fe(!0),p(!0),P([])):(Fe(!1),p(!1),Ze(r))},children:[e.jsx(ls,{"aria-label":"Switch active business",className:"bg-background",children:e.jsx(os,{placeholder:"Select a business"})}),e.jsxs(cs,{children:[Q.map(r=>
14e.jsx(ke,{value:r.id,children:e.jsxs("span",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"truncate",children:r.business_name}),r.status!=="active"&&e.jsx(J,{variant:"outline",className:"text-[10px] py-0 h-4",children:ea(r.status)})]})},r.id)),e.jsx(ke,{value:"__new__",children:e.jsxs("span",{className:"flex items-center gap-2 text-primary font-medium",children:[e.jsx(Ye,{className:"h-3.5 w-3.5"})," Add another businessâ¦"]})})]})]})}),e.jsxs(_,{type:"button",size:"sm",variant:"outline",onClick:()=>{Fe(!0),p(!0),P([])},className:"shrink-0",children:[e.jsx(Ye,{className:"h-4 w-4 mr-1"})," Add business"]})]})}),Q&&Q.length===1&&!ge&&e.jsx("div",{className:"mb-4",children:e.jsxs(_,{type:"button",size:"sm",variant:"ghost",className:"px-0 text-muted-foreground hover:text-foreground",onClick:()=>{Fe(!0),p(!0),P([])},children:[e.jsx(Ye,{className:"h-4 w-4 mr-1"})," Add another business"]})}),e.jsx("p",{className:"text-muted-foreground mb-4",children:ge?"Set up an additional business listing below":o?`Welcome back, ${o.business_name}`:"Set up your business listing below"}),(o==null?void 0:o.plan_id)&&e.jsx("div",{className:"mt-4",children:e.jsx(Dn,{contractorId:o.id})}),o&&e.jsxs(e.Fragment,{children:[e.jsx(hn,{onEdit:()=>p(!0)}),e.jsx(dn,{listing:o,onEdit:()=>p(!0)}),e.jsx(vi,{contractorIds:(Q==null?void 0:Q.map(r=>r.id))??[o.id]}),e.jsx(gi,{userId:s.id,contractorIds:(Q==null?void 0:Q.map(r=>r.id))??[o.id]}),e.jsx(hi,{contractorId:o.id}),e.jsx(Rn,{slugs:(Q??[]).map(r=>r.slug).filter(r=>!!r)}),(()=>{var F;const r=((F=(y??[]).find(S=>S.id===o.plan_id))==null?void 0:F.name)??"",T=r.toLowerCase().includes("premium")?"premium":r.toLowerCase().includes("pro")?"pro":r.toLowerCase().includes("basic")?"basic":"free";return e.jsx(Tn,{contractorIds:(Q==null?void 0:Q.map(S=>S.id))??[],tier:T})})(),(()=>{var F;return(((F=(y??[]).find(S=>S.id===o.plan_id))==null?void 0:F.name)??"").toLowerCase().includes("premium")?e.jsx(Fn,{contractorIds:(Q==null?void 0:Q.map(S=>S.id))??[]}):o.plan_id?e.jsxs("div",{className:"mb-6 rounded-lg border border-dashed border-muted-foreground/30 p-6 text-center",children:[e.jsx(ns,{className:"h-5 w-5 mx-auto mb-2 text-muted-foreground"}),e.jsx("p",{className:"text-sm font-medium text-foreground",children:"Lead Management Tools"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"Upgrade to Premium to access the full lead management inbox with filtering, response tracking, and conversion analytics."})]}):null})(),e.jsx(q,{className:`mb-6 border-primary/30 ${(ne??0)>0?"bg-primary/5":"bg-muted/50"}`,children:e.jsxs(M,{className:"p-4 flex items-center gap-3",children:[e.jsx(ha,{className:"h-5 w-5 text-primary"}),e.jsxs("div",{children:[e.jsxs("p",{className:"font-semibold text-sm",children:["Account Credit Balance: ",e.jsxs("span",{className:"text-primary",children:["$",((ne??0)/100).toFixed(2)]})]}),(ne??0)>0?e.jsx("p",{className:"text-xs text-muted-foreground",children:"Credits will be automatically applied to your next checkout."}):e.jsx("p",{className:"text-xs text-muted-foreground",children:"Earn credits by donating a gift certificate! Approved donations add credits to your balance that reduce future payments."})]})]})}),((Ae==null?void 0:Ae.length)??0)>0&&e.jsxs(q,{className:"mb-6",children:[e.jsx(Z,{className:"pb-2",children:e.jsxs(ee,{className:"text-sm font-semibold flex items-center gap-2",children:[e.jsx(Zt,{className:"h-4 w-4"}),"Credit History"]})}),e.jsx(M,{className:"p-0",children:(()=>{const T=Ae.length,F=Math.ceil(T/10),S=Ae.slice($*10,($+1)*10);return e.jsxs(e.Fragment,{children:[e.jsxs(vt,{children:[e.jsx(bt,{children:e.jsxs(es,{children:[e.jsx(ye,{className:"text-xs",children:"Date"}),e.jsx(ye,{className:"text-xs",children:"Description"}),e.jsx(ye,{className:"text-xs text-right",children:"Amount"})]})}),e.jsx(yt,{children:S.map(z=>e.jsxs(es,{children:[e.jsx(Ne,{className:"text-xs text-muted-foreground",children:new Date(z.created_at).toLocaleDateString()}),e.jsx(Ne,{className:"text-xs",children:z.reason}),e.jsxs(Ne,{className:`text-xs text-right font-medium ${z.amount_cents>=0?"text-green-600":"text-destructive"}`,children:[z.amount_cents>=0?"+":"","$",(z.amount_cents/100).toFixed(2)]})]},z.id))})]}),F>1&&e.jsxs("div",{className:"flex items-center justify-between px-4 py-2 border-t",children:[e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Page ",$+1," of ",F," (",T," entries)"]}
14),e.jsxs("div",{className:"flex gap-1",children:[e.jsx(_,{variant:"outline",size:"sm",className:"h-7 text-xs",disabled:$===0,onClick:()=>re(z=>z-1),children:"Previous"}),e.jsx(_,{variant:"outline",size:"sm",className:"h-7 text-xs",disabled:$>=F-1,onClick:()=>re(z=>z+1),children:"Next"})]})]})]})})()})]}),e.jsx(wn,{businessName:o.business_name,slug:o.slug,phone:o.phone,email:o.email,website:o.website,serviceArea:o.service_area,categoryName:(Ft=o.categories)==null?void 0:Ft.name,logoUrl:o.logo_url,description:o.description}),e.jsx(Cn,{}),e.jsx(Sn,{}),e.jsx(An,{businessName:o.business_name,slug:o.slug,categoryName:(qt=o.categories)==null?void 0:qt.name,logoUrl:o.logo_url,couponText:o.coupon_text}),o.plan_id&&e.jsx(qn,{contractorId:o.id,businessName:o.business_name,slug:o.slug,categoryName:($t=o.categories)==null?void 0:$t.name,currentCoupon:o.coupon_text}),e.jsxs("div",{className:"grid grid-cols-3 gap-2 sm:gap-4 mb-4 sm:mb-6",children:[e.jsx(q,{children:e.jsxs(M,{className:"p-2 sm:p-4 text-center",children:[e.jsx("p",{className:"text-lg sm:text-2xl font-bold leading-tight",children:(Ue==null?void 0:Ue.count)??0}),e.jsx("p",{className:"text-[10px] sm:text-xs text-muted-foreground",children:"Total Reviews"})]})}),e.jsx(q,{children:e.jsxs(M,{className:"p-2 sm:p-4 text-center",children:[e.jsxs("div",{className:"flex items-center justify-center gap-1",children:[e.jsx(ss,{className:"h-3.5 w-3.5 sm:h-4 sm:w-4 fill-amber-400 text-amber-400"}),e.jsx("span",{className:"text-lg sm:text-2xl font-bold leading-tight",children:Ue!=null&&Ue.avg?Ue.avg.toFixed(1):"â"})]}),e.jsx("p",{className:"text-[10px] sm:text-xs text-muted-foreground",children:"Avg Rating"})]})}),e.jsx(q,{children:e.jsxs(M,{className:"p-2 sm:p-4 text-center",children:[e.jsx("p",{className:"text-lg sm:text-2xl font-bold leading-tight",children:o.listing_expires_at?(()=>{const r=Math.ceil((new Date(o.listing_expires_at).getTime()-Date.now())/864e5);return r>0?r:"0"})():"â"}),e.jsx("p",{className:"text-[10px] sm:text-xs text-muted-foreground",children:"Days Left"})]})})]})]}),o&&!o.plan_id&&!n&&e.jsx(q,{className:"mb-6 border-2 border-primary bg-gradient-to-br from-primary/10 to-accent/10 shadow-lg",children:e.jsx(M,{className:"p-6",children:e.jsxs("div",{className:"flex items-start gap-4",children:[e.jsx("div",{className:"flex h-14 w-14 shrink-0 items-center justify-center rounded-2xl bg-primary text-primary-foreground shadow-md",children:e.jsx(wt,{className:"h-7 w-7"})}),e.jsxs("div",{className:"flex-1",children:[e.jsx("h3",{className:"font-heading font-bold text-xl",children:"Ready to Go Live? ð"}),e.jsxs("p",{className:"text-sm text-muted-foreground mt-1",children:["Your listing is set up â now choose a plan to make it visible to customers. Start with our ",e.jsx("strong",{children:"free 1-year listing"})," or upgrade for more features."]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-3 mt-4",children:[e.jsx(_,{size:"lg",className:"gap-2",onClick:async()=>{try{const{error:r}=await D.rpc("activate_free_listing",{_contractor_id:o.id});if(r)throw r;a({title:"ð You're live!",description:"Your free listing is now active for 1 year."}
14),m.invalidateQueries({queryKey:["my-contractors"]})}catch(r){a({title:"Error",description:r.message,variant:"destructive"})}},children:"Start Free (1 Year)"}),e.jsx("a",{href:"#plans-section",children:e.jsxs(_,{variant:"outline",size:"lg",className:"gap-2",children:[e.jsx(ss,{className:"h-4 w-4"})," Compare Plans"]})})]})]})]})})}),e.jsx(yi,{}),(o==null?void 0:o.listing_expires_at)&&(()=>{const r=Math.ceil((new Date(o.listing_expires_at).getTime()-Date.now())/864e5);return r<=0?e.jsxs(gs,{variant:"destructive",className:"mb-6",children:[e.jsx(ks,{className:"h-4 w-4"}),e.jsx(Vs,{children:"Free Listing Expired"}),e.jsx(fs,{children:"Your free listing has expired. Upgrade to a paid plan to keep your listing active."})]}):r<=7?e.jsxs(gs,{className:"mb-6 border-yellow-500/50 bg-yellow-50 dark:bg-yellow-950/20",children:[e.jsx(ks,{className:"h-4 w-4 text-yellow-600"}),e.jsx(Vs,{className:"text-yellow-800 dark:text-yellow-400",children:"Free Listing Expiring Soon"}),e.jsxs(fs,{className:"text-yellow-700 dark:text-yellow-500",children:["Your free listing expires in ",r," day",r!==1?"s":"",". Upgrade now to keep your listing visible."]})]}):null})(),o&&e.jsx(q,{className:"mb-6 border-primary/30 bg-primary/5",children:e.jsx(M,{className:"p-6",children:e.jsxs("div",{className:"flex items-start gap-4",children:[e.jsx("div",{className:"flex h-12 w-12 shrink-0 items-center justify-center rounded-xl bg-primary/10 text-primary",children:e.jsx(Be,{className:"h-6 w-6"})}),e.jsxs("div",{className:"flex-1",children:[e.jsx("h3",{className:"font-heading font-semibold text-lg",children:"Apply Promo Code"}),e.jsxs("p",{className:"text-sm text-muted-foreground mt-1",children:["Founding members save ",e.jsx("strong",{children:"up to 20% off"}
14)," their first annual renewal (one-time, first renewal only)."]}),e.jsxs("div",{className:"flex items-center gap-3 mt-4",children:[e.jsx(Y,{value:l,onChange:r=>f(r.target.value.toUpperCase()),placeholder:"Enter promo code",className:"max-w-[180px] font-mono uppercase"}),e.jsx(_,{onClick:it,disabled:j||!l.trim(),children:j?e.jsxs(e.Fragment,{children:[e.jsx(ie,{className:"h-4 w-4 mr-2 animate-spin"})," Processing..."]}):"Activate Promo"})]})]})]})})}),o&&o.promo_code&&(()=>{const r=Nn(o.promo_code),T=r.status==="matched"?r:null,F=r.status==="unrecognized",S=T?"border-primary/40 bg-gradient-to-r from-primary/10 to-accent/5":F?"border-amber-500/40 bg-amber-500/5":"border-muted bg-muted/30";return e.jsxs(gs,{className:`mb-6 ${S}`,children:[e.jsx(Be,{className:`h-4 w-4 ${T?"text-primary":F?"text-amber-600":"text-muted-foreground"}`}),e.jsxs(Vs,{className:"flex items-center gap-2 flex-wrap",children:["Promo on file: ",e.jsx("span",{className:"font-mono",children:o.promo_code}),T&&e.jsxs(J,{variant:"secondary",className:"ml-1",children:[T.percent,"% off first annual renewal"]}),F&&e.jsx(J,{variant:"outline",className:"ml-1 border-amber-500/60 text-amber-700",children:"Not a recognized renewal code"})]}),e.jsx(fs,{className:"space-y-1",children:T?e.jsxs(e.Fragment,{children:[e.jsxs("p",{children:["Your kickoff promotion is active! Enjoy your free listing period.",o.listing_expires_at&&` Free until ${new Date(o.listing_expires_at).toLocaleDateString()}.`]}),e.jsxs("p",{className:"text-sm",children:[e.jsx("strong",{children:"Renewal discount confirmed:"})," ",T.label,". The code ",e.jsx("span",{className:"font-mono",children:T.code})," will be applied automatically at your first annual renewal. Standard pricing applies for all renewals after that."]})]}):F?e.jsxs("p",{className:"text-sm",children:[e.jsx("strong",{children:"Standard pricing applies at renewal."})," The code on your account isn't a recognized founding-member renewal code. Valid launch codes (LAUNCH50/40/30/25/20) grant up to 50% off the first annual renewal only. Contact support if you believe this is an error."]}):e.jsxs("p",{className:"text-sm text-muted-foreground",children:[e.jsx("strong",{children:"Standard pricing applies at renewal."})," No founding-member discount is attached to this code."]})})]})})(),o&&e.jsx(q,{className:"mb-6 border-accent/30 bg-gradient-to-r from-accent/5 to-primary/5",children:e.jsx(M,{className:"p-6",children:e.jsxs("div",{className:"flex items-start gap-4",children:[e.jsx("div",{className:"flex h-12 w-12 shrink-0 items-center justify-center rounded-xl bg-accent/10 text-accent",children:e.jsx(Be,{className:"h-6 w-6"})}),e.jsxs("div",{className:"flex-1",children:[e.jsx("h3",{className:"font-heading font-semibold text-lg",children:"Earn Listing Credits ð°"}),e.jsxs("p",{className:"text-sm text-muted-foreground mt-1",children:["Donate a gift certificate or giveaway prize and get ",e.jsx("strong",{children:"dollar-for-dollar listing credits"}),". A $50 gift card = $50 credit toward your plan, renewal, or add-ons."]}),e.jsxs("div",{className:"flex items-center gap-3 mt-4",children:[e.jsx(X,{to:"/gift-credit",children:e.jsx(_,{variant:"outline",size:"sm",children:"Learn about listing credits"})}),e.jsx("a",{href:"#credits",children:e.jsx(_,{size:"sm",className:"bg-accent hover:bg-accent/90 text-accent-foreground",children:"Donate Now"})})]})]})]})})}),o&&!n&&e.jsxs(q,{children:[e.jsx(Z,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsxs("label",{className:"relative cursor-pointer group/logo",children:[e.jsx("div",{className:"h-14 w-14 rounded-lg bg-muted flex items-center justify-center overflow-hidden border border-border",children:Zs(o.logo_url)?e.jsx(Cs,{className:"h-6 w-6 text-muted-foreground"}):o.logo_url?e.jsx("img",{src:o.logo_url,alt:"Logo",className:"h-full w-full object-cover"}):e.jsx(ms,{className:"h-6 w-6 text-muted-foreground"})}),e.jsx("div",{className:"absolute inset-0 rounded-lg bg-black/50 flex items-center justify-center opacity-0 group-hover/logo:opacity-100 transition-opacity",children:A?e.jsx(ie,{className:"h-4 w-4 text-white animate-spin"}):e.jsx(Xs,{className:"h-4 w-4 text-white"})}),e.jsx("input",{type:"file",accept:Kt,className:"hidden",onChange:Es,disabled:A})]}),e.jsxs("div",{children:[e.jsx(ee,{children:o.business_name}),e.jsxs(he,{className:"flex items-center gap-2 mt-1",children:["Status: ",e.jsx(J,{variant:o.status==="active"?"default":"secondary",children:ea(o.status)})]})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsxs(_,{size:"sm",onClick:()=>K(!0),className:"bg-gradient-to-r from-primary to-accent text-primary-foreground hover:opacity-90",children:[e.jsx(wt,{className:"h-4 w-4 mr-1"}),o.plan_id&&(y!=null&&y.find(r=>r.id===o.plan_id&&r.price_cents>0))?"Change Plan":"Upgrade Plan"]}),e.jsx(X,{to:`/contractor/${o.slug}`,children:e.jsxs(_,{variant:"outline",size:"sm",children:[e.jsx(Ke,{className:"h-4 w-4 mr-1"})," View"]})}),e.jsxs(_,{variant:"outline",size:"sm",onClick:()=>p(!0),children:[e.jsx(Et,{className:"h-4 w-4 mr-1"})," Edit"]}),e.jsx(va,{url:`${window.location.origin}/contractor/${o.slug}`,title:"Share your listing",triggerSize:"sm"})]})]})}),e.jsx(M,{children:e.jsxs("div",{className:"grid gap-4 text-sm",children:[o.description&&e.jsx("p",{className:"text-muted-foreground",children:o.description}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[o.phone&&e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"Phone:"})," ",o.phone]}),o.email&&e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"Email:"})," ",o.email]}),o.service_area&&e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"Area:"})," ",o.service_area]}),o.metro_area&&e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"Metro:"})," ",((Mt=Pe.find(r=>r.value===o.metro_area))==null?void 0:Mt.label)||o.metro_area]}),o.categories&&e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"Category:"})," ",o.categories.name]})]}),o&&s&&e.jsx("div",{className:"mt-4 pt-4 border-t",children:e.jsx(jn,{contractorId:o.id,userId:s.id,photos:N,onPhotosChange:C})}),o&&s&&e.jsx("div",{className:"mt-4 pt-4 border-t",children:e.jsx(bn,{contractorId:o.id,userId:s.id,hasVideoAddon:o.has_video_addon,videoUrl:o.video_url,videoFileUrl:o.video_file_url})})]})})]}),Ea&&e.jsxs(q,{children:[e.jsxs(Z,{children:[e.jsx(ee,{children:o?"Edit Your Listing":"Create Your Listing"}),e.jsx(he,{children:"Fill in your business details to get listed"})]}
14),e.jsxs(M,{children:[!o&&sessionStorage.getItem("pendingPromoCode")&&e.jsxs("div",{className:"flex items-center justify-between rounded-lg border border-primary/30 bg-primary/5 p-3 mb-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Be,{className:"h-4 w-4 text-primary shrink-0"}),e.jsxs("span",{className:"text-sm",children:["Promo code ",e.jsx(J,{variant:"secondary",className:"font-mono mx-1",children:sessionStorage.getItem("pendingPromoCode")})," will be applied when you create your listing"]})]}),e.jsxs("div",{className:"flex items-center gap-1 shrink-0",children:[e.jsx(_,{type:"button",variant:"ghost",size:"sm",className:"h-7 text-xs",onClick:()=>{const r=prompt("Enter a new promo code (or leave empty to remove):",sessionStorage.getItem("pendingPromoCode")||"");if(r===null)return;const T=r.trim().toUpperCase();T?sessionStorage.setItem("pendingPromoCode",T):(sessionStorage.removeItem("pendingPromoCode"),sessionStorage.removeItem("promoSource")),window.dispatchEvent(new Event("storage")),location.reload()},children:"Change"}),e.jsx(_,{type:"button",variant:"ghost",size:"icon",className:"h-10 w-10 text-muted-foreground hover:text-destructive",onClick:()=>{sessionStorage.removeItem("pendingPromoCode"),sessionStorage.removeItem("promoSource"),location.reload()},children:e.jsx(Ca,{className:"h-4 w-4"})})]})]}),e.jsxs("form",{onSubmit:Ta,className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(W,{children:"Business Name *"}),e.jsx(Y,{name:"business_name",required:!0,defaultValue:(o==null?void 0:o.business_name)||""})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(W,{children:"Category"}),e.jsxs(is,{name:"category_id",defaultValue:(o==null?void 0:o.category_id)||"",children:[e.jsx(ls,{children:e.jsx(os,{placeholder:"Select category"})}),e.jsx(cs,{children:us==null?void 0:us.map(r=>e.jsx(ke,{value:r.id,children:r.name},r.id))})]})]}),!o&&e.jsxs("div",{className:"space-y-3",children:[e.jsxs(W,{className:"flex items-center gap-1.5",children:[e.jsx(Ve,{className:"h-4 w-4 text-primary"})," Listing Areas *"]}),e.jsxs(gs,{className:"border-primary/20 bg-primary/5",children:[e.jsx(Ve,{className:"h-4 w-4 text-primary"}),e.jsxs(fs,{className:"text-sm",children:[e.jsx("strong",{children:"Each metro area is a separate listing."})," Select every market you want to appear in.",h.length>1&&e.jsxs("span",{className:"block mt-1 text-primary font-semibold",children:["ð Multi-listing discount: 10% off for each additional area! You're saving on ",h.length-1," extra listing",h.length>2?"s":"","."]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("label",{className:"flex items-center gap-2 cursor-pointer font-medium text-sm",children:[e.jsx(He,{checked:Pe.length>0&&h.length===Pe.length,onCheckedChange:r=>{P(r?Pe.map(T=>T.value):[])}}),"All Areas (",Pe.length," listings)"]}),e.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-2 pl-1",children:Pe.map(r=>e.jsxs("label",{className:"flex items-center gap-2 cursor-pointer text-sm",children:[e.jsx(He,{checked:h.includes(r.value),onCheckedChange:T=>{P(F=>T?[...F,r.value]:F.filter(S=>S!==r.value))}}),r.label]},r.value))})]}),h.length>0&&e.jsxs("p",{className:"text-xs text-muted-foreground font-medium",children:[h.length," listing",h.length!==1?"s":""," will be created",h.length>1&&" ⢠10% multi-listing discount applies at checkout"]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(W,{children:"Business Logo"}),e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsxs("label",{className:"relative cursor-pointer group/logo",children:[e.jsx("div",{className:"h-16 w-16 rounded-lg bg-muted flex items-center justify-center overflow-hidden border border-border",children:Zs(o==null?void 0:o.logo_url)?e.jsx(Cs,{className:"h-7 w-7 text-muted-foreground"}):o!=null&&o.logo_url?e.jsx("img",{src:o.logo_url,alt:"Logo",className:"h-full w-full object-cover"}):e.jsx(ms,{className:"h-6 w-6 text-muted-foreground"})}),e.jsx("div",{className:"absolute inset-0 rounded-lg bg-black/50 flex items-center justify-center opacity-0 group-hover/logo:opacity-100 transition-opacity",children:A?e.jsx(ie,{className:"h-4 w-4 text-white animate-spin"}):e.jsx(Xs,{className:"h-4 w-4 text-white"})}),e.jsx("input",{type:"file",accept:Kt,className:"hidden",onChange:Es,disabled:A})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Click to upload or change your logo (photo or PDF, max 100MB)"})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(W,{children:"Description"}),e.jsx(rs,{name:"description",rows:3,defaultValue:(o==null?void 0:o.description)||""})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(W,{children:"Phone"}),e.jsx(Y,{name:"phone",defaultValue:(o==null?void 0:o.phone)||""})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(W,{children:"Email"}),e.jsx(Y,{name:"email",type:"email",defaultValue:(o==null?void 0:o.email)||""})]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(W,{children:"Website"}),e.jsx(Y,{name:"website",defaultValue:(o==null?void 0:o.website)||""})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(W,{children:"WhatsApp"}),e.jsx(Y,{name:"whatsapp",defaultValue:(o==null?void 0:o.whatsapp)||""})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(W,{children:"Service Area"}),e.jsx(Y,{name:"service_area",placeholder:"e.g. Downtown, Metro Area",defaultValue:(o==null?void 0:o.service_area)||""})]}),!o&&e.jsxs("div",{className:"space-y-2",children:[e.jsx(W,{children:"Coupon / Special Offer (optional)"}),e.jsx(Y,{name:"coupon_text",placeholder:"e.g. 10% off first visit â mention Townsyâ¢!"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"You can edit your coupon any time from the Coupon Builder. All future edits are reviewed by an admin before going live."})]}),!o&&!sessionStorage.getItem("pendingPromoCode")&&e.jsxs("div",{className:"space-y-2",children:[e.jsxs(W,{className:"flex items-center gap-1.5",children:[e.jsx(Be,{className:"h-4 w-4 text-primary"})," Promo Code (optional)"]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(Y,{placeholder:"e.g. LAUNCH50",value:l,onCh
14ange:r=>f(r.target.value.toUpperCase())}),l.trim()&&e.jsx(_,{type:"button",variant:"outline",size:"sm",className:"shrink-0",onClick:()=>{sessionStorage.setItem("pendingPromoCode",l.trim()),sessionStorage.setItem("promoSource","listing_form"),location.reload()},children:"Apply"})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Have a founding member promo code? Enter it here to lock in your discount."})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(_,{type:"submit",disabled:ct.isPending||!o&&h.length===0,children:ct.isPending?"Saving...":o?"Update Listing":h.length>1?`Create ${h.length} Listings`:"Create Listing"}),n&&e.jsx(_,{type:"button",variant:"outline",onClick:()=>p(!1),children:"Cancel"})]})]})]})]}),Q&&Q.length>1&&y&&y.length>0&&e.jsxs(q,{className:"mt-8 border-primary/30 bg-primary/5",children:[e.jsxs(Z,{children:[e.jsxs(ee,{className:"flex items-center gap-2",children:[e.jsx(Ve,{className:"h-5 w-5 text-primary"}),"Upgrade All ",Q.length," Listings"]}),e.jsxs(he,{children:["You have ",e.jsxs("strong",{children:[Q.length," listings"]})," across different metro areas. Upgrade them all at once and save with our multi-listing discount!"]})]}),e.jsx(M,{children:e.jsx("div",{className:"space-y-3",children:y.filter(r=>r.price_cents>0).map(r=>{const T=Q.length,F=r.price_cents,S=Math.round(F*.9),z=F+(T>1?S*(T-1):0),le=F*T-z;return e.jsxs("div",{className:"flex items-center justify-between p-4 rounded-lg border bg-background",children:[e.jsxs("div",{children:[e.jsxs("p",{className:"font-semibold",children:[r.name," Ã ",T," listings"]}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["1st listing: $",(F/100).toFixed(2),T>1&&` + ${T-1} Ã $${(S/100).toFixed(2)} (10% off)`]}),le>0&&e.jsxs("p",{className:"text-xs text-primary font-semibold mt-1",children:["You save $",(le/100).toFixed(2),"!"]})]}),e.jsxs("div",{className:"text-right",children:[e.jsxs("p",{className:"text-xl font-bold font-heading",children:["$",(z/100).toFixed(2)]}),e.jsx(_,{size:"sm",className:"mt-2",onClick:()=>lt(r.id),disabled:k,children:k?e.jsxs(e.Fragment,{children:[e.jsx(ie,{className:"h-4 w-4 mr-2 animate-spin"})," Processing..."]}):"Upgrade All"})]})]},r.id)})})})]}),y&&y.length>0&&e.jsxs("div",{className:"mt-8",id:"plans-section",children:[e.jsxs("div",{className:"flex items-center justify-between flex-wrap gap-2 mb-4",children:[e.jsx("h2",{className:"font-heading text-xl font-bold",children:"Listing Plans"}),e.jsx(J,{variant:E?"default":"destructive",className:"text-xs",children:E?"â Agreement accepted":"â Agreement not accepted"})]}),e.jsx("div",{role:"status","aria-live":"polite","aria-atomic":"true",className:"sr-only",children:O}),e.jsxs("div",{id:"listing-agreement-section",className:`flex items-start gap-2 mb-4 p-3 rounded-lg border transition-all duration-300 ${L?"bg-destructive/10 border-destructive ring-2 ring-destructive/40 animate-pulse":E?"bg-primary/5 border-primary/30":"bg-muted/30"}`,children:[e.jsx(He,{id:"listing-agreement",checked:E,onCheckedChange:r=>U(r===!0),onKeyDown:ce,onBlur:xe,className:"mt-0.5"}),e.jsxs(W,{htmlFor:"listing-agreement",className:"text-sm leading-relaxed cursor-pointer",children:[e.jsx("span",{className:"font-medium",children:"Required:"})," I have read and agree to the"," ",e.jsx("a",{href:"/listing-agreement",target:"_blank",className:"text-primary underline hover:text-primary/80",children:"Business Listing Agreement"}),!E&&e.jsx("span",{className:"block text-xs text-muted-foreground mt-1",children:"You must check this box before upgrading or purchasing any plan."})]})]}),e.jsx("div",{className:"grid gap-4 sm:grid-cols-3",children:y.map(r=>{const T=r.price_cents===0,F=(o==null?void 0:o.plan_id)===r.id;return e.jsxs(q,{className:`relative ${F?"border-primary ring-2 ring-primary/20":""} ${T?"":"border-primary/40"}`,children:[F&&e.jsx(J,{className:"absolute -top-2.5 left-4 text-xs",children:"Current Plan"}),!T&&!F&&e.jsx(J,{variant:"secondary",className:"absolute -top-2.5 left-4 text-xs",children:"Upgrade"}),e.jsxs(Z,{children:[e.jsx(ee,{className:"text-lg",children:r.name}),e.jsx(he,{children:r.description})]}),e.jsxs(M,{children:[e.jsxs("p",{className:"text-2xl font-bold font-heading",children:[T?"Free":`$${(r.price_cents/100).toFixed(2)}`,!T&&e.jsx("span",{className:"text-sm text-muted-foreground font-normal",children:"/yr"})]}),!T&&r.monthly_price_cents>0&&e.jsxs("p",{className:"text-sm text-muted-foreground mt-1",children:["or $",(r.monthly_price_cents/100).toFixed(0),"/mo"]}),r.features&&e.jsx("ul",{className:"mt-3 space-y-1 text-sm text-muted-foreground",children:r.features.map((S,z)=>
14e.jsxs("li",{children:["â ",S]},z))}),!T&&!F&&o&&e.jsxs("div",{className:"mt-4 flex flex-col gap-2",children:[E?e.jsx("p",{className:"text-xs font-medium text-primary",children:"â Agreement accepted â ready to upgrade"}):e.jsx("button",{type:"button",onClick:S=>{const z=S.currentTarget.closest("[data-plan-card]"),le=z==null?void 0:z.querySelector("[data-upgrade-button]");le&&(ue.current=le,se(r.id),pe.current=!1);const Ce=document.getElementById("listing-agreement-section"),Se=document.getElementById("listing-agreement");Ce&&Ce.scrollIntoView({behavior:"smooth",block:"center"}),R(!0),setTimeout(()=>R(!1),3e3),setTimeout(()=>Se==null?void 0:Se.focus({preventScroll:!0}),500)},onKeyDown:S=>{(S.key==="Enter"||S.key===" ")&&(S.preventDefault(),S.currentTarget.click())},"aria-label":"Review Listing Agreement â jump to and focus the agreement checkbox to enable upgrade","aria-controls":"listing-agreement-section","aria-describedby":`plan-${r.id}-agreement-hint`,className:"text-xs font-medium text-destructive underline-offset-2 hover:underline text-left cursor-pointer rounded-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-destructive focus-visible:ring-offset-2",children:"â Review Listing Agreement â click to jump to checkbox"}),e.jsx("span",{id:`plan-${r.id}-agreement-hint`,className:"sr-only",children:"You must accept the Listing Agreement before this upgrade button becomes active. After accepting, focus will return here automatically."}),e.jsxs("div",{"data-plan-card":!0,children:[e.jsx(_,{"data-upgrade-button":!0,className:`w-full transition-all ${G===r.id&&!E?"ring-2 ring-accent ring-offset-2 animate-pulse":""}`,onClick:()=>Xe(r.id,"annual"),disabled:u===r.id||!E,title:E?void 0:"Accept the Listing Agreement above to enable",children:u===r.id?e.jsxs(e.Fragment,{children:[e.jsx(ie,{className:"h-4 w-4 mr-2 animate-spin"})," Processing..."]}):`Pay Annually â $${(r.price_cents/100).toFixed(0)}/yr`}),r.monthly_price_cents>0&&e.jsx(_,{variant:"outline",className:"w-full mt-2",onClick:()=>Xe(r.id,"monthly"),disabled:u===r.id||!E,title:E?void 0:"Accept the Listing Agreement above to enable",children:u===r.id?e.jsxs(e.Fragment,{children:[e.jsx(ie,{className:"h-4 w-4 mr-2 animate-spin"})," Processing..."]}):`Pay Monthly â $${(r.monthly_price_cents/100).toFixed(0)}/mo`})]})]})]})]},r.id)})})]}),V&&V.length>0&&o&&e.jsxs("div",{className:"mt-8",children:[e.jsx("h2",{className:"font-heading text-xl font-bold mb-2",children:"Boost Your Visibility"}),e.jsx("p",{className:"text-muted-foreground text-sm mb-4",children:"Purchase a sponsorship to get featured placement and attract more customers."}),e.jsx("div",{className:"grid gap-4 sm:grid-cols-3",children:V.map(r=>{const T=o.is_sponsored&&o.sponsor_end_date&&new Date(o.sponsor_end_date)>new Date;return e.jsxs(q,{className:"relative border-accent/40",children:[e.jsx("div",{className:"absolute -top-2.5 left-4",children:e.jsxs(J,{variant:"outline",className:"text-xs bg-background",children:[e.jsx(ss,{className:"h-3 w-3 mr-1"}),r.placement==="homepage"?"Homepage":r.placement==="category"?"Category":"All Pages"]})}),e.jsxs(Z,{children:[e.jsx(ee,{className:"text-lg",children:r.name}),e.jsx(he,{children:r.description})]}),e.jsxs(M,{children:[e.jsxs("p",{className:"text-2xl font-bold font-heading",children:["$",(r.price_cents/100).toFixed(2),e.jsxs("span",{className:"text-sm text-muted-foreground font-normal",children:["/",r.duration_days," days"]})]}),T?e.jsxs(J,{className:"mt-4",children:["Active until ",new Date(o.sponsor_end_date).toLocaleDateString()]}):e.jsx(_,{className:"mt-4 w-full",variant:"outline",onClick:()=>Ls(r.id),disabled:w===r.id,children:w===r.id?e.jsxs(e.Fragment,{children:[e.jsx(ie,{className:"h-4 w-4 mr-2 animate-spin"})," Processing..."]}):"Purchase Spotlight"})]})]},r.id)})})]}),o&&I&&I.length>0&&e.jsxs("div",{className:"mt-8",children:[e.jsxs("h2",{className:"font-heading text-xl font-bold mb-4 flex items-center gap-2",children:[e.jsx(Zt,{className:"h-5 w-5"})," Payment History"]}),e.jsx(q,{children:e.jsx(M,{className:"p-0 overflow-x-auto",children:e.jsxs(vt,{className:"min-w-[560px]",children:[e.jsx(bt,{children:e.jsxs(es,{children:[e.jsx(ye,{children:"Date"}),e.jsx(ye,{children:"Type"}),e.jsx(ye,{children:"Method"}),e.jsx(ye,{children:"Status"}),e.jsx(ye,{className:"text-right",children:"Amount"}),e.jsx(ye,{className:"text-right",children:"Receipt"})]})}),e.jsx(yt,{children:I.map(r=>e.jsxs(es,{children:[e.jsx(Ne,{children:new Date(r.created_at).toLocaleDateString()}),e.jsx(Ne,{className:"capitalize",children:r.payment_type.replace(/_/g," ")}),e.jsx(Ne,{className:"capitalize",children:r.payment_method}),e.jsx(Ne,{children:e.jsx(J,{variant:r.status==="completed"?"default":r.status==="pending"?"secondary":"destructive",children:r.status})}),e.jsxs(Ne,{className:"text-right font-medium",children:["$",(r.amount_cents/100).toFixed(2)]}),e.jsx(Ne,{className:"text-right",children:e.jsx(_,{variant:"ghost",size:"sm",onClick:()=>La(r,I.indexOf(r),I.length),title:"Download PDF receipt",children:e.jsx(Ps,{className:"h-4 w-4"})})})]},r.id))})]})})})]})]})]})]}),e.jsx(Zr,{open:me,onOpenChange:K,plans:y??[],currentPlanId:o==null?void 0:o.plan_id,upgradingPlanId:u,onConfirm:(r,T)=>Xe(r,T,{skipAgreementGate:!0}),sponsorshipPackages:V??[],sponsoringPkgId:w,onSponsorPurchase:Ls,isSponsorshipActive:!!(o!=null&&o.is_sponsored&&(o!=null&&o.sponsor_end_date)&&new Date(o.sponsor_end_date)>new Date),sponsorEndDate:(o==null?void 0:o.sponsor_end_date)??null})]})}
14export{so 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.