mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
2 lines
14 KiB
JavaScript
2 lines
14 KiB
JavaScript
import{l as ye,r as p,d as je,aR as we,k as ve,v as l,j as e,B as E,aF as I,t as N,aS as ne}from"./index-Db-xuq0b.js";import{r as ke,u as ie}from"./xlsx-sUI8S2SR.js";import{u as Ee}from"./useQueries-XKsSk0XW.js";import{A as oe,b as le,a as de}from"./alert-8Xu28MAD.js";import{u as Se}from"./useUnit-C4s9nepK.js";import{S as Pe,a as Ue,b as $e,c as _e,d as Ae}from"./select-BoQxM42A.js";import{g as Ce}from"./unitService-CmGVtFHQ.js";import{C as me}from"./circle-alert-Cd_zeQMw.js";const Re=async R=>ye.post("/employees/upload-user-csv-2",R,{}),Fe=()=>{var Q,H,K;const R=p.useRef(null),[O,B]=p.useState(null),[v,D]=p.useState(""),[S,T]=p.useState(null),[k,V]=p.useState(!1),[F,W]=p.useState(!1),[q,L]=p.useState(!1),[y,j]=p.useState(null),[w,P]=p.useState(null),{user:U}=je(),ce=we.language,{getErrorMessage:ue}=ve(l),X=U!=null&&U.employee&&U.employee.length>0?U.employee[0].organizationId:void 0,{getList:he}=Se(),{data:M,isLoading:xe}=X?he(X):{data:void 0,isLoading:!1},G=((Q=M==null?void 0:M.data)==null?void 0:Q.items)??[],J=Ee({queries:G?.map(t=>({queryKey:["unitChildren",t.id],queryFn:()=>Ce(t.id),enabled:!!t.id,staleTime:0}))}),$=p.useMemo(()=>{const t=[];G.forEach((u,g)=>{var a,i;t.push({id:u.id,name:u.name,depth:0});const m=(i=(a=J[g])==null?void 0:a.data)==null?void 0:i.data;(Array.isArray(m)?m:(m==null?void 0:m.items)??[]).forEach(s=>{s!=null&&s.id&&t.push({id:s.id,name:s.name,depth:1})})});const c=new Set;return t.filter(u=>c.has(u.id)?!1:(c.add(u.id),!0))},[M,J?.map(t=>t.data).join("|")]);p.useEffect(()=>{$.length===1&&D($[0].id)},[$]);const _=()=>{T(null),L(!1)},pe=t=>{const c=a=>a.replace(/_/g," ").replace(/\b\w/g,i=>i.toUpperCase()),u=a=>{const i=a.indexOf(":");return i>=0?{reason:a.slice(0,i).trim(),value:a.slice(i+1).trim()}:{reason:a.trim(),value:""}},g=(a,i)=>{const{reason:s,value:o}=u(i),f=c(a);if(s.endsWith("_already_exists"))return o?`${f} "${o}" already exists`:`${f} already exists`;const h=c(s);return o?`${f}: ${h} (${o})`:`${f}: ${h}`},m=[],b=(a,i)=>{const s=/(\d+)/.exec(a),o=s?Number(s[1]):Number.MAX_SAFE_INTEGER,f=s?`Row ${s[1]}`:a;for(const[h,A]of Object.entries(i))typeof A!="string"||!A.trim()||m.push({row:o,text:`${f} — ${g(h,A)}`})};if(Array.isArray(t)){for(const a of t)if(!(!a||typeof a!="object"))for(const[i,s]of Object.entries(a))s&&typeof s=="object"&&b(i,s)}else if(t&&typeof t=="object"){const a=t;for(const[i,s]of Object.entries(a))s&&typeof s=="object"?b(i,s):typeof s=="string"&&s.trim()&&m.push({row:Number.MAX_SAFE_INTEGER,text:g(i,s)})}return m.sort((a,i)=>a.row-i.row)?.map(a=>a.text)},ge=async t=>{var g,m,b,a,i;const c=await ue(t),u=c.split(",")?.map(s=>s.trim()).filter(Boolean);if(typeof t=="object"&&t!==null&&"response"in t){let s=(g=t.response)==null?void 0:g.data;if(s instanceof Blob)try{s=JSON.parse(await s.text())}catch{s=null}const o=(s==null?void 0:s.message)??((b=(m=s==null?void 0:s.exception)==null?void 0:m.response)==null?void 0:b.message),f=(s==null?void 0:s.errors)??((i=(a=s==null?void 0:s.exception)==null?void 0:a.response)==null?void 0:i.errors);if(s&&typeof s=="object"&&o==="duplicate_values_found"){const h=pe(f);return{title:"Duplicate values found",message:h.length>0?`Found ${h.length} duplicate value${h.length>1?"s":""}. Fix the rows below in your Excel file and try again.`:"Some values already exist in the system. Review the conflicts and update the file before trying again.",errors:h.length>0?h:void 0}}}return u.length>1?{title:"We could not submit these users",message:"Some records could not be submitted. Review the issues below, update the file, and try again.",errors:u}:{title:"We could not submit these users",message:c}},fe=async t=>{var g;const c=(g=t.target.files)==null?void 0:g[0],u=t.target;if(c)try{W(!0),_(),j(null),P(null),B(c.name);const m=await c.arrayBuffer(),b=ke(m,{type:"array"}),a=b.Sheets.Positions,i=b.Sheets.OrgStructure;if(!a&&!i){N.error(l("contentManagement.posMissing")),j({title:"Missing template sheets",message:"The file must include the 'Positions' and 'OrgStructure' sheets before it can be imported."}),_();return}const s=(r,n)=>{if(r[n]!==void 0)return r[n];const d=Object.keys(r).find(C=>C.trim().toLowerCase()===n.toLowerCase());return d?r[d]:""},o=r=>String(r??"").trim(),f=(r,n)=>{const d=r.__rowNum__;return typeof d=="number"?d+1:n+2},h=r=>Object.values(r)?.some(n=>o(n)!==""),A=r=>[r.EnglishFirstName,r.EnglishLastName,r.Email,r.PhoneNumber,r.Username,r.Position]?.some(n=>o(n)!==""),Y=a?ie.sheet_to_json(a,{defval:""})?.map(r=>{const n=r;return{Position:o(s(n,"EnglishPosition")),AmharicPosition:o(s(n,"AmharicPosition")),ReportsTo:o(s(n,"ReportsTo")),PositionType:o(s(n,"PositionType"))}}).filter(r=>h(r)):[],z=i?ie.sheet_to_json(i,{defval:""})?.map((r,n)=>{const d=r;return{AmharicFirstName:o(s(d,"AmharicFirstName")),AmharicLastName:o(s(d,"AmharicLastName")),EnglishFirstName:o(s(d,"EnglishFirstName")),EnglishLastName:o(s(d,"EnglishLastName")),Email:o(s(d,"Email")),PhoneNumber:o(s(d,"PhoneNumber")),Position:o(s(d,"Position")),Username:o(s(d,"Username")),__rowNumber:f(d,n)}}).filter(r=>A(r)):[];if(!Y.length&&!z.length){N.error(l("contentManagement.invalidFile")),j({title:"No importable rows found",message:"We could not find any valid rows in the uploaded file. Check that the template columns are filled and try again."}),_();return}const x=[];if(z.forEach(r=>{var d,C,Z,ee,se,te,re,ae;const n=r.__rowNumber;(d=r.EnglishFirstName)!=null&&d.trim()||x.push(`Row ${n}: English First Name is required`),(C=r.EnglishLastName)!=null&&C.trim()||x.push(`Row ${n}: English Last Name is required`),(Z=r.Email)!=null&&Z.trim()||x.push(`Row ${n}: Email is required`),(ee=r.PhoneNumber)!=null&&ee.trim()||x.push(`Row ${n}: Phone Number is required`),(se=r.Username)!=null&&se.trim()||x.push(`Row ${n}: Username is required`),(te=r.Position)!=null&&te.trim()||x.push(`Row ${n}: Position is required`),(re=r.Email)!=null&&re.trim()&&!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(r.Email.trim())&&x.push(`Row ${n}: Invalid email format`),(ae=r.PhoneNumber)!=null&&ae.trim()&&!/^\+?[\d\s\-\(\)]+$/.test(r.PhoneNumber.trim())&&x.push(`Row ${n}: Invalid phone number format`)}),x.length>0){N.error(`Found ${x.length} validation errors.`),j({title:"Please fix the highlighted rows",message:"Some rows are missing required values or contain invalid formats. Update the file and upload it again.",errors:x}),_();return}const Ne={unitId:v,positions:Y,users:z?.map(({__rowNumber:r,...n})=>n)};T(Ne),j(null),P(null),N.success(l("contentManagement.parseSuccess"))}catch(m){N.error(l("contentManagement.parseError")),j({title:"We could not read this file",message:m instanceof Error?m.message:"The uploaded file could not be parsed. Please verify the Excel format and try again."}),_()}finally{W(!1),u.value=""}},be=async()=>{if(!S){N.error(l("contentManagement.noData"));return}if(!v){N.warning(l("organization.selectUnit"));return}try{V(!0),P(null),await Re({...S,unitId:v}),N.success(l("organization.uploadSuccess")),T(null),B(null),L(!1)}catch(t){P(await ge(t))}finally{V(!1)}};return e.jsxs("div",{className:"p-4 border rounded-xl bg-white shadow-sm dark:bg-gray-900 mt-10",children:[e.jsx("div",{children:$.length>0&&e.jsxs("div",{className:"mb-4 w-1/2",children:[e.jsx("label",{className:"block text-sm font-medium text-gray-700",children:l("organization.selectUnit")}),e.jsxs(Pe,{value:v,onValueChange:t=>D(t),children:[e.jsx(Ue,{className:"mt-1 block w-full border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm",children:e.jsx($e,{placeholder:xe?l("organization.loading"):l("organization.selectUnit")})}),e.jsx(_e,{children:$?.map(t=>{var c,u;return e.jsx(Ae,{value:t.id,children:e.jsxs("span",{style:{paddingLeft:t.depth*12},children:[t.depth>0?"└─ ":"",ce==="en"?(c=t.name)==null?void 0:c.en:(u=t.name)==null?void 0:u.am]})},t.id)})})]})]})}),e.jsx("p",{className:"text-sm mb-2 text-gray-700 dark:text-gray-300 font-medium",children:l("contentManagement.bulkMsg")}),e.jsxs("div",{className:"flex items-center gap-3 mb-3",children:[e.jsx(E,{variant:"outline",onClick:()=>{var t;if(!v){N.warning(l("organization.selectUnit"));return}(t=R.current)==null||t.click()},disabled:k||F||!v,children:F?e.jsxs("span",{className:"inline-flex items-center gap-2",children:[e.jsx(I,{className:"h-4 w-4 animate-spin"}),"Parsing file..."]}):k?l("userIncoming.Processing..."):l("contentManagement.selectFile")}),O&&e.jsx("span",{className:"text-sm text-gray-500 dark:text-gray-400 truncate",children:O})]}),e.jsx("input",{ref:R,type:"file",accept:".xlsx, .xls",onChange:fe,className:"hidden"}),F&&e.jsxs("div",{className:"mb-4 flex items-center gap-3 rounded-lg border border-slate-200 bg-slate-50 px-4 py-3 text-sm text-slate-700 shadow-sm dark:border-slate-800 dark:bg-slate-900/60 dark:text-slate-200",children:[e.jsx(I,{className:"h-4 w-4 animate-spin text-slate-600 dark:text-slate-300"}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"font-medium",children:"Reading and validating your Excel file"}),e.jsx("p",{className:"text-xs text-slate-500 dark:text-slate-400",children:"Please wait while we parse the sheets and check for errors."})]})]}),y&&e.jsxs(oe,{className:"mb-4 border-red-200 bg-red-50/80 text-red-950 shadow-sm dark:border-red-900/60 dark:bg-red-950/30 dark:text-red-100",children:[e.jsx(me,{className:"h-4 w-4"}),e.jsxs("div",{className:"w-full space-y-3",children:[e.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(le,{className:"text-sm font-semibold",children:y.title}),e.jsx(de,{className:"text-sm text-red-800 dark:text-red-200",children:y.message})]}),e.jsxs(E,{type:"button",variant:"ghost",size:"sm",className:"h-8 self-start px-2 text-red-700 hover:bg-red-100 hover:text-red-900 dark:text-red-200 dark:hover:bg-red-900/40 dark:hover:text-red-50",onClick:()=>j(null),children:[e.jsx(ne,{className:"mr-1 h-4 w-4"}),l("common.close")]})]}),(H=y.errors)!=null&&H.length?e.jsxs("div",{className:"rounded-lg border border-red-200/80 bg-white/80 p-3 dark:border-red-900/60 dark:bg-red-950/20",children:[e.jsxs("div",{className:"mb-2 flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:"text-sm font-medium text-red-900 dark:text-red-100",children:"Validation details"}),e.jsxs("span",{className:"rounded-full bg-red-100 px-2 py-0.5 text-xs font-medium text-red-700 dark:bg-red-900/50 dark:text-red-100",children:[y.errors.length," issue",y.errors.length>1?"s":""]})]}),e.jsx("div",{className:"max-h-56 overflow-y-auto pr-1",children:e.jsx("ul",{className:"grid gap-2 text-sm text-red-800 dark:text-red-200 sm:grid-cols-2",children:y.errors?.map(t=>e.jsx("li",{className:"rounded-md border border-red-100 bg-red-50 px-3 py-2 leading-relaxed dark:border-red-900/50 dark:bg-red-950/30",children:t},t))})})]}):null]})]}),S&&e.jsxs("div",{className:"mt-4 space-y-4",children:[e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx(E,{variant:"outline",onClick:()=>L(!q),disabled:k,children:q?l("common.Cancel"):l("contentManagement.preview")}),e.jsx(E,{onClick:be,disabled:k||F,children:k?e.jsxs("span",{className:"inline-flex items-center gap-2",children:[e.jsx(I,{className:"h-4 w-4 animate-spin"}),"Uploading users..."]}):l("contentManagement.submitUsers")})]}),k&&e.jsxs("div",{className:"flex items-center gap-3 rounded-lg border border-primary-200 bg-primary-50 px-4 py-3 text-sm text-primary-900 shadow-sm dark:border-primary-900/60 dark:bg-primary-950/30 dark:text-primary-100",children:[e.jsx(I,{className:"h-4 w-4 animate-spin text-primary-700 dark:text-primary-200"}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"font-medium",children:"Submitting users to the server"}),e.jsx("p",{className:"text-xs text-primary-700/80 dark:text-primary-200/80",children:"Please wait while we create the uploaded users and positions."})]})]}),w&&e.jsxs(oe,{className:"border-amber-200 bg-amber-50/80 text-amber-950 shadow-sm dark:border-amber-900/60 dark:bg-amber-950/30 dark:text-amber-100",children:[e.jsx(me,{className:"h-4 w-4"}),e.jsxs("div",{className:"w-full space-y-3",children:[e.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(le,{className:"text-sm font-semibold",children:w.title}),e.jsx(de,{className:"text-sm text-amber-800 dark:text-amber-200",children:w.message})]}),e.jsxs(E,{type:"button",variant:"ghost",size:"sm",className:"h-8 self-start px-2 text-amber-700 hover:bg-amber-100 hover:text-amber-900 dark:text-amber-200 dark:hover:bg-amber-900/40 dark:hover:text-amber-50",onClick:()=>P(null),children:[e.jsx(ne,{className:"mr-1 h-4 w-4"}),l("common.close")]})]}),(K=w.errors)!=null&&K.length?e.jsxs("div",{className:"rounded-lg border border-amber-200/80 bg-white/80 p-3 dark:border-amber-900/60 dark:bg-amber-950/20",children:[e.jsxs("div",{className:"mb-2 flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:"text-sm font-medium text-amber-900 dark:text-amber-100",children:"Submission details"}),e.jsxs("span",{className:"rounded-full bg-amber-100 px-2 py-0.5 text-xs font-medium text-amber-700 dark:bg-amber-900/50 dark:text-amber-100",children:[w.errors.length," issue",w.errors.length>1?"s":""]})]}),e.jsx("div",{className:"max-h-56 overflow-y-auto pr-1",children:e.jsx("ul",{className:"grid gap-2 text-sm text-amber-800 dark:text-amber-200 sm:grid-cols-2",children:w.errors?.map(t=>e.jsx("li",{className:"rounded-md border border-amber-100 bg-amber-50 px-3 py-2 leading-relaxed dark:border-amber-900/50 dark:bg-amber-950/30",children:t},t))})})]}):null]})]})]}),q&&S&&e.jsxs("div",{className:"mt-4 p-4 border rounded-lg bg-gray-50 dark:bg-gray-800 max-h-96 overflow-auto",children:[e.jsxs("div",{className:"flex justify-between items-center mb-2",children:[e.jsx("h3",{className:"text-lg font-semibold text-gray-900 dark:text-gray-100",children:l("contentManagement.preview")}),e.jsx(E,{variant:"ghost",size:"sm",onClick:()=>L(!1),children:"✕"})]}),e.jsx("pre",{className:"text-sm text-gray-700 dark:text-gray-300 whitespace-pre-wrap",children:JSON.stringify(S,null,2)})]})]})},De=()=>e.jsx(Fe,{});export{De as default};
|