1import{j as e}from"./ui--d0NOyFY.js";import{r as m}from"./vendor-De2ayNVB.js";import{l as be,S as ye,a as g,X as ae,p as D,L as H,d as ys,c as I,D as bs,e as Ns,H as ws,I as se,v as Cs,R as Ss,C as De,s as Fs,T as ks,q as v}from"./index-697EzMVj.js";import{C as ue,a as xe,b as he,d as ge}from"./card-DMXJY_63.js";import{L as fe}from"./label-CpnKkNwE.js";import{S as ht,a as gt,b as ft,c as jt,d as ze}from"./select-CjYtKxqm.js";import{D as vt,a as yt,b as bt,c as Nt,d as wt}from"./dialog-FPnIf5kz.js";import{S as Ct}from"./shimmer-text-C_xYx_nM.js";import{a as je,c as Q}from"./query-S5gZy6qD.js";import{b as As,p as Ve,i as qe,d as St,e as Ts,c as Ft}from"./excelParser-jgbPqEhX.js";import{e as Dt,v as $s,F as Es}from"./templateApply-DuEU6ddQ.js";import{A as Ms}from"./AITemplateBuilder-Cih6YaAJ.js";import{G as Rs}from"./globe-Bp6IHR0l.js";import{C as _s}from"./circle-alert-CId1xNp6.js";import{U as Ke}from"./upload-otloQOH7.js";import{S as kt}from"./save-aScXlWBZ.js";import{C as Ps}from"./clock-Bh2A8xGJ.js";import{F as At}from"./file-text-Cf6IU2WN.js";import{D as Tt}from"./download-CV646FIC.js";import{C as $t}from"./circle-x-CKJTFmtu.js";import{A as Et}from"./arrow-right-DyFdEFTO.js";import{S as Is}from"./shield-check-3ixhj4eI.js";import{P as Mt}from"./pen-DOjBTYBM.js";import{T as Os}from"./trash-2-B0GHv1Gj.js";import"./charts-DhvWcKTH.js";import"./xlsx-BQJtVpeU.js";import"./AnalyzingState-BYoJQr_0.js";import"./TealShimmerText-Cj27K2q_.js";import"./CoachMascotVector-pJgrtbb8.js";import"./invalidateCreditState-BgOA2O2y.js";import"./circle-help-OSS_1ZA8.js";/** 2 * @license lucide-react v0.462.0 - ISC 3 * 4 * This source code is licensed under the ISC license. 5 * See the LICENSE file in the root directory of this source tree. 6 */const Ls=be("GitCompare",[["circle",{cx:"18",cy:"18",r:"3",key:"1xkwt0"}],["circle",{cx:"6",cy:"6",r:"3",key:"1lh9wr"}],["path",{d:"M13 6h3a2 2 0 0 1 2 2v7",key:"1yeb86"}],["path",{d:"M11 18H8a2 2 0 0 1-2-2V9",key:"19pyzm"}]]);/** 7 * @license lucide-react v0.462.0 - ISC 8 * 9 * This source code is licensed under the ISC license. 10 * See the LICENSE file in the root directory of this source tree. 11 */const Rt=be("Grid3x3",[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}],["path",{d:"M3 9h18",key:"1pudct"}],["path",{d:"M3 15h18",key:"5xshup"}],["path",{d:"M9 3v18",key:"fh3hqa"}],["path",{d:"M15 3v18",key:"14nvp0"}]]);/** 12 * @license lucide-react v0.462.0 - ISC 13 * 14 * This source code is licensed under the ISC license. 15 * See the LICENSE file in the root directory of this source tree. 16 */const Bs=be("Inbox",[["polyline",{points:"22 12 16 12 14 15 10 15 8 12 2 12",key:"o97t9d"}],["path",{d:"M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z",key:"oot6mr"}]]);/** 17 * @license lucide-react v0.462.0 - ISC 18 * 19 * This source code is licensed under the ISC license. 20 * See the LICENSE file in the root directory of this source tree. 21 */const Ds=be("Table",[["path",{d:"M12 3v18",key:"108xh3"}],["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}],["path",{d:"M3 9h18",key:"1pudct"}],["path",{d:"M3 15h18",key:"5xshup"}]]);function zs(s){return Object.values(s).reduce((o,h)=>o+Object.keys(h).length,0)}function Vs({rows:s,setRows:o,selectingTarget:h,setSelectingTarget:f,targetSchema:y,categoryLabels:x,formatCellValue:E}){const F={};for(const R of s){const L=R.targetField.split(".")[0]||"other";F[L]||(F[L]=[]),F[L].push(R)}const $=zs(y),O=s.length,z=Math.max(0,$-O);return e.jsxs("div",{className:"space-y-3","data-testid":"step2-field-mapping-list",children:[e.jsxs("p",{className:"text-sm text-foreground","data-testid":"step2-mapping-progress",children:[e.jsxs("span",{className:"font-medium",children:[O," of ",$," mapped"]}),z>0&&e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"text-muted-foreground",children:" · "}),e.jsxs("span",{className:"text-[#854F0B]",children:[z," left"]})]})]}),Object.entries(x).map(([R,L])=>{const Y=y[R]||{},q=F[R]||[];return e.jsxs("div",{className:"space-y-1",children:[e.jsx("p",{className:"text-[11px] font-semibold uppercase tracking-wider text-muted-foreground
21/80",children:L}),Object.entries(Y).map(([K,V])=>{const M=`${R}.${K}`,c=q.find(Z=>Z.targetField===M),k=h===M,ie=c!=null&&c.sheet&&(c!=null&&c.cell)?`${c.sheet}!${c.cell}`:(c==null?void 0:c.label)||"mapped (no cell ref)";return e.jsxs("div",{className:`flex items-start justify-between gap-3 rounded-md px-2 py-2 ${c?"":"bg-[rgba(186,117,23,0.05)]"}`,"data-testid":`cellref-row-${M}`,children:[e.jsxs("div",{className:"min-w-0 flex-1 space-y-0.5",children:[e.jsx("p",{className:"truncate text-sm font-medium text-foreground",title:V,children:V}),c?e.jsxs("p",{className:"flex min-w-0 flex-wrap items-center gap-x-1.5 gap-y-0.5 text-xs text-muted-foreground",children:[e.jsx("span",{className:"shrink-0 font-mono text-[#0F6E56]",children:ie}),c.previewValue!=null&&e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"text-muted-foreground/60",children:"·"}),e.jsxs("span",{className:"min-w-0 truncate",title:String(c.previewValue),children:["= ",E(c.previewValue)]})]}),c.aiMapped&&e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"text-muted-foreground/60",children:"·"}),e.jsxs("span",{className:"inline-flex shrink-0 items-center gap-0.5 text-muted-foreground",children:[e.jsx(ye,{className:"h-3 w-3 text-[#0F6E56]","aria-hidden":!0}),c.confidence!=null&&e.jsxs("span",{"data-testid":`mapping-confidence-${M}`,children:[Math.round(c.confidence*100),"%"]})]})]})]}):e.jsx("p",{className:"text-xs italic text-[#854F0B]",children:"Not mapped"})]}),e.jsxs("div",{className:"flex shrink-0 items-center gap-1",children:[e.jsx(g,{variant:k?"default":c?"outline":void 0,size:"sm",className:c?"h-7 text-xs px-2":"h-7 border-0 bg-[#0F6E56] text-xs text-white px-3 hover:bg-[#0F6E56]/90 hover:text-white",onClick:()=>f(k?null:M),"data-testid":`button-pick-cell-${M}`,children:k?"Selecting...":c?"Change":"Pick cell"}),c&&e.jsx(g,{variant:"ghost",size:"icon",className:"h-7 w-7",onClick:()=>o(s.filter(Z=>Z.targetField!==M)),"data-testid":`button-remove-cellref-${M}`,"aria-label":`Remove mapping for ${V}`,children:e.jsx(ae,{className:"h-3.5 w-3.5"})})]})]},M)})]},R)})]})}function qs({fieldLabel:s,onCancel:o}){return e.jsxs("div",{className:"flex items-center justify-between rounded-md border border-[#9FE1CB] bg-[#E1F5EE] p-2","data-testid":"template-step2-pick-banner",children:[e.jsxs("p",{className:"text-xs font-medium text-[#04342C]",children:["Selecting cell for ",s," â click a cell below"]}),e.jsxs(g,{variant:"ghost",size:"sm",className:"text-[#0F6E56] hover:bg-[#9FE1CB]/30",onClick:o,"data-testid":"button-cancel-select",children:[e.jsx(ae,{className:"h-3 w-3 mr-1"}),"Cancel"]})]})}const Ks="#0F6E56",Us="#BA7517",Qs="#0F6E56";function _t(s){if(!s)return[];try{let o=s;o.startsWith('"')&&o.endsWith('"')&&(o=o.slice(1,-1).replace(/""/g,'"'));let h=JSON.parse(o);if(typeof h=="string")try{h=JSON.parse(h)}catch{return[]}if(!h||typeof h!="object"||Array.isArray(h))return[];const f=new Set;for(const[y,x]of Object.entries(h))if(x&&typeof x=="object"&&!Array.isArray(x))for(const E of Object.keys(x))f.add(`${y}.${E}`);else f.add(y);return[...f].sort()}catch{return[]}}function Pt(s){if(!s||!String(s).trim())return null;try{const o=JSON.parse(s);return o&&Array.isArray(o.sheetNames)&&Array.isArray(o.labelPositions)&&o.columnHeaders&&typeof o.columnHeaders=="object"&&o.sheetRowCounts&&typeof o.sheetRowCounts=="object"?o:null}catch{return null}}function It(s){return Dt(s)}function Hs(s){return(typeof s=="string"?new Date(s):s).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})}const Js=[{key:"sheetNames",label:"Sheets"},{key:"exactLabels",label:"Labels (exact)"},{key:"nearLabels",label:"Labels (near)"},{key:"fuzzyLabels",label:"Labels (fuzzy)"},{key:"headers",label:"Headers"},{key:"rowCounts",label:"Row counts"}];function Ot({submissionFp:s,globalFp:o}){if(!s||!o)return e.jsx("p",{className:"text-xs text-muted-foreground",children:"No fingerprint â field diff only."});const h=As(s,o);return e.jsx("div",{className:"grid grid-cols-2 gap-x-3 gap-y-1 text-xs",children:Js.map(({key:f,label:y})=>{const x=h.dimensions[f];if(x==null)return e.jsxs("span",{className:"col-span-2 text-muted-foreground",children:[y,": N/A"]},f);const E=x>=.8?Ks:Us;return e.jsxs("span",{className:"contents",children:[e.jsxs("span",{className:"text-muted-foreground",children:[y,":"]}),e.jsxs("span",{className:"tabular-nums font-medium",style:{color:E},children:[(x*100).toFixed(0),"%"]})]},f)})})}function Lt({titleAdded:s,titleRemoved:o,titleShared:h,added:f,removed:y,shared:x,addedBg:E,removedBg:F,sharedBg:$}){return e.jsxs("div",{className:"space-y-2 mt-3",children:[e.jsxs("details",{className:"rounded-md border overflow-hidden",open:f.length>0&&f.length<=12,children:[e.jsx("summary",{className:"cursor-pointer px-2 py-1.5 text-xs font-medium",style:{backgroundColor:E},children:s}),e.jsx("div",{className:"px-2 py-1 text-xs break-words",children:f.length?f.join(", "):"â"})]}),e.jsxs("details",{className:"rounded-md border overflow-hidden",children:[e.jsx("summary",{className:"cursor-pointer px-2 py-1.5 text-xs font-medium",style:{backgroundColor:F},children:o}),e.jsx("div",{className:"px-2 py-1 text-xs break-words",children:y.length?y.join(", "):"â"})]}),e.jsxs("details",{className:"rounded-md border overflow-hidden",children:[e.jsx("summary",{className:"cursor-pointer px-2 py-1.5 text-xs font-medium",style:{backgroundColor:$},children:h}),e.jsx("div",{className:"px-2 py-1 text-xs break-words",children:x.length?x.join(", "):"â"})]})]})}function Gs({submission:s,currentGlobal:o,onPromote:h,onReject:f,onCancel:y,isPromoting:x,isRejecting:E}){const F=Pt(s.layoutFingerprint),$=o?Pt(o.layoutFingerprint):null,O=_t(s.fieldMappings),z=o?_t(o.fieldMappings):[],R=new Set(O),L=new Set(z),Y=O.filter(k=>!L.has(k)),q=z.filter(k=>!R.has(k)),K=O.filter(k=>L.has(k)),V=z.filter(k=>!R.has(k)),M=O.filter(k=>!L.has(k)),c=z.filter(k=>R.has(k));return e.jsxs("div",{className:"rounded-lg border overflow-hidden mb-4 shadow-sm","data-testid":"admin-template-compare",children:[e.jsxs("div",{className:"flex items-center justify-between px-4 py-3 border-b",style:{backgroundColor:"rgba(15, 110, 86, 0.12)"},children:[e.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[e.jsx(Ls,{className:"h-5 w-5 shrink-0 text-[#0F6E56]"}),e.jsxs("span",{className:"font-semibold text-sm truncate",children:["Comparing: ",s.name]})]}),e.jsx(g,{type:"button",variant:"ghost",size:"icon",className:"shrink-0",onClick:y,"aria-label":"Close",children:e.jsx(ae,{className:"h-4 w-4"})})]}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 divide-y md:divide-y-0 md:divide-x",children:[e.jsxs("div",{className:"p-4 space-y-2",children:[e.jsx(D,{className:"bg-[#0F6E56] hover:bg-[#0F6E56] text-white border-0",children:"Submission"}),e.jsx("div",{className:"text-[15px] font-medium",children:s.name}),e.jsx("p",{className:"text-xs text-muted-foreground",children:s.description||"â"}),e.jsxs("div",{className:"flex flex-wrap gap-2 pt-1",children:[e.jsxs("span",{className:"text-xs rounded-md border px-2 py-0.5 bg-muted/50",children:["Fields: ",It(s.fieldMappings)]}),e.jsxs("span",{className:"text-xs rounded-md border px-2 py-0.5 bg-muted/50",children:["Asset: ",s.assetType]}),e.jsxs("span",{className:"text-xs rounded-md border px-2 py-0.5 bg-muted/50",children:["Usage: ",s.usageCount]})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-xs font-semibold mt-2 mb-1",children:"Fingerprint subscores"}),F&&$?e.jsx(Ot,{submissionFp:F,globalFp:$}):e.jsx("p",{className:"text-xs text-muted-foreground",children:"No fingerprint â field diff only."})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-xs font-semibold mt-2",children:"Fields vs current global"}),o?e.jsx(Lt,{titleAdded:`Added (${Y.length} new fields)`,titleRemoved:`Removed (${q.length} fields)`,titleShared:`Shared (${K.length} fields)`,added:Y,removed:q,shared:K,addedBg:"rgba(15, 110, 86, 0.12)",removedBg:"rgba(220, 38, 38, 0.12)",sharedBg:"rgba(107, 114, 128, 0.15)"}):e.jsxs("p",{className:"text-xs text-muted-foreground mt-1",children:["No current global â this will be the first global template for"," ",s.assetType,"."]})]})]}),e.jsx("div",{className:"p-4 space-y-2",children:o?e.jsxs(e.Fragment,{children:[e.jsxs(D,{className:"bg-emerald-700 hover:bg-emerald-700 text-white border-0 gap-1",children:[e.jsx(Rs,{className:"h-3 w-3"}),"Current global"]}),e.jsx("div",{className:"text-[15px] font-medium",children:o.name}),e.jsx("p",{className:"text-xs text-muted-foreground",children:o.description||"â"}),e.jsxs("div",{className:"flex flex-wrap gap-2 pt-1",children:[e.jsxs("span",{className:"text-xs rounded-md border px-2 py-0.5 bg-muted/50",children:["Fields: ",It(o.fieldMappings)]}),e.jsxs("span",{className:"text-xs rounded-md border px-2 py-0.5 bg-muted/50",children:["Asset: ",o.assetType]}),e.jsxs("span",{className:"text-xs rounded-md border px-2 py-0.5 bg-muted/50",children:["Usage: ",o.usageCount]})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-xs font-semibold mt-2 mb-1",children:"Fingerprint subscores"}),F&&$?e.jsx(Ot,{submissionFp:F,globalFp:$}):e.jsx("p",{className:"text-xs text-muted-foreground",children:"No fingerprint â field diff only."})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-xs font-semibold mt-2",children:"Field diff (global perspective)"}),e.jsx(Lt,{titleAdded:`Added (${V.length} fields vs submission)`,titleRemoved:`Removed (${M.length} fields vs submission)`,titleShared:`Shared (${c.length} fields)`,added:V,removed:M,shared:c,addedBg:"rgba(15, 110, 86, 0.12)",removedBg:"rgba(220, 38, 38, 0.12)",sharedBg:"rgba(107, 114, 128, 0.15)"})]})]}):e.jsxs("div",{className:"flex flex-col items-center justify-center text-center min-h-[200px] px-4 text-sm text-muted-foreground",children:["No current global template for ",s.assetType,". Promoting this submission will make it the first."]})})]}),e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 px-4 py-3 border-t bg-muted/40",children:[e.jsxs("div",{className:"flex items-start gap-2 text-xs text-muted-foreground max-w-xl",children:[e.jsx(_s,{className:"h-4 w-4 shrink-0 mt-0.5"}),e.jsx("span",{children:o?`Promoting will demote ${o.name} from global. It stays in the DB.`:`This will become the first global template for ${s.assetType}.`})]}),e.jsxs("div",{className:"flex items-center gap-2.5 shrink-0",children:[e.jsx(g,{type:"button",variant:"ghost",onClick:y,disabled:x,children:"Cancel"}),e.jsx(g,{type:"button",variant:"outline",className:"border-red-600 text-red-600 hover:bg-red-50 hover:text-red-700",onClick:()=>
21void f(),disabled:E||x,children:E?e.jsxs(e.Fragment,{children:[e.jsx(H,{className:"mr-2 h-4 w-4 animate-spin"}),"Rejectingâ¦"]}):"Reject"}),e.jsx(g,{type:"button",className:"text-white border-0 hover:opacity-90",style:{backgroundColor:Qs},onClick:()=>void h(),disabled:x||E,children:x?e.jsxs(e.Fragment,{children:[e.jsx(H,{className:"mr-2 h-4 w-4 animate-spin"}),"Promotingâ¦"]}):"Promote to global"})]})]})]})}const Qe={project:{name:"Property Name",address:"Address",city:"City",state:"State",zip_code:"ZIP Code"},property_details:{total_units:"Total Units",purchase_price:"Purchase Price",closing_costs:"Closing Costs",capex_budget:"CapEx Budget",total_sqft:"Total SqFt",year_built:"Year Built",property_type:"Property Type",avg_sqft:"Avg Unit SqFt"},income_assumptions:{vacancy_rate:"Vacancy Rate",bad_debt_rate:"Bad Debt Rate",other_income_monthly:"Other Income (Monthly)",other_income_annual:"Other Income (Annual)",annual_rent_growth:"Annual Rent Growth",avg_monthly_rent:"Avg Monthly Rent",concessions_rate:"Concessions Rate",effective_gross_income:"Effective Gross Income"},operating_expenses:{property_taxes:"Property Taxes",insurance:"Insurance",utilities:"Utilities",repairs_maintenance:"Repairs & Maintenance",property_management_rate:"Management Rate",payroll:"Payroll",administrative:"Administrative",marketing:"Marketing",reserves_per_unit:"Reserves/Unit",annual_expense_growth:"Annual Expense Growth",net_operating_income:"Net Operating Income"},financing:{loan_amount:"Loan Amount",interest_rate:"Interest Rate",amortization_years:"Amortization (Years)",loan_term_years:"Loan Term (Years)",interest_only_months:"Interest-Only Months"}},X=Object.entries(Qe).flatMap(([s,o])=>Object.entries(o).map(([h,f])=>({value:`${s}.${h}`,label:`${f}`,category:s}))),Bt={project:"Project Info",property_details:"Property Details",income_assumptions:"Income Assumptions",operating_expenses:"Operating Expenses",financing:"Financing"};function zt(s){let o="",h=s+1;for(;h>0;)h--,o=String.fromCharCode(65+h%26)+o,h=Math.floor(h/26);return o}function ve(s,o){return`${zt(o)}${s+1}`}function Ue(s){return s==null?"":typeof s=="number"?Math.abs(s)<1&&s!==0?`${(s*100).toFixed(1)}%`:s>1e3?s.toLocaleString():String(s):String(s).substring(0,50)}function ka(){const{toast:s}=ys(),[o,h]=m.useState({}),[f,y]=m.useState("idle"),[x,E]=m.useState([]),[F,$]=m.useState([]),[O,z]=m.useState(""),[R,L]=m.useState(""),[Y,q]=m.useState(0),[K,V]=m.useState(null),M=m.useRef(null);m.useEffect(()=>{var t;K&&f==="mapping"&&((t=M.current)==null||t.scrollIntoView({behavior:"smooth",block:"nearest"}))},[K,f]);const[c,k]=m.useState(null),[ie,Z]=m.useState(""),[Ne,He]=m.useState("multifamily"),[J,G]=m.useState([]),[Vt,ne]=m.useState(!1),[U,Je]=m.useState([]),[qt,we]=m.useState(0),[Ce,le]=m.useState(null),[Ge,Se]=m.useState(null),[re,We]=m.useState(!1),[de,Ye]=m.useState(!1),[Kt,Fe]=m.useState(null),[Ze,ke]=m.useState(null),[Ut,Ae]=m.useState(!1),[Te,Qt]=m.useState(null),[Xe,Ht]=m.useState(""),[ee,Jt]=m.useState([]),[Gt,$e]=m.useState(!1),{data:te=[],isLoading:Wt}=je({queryKey:["/api/admin/templates"]}),[B,oe]=m.useState(null),[Yt,Zt]=m.useState(null),[et,ce]=m.useState(!1),[Xt,tt]=m.useState(!1),[es,st]=m.useState(!1),{data:Ee=[],refetch:at}=je({queryKey:["/api/admin/templates/submitted"]}),ts=t=>Dt(t),ss=t=>{const a=te.find(i=>i.isGlobal===1&&i.assetType===t.assetType)??null;oe(t),Zt(a),ce(!0)},as=async()=>{if(B){tt(!0);try{await I("PATCH",`/api/admin/templates/${B.id}/promote`,{}),s({title:`"${B.name}" is now the global template for ${B.assetType}.`}),await at(),await v.invalidateQueries({queryKey:["/api/approved-templates"]}),await v.invalidateQueries({queryKey:["/api/mapping-templates"]}),await v.invalidateQueries({queryKey:["/api/admin/templates"]}),await v.invalidateQueries({queryKey:["/api/admin/templates/submitted"]}),ce(!1),oe(null)}catch{s({title:"Promote failed",variant:"destructive"})}finally{tt(!1)}}},is=async()=>{if(B){st(!0);try{await I("PATCH",`/api/admin/templates/${B.id}/reject`,{}),s({title:`"${B.name}" rejected.`}),await at(),await v.invalidateQueries({queryKey:["/api/admin/templates/submitted"]}),ce(!1),oe(null)}catch{s({title:"Reject failed",variant:"destructive"})}finally{st(!1)}}},{data:it=[],isLoading:ns}=je({queryKey:["/api/template-requests"]}),{data:Me=[]}=je({queryKey:["/api/admin/corrections/aggregated"]}),ls=Q({mutationFn:async({templateId:t,originalLabel:a,targetField:i})=>(await I("POST","/api/admin/corrections/approve",{templateId:t,originalLabel:a,targetField:i})).json(),onSuccess:t=>
21{v.invalidateQueries({queryKey:["/api/admin/templates"]}),v.invalidateQueries({queryKey:["/api/admin/corrections/aggregated"]}),s({title:t.message||"Correction approved into template"})},onError:t=>{s({title:"Failed to approve correction",description:t==null?void 0:t.message,variant:"destructive"})}}),nt=Q({mutationFn:async({id:t,isApproved:a})=>(await I("PATCH",`/api/mapping-templates/${t}/approve`,{isApproved:a})).json(),onSuccess:()=>{v.invalidateQueries({queryKey:["/api/admin/templates"]}),v.invalidateQueries({queryKey:["/api/approved-templates"]}),v.invalidateQueries({queryKey:["/api/mapping-templates"]}),s({title:"Template status updated"})}}),lt=Q({mutationFn:async t=>{await I("DELETE",`/api/mapping-templates/${t}`)},onSuccess:()=>{v.invalidateQueries({queryKey:["/api/admin/templates"]}),v.invalidateQueries({queryKey:["/api/approved-templates"]}),v.invalidateQueries({queryKey:["/api/mapping-templates"]}),s({title:"Template deleted"})}}),rs=m.useCallback(async(t,a)=>{$e(!0),Ht(a.name);try{const i=await a.arrayBuffer(),l=Ve(i);let r=t.fieldMappings||"{}";r.startsWith('"')&&r.endsWith('"')&&(r=r.slice(1,-1).replace(/""/g,'"'));let p=JSON.parse(r);if(typeof p=="string")try{p=JSON.parse(p)}catch{}if(!qe(p)){s({title:"Cannot validate",description:"This template is not in cell-reference format.",variant:"destructive"}),$e(!1);return}const u=St(p),j=Ts(l,u),b=$s(j,Es);Jt(b),Ae(!0),b.length===0&&s({title:"Template validates cleanly",description:`No type issues detected on ${a.name}.`})}catch(i){s({title:"Validation failed",description:i instanceof Error?i.message:"Could not parse file.",variant:"destructive"})}finally{$e(!1)}},[s]),me=Q({mutationFn:async({id:t,status:a,adminNotes:i})=>(await I("PATCH",`/api/template-requests/${t}`,{status:a,adminNotes:i})).json(),onSuccess:()=>{v.invalidateQueries({queryKey:["/api/template-requests"]}),s({title:"Request updated"})}}),[ds,rt]=m.useState(null),[os,Re]=m.useState(null),_e=Q({mutationFn:async t=>{const i=await(await I("POST","/api/mapping-templates",{name:t.name,description:t.description,fieldMappings:t.fieldMappings,layoutFingerprint:t.layoutFingerprint||null,isGlobal:!0})).json();if(await I("PATCH",`/api/mapping-templates/${i.id}/approve`,{isApproved:!0}),t.aiBuilderSessionId)try{await I("PATCH",`/api/admin/template-builder/sessions/${t.aiBuilderSessionId}/link`,{templateId:i.id})}catch{}const l=ds??os,r=x.length>0;if(l||r)try{const p=new FormData;l&&p.append("file",l),r&&p.append("rawWorkbookData",JSON.stringify(x)),await fetch(`/api/mapping-templates/${i.id}/upload-sample`,{method:"POST",body:p,credentials:"include"})}catch{}return i},onSuccess:()=>{v.invalidateQueries({queryKey:["/api/admin/templates"]}),v.invalidateQueries({queryKey:["/api/approved-templates"]}),v.invalidateQueries({queryKey:["/api/admin/template-builder/sessions"]}),s({title:"Template created and approved!"}),Fe(null),ke(null),rt(null),Re(null),ot()},onError:t=>{s({title:"Failed to create template",description:t==null?void 0:t.message,variant:"destructive"})}}),Pe=Q({mutationFn:async({id:t,fieldMappings:a})=>(await I("PATCH",`/api/mapping-templates/${t}/mappings`,{fieldMappings:a})).json(),onSuccess:()=>{v.invalidateQueries({queryKey:["/api/admin/templates"]}),v.invalidateQueries({queryKey:["/api/approved-templates"]}),s({title:"Template mappings updated"}),ne(!1),k(null)},onError:t=>{s({title:"Failed to update mappings",description:t==null?void 0:t.message,variant:"destructive"})}}),cs=Q({mutationFn:async({id:t,fingerprint:a})=>{await I("PATCH",`/api/mapping-templates/${t}/fingerprint`,{layoutFingerprint:a})},onSuccess:()=>{v.invalidateQueries({queryKey:["/api/admin/templates"]}),v.invalidateQueries({queryKey:["/api/approved-templates"]}),s({title:"Fingerprint updated"})},onError:t=>{s({title:"Failed to update fingerprint",description:t.message,variant:"destructive"})}}),ms=Q({mutationFn:async({id:t,name:a})=>{await I("PATCH",`/api/mapping-templates/${t}/name`,{name:a})},onSuccess:()=>{v.invalidateQueries({queryKey:["/api/admin/templates"]}),s({title:"Template renamed"})},onError:t=>{s({title:"Failed to rename",description:t.message,variant:"destructive"})}}),ps=Q({mutationFn:async({id:t,assetType:a})=>{await I("PATCH",`/api/mapping-templates/${t}/asset-type`,{assetType:a})},onSuccess:()=>
21{v.invalidateQueries({queryKey:["/api/admin/templates"]}),s({title:"Asset type updated"})},onError:t=>{s({title:"Failed to update asset type",description:t.message,variant:"destructive"})}}),dt=m.useCallback(()=>{y("idle"),E([]),$([]),Fe(null),ke(null),Re(null)},[]),ot=()=>{dt(),z(""),L(""),q(0),V(null)},us=m.useCallback(async t=>{y("parsing"),rt(t);try{const a=await t.arrayBuffer(),i=Ve(a);if(i.length===0||i.every(l=>l.data.length===0)){s({title:"No data found in the uploaded file",variant:"destructive"}),y("idle");return}E(i),q(0),$([]),y("mapping"),pe(i,[],$,We)}catch(a){s({title:"Failed to parse file",description:a==null?void 0:a.message,variant:"destructive"}),y("idle")}},[s]),xs=m.useCallback(async t=>{try{const a=await t.arrayBuffer(),i=Ve(a);if(i.length===0){s({title:"No data found in the uploaded file",variant:"destructive"});return}Se(t),Je(i),we(0);const l=J.filter(r=>r.sheet&&r.cell).map(r=>{const p=i.find(n=>n.name.toLowerCase()===r.sheet.toLowerCase());if(!p||!r.cell)return r;const u=r.cell.match(/^([A-Z]+)(\d+)$/i);if(!u)return r;const j=u[1].toUpperCase(),b=parseInt(u[2],10)-1;let A=0;for(let n=0;n<j.length;n++)A=A*26+(j.charCodeAt(n)-64);A--;const T=p.data[b],w=T?T[A]:null;return{...r,previewValue:w}});G(l),s({title:`Loaded ${i.length} sheets`,description:"Running AI auto-mapping..."}),pe(i,l,G,Ye)}catch(a){s({title:"Failed to parse file",description:a==null?void 0:a.message,variant:"destructive"})}},[s,J]),hs=(t,a,i,l,r,p,u,j)=>{var d,_,C;const b=t[a];if(!b)return;const A=ve(i,l),T=(d=b.data[i])==null?void 0:d[l],w=l>0?(_=b.data[i])==null?void 0:_[l-1]:null,n=w?String(w).trim():"";if(r){const N=p.findIndex(S=>S.targetField===r),P={sheet:b.name,cell:A,targetField:r,label:n,previewValue:T};if(N>=0){const S=[...p];S[N]=P,u(S)}else u([...p,P]);j(null),s({title:`Mapped ${A} (${b.name})`,description:`â ${((C=X.find(S=>S.value===r))==null?void 0:C.label)||r}`})}},ct=t=>{const a={};for(const i of t)i.targetField&&i.sheet&&i.cell&&(a[i.targetField]={sheet:i.sheet,cell:i.cell,label:i.label||""});return a},pe=m.useCallback(async(t,a,i,l)=>{var r,p;l(!0);try{const u=[];for(const n of t)for(const d of n.labelValuePairs)d.value===null||d.value===void 0||String(d.value).trim()===""||u.push({sheet:d.sheet||n.name,label:d.label,value:String(d.value).substring(0,120),labelCell:ve(d.row,d.col),valueCell:ve(d.row,d.valueCol)});if(u.length===0){s({title:"No label-value data found to analyze",variant:"destructive"}),l(!1);return}const b=await(await I("POST","/api/ai/auto-map-cells",{pairs:u})).json();if(!b.mappings||!Array.isArray(b.mappings)){s({title:"AI returned no mappings",variant:"destructive"}),l(!1);return}const A=new Set(X.map(n=>n.value)),T=new Set(a.filter(n=>n.sheet&&n.cell).map(n=>n.targetField)),w=[];for(const n of b.mappings){if(!A.has(n.targetField)||T.has(n.targetField))continue;const d=t.find(N=>N.name.toLowerCase()===n.sheet.toLowerCase()),_=n.cell.match(/^([A-Z]+)(\d+)$/i);let C=n.cell;if(d&&_){const N=_[1].toUpperCase().split("").reduce((S,W)=>S*26+W.charCodeAt(0)-64,0)-1,P=parseInt(_[2])-1;C=((r=d.data[P])==null?void 0:r[N])??n.cell}w.push({sheet:n.sheet,cell:n.cell,targetField:n.targetField,label:n.label||((p=X.find(N=>N.value===n.targetField))==null?void 0:p.label)||n.targetField,previewValue:C,aiMapped:!0,confidence:n.confidence}),T.add(n.targetField)}w.length>0?(i([...a,...w]),s({title:`AI mapped ${w.length} additional field${w.length!==1?"s":""}`,description:"Review the highlighted mappings below"})):s({title:"AI found no additional fields to map",description:"All detected fields were already mapped"})}catch(u){s({title:"AI auto-mapping failed",description:(u==null?void 0:u.message)||"Unknown error",variant:"destructive"})}l(!1)},[s]),gs=()=>{if(!O.trim()){s({title:"Please enter a template name",variant:"destructive"});return}const t=ct(F);if(Object.keys(t).length===0){s({title:"At least one cell mapping is required",variant:"destructive"});return}let a=null;if(x.length>0)try{const i=Ft(x);a=JSON.stringify(i),console.log("[AdminTemplates] Computed layout fingerprint for template")}catch(i){console.warn("[AdminTemplates] Failed to compute fingerprint:",i)}!a&&Ze&&(a=Ze),_e.mutate({name:O.trim(),description:R.trim(),fieldMappings:t,aiBuilderSessionId:Kt,layoutFingerprint:a})},fs=t=>{k(t),Z(t.name),He(t.assetType||"multifamily"),Je([]),Se(null),we(0),le(null);let a={};try{let i=t.fieldMappings||"{}";i.startsWith('"')&&i.endsWith('"')&&(i=i.slice(1,-1).replace(/""/g,'"'));let l=JSON.parse(i);if(typeof l=="string")try{l=JSON.parse(l)}catch{}a=l}catch{a={}}if(qe(a)){const i=St(a);G(i.map(l=>({sheet:l.sheet,cell:l.cell,targetField:l.targetField,label:l.label||"",previewValue:null})))}else{const i=Object.entries(a).map(([l,r])=>typeof r=="object"&&!Array.isArray(r)&&(r!=null&&r.sheet)?{sheet:r.sheet,cell:r.cell,targetField:l,label:r.label||"",previewValue:null}:{sheet:"",cell:"",targetField:Array.isArray(r)?r.join(", "):String(r),label:l,previewValue:null});G(i)}ne(!0)},js=async()=>
21{if(!c)return;const t=ie.trim();t&&t!==c.name&&ms.mutate({id:c.id,name:t}),Ne!==c.assetType&&ps.mutate({id:c.id,assetType:Ne});const a=ct(J);if(Pe.mutate({id:c.id,fieldMappings:a}),U.length>0){const i=Ft(U);cs.mutate({id:c.id,fingerprint:JSON.stringify(i)})}if(Ge){const i=new FormData;i.append("file",Ge);try{await fetch(`/api/mapping-templates/${c.id}/upload-sample`,{method:"POST",body:i,credentials:"include"})}catch{}Se(null)}},vs=m.useCallback((t,a,i,l,r)=>{Fe(i),Re(r??null),l&&ke(JSON.stringify(l));const p=t.map(u=>{var b;let j=null;if(a.length>0){const A=a.find(T=>T.name.toLowerCase()===u.sheet.toLowerCase());if(A&&u.cell){const T=u.cell.match(/^([A-Z]+)(\d+)$/i);if(T){const w=T[1].toUpperCase().split("").reduce((_,C)=>_*26+C.charCodeAt(0)-64,0)-1,n=parseInt(T[2])-1,d=((b=A.data[n])==null?void 0:b[w])??null;j=typeof d=="string"||typeof d=="number"?d:d!==null?String(d):null}}}return{sheet:u.sheet,cell:u.cell,targetField:u.targetField,label:u.label,previewValue:j,aiMapped:!0,confidence:u.confidence}});$(p),a.length>0&&(E(a),q(0)),y("mapping")},[]),Ie=it.filter(t=>t.status==="pending"),mt=it.filter(t=>t.status!=="pending"),pt=(t,a,i,l,r,p,u)=>{var w;if(t.length===0)return null;const j=t[a];if(!j)return null;const b=j.data.length,A=Math.min(j.data.reduce((n,d)=>Math.max(n,(d==null?void 0:d.length)||0),0),20),T=new Map;for(const n of l)n.sheet.toLowerCase()===j.name.toLowerCase()&&n.cell&&T.set(n.cell,n.targetField);return e.jsxs("div",{className:"space-y-3",children:[e.jsx("div",{className:"flex items-center gap-1 overflow-x-auto pb-1",children:t.map((n,d)=>e.jsx("button",{onClick:()=>i(d),className:`px-3 py-1.5 text-xs font-medium rounded-t border transition-colors whitespace-nowrap ${d===a?"bg-primary text-primary-foreground border-primary":"bg-muted/50 text-muted-foreground border-border hover:bg-muted"}`,"data-testid":`sheet-tab-${d}`,children:n.name},d))}),p&&e.jsx(qs,{fieldLabel:((w=X.find(n=>n.value===p))==null?void 0:w.label)||p,onCancel:()=>u(null)}),e.jsx("div",{className:"border rounded-md overflow-auto max-h-[400px]",children:e.jsxs("table",{className:"text-xs border-collapse w-full",children:[e.jsx("thead",{className:"sticky top-0 z-10",children:e.jsxs("tr",{className:"bg-muted",children:[e.jsx("th",{className:"border px-1.5 py-1 text-center text-muted-foreground font-normal w-8"}),Array.from({length:A},(n,d)=>e.jsx("th",{className:"border px-1.5 py-1 text-center text-muted-foreground font-normal min-w-[80px]",children:zt(d)},d))]})}),e.jsx("tbody",{children:Array.from({length:b},(n,d)=>{const _=j.data[d]||[];return e.jsxs("tr",{className:"hover:bg-muted/30",children:[e.jsx("td",{className:"border px-1.5 py-0.5 text-center text-muted-foreground bg-muted/50 font-mono",children:d+1}),Array.from({length:A},(C,N)=>{var ut,xt;const P=ve(d,N),S=T.get(P),W=_[N],Le=W==null||String(W).trim()==="";return e.jsxs("td",{className:`border px-1.5 py-0.5 truncate max-w-[120px] transition-colors ${S?"bg-green-100 dark:bg-green-900/30 font-medium ring-1 ring-green-500/50":p&&!Le?"cursor-pointer hover:bg-blue-100 dark:hover:bg-blue-900/30":""}`,title:S?`${P} â ${((ut=X.find(Be=>Be.value===S))==null?void 0:ut.label)||S}`:W!=null?`${P}: ${String(W)}`:P,onClick:()=>{p&&!Le&&hs(t,a,d,N,p,l,r,u)},"data-testid":`cell-${P}`,children:[S&&e.jsx("span",{className:"text-[9px] text-green-700 dark:text-green-400 block leading-none mb-0.5",children:((xt=X.find(Be=>Be.value===S))==null?void 0:xt.label)||S}),e.jsx("span",{className:Le?"text-muted-foreground/30":"",children:Ue(W)||" "})]},N)})]},d)})})]})}),e.jsxs("p",{className:"text-xs text-muted-foreground text-center",children:[j.data.length," rows · ",A," columns"]})]})},Oe=(t,a,i,l,r)=>{if(r)return e.jsx(Vs,{rows:t,setRows:a,selectingTarget:i,setSelectingTarget:l,targetSchema:Qe,categoryLabels:Bt,formatCellValue:Ue});const p={};for(const u of t){const j=u.targetField.split(".")[0]||"other";p[j]||(p[j]=[]),p[j].push(u)}return e.jsxs("div",{className:"space-y-3",children:[e.jsx("div",{className:"flex items-center justify-between",children:e.jsxs("p",{className:"text-sm font-medium",children:[t.length," field",t.length!==1?"s":""," mapped"]})}),Object.entries(Bt).map(([u,j])=>{const b=Qe[u]||{},A=p[u]||[];return e.jsxs("div",{className:"space-y-1",children:[e.jsx("p",{className:"text-xs font-semibold text-muted-foreground uppercase tracking-wide",children:j}),Object.entries(b).map(([T,w])=>{const n=`${u}.${T}`,d=A.find(C=>C.targetField===n),_=i===n;return e.jsxs("div",{className:"flex items-center gap-2 text-xs py-0.5","data-testid":`cellref-row-${n}`,children:[e.jsx("span",{className:"w-[140px] truncate font-medium",title:w,children:w}),e.jsx(Et,{className:"h-3 w-3 shrink-0 text-muted-foreground"}),d?e.jsxs(e.Fragment,{children:[e.jsx(D,{variant:"outline",className:`text-xs font-mono ${d.aiMapped?"border-[#0F6E56] dark:border-[#5DCAA5]":""}`,children:d.sheet&&d.cell?`${d.sheet}!${d.cell}
21`:d.label||"mapped (no cell ref)"}),d.aiMapped&&e.jsxs(D,{variant:"secondary",className:"text-[9px] px-1 py-0 bg-[#E1F5EE] dark:bg-[#04342C]/30 text-[#0F6E56] dark:text-[#9FE1CB]",children:[e.jsx(ye,{className:"h-2.5 w-2.5 mr-0.5"}),"AI",d.confidence?` ${Math.round(d.confidence*100)}%`:""]}),d.previewValue!=null&&e.jsxs("span",{className:"text-muted-foreground truncate max-w-[100px]",title:String(d.previewValue),children:["= ",Ue(d.previewValue)]}),e.jsx(g,{variant:"ghost",size:"icon",className:"h-5 w-5",onClick:()=>a(t.filter(C=>C.targetField!==n)),"data-testid":`button-remove-cellref-${n}`,children:e.jsx(ae,{className:"h-3 w-3"})})]}):e.jsx("span",{className:"text-muted-foreground/50 italic",children:"not mapped"}),r&&e.jsx(g,{variant:_?"default":"outline",size:"sm",className:"h-5 text-[10px] px-2 ml-auto",onClick:()=>l(_?null:n),"data-testid":`button-pick-cell-${n}`,children:_?"Selecting...":d?"Change":"Pick Cell"}),!r&&d&&e.jsx(g,{variant:"outline",size:"sm",className:"h-5 text-[10px] px-2 ml-auto",onClick:()=>a(t.filter(C=>C.targetField!==n)),"data-testid":`button-edit-cellref-${n}`,children:"Edit"}),!r&&!d&&e.jsxs("div",{className:"flex items-center gap-1 ml-auto",children:[e.jsx(se,{className:"h-5 text-[10px] w-[80px] px-1",placeholder:"Sheet name",defaultValue:"","data-testid":`input-sheet-${n}`,onBlur:C=>{if(C.target.value.trim()){const N=document.querySelector(`[data-testid="input-cell-${n}"]`);N!=null&&N.value.trim()&&a([...t,{sheet:C.target.value.trim(),cell:N.value.trim().toUpperCase(),targetField:n,label:w}])}}}),e.jsx(se,{className:"h-5 text-[10px] w-[50px] px-1 font-mono",placeholder:"B12","data-testid":`input-cell-${n}`,onKeyDown:C=>{if(C.key==="Enter"){const N=C.target.value.trim().toUpperCase(),P=document.querySelector(`[data-testid="input-sheet-${n}"]`),S=P==null?void 0:P.value.trim();S&&N&&a([...t,{sheet:S,cell:N,targetField:n,label:w}])}}})]})]},n)})]},u)})]})};return e.jsx(bs,{children:e.jsxs("div",{className:"space-y-6 p-6 max-w-5xl",children:[e.jsxs("div",{children:[e.jsxs("h1",{className:"text-2xl font-bold flex items-center gap-2",children:[e.jsx(Ns,{className:"h-6 w-6 text-primary"}),"Template Management"]}),e.jsx("p",{className:"text-muted-foreground mt-1",children:"Manage approved underwriting templates and review user requests"})]}),e.jsx(Ms,{onGenerateTemplate:vs,onBuilderReset:dt}),e.jsxs(ue,{children:[e.jsx(xe,{children:e.jsxs(he,{className:"flex items-center gap-2",children:[e.jsx("span",{className:"inline-flex items-center justify-center h-6 w-6 rounded-full bg-[#0F6E56] text-white text-xs font-bold shrink-0",children:"2"}),e.jsx(Ke,{className:"h-5 w-5"}),"Review & Save Template"]})}),e.jsxs(ge,{children:[f==="idle"&&e.jsxs("div",{className:"space-y-4",children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"Upload an Excel underwriting model to create a new template. You'll map specific cells (Sheet + Cell Reference) to underwriting fields."}),e.jsxs("div",{className:"border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors hover:border-primary/50",onClick:()=>{var t;return(t=document.getElementById("admin-upload-input"))==null?void 0:t.click()},"data-testid":"dropzone-admin-upload",children:[e.jsx(Ke,{className:"h-10 w-10 mx-auto text-muted-foreground mb-2"}),e.jsx("p",{className:"text-sm font-medium",children:"Click to upload an Excel file"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:".xlsx, .xls, or .xlsm"})]}),e.jsx("input",{id:"admin-upload-input",type:"file",accept:".xlsx,.xls,.xlsm",className:"hidden",onChange:t=>{var a;(a=t.target.files)!=null&&a[0]&&us(t.target.files[0]),t.target.value=""},"data-testid":"input-admin-upload"})]}),f==="parsing"&&e.jsxs("div",{className:"flex items-center justify-center py-12",children:[e.jsx(H,{className:"h-8 w-8 animate-spin text-primary"}),e.jsx("span",{className:"ml-3 text-sm",children:"Parsing file..."})]}),f==="mapping"&&e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsxs("p",{className:"text-sm font-medium flex items-center gap-2",children:[e.jsx(Ds,{className:"h-4 w-4"}),x.length," sheet",x.length!==1?"s":""," loaded"]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Select a target field below, then click the cell in the spreadsheet to map it"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(g,{variant:"outline",size:"sm",onClick:()=>pe(x,F,$,We),disabled:re||x.length===0,"data-testid":"button-ai-auto-map",children:[re?e.jsx(H,{className:"h-4 w-4 mr-1 animate-spin"}):e.jsx(ye,{className:"h-4 w-4 mr-1"}),re?"AI Analyzing...":"Re-run AI Map"]}),e.jsxs(g,{variant:"ghost",size:"sm",onClick:ot,"data-testid":"button-cancel-upload",children:[e.jsx(ws,{className:"h-4 w-4 mr-1"}),"Start Over"]})]})]}),re&&e.jsx("div",{className:"flex items-center gap-2 p-3 bg-primary/5 border border-primary/20 rounded-lg",children:e.jsx(Ct,{text:"AI is analyzing your spreadsheet structure to find f
21ield mappings...",className:"text-sm"})}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"border rounded-lg p-3 max-h-[500px] overflow-y-auto",children:[e.jsxs("p",{className:"text-xs font-semibold text-muted-foreground uppercase mb-2 flex items-center gap-1 tracking-wide",children:[e.jsx(Rt,{className:"h-3 w-3"}),"Field Mappings"]}),Oe(F,$,K,V,!0)]}),e.jsx("div",{ref:M,className:"w-full","data-testid":"step2-grid-section",children:pt(x,Y,q,F,$,K,V)})]}),e.jsxs("div",{className:"space-y-3 border-t pt-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(fe,{children:"Template Name"}),e.jsx(se,{placeholder:"e.g., Marcus & Millichap v3",value:O,onChange:t=>z(t.target.value),"data-testid":"input-new-template-name"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(fe,{children:"Description (optional)"}),e.jsx(Cs,{placeholder:"Brief description of this template format...",value:R,onChange:t=>L(t.target.value),className:"min-h-[60px]","data-testid":"input-new-template-description"})]}),e.jsxs(g,{onClick:gs,disabled:!O.trim()||F.length===0||_e.isPending,className:"w-full","data-testid":"button-save-new-template",children:[_e.isPending?e.jsx(H,{className:"mr-2 h-4 w-4 animate-spin"}):e.jsx(kt,{className:"mr-2 h-4 w-4"}),"Save & Approve Template (",F.length," mappings)"]})]})]})]})]}),e.jsxs(ue,{children:[e.jsx(xe,{children:e.jsxs(he,{className:"flex items-center gap-2",children:[e.jsx(Ps,{className:"h-5 w-5"}),"Pending Template Requests (",Ie.length,")"]})}),e.jsxs(ge,{children:[ns?e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx(H,{className:"h-6 w-6 animate-spin"})}):Ie.length===0?e.jsx("p",{className:"text-sm text-muted-foreground py-4 text-center",children:"No pending requests"}):e.jsx("div",{className:"space-y-4",children:Ie.map(t=>e.jsxs("div",{className:"border rounded-lg p-4 space-y-3","data-testid":`request-card-${t.id}`,children:[e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-medium",children:t.templateName}),t.description&&e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:t.description}),t.sampleFileName&&e.jsxs("div",{className:"flex items-center gap-2 mt-2",children:[e.jsx(At,{className:"h-4 w-4 text-muted-foreground"}),e.jsx("span",{className:"text-sm",children:t.sampleFileName}),e.jsxs(g,{variant:"outline",size:"sm",onClick:()=>window.open(`/api/template-requests/${t.id}/download`,"_blank"),"data-testid":`button-download-file-${t.id}`,children:[e.jsx(Tt,{className:"h-3 w-3 mr-1"}),"Download"]})]}),e.jsxs("p",{className:"text-xs text-muted-foreground mt-1",children:["Requested ",new Date(t.createdAt).toLocaleDateString()]})]}),e.jsx(D,{variant:"secondary",children:"Pending"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(se,{placeholder:"Admin notes (optional)...",value:o[t.id]||"",onChange:a=>h(i=>({...i,[t.id]:a.target.value})),"data-testid":`input-admin-notes-${t.id}`}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(g,{size:"sm",onClick:()=>me.mutate({id:t.id,status:"approved",adminNotes:o[t.id]||"Approved - template will be added soon"}),disabled:me.isPending,"data-testid":`button-approve-request-${t.id}`,children:[e.jsx(Ss,{className:"mr-1 h-3.5 w-3.5"}),"Approve"]}),e.jsxs(g,{size:"sm",variant:"destructive",onClick:()=>me.mutate({id:t.id,status:"rejected",adminNotes:o[t.id]||""}),disabled:me.isPending,"data-testid":`button-reject-request-${t.id}`,children:[e.jsx(ae,{className:"mr-1 h-3.5 w-3.5"}),"Reject"]})]})]})]},t.id))}),mt.length>0&&e.jsxs("div",{className:"mt-6 border-t pt-4",children:[e.jsx("p",{className:"text-xs font-semibold text-muted-foreground uppercase mb-3",children:"Resolved Requests"}),e.jsx("div",{className:"space-y-2",children:mt.map(t=>e.jsxs("div",{className:"flex items-center gap-3 text-sm py-1","data-testid":`resolved-request-${t.id}`,children:[t.status==="approved"?e.jsx(De,{className:"h-4 w-4 text-green-500 shrink-0"}):e.jsx($t,{className:"h-4 w-4 text-red-500 shrink-0"}),e.jsx("span",{className:"flex-1",children:t.templateName}),t.sampleFileName&&e.jsxs(g,{variant:"ghost",size:"sm",onClick:()=>window.open(`/api/template-requests/${t.id}/download`,"_blank"),"data-testid":`button-download-resolved-${t.id}`,children:[e.jsx(Tt,{className:"h-3 w-3 mr-1"}),"File"]}),t.adminNotes&&e.jsx("span",{className:"text-xs text-muted-foreground truncate max-w-[200px]",children:t.adminNotes}),e.jsx(D,{variant:t.status==="approved"?"default":"destructive",className:"text-xs",children:t.status})]},t.id))})]})]})]}),Me.length>0&&e.jsxs(ue,{children:[e.jsx(xe,{children:e.jsxs(he,{className:"flex items-center gap-2",children:[e.jsx(Fs,{className:"h-5 w-5 text-yellow-500"}
21),"Suggested Template Updates (",Me.length,")"]})}),e.jsxs(ge,{children:[e.jsx("p",{className:"text-sm text-muted-foreground mb-4",children:"These label-to-field corrections have been made by users multiple times. Approve them to add the mappings to a template."}),e.jsx("div",{className:"space-y-2",children:Me.map((t,a)=>e.jsxs("div",{className:"flex items-center gap-3 py-2 px-3 rounded-lg border bg-yellow-50/50 dark:bg-yellow-950/20 border-yellow-200 dark:border-yellow-800","data-testid":`suggested-correction-${a}`,children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsx("span",{className:"font-mono text-xs bg-muted px-1.5 py-0.5 rounded truncate max-w-[200px]",title:t.originalLabel,children:t.originalLabel}),e.jsx(Et,{className:"h-3 w-3 text-muted-foreground shrink-0"}),e.jsx("span",{className:"font-medium",children:t.targetField})]}),e.jsxs("p",{className:"text-xs text-muted-foreground mt-0.5",children:[t.totalCount," corrections across ",t.userCount," user",t.userCount!==1?"s":""," · ",t.documentType]})]}),e.jsxs(ht,{onValueChange:i=>{ls.mutate({templateId:parseInt(i),originalLabel:t.originalLabel,targetField:t.targetField})},children:[e.jsx(gt,{className:"w-[180px]","data-testid":`select-template-correction-${a}`,children:e.jsx(ft,{placeholder:"Add to template..."})}),e.jsx(jt,{children:te.map(i=>e.jsx(ze,{value:String(i.id),children:i.name},i.id))})]})]},a))})]})]}),e.jsxs("div",{className:"rounded-lg border overflow-hidden mb-4 shadow-sm",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2 px-4 py-3 border-b bg-muted/50",children:[e.jsx(Bs,{className:"h-5 w-5 text-muted-foreground"}),e.jsx("span",{className:"font-semibold text-sm",children:"Submitted for review"}),e.jsx(D,{className:"bg-[#0F6E56] hover:bg-[#0F6E56] text-white border-0",children:Ee.length}),e.jsx("span",{className:"text-xs text-muted-foreground ml-auto text-right",children:"Promote to make a template globally available to all users"})]}),e.jsx("div",{children:Ee.length===0?e.jsx("div",{className:"px-4 py-6 text-sm text-muted-foreground text-center",children:"No templates pending review."}):Ee.map(t=>{const a=ts(t.fieldMappings),i=!!(t.layoutFingerprint&&String(t.layoutFingerprint).trim()),l=(B==null?void 0:B.id)===t.id&&et;return e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-[2fr_1.2fr_0.8fr_0.9fr_auto] gap-2 items-center px-4 py-3 border-b last:border-b-0",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"font-medium text-sm truncate",children:t.name}),e.jsx("p",{className:"text-xs text-muted-foreground truncate",children:t.userEmail||"â"})]}),e.jsxs("div",{className:"text-sm",children:[a," fields mapped"]}),e.jsx("div",{className:"text-sm text-muted-foreground",children:Hs(t.createdAt)}),e.jsx("div",{children:e.jsx(D,{variant:"outline",className:i?"border-emerald-600 text-emerald-800 bg-emerald-50 dark:bg-emerald-950/30":"text-muted-foreground",children:i?"Has fingerprint":"No fingerprint"})}),e.jsx("div",{className:"flex justify-end",children:e.jsx(g,{type:"button",size:"sm",variant:l?"default":"outline",className:l?"bg-[#0F6E56] hover:bg-[#0F6E56] text-white border-0":"",onClick:()=>ss(t),children:l?"Comparing":"Compare & Promote"})})]},t.id)})})]}),et&&B&&e.jsx(Gs,{submission:B,currentGlobal:Yt,onPromote:as,onReject:is,onCancel:()=>{ce(!1),oe(null)},isPromoting:Xt,isRejecting:es}),e.jsxs(ue,{children:[e.jsx(xe,{children:e.jsxs(he,{className:"flex items-center gap-2",children:[e.jsx(At,{className:"h-5 w-5"}),"All Templates (",te.length,")"]})}),e.jsx(ge,{children:Wt?e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx(H,{className:"h-6 w-6 animate-spin"})}):te.length===0?e.jsx("p",{className:"text-sm text-muted-foreground py-4 text-center",children:"No templates yet"}):e.jsx("div",{className:"space-y-2",children:te.map(t=>{let a=0,i="none";try{let l=t.fieldMappings||"{}";l.startsWith('"')&&l.endsWith('"')&&(l=l.slice(1,-1).replace(/""/g,'"'));let r=JSON.parse(l);if(typeof r=="string")try{r=JSON.parse(r)}catch{}
21a=Object.keys(r).length,qe(r)?i="cell-ref":a>0&&(i="legacy")}catch{}return e.jsxs("div",{className:"flex items-center gap-3 py-2 px-3 rounded-lg border","data-testid":`admin-template-${t.id}`,children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("p",{className:"font-medium text-sm truncate",children:t.name}),e.jsx(D,{variant:"outline",className:"text-xs capitalize",children:(t.assetType||"multifamily").replace("_"," ")}),t.isPreset===1&&e.jsx(D,{variant:"secondary",className:"text-xs",children:"Official"}),t.isGlobal===1&&e.jsx(D,{variant:"outline",className:"text-xs",children:"Global"})]}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Used ",t.usageCount,"x · ",a," mappings",i==="cell-ref"&&e.jsx("span",{className:"text-green-600 dark:text-green-400 ml-1",children:"(cell references)"}),i==="legacy"&&e.jsx("span",{className:"text-amber-600 dark:text-amber-400 ml-1",children:"(keyword/label)"}),i==="none"&&e.jsx("span",{className:"text-red-500 ml-1",children:"(no mappings)"}),t.layoutFingerprint?e.jsx("span",{className:"text-green-600 dark:text-green-400 ml-1",children:"· fingerprint"}):e.jsx("span",{className:"text-amber-600 dark:text-amber-400 ml-1",children:"· no fingerprint"}),t.description&&` · ${t.description}`]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[i==="cell-ref"&&e.jsxs(e.Fragment,{children:[e.jsx("input",{type:"file",accept:".xlsx,.xlsm",className:"hidden",id:`validate-input-${t.id}`,"data-testid":`validate-input-${t.id}`,onChange:l=>{var p;const r=(p=l.target.files)==null?void 0:p[0];r&&(Qt(t),rs(t,r)),l.target.value=""}}),e.jsxs(g,{size:"sm",variant:"outline",disabled:Gt,onClick:()=>{var l;return(l=document.getElementById(`validate-input-${t.id}`))==null?void 0:l.click()},"data-testid":`button-validate-template-${t.id}`,children:[e.jsx(Is,{className:"mr-1 h-3.5 w-3.5"}),"Validate Template"]})]}),e.jsxs(g,{size:"sm",variant:"outline",onClick:()=>fs(t),"data-testid":`button-edit-template-${t.id}`,children:[e.jsx(Mt,{className:"mr-1 h-3.5 w-3.5"}),"Edit"]}),e.jsx(g,{size:"sm",variant:t.isApproved===1?"default":"outline",onClick:()=>nt.mutate({id:t.id,isApproved:t.isApproved!==1}),disabled:nt.isPending,"data-testid":`button-toggle-approve-${t.id}`,children:t.isApproved===1?e.jsxs(e.Fragment,{children:[e.jsx(De,{className:"mr-1 h-3.5 w-3.5"})," Visible in picker"]}):e.jsxs(e.Fragment,{children:[e.jsx($t,{className:"mr-1 h-3.5 w-3.5"})," Hidden from picker"]})}),t.isPreset!==1&&e.jsx(g,{size:"icon",variant:"ghost",onClick:()=>lt.mutate(t.id),disabled:lt.isPending,"data-testid":`button-delete-template-${t.id}`,children:e.jsx(Os,{className:"h-4 w-4 text-destructive"})})]})]},t.id)})})})]}),e.jsx(vt,{open:Vt,onOpenChange:ne,children:e.jsxs(yt,{className:"max-w-4xl max-h-[85vh] overflow-y-auto",children:[e.jsxs(bt,{children:[e.jsxs(Nt,{className:"flex items-center gap-2",children:[e.jsx(Mt,{className:"h-5 w-5"}),"Edit Template: ",c==null?void 0:c.name]}),e.jsx(wt,{children:"Upload a sample Excel file to view sheets and map cells, or manually enter sheet names and cell references."})]}),e.jsxs("div",{className:"space-y-4 mt-2",children:[e.jsxs("div",{className:"flex gap-4",children:[e.jsxs("div",{className:"flex-1 space-y-2",children:[e.jsx(fe,{className:"text-sm font-medium",children:"Template Name"}),e.jsx(se,{value:ie,onChange:t=>Z(t.target.value),placeholder:"Template name...","data-testid":"input-edit-template-name"})]}),e.jsxs("div",{className:"w-48 space-y-2",children:[e.jsx(fe,{className:"text-sm font-medium",children:"Asset Type"}),e.jsxs(ht,{value:Ne,onValueChange:He,children:[e.jsx(gt,{"data-testid":"select-edit-asset-type",children:e.jsx(ft,{})}),e.jsxs(jt,{children:[e.jsx(ze,{value:"multifamily",children:"Multifamily"}),e.jsx(ze,{value:"self_storage",children:"Self Storage"})]})]})]})]}),e.jsxs("div",{className:"border-2 border-dashed rounded-lg p-4 text-center cursor-pointer transition-colors hover:border-primary/50",onClick:()=>{var t;return(t=document.getElementById("edit-upload-input"))==null?void 0:t.click()},"data-testid":"dropzone-edit-upload",children:[e.jsx(Ke,{className:"h-6 w-6 mx-auto text-muted-foreground mb-1"}),e.jsx("p",{className:"text-xs font-medium",children:U.length>0?`${U.length} sheets loaded â fingerprint will update on save`:"Upload a sample Excel file to map cells visually"}),e.jsx("p",{className:"text-[10px] text-muted-foreground mt-1",children:U.length>0?"New fingerprint ready":c!=null&&c.layoutFingerprint?"Fingerprint: saved":"No fingerprint â upload file to enable auto-matching"})]}),e.jsx("input",{id:"edit-upload-input",type:"file",accept:".xlsx,.xls,.xlsm",className:"hidden",onChange:t=>{var a;(a=t.target.files)!=null&&a[0]&&xs(t.target.files[0]),t.target.value=""},"data-testid":"input-edit-upload"}),U.length>0&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[e.jsxs(g,{variant:"outline",size:"sm",onClick:()=>pe(U,J,G,Ye),disabled:de,"data-testid":"button-ai-auto-map-edit",children:[de?e.jsx(H,{className:"h-4 w-4 mr-1 animate-spin"}):e.jsx(ye,{className:"h-4 w-4 mr-1"}),de?"AI Analyzing...":"Re-run AI Map"]}),de&&e.jsx(Ct,{text:"Analyzing spreadsheet...",className:"text-xs"})]}),e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-4",children:[e.jsxs("div",{className:"border rounded-lg p-3 max-h-[400px] overflow-y-auto",children:[e.jsxs("p",{className:"text-xs font-semibold text-muted-foreground uppercase mb-2 flex items-center gap-1",children:[e.jsx(Rt,{className:"h-3 w-3"}),"Cell Mappings"]}),Oe(J,G,Ce,le,!0)]}),e.jsx("div",{children:pt(U,qt,we,J,G,Ce,le)})]})]}),U.length===0&&e.jsxs("div",{className:"border rounded-lg p-3 max-h-[400px] overflow-y-auto",children:[e.jsx("p",{className:"text-xs font-semibold text-muted-foreground uppercase mb-2",children:"Cell Mappings (manual entry â upload a file for visual mapping)"}
21),Oe(J,G,Ce,le,!1)]}),e.jsxs("div",{className:"flex gap-2 justify-end",children:[e.jsx(g,{variant:"outline",onClick:()=>ne(!1),"data-testid":"button-cancel-edit",children:"Cancel"}),e.jsxs(g,{onClick:js,disabled:Pe.isPending,"data-testid":"button-save-edit-mappings",children:[Pe.isPending?e.jsx(H,{className:"mr-2 h-4 w-4 animate-spin"}):e.jsx(kt,{className:"mr-2 h-4 w-4"}),"Save Changes (",J.length," mappings)"]})]})]})]})}),e.jsx(vt,{open:Ut,onOpenChange:Ae,children:e.jsxs(yt,{className:"max-w-2xl","data-testid":"dialog-validate-results",children:[e.jsxs(bt,{children:[e.jsx(Nt,{children:ee.length===0?"Template validates cleanly":`${ee.length} issue${ee.length===1?"":"s"} found`}),e.jsxs(wt,{children:[Te==null?void 0:Te.name,Xe?` · ${Xe}`:""]})]}),ee.length===0?e.jsxs("div",{className:"flex items-start gap-2 rounded-md border border-green-200 bg-green-50 p-3 text-sm dark:border-green-900/40 dark:bg-green-950/30",children:[e.jsx(De,{className:"mt-0.5 h-4 w-4 shrink-0 text-green-600 dark:text-green-400"}),e.jsx("span",{className:"text-green-900 dark:text-green-200",children:"No type mismatches detected against the field-type expectations."})]}):e.jsx("div",{className:"max-h-96 space-y-2 overflow-y-auto",children:ee.map((t,a)=>e.jsxs("div",{className:"flex items-start gap-2 rounded-md border border-amber-200 bg-amber-50 p-3 text-sm dark:border-amber-900/40 dark:bg-amber-950/30","data-testid":`validation-issue-${a}`,children:[e.jsx(ks,{className:"mt-0.5 h-4 w-4 shrink-0 text-amber-600 dark:text-amber-400"}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("div",{className:"font-mono text-xs text-amber-900 dark:text-amber-200",children:t.targetField}),e.jsx("div",{className:"mt-0.5 text-amber-900 dark:text-amber-100",children:t.reason})]})]},`${t.targetField}-${a}`))}),e.jsx("div",{className:"flex justify-end pt-2",children:e.jsx(g,{variant:"outline",onClick:()=>Ae(!1),"data-testid":"button-close-validate-dialog",children:"Close"})})]})})]})})}export{ka 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.