1import{b as A,r as n,e as N,j as e}from"./index-BsRJbbzd.js";function D(){const{me:s}=A(),[o,t]=n.useState({roles_catalog:[],rows:[]}),[a,i]=n.useState(!0),[h,p]=n.useState(null),[c,y]=n.useState(null),[g,l]=n.useState(!1),[x,m]=n.useState(""),j=n.useCallback(async()=>{i(!0);try{const d=await N.accessRoster();t(d),p(null)}catch(d){p(d.detail||d.message)}finally{i(!1)}},[]);n.useEffect(()=>{j()},[j]);const f=n.useMemo(()=>{const d=x.trim().toLowerCase(),k=o.rows||[];return d?k.filter(r=>(r.display_name||"").toLowerCase().includes(d)||(r.email||"").toLowerCase().includes(d)||(r.odoo_login||"").toLowerCase().includes(d)):k},[o,x]);if(!s)return null;if(!s.is_super)return e.jsx(M,{});const _=f.find(d=>d.row_id===c)||null;return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3 flex-wrap",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-xl font-semibold text-slate-900",children:"Access & Authorizations"}),e.jsx("p",{className:"text-xs text-slate-500 max-w-2xl",children:"One place for every actor â roles (written straight to Odoo contact tags), each person's Odoo API key, admin-panel permissions, and activate/deactivate. Replaces the old Admin-users and Warehouse-staff pages."})]}),e.jsx("button",{type:"button",onClick:()=>l(!0),className:"rounded-xl bg-slate-900 text-white text-xs font-semibold px-3 py-2",children:"+ Add user"})]}),h&&e.jsx("p",{className:"text-sm text-red-600 bg-red-50 border border-red-100 rounded-lg px-3 py-2",children:h}),e.jsx(B,{}),e.jsx(R,{data:o,onChanged:j}),o&&o.odoo_link_reachable===!1&&e.jsx("p",{className:"text-xs text-amber-800 bg-amber-50 border border-amber-100 rounded-lg px-3 py-2",children:"Couldn't reach Odoo to match staff records to admin logins, so someone with both may appear twice below until it's back."}),e.jsx("input",{value:x,onChange:d=>m(d.target.value),placeholder:"Search name, email, Odoo loginâ¦",className:"w-full sm:w-80 rounded-lg border border-slate-200 px-3 py-2 text-sm"}),e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-[minmax(0,1fr)_minmax(0,1.2fr)] gap-4",children:[e.jsx("div",{className:"rounded-xl border border-slate-200 overflow-hidden",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"bg-slate-50 text-slate-500 text-xs",children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-3 py-2 text-left",children:"User"}),e.jsx("th",{className:"px-3 py-2 text-left",children:"Roles"}),e.jsx("th",{className:"px-3 py-2 text-left",children:"Key"}),e.jsx("th",{className:"px-3 py-2 text-left",children:"Status"})]})}),e.jsx("tbody",{children:a?e.jsx("tr",{children:e.jsx("td",{colSpan:4,className:"px-3 py-6 text-center text-slate-400",children:"Loadingâ¦"})}):f.length===0?e.jsx("tr",{children:e.jsx("td",{colSpan:4,className:"px-3 py-6 text-center text-slate-400",children:"No users."})}):f.map(d=>{const k=Object.entries(d.roles||{}).filter(([,r])=>r).map(([r])=>r);return e.jsxs("tr",{onClick:()=>y(d.row_id),className:`border-t border-slate-100 cursor-pointer hover:bg-slate-50 ${c===d.row_id?"bg-indigo-50":""}`,children:[e.jsxs("td",{className:"px-3 py-2",children:[e.jsx("div",{className:"font-medium text-slate-800",children:d.display_name}),e.jsxs("div",{className:"text-[11px] text-slate-400",children:[d.email||d.odoo_login||"â",d.kinds.includes("admin")&&e.jsx("span",{className:"ml-1 text-indigo-500",children:"admin"})]})]}),e.jsx("td",{className:"px-3 py-2 text-[11px] text-slate-600",children:d.is_super?"Super-admin":k.length?k.join(", "):"â"}),e.jsx("td",{className:"px-3 py-2",children:d.has_key?e.jsx("span",{className:"text-emerald-600 text-xs",children:"â key"}):e.jsx("span",{className:"text-slate-300 text-xs",children:"â"})}),e.jsx("td",{className:"px-3 py-2",children:d.active?e.jsx("span",{className:"text-emerald-600 text-xs",children:"Active"}):e.jsx("span",{className:"text-red-500 text-xs",children:"Off"})})]},d.row_id)})})]})}),_?e.jsx(C,{row:_,rolesCatalog:o.roles_catalog,permissionCatalog:o.permission_catalog,onChanged:j},_.row_id):e.jsx("div",{className:"rounded-xl border border-dashed border-slate-200 p-8 text-center text-slate-400 text-sm",children:"Select a user to manage their access."})]}),g&&e.jsx(E,{onClose:()=>l(!1),onAdded:j})]})}function C({row:s,rolesCatalog:o,permissionCatalog:t,onChanged:a}){const[i,h]=n.useState("roles");return e.jsxs("div",{className:"rounded-xl border border-slate-200 p-4 space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-semibold text-slate-900",children:s.display_name}),e.jsx("div",{className:"text-[11px] text-slate-400",children:s.email||s.odo
1o_login||"â"})]}),e.jsx(T,{row:s,onChanged:a})]}),e.jsx(P,{row:s,onChanged:a}),e.jsxs("div",{className:"flex gap-2 text-xs border-b border-slate-100",children:[e.jsx(O,{on:i==="roles",onClick:()=>h("roles"),children:"Roles & Odoo"}),e.jsx(O,{on:i==="admin",onClick:()=>h("admin"),children:"Admin access"})]}),i==="roles"?e.jsx(L,{row:s,rolesCatalog:o,onChanged:a}):e.jsx(I,{row:s,permissionCatalog:t,onChanged:a})]})}function R({data:s,onChanged:o}){const[t,a]=n.useState(null),[i,h]=n.useState(!1),[p,c]=n.useState(null),y=(s.rows||[]).filter(l=>l.kinds.includes("exec")&&l.kinds.includes("admin")&&l.link_source&&l.link_source!=="explicit");if(!y.length&&!t&&!p)return null;const g=async l=>{h(!0),c(null);try{const x=await N.accessBulkAdminLink(l);l?a(x):(a(null),c(`Linked ${x.linked.length} ${x.linked.length===1?"person":"people"} for reporting.`),await o())}catch(x){c((x==null?void 0:x.detail)||(x==null?void 0:x.message)||"Couldn't link them.")}finally{h(!1)}};return e.jsxs("div",{className:"rounded-lg border border-indigo-100 bg-indigo-50 px-3 py-2 text-xs text-indigo-900 space-y-2",children:[t?e.jsxs("div",{className:"space-y-2",children:[e.jsxs("p",{className:"font-medium",children:["This will link ",t.would_link.length," ",t.would_link.length===1?"person":"people",":"]}),e.jsx("ul",{className:"space-y-0.5",children:t.would_link.map(l=>e.jsxs("li",{children:[l.name," ",e.jsx("span",{className:"text-indigo-500",children:l.email})," ",e.jsxs("span",{className:"text-indigo-400",children:["· matched by"," ",l.matched_by==="odoo_uid"?"their Odoo API key":"their Odoo employee record"]})]},l.admin_id))}),t.skipped.length>0&&e.jsxs(e.Fragment,{children:[e.jsxs("p",{className:"font-medium text-amber-800",children:["Skipped ",t.skipped.length,":"]}),e.jsx("ul",{className:"space-y-0.5 text-amber-800",children:t.skipped.map(l=>e.jsxs("li",{children:[l.name," â ",l.reason]},l.admin_id))})]}),e.jsxs("div",{className:"flex gap-2 pt-1",children:[e.jsx("button",{type:"button",disabled:i||t.would_link.length===0,onClick:()=>g(!1),className:"rounded-md bg-indigo-700 px-2 py-1 font-medium text-white disabled:opacity-50",children:i?"Linkingâ¦":"Confirm"}),e.jsx("button",{type:"button",disabled:i,onClick:()=>a(null),className:"rounded-md border border-indigo-300 bg-white px-2 py-1 disabled:opacity-50",children:"Cancel"})]})]}):e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("span",{children:[y.length," ",y.length===1?"person is":"people are"," shown as one row but not yet linked for reporting â their admin-panel work isn't credited to them in the KRA exports."]}),e.jsx("button",{type:"button",disabled:i,onClick:()=>g(!0),className:"shrink-0 rounded-md border border-indigo-300 bg-white px-2 py-1 font-medium disabled:opacity-50",children:i?"Checkingâ¦":"Link all for reporting"})]}),p&&e.jsx("p",{className:"text-indigo-700",children:p})]})}function P({row:s,onChanged:o}){const[t,a]=n.useState(!1),[i,h]=n.useState(null);if(!(s.kinds.includes("exec")&&s.kinds.includes("admin")))return null;const c=s.link_source==="explicit",y=async g=>{a(!0),h(null);try{await N.accessSetAdminLink({exec_id:s.exec_id,admin_profile_id:g?s.admin_id:null}),await o()}catch(l){h((l==null?void 0:l.detail)||(l==null?void 0:l.message)||"Couldn't save the link.")}finally{a(!1)}};return e.jsxs("div",{className:"rounded-lg border border-slate-200 bg-slate-50 px-3 py-2 text-[11px] text-slate-600",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsxs("span",{children:["Staff record and admin login shown as one person â"," ",c?"linked for reporting.":s.link_source==="odoo_uid"?"matched by their Odoo API key.":"matched by their Odoo employee record."]}),c?e.jsx("button",{type:"button",disabled:t,onClick:()=>y(!1),className:"shrink-0 text-slate-500 underline disabled:opacity-50",children:"Unlink"}):e.jsx("button",{type:"button",disabled:t,onClick:()=>y(!0),className:"shrink-0 rounded-md border border-emerald-300 bg-white px-2 py-1 font-medium text-emerald-700 disabled:opacity-50",children:t?"Linkingâ¦":"Link for reporting"})]}),!c&&e.jsx("p",{className:"mt-1 text-slate-400",children:"Until it's linked, work they do in the admin panel isn't credited to them in the KRA reports."}),i&&e.jsx("p",{className:"mt-1 text-red-600",children:i})]})}function L({row:s,rolesCatalog:o,onChanged:t}){var j,f,_,d,k,r;const[a,i]=n.useState(!1),[h,p]=n.useState(null),[c,y]=n.useState(null),g=!!s.odoo_partner_id,l=async()=>{var b,u;if(!g){p("This user has no linked Odoo contact â add them via + Add user.");return}i(!0),p(null),y(null);try{const v=await N.accessRefreshRoles({odoo_partner_id:s.odoo_partner_id}),w=(v.changes||[])[0];if(v.failed)p("Couldn't read the tags from Odoo just now â nothing changed. Try again.");else if(!w)y("Already matches Odoo â nothing to change.");else{const S=[];(b=w.granted)!=null&&b.length&&S.push(`turned on ${w.granted.join(", ")}`),(u=w.cleared)!=null&&u.length&&S.push(`turned off ${w.cleared.join(", ")}`),y(`Read from Odoo â ${S.join("; ")}.`)}await t()}catch(v){p(v.detail||v.message)}finally{i(!1)}},x=async(b,u)=>{if(!g){p("This user has no linked Odoo contact â add them via + Add user.");return}i(!0),p(null),y(null);try{await N.accessSetRoles({odoo_partner_id:s.odoo_partner_id,grant:u?[]:[b],revoke:u?[b]:[]}),await t()}catch(v){p(v.detail||v.message)}finally{i(!1)}},m=n.useMemo(()=>{const b={warehouse:[],field:[]};
1return(o||[]).forEach(u=>(b[u.group]||(b[u.group]=[])).push(u)),b},[o]);return e.jsxs("div",{className:"space-y-4",children:[h&&e.jsx("p",{className:"text-xs text-red-600 bg-red-50 border border-red-100 rounded px-2 py-1",children:h}),c&&e.jsx("p",{className:"text-xs text-emerald-700 bg-emerald-50 border border-emerald-100 rounded px-2 py-1",children:c}),!g&&e.jsx("p",{className:"text-[11px] text-amber-600",children:"No Odoo contact linked â role tags can't be written for this user."}),e.jsxs("div",{className:"flex items-center justify-between gap-2 flex-wrap",children:[e.jsx("p",{className:"text-[11px] text-slate-400",children:"These chips show what the app has stored. A tag changed in Odoo itself only shows here after a refresh."}),e.jsxs("button",{type:"button",disabled:a||!g,onClick:l,className:"shrink-0 inline-flex items-center gap-1 rounded-full border border-slate-200 bg-white px-3 py-1 text-xs font-medium text-slate-700 hover:border-slate-300 disabled:opacity-50",children:[e.jsx("span",{"aria-hidden":"true",children:"â»"}),a?"Reading Odooâ¦":"Refresh from Odoo"]})]}),["field","warehouse"].map(b=>e.jsxs("div",{children:[e.jsx("div",{className:"text-[11px] uppercase tracking-wide text-slate-400 mb-1",children:b==="field"?"Field / sales roles":"Warehouse roles"}),e.jsx("div",{className:"flex flex-wrap gap-2",children:(m[b]||[]).map(u=>{const v=!!(s.roles||{})[u.key];return e.jsx("button",{disabled:a,onClick:()=>x(u.key,v),title:`Odoo tag: ${u.tag}`,className:`px-2.5 py-1 rounded-full text-xs border transition ${v?"bg-emerald-600 text-white border-emerald-600":"bg-white text-slate-600 border-slate-200 hover:border-slate-300"}`,children:u.label},u.key)})})]},b)),(((j=s.approver_warehouses)==null?void 0:j.length)>0||((f=s.picker_warehouses)==null?void 0:f.length)>0)&&e.jsxs("div",{className:"text-[11px] text-slate-500",children:["Warehouse scope â"," ",(_=s.approver_warehouses)!=null&&_.length?`approver @ ${s.approver_warehouses.join(", ")}`:"",(d=s.approver_warehouses)!=null&&d.length&&((k=s.picker_warehouses)!=null&&k.length)?" · ":"",(r=s.picker_warehouses)!=null&&r.length?`picker @ ${s.picker_warehouses.join(", ")}`:"",e.jsxs("span",{className:"text-slate-300",children:[" ","(edit on Warehouses page)"]})]}),e.jsx($,{row:s,onChanged:t})]})}function $({row:s,onChanged:o}){const t=s.kinds.includes("exec")?"exec":"admin",a=t==="exec"?s.exec_id:s.admin_id,[i,h]=n.useState(s.odoo_login||s.email||""),[p,c]=n.useState(""),[y,g]=n.useState(!1),[l,x]=n.useState(null),m=async()=>{g(!0),x(null);try{const f=await N.accessSetOdooKey({kind:t,id:a,odoo_login:i,odoo_api_key:p});c(""),x(`Verified as ${f.verified_as}`),await o()}catch(f){x(f.detail||f.message)}finally{g(!1)}},j=async()=>{g(!0),x(null);try{await N.accessSetOdooKey({kind:t,id:a,clear:!0}),await o()}catch(f){x(f.detail||f.message)}finally{g(!1)}};return e.jsxs("div",{className:"rounded-lg border border-slate-200 p-3 space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("div",{className:"text-xs font-semibold text-slate-700",children:"Odoo API key"}),s.has_key?e.jsx("span",{className:"text-[11px] text-emerald-600",children:"â linked"}):e.jsx("span",{className:"text-[11px] text-slate-400",children:"not linked"})]}),e.jsx("p",{className:"text-[11px] text-slate-400",children:"Approvals & submits run as this Odoo user. Needed where Odoo's per-warehouse approval rule authorises a specific person."}),e.jsx("input",{value:i,onChange:f=>h(f.target.value),placeholder:"Odoo login (email)",className:"w-full rounded border border-slate-200 px-2 py-1 text-xs"}),e.jsx("input",{value:p,onChange:f=>c(f.target.value),placeholder:s.has_key?"â¢â¢â¢â¢ enter a new key to replace":"Odoo API key",type:"password",className:"w-full rounded border border-slate-200 px-2 py-1 text-xs"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("button",{disabled:y||!i||!p,onClick:m,className:"rounded bg-slate-900 text-white text-xs px-3 py-1 disabled:opacity-40",children:"Save & verify"}),s.has_key&&e.jsx("button",{disabled:y,onClick:j,className:"rounded border border-red-200 text-red-600 text-xs px-3 py-1",children:"Revoke key"})]}),l&&e.jsx("p",{className:"text-[11px] text-slate-500",children:l})]})}function I({row:s,permissionCatalog:o,onChanged:t}){const[a,i]=n.useState(!!s.is_super),[h,p]=n.useState(new Set(s.permissions||[])),[c,y]=n.useState(!1),[g,l]=n.useState(null),x=!!s.admin_id,[m,j]=n.useState(s.email||s.odo
1o_login||""),f=o||[],_=n.useMemo(()=>{const r=new Map;return f.forEach(b=>{r.has(b.group)||r.set(b.group,[]),r.get(b.group).push(b)}),Array.from(r.entries())},[f]),d=r=>{p(b=>{const u=new Set(b);return u.has(r)?u.delete(r):u.add(r),u})},k=async()=>{const r=(m||"").trim();if(!x&&(!r||!r.includes("@"))){l("Enter this person's Odoo HR work email to grant admin-panel access.");return}y(!0),l(null);try{await N.accessSetAdminAccess({admin_id:s.admin_id||void 0,email:x?void 0:r,display_name:s.display_name,is_super:a,permissions:a?[]:Array.from(h)}),l("Saved."),await t()}catch(b){l(b.detail||b.message)}finally{y(!1)}};return e.jsxs("div",{className:"space-y-3",children:[e.jsx("p",{className:"text-[11px] text-slate-400",children:"Panel access + permission scope. Granting reactivates a deactivated admin account."}),!x&&e.jsxs("div",{children:[e.jsx("div",{className:"text-[11px] text-slate-500 mb-1",children:"Odoo HR work email (they log into admin with this + their HR PIN)"}),e.jsx("input",{type:"email",value:m,onChange:r=>j(r.target.value),placeholder:"[email protected]",className:"w-full rounded border border-slate-200 px-2 py-1 text-xs"}),e.jsx("p",{className:"mt-1 text-[10px] text-slate-400",children:"This person doesn't have admin access yet â saving grants it."})]}),e.jsxs("label",{className:"flex items-center gap-2 text-sm",children:[e.jsx("input",{type:"checkbox",checked:a,onChange:r=>i(r.target.checked)}),"Super-admin (full access)"]}),!a&&e.jsxs("div",{children:[e.jsxs("p",{className:"text-[11px] font-medium text-slate-600 mb-1.5",children:["Pages this user can access (",h.size," selected)"]}),_.length===0?e.jsx("p",{className:"text-[11px] text-slate-400",children:"Permission catalog unavailable â reload the page."}):e.jsx("div",{className:"space-y-3 max-h-72 overflow-auto rounded border border-slate-100 p-2",children:_.map(([r,b])=>e.jsxs("div",{children:[e.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-wider text-slate-500",children:r}),e.jsx("div",{className:"mt-1 space-y-1",children:b.map(u=>e.jsxs("label",{className:"flex items-start gap-2 cursor-pointer",children:[e.jsx("input",{type:"checkbox",checked:h.has(u.key),onChange:()=>d(u.key),className:"mt-0.5"}),e.jsxs("span",{className:"text-xs text-slate-800",children:[u.label," ",e.jsxs("span",{className:"text-slate-400 font-mono",children:["(",u.key,")"]})]})]},u.key))})]},r))})]}),e.jsx("button",{disabled:c,onClick:k,className:"rounded bg-slate-900 text-white text-xs px-3 py-1",children:"Save admin access"}),g&&e.jsx("p",{className:"text-[11px] text-slate-500",children:g})]})}function T({row:s,onChanged:o}){const t=s.kinds.includes("exec")?"exec":"admin",a=t==="exec"?s.exec_id:s.admin_id,[i,h]=n.useState(!1),p=async()=>{h(!0);try{if(s.active){const c=t==="exec"&&window.confirm(`Deactivate this user. 2 3OK = also remove their Odoo role tags (revoke capability in Odoo too). 4Cancel = deactivate in-app only.`);await N.accessDeactivate({kind:t,id:a,remove_tags:c})}else await N.accessActivate({kind:t,id:a});await o()}catch(c){alert(c.detail||c.message)}finally{h(!1)}};return e.jsx("button",{disabled:i,onClick:p,className:`text-xs px-3 py-1 rounded-lg border ${s.active?"border-red-200 text-red-600":"border-emerald-200 text-emerald-600"}`,children:s.active?"Deactivate":"Reactivate"})}function E({onClose:s,onAdded:o}){const[t,a]=n.useState(""),[i,h]=n.useState([]),[p,c]=n.useState(!1),[y,g]=n.useState(null),l=async()=>{c(!0),g(null);try{const m=await N.accessFindContacts(t);h(m.results||[]),(m.results||[]).length||g("No Odoo contacts matched.")}catch(m){g(m.detail||m.message)}finally{c(!1)}},x=async m=>{c(!0);try{await N.accessProvisionExec({odoo_partner_id:m.id,display_name:m.name}),await o(),s()}catch(j){g(j.detail||j.message)}finally{c(!1)}};return e.jsx("div",{className:"fixed inset-0 bg-black/30 flex items-start justify-center p-4 z-50",children:e.jsxs("div",{className:"bg-white rounded-xl w-full max-w-md p-4 space-y-3 mt-20",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("div",{className:"font-semibold text-slate-900",children:"Add user"}),e.jsx("button",{onClick:s,className:"text-slate-400",children:"â"})]}),e.jsx("p",{className:"text-[11px] text-slate-400",children:"Find the person's Odoo contact, then grant roles + key once added."}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("input",{value:t,onChange:m=>a(m.target.value),onKeyDown:m=>m.key==="Enter"&&l(),placeholder:"Name or phoneâ¦",className:"flex-1 rounded border border-slate-200 px-2 py-1 text-sm"}),e.jsx("button",{disabled:p||t.trim().length<3,onClick:l,className:"rounded bg-slate-900 text-white text-xs px-3 disabled:opacity-40",children:"Search"})]}),y&&e.jsx("p",{className:"text-[11px] text-slate-500",children:y}),e.jsx("div",{className:"max-h-64 overflow-auto divide-y divide-slate-100",children:i.map(m=>e.jsxs("div",{className:"flex items-center justify-between py-2",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-sm text-slate-800",children:m.name}),e.jsx("div",{className:"text-[11px] text-slate-400",children:m.phone||m.email||`#${m.id}`})]}),e.jsx("button",{disabled:p,onClick:()=>x(m),className:"text-xs rounded bg-indigo-600 text-white px-3 py-1",children:"Add"})]},m.id))})]})})}function O({on:s,onClick:o,children:t}){return e.jsx("button",{onClick:o,className:`px-3 py-2 -mb-px border-b-2 ${s?"border-slate-900 text-slate-900 font-semibold":"border-transparent text-slate-400"}`,children:t})}function M(){return e.jsx("div",{className:"rounded-xl border border-slate-200 p-8 text-center text-slate-500",children:"Not authorised â super-admin only."})}function B(){const[s,o]=n.useState(null);if(n.useEffect(()=>{N.accessOdooKeyHealth().then(o).catch(()=>{})},[]),!s)return null;if(s.reachable===!1)return e.jsx("p",{className:"text-xs text-slate-600 bg-slate-50 border border-slate-200 rounded-lg px-3 py-2",children:"Odoo could not be read, so API-key expiry could not be checked. This is not a clean bill of health."});const t=(s.rows||[]).filter(a=>a.state&&a.state!=="ok");return t.length?e.jsxs("div",{className:"rounded-lg border border-amber-200 bg-amber-50/70 px-3 py-2",children:[e.jsxs("p",{className:"text-sm font-medium text-amber-900",children:[t.length," Odoo API key",t.length===1?"":"s"," need",t.length===1?"s":""," attention"]}),e.jsx("ul",{className:"mt-1 space-y-0.5",children:t.map(a=>e.jsxs("li",{className:"text-xs text-amber-900",children:[e.jsx("span",{className:"font-semibold",children:a.person})," â ",a.label,typeof a.days_to_expiry=="number"&&a.state==="expiring"?` in ${a.days_to_expiry} days`:"",a.expires_at?e.jsxs("span",{className:"text-amber-700",children:[" ","(",String(a.expires_at).slice(0,10),")"]}):null]},a.credential_id))}),e.jsx("p",{className:"mt-1 text-[11px] text-amber-800",children:"Only the person can mint a replacement â Odoo asks for their password â and they can paste it themselves on the warehouse app's Me tab. An expired key does not fail loudly: the work silently runs as the service account instead of them."})]}):null}export{D 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.