1import{e as F,r as a,bY as T,bc as P,j as e,L as $,A as _,C as O,X as B,ap as Q,B as z,bZ as Z,s as G}from"./index-CK9bD5Q6.js";import{Z as K}from"./zap-DvBjN2Nd.js";import{C as W}from"./camera-DU0-4ouM.js";const M=()=>new Date().toLocaleDateString("en-CA"),X=1600;function q(o){return new Promise((h,p)=>{const m=URL.createObjectURL(o),r=new Image;r.onload=()=>{URL.revokeObjectURL(m);const x=Math.min(1,X/Math.max(r.width,r.height)),c=Math.max(1,Math.round(r.width*x)),l=Math.max(1,Math.round(r.height*x)),i=document.createElement("canvas");i.width=c,i.height=l;const u=i.getContext("2d");if(!u){p(new Error("no canvas"));return}u.drawImage(r,0,0,c,l),h(i.toDataURL("image/jpeg",.82))},r.onerror=()=>{URL.revokeObjectURL(m),p(new Error("bad image"))},r.src=m})}const k="w-full rounded-xl border border-line bg-surface px-4 py-3.5 text-base font-light text-ink outline-none focus:border-cyan/40";function te(){const o=F(),[h,p]=a.useState("expense"),[m,r]=a.useState([]),[x,c]=a.useState([]),[l,i]=a.useState(null);a.useEffect(()=>{document.title="Snap â LiqLab"},[]),a.useEffect(()=>{o!=null&&o.isAdmin&&(T().then(n=>n.ok&&r((n.data.categories??[]).filter(d=>!d.archived))),P().then(n=>n.ok&&c((n.data.projects??[]).filter(d=>!d.archived))))},[o==null?void 0:o.isAdmin]);const u=n=>{i(n),window.setTimeout(()=>i(null),950)};return o!=null&&o.isAdmin?e.jsxs("main",{className:"mx-auto max-w-md px-5 pb-24 pt-28",children:[e.jsx("style",{children:"@keyframes snap-pop{0%{transform:scale(.4);opacity:0}
160%{transform:scale(1.12)}100%{transform:scale(1);opacity:1}}"}),e.jsxs("p",{className:"eyebrow flex items-center gap-2",children:[e.jsx(K,{size:12})," LIQ Snap · pocket capture"]}),e.jsx("h1",{className:"mt-3 font-display text-3xl font-extralight tracking-wide",children:"Snap it. Keep moving."}),e.jsx("div",{className:"mt-6 grid grid-cols-2 gap-2",children:[["expense","ð¸ Expense"],["task","â Task"]].map(([n,d])=>e.jsx("button",{onClick:()=>p(n),className:`rounded-2xl border py-4 font-mono text-[12px] uppercase tracking-wider transition-colors ${h===n?"border-cyan/40 bg-cyan/10 text-cyan":"border-line text-muted hover:border-line-bright"}`,children:d},n))}),e.jsx("div",{className:"glass mt-4 rounded-2xl border border-line p-5",children:h==="expense"?e.jsx(H,{cats:m,projects:x,onSaved:u}):e.jsx(Y,{projects:x,onSaved:u})}),e.jsx("p",{className:"mt-6 text-center font-mono text-[10px] uppercase tracking-wider text-dim",children:"Tip: Add this page to your home screen â browser menu â Add to Home Screen â for one-tap Snap Expense."}),l&&e.jsxs("div",{className:"fixed inset-0 z-50 flex flex-col items-center justify-center bg-bg/85 backdrop-blur-sm",children:[e.jsx("div",{className:"flex h-24 w-24 items-center justify-center rounded-full border border-emerald-400/40 bg-emerald-400/10 text-emerald-300",style:{animation:"snap-pop .4s cubic-bezier(.2,1.4,.4,1) both"},children:e.jsx(O,{size:44,strokeWidth:1.5})}),e.jsx("p",{className:"mt-5 px-8 text-center font-mono text-[11px] uppercase tracking-wider text-muted",children:l})]})]}):e.jsx("main",{className:"flex min-h-screen items-center justify-center px-5",children:e.jsxs("div",{className:"hairline max-w-sm rounded-[1.6rem] p-10 text-center",children:[e.jsx("p",{className:"eyebrow",children:"LIQ Snap"}),e.jsx("h1",{className:"mt-4 font-display text-2xl font-extralight",children:"Operator only."}),e.jsx("p",{className:"mt-3 text-sm font-light text-muted",children:"LIQ Snap is for the operator's pocket â sign in as admin."}),e.jsxs($,{to:"/account",className:"mt-6 inline-flex items-center gap-2 text-sm text-cyan hover:underline",children:["To the lab door ",e.jsx(_,{size:14})]})]})})}function H({cats:o,projects:h,onSaved:p}){const[m,r]=a.useState(""),[x,c]=a.useState(""),[l,i]=a.useState(null),[u,n]=a.useState(!1),[d,N]=a.useState(!1),[g,s]=a.useState(""),[b,j]=a.useState(""),[w,S]=a.useState(M()),[C,R]=a.useState(!1),[E,v]=a.useState(null),L=a.useRef(null),A=a.useRef(null),I=[...o].sort((t,f)=>t.kind===f.kind?(t.sort??0)-(f.sort??0):t.kind==="expense"?-1:1),D=async t=>{var y;const f=(y=t.target.files)==null?void 0:y[0];if(t.target.value="",!!f){n(!0),v(null);try{i(await q(f))}catch{v("Couldn't read that photo â try again.")}n(!1)}},U=async()=>{var y;const t=Number(m);if(!Number.isFinite(t)||t<=0){v("Enter the amount first.");return}R(!0),v(null);const f=await Z({amount:t,category_id:x||null,occurred_on:w,memo:b.trim(),project_id:g||null,book:"draft",...l?{receiptDataUrl:l}:{}});if(R(!1),!f.ok){v(f.data.error??"Couldn't save â try again.");return}r(""),c(""),i(null),j(""),S(M()),p("In the draft ledger â reconcile later"),(y=L.current)==null||y.focus()};return e.jsxs("div",{children:[e.jsx("p",{className:"font-mono text-[10px] uppercase tracking-wider text-dim",children:"Amount"}),e.jsxs("div",{className:"mt-2 flex items-center rounded-2xl border border-line bg-surface px-5 focus-within:border-cyan/40",children:[e.jsx("span",{className:"text-3xl font-extralight text-dim",children:"$"}),e.jsx("input",{ref:L,value:m,onChange:t=>r(t.target.value),inputMode:"decimal",autoFocus:!0,placeholder:"0.00",className:"w-full bg-transparent py-5 pl-2 text-4xl font-extralight tabular-nums text-ink outline-none placeholder:text-dim"})]}),e.jsx("p",{className:"mt-5 font-mono text-[10px] uppercase tracking-wider text-dim",children:"Category"}),e.jsxs("div",{className:"mt-2 flex flex-wrap gap-2",children:[I.map(t=>e.jsx("button",{onClick:()=>c(x===t.id?"":t.id),className:`rounded-full border px-4 py-2.5 font-mono text-[11px] uppercase tracking-wider transition-colors ${x===t.id?"border-cyan/40 bg-cyan/10 text-cyan":"border-line text-muted hover:border-line-bright"}`,children:t.name},t.id)),I.length===0&&e.jsx("span",{className:"text-[12px] font-light text-dim",children:"No categories yet â that's fine, snap it anyway."})]}),e.jsx("input",{ref:A,type:"file",accept:"image/*",capture:"environment",onChange:t=>void D(t),className:"hidden"}),l?e.jsxs("div",{className:"mt-4 flex items-center gap-3 rounded-xl border border-line bg-surface p-3",children:[e.jsx("img",{src:l,alt:"Receipt",className:"h-20 w-20 rounded-lg border border-line object-cover"}),e.jsx("span",{className:"min-w-0 flex-1 font-mono text-[10px] uppercase tracking-wider text-muted",children:"Receipt attached"}),e.jsx("button",{onClick:()=>i(null),className:"p-2 text-dim hover:text-magenta","aria-label":"Remove receipt",children:e.jsx(B,{size:16})})]}):e.jsxs("button",{onClick:()=>{var t;return(t=A.current)==null?void 0:t.click()},disabled:u,className:"mt-4 flex w-full items-center justify-center gap-2 rounded-xl border border-dashed border-line-bright py-4 font-mono text-[11px] uppercase tracking-wider text-muted transition-colors hover:border-cyan/40 hover:text-cyan disabled:opacity-50",children:[e.jsx(W,{size:15})," ",u?"Shrinkingâ¦":"ð· Snap receipt"]}),e.jsxs("button",{onClick:()=>N(t=>
1!t),className:"mt-4 flex items-center gap-1.5 font-mono text-[10px] uppercase tracking-wider text-dim hover:text-muted",children:[e.jsx(Q,{size:12,className:`transition-transform ${d?"rotate-180":""}`})," More"]}),d&&e.jsxs("div",{className:"mt-3 space-y-2.5",children:[e.jsxs("select",{value:g,onChange:t=>s(t.target.value),className:k,children:[e.jsx("option",{value:"",children:"â no project â"}),h.map(t=>e.jsx("option",{value:t.id,children:t.name},t.id))]}),e.jsx("input",{value:b,onChange:t=>j(t.target.value),placeholder:"Memo (optional)",className:k}),e.jsx("input",{type:"date",value:w,onChange:t=>S(t.target.value),className:k})]}),E&&e.jsx("p",{className:"mt-3 text-[12px] font-light text-magenta",children:E}),e.jsx(z,{size:"lg",className:"mt-5 w-full",onClick:()=>void U(),disabled:C,children:C?"Savingâ¦":"Save to draft ledger"}),e.jsx("p",{className:"mt-3 text-center font-mono text-[9px] uppercase tracking-wider text-dim",children:"Draft book by design â reconcile to official on desktop"})]})}function Y({projects:o,onSaved:h}){const[p,m]=a.useState(""),[r,x]=a.useState(""),[c,l]=a.useState(""),[i,u]=a.useState(!1),[n,d]=a.useState(null),N=a.useRef(null),g=async()=>{var j;const s=p.trim();if(s.length<2){d("Give it a title first.");return}u(!0),d(null);const b=await G({kind:"task",title:s,status:"backlog",project_id:r||null,...c?{assignee:c,assignee_kind:c==="arthur"?"human":"agent"}:{}});if(u(!1),!b.ok){d(b.data.error??"Couldn't save â try again.");return}m(""),l(""),h("On the board â backlog"),(j=N.current)==null||j.focus()};return e.jsxs("div",{children:[e.jsx("p",{className:"font-mono text-[10px] uppercase tracking-wider text-dim",children:"Task"}),e.jsx("input",{ref:N,value:p,onChange:s=>m(s.target.value),onKeyDown:s=>{s.key==="Enter"&&g()},autoFocus:!0,placeholder:"What needs doing?",className:`mt-2 ${k} py-4 text-lg`}),e.jsx("p",{className:"mt-5 font-mono text-[10px] uppercase tracking-wider text-dim",children:"Assign"}),e.jsx("div",{className:"mt-2 flex gap-2",children:["arthur","claude"].map(s=>e.jsx("button",{onClick:()=>l(c===s?"":s),className:`flex-1 rounded-full border py-3 font-mono text-[11px] uppercase tracking-wider transition-colors ${c===s?"border-cyan/40 bg-cyan/10 text-cyan":"border-line text-muted hover:border-line-bright"}`,children:s},s))}),e.jsx("p",{className:"mt-5 font-mono text-[10px] uppercase tracking-wider text-dim",children:"Project (optional)"}),e.jsxs("select",{value:r,onChange:s=>x(s.target.value),className:`mt-2 ${k}`,children:[e.jsx("option",{value:"",children:"â no project â"}),o.map(s=>e.jsx("option",{value:s.id,children:s.name},s.id))]}),n&&e.jsx("p",{className:"mt-3 text-[12px] font-light text-magenta",children:n}),e.jsx(z,{size:"lg",className:"mt-5 w-full",onClick:()=>void g(),disabled:i,children:i?"Savingâ¦":"Save task"})]})}export{te 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.