PageSourceSearch

https://smp-mockup-core.lovable.app/assets/LeadsTable-vxaDeLzO.js

js smp-mockup-core.lovable.app collected 2026-10-03 03:46:15 UTC 19,210 bytes, 2 lines download raw bytes

1import{j as e}from"./three-vendor-eMlpIIeK.js";import{v as _,L as N,a1 as q,a2 as H,a3 as W,a4 as V,a0 as U,B as f,E as te,P as ge,ah as se,V as fe,Y as we,Z as je,_ as be,ac as Ne}from"./constants-Dkj0adwx.js";import{T as ye,a as ke,b as ae,c as p,d as ve,e as h}from"./table-BbgqZHA7.js";import{ay as ne,r as Se,aK as Ce,aL as De,aM as Me,aN as Le,aO as Te,aP as Re,aQ as Ae,aR as Ee,aS as Pe,H as $e}from"./App-B5haZJTd.js";import{r as n,f as Fe}from"./react-vendor-DJVhemsP.js";import{e as Oe,T as Ie,b as Ue,d as ze}from"./slider-BJ9QjduM.js";import{T as Be}from"./trash-2-8wyidnj-.js";import{P as qe}from"./pencil-CSKlK64d.js";import{C as He}from"./chevron-left-BbWIO3Su.js";import"./ui-vendor-BXF9F99b.js";import"./supabase-vendor-DCpyB9X6.js";import"./TurnstileWidget-CfLIJlXx.js";import"./widgetConfigCache-DEukyDq3.js";const We=(g,m)=>{const[M,y]=n.useState([]),[z,E]=n.useState(!0),l=async()=>{if(!g||!m){y([]),E(!1);return}try{const{data:d,error:o}=await _.from("widget_leads").select("id, name, email, phone, business_name, utm_source, utm_medium, utm_campaign, utm_term, utm_content, lead_user_id, created_at, clicked_consult_button, mockup_count, time_in_studio_seconds, last_active_at, deleted_at, last_photo_at, source, source_detail").eq("widget_owner_id",g).is("deleted_at",null).order("created_at",{ascending:!1});if(o)throw o;const w=d||[],j=w.map(a=>a.lead_user_id).filter(a=>!!a);let k={},b={},S={};const $=w.map(a=>a.id);if($.length>0){const{data:a}=await _.from("lead_mockups").select("lead_id").in("lead_id",$).is("deleted_at",null);if(a)for(const r of a){const u=r.lead_id;S[u]=(S[u]||0)+1}}if(j.length>0){const{data:a}=await _.from("variants").select("user_id").in("user_id",j);if(a)for(const u of a){const x=u.user_id;k[x]=(k[x]||0)+1}const{data:r}=await _.from("user_sessions").select("user_id, created_at, last_active_at").in("user_id",j);if(r)for(const u of r){const x=u.user_id,C=new Date(u.created_at).getTime(),D=new Date(u.last_active_at).getTime(),T=Math.max(0,Math.floor((D-C)/1e3));b[x]||(b[x]={count:0,seconds:0}),b[x].count+=1,b[x].seconds+=T}}const F=w.map(a=>{const r=a.lead_user_id,u=a.mockup_count||0,x=r&&k[r]||0,C=S[a.id]||0,D=a.time_in_studio_seconds||0,T=r&&b[r]?.seconds||0;return{id:a.id,name:a.name,email:a.email,phone:a.phone,business_name:a.business_name,utm_source:a.utm_source,utm_medium:a.utm_medium,utm_campaign:a.utm_campaign,utm_term:a.utm_term,utm_content:a.utm_content,lead_user_id:a.lead_user_id,created_at:a.created_at,clicked_consult_button:a.clicked_consult_button,mockup_count:Math.max(u,x,C),session_count:r&&b[r]?.count||0,time_in_tool_seconds:Math.max(D,T),last_photo_at:a.last_photo_at,source:a.source||null,source_detail:a.source_detail||null}});y(F)}catch{}finally{E(!1)}};return n.useEffect(()=>{if(l(),!g||!m)return;const d=_.channel("widget-leads-changes").on("postgres_changes",{event:"*",schema:"public",table:"widget_leads",filter:`widget_owner_id=eq.${g}`},()=>{l()}).subscribe();return()=>{_.removeChannel(d)}},[g,m]),{leads:M,loading:z,deleteLead:async d=>{try{const{error:o}=await _.from("widget_leads").update({deleted_at:new Date().toISOString()}).eq("id",d);if(o)throw o;return y(w=>w.filter(j=>j.id!==d)),!0}catch{return!1}},restoreLead:async d=>{try{const{error:o}=await _.from("widget_leads").update({deleted_at:null}).eq("id",d);if(o)throw o;return l(),!0}catch{return!1}},refetch:l}},Y=10;function ot({userId:g,isPaid:m,zapierWebhookUrl:M}){const{leads:y,loading:z,deleteLead:E}=We(g,m),[l,L]=n.useState(null),[P,d]=n.useState(!1),[o,w]=n.useState(1),[j,k]=n.useState(null),[b,S]=n.useState([]),[$,F]=n.useState(!1),[a,r]=n.useState(new Set),[u,x]=n.useState(new Set),[C,D]=n.useState(null),[T,J]=n.useState(!1),B=n.useRef(null),G=n.useRef(!1),oe=Fe();n.useEffect(()=>{if(!(!g||G.current)){if(G.current=!0,M){B.current=M;return}_.from("webhooks").select("endpoint").eq("user_id",g).eq("is_active",!0).limit(1).then(({data:t})=>{t&&t.length>0&&(B.current=t[0].endpoint)})}},[g,M]);const ie=n.useCallback(async t=>{const s=B.current;if(!s){N.error(e.jsxs("span",{children:["Webhook is missing from widget settings, please add a webhook or"," ",e.jsx("button",{className:"underline font-semibold",onClick:()=>{J(!0)},children:"contact support"}),"."]}),{duration:6e3});return}D(t.id);const i={leadId:t.id,name:t.name,email:t.email,phone:t.phone||null,businessName:t.business_name||null,timestamp:t.created_at,
1source:t.source||"Consumer Marketplace",utm_source:t.utm_source||null,utm_medium:t.utm_medium||null,utm_campaign:t.utm_campaign||null,utm_term:t.utm_term||null,utm_content:t.utm_content||null};try{const{data:v,error:R}=await _.functions.invoke("test-webhook",{body:{webhookUrl:s,testData:i}});if(R)throw R;x(A=>new Set([...A,t.id])),N.success("Lead sent to CRM successfully")}catch{N.error("Failed to send lead to CRM. Please try again.")}finally{D(null)}},[]),le=(t,s)=>{try{sessionStorage.setItem("smp_uploaded_image",t),sessionStorage.removeItem("smp_image_loaded"),sessionStorage.setItem("smp_enter_studio","1"),k(null),oe("/studio"),N.success(`Loading "${s}" into canvas...`)}catch{N.error("Failed to load image into canvas")}},re=[{id:"sample-1",name:"John Smith",email:"[email protected]",phone:"+1 (555) 123-4567",business_name:"Advanced Hair Solutions",created_at:new Date(Date.now()-2*60*60*1e3).toISOString(),clicked_consult_button:!0,lead_user_id:null,mockup_count:3,session_count:2,time_in_tool_seconds:420,utm_source:"google",utm_medium:"cpc",utm_campaign:"smp-mockup",utm_content:null,utm_term:null,last_photo_at:null,source:null,source_detail:null},{id:"sample-2",name:"Sarah Johnson",email:"[email protected]",phone:"+1 (555) 234-5678",business_name:"Elite SMP Studio",created_at:new Date(Date.now()-5*60*60*1e3).toISOString(),clicked_consult_button:!1,lead_user_id:null,mockup_count:5,session_count:3,time_in_tool_seconds:1200,utm_source:"facebook",utm_medium:"social",utm_campaign:"summer-promo",utm_content:null,utm_term:null,last_photo_at:null,source:null,source_detail:null},{id:"sample-3",name:"Michael Davis",email:"[email protected]",phone:"+1 (555) 345-6789",business_name:"Precision Scalp Artistry",created_at:new Date(Date.now()-24*60*60*1e3).toISOString(),clicked_consult_button:!0,lead_user_id:null,mockup_count:2,session_count:1,time_in_tool_seconds:300,utm_source:"instagram",utm_medium:"social",utm_campaign:"brand-awareness",utm_content:null,utm_term:null,last_photo_at:null,source:null,source_detail:null},{id:"sample-4",name:"Emily Brown",email:"[email protected]",phone:"+1 (555) 456-7890",business_name:"Natural Look SMP",created_at:new Date(Date.now()-48*60*60*1e3).toISOString(),clicked_consult_button:!1,lead_user_id:null,mockup_count:4,session_count:2,time_in_tool_seconds:900,utm_source:"linkedin",utm_medium:"social",utm_campaign:"professional-network",utm_content:null,utm_term:null,last_photo_at:null,source:null,source_detail:null},{id:"sample-5",name:"David Wilson",email:"[email protected]",phone:"+1 (555) 567-8901",business_name:"Premium Scalp Solutions",created_at:new Date(Date.now()-72*60*60*1e3).toISOString(),clicked_consult_button:!0,lead_user_id:null,mockup_count:6,session_count:4,time_in_tool_seconds:1800,utm_source:"direct",utm_medium:"none",utm_campaign:null,utm_content:null,utm_term:null,last_photo_at:null,source:null,source_detail:null}],ce=t=>{if(!t.last_photo_at)return!1;const s=new Date(t.last_photo_at).getTime(),i=new Date(t.created_at).getTime();return s>i+6e4},me=re.filter(t=>!a.has(t.id)),O=m&&y.length>0?y:me,K=!(m&&y.length>0),I=Math.ceil(O.length/Y),Q=(o-1)*Y,Z=O.slice(Q,Q+Y),X=t=>{const s=new Date(t),i=s.toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"}),v=s.toLocaleTimeString("en-US",{hour:"2-digit",minute:"2-digit"});return e.jsxs(e.Fragment,{children:[i,e.jsx("br",{}),e.jsx("span",{className:"text-muted-foreground text-xs",children:v})]})},ee=t=>{if(t<60)return`${t}s`;const s=Math.floor(t/60);if(s<60)return`${s}m`;const i=Math.floor(s/60),v=s%60;return`${i}h ${v}m`},de=t=>{const s=[];return t.utm_source&&s.push(`Source: ${t.utm_source}`),t.utm_medium&&s.push(`Medium: ${t.utm_medium}`),t.utm_campaign&&s.push(`Campaign: ${t.utm_campaign}`),t.utm_term&&s.push(`Term: ${t.utm_term}`),t.utm_content&&s.push(`Content: ${t.utm_content}`),s.length>0?s.join(" | "):"—"},ue=()=>{const s=[["Date","Name","Phone","Email","Business Name","Clicked Consult","Mockups","Time in Tool","Sessions","UTM Source","UTM Medium","UTM Campaign"].join(",")];O.forEach(c=>{const _e=[X(c.created_at),`"${c.name}"`,c.phone||"",c.email,c.business_name||"",c.clicked_consult_button?"Yes":"No",c.mockup_count,c.time_in_tool_seconds>0?ee(c.time_in_tool_seconds):"",c.session_count,c.utm_source||"",c.utm_medium||"",c.utm_campaign||""];s.push(_e.join(","))});const i=s.join(`
2`),v=new Blob([i],{type:"text/csv;charset=utf-8;"}),R=URL.createObjectURL(v),A=document.createElement("a");A.href=R,A.download=`widget-leads-${new Date().toISOString().split("T")[0]}.csv`,A.click(),URL.revokeObjectURL(R),N.success("Leads exported successfully")},pe=async t=>{k(t),F(!0),S([]);try{const{data:s,error:i}=await _.from("lead_mockups").select("id, image_data, name, created_at").eq("lead_id",t.id).order("created_at",{ascending:!1});if(i)throw i;S(s||[])}catch{}finally{F(!1)}},he=async()=>
2{if(!l)return;if(l.id.startsWith("sample-")){r(i=>new Set([...i,l.id])),N.success(`Sample lead "${l.name}" removed`),L(null);return}d(!0);const s=await E(l.id);d(!1),s?N.success(`Lead "${l.name}" deleted`):N.error("Failed to delete lead"),L(null)},xe=()=>I<=1?null:e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(f,{variant:"ghost",size:"sm",onClick:()=>w(t=>Math.max(1,t-1)),disabled:o===1,className:"h-8 w-8 p-0",children:e.jsx(He,{className:"h-4 w-4"})}),Array.from({length:I},(t,s)=>s+1).map(t=>e.jsx(f,{variant:o===t?"default":"ghost",size:"sm",onClick:()=>w(t),className:"h-8 w-8 p-0",children:t},t)),e.jsx(f,{variant:"ghost",size:"sm",onClick:()=>w(t=>Math.min(I,t+1)),disabled:o===I,className:"h-8 w-8 p-0",children:e.jsx(Ne,{className:"h-4 w-4"})})]});return z&&m?e.jsxs(q,{className:"mb-6",children:[e.jsx(H,{children:e.jsx(W,{children:"Widget Leads"})}),e.jsx(V,{className:"flex justify-center py-8",children:e.jsx(U,{className:"h-8 w-8 animate-spin text-primary"})})]}):Z.length===0&&m?e.jsxs(q,{className:"mb-6",children:[e.jsx(H,{children:e.jsx(W,{children:"Widget Leads"})}),e.jsx(V,{children:e.jsx("p",{className:"text-muted-foreground text-center py-8",children:"No leads yet. Leads will appear here when someone submits the contact form on your widget."})})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"relative mt-4 mb-8 rounded-lg p-[1px] overflow-hidden mx-0 sm:mx-0",style:{backgroundColor:"#4A6BDD"},children:[!m&&e.jsx("div",{className:"relative z-10 mt-2 mb-6 mx-auto max-w-fit",children:e.jsx("div",{className:"bg-gradient-to-r from-purple-500 via-pink-500 to-purple-500 p-[2px] rounded-2xl",children:e.jsx("div",{className:"bg-black px-6 py-3 rounded-2xl",children:e.jsx("p",{className:"text-white font-semibold text-center",children:"📊 Sample Data Preview - Upgrade to see your real leads"})})})}),e.jsxs(q,{className:"relative bg-background",children:[e.jsx(H,{className:"px-2 py-2 sm:p-6",children:e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs(W,{className:"text-base sm:text-xl",children:["Widget Leads (",O.length,")"]}),xe()]}),e.jsxs(f,{variant:"outline",size:"sm",onClick:ue,className:"gap-1.5 self-start",children:[e.jsx(te,{className:"h-4 w-4"}),"Export Leads"]})]})}),e.jsx(V,{className:"px-1 py-2 sm:p-6",children:e.jsxs(ne,{className:"w-full [&_[data-radix-scroll-area-scrollbar]]:!opacity-100",children:[e.jsx("div",{className:"rounded-md min-w-[1400px] border-spacing-0 bg-[#F7F8FA]",children:e.jsxs(ye,{className:"border-spacing-0",children:[e.jsx(ke,{children:e.jsxs(ae,{className:"bg-gradient-to-r from-[hsl(217,91%,60%)] to-[hsl(263,70%,60%)] border-none",children:[e.jsx(p,{className:"text-white font-bold min-w-[140px] py-2 px-2",children:"Date"}),e.jsx(p,{className:"text-white font-bold min-w-[150px] py-2 px-2",children:"Name"}),e.jsx(p,{className:"text-white font-bold min-w-[140px] py-2 px-2",children:"Phone"}),e.jsx(p,{className:"text-white font-bold min-w-[200px] py-2 px-2",children:"Email"}),e.jsxs(p,{className:"text-white font-bold min-w-[100px] py-2 px-2 whitespace-normal leading-tight",children:["Clicked",e.jsx("br",{}),"Consult"]}),e.jsx(p,{className:"text-white font-bold min-w-[100px] py-2 px-2",children:"Mockups"}),e.jsx(p,{className:"text-white font-bold min-w-[80px] py-2 px-2",children:"CRM"}),e.jsx(p,{className:"text-white font-bold min-w-[140px] py-2 px-2",children:"View Mockups"}),e.jsx(p,{className:"text-white font-bold min-w-[120px] py-2 px-2",children:"Time in Studio"}),e.jsx(p,{className:"text-white font-bold min-w-[120px] py-2 px-2",children:"Session Count"}),e.jsx(p,{className:"text-white font-bold min-w-[300px] py-2 px-2",children:"UTM Parameters"}),(m||K)&&e.jsx(p,{className:"text-white font-bold min-w-[80px] py-2 px-2",children:"Actions"})]})}),e.jsx(ve,{children:Z.map(t=>e.jsxs(ae,{className:"bg-[#F7F8FA] hover:bg-[#F7F8FA]/90",children:[e.jsx(h,{className:"text-sm text-black py-2 px-2",children:X(t.created_at)}),e.jsx(h,{className:"font-medium text-black py-2 px-2",children:e.jsxs("div",{className:"flex items-center gap-2",children:[t.name,t.source_detail==="Landing Page"&&e.jsx("span",{className:"inline-flex items-center px-1.5 py-0.5 rounded-full text-[10px] font-medium bg-orange-100 text-orange-800 dark:bg-orange-900/30 dark:text-orange-300 whitespace-nowrap",children:"LP"}),ce(t)&&e.jsx(Oe,{children:e.jsxs(Ie,{children:[e.jsx(Ue,{asChild:!0,children:e.jsx("span",{className:"inline-flex items-center px-1.5 py-0.5 rounded-full text-[10px] font-medium bg-purple-100 text-purple-800 dark:bg-purple-900/30 dark:text-purple-300 whitespace-nowrap cursor-help",children:"Returned"})}),e.jsx(ze,{children:e.jsx("p",{children:"This lead returned and uploaded additional photos after their initial submission"})})]})}),t.source==="Consumer Marketplace"&&e.jsx("span",{className:"inline-flex items-center px-1.5 py-0.5 rounded-full text-[10px] font-medium bg-emerald-100 text-emerald-800 dark:bg-emerald-900/30 dark:text-emerald-300 whitespace-nowrap",children:"Purchased"})]})}),e.jsx(h,{className:"text-black py-2 px-2",children:t.phone||"—"}),e.jsx(h,{className:"text-black py-2 px-2",children:t.email}),e.jsx(h,{className:"text-black py-2 px-2",children:t.clicked_consult_button?"Yes":"No"}),e.jsx(h,{className:"py-2 px-2",children:e.jsx("span",{className:"inline-flex items-center justify-center w-7 h-7 rounded-full bg-primary/10 text-primary font-semibold text-sm",children:t.mockup_count})}),e.jsx(h,{className:"py-2 px-2",children:t.source==="Consumer Marketplace"?u.has(t.id)?e.jsxs(f,{variant:"ghost",size:"sm",disabled:!0,className:"gap-1 h-6 text-[10px] px-2 bg-emerald-500/10 text-emerald-600 hover:bg-emerald-500/10 hover:text-emerald-600 cursor-default",children:[e.jsx(ge,{className:"h-3 w-3"}),"Sent"]}):e.jsxs(f,{variant:"outline",size:"sm",className:"gap-1 h-6 text-[10px] px-2",disabled:C===t.id,onClick:()=>ie(t),children:[C===t.id?e.jsx(U,{className:"h-3 w-3 animate-spin"}):e.jsx(Se,{className:"h-3 w-3"}),"CRM"]}):e.jsx("span",{className:"text-muted-foreground",children:"—"})}),e.jsx(h,{className:"py-2 px-2",children:t.mockup_count>0?e.jsxs(f,{variant:"ghost",size:"sm",className:"gap-1 bg-muted hover:bg-muted/80 px-2 py-1 h-auto text-xs",onClick:()=>pe(t),children:[e.jsx(se,{className:"h-3 w-3"}),"View"]}
2):e.jsx("span",{className:"text-muted-foreground",children:"—"})}),e.jsx(h,{className:"text-black py-2 px-2",children:t.time_in_tool_seconds>0?ee(t.time_in_tool_seconds):"—"}),e.jsx(h,{className:"text-black py-2 px-2",children:t.session_count>0?t.session_count:"—"}),e.jsx(h,{className:"text-black py-2 px-2 text-xs",children:de(t)}),(m||K)&&e.jsx(h,{className:"py-2 px-2",children:e.jsx(f,{variant:"ghost",size:"sm",className:"h-8 w-8 p-0 text-destructive hover:text-destructive hover:bg-destructive/10",onClick:()=>L(t),children:e.jsx(Be,{className:"h-4 w-4"})})})]},t.id))})]})}),e.jsx(Ce,{orientation:"horizontal",forceVisible:!0,className:"h-3 md:h-3 bg-primary/20 hover:bg-primary/30"})]})})]})]}),e.jsx(De,{open:l!==null,onOpenChange:t=>!t&&L(null),children:e.jsxs(Me,{children:[e.jsxs(Le,{children:[e.jsx(Te,{children:"Delete Lead"}),e.jsxs(Re,{children:['Are you sure you want to delete the lead "',l?.name,'"? This action cannot be undone.']})]}),e.jsxs(Ae,{children:[e.jsx(Ee,{disabled:P,children:"Cancel"}),e.jsx(Pe,{onClick:he,disabled:P,className:"bg-destructive text-destructive-foreground hover:bg-destructive/90",children:P?e.jsxs(e.Fragment,{children:[e.jsx(U,{className:"mr-2 h-4 w-4 animate-spin"}),"Deleting..."]}):"Delete"})]})]})}),e.jsx(fe,{open:j!==null,onOpenChange:t=>!t&&k(null),children:e.jsxs(we,{className:"sm:max-w-2xl max-h-[80vh] overflow-hidden",children:[e.jsx(je,{children:e.jsxs(be,{children:["Mockups for ",j?.name]})}),e.jsx("div",{className:"py-4",children:$?e.jsx("div",{className:"flex justify-center py-8",children:e.jsx(U,{className:"h-8 w-8 animate-spin text-primary"})}):b.length>0?e.jsx(ne,{className:"h-[50vh] sm:h-[60vh] max-h-[600px] pr-4",children:e.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:b.map(t=>e.jsxs("div",{className:"border border-border rounded-lg overflow-hidden bg-card",children:[e.jsx("img",{src:t.image_data,alt:t.name,className:"w-full aspect-[4/5] object-cover"}),e.jsxs("div",{className:"p-2 space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-xs text-muted-foreground truncate max-w-[120px]",title:t.name,children:t.name}),e.jsx("span",{className:"text-xs text-muted-foreground",children:new Date(t.created_at).toLocaleDateString("en-US",{month:"short",day:"numeric"})})]}),e.jsxs("div",{className:"flex flex-col sm:flex-row gap-1.5",children:[e.jsxs(f,{variant:"default",size:"sm",className:"flex-1 h-10 sm:h-7 text-xs gap-1.5",onClick:()=>le(t.image_data,t.name),children:[e.jsx(qe,{className:"h-3.5 w-3.5 sm:h-3 sm:w-3"}),"Send to Canvas"]}),e.jsxs(f,{variant:"outline",size:"sm",className:"h-9 sm:h-7 sm:w-auto sm:px-2 text-xs gap-1.5",onClick:()=>{const s=document.createElement("a");s.href=t.image_data,s.download=`${j?.name||"lead"}-mockup-${t.id.slice(0,8)}.jpg`,s.click()},children:[e.jsx(te,{className:"h-3.5 w-3.5 sm:h-3 sm:w-3"}),e.jsx("span",{className:"sm:hidden",children:"Download"})]})]})]})]},t.id))})}):e.jsxs("div",{className:"text-center space-y-3 py-8",children:[e.jsx("div",{className:"w-12 h-12 rounded-full bg-muted flex items-center justify-center mx-auto",children:e.jsx(se,{className:"w-6 h-6 text-muted-foreground"})}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"No mockups available yet."}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Mockups will appear here when this lead saves their work."})]})})]})}),e.jsx($e,{open:T,onOpenChange:J,defaultCategory:"widget"})]})}export{ot as LeadsTable};

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.