PageSourceSearch

https://people.october.health/build/assets/import-u6VTo7Bz.js

js october.health collected 2026-09-24 13:18:58 UTC 11,773 bytes, 1 lines download raw bytes

1import{a as te}from"./rolldown-runtime-DS2seoW7.js";import{O as re}from"./charts-B3EPD53g.js";import{_ as ae,a as B,i as le}from"./vendor-DrhYhv1J.js";import{t as T}from"./arrow-left-BiN_aeI6.js";import{t as H}from"./arrow-right-GRlvHIi6.js";import{t as V}from"./circle-alert-Dw70LUv4.js";import{t as q}from"./circle-check-CHHAtrVR.js";import{t as U}from"./upload-BKRBShI0.js";import{ct as c,f as X}from"./app-DkW1paqt.js";import{a as ie,i as ne,r as oe,t as de}from"./page-toolbar-BaM6JRQ9.js";import{a as b,n as x,o as v,r as N,t as h}from"./card-svQjEXix.js";import{c as ce,i as z,n as me,s as ue,t as pe}from"./select-ttJ-unBI.js";import{a as f,n as xe,o as he,r as m,s as D,t as fe}from"./table-BdMGfApJ.js";import{t as je}from"./app-layout-DTIpDKsM.js";var o=te(re(),1),e=ae(),ge=[{title:"Dashboard",href:"/dashboard"},{title:"Assets",href:"/assets"},{title:"Import",href:"#"}],y=[{name:"name",label:"Asset Name",required:!0},{name:"type",label:"Type (laptop, phone, monitor, keyboard, headset, other)",required:!1},{name:"serial_number",label:"Serial Number",required:!1},{name:"notes",label:"Notes",required:!1},{name:"status",label:"Status (available, assigned, retired)",required:!1},{name:"assigned_to",label:"Assigned To (employee name or email)",required:!1}];function Ie(){const[u,d]=(0,o.useState)("upload"),[i,w]=(0,o.useState)(null),[j,g]=(0,o.useState)([]),[A,F]=(0,o.useState)(!1),[I,M]=(0,o.useState)(!1),[n,C]=(0,o.useState)(null),[W,S]=(0,o.useState)(!1),[R,O]=(0,o.useState)(null),$=s=>{const t=[];for(const r of s){const a=r.toLowerCase().replace(/[_\s-]/g,"");for(const l of y){const p=l.name.toLowerCase().replace(/[_\s-]/g,""),ee=l.label.toLowerCase().replace(/[_\s-]/g,"");if((a===p||a===ee||a.includes(p)||p.includes(a))&&!t.some(se=>se.target_field===l.name)){t.push({source_column:r,target_field:l.name});break}}}g(t)},L=(0,o.useCallback)(async s=>{if(O(null),!s.name.toLowerCase().endsWith(".csv")){O("Only CSV files are supported. Please upload a .csv file.");return}F(!0);const t=new FormData;t.append("file",s);try{const r=await(await fetch("/assets-import/preview",{method:"POST",headers:{"X-CSRF-TOKEN":document.querySelector('meta[name="csrf-token"]')?.getAttribute("content")||"","X-Requested-With":"XMLHttpRequest"},body:t})).json();r.success?(w(r.data),d("map"),$(r.data.headers)):alert(r.message||"Failed to parse file")}catch{alert("Failed to upload file")}finally{F(!1)}},[]),K=(s,t)=>{g(r=>{const a=r.filter(l=>l.source_column!==s);return t?[...a,{source_column:s,target_field:t}]:a})},P=s=>j.find(t=>t.source_column===s)?.target_field||"",_=s=>{s.preventDefault(),s.stopPropagation(),s.type==="dragenter"||s.type==="dragover"?S(!0):s.type==="dragleave"&&S(!1)},J=s=>{s.preventDefault(),s.stopPropagation(),S(!1),s.dataTransfer.files&&s.dataTransfer.files[0]&&L(s.dataTransfer.files[0])},Y=s=>{s.target.files&&s.target.files[0]&&L(s.target.files[0])},k=y.filter(s=>s.required),E=k.filter(s=>j.some(t=>t.target_field===s.name)),G=E.length===k.length,Q=async()=>{if(!i)return;M(!0);const s=i.rows.map(t=>{const r={};for(const a of j)r[a.target_field]=t[a.source_column]||"";return r});try{const t=await(await fetch("/assets-import/process",{method:"POST",headers:{"Content-Type":"application/json","X-CSRF-TOKEN":document.querySelector('meta[name="csrf-token"]')?.getAttribute("content")||"","X-Requested-With":"XMLHttpRequest"},body:JSON.stringify({records:s})})).json();C(t),d("result")}catch{C({success:!1,imported:0,failed:i.rows.length,errors:["Failed to process import. Please try again."]}),d("result")}finally{M(!1)}},Z=()=>{d("upload"),w(null),g([]),C(null)};return(0,e.jsxs)(je,{breadcrumbs:ge,children:[(0,e.jsx)(le,{title:"Import Assets"}),(0,e.jsxs)("div",{className:"flex w-full flex-col gap-5 p-4 sm:p-6 lg:gap-7 lg:p-8",children:[(0,e.jsx)(de,{className:"pb-0",children:(0,e.jsxs)("div",{className:"flex items-start gap-3",children:[(0,e.jsx)(c,{asChild:!0,variant:"outline",size:"icon",className:"shrink-0",children:(0,e.jsx)(B,{href:"/assets","aria-label":"Back",children:(0,e.jsx)(T,{className:"h-4 w-4"})})}),(0,e.jsxs)(ne,{children:[(0,e.jsx)(ie,{children:"Import Assets"}),(0,e.jsx)(oe,{children:"Upload assets from a CSV file"})]})]})}),(0,e.jsx)("div",{className:"flex items-center gap-2",children:["Upload","Map Columns","Preview","Done"].map((s,t)=>{const r=["upload","map","preview","result"].indexOf(u),a=t===r,l=t<r;return(0,e.jsxs)("div",{className:"flex items-center",children:[(0,e.jsx)("div",{className:`flex h-8 w-8 items-center justify-center rounded-full text-sm font-medium ${a?"bg-primary text-primary-foreground":l?"bg-secondary text-secondary-foreground":"bg-muted text-muted-foreground"}`,children:l?(0,e.jsx)(q,{className:"h-4 w-4"}
1):t+1}),(0,e.jsx)("span",{className:`ml-2 text-sm ${a?"font-medium":"text-muted-foreground"}`,children:s}),t<3&&(0,e.jsx)("div",{className:"mx-4 h-px w-8 bg-border"})]},s)})}),u==="upload"&&(0,e.jsxs)("div",{className:"grid gap-6 lg:grid-cols-2",children:[(0,e.jsxs)(h,{children:[(0,e.jsxs)(b,{children:[(0,e.jsx)(v,{children:"Upload File"}),(0,e.jsx)(N,{children:"Drag and drop a CSV file, or click to browse"})]}),(0,e.jsxs)(x,{children:[(0,e.jsxs)("div",{className:`relative flex flex-col items-center justify-center rounded-lg border-2 border-dashed p-12 transition-colors ${W?"border-primary bg-primary/5":"border-border"}`,onDragEnter:_,onDragLeave:_,onDragOver:_,onDrop:J,children:[(0,e.jsx)("input",{type:"file",accept:".csv",onChange:Y,className:"absolute inset-0 cursor-pointer opacity-0",disabled:A}),A?(0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)(X,{className:"h-10 w-10"}),(0,e.jsx)("p",{className:"mt-4 text-muted-foreground",children:"Processing file..."})]}):(0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)(U,{className:"h-10 w-10 text-muted-foreground"}),(0,e.jsx)("p",{className:"mt-4 text-center text-muted-foreground",children:"Drop your file here, or click to browse"}),(0,e.jsx)("p",{className:"mt-2 text-xs text-muted-foreground",children:"Supports CSV files only (max 5MB)"})]})]}),R&&(0,e.jsxs)("div",{className:"mt-4 flex items-center gap-2 rounded-md border border-destructive/30 bg-destructive/5 px-4 py-3 text-sm text-destructive",children:[(0,e.jsx)(V,{className:"h-4 w-4 shrink-0"}),R]})]})]}),(0,e.jsxs)(h,{children:[(0,e.jsxs)(b,{children:[(0,e.jsx)(v,{children:"Expected Columns"}),(0,e.jsx)(N,{children:"Your file should include these fields"})]}),(0,e.jsxs)(x,{className:"space-y-4",children:[(0,e.jsx)("div",{className:"space-y-2",children:y.map(s=>(0,e.jsxs)("div",{className:"flex items-center gap-2 text-sm text-muted-foreground",children:[(0,e.jsx)("span",{className:"text-muted-foreground/50",children:"•"}),(0,e.jsxs)("span",{children:[s.label,s.required&&(0,e.jsxs)("span",{className:"text-destructive",children:[" ","*"]})]})]},s.name))}),(0,e.jsx)("div",{className:"rounded-lg border border-border bg-muted/30 p-3",children:(0,e.jsx)("p",{className:"text-sm text-muted-foreground",children:'Only the asset name is required. Type defaults to "Other" and status defaults to "Available" if not specified. Employees can be matched by full name or email.'})})]})]})]}),u==="map"&&i&&(0,e.jsxs)("div",{className:"space-y-6",children:[(0,e.jsxs)(h,{children:[(0,e.jsxs)(b,{children:[(0,e.jsx)(v,{children:"Map Columns"}),(0,e.jsxs)(N,{children:["Match your file columns to the target fields (",E.length,"/",k.length," required fields mapped)"]})]}),(0,e.jsx)(x,{children:(0,e.jsx)("div",{className:"space-y-3",children:i.headers.map(s=>(0,e.jsxs)("div",{className:"flex items-center gap-4",children:[(0,e.jsx)("div",{className:"w-1/3 rounded-md border border-border bg-muted/50 px-3 py-2 text-sm",children:s}),(0,e.jsx)(H,{className:"h-4 w-4 shrink-0 text-muted-foreground"}),(0,e.jsxs)(pe,{value:P(s)||"skip",onValueChange:t=>K(s,t==="skip"?"":t),children:[(0,e.jsx)(ue,{className:"flex-1",children:(0,e.jsx)(ce,{placeholder:"Select target field..."})}),(0,e.jsxs)(me,{children:[(0,e.jsx)(z,{value:"skip",children:"-- Skip this column --"}),y.map(t=>(0,e.jsxs)(z,{value:t.name,children:[t.label,t.required&&" *"]},t.name))]})]}),P(s)&&(0,e.jsx)(q,{className:"h-5 w-5 shrink-0 text-secondary"})]},s))})})]}),(0,e.jsxs)("div",{className:"flex justify-between",children:[(0,e.jsxs)(c,{variant:"outline",onClick:()=>{w(null),g([]),d("upload")},children:[(0,e.jsx)(T,{className:"mr-2 h-4 w-4"}),"Back"]}),(0,e.jsxs)(c,{onClick:()=>d("preview"),disabled:!G,children:["Continue to Preview",(0,e.jsx)(H,{className:"ml-2 h-4 w-4"})]})]})]}),u==="preview"&&i&&(0,e.jsxs)("div",{className:"space-y-6",children:[(0,e.jsxs)(h,{children:[(0,e.jsxs)(b,{children:[(0,e.jsx)(v,{children:"Preview Import"}),(0,e.jsxs)(N,{children:["Review the data before importing (",i.total_rows," records)"]})]}),(0,e.jsx)(x,{children:(0,e.jsx)("div",{className:"overflow-x-auto rounded-lg border border-border",children:(0,e.jsxs)(fe,{children:[(0,e.jsx)(he,{className:"bg-muted/30",children:(0,e.jsxs)(D,{children:[(0,e.jsx)(f,{children:"Name"}),(0,e.jsx)(f,{children:"Type"}),(0,e.jsx)(f,{children:"Serial Number"}),(0,e.jsx)(f,{children:"Status"}),(0,e.jsx)(f,{children:"Assigned To"})]})}),(0,e.jsxs)(xe,{children:[i.rows.slice(0,10).map((s,t)=>{const r=a=>{const l=j.find(p=>p.target_field===a);return l&&s[l.source_column]||"—"};return(0,e.jsxs)(D,{children:[(0,e.jsx)(m,{className:"font-medium",children:r("name")}
1),(0,e.jsx)(m,{children:r("type")}),(0,e.jsx)(m,{className:"font-mono text-sm",children:r("serial_number")}),(0,e.jsx)(m,{children:r("status")}),(0,e.jsx)(m,{children:r("assigned_to")})]},t)}),i.rows.length>10&&(0,e.jsx)(D,{children:(0,e.jsxs)(m,{colSpan:5,className:"text-center text-muted-foreground",children:["... and"," ",i.rows.length-10," ","more records"]})})]})]})})})]}),(0,e.jsxs)("div",{className:"flex justify-between",children:[(0,e.jsxs)(c,{variant:"outline",onClick:()=>d("map"),children:[(0,e.jsx)(T,{className:"mr-2 h-4 w-4"}),"Back"]}),(0,e.jsxs)(c,{onClick:Q,disabled:I,children:[I&&(0,e.jsx)(X,{className:"mr-2 h-4 w-4"}),(0,e.jsx)(U,{className:"mr-2 h-4 w-4"}),"Import ",i.total_rows," Assets"]})]})]}),u==="result"&&n&&(0,e.jsx)(h,{children:(0,e.jsxs)(x,{className:"py-12",children:[n.imported>0&&n.failed===0?(0,e.jsxs)("div",{className:"flex flex-col items-center text-center",children:[(0,e.jsx)("div",{className:"flex h-16 w-16 items-center justify-center rounded-full bg-secondary/10",children:(0,e.jsx)(q,{className:"h-8 w-8 text-secondary"})}),(0,e.jsx)("h3",{className:"mt-4 text-lg font-semibold",children:"Import Successful"}),(0,e.jsxs)("p",{className:"mt-2 text-muted-foreground",children:[n.imported," asset",n.imported!==1?"s":""," ","imported successfully."]})]}):(0,e.jsxs)("div",{className:"flex flex-col items-center text-center",children:[(0,e.jsx)("div",{className:"flex h-16 w-16 items-center justify-center rounded-full bg-destructive/10",children:(0,e.jsx)(V,{className:"h-8 w-8 text-destructive"})}),(0,e.jsx)("h3",{className:"mt-4 text-lg font-semibold",children:"Import Completed with Issues"}),(0,e.jsxs)("p",{className:"mt-2 text-muted-foreground",children:[n.imported," imported,"," ",n.failed," failed."]})]}),n.errors.length>0&&(0,e.jsxs)("div",{className:"mx-auto mt-6 max-h-40 max-w-md overflow-y-auto rounded-lg border border-destructive/30 bg-destructive/5 p-4",children:[(0,e.jsx)("h4",{className:"mb-2 font-medium text-destructive",children:"Errors:"}),(0,e.jsx)("ul",{className:"list-inside list-disc space-y-1 text-sm text-destructive",children:n.errors.map((s,t)=>(0,e.jsx)("li",{children:s},t))})]}),(0,e.jsxs)("div",{className:"mt-8 flex justify-center gap-4",children:[(0,e.jsx)(c,{variant:"outline",onClick:Z,children:"Import More"}),(0,e.jsx)(c,{asChild:!0,children:(0,e.jsx)(B,{href:"/assets",children:"Back to Assets"})})]})]})})]})]})}export{Ie 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.