PageSourceSearch

https://app.aimpact.com/assets/import-Dgwv8c9E.js

js aimpact.com collected 2026-10-02 20:34:08 UTC 10,839 bytes, 1 lines download raw bytes

1import{r as i,j as e}from"./vendor-react-BD_epXGo.js";import{u as O,L as W}from"./vendor-tanstack-CtE3CGcS.js";import{P as D}from"./vendor-parsing-CtQ6HmbH.js";import{B as x}from"./button-B9LIQXsK.js";import{C as y,b as N,c as w,a as v}from"./card-BXtfeEdF.js";import{I as H}from"./input-DX0o0htb.js";import{L as z}from"./label-By0yglpv.js";import{C as X}from"./checkbox-C1EUOrKp.js";import{S as J,a as K,b as Q,c as Y,d as T}from"./select-tLjhKCd9.js";import{B as M}from"./badge-DKH4Kzzf.js";import{t as C}from"./index-BM3TWaLK.js";import{u as Z}from"./useCRMImportExport-BFo_k8dB.js";import"./dropdown-menu-BupvtmGK.js";import{S as ee}from"./ReminderForm-BLWXKUF6.js";import"./tooltip-CstIodXN.js";import"./tabs-CsbJ50Cc.js";import{A as se,ad as te,C as ae,q as re}from"./vendor-icons-CfCU8ITX.js";import"./vendor-ui-CWt54UKW.js";import"./bundle-mjs-CtRjYbyI.js";import"./vendor-validation-C7IuoilE.js";import"./vendor-forms-h8ybKdsJ.js";import"./data-migration-CHSjlPji.js";import"./textarea-CHHvu5Qh.js";function le(l){const s=l.map(r=>({column:r,value:r.trim().toLowerCase()})),a=r=>{var o;return((o=s.find(({value:h})=>r.some(p=>h.includes(p))))==null?void 0:o.column)??""};return{name:a(["name","full name","contact"]),company:a(["company","firm","organization"]),role:a(["role","title","position"]),email:a(["email","mail"]),phone:a(["phone","mobile"]),linkedinUrl:a(["linkedin"]),twitterUrl:a(["twitter","x.com"]),telegramLink:a(["telegram"]),notes:a(["note","context","background"]),statusGroup:a(["status","stage"]),labels:a(["label","tags","categories"])}}function ne(l,s){return l.map(a=>{const r=p=>{const m=s[p];if(!m)return;const u=a[m];if(u==null)return;const f=String(u).trim();return f.length?f:void 0},o=r("statusGroup"),h=ce(o);return{name:r("name")??"",company:r("company")??null,role:r("role")??null,email:ie(r("email")),phone:r("phone")??null,linkedin_url:R(r("linkedinUrl")),twitter_url:R(r("twitterUrl")),telegram_link:R(r("telegramLink")),notes:r("notes")??null,status_group:h,labels:oe(r("labels"))}})}function ie(l){if(!l)return null;const s=l.trim();return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(s)?s:null}function R(l){if(!l)return null;const s=l.trim();return s?/^https?:\/\//i.test(s)?s:`https://${s}`:null}function oe(l){return l?l.split(",").map(s=>s.trim()).filter(s=>s.length>0):[]}function ce(l){if(!l)return"new";const s=l.toLowerCase().replace(/[^a-z]/g,"");return s.includes("won")||s.includes("success")?"closed_won":s.includes("lost")||s.includes("fail")||s.includes("reject")?"closed_lost":s.includes("negot")?"negotiation":s.includes("proposal")||s.includes("offer")?"proposal":s.includes("qualif")||s.includes("warm")||s.includes("hot")?"qualified":s.includes("contact")||s.includes("reach")||s.includes("follow")?"contacted":"new"}const me=[{key:"name",label:"Name",required:!0,helper:"Required"},{key:"company",label:"Company"},{key:"role",label:"Role"},{key:"email",label:"Email"},{key:"phone",label:"Phone"},{key:"linkedinUrl",label:"LinkedIn URL"},{key:"twitterUrl",label:"Twitter / X URL"},{key:"telegramLink",label:"Telegram link"},{key:"notes",label:"Notes"},{key:"statusGroup",label:"Status",helper:Object.values(ee).join(", ")},{key:"labels",label:"Labels",helper:"Comma-separated list"}],de=["Upload CSV","Map columns","Preview data","Confirm import"];function Te(){const l=O(),s=Z(),[a,r]=i.useState(0),[o,h]=i.useState(""),[p,m]=i.useState(!1),[u,f]=i.useState([]),[V,B]=i.useState([]),[g,_]=i.useState({name:"",company:"",role:"",email:"",phone:"",linkedinUrl:"",twitterUrl:"",telegramLink:"",notes:"",statusGroup:"",labels:""}),[U,A]=i.useState(!0),[I,k]=i.useState([]),S=i.useMemo(()=>ne(u,g),[u,g]),c=i.useMemo(()=>S.filter(t=>t.name.trim().length>0),[S]),L=S.length-c.length,F=t=>{var d;const n=(d=t.target.files)==null?void 0:d[0];if(n){if(n.size>5*1024*1024){C.error("CSV exceeds 5MB limit");return}m(!0),k([]),D.parse(n,{header:!0,skipEmptyLines:!0,complete:j=>{const P=(j.data||[]).filter(b=>Object.keys(b).some(G=>String(b[G]??"").trim().length>0)),E=j.meta.fields??[];if(!P.length){k(["No rows detected in CSV"]),m(!1);return}f(P),B(E),_(b=>({...b,...le(E)})),h(n.name),m(!1),r(1)},error:j=>{k([j.message]),m(!1)}})}},q=(t,n)=>{_(d=>({...d,[t]:n==="__ignore__"?"":n}))},$=async()=>
1{if(!c.length){C.error("No valid contacts to import");return}try{const t=await s.mutateAsync({contacts:c,createMissingLabels:U});C.success(`Imported ${t.imported} contact${t.imported===1?"":"s"}`+(t.createdLabels>0?` and created ${t.createdLabels} labels`:"")),l({to:"/dashboard/crm"})}catch(t){console.error(t);const n=t instanceof Error?t.message:"Failed to import contacts";C.error(n)}};return e.jsxs("div",{className:"mx-auto w-full max-w-5xl space-y-4 sm:space-y-6",children:[e.jsx(W,{to:"/dashboard/crm",children:e.jsxs(x,{variant:"ghost",className:"gap-2 px-2",children:[e.jsx(se,{className:"h-4 w-4"}),"Back to CRM"]})}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("h1",{className:"text-xl font-semibold leading-tight sm:text-2xl",children:"Import contacts"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Upload a CSV file with your investors or partners. We'll help you map columns and preview data before importing."})]}),e.jsx(pe,{current:a}),a===0&&e.jsxs(y,{children:[e.jsx(N,{className:"p-4 sm:p-6",children:e.jsx(w,{children:"Step 1 · Upload CSV"})}),e.jsxs(v,{className:"space-y-4 p-4 pt-0 sm:p-6 sm:pt-0",children:[e.jsxs("label",{className:"flex h-44 cursor-pointer flex-col items-center justify-center rounded-xl border-2 border-dashed border-muted-foreground/30 bg-muted/20 px-4 text-center transition [@media(hover:hover)]:hover:border-primary/40 [@media(hover:hover)]:hover:bg-muted/30 sm:h-48",children:[e.jsx(te,{className:"h-8 w-8 text-primary"}),e.jsx("span",{className:"mt-3 text-sm text-muted-foreground",children:p?"Parsing file…":o||"Click to upload or drag your CSV file here"}),e.jsx("span",{className:"text-xs text-muted-foreground/70",children:"Max 5MB · UTF-8 encoded CSV"}),e.jsx(H,{type:"file",accept:".csv",className:"hidden",onChange:F,disabled:p})]}),I.length>0&&e.jsx("div",{className:"rounded-lg border border-destructive/30 bg-destructive/10 p-3 text-sm text-destructive",children:I.map(t=>e.jsx("div",{children:t},t))})]})]}),a===1&&e.jsxs(y,{children:[e.jsx(N,{className:"p-4 sm:p-6",children:e.jsx(w,{children:"Step 2 · Map columns"})}),e.jsxs(v,{className:"space-y-4 p-4 pt-0 sm:p-6 sm:pt-0",children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"Match the columns from your CSV to CRM fields. Fields left unmapped will be skipped."}),e.jsx("div",{className:"grid gap-3 md:grid-cols-2",children:me.map(t=>e.jsxs("div",{className:"space-y-1",children:[e.jsxs(z,{className:"text-sm font-medium",children:[t.label,t.required&&e.jsx("span",{className:"ml-1 text-xs text-destructive",children:"*"})]}),e.jsxs(J,{value:g[t.key],onValueChange:n=>q(t.key,n),children:[e.jsx(K,{children:e.jsx(Q,{placeholder:"Select column"})}),e.jsxs(Y,{children:[e.jsx(T,{value:"__ignore__",children:"Ignore"}),V.map(n=>e.jsx(T,{value:n,children:n},n))]})]}),t.helper&&e.jsx("p",{className:"text-xs text-muted-foreground",children:t.helper})]},t.key))}),e.jsx("div",{className:"flex justify-end",children:e.jsx(x,{className:"w-full sm:w-auto",onClick:()=>r(2),disabled:g.name==="",children:"Continue to preview"})})]})]}),a===2&&e.jsxs(y,{children:[e.jsx(N,{className:"p-4 sm:p-6",children:e.jsx(w,{children:"Step 3 · Preview data"})}),e.jsxs(v,{className:"space-y-4 p-4 pt-0 sm:p-6 sm:pt-0",children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"Review the first few contacts to ensure everything looks right."}),e.jsx("div",{className:"overflow-x-auto rounded-lg border",children:e.jsxs("table",{className:"min-w-full divide-y text-sm",children:[e.jsx("thead",{className:"bg-muted/50",children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-4 py-2 text-left font-medium",children:"Name"}),e.jsx("th",{className:"px-4 py-2 text-left font-medium",children:"Company"}),e.jsx("th",{className:"px-4 py-2 text-left font-medium",children:"Email"}),e.jsx("th",{className:"px-4 py-2 text-left font-medium",children:"Status"}),e.jsx("th",{className:"px-4 py-2 text-left font-medium",children:"Labels"})]})}),e.jsx("tbody",{className:"divide-y",children:c.slice(0,5).map((t,n)=>{var d;return e.jsxs("tr",{children:[e.jsx("td",{className:"px-4 py-2",children:t.name}),e.jsx("td",{className:"px-4 py-2 text-muted-foreground",children:t.company??"—"}),e.jsx("td",{className:"px-4 py-2 text-muted-foreground",children:t.email??"—"}),e.jsx("td",{className:"px-4 py-2 text-muted-foreground capitalize",children:t.status_group??"new"}),e.jsx("td",{className:"px-4 py-2 text-muted-foreground",children:(d=t.labels)!=null&&d.length?t.labels.join(", "):"—"})]},n)})})]})}),e.jsxs("div",{className:"flex flex-wrap items-center gap-3 text-sm",children:[e.jsxs(M,{variant:"secondary",className:"bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400",children:[e.jsx(ae,{className:"mr-1 h-4 w-4"})," ",c.length," ready to import"]}
1),L>0&&e.jsxs(M,{variant:"outline",className:"text-amber-600 dark:text-amber-400",children:[e.jsx(re,{className:"mr-1 h-4 w-4"})," ",L," rows missing name will be skipped"]})]}),e.jsxs("div",{className:"flex flex-col-reverse gap-2 sm:flex-row sm:justify-between",children:[e.jsx(x,{variant:"outline",className:"w-full sm:w-auto",onClick:()=>r(1),children:"Adjust mapping"}),e.jsx(x,{className:"w-full sm:w-auto",onClick:()=>r(3),children:"Proceed to import"})]})]})]}),a===3&&e.jsxs(y,{children:[e.jsx(N,{className:"p-4 sm:p-6",children:e.jsx(w,{children:"Step 4 · Confirm import"})}),e.jsxs(v,{className:"space-y-4 p-4 pt-0 sm:p-6 sm:pt-0",children:[e.jsxs("div",{className:"space-y-2 text-sm text-muted-foreground",children:[e.jsxs("p",{children:["We're ready to import ",e.jsx("strong",{children:c.length})," contact",c.length===1?"":"s",". Rows without a name (",L,") will be skipped automatically."]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(X,{checked:U,onCheckedChange:t=>A(t===!0),id:"create-labels"}),e.jsx(z,{htmlFor:"create-labels",className:"text-sm",children:"Create any missing labels automatically"})]})]}),e.jsxs("div",{className:"flex flex-col-reverse gap-2 sm:flex-row sm:justify-between",children:[e.jsx(x,{variant:"outline",className:"w-full sm:w-auto",onClick:()=>r(2),children:"Review preview"}),e.jsx(x,{className:"w-full sm:w-auto",onClick:$,disabled:s.isPending,children:s.isPending?"Importing…":`Import ${c.length} contacts`})]})]})]})]})}function pe({current:l}){return e.jsx("div",{className:"flex gap-2 overflow-x-auto pb-1 text-sm",children:de.map((s,a)=>{const r=a===l,o=a<l;return e.jsxs(M,{variant:r?"default":o?"secondary":"outline",className:"shrink-0",children:[a+1,". ",s]},s)})})}export{Te as component};

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.