@atyaio/ledgr-web 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/assets/badge-BTiDEJlh.js +55 -0
  2. package/dist/assets/breakdown-D9nBrbad.js +1 -0
  3. package/dist/assets/categories-B7jajln6.js +1 -0
  4. package/dist/assets/color-picker-DLlr-Cq6.js +1 -0
  5. package/dist/assets/custom-cell-Wgh3D7lb.js +1 -0
  6. package/dist/assets/data-DLjPdfYn.js +1 -0
  7. package/dist/assets/download-CIyMPSgr.js +1 -0
  8. package/dist/assets/expenses-DglPf9Hj.js +1 -0
  9. package/dist/assets/format-GDcQVAp4.js +1 -0
  10. package/dist/assets/index-B3RS60Xw.css +2 -0
  11. package/dist/assets/index-DOwVPfdT.js +31 -0
  12. package/dist/assets/insights-C_lA_1Ig.js +1 -0
  13. package/dist/assets/integrations-C4NPnoJ4.js +1 -0
  14. package/dist/assets/ledger-toolbar-yj0u4-Rm.js +1 -0
  15. package/dist/assets/media-Cr7juL5w.js +1 -0
  16. package/dist/assets/menu-BDGd2JUq.js +1 -0
  17. package/dist/assets/money-Ch2MLu6J.js +1 -0
  18. package/dist/assets/money-input-C8ZuBxvX.js +1 -0
  19. package/dist/assets/overview-Ddn6RbvU.js +1 -0
  20. package/dist/assets/payments-q8beCPp-.js +1 -0
  21. package/dist/assets/project-Bgpq3nFR.js +1 -0
  22. package/dist/assets/pull-shift-sheet-DTwTC0rg.js +1 -0
  23. package/dist/assets/queries-IGiwF8nF.js +1 -0
  24. package/dist/assets/recurring-xqowgQWt.js +1 -0
  25. package/dist/assets/revenue-CB8ggUDa.js +1 -0
  26. package/dist/assets/search-jkqZqVJy.js +1 -0
  27. package/dist/assets/settings-DJ670Ax6.js +4 -0
  28. package/dist/assets/shift-sales-B0yokKuf.js +1 -0
  29. package/dist/assets/stakeholders-wioC2mrf.js +1 -0
  30. package/dist/assets/star-cwF2fEe6.js +1 -0
  31. package/dist/assets/table-DQsx5_iN.js +1 -0
  32. package/dist/assets/tooltip-CKyX36D7.js +55 -0
  33. package/dist/favicon.svg +1 -0
  34. package/dist/icons/add-expense-96.png +0 -0
  35. package/dist/icons/add-expense.svg +1 -0
  36. package/dist/icons/add-revenue-96.png +0 -0
  37. package/dist/icons/add-revenue.svg +1 -0
  38. package/dist/icons/apple-touch-icon.png +0 -0
  39. package/dist/icons/icon-192.png +0 -0
  40. package/dist/icons/icon-512.png +0 -0
  41. package/dist/icons/icon.svg +1 -0
  42. package/dist/icons/maskable-192.png +0 -0
  43. package/dist/icons/maskable-512.png +0 -0
  44. package/dist/icons/maskable.svg +1 -0
  45. package/dist/index.html +39 -0
  46. package/dist/manifest.webmanifest +21 -0
  47. package/package.json +43 -3
  48. package/README.md +0 -3
@@ -0,0 +1 @@
1
+ import{d as e,dt as t,f as n,ft as r,gt as i,h as a,i as o,l as s,o as c,pt as l,s as u,v as d,y as f}from"./badge-BTiDEJlh.js";import{O as p,d as m,i as h,v as g}from"./queries-IGiwF8nF.js";import{n as _}from"./project-Bgpq3nFR.js";import{a as v,c as y,d as b,f as x,h as S,i as C,l as w,m as T,n as E,o as D,p as ee,r as te,s as O,t as k,u as A}from"./tooltip-CKyX36D7.js";import{a as j,i as M,o as N,r as P,s as F}from"./table-DQsx5_iN.js";import{a as I,c as L,t as R}from"./media-Cr7juL5w.js";import{C as z,D as B,_ as V,f as H,h as U,x as ne}from"./index-DOwVPfdT.js";import{r as re,t as W}from"./format-GDcQVAp4.js";import{t as G}from"./money-Ch2MLu6J.js";import{t as K}from"./breakdown-D9nBrbad.js";import{r as q}from"./shift-sales-B0yokKuf.js";var J=i(l()),ie=[`axis`,`item`],ae=(0,J.forwardRef)((e,t)=>J.createElement(C,{chartName:`BarChart`,defaultTooltipEventType:`axis`,validateTooltipEventTypes:ie,tooltipPayloadSearcher:b,categoricalChartProps:e,ref:t})),oe=r(),Y=t();function X({label:e,options:t,value:n,onChange:r,icon:i}){let[s,c]=(0,J.useState)(!1),l=(0,J.useRef)(null),u=(0,J.useRef)(null),[f,p]=(0,J.useState)(null),m=R(),{t:h}=d(),g=t.filter(e=>n.includes(e.id));(0,J.useEffect)(()=>{if(!s)return;let e=()=>{let e=l.current?.getBoundingClientRect();e&&p({top:e.bottom+6,left:Math.min(e.left,window.innerWidth-280)})};e();let t=e=>{let t=e.target;!l.current?.contains(t)&&!u.current?.contains(t)&&c(!1)},n=e=>e.key===`Escape`&&c(!1);return document.addEventListener(`mousedown`,t),document.addEventListener(`keydown`,n),window.addEventListener(`resize`,e),()=>{document.removeEventListener(`mousedown`,t),document.removeEventListener(`keydown`,n),window.removeEventListener(`resize`,e)}},[s]);let _=e=>r(n.includes(e)?n.filter(t=>t!==e):[...n,e]),v=g.length===0?h(`All`):g.length===1?g[0].label:h(`{n} selected`,{n:g.length}),y=(0,Y.jsxs)(`ul`,{className:`max-h-[320px] overflow-y-auto py-1`,children:[t.map(e=>{let t=n.includes(e.id);return(0,Y.jsx)(`li`,{children:(0,Y.jsxs)(`button`,{type:`button`,onClick:()=>_(e.id),className:`w-full flex items-center gap-2.5 px-3 h-10 md:h-9 text-start text-[14px] md:text-[13.5px] hover:bg-card-hover`,children:[(0,Y.jsx)(`span`,{className:a(`size-[18px] rounded-[5px] border inline-flex items-center justify-center shrink-0`,t?`bg-accent border-accent text-white`:`border-line-strong`),children:t&&(0,Y.jsx)(z,{className:`size-3`})}),e.color&&(0,Y.jsx)(o,{color:e.color}),(0,Y.jsx)(`span`,{className:`flex-1 truncate`,children:e.label}),e.hint&&(0,Y.jsx)(`span`,{className:`text-[12px] text-ink-3`,children:e.hint})]})},e.id)}),!t.length&&(0,Y.jsx)(`li`,{className:`px-3 py-3 text-[13px] text-ink-3`,children:h(`Nothing to filter by yet.`)})]});return(0,Y.jsxs)(`div`,{ref:l,className:`relative inline-block`,children:[(0,Y.jsxs)(`button`,{type:`button`,onClick:()=>c(e=>!e),className:a(`h-9 ps-3 pe-2 inline-flex items-center gap-1.5 rounded-full border text-[13.5px] font-medium whitespace-nowrap`,g.length?`bg-primary text-primary-ink border-primary`:`bg-card border-line text-ink-2 hover:text-ink`),children:[i,(0,Y.jsxs)(`span`,{className:`opacity-70`,children:[e,`:`]}),` `,v,g.length?(0,Y.jsx)(`span`,{role:`button`,"aria-label":h(`Clear {label}`,{label:e}),onClick:e=>{e.stopPropagation(),r([])},className:`ms-0.5 inline-flex size-5 items-center justify-center rounded-full hover:bg-white/20`,children:(0,Y.jsx)(L,{className:`size-3.5`})}):(0,Y.jsx)(F,{className:`size-4 opacity-70`})]}),s&&(0,oe.createPortal)(m?(0,Y.jsxs)(`div`,{className:`fixed inset-0 z-50 flex items-end`,children:[(0,Y.jsx)(`div`,{className:`absolute inset-0 bg-black/40`,onClick:()=>c(!1)}),(0,Y.jsxs)(`div`,{ref:u,className:`relative w-full bg-card rounded-t-[24px] pb-[max(12px,var(--safe-bottom))] shadow-2xl`,children:[(0,Y.jsx)(`div`,{className:`mx-auto mt-2.5 h-1.5 w-10 rounded-full bg-line-strong`}),(0,Y.jsx)(`div`,{className:`px-4 pt-3 pb-1 text-[15px] font-semibold`,children:e}),y]})]}):(0,Y.jsx)(`div`,{ref:u,style:{position:`fixed`,top:f?.top??0,left:f?.left??0,zIndex:60,visibility:f?`visible`:`hidden`},className:`w-[270px] card shadow-[var(--shadow-pop)]`,children:y}),document.body)]})}var se=[{id:`both`,label:`Both`},{id:`revenue`,label:`Revenue`},{id:`expenses`,label:`Expenses`}];function ce(){let{t,name:r}=d(),{range:i}=H(),[a,o]=B(),c=a.get(`ledger`)||`both`,l=(a.get(`cats`)??``).split(`,`).filter(Boolean),f=(a.get(`methods`)??``).split(`,`).filter(Boolean),_=a.get(`partner`)??``,v=a.get(`g`)??``,y=e=>o(t=>{let n=new URLSearchParams(t);for(let[t,r]of Object.entries(e))r?n.set(t,r):n.delete(t);return n},{replace:!0}),b=h(void 0,!1),x=g(),S=p(),C=m((0,J.useMemo)(()=>({from:i.from,to:i.to,ledger:c,categoryIds:l.join(`,`)||void 0,paymentMethodIds:f.join(`,`)||void 0,stakeholderId:_||void 0,granularity:v||void 0}),[i,c,l.join(`,`),f.join(`,`),_,v])),w=(0,J.useMemo)(()=>(b.data?.items??[]).filter(e=>c===`both`||e.kind===(c===`revenue`?`revenue`:`expense`)).map(e=>({id:e.id,label:r(e),color:e.color,hint:t(e.kind)})),[b.data,c,r,t]),T=(0,J.useMemo)(()=>(x.data?.items??[]).map(e=>({id:e.id,label:r(e),color:e.color})),[x.data,r]);return(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(e,{title:t(`Insights`),subtitle:t(`Slice the ledger by category, payment method and partner, compared with the previous period.`)}),(0,Y.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap mb-4`,children:[(0,Y.jsx)(n,{value:c,onChange:e=>y({ledger:e===`both`?null:e,cats:null}),items:se.map(e=>({id:e.id,label:t(e.label)}))}),(0,Y.jsx)(X,{label:t(`Categories`),icon:(0,Y.jsx)(V,{className:`size-4`}),options:w,value:l,onChange:e=>y({cats:e.join(`,`)||null})}),(0,Y.jsx)(X,{label:t(`Payment`),icon:(0,Y.jsx)(ne,{className:`size-4`}),options:T,value:f,onChange:e=>y({methods:e.join(`,`)||null})}),(0,Y.jsxs)(`div`,{className:`inline-flex items-center gap-1.5 h-9 ps-3 pe-1 rounded-full border border-line bg-card text-[13.5px] text-ink-2`,children:[(0,Y.jsx)(U,{className:`size-4`}),(0,Y.jsxs)(I,{compact:!0,className:`h-7 border-0 bg-transparent ps-1 pe-7 w-[150px] rounded-full`,value:_,onChange:e=>y({partner:e.target.value||null}),children:[(0,Y.jsx)(`option`,{value:``,children:t(`Partner: all`)}),S.data?.items.map(e=>(0,Y.jsx)(`option`,{value:e.id,children:r(e)},e.id))]})]}),(0,Y.jsx)(`div`,{className:`flex-1`}),(0,Y.jsx)(n,{size:`xs`,value:v||`auto`,onChange:e=>y({g:e===`auto`?null:e}),items:[{id:`auto`,label:t(`Auto`)},{id:`day`,label:t(`Day`)},{id:`week`,label:t(`Week`)},{id:`month`,label:t(`Month`)}]})]}),C.isPending&&(0,Y.jsx)(s,{label:t(`Slicing the ledger`)}),C.isError&&(0,Y.jsx)(u,{title:t(`Could not load insights`),description:C.error.message}),C.data&&(0,Y.jsx)(le,{d:C.data,ledger:c,filtered:!!(l.length||f.length||_)})]})}function Z({value:e,invert:t}){let{t:n}=d();if(e===null||!Number.isFinite(e))return(0,Y.jsx)(`span`,{className:`text-ink-3 text-[12px]`,children:n(`no previous period`)});Math.abs(e)<.05&&(e=0);let r=e>0,i=t?!r:r,o=e===0?ee:r?T:S;return(0,Y.jsxs)(`span`,{className:a(`inline-flex items-center gap-0.5 text-[12px] font-medium`,e===0?`text-ink-3`:i?`text-good`:`text-critical`),children:[(0,Y.jsx)(o,{className:`size-3.5`}),re(e,1),` `,(0,Y.jsx)(`span`,{className:`font-normal text-ink-3`,children:n(`vs previous`)})]})}function le({d:e,ledger:t,filtered:n}){let{t:r,lang:i}=d(),{money:s,date:l}=_(),f=t!==`expenses`,p=t!==`revenue`,m=e.totals;return(0,Y.jsxs)(`div`,{className:a(`space-y-4`,n&&`fade-up`),children:[(0,Y.jsxs)(`div`,{className:`grid grid-cols-2 md:grid-cols-4 gap-3`,children:[f&&(0,Y.jsx)(Q,{label:r(`Revenue`),value:s(m.revenueMinor),sub:(0,Y.jsx)(Z,{value:e.delta.revenuePct}),extra:r(`{n} entries · avg {avg}`,{n:m.revenueCount,avg:s(m.avgRevenuePerEntryMinor,{compact:!0})})}),p&&(0,Y.jsx)(Q,{label:r(`Expenses`),value:s(m.expenseMinor),sub:(0,Y.jsx)(Z,{value:e.delta.expensePct,invert:!0}),extra:r(`{n} entries · avg {avg}`,{n:m.expenseCount,avg:s(m.avgExpensePerEntryMinor,{compact:!0})})}),f&&p&&(0,Y.jsx)(Q,{label:r(`Net`),value:s(m.netMinor,{signed:!0}),tone:m.netMinor<0?`bad`:void 0,sub:(0,Y.jsx)(Z,{value:e.delta.netPct}),extra:m.marginPct===null?r(`no revenue`):r(`margin {pct}`,{pct:W(m.marginPct,1)})}),f?(0,Y.jsx)(Q,{label:r(`Per day`),value:s(m.avgRevenuePerDayMinor),sub:(0,Y.jsx)(`span`,{className:`text-[12px] text-ink-3`,children:r(`{active} of {days} days active`,{active:m.activeDays,days:e.range.days})}),extra:m.bestDay?r(`best {date} · {amount}`,{date:l(m.bestDay.date,`short`),amount:s(m.bestDay.revenueMinor,{compact:!0})}):void 0}):(0,Y.jsx)(Q,{label:r(`Per day`),value:s(m.avgExpensePerDayMinor),sub:(0,Y.jsx)(`span`,{className:`text-[12px] text-ink-3`,children:r(`{active} of {days} days active`,{active:m.activeDays,days:e.range.days})})})]}),(0,Y.jsx)(c,{title:r(`Trend`),subtitle:r(`By {granularity} · dotted line is the previous period ({from} – {to})`,{granularity:r(e.range.granularity),from:l(e.range.previousFrom,`short`),to:l(e.range.previousTo)}),children:(0,Y.jsx)(`div`,{className:`h-[280px]`,children:(0,Y.jsx)(de,{d:e,showRev:f,showExp:p})})}),(0,Y.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4`,children:[f&&(0,Y.jsx)(c,{title:r(`Revenue by category`),children:(0,Y.jsx)(K,{items:e.revenueByCategory.map(e=>({id:e.id,name:e.name,nameAr:e.nameAr,color:e.color,amountMinor:e.revenueMinor,pct:e.pct,count:e.count})),emptyLabel:r(`No revenue`)})}),p&&(0,Y.jsx)(c,{title:r(`Expenses by category`),children:(0,Y.jsx)(K,{items:e.expensesByCategory.map(e=>({id:e.id,name:e.name,nameAr:e.nameAr,color:e.color,amountMinor:e.expenseMinor,pct:e.pct,count:e.count})),emptyLabel:r(`No expenses`)})}),(0,Y.jsx)(c,{title:r(`By payment method`),subtitle:f&&p?r(`Revenue and expenses combined`):void 0,children:(0,Y.jsx)($,{groups:e.byPaymentMethod,showRev:f,showExp:p})}),(0,Y.jsx)(c,{title:r(`By partner`),subtitle:r(`Received by / paid by`),children:(0,Y.jsx)($,{groups:e.byStakeholder,showRev:f,showExp:p})}),(0,Y.jsx)(c,{title:r(`Weekday pattern`),subtitle:r(`Average per day of the week`),className:a(f&&p&&`xl:col-span-2`),children:(0,Y.jsx)(`div`,{className:`h-[220px]`,children:(0,Y.jsx)(fe,{d:e,showRev:f,showExp:p})})})]}),f&&e.posSales&&(0,Y.jsx)(ue,{s:e.posSales}),(0,Y.jsxs)(`div`,{className:`grid grid-cols-1 xl:grid-cols-3 gap-4`,children:[(0,Y.jsx)(c,{className:`xl:col-span-2`,title:r(`Month by month`),flush:!0,children:(0,Y.jsxs)(P,{children:[(0,Y.jsx)(`thead`,{children:(0,Y.jsxs)(`tr`,{children:[(0,Y.jsx)(j,{children:r(`Month`)}),f&&(0,Y.jsx)(j,{align:`right`,children:r(`Revenue`)}),p&&(0,Y.jsx)(j,{align:`right`,children:r(`Expenses`)}),f&&p&&(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(j,{align:`right`,children:r(`Net`)}),(0,Y.jsx)(j,{align:`right`,children:r(`Margin`)})]}),(0,Y.jsx)(j,{align:`right`,children:r(`Entries`)})]})}),(0,Y.jsx)(`tbody`,{children:e.byMonth.map(e=>(0,Y.jsxs)(N,{children:[(0,Y.jsx)(M,{className:`font-medium`,children:new Intl.DateTimeFormat(void 0,{month:`long`,year:`numeric`,timeZone:`UTC`}).format(new Date(`${e.month}-01T00:00:00Z`))}),f&&(0,Y.jsx)(M,{align:`right`,children:(0,Y.jsx)(G,{minor:e.revenueMinor})}),p&&(0,Y.jsx)(M,{align:`right`,children:(0,Y.jsx)(G,{minor:e.expenseMinor})}),f&&p&&(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(M,{align:`right`,children:(0,Y.jsx)(G,{minor:e.netMinor,tone:`flow`,signed:!0})}),(0,Y.jsx)(M,{align:`right`,className:`num text-ink-2`,children:e.marginPct===null?`—`:W(e.marginPct,0)})]}),(0,Y.jsx)(M,{align:`right`,className:`num text-ink-2`,children:(f?e.revenueCount:0)+(p?e.expenseCount:0)})]},e.month))})]})}),(0,Y.jsx)(c,{title:r(f?`Largest revenue`:`Largest expenses`),flush:!0,children:(0,Y.jsxs)(`ul`,{className:`divide-y divide-line`,children:[(f?e.topRevenue:e.topExpenses).slice(0,8).map(e=>(0,Y.jsxs)(`li`,{className:`px-4 md:px-5 py-2.5 flex items-center gap-3`,children:[(0,Y.jsx)(o,{color:e.groupColor,size:9}),(0,Y.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,Y.jsx)(`div`,{dir:`auto`,className:`text-[14px] font-medium truncate`,children:e.description}),(0,Y.jsxs)(`div`,{className:`text-[12px] text-ink-3`,children:[e.groupNameAr&&i===`ar`?e.groupNameAr:r(e.groupName),` · `,l(e.date)]})]}),(0,Y.jsx)(G,{minor:e.amountMinor,className:`font-semibold`})]},e.id)),!(f?e.topRevenue:e.topExpenses).length&&(0,Y.jsx)(`li`,{children:(0,Y.jsx)(u,{title:r(`Nothing here`)})})]})})]})]})}function ue({s:e}){let{t}=d(),{money:n,locale:r}=_(),i=e.netMinor>0&&e.costMinor>0?(e.netMinor-e.costMinor)/e.netMinor*100:null;return(0,Y.jsxs)(`div`,{className:`grid grid-cols-1 xl:grid-cols-3 gap-4`,children:[(0,Y.jsx)(c,{className:`xl:col-span-2`,title:t(`Best sellers`),subtitle:t(`From {n} Loyverse shifts in this range · {qty} items · {amount} net`,{n:e.shifts,qty:q(e.quantity,r),amount:n(e.netMinor,{compact:!0})}),flush:!0,children:(0,Y.jsxs)(P,{children:[(0,Y.jsx)(`thead`,{children:(0,Y.jsxs)(`tr`,{children:[(0,Y.jsx)(j,{children:t(`Item`)}),(0,Y.jsx)(j,{children:t(`Category`)}),(0,Y.jsx)(j,{align:`right`,children:t(`Qty`)}),(0,Y.jsx)(j,{align:`right`,children:t(`Net sales`)}),(0,Y.jsx)(j,{align:`right`,children:t(`Share`)})]})}),(0,Y.jsx)(`tbody`,{children:e.byItem.map(e=>(0,Y.jsxs)(N,{children:[(0,Y.jsx)(M,{children:(0,Y.jsxs)(`div`,{dir:`auto`,className:`font-medium truncate max-w-[320px]`,children:[e.itemName,e.variantName?(0,Y.jsxs)(`span`,{className:`text-ink-3 font-normal`,children:[` · `,e.variantName]}):null]})}),(0,Y.jsx)(M,{className:`text-ink-2 text-[13px]`,children:e.categoryName??(0,Y.jsx)(`span`,{className:`text-ink-4`,children:`—`})}),(0,Y.jsx)(M,{align:`right`,className:`num text-ink-2`,children:q(e.quantity,r)}),(0,Y.jsx)(M,{align:`right`,children:(0,Y.jsx)(G,{minor:e.netMinor,className:`font-medium`})}),(0,Y.jsx)(M,{align:`right`,className:`num text-ink-2`,children:W(e.pct,0)})]},`${e.itemName}|${e.variantName??``}`))})]})}),(0,Y.jsx)(c,{title:t(`Sales by category`),subtitle:i===null?void 0:t(`gross margin {pct} after item costs`,{pct:W(i,0)}),children:(0,Y.jsx)(K,{items:e.byCategory.map((e,n)=>({id:e.name||null,name:e.name||t(`Uncategorised`),color:f[n%f.length],amountMinor:e.netMinor,pct:e.pct,count:Math.round(e.quantity)})),emptyLabel:t(`No sales`)})})]})}function Q({label:e,value:t,sub:n,extra:r,tone:i}){return(0,Y.jsxs)(`div`,{className:`card p-4`,children:[(0,Y.jsx)(`div`,{className:`label`,children:e}),(0,Y.jsx)(`div`,{className:a(`num text-[22px] md:text-[24px] font-semibold tracking-tight mt-1`,i===`bad`&&`text-critical`),children:t}),(0,Y.jsx)(`div`,{className:`mt-1 min-h-[18px]`,children:n}),r&&(0,Y.jsx)(`div`,{className:`text-[12px] text-ink-3 mt-0.5 truncate`,children:r})]})}function $({groups:e,showRev:t,showExp:n}){let{t:r,lang:i}=d(),{money:a}=_();if(!e.length)return(0,Y.jsx)(`div`,{className:`text-[13.5px] text-ink-3 py-8 text-center`,children:r(`Nothing in this range`)});let s=e=>(t?e.revenueMinor:0)+(n?e.expenseMinor:0),c=Math.max(1,...e.map(s));return(0,Y.jsx)(`ul`,{className:`space-y-3`,children:e.map(e=>(0,Y.jsxs)(`li`,{children:[(0,Y.jsxs)(`div`,{className:`flex items-center justify-between text-[13.5px] mb-1.5`,children:[(0,Y.jsxs)(`span`,{className:`inline-flex items-center gap-2 truncate`,children:[(0,Y.jsx)(o,{color:e.color,size:9}),e.nameAr&&i===`ar`?e.nameAr:r(e.name),(0,Y.jsx)(`span`,{className:`num text-[12px] text-ink-3`,children:e.count})]}),(0,Y.jsxs)(`span`,{className:`num font-medium`,children:[a(s(e)),t&&n&&e.revenueMinor&&e.expenseMinor?(0,Y.jsxs)(`span`,{className:`text-ink-3 font-normal text-[12px]`,children:[` · `,r(`in {in} / out {out}`,{in:a(e.revenueMinor,{compact:!0}),out:a(e.expenseMinor,{compact:!0})})]}):null]})]}),(0,Y.jsxs)(`div`,{className:`h-2 rounded-full bg-sunken overflow-hidden flex gap-[2px]`,children:[t&&e.revenueMinor>0&&(0,Y.jsx)(`div`,{className:`h-full rounded-full`,style:{width:`${e.revenueMinor/c*100}%`,background:n?`var(--s-revenue)`:e.color}}),n&&e.expenseMinor>0&&(0,Y.jsx)(`div`,{className:`h-full rounded-full`,style:{width:`${e.expenseMinor/c*100}%`,background:t?`var(--s-expense)`:e.color}})]})]},e.id??`none`))})}function de({d:e,showRev:t,showExp:n}){let{t:r}=d(),{money:i,date:a,toMajor:o,locale:s}=_(),c=e.range.granularity,l=e=>new Intl.NumberFormat(s,{notation:`compact`,maximumFractionDigits:1}).format(o(e)),u=e=>c===`month`?new Intl.DateTimeFormat(s,{month:`short`,year:`2-digit`,timeZone:`UTC`}).format(new Date(`${e}T00:00:00Z`)):a(e,`short`),f=e.series.map(e=>({...e,label:u(e.bucket)})),p=[...t?[{label:r(`Revenue`),color:`var(--s-revenue)`}]:[],...n?[{label:r(`Expenses`),color:`var(--s-expense)`}]:[],{label:r(`Previous period`),color:`var(--ink-3)`,kind:`line`}];return(0,Y.jsxs)(`div`,{className:`h-full flex flex-col`,children:[(0,Y.jsx)(`div`,{className:`pb-2`,children:(0,Y.jsx)(E,{items:p})}),(0,Y.jsx)(`div`,{className:`flex-1 -ms-3`,children:(0,Y.jsx)(x,{width:`100%`,height:`100%`,children:(0,Y.jsxs)(te,{data:f,margin:{top:12,right:12,bottom:0,left:0},barGap:2,barCategoryGap:`28%`,children:[(0,Y.jsx)(w,{vertical:!1,stroke:`var(--line)`}),(0,Y.jsx)(D,{dataKey:`label`,tickLine:!1,axisLine:{stroke:`var(--line)`},tick:{fill:`var(--ink-3)`,fontSize:11},interval:`preserveStartEnd`,minTickGap:28}),(0,Y.jsx)(v,{tickLine:!1,axisLine:!1,tickFormatter:l,width:48,tick:{fill:`var(--ink-3)`,fontSize:11}}),(0,Y.jsx)(A,{cursor:{fill:`var(--card-hover)`,opacity:.8},content:({active:e,payload:o})=>{if(!e||!o?.length)return null;let s=o[0].payload;return(0,Y.jsx)(k,{title:c===`day`?a(s.bucket,`long`):c===`week`?r(`Week of {date}`,{date:a(s.bucket)}):u(s.bucket),rows:[...t?[{label:r(`Revenue`),value:`${i(s.revenueMinor)} · ${s.revenueCount}`,color:`var(--s-revenue)`},{label:r(`Prev. revenue`),value:i(s.prevRevenueMinor)}]:[],...n?[{label:r(`Expenses`),value:`${i(s.expenseMinor)} · ${s.expenseCount}`,color:`var(--s-expense)`},{label:r(`Prev. expenses`),value:i(s.prevExpenseMinor)}]:[]]})}}),t&&(0,Y.jsx)(O,{dataKey:`revenueMinor`,fill:`var(--s-revenue)`,radius:[4,4,0,0],maxBarSize:24,isAnimationActive:!1}),n&&(0,Y.jsx)(O,{dataKey:`expenseMinor`,fill:`var(--s-expense)`,radius:[4,4,0,0],maxBarSize:24,isAnimationActive:!1}),t&&(0,Y.jsx)(y,{type:`monotone`,dataKey:`prevRevenueMinor`,stroke:`var(--s-revenue)`,strokeDasharray:`4 4`,strokeOpacity:.7,strokeWidth:1.5,dot:!1,isAnimationActive:!1}),n&&(0,Y.jsx)(y,{type:`monotone`,dataKey:`prevExpenseMinor`,stroke:`var(--s-expense)`,strokeDasharray:`4 4`,strokeOpacity:.7,strokeWidth:1.5,dot:!1,isAnimationActive:!1})]})})})]})}function fe({d:e,showRev:t,showExp:n}){let{t:r,lang:i}=d(),{money:a,toMajor:o,locale:s}=_(),c=e=>new Intl.NumberFormat(s,{notation:`compact`,maximumFractionDigits:1}).format(o(e)),l=e.byWeekday.map(e=>({...e,full:r(e.label),label:i===`ar`?r(e.label):r(e.label).slice(0,3)}));return(0,Y.jsx)(x,{width:`100%`,height:`100%`,children:(0,Y.jsxs)(ae,{data:l,margin:{top:12,right:8,bottom:0,left:-8},barGap:2,barCategoryGap:`30%`,children:[(0,Y.jsx)(w,{vertical:!1,stroke:`var(--line)`}),(0,Y.jsx)(D,{dataKey:`label`,tickLine:!1,axisLine:{stroke:`var(--line)`},tick:{fill:`var(--ink-3)`,fontSize:11}}),(0,Y.jsx)(v,{tickLine:!1,axisLine:!1,tickFormatter:c,width:48,tick:{fill:`var(--ink-3)`,fontSize:11}}),(0,Y.jsx)(A,{cursor:{fill:`var(--card-hover)`,opacity:.8},content:({active:e,payload:i})=>{if(!e||!i?.length)return null;let o=i[0].payload;return(0,Y.jsx)(k,{title:r(`{day} · {n} days`,{day:o.full,n:o.days}),rows:[...t?[{label:r(`Avg revenue`),value:a(o.avgRevenueMinor),color:`var(--s-revenue)`}]:[],...n?[{label:r(`Avg expenses`),value:a(o.avgExpenseMinor),color:`var(--s-expense)`}]:[]]})}}),t&&(0,Y.jsx)(O,{dataKey:`avgRevenueMinor`,fill:`var(--s-revenue)`,radius:[4,4,0,0],maxBarSize:28,isAnimationActive:!1}),n&&(0,Y.jsx)(O,{dataKey:`avgExpenseMinor`,fill:`var(--s-expense)`,radius:[4,4,0,0],maxBarSize:28,isAnimationActive:!1})]})})}export{ce as InsightsPage};
@@ -0,0 +1 @@
1
+ import{O as e,d as t,dt as n,g as r,gt as i,h as a,i as o,l as s,n as c,o as l,pt as u,s as d,v as f}from"./badge-BTiDEJlh.js";import{f as p,i as m,m as h,p as g,v as _}from"./queries-IGiwF8nF.js";import{n as v}from"./project-Bgpq3nFR.js";import{a as y,i as b,o as x,r as S,t as C}from"./table-DQsx5_iN.js";import{t as w}from"./download-CIyMPSgr.js";import{n as T,t as E}from"./search-jkqZqVJy.js";import{n as D,t as O}from"./pull-shift-sheet-DTwTC0rg.js";import{a as k,i as A,n as j,r as M,s as N,t as P}from"./media-Cr7juL5w.js";import{C as ee,b as F,c as te,d as I,g as ne,l as L,m as R,p as z}from"./index-DOwVPfdT.js";import{n as B}from"./format-GDcQVAp4.js";var V={name:`external-link`,size:24,node:[[`path`,{d:`M15 3h6v6`,key:`1q9fwt`}],[`path`,{d:`M10 14 21 3`,key:`gplh6r`}],[`path`,{d:`M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6`,key:`a6xqqp`}]]};V.node;var H=r(V),U={name:`unplug`,size:24,node:[[`path`,{d:`m19 5 3-3`,key:`yk6iyv`}],[`path`,{d:`m2 22 3-3`,key:`19mgm9`}],[`path`,{d:`M6.3 20.3a2.4 2.4 0 0 0 3.4 0L12 18l-6-6-2.3 2.3a2.4 2.4 0 0 0 0 3.4Z`,key:`goz73y`}],[`path`,{d:`M7.5 13.5 10 11`,key:`7xgeeb`}],[`path`,{d:`M10.5 16.5 13 14`,key:`10btkg`}],[`path`,{d:`m12 6 6 6 2.3-2.3a2.4 2.4 0 0 0 0-3.4l-2.6-2.6a2.4 2.4 0 0 0-3.4 0Z`,key:`1snsnr`}]]};U.node;var W=r(U),G=i(u(),1),K=n(),q=`https://r.loyverse.com/dashboard/#/integrations/tokens`;function J(){let{t:e}=f(),n=p(),[r,i]=(0,G.useState)(!1);return(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(t,{title:e(`Integrations`),subtitle:e(`Pull data from the systems your business already runs on.`)}),n.isPending?(0,K.jsx)(s,{}):n.isError?(0,K.jsx)(d,{title:e(`Could not load integrations`),description:n.error.message}):n.data.connected?(0,K.jsx)(Z,{i:n.data,onReconnect:()=>i(!0)}):(0,K.jsxs)(`div`,{className:`grid grid-cols-1 xl:grid-cols-3 gap-4`,children:[(0,K.jsx)(l,{className:`xl:col-span-2`,children:(0,K.jsxs)(`div`,{className:`flex items-start gap-4 py-2`,children:[(0,K.jsx)(Y,{}),(0,K.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[(0,K.jsx)(`h3`,{className:`text-[17px] font-semibold tracking-tight`,children:`Loyverse`}),(0,K.jsx)(c,{children:e(`Point of sale`)})]}),(0,K.jsx)(`p`,{className:`text-[13.5px] text-ink-2 mt-1 max-w-[52ch]`,children:e(`Keep the item catalogue in sync and turn each closed shift into a revenue row with one tap, cash only by default.`)}),(0,K.jsx)(`div`,{className:`mt-4`,children:(0,K.jsx)(I,{variant:`primary`,icon:(0,K.jsx)(F,{className:`size-4`}),onClick:()=>i(!0),children:e(`Connect Loyverse`)})})]})]})}),(0,K.jsx)(l,{title:e(`How it works`),children:(0,K.jsxs)(`ol`,{className:`text-[13.5px] text-ink-2 space-y-2 list-decimal ps-4`,children:[(0,K.jsx)(`li`,{children:e(`Create an access token in the Loyverse Back Office and paste it here.`)}),(0,K.jsx)(`li`,{children:e(`Sync items to see the catalogue with its categories.`)}),(0,K.jsx)(`li`,{children:e(`On the Revenue page, tap “Pull last shift” after closing the till.`)})]})})]}),(0,K.jsx)(X,{open:r,onClose:()=>i(!1)})]})}function Y(){return(0,K.jsx)(`span`,{className:`size-12 rounded-[14px] bg-[#1e9e6a]/12 text-[#1e9e6a] inline-flex items-center justify-center shrink-0 font-bold text-[18px] tracking-tight select-none`,"aria-hidden":!0,children:`L`})}function X({open:e,onClose:t}){let{t:n}=f(),r=R(),{connect:i}=h(),[a,o]=(0,G.useState)(``);(0,G.useEffect)(()=>{e&&o(``)},[e]);let s=async()=>{try{let e=await i.mutateAsync({accessToken:a.trim()});r.success(n(`Connected to {name}`,{name:e.merchantName??`Loyverse`}),n(`{stores} stores · {types} payment types`,{stores:e.stores.length,types:e.paymentTypes.length})),t()}catch(e){r.error(n(`Could not connect`),z(e))}},c=a.trim().length>=10;return(0,K.jsx)(L,{open:e,onClose:t,title:n(`Connect Loyverse`),description:n(`A personal access token gives ledgr read access to this Loyverse account.`),width:480,footer:(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(I,{variant:`ghost`,size:`md`,onClick:t,children:n(`Cancel`)}),(0,K.jsx)(I,{variant:`primary`,size:`md`,onClick:s,loading:i.isPending,disabled:!c,children:n(`Connect`)})]}),children:(0,K.jsxs)(`form`,{className:`space-y-4`,onSubmit:e=>{e.preventDefault(),c&&s()},children:[(0,K.jsx)(M,{label:n(`Access token`),required:!0,hint:(0,K.jsxs)(`a`,{className:`inline-flex items-center gap-1 text-accent`,href:q,target:`_blank`,rel:`noreferrer`,children:[n(`Back Office → Integrations → Access tokens`),` `,(0,K.jsx)(H,{className:`size-3`})]}),children:(0,K.jsx)(A,{mono:!0,autoFocus:!0,value:a,onChange:e=>o(e.target.value),placeholder:`fMYgxHEYtcyT8cvtvgi1Za5DRs4vArSy…`,autoComplete:`off`,spellCheck:!1})}),(0,K.jsx)(`p`,{className:`text-[12.5px] text-ink-3`,children:n(`The token is stored in this project’s database only. Its currency must match the project currency.`)})]})})}function Z({i:t,onReconnect:n}){let{t:r,name:i}=f(),{locale:o}=v(),s=R(),{syncItems:u,disconnect:d,settings:p}=h(),g=m(`revenue`),y=_(!0),[b,x]=(0,G.useState)(!1),[S,C]=(0,G.useState)(!1),[E,D]=(0,G.useState)(t.settings.storeIds),[A,P]=(0,G.useState)(t.settings.paymentTypeIds),[F,L]=(0,G.useState)(t.settings.methodMap),[V,H]=(0,G.useState)(t.settings.categoryId??``),[U,q]=(0,G.useState)(t.settings.subtractPayouts??!0);(0,G.useEffect)(()=>{D(t.settings.storeIds),P(t.settings.paymentTypeIds),L(t.settings.methodMap),H(t.settings.categoryId??``),q(t.settings.subtractPayouts??!0)},[t.settings]);let J=A.length?A:t.paymentTypes.filter(e).map(e=>e.id),X=JSON.stringify({storeIds:E,typeIds:A,methodMap:F,categoryId:V,subtractPayouts:U})!==JSON.stringify({storeIds:t.settings.storeIds,typeIds:t.settings.paymentTypeIds,methodMap:t.settings.methodMap,categoryId:t.settings.categoryId??``,subtractPayouts:t.settings.subtractPayouts??!0}),Z=async()=>{try{await p.mutateAsync({storeIds:E,paymentTypeIds:J,methodMap:F,categoryId:V||null,subtractPayouts:U}),s.success(r(`Integration settings saved`))}catch(e){s.error(r(`Could not save`),z(e))}},$=(e,t)=>e.includes(t)?e.filter(e=>e!==t):[...e,t],ie=(y.data?.items??[]).filter(e=>!e.archived);return(0,K.jsxs)(`div`,{className:`space-y-4`,children:[t.lastError&&(0,K.jsxs)(`div`,{className:`card px-4 py-3 flex items-start gap-3 border-warning/40`,children:[(0,K.jsx)(ne,{className:`size-5 text-warning shrink-0 mt-0.5`}),(0,K.jsxs)(`div`,{className:`min-w-0 text-[13.5px]`,children:[(0,K.jsx)(`span`,{className:`font-medium`,children:r(`Last Loyverse call failed`)}),(0,K.jsx)(`div`,{className:`text-ink-3 break-words`,children:t.lastError})]})]}),(0,K.jsxs)(`div`,{className:`grid grid-cols-1 xl:grid-cols-3 gap-4`,children:[(0,K.jsx)(l,{className:`xl:col-span-2`,children:(0,K.jsxs)(`div`,{className:`flex items-start gap-4 py-1`,children:[(0,K.jsx)(Y,{}),(0,K.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[(0,K.jsx)(`h3`,{className:`text-[17px] font-semibold tracking-tight truncate`,children:t.merchantName??`Loyverse`}),(0,K.jsxs)(c,{tone:`good`,children:[(0,K.jsx)(ee,{className:`size-3`}),` `,r(`Connected`)]}),t.currency&&(0,K.jsx)(c,{children:t.currency})]}),(0,K.jsxs)(`dl`,{className:`mt-2 grid grid-cols-2 sm:grid-cols-4 gap-x-4 gap-y-1 text-[12.5px]`,children:[(0,K.jsx)(Q,{label:r(`Stores`),value:String(t.stores.length)}),(0,K.jsx)(Q,{label:r(`Items`),value:String(t.itemCount),sub:t.lastItemsSyncAt?r(`synced {when}`,{when:B(t.lastItemsSyncAt,o)}):r(`not synced yet`)}),(0,K.jsx)(Q,{label:r(`Categories`),value:String(t.categoryCount)}),(0,K.jsx)(Q,{label:r(`Shifts pulled`),value:String(t.shiftCount),sub:t.lastShiftPullAt?r(`last {when}`,{when:B(t.lastShiftPullAt,o)}):void 0})]}),(0,K.jsxs)(`div`,{className:`mt-4 flex flex-wrap gap-2`,children:[(0,K.jsx)(I,{variant:`primary`,icon:(0,K.jsx)(T,{className:a(`size-4`,u.isPending&&`animate-spin`)}),loading:u.isPending,onClick:async()=>{try{let e=await u.mutateAsync();s.success(r(`Items synced`),r(`{items} items · {categories} categories{removed}`,{items:e.items,categories:e.categories,removed:e.removed?` · ${r(`{n} removed`,{n:e.removed})}`:``}))}catch(e){s.error(r(`Sync failed`),z(e))}},children:r(`Sync items`)}),(0,K.jsx)(I,{variant:`secondary`,icon:(0,K.jsx)(w,{className:`size-4`}),onClick:()=>C(!0),children:r(`Pull last shift`)}),(0,K.jsx)(I,{variant:`ghost`,onClick:n,children:r(`Replace token`)}),(0,K.jsx)(I,{variant:`ghost`,className:`text-critical`,icon:(0,K.jsx)(W,{className:`size-4`}),onClick:()=>x(!0),children:r(`Disconnect`)})]})]})]})}),(0,K.jsx)(l,{title:r(`Shift pulls`),subtitle:r(`What goes on the revenue row`),actions:X?(0,K.jsx)(I,{size:`xs`,variant:`primary`,loading:p.isPending,onClick:Z,children:r(`Save`)}):void 0,children:(0,K.jsxs)(`div`,{className:`space-y-4`,children:[(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`div`,{className:`label mb-1.5`,children:r(`Payment types to pull`)}),(0,K.jsxs)(`ul`,{className:`space-y-1.5`,children:[t.paymentTypes.map(t=>(0,K.jsxs)(`li`,{className:`flex items-center gap-2`,children:[(0,K.jsx)(j,{label:(0,K.jsxs)(`span`,{dir:`auto`,children:[t.name,` `,(0,K.jsx)(`span`,{className:`text-ink-3 text-[12px]`,children:e(t)?r(`cash`):t.type===`NONINTEGRATEDCARD`?r(`card`):t.type.toLowerCase()})]}),checked:J.includes(t.id),onChange:()=>P($(J,t.id))}),J.includes(t.id)&&(0,K.jsxs)(k,{compact:!0,className:`ms-auto w-[150px]`,value:F[t.id]??``,onChange:e=>L(()=>{let n={...F};return e.target.value?n[t.id]=e.target.value:delete n[t.id],n}),title:r(`ledgr payment method`),children:[(0,K.jsx)(`option`,{value:``,children:r(`→ “{name}” (auto)`,{name:e(t)?r(`Cash`):t.name})}),ie.map(e=>(0,K.jsxs)(`option`,{value:e.id,children:[`→ `,i(e)]},e.id))]})]},t.id)),!t.paymentTypes.length&&(0,K.jsx)(`li`,{className:`text-[13px] text-ink-3`,children:r(`No payment types found in Loyverse.`)})]}),(0,K.jsx)(`p`,{className:`text-[12px] text-ink-3 mt-1.5`,children:r(`Cash-like types are summed into one Cash amount. Unticked types stay in Loyverse (shown on the shift, not added to the ledger).`)})]}),t.stores.length>1&&(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`div`,{className:`label mb-1.5`,children:r(`Stores`)}),(0,K.jsx)(`ul`,{className:`space-y-1.5`,children:t.stores.map(e=>(0,K.jsx)(`li`,{children:(0,K.jsx)(j,{label:e.name,checked:!E.length||E.includes(e.id),onChange:()=>D(E.length?$(E,e.id):t.stores.filter(t=>t.id!==e.id).map(e=>e.id))})},e.id))})]}),(0,K.jsx)(N,{checked:U,onChange:q,label:r(`Subtract cash pay-outs`),description:r(`Money taken out of the drawer during the shift (supplies, petty cash) comes off the cash amount.`)}),(0,K.jsx)(M,{label:r(`Revenue category`),hint:r(`for the shift rows`),children:(0,K.jsxs)(k,{value:V,onChange:e=>H(e.target.value),children:[(0,K.jsx)(`option`,{value:``,children:r(`Default category`)}),(g.data?.items??[]).filter(e=>!e.archived).map(e=>(0,K.jsx)(`option`,{value:e.id,children:i(e)},e.id))]})})]})})]}),(0,K.jsx)(re,{i:t}),(0,K.jsx)(O,{open:S,onClose:()=>C(!1)}),(0,K.jsx)(te,{open:b,onClose:()=>x(!1),loading:d.isPending,title:r(`Disconnect Loyverse?`),description:r(`The token and the cached catalogue are removed. Revenue rows already pulled stay in the ledger.`),onConfirm:async()=>{try{await d.mutateAsync(),x(!1),s.success(r(`Loyverse disconnected`))}catch(e){s.error(r(`Failed`),z(e))}}})]})}function Q({label:e,value:t,sub:n}){return(0,K.jsxs)(`div`,{className:`min-w-0`,children:[(0,K.jsx)(`dt`,{className:`text-ink-3`,children:e}),(0,K.jsxs)(`dd`,{className:`num text-[15px] font-semibold text-ink`,children:[t,n&&(0,K.jsx)(`span`,{className:`block num text-[11.5px] font-normal text-ink-3 truncate`,children:n})]})]})}function re({i:e}){let{t}=f(),{money:n}=v(),r=P(),[i,s]=(0,G.useState)(``),[c,u]=(0,G.useState)(``),[p,m]=(0,G.useState)(``);(0,G.useEffect)(()=>{let e=setTimeout(()=>m(i.trim()),200);return()=>clearTimeout(e)},[i]);let h=g((0,G.useMemo)(()=>({q:p||void 0,categoryId:c||void 0}),[p,c])),_=h.data?.items??[],w=h.data?.categories.filter(e=>!e.deletedAt)??[];return!e.itemCount&&!h.data?.total&&!p&&!c?(0,K.jsx)(l,{flush:!0,children:(0,K.jsx)(d,{icon:(0,K.jsx)(D,{}),title:t(`No items yet`),description:t(`Sync items to see the Loyverse catalogue here with its categories, prices and costs.`)})}):(0,K.jsx)(l,{title:t(`Items`),subtitle:h.data?t(`{n} items in {c} categories`,{n:h.data.total,c:w.length}):void 0,flush:!0,actions:(0,K.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,K.jsxs)(k,{compact:!0,value:c,onChange:e=>u(e.target.value),className:`w-[150px]`,children:[(0,K.jsx)(`option`,{value:``,children:t(`All categories`)}),w.map(e=>(0,K.jsxs)(`option`,{value:e.id,children:[e.name,` (`,e.itemCount,`)`]},e.id)),(0,K.jsx)(`option`,{value:`none`,children:t(`Uncategorised`)})]}),(0,K.jsxs)(`div`,{className:`relative`,children:[(0,K.jsx)(E,{className:`size-4 absolute start-2.5 top-1/2 -translate-y-1/2 text-ink-3 pointer-events-none`}),(0,K.jsx)(A,{compact:!0,value:i,onChange:e=>s(e.target.value),placeholder:t(`Search items`),className:`ps-8 w-[160px] md:w-[220px]`})]})]}),children:r?(0,K.jsxs)(`ul`,{className:`divide-y divide-line`,children:[_.map(e=>(0,K.jsxs)(`li`,{className:`px-4 py-3 flex items-center gap-3`,children:[(0,K.jsx)(o,{color:$(e.category?.color),size:10}),(0,K.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,K.jsx)(`div`,{dir:`auto`,className:`text-[14.5px] font-medium truncate`,children:e.name}),(0,K.jsxs)(`div`,{className:`text-[12.5px] text-ink-3 truncate`,children:[e.category?.name??t(`Uncategorised`),e.sku?` · ${e.sku}`:``,e.variantCount>1?` · ${t(`{n} variants`,{n:e.variantCount})}`:``]})]}),(0,K.jsx)(`div`,{className:`text-end num text-[14px]`,children:e.priceMinor===null?(0,K.jsx)(`span`,{className:`text-ink-4`,children:`—`}):n(e.priceMinor)})]},e.id)),!_.length&&(0,K.jsx)(`li`,{className:`px-4 py-8 text-center text-[13px] text-ink-3`,children:t(`No items match.`)})]}):(0,K.jsxs)(S,{children:[(0,K.jsx)(`thead`,{children:(0,K.jsxs)(`tr`,{children:[(0,K.jsx)(y,{children:t(`Item`)}),(0,K.jsx)(y,{children:t(`Category`)}),(0,K.jsx)(y,{children:t(`SKU`)}),(0,K.jsx)(y,{align:`right`,children:t(`Price`)}),(0,K.jsx)(y,{align:`right`,children:t(`Cost`)}),(0,K.jsx)(y,{align:`right`,children:t(`Margin`)})]})}),(0,K.jsxs)(`tbody`,{children:[h.isPending&&(0,K.jsx)(C,{colSpan:6,children:t(`Loading…`)}),!h.isPending&&!_.length&&(0,K.jsx)(C,{colSpan:6,children:t(`No items match.`)}),_.map(e=>{let r=e.priceMinor&&e.costMinor!==null?(e.priceMinor-e.costMinor)/e.priceMinor*100:null;return(0,K.jsxs)(x,{children:[(0,K.jsxs)(b,{children:[(0,K.jsx)(`div`,{dir:`auto`,className:`font-medium truncate max-w-[360px]`,children:e.name}),e.variantCount>1&&(0,K.jsx)(`div`,{className:`text-[12px] text-ink-3`,children:t(`{n} variants`,{n:e.variantCount})})]}),(0,K.jsx)(b,{children:e.category?(0,K.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 text-[13px] text-ink-2`,children:[(0,K.jsx)(o,{color:$(e.category.color)}),e.category.name]}):(0,K.jsx)(`span`,{className:`text-ink-4`,children:`—`})}),(0,K.jsx)(b,{className:`mono text-[12.5px] text-ink-2`,children:e.sku??(0,K.jsx)(`span`,{className:`text-ink-4`,children:`—`})}),(0,K.jsx)(b,{align:`right`,className:`num`,children:e.priceMinor===null?(0,K.jsx)(`span`,{className:`text-ink-4`,children:`—`}):n(e.priceMinor)}),(0,K.jsx)(b,{align:`right`,className:`num text-ink-2`,children:e.costMinor===null?(0,K.jsx)(`span`,{className:`text-ink-4`,children:`—`}):n(e.costMinor)}),(0,K.jsx)(b,{align:`right`,className:a(`num`,r!==null&&r<0&&`text-critical`),children:r===null?(0,K.jsx)(`span`,{className:`text-ink-4`,children:`—`}):`${Math.round(r)}%`})]},e.id)})]})]})})}function $(e){return e&&{GREY:`#9aa0ab`,RED:`#e5484d`,PINK:`#e93d82`,ORANGE:`#f76b15`,YELLOW:`#f5b400`,GREEN:`#30a46c`,BLUE:`#3e63dd`,PURPLE:`#8e4ec6`}[e.toUpperCase()]||`var(--s-other)`}export{J as IntegrationsPage};
@@ -0,0 +1 @@
1
+ import{dt as e,g as t,gt as n,h as r,pt as i,v as a}from"./badge-BTiDEJlh.js";import{C as o,l as s}from"./queries-IGiwF8nF.js";import{n as c}from"./project-Bgpq3nFR.js";import{t as l}from"./download-CIyMPSgr.js";import{n as u,t as d}from"./menu-BDGd2JUq.js";import{t as f}from"./search-jkqZqVJy.js";import{a as p,c as m,i as h,r as g}from"./media-Cr7juL5w.js";import{t as _}from"./money-input-C8ZuBxvX.js";import{D as v,d as y,l as b,m as x,p as S}from"./index-DOwVPfdT.js";var C={name:`file-spreadsheet`,size:24,node:[[`path`,{d:`M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z`,key:`1oefj6`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}],[`path`,{d:`M8 13h2`,key:`yr2amv`}],[`path`,{d:`M14 13h2`,key:`un5t4a`}],[`path`,{d:`M8 17h2`,key:`2yhykz`}],[`path`,{d:`M14 17h2`,key:`10kma7`}]]};C.node;var w=t(C),T={name:`file-text`,size:24,node:[[`path`,{d:`M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z`,key:`1oefj6`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}],[`path`,{d:`M10 9H8`,key:`b1mrlr`}],[`path`,{d:`M16 13H8`,key:`t4e002`}],[`path`,{d:`M16 17H8`,key:`z1uh3a`}]]};T.node;var E=t(T),D={name:`sliders-horizontal`,size:24,node:[[`path`,{d:`M10 5H3`,key:`1qgfaw`}],[`path`,{d:`M12 19H3`,key:`yhmn1j`}],[`path`,{d:`M14 3v4`,key:`1sua03`}],[`path`,{d:`M16 17v4`,key:`1q0r14`}],[`path`,{d:`M21 12h-9`,key:`1o4lsq`}],[`path`,{d:`M21 19h-5`,key:`1rlt1p`}],[`path`,{d:`M21 5h-7`,key:`1oszz2`}],[`path`,{d:`M8 10v4`,key:`tgpxqk`}],[`path`,{d:`M8 12H3`,key:`a7s4jb`}]]};D.node;var O=t(D),k={name:`square-check-big`,size:24,node:[[`path`,{d:`M21 10.656V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h12.344`,key:`2acyp4`}],[`path`,{d:`m9 11 3 3L22 4`,key:`1pflzl`}]],aliases:[`check-square`]};k.node;var A=t(k),j={name:`square`,size:24,node:[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,key:`afitv7`}]]};j.node;var M=t(j),N=n(i(),1),P=e();function F({target:e,onClose:t}){let{t:n,name:r}=a(),{money:i}=c(),l=o(),u=s(),d=x(),[f,p]=(0,N.useState)(null),m=e?.entry.payments.find(t=>t.paymentMethodId===e.method.id)?.amountMinor??null;if((0,N.useEffect)(()=>p(m),[m,e]),!e)return null;let{entry:h,method:v}=e,C=e.kind===`revenue`?l.setPayment:u.setPayment,w=h.payments.filter(e=>e.paymentMethodId!==v.id).reduce((e,t)=>e+t.amountMinor,0)+(f??0),T=async()=>{try{await C.mutateAsync({id:h.id,paymentMethodId:v.id,amountMinor:f??0}),d.success(n(f?`{method} amount saved`:`{method} amount removed`,{method:r(v)})),t()}catch(e){d.error(n(`Could not save`),S(e))}};return(0,P.jsx)(b,{open:!0,onClose:t,title:n(m?`Edit {method} amount`:`Add {method} amount`,{method:r(v)}),description:h.description,footer:(0,P.jsxs)(P.Fragment,{children:[m!==null&&(0,P.jsx)(y,{variant:`danger`,size:`md`,onClick:()=>p(0),disabled:f===0,children:n(`Clear`)}),(0,P.jsx)(y,{variant:`ghost`,size:`md`,onClick:t,children:n(`Cancel`)}),(0,P.jsx)(y,{variant:`primary`,size:`md`,onClick:T,loading:C.isPending,disabled:f===null||f<0||w<=0,children:n(`Save`)})]}),children:(0,P.jsxs)(`form`,{className:`space-y-3`,onSubmit:e=>{e.preventDefault(),T()},children:[(0,P.jsx)(g,{label:n(`{method} amount`,{method:r(v)}),children:(0,P.jsx)(_,{large:!0,value:f,onChange:p,autoFocus:!0})}),(0,P.jsxs)(`div`,{className:`flex items-center justify-between text-[13px] text-ink-3`,children:[(0,P.jsx)(`span`,{children:n(`New total`)}),(0,P.jsx)(`span`,{className:`num font-semibold text-ink`,children:i(w)})]})]})})}function I(){let[e,t]=v();return{q:e.get(`q`)??``,categoryId:e.get(`categoryId`)??``,stakeholderId:e.get(`stakeholderId`)??``,paymentMethodId:e.get(`paymentMethodId`)??``,sort:e.get(`sort`)??`date`,order:e.get(`order`)??`desc`,page:Number(e.get(`page`)??`1`)||1,set:e=>t(t=>{let n=new URLSearchParams(t);for(let[t,r]of Object.entries(e))r?n.set(t,r):n.delete(t);return`page`in e||n.delete(`page`),n},{replace:!0})}}function L({categories:e,stakeholders:t,stakeholderLabel:n=`Paid by`,paymentMethods:i,onExport:o,extra:s}){let{t:c,name:g}=a(),_=I(),v=[_.categoryId,_.stakeholderId,i?_.paymentMethodId:``].filter(Boolean).length,[b,x]=(0,N.useState)(v>0);return(0,P.jsxs)(`div`,{className:`space-y-2`,children:[(0,P.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,P.jsxs)(`div`,{className:`relative flex-1 md:max-w-[320px]`,children:[(0,P.jsx)(f,{className:`absolute start-3 top-1/2 -translate-y-1/2 size-4 text-ink-3`}),(0,P.jsx)(h,{compact:!0,className:`ps-9 h-10 md:h-9 rounded-full`,placeholder:c(`Search`),value:_.q,onChange:e=>_.set({q:e.target.value||null})}),_.q&&(0,P.jsx)(`button`,{type:`button`,"aria-label":c(`Clear search`),onClick:()=>_.set({q:null}),className:`absolute end-2 top-1/2 -translate-y-1/2 size-6 inline-flex items-center justify-center rounded-full text-ink-3 hover:bg-card-hover`,children:(0,P.jsx)(m,{className:`size-3.5`})})]}),(0,P.jsxs)(`button`,{type:`button`,onClick:()=>x(e=>!e),className:r(`h-10 md:h-9 px-3 inline-flex items-center gap-1.5 rounded-full border text-[13.5px] font-medium`,b||v?`bg-primary text-primary-ink border-primary`:`bg-card border-line text-ink-2 hover:text-ink`),children:[(0,P.jsx)(O,{className:`size-4`}),` `,(0,P.jsx)(`span`,{className:`hidden sm:inline`,children:c(`Filters`)}),v>0&&(0,P.jsx)(`span`,{className:`num text-[12px] opacity-80`,children:v})]}),(0,P.jsx)(`div`,{className:`flex-1 hidden md:block`}),s,o&&(0,P.jsx)(d,{align:`right`,className:`max-md:hidden`,trigger:()=>(0,P.jsx)(y,{size:`sm`,variant:`secondary`,className:`rounded-full`,icon:(0,P.jsx)(l,{className:`size-4`}),children:c(`Export`)}),children:e=>(0,P.jsxs)(P.Fragment,{children:[(0,P.jsx)(u,{icon:(0,P.jsx)(w,{}),onClick:()=>{e(),o(`xlsx`)},children:c(`Excel (.xlsx), with dropdowns`)}),(0,P.jsx)(u,{icon:(0,P.jsx)(E,{}),onClick:()=>{e(),o(`csv`)},children:c(`CSV`)})]})})]}),b&&(0,P.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap fade-up`,children:[(0,P.jsxs)(p,{compact:!0,className:`w-[180px]`,value:_.categoryId,onChange:e=>_.set({categoryId:e.target.value||null}),children:[(0,P.jsx)(`option`,{value:``,children:c(`All categories`)}),e.map(e=>(0,P.jsx)(`option`,{value:e.id,children:g(e)},e.id))]}),(0,P.jsxs)(p,{compact:!0,className:`w-[180px]`,value:_.stakeholderId,onChange:e=>_.set({stakeholderId:e.target.value||null}),children:[(0,P.jsx)(`option`,{value:``,children:c(`{label}: anyone`,{label:c(n)})}),t.map(e=>(0,P.jsx)(`option`,{value:e.id,children:g(e)},e.id))]}),i&&(0,P.jsxs)(p,{compact:!0,className:`w-[180px]`,value:_.paymentMethodId,onChange:e=>_.set({paymentMethodId:e.target.value||null}),children:[(0,P.jsx)(`option`,{value:``,children:c(`All payment methods`)}),i.map(e=>(0,P.jsx)(`option`,{value:e.id,children:g(e)},e.id))]}),v>0&&(0,P.jsx)(y,{size:`xs`,variant:`ghost`,icon:(0,P.jsx)(m,{className:`size-3.5`}),onClick:()=>_.set({categoryId:null,stakeholderId:null,paymentMethodId:null}),children:c(`Clear`)}),o&&(0,P.jsxs)(P.Fragment,{children:[(0,P.jsx)(y,{size:`xs`,variant:`ghost`,className:`md:hidden`,icon:(0,P.jsx)(l,{className:`size-3.5`}),onClick:()=>o(`xlsx`),children:c(`Excel`)}),(0,P.jsx)(y,{size:`xs`,variant:`ghost`,className:`md:hidden`,onClick:()=>o(`csv`),children:c(`CSV`)})]})]})]})}export{A as a,M as i,I as n,F as r,L as t};
@@ -0,0 +1 @@
1
+ import{dt as e,g as t,gt as n,h as r,pt as i}from"./badge-BTiDEJlh.js";var a={name:`x`,size:24,node:[[`path`,{d:`M18 6 6 18`,key:`1bl5f8`}],[`path`,{d:`m6 6 12 12`,key:`d8bk6v`}]]};a.node;var o=t(a),s=n(i(),1),c=e(),l=`w-full bg-card border border-line-strong rounded-[12px] px-3.5 text-ink placeholder:text-ink-3 hover:border-ink-4 focus:border-accent focus:outline-none focus:ring-4 focus:ring-accent/15 transition-colors disabled:opacity-50`,u=(0,s.forwardRef)(function({className:e,mono:t,compact:n,...i},a){return(0,c.jsx)(`input`,{ref:a,className:r(l,n?`h-9 rounded-[10px] text-[13.5px]`:`h-11 md:h-10`,t&&`num`,e),...i})}),d=(0,s.forwardRef)(function({className:e,...t},n){return(0,c.jsx)(`textarea`,{ref:n,className:r(l,`py-2.5 min-h-[76px] resize-y`,e),...t})}),f=(0,s.forwardRef)(function({className:e,children:t,compact:n,...i},a){return(0,c.jsxs)(`div`,{className:`relative`,children:[(0,c.jsx)(`select`,{ref:a,className:r(l,`appearance-none pe-9`,n?`h-9 rounded-[10px] text-[13.5px]`:`h-11 md:h-10`,e),...i,children:t}),(0,c.jsx)(`svg`,{className:`pointer-events-none absolute end-3 top-1/2 -translate-y-1/2 size-4 text-ink-3`,viewBox:`0 0 16 16`,fill:`none`,"aria-hidden":!0,children:(0,c.jsx)(`path`,{d:`M4 6l4 4 4-4`,stroke:`currentColor`,strokeWidth:`1.6`,strokeLinecap:`round`,strokeLinejoin:`round`})})]})});function p({label:e,hint:t,error:n,children:i,className:a,required:o}){return(0,c.jsxs)(`label`,{className:r(`block`,a),children:[(0,c.jsxs)(`span`,{className:`mb-1.5 flex items-baseline justify-between gap-2`,children:[(0,c.jsxs)(`span`,{className:`text-[13px] font-medium text-ink-2`,children:[e,o&&(0,c.jsx)(`span`,{className:`text-critical ms-0.5`,children:`*`})]}),t&&(0,c.jsx)(`span`,{className:`text-[12px] text-ink-3`,children:t})]}),i,n&&(0,c.jsx)(`span`,{className:`mt-1.5 block text-[12.5px] text-critical`,children:n})]})}function m({label:e,className:t,...n}){return(0,c.jsxs)(`label`,{className:r(`inline-flex items-center gap-2.5 cursor-pointer text-[14px] text-ink-2 select-none min-h-[32px]`,t),children:[(0,c.jsx)(`input`,{type:`checkbox`,className:`size-[18px] rounded-[5px] border border-line-strong accent-[var(--accent)]`,...n}),e]})}function h({checked:e,onChange:t,label:n,disabled:i,description:a}){return(0,c.jsxs)(`button`,{type:`button`,role:`switch`,"aria-checked":e,disabled:i,onClick:()=>t(!e),className:`w-full flex items-center justify-between gap-3 text-start text-[14px] text-ink disabled:opacity-50 min-h-[40px]`,children:[(0,c.jsxs)(`span`,{children:[(0,c.jsx)(`span`,{className:`block font-medium`,children:n}),a&&(0,c.jsx)(`span`,{className:`block text-[12.5px] text-ink-3`,children:a})]}),(0,c.jsx)(`span`,{className:r(`relative inline-block h-[26px] w-[44px] shrink-0 rounded-full transition-colors`,e?`bg-accent`:`bg-line-strong`),children:(0,c.jsx)(`span`,{className:r(`absolute top-[3px] size-5 rounded-full bg-white shadow transition-transform`,e?`translate-x-[21px]`:`translate-x-[3px]`)})})]})}function g(e){let[t,n]=(0,s.useState)(()=>typeof window<`u`&&window.matchMedia(e).matches);return(0,s.useEffect)(()=>{let t=window.matchMedia(e),r=()=>n(t.matches);return r(),t.addEventListener(`change`,r),()=>t.removeEventListener(`change`,r)},[e]),t}var _=()=>g(`(max-width: 767px)`);export{f as a,o as c,u as i,m as n,d as o,p as r,h as s,_ as t};
@@ -0,0 +1 @@
1
+ import{dt as e,ft as t,g as n,gt as r,h as i,pt as a}from"./badge-BTiDEJlh.js";import{t as o}from"./media-Cr7juL5w.js";import{T as s,w as c}from"./index-DOwVPfdT.js";var l={name:`ellipsis`,size:24,node:[[`circle`,{cx:`12`,cy:`12`,r:`1`,key:`41hilf`}],[`circle`,{cx:`19`,cy:`12`,r:`1`,key:`1wjl8i`}],[`circle`,{cx:`5`,cy:`12`,r:`1`,key:`1pcz8c`}]],aliases:[`more-horizontal`]};l.node;var u=n(l),d={name:`pencil`,size:24,node:[[`path`,{d:`M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z`,key:`1a8usu`}],[`path`,{d:`m15 5 4 4`,key:`1mk7zo`}]]};d.node;var f=n(d),p={name:`trash`,size:24,node:[[`path`,{d:`M10 11v6`,key:`nco0om`}],[`path`,{d:`M14 11v6`,key:`outv1u`}],[`path`,{d:`M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6`,key:`miytrc`}],[`path`,{d:`M3 6h18`,key:`d0wm0j`}],[`path`,{d:`M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2`,key:`e791ji`}]],aliases:[`trash-2`]};p.node;var m=n(p),h=r(a(),1),g=t(),_=e();function v({trigger:e,children:t,align:n=`right`,className:r,title:a}){let[l,u]=(0,h.useState)(!1),[d,f]=(0,h.useState)(null),p=(0,h.useRef)(null),m=(0,h.useRef)(null),v=o();(0,h.useLayoutEffect)(()=>{if(!l||v)return;let e=()=>{let e=p.current?.getBoundingClientRect();if(!e)return;let t=m.current?.offsetHeight??200,r=e.bottom+t+12>window.innerHeight&&e.top>t+12;f({top:r?e.top-6:e.bottom+6,...n===`right`?{right:Math.max(8,window.innerWidth-e.right)}:{left:Math.max(8,e.left)},up:r})};return e(),window.addEventListener(`resize`,e),window.addEventListener(`scroll`,e,!0),()=>{window.removeEventListener(`resize`,e),window.removeEventListener(`scroll`,e,!0)}},[l,v,n]),(0,h.useEffect)(()=>{if(!l)return;let e=e=>{let t=e.target;!p.current?.contains(t)&&!m.current?.contains(t)&&u(!1)},t=e=>e.key===`Escape`&&u(!1);return v||document.addEventListener(`mousedown`,e),document.addEventListener(`keydown`,t),()=>{document.removeEventListener(`mousedown`,e),document.removeEventListener(`keydown`,t)}},[l,v]);let y=()=>u(!1),b=typeof t==`function`?t(y):t;return(0,_.jsxs)(`div`,{ref:p,className:i(`relative inline-block`,r),children:[(0,_.jsx)(`div`,{onClick:()=>u(e=>!e),children:e(l)}),(0,g.createPortal)((0,_.jsx)(s,{children:l&&(v?(0,_.jsxs)(`div`,{className:`fixed inset-0 z-50 flex items-end`,role:`menu`,children:[(0,_.jsx)(c.div,{className:`absolute inset-0 bg-black/40`,initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},onClick:y}),(0,_.jsxs)(c.div,{ref:m,className:`relative w-full bg-card rounded-t-[24px] p-2 pb-[max(8px,var(--safe-bottom))] shadow-2xl`,initial:{y:`100%`},animate:{y:0},exit:{y:`100%`},transition:{type:`spring`,stiffness:420,damping:40},children:[(0,_.jsx)(`div`,{className:`mx-auto mt-1 mb-2 h-1.5 w-10 rounded-full bg-line-strong`}),a&&(0,_.jsx)(`div`,{className:`px-3 pb-2 text-[13px] text-ink-3 font-medium`,children:a}),b]})]}):(0,_.jsx)(`div`,{ref:m,style:{position:`fixed`,top:d?.top??0,left:d?.left,right:d?.right,transform:d?.up?`translateY(-100%)`:void 0,zIndex:60,visibility:d?`visible`:`hidden`},className:`min-w-[200px] card p-1.5 shadow-[var(--shadow-pop)]`,role:`menu`,children:b}))}),document.body)]})}function y({children:e,onClick:t,danger:n,icon:r,disabled:a}){return(0,_.jsxs)(`button`,{type:`button`,role:`menuitem`,disabled:a,onClick:t,className:i(`w-full flex items-center gap-3 h-11 md:h-9 px-3 rounded-[10px] text-start text-[15px] md:text-[13.5px] hover:bg-card-hover disabled:opacity-40 disabled:pointer-events-none`,n?`text-critical`:`text-ink`),children:[r&&(0,_.jsx)(`span`,{className:`text-ink-3 [&>svg]:size-[18px] md:[&>svg]:size-4`,children:r}),e]})}function b(){return(0,_.jsx)(`div`,{className:`my-1 h-px bg-line`})}export{f as a,m as i,y as n,u as o,b as r,v as t};
@@ -0,0 +1 @@
1
+ import{dt as e,h as t}from"./badge-BTiDEJlh.js";import{n}from"./project-Bgpq3nFR.js";var r=e();function i({minor:e,className:i,tone:a=`neutral`,signed:o,compact:s,muted:c}){let{money:l}=n(),u={signed:o,compact:s};return(0,r.jsx)(`span`,{className:t(`num`,a===`flow`?e>0?`text-good`:e<0?`text-critical`:`text-ink-3`:a===`expense`?`text-expense`:a===`revenue`?`text-revenue`:c?`text-ink-3`:``,i),title:l(e),children:l(e,u)})}export{i as t};
@@ -0,0 +1 @@
1
+ import{M as e,dt as t,gt as n,pt as r}from"./badge-BTiDEJlh.js";import{n as i}from"./project-Bgpq3nFR.js";import{i as a}from"./media-Cr7juL5w.js";var o=n(r(),1),s=t(),c=(0,o.forwardRef)(function({value:t,onChange:n,large:r,className:c,...l},u){let{currency:d,toMajor:f,digits:p}=i(),[m,h]=(0,o.useState)(t===null?``:f(t).toFixed(p));return(0,o.useEffect)(()=>{e(m,d)!==t&&h(t===null?``:f(t).toFixed(p))},[t]),(0,s.jsxs)(`div`,{className:`relative`,dir:`ltr`,children:[(0,s.jsx)(`span`,{className:`absolute start-3.5 top-1/2 -translate-y-1/2 text-ink-3 font-medium pointer-events-none ${r?`text-[16px]`:`text-[13px]`}`,children:d}),(0,s.jsx)(a,{ref:u,mono:!0,inputMode:`decimal`,className:`${r?`ps-16 h-14 text-[26px] font-semibold rounded-[14px]`:`ps-14`} text-end ${c??``}`,value:m,placeholder:`0.00`,onChange:t=>{h(t.target.value),n(e(t.target.value,d))},onBlur:()=>{let t=e(m,d);t!==null&&h(f(t).toFixed(p))},...l})]})});export{c as t};
@@ -0,0 +1 @@
1
+ import{dt as e,h as t,i as n,l as r,o as i,s as a,t as o,u as s,v as c}from"./badge-BTiDEJlh.js";import{g as l}from"./queries-IGiwF8nF.js";import{n as u}from"./project-Bgpq3nFR.js";import{a as d,c as f,f as p,h as m,l as h,m as g,n as _,o as v,p as y,r as b,s as x,t as S,u as C}from"./tooltip-CKyX36D7.js";import{E as w,S as T,d as E,f as D}from"./index-DOwVPfdT.js";import{r as O,t as k}from"./format-GDcQVAp4.js";import{t as A}from"./money-Ch2MLu6J.js";import{t as j}from"./breakdown-D9nBrbad.js";var M=e(),N=[{key:`revenueMinor`,label:`Revenue`,color:`var(--s-revenue)`,kind:`bar`},{key:`expenseMinor`,label:`Expenses`,color:`var(--s-expense)`,kind:`bar`},{key:`netMinor`,label:`Net`,color:`var(--s-net)`,kind:`line`}];function P({series:e,granularity:t}){let{t:n}=c(),{money:r,date:i,toMajor:a,currency:o,locale:s}=u(),l=e=>new Intl.NumberFormat(s,{notation:`compact`,maximumFractionDigits:1}).format(a(e)),m=e=>t===`month`?new Intl.DateTimeFormat(s,{month:`short`,year:`2-digit`,timeZone:`UTC`}).format(new Date(`${e}T00:00:00Z`)):i(e,`short`),g=e.map(e=>({...e,label:m(e.bucket)}));return(0,M.jsxs)(`div`,{className:`h-full flex flex-col`,children:[(0,M.jsxs)(`div`,{className:`flex items-center justify-between pt-1 pb-2`,children:[(0,M.jsx)(_,{items:N.map(e=>({label:n(e.label),color:e.color,kind:e.kind}))}),(0,M.jsxs)(`span`,{className:`label`,children:[o,` · `,n(`by {granularity}`,{granularity:n(t)})]})]}),(0,M.jsx)(`div`,{className:`flex-1 min-h-[220px] -ms-3`,children:(0,M.jsx)(p,{width:`100%`,height:`100%`,children:(0,M.jsxs)(b,{data:g,margin:{top:16,right:12,bottom:0,left:0},barGap:2,barCategoryGap:`28%`,children:[(0,M.jsx)(h,{vertical:!1,stroke:`var(--line)`,strokeWidth:1}),(0,M.jsx)(v,{dataKey:`label`,tickLine:!1,axisLine:{stroke:`var(--line)`},tick:{fill:`var(--ink-3)`,fontSize:11},interval:`preserveStartEnd`,minTickGap:28}),(0,M.jsx)(d,{tickLine:!1,axisLine:!1,tickFormatter:l,width:48,tick:{fill:`var(--ink-3)`,fontSize:11}}),(0,M.jsx)(C,{cursor:{fill:`var(--card-hover)`,opacity:.8},content:({active:e,payload:a})=>{if(!e||!a?.length)return null;let o=a[0].payload;return(0,M.jsx)(S,{title:t===`day`?i(o.bucket,`long`):t===`week`?n(`Week of {date}`,{date:i(o.bucket)}):m(o.bucket),rows:[{label:n(`Revenue`),value:r(o.revenueMinor),color:`var(--s-revenue)`},{label:n(`Expenses`),value:r(o.expenseMinor),color:`var(--s-expense)`},{label:n(`Net`),value:r(o.netMinor,{signed:!0}),color:`var(--s-net)`},{label:n(`Cumulative`),value:r(o.cumulativeNetMinor,{signed:!0})}]})}}),(0,M.jsx)(x,{dataKey:`revenueMinor`,fill:`var(--s-revenue)`,radius:[4,4,0,0],maxBarSize:24,isAnimationActive:!1}),(0,M.jsx)(x,{dataKey:`expenseMinor`,fill:`var(--s-expense)`,radius:[4,4,0,0],maxBarSize:24,isAnimationActive:!1}),(0,M.jsx)(f,{type:`monotone`,dataKey:`netMinor`,stroke:`var(--s-net)`,strokeWidth:2,dot:!1,activeDot:{r:4,stroke:`var(--card)`,strokeWidth:2},isAnimationActive:!1})]})})})]})}function F({values:e,color:t=`var(--s-net)`,width:n=96,height:r=26,baseline:i}){if(e.length<2)return(0,M.jsx)(`svg`,{width:n,height:r,"aria-hidden":!0});let a=Math.min(0,...e),o=Math.max(0,...e)-a||1,s=n/(e.length-1),c=e=>r-(e-a)/o*(r-4)-2,l=e.map((e,t)=>`${t===0?`M`:`L`}${(t*s).toFixed(1)},${c(e).toFixed(1)}`).join(` `),u=e[e.length-1];return(0,M.jsxs)(`svg`,{width:n,height:r,"aria-hidden":!0,className:`overflow-visible`,children:[i&&(0,M.jsx)(`line`,{x1:0,x2:n,y1:c(0),y2:c(0),stroke:`var(--line-strong)`,strokeWidth:1}),(0,M.jsx)(`path`,{d:l,fill:`none`,stroke:t,strokeWidth:1.5,strokeLinejoin:`round`,strokeLinecap:`round`}),(0,M.jsx)(`circle`,{cx:(e.length-1)*s,cy:c(u),r:2.5,fill:t,stroke:`var(--card)`,strokeWidth:1.5})]})}function I(){let{t:e}=c(),{locale:n}=u(),{range:o}=D(),s=l(o.from,o.to);if(s.isPending)return(0,M.jsx)(r,{label:e(`Crunching the numbers`)});if(s.isError)return(0,M.jsx)(a,{title:e(`Could not load analytics`),description:s.error.message});let d=s.data,f=typeof location<`u`?location.search:``;return(0,M.jsxs)(`div`,{className:t(`space-y-4`,s.isFetching&&`opacity-80 transition-opacity`),children:[(0,M.jsx)(R,{o:d}),(0,M.jsxs)(`div`,{className:`grid grid-cols-1 xl:grid-cols-3 gap-4`,children:[(0,M.jsx)(i,{className:`xl:col-span-2 min-h-[320px]`,title:e(`Cashflow`),children:d.series.length?(0,M.jsx)(`div`,{className:`h-[260px]`,children:(0,M.jsx)(P,{series:d.series,granularity:d.range.granularity})}):(0,M.jsx)(a,{title:e(`No entries in this range`)})}),(0,M.jsx)(i,{title:e(`Where the money went`),actions:(0,M.jsxs)(w,{to:{pathname:`/expenses`,search:f},className:`text-[13px] font-medium text-accent inline-flex items-center`,children:[e(`All`),` `,(0,M.jsx)(T,{className:`size-4 rtl-flip`})]}),children:(0,M.jsx)(j,{items:d.expensesByCategory.map(e=>({id:e.categoryId,...e}))})})]}),(0,M.jsxs)(`div`,{className:`grid grid-cols-1 xl:grid-cols-3 gap-4`,children:[(0,M.jsx)(i,{className:`xl:col-span-2`,title:e(`Partners`),subtitle:e(`Balances for this period`),actions:(0,M.jsxs)(w,{to:{pathname:`/stakeholders`,search:`${f?f+`&`:`?`}tab=balances`},className:`text-[13px] font-medium text-accent inline-flex items-center`,children:[e(`Settle up`),` `,(0,M.jsx)(T,{className:`size-4 rtl-flip`})]}),flush:!0,children:(0,M.jsx)(B,{o:d})}),(0,M.jsx)(i,{title:e(`Budgets`),subtitle:d.budgets.length?U(d.range.to,n):void 0,children:(0,M.jsx)(V,{o:d})})]}),(0,M.jsxs)(`div`,{className:`grid grid-cols-1 xl:grid-cols-3 gap-4`,children:[(0,M.jsx)(i,{className:`xl:col-span-2`,title:e(`Largest expenses`),flush:!0,children:(0,M.jsx)(H,{o:d})}),(0,M.jsx)(i,{title:e(`Revenue by category`),children:(0,M.jsx)(j,{items:d.revenueByCategory.map(e=>({id:e.categoryId,...e})),emptyLabel:e(`No revenue in this range`)})})]}),((d.revenueByPaymentMethod??[]).some(e=>e.paymentMethodId)||(d.expensesByPaymentMethod??[]).some(e=>e.paymentMethodId))&&(0,M.jsxs)(`div`,{className:`grid grid-cols-1 xl:grid-cols-3 gap-4`,children:[(0,M.jsx)(i,{title:e(`Revenue by payment method`),subtitle:e(`How customers paid`),actions:(0,M.jsxs)(w,{to:`/payments`,className:`text-[13px] font-medium text-accent inline-flex items-center`,children:[e(`Manage`),` `,(0,M.jsx)(T,{className:`size-4 rtl-flip`})]}),children:(0,M.jsx)(j,{items:(d.revenueByPaymentMethod??[]).map(e=>({id:e.paymentMethodId,...e})),emptyLabel:e(`No revenue in this range`)})}),(0,M.jsx)(i,{title:e(`Expenses by payment method`),subtitle:e(`How you paid`),children:(0,M.jsx)(j,{items:(d.expensesByPaymentMethod??[]).map(e=>({id:e.paymentMethodId,...e})),emptyLabel:e(`No expenses in this range`)})})]})]})}function L({value:e,invert:n}){let{t:r}=c();if(e===null||!Number.isFinite(e))return(0,M.jsx)(`span`,{className:`text-ink-3 text-[12.5px]`,children:r(`no previous period`)});Math.abs(e)<.05&&(e=0);let i=e>0,a=n?!i:i,o=e===0?y:i?g:m;return(0,M.jsxs)(`span`,{className:t(`inline-flex items-center gap-1 text-[12.5px] font-medium`,e===0?`text-ink-3`:a?`text-good`:`text-critical`),children:[(0,M.jsx)(o,{className:`size-3.5`}),` `,O(e,1),` `,(0,M.jsx)(`span`,{className:`text-ink-3 font-normal`,children:r(`vs previous`)})]})}function R({o:e}){let{t:n}=c(),{money:r}=u(),i=e.series.map(e=>e.netMinor);return(0,M.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-3 gap-3 md:gap-4`,children:[(0,M.jsxs)(`div`,{className:`card p-5 md:col-span-1 flex flex-col justify-between gap-4`,children:[(0,M.jsxs)(`div`,{children:[(0,M.jsx)(`div`,{className:`label`,children:n(`Net result`)}),(0,M.jsx)(`div`,{className:t(`num text-[34px] md:text-[36px] font-semibold tracking-[-0.02em] leading-none mt-2`,e.totals.netMinor<0?`text-critical`:`text-ink`),children:r(e.totals.netMinor,{signed:!0})}),(0,M.jsx)(`div`,{className:`mt-2`,children:(0,M.jsx)(L,{value:e.delta.netPct})})]}),(0,M.jsxs)(`div`,{className:`flex items-end justify-between gap-3`,children:[(0,M.jsxs)(`div`,{className:`text-[12.5px] text-ink-3`,children:[n(`Margin`),` `,(0,M.jsx)(`span`,{className:`num text-ink font-medium`,children:e.totals.marginPct===null?`—`:k(e.totals.marginPct,1)})]}),(0,M.jsx)(F,{values:i,width:120,height:32,baseline:!0})]})]}),(0,M.jsxs)(`div`,{className:`grid grid-cols-2 gap-3 md:gap-4 md:col-span-2`,children:[(0,M.jsx)(z,{label:n(`Revenue`),minor:e.totals.revenueMinor,tone:`revenue`,delta:(0,M.jsx)(L,{value:e.delta.revenuePct}),count:n(`{n} entries`,{n:e.totals.revenueCount}),values:e.series.map(e=>e.revenueMinor),color:`var(--s-revenue)`}),(0,M.jsx)(z,{label:n(`Expenses`),minor:e.totals.expenseMinor,tone:`expense`,delta:(0,M.jsx)(L,{value:e.delta.expensePct,invert:!0}),count:n(`{n} entries`,{n:e.totals.expenseCount}),values:e.series.map(e=>e.expenseMinor),color:`var(--s-expense)`})]})]})}function z({label:e,minor:r,delta:i,count:a,values:o,color:s,tone:c}){let{money:l}=u();return(0,M.jsxs)(`div`,{className:`card p-4 md:p-5 flex flex-col justify-between gap-3`,children:[(0,M.jsxs)(`div`,{children:[(0,M.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,M.jsx)(n,{color:s,size:9}),(0,M.jsx)(`span`,{className:`label`,children:e})]}),(0,M.jsx)(`div`,{className:t(`num text-[22px] md:text-[26px] font-semibold tracking-[-0.02em] leading-none mt-2`,`text-ink`),children:l(r)})]}),(0,M.jsxs)(`div`,{className:`flex items-end justify-between gap-2`,children:[(0,M.jsxs)(`div`,{className:`flex flex-col gap-0.5 min-w-0`,children:[i,(0,M.jsx)(`span`,{className:`text-[12px] text-ink-3`,children:a})]}),(0,M.jsx)(`span`,{className:`hidden sm:block`,children:(0,M.jsx)(F,{values:o,color:s,width:80,height:26})})]})]})}function B({o:e}){let{t,name:n}=c(),{money:r}=u();return e.stakeholders.length?(0,M.jsx)(`ul`,{className:`divide-y divide-line`,children:e.stakeholders.map(e=>(0,M.jsxs)(`li`,{className:`px-4 md:px-5 py-3 flex items-center gap-3`,children:[(0,M.jsx)(o,{name:n(e),color:e.color,size:36}),(0,M.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,M.jsxs)(`div`,{className:`text-[14.5px] font-medium truncate`,children:[n(e),` `,(0,M.jsx)(`span`,{className:`num text-[12.5px] text-ink-3 font-normal`,children:k(e.sharePercent,0)})]}),(0,M.jsxs)(`div`,{className:`text-[12.5px] text-ink-3 truncate`,children:[t(`Paid {paid} · share {share}`,{paid:r(e.paidMinor,{compact:!0}),share:r(e.owedMinor,{compact:!0})}),(0,M.jsxs)(`span`,{className:`hidden sm:inline`,children:[` · `,t(`profit`),` `,r(e.profitShareMinor,{compact:!0,signed:!0})]})]})]}),(0,M.jsxs)(`div`,{className:`text-end shrink-0`,children:[(0,M.jsx)(A,{minor:e.netMinor,tone:`flow`,signed:!0,className:`text-[15px] font-semibold block`}),(0,M.jsx)(`span`,{className:`text-[11.5px] text-ink-3`,children:e.netMinor>0?t(`is owed`):e.netMinor<0?t(`owes`):t(`settled`)})]})]},e.id))}):(0,M.jsx)(a,{title:t(`No partners yet`),description:t(`Add stakeholders and their ownership share to start splitting expenses.`),action:(0,M.jsx)(w,{to:`/stakeholders`,children:(0,M.jsx)(E,{variant:`soft`,children:t(`Add partners`)})})})}function V({o:e}){let{t:r,name:i}=c(),{money:o}=u();return e.budgets.length?(0,M.jsx)(`ul`,{className:`space-y-4`,children:e.budgets.map(e=>(0,M.jsxs)(`li`,{children:[(0,M.jsxs)(`div`,{className:`flex items-center justify-between text-[13.5px] mb-1.5`,children:[(0,M.jsxs)(`span`,{className:`inline-flex items-center gap-2`,children:[(0,M.jsx)(n,{color:e.color,size:9}),i(e)]}),(0,M.jsxs)(`span`,{className:`num`,children:[(0,M.jsx)(`span`,{className:t(`font-medium`,e.pct>=100&&`text-critical`),children:o(e.spentMinor,{compact:!0})}),(0,M.jsxs)(`span`,{className:`text-ink-3`,children:[` / `,o(e.budgetMinor,{compact:!0})]})]})]}),(0,M.jsx)(s,{value:e.pct}),(0,M.jsx)(`div`,{className:t(`text-[12px] mt-1`,e.pct>=100?`text-critical`:e.pct>=85?`text-warning`:`text-ink-3`),children:e.remainingMinor>=0?r(`{amount} left`,{amount:o(e.remainingMinor)}):r(`{amount} over budget`,{amount:o(-e.remainingMinor)})})]},e.categoryId))}):(0,M.jsx)(a,{title:r(`No budgets`),description:r(`Set a monthly budget on an expense category to track it here.`),action:(0,M.jsx)(w,{to:`/categories`,children:(0,M.jsx)(E,{variant:`soft`,size:`sm`,children:r(`Categories`)})})})}function H({o:e}){let{t,name:r}=c(),{date:i}=u();return e.topExpenses.length?(0,M.jsx)(`ul`,{className:`divide-y divide-line`,children:e.topExpenses.slice(0,6).map(e=>(0,M.jsxs)(`li`,{className:`px-4 md:px-5 py-3 flex items-center gap-3`,children:[(0,M.jsx)(`span`,{className:`inline-flex items-center justify-center size-9 rounded-[12px] shrink-0`,style:{background:`${e.categoryColor}1f`},children:(0,M.jsx)(n,{color:e.categoryColor,size:10})}),(0,M.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,M.jsx)(`div`,{dir:`auto`,className:`text-[14.5px] font-medium truncate`,children:e.description}),(0,M.jsxs)(`div`,{className:`text-[12.5px] text-ink-3 truncate`,children:[r({name:e.categoryName,nameAr:e.categoryNameAr}),` · `,i(e.date)]})]}),(0,M.jsx)(A,{minor:e.amountMinor,className:`text-[15px] font-semibold shrink-0`})]},e.id))}):(0,M.jsx)(a,{title:t(`No expenses in this range`)})}function U(e,t){let n=new Date().toISOString().slice(0,10),r=(e<n?e:n).slice(0,7);return new Intl.DateTimeFormat(t,{month:`long`,year:`numeric`,timeZone:`UTC`}).format(new Date(`${r}-01T00:00:00Z`))}export{I as OverviewPage};
@@ -0,0 +1 @@
1
+ import{a as e,c as t,d as n,dt as r,gt as i,h as a,i as o,l as s,n as c,o as l,pt as u,s as d,v as f,y as p}from"./badge-BTiDEJlh.js";import{_ as m,v as h}from"./queries-IGiwF8nF.js";import{n as g,r as _,t as v}from"./star-cwF2fEe6.js";import{a as y,i as b,n as x,o as S,r as C,t as w}from"./menu-BDGd2JUq.js";import{i as T,n as E,r as D,s as O}from"./media-Cr7juL5w.js";import{c as k,d as A,l as j,m as M,p as N,x as P,y as F}from"./index-DOwVPfdT.js";import{t as I}from"./color-picker-DLlr-Cq6.js";var L=i(u(),1),R=r();function z({open:e,onClose:t,method:n}){let r=M(),{t:i}=f(),{create:a,update:o}=m(),[s,c]=(0,L.useState)(``),[l,u]=(0,L.useState)(``),[d,h]=(0,L.useState)(p[0]),[g,_]=(0,L.useState)(!1),[v,y]=(0,L.useState)(!1);(0,L.useEffect)(()=>{e&&(c(n?.name??``),u(n?.nameAr??``),h(n?.color??p[Math.floor(Math.random()*7)]),_(n?.isDefault??!1),y(n?.archived??!1))},[e,n]);let b=s.trim().length>0,x=a.isPending||o.isPending,S=async()=>{let e={name:s.trim(),nameAr:l.trim()||null,color:d,isDefault:g,archived:v};try{n?await o.mutateAsync({id:n.id,...e}):await a.mutateAsync(e),r.success(i(n?`Payment method updated`:`Payment method added`)),t()}catch(e){r.error(i(`Could not save`),N(e))}};return(0,R.jsx)(j,{open:e,onClose:t,title:i(n?`Edit payment method`:`New payment method`),footer:(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)(A,{variant:`ghost`,size:`md`,onClick:t,children:i(`Cancel`)}),(0,R.jsx)(A,{variant:`primary`,size:`md`,onClick:S,loading:x,disabled:!b,children:i(n?`Save`:`Add`)})]}),children:(0,R.jsxs)(`form`,{className:`space-y-4`,onSubmit:e=>{e.preventDefault(),b&&S()},children:[(0,R.jsx)(D,{label:i(`Name`),required:!0,children:(0,R.jsx)(T,{value:s,onChange:e=>c(e.target.value),autoFocus:!0,placeholder:i(`Cash, Visa, Instapay, PayPal…`)})}),(0,R.jsx)(D,{label:i(`Arabic name`),hint:i(`optional`),children:(0,R.jsx)(T,{lang:`ar`,dir:`rtl`,value:l,onChange:e=>u(e.target.value),placeholder:`كاش، فيزا، إنستاباي…`})}),(0,R.jsx)(I,{value:d,onChange:h}),(0,R.jsx)(O,{checked:g,onChange:_,label:i(`Default for new entries`),description:i(`The expense and revenue forms ask for this method's amount first. Only one method can be the default.`)}),n&&(0,R.jsx)(O,{checked:!v,onChange:e=>y(!e),label:i(`Active`),description:i(v?`Archived: hidden from forms, history kept`:`Shown in forms, filters and exports`)})]})})}var B=[`Cash`,`Visa`,`Mastercard`,`Bank transfer`,`Instapay`,`Vodafone Cash`,`PayPal`,`Stripe`,`Online payment`];function V(){let[r,i]=(0,L.useState)(!1),u=h(!0),{create:p,update:T,remove:D}=m(),O=M(),{t:j,name:I}=f(),[V,H]=(0,L.useState)(void 0),[U,W]=(0,L.useState)(null),G=u.data?.items??[],K=G.filter(e=>r||!e.archived),q=B.filter(e=>!G.some(t=>t.name.toLowerCase()===e.toLowerCase()));return(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)(n,{title:j(`Payment methods`),subtitle:j(`Cash, cards, online… Each expense and revenue row can hold an amount per method. Shown in tables, analytics and exports.`),actions:(0,R.jsx)(A,{variant:`primary`,size:`sm`,className:`rounded-full`,icon:(0,R.jsx)(F,{className:`size-4`}),onClick:()=>H(null),children:j(`New method`)})}),(0,R.jsx)(`div`,{className:`flex items-center justify-end mb-4`,children:(0,R.jsx)(E,{label:j(`Archived`),checked:r,onChange:e=>i(e.target.checked)})}),(0,R.jsxs)(`div`,{className:`grid grid-cols-1 xl:grid-cols-3 gap-4`,children:[(0,R.jsx)(l,{className:`xl:col-span-2`,flush:!0,children:u.isPending?(0,R.jsx)(s,{}):K.length?(0,R.jsx)(`ul`,{className:`divide-y divide-line`,children:K.map(n=>(0,R.jsxs)(`li`,{className:a(`flex items-center`,n.archived&&`opacity-60`),children:[(0,R.jsx)(t,{className:`flex-1`,leading:(0,R.jsx)(e,{color:n.color,children:(0,R.jsx)(o,{color:n.color,size:12})}),title:(0,R.jsxs)(`span`,{className:`inline-flex items-center gap-2`,children:[I(n),n.isDefault&&(0,R.jsx)(c,{tone:`accent`,children:j(`default`)}),n.archived&&(0,R.jsx)(c,{children:j(`archived`)})]}),onClick:()=>H(n)}),(0,R.jsx)(`div`,{className:`pe-3`,children:(0,R.jsx)(w,{trigger:()=>(0,R.jsx)(`button`,{type:`button`,className:`size-9 inline-flex items-center justify-center rounded-full text-ink-3 hover:text-ink hover:bg-card-hover`,"aria-label":j(`Actions`),children:(0,R.jsx)(S,{className:`size-4`})}),children:e=>(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)(x,{icon:(0,R.jsx)(y,{}),onClick:()=>{e(),H(n)},children:j(`Edit`)}),!n.archived&&(0,R.jsx)(x,{icon:(0,R.jsx)(v,{}),onClick:async()=>{e();try{await T.mutateAsync({id:n.id,isDefault:!n.isDefault})}catch(e){O.error(j(`Failed`),N(e))}},children:j(n.isDefault?`Remove as default`:`Make default`)}),(0,R.jsx)(x,{icon:n.archived?(0,R.jsx)(_,{}):(0,R.jsx)(g,{}),onClick:async()=>{e();try{await T.mutateAsync({id:n.id,archived:!n.archived})}catch(e){O.error(j(`Failed`),N(e))}},children:j(n.archived?`Restore`:`Archive`)}),(0,R.jsx)(C,{}),(0,R.jsx)(x,{icon:(0,R.jsx)(b,{}),danger:!0,onClick:()=>{e(),W(n)},children:j(`Delete`)})]})})})]},n.id))}):(0,R.jsx)(d,{icon:(0,R.jsx)(P,{}),title:j(`No payment methods yet`),description:j(`Add the ways this project gets paid. Pick from the suggestions or create your own.`),action:(0,R.jsx)(A,{variant:`soft`,onClick:()=>H(null),children:j(`Add one`)})})}),(0,R.jsx)(l,{title:j(`Quick add`),subtitle:j(`Common ones, one tap each`),children:q.length?(0,R.jsx)(`div`,{className:`flex flex-wrap gap-2`,children:q.map(e=>(0,R.jsx)(A,{size:`sm`,variant:`secondary`,className:`rounded-full`,icon:(0,R.jsx)(F,{className:`size-3.5`}),loading:p.isPending&&p.variables?.name===e,onClick:async()=>{try{await p.mutateAsync({name:e,isDefault:G.length===0})}catch(e){O.error(j(`Could not add`),N(e))}},children:e},e))}):(0,R.jsx)(`p`,{className:`text-[13.5px] text-ink-3`,children:j(`All suggestions are already added.`)})})]}),(0,R.jsx)(z,{open:V!==void 0,onClose:()=>H(void 0),method:V??null}),(0,R.jsx)(k,{open:!!U,onClose:()=>W(null),onConfirm:async()=>{try{await D.mutateAsync(U.id),O.success(j(`Payment method deleted`)),W(null)}catch(e){O.error(j(`Could not delete`),N(e))}},loading:D.isPending,title:j(`Delete {name}?`,{name:I(U)}),description:j(`Only possible when no revenue uses it. Otherwise archive it instead.`)})]})}export{V as PaymentsPage};
@@ -0,0 +1 @@
1
+ import{A as e,B as t,D as n,U as r,dt as i,gt as a,j as o,k as s,pt as c,v as l}from"./badge-BTiDEJlh.js";var u=a(c(),1),d=i(),f=(0,u.createContext)(null);function p(){return r({queryKey:[`project`],queryFn:()=>t.get(`/project`),staleTime:6e4})}function m({project:t,children:r}){let{intlLocale:i}=l(),a=(0,u.useMemo)(()=>{let{currency:r,weekStartsOn:a,fiscalYearStartMonth:c}=t.config,l=i(t.config.locale),u={short:new Intl.DateTimeFormat(l,{day:`2-digit`,month:`short`,timeZone:`UTC`}),medium:new Intl.DateTimeFormat(l,{day:`2-digit`,month:`short`,year:`numeric`,timeZone:`UTC`}),long:new Intl.DateTimeFormat(l,{weekday:`short`,day:`2-digit`,month:`long`,year:`numeric`,timeZone:`UTC`})};return{project:t,currency:r,locale:l,weekStartsOn:a,fiscalYearStartMonth:c,digits:o(r),money:(e,t)=>n(e,r,{locale:l,...t}),toMajor:t=>e(t,r),toMinor:e=>s(e,r),date:(e,t=`medium`)=>{if(!e)return``;let n=new Date(`${e.slice(0,10)}T00:00:00Z`);return Number.isNaN(n.getTime())?e:u[t].format(n)}}},[t,i]);return(0,d.jsx)(f.Provider,{value:a,children:r})}function h(){let e=(0,u.useContext)(f);if(!e)throw Error(`useProject outside ProjectProvider`);return e}export{h as n,p as r,m as t};
@@ -0,0 +1 @@
1
+ import{dt as e,g as t,gt as n,h as r,l as i,n as a,pt as o,s,v as c}from"./badge-BTiDEJlh.js";import{h as l,m as u}from"./queries-IGiwF8nF.js";import{n as d}from"./project-Bgpq3nFR.js";import{t as f}from"./download-CIyMPSgr.js";import{n as p}from"./search-jkqZqVJy.js";import{C as m,E as h,d as g,m as _,p as v,u as y}from"./index-DOwVPfdT.js";import{n as b}from"./shift-sales-B0yokKuf.js";var x={name:`store`,size:24,node:[[`path`,{d:`M15 21v-5a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v5`,key:`slp6dd`}],[`path`,{d:`M17.774 10.31a1.12 1.12 0 0 0-1.549 0 2.5 2.5 0 0 1-3.451 0 1.12 1.12 0 0 0-1.548 0 2.5 2.5 0 0 1-3.452 0 1.12 1.12 0 0 0-1.549 0 2.5 2.5 0 0 1-3.77-3.248l2.889-4.184A2 2 0 0 1 7 2h10a2 2 0 0 1 1.653.873l2.895 4.192a2.5 2.5 0 0 1-3.774 3.244`,key:`o0xfot`}],[`path`,{d:`M4 10.95V19a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8.05`,key:`wn3emo`}]]};x.node;var S=t(x),C=n(o(),1),w=e();function T(){let{locale:e,project:t}=d(),n=t.config.timezone,r=new Intl.DateTimeFormat(e,{hour:`2-digit`,minute:`2-digit`,timeZone:n}),i=new Intl.DateTimeFormat(e,{weekday:`short`,day:`2-digit`,month:`short`,timeZone:n});return{time:e=>r.format(new Date(e)),day:e=>i.format(new Date(e)),window:(e,t)=>`${r.format(new Date(e))} – ${r.format(new Date(t))}`}}function E({open:e,onClose:t}){let{t:n}=c(),{money:o}=d(),x=_(),E=T(),D=l(e),{pullShift:O}=u(),[k,A]=(0,C.useState)(null),[j,M]=(0,C.useState)(null);(0,C.useEffect)(()=>{e&&A(null)},[e]);let N=async e=>{M(e.externalId);try{let t=await O.mutateAsync({shiftId:e.externalId});A(t),x.success(n(t.created?`Shift added to revenue`:`Shift revenue updated`),`${t.revenue.description} · ${o(t.revenue.amountMinor)}`)}catch(e){x.error(n(`Could not pull the shift`),v(e))}finally{M(null)}},P=D.data?.[0];return(0,w.jsx)(y,{open:e,onClose:t,title:n(k?`Shift pulled`:`Pull a shift from Loyverse`),description:k?k.revenue.description:n(`Closed shifts, newest first. Only the payment types chosen in the integration settings go on the row.`),width:520,footer:k?(0,w.jsxs)(w.Fragment,{children:[(0,w.jsx)(g,{variant:`ghost`,size:`md`,onClick:()=>A(null),children:n(`Pull another`)}),(0,w.jsx)(g,{variant:`primary`,size:`md`,onClick:t,children:n(`Done`)})]}):(0,w.jsxs)(w.Fragment,{children:[(0,w.jsx)(g,{variant:`ghost`,size:`md`,icon:(0,w.jsx)(p,{className:r(`size-4`,D.isFetching&&`animate-spin`)}),onClick:()=>D.refetch(),disabled:D.isFetching,children:n(`Refresh`)}),(0,w.jsx)(g,{variant:`primary`,size:`md`,icon:(0,w.jsx)(f,{className:`size-4`}),loading:!!j&&j===P?.externalId,disabled:!P||!!j,onClick:()=>P&&N(P),children:P?.pulled?n(`Re-pull last shift`):n(`Pull last shift`)})]}),children:k?(0,w.jsxs)(`div`,{className:`space-y-4`,children:[(0,w.jsxs)(`div`,{className:`card p-4 flex items-center gap-3`,children:[(0,w.jsx)(`span`,{className:`size-10 rounded-full bg-revenue-soft text-revenue inline-flex items-center justify-center shrink-0`,children:(0,w.jsx)(m,{className:`size-5`})}),(0,w.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,w.jsx)(`div`,{className:`text-[13px] text-ink-3`,children:n(k.created?`New revenue row`:`Existing row updated`)}),(0,w.jsx)(`div`,{className:`num text-[22px] font-semibold tracking-tight text-revenue`,children:o(k.revenue.amountMinor)}),(0,w.jsx)(`div`,{className:`text-[12.5px] text-ink-3 truncate`,children:k.revenue.payments.filter(e=>e.amountMinor>0).map(e=>`${e.name} ${o(e.amountMinor,{compact:!0})}`).join(` · `)})]})]}),(0,w.jsx)(b,{sales:k.sales,compact:!0})]}):D.isPending?(0,w.jsx)(i,{label:n(`Asking Loyverse for the latest shifts`)}):D.isError?(0,w.jsx)(s,{title:n(`Could not reach Loyverse`),description:D.error.message,action:(0,w.jsx)(h,{to:`/integrations`,children:(0,w.jsx)(g,{variant:`soft`,size:`sm`,children:n(`Integration settings`)})})}):D.data.length?(0,w.jsx)(`ul`,{className:`divide-y divide-line -mx-1`,children:D.data.map((e,t)=>{let i=e.payments.filter(e=>e.selected&&e.amountMinor!==0),s=i.reduce((e,t)=>e+t.amountMinor,0);return(0,w.jsxs)(`li`,{className:r(`flex items-center gap-3 px-1 py-3`,t===0&&`bg-accent-soft/40 rounded-[12px]`),children:[(0,w.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,w.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[(0,w.jsx)(`span`,{className:`text-[14.5px] font-medium`,children:E.day(e.openedAt)}),(0,w.jsx)(`span`,{className:`num text-[12.5px] text-ink-3`,children:E.window(e.openedAt,e.closedAt)}),e.storeName&&(0,w.jsx)(a,{children:e.storeName}),e.pulled&&(0,w.jsx)(a,{tone:e.pulled.revenueId?`good`:`warning`,children:e.pulled.revenueId?n(`in ledger`):n(`row deleted`)})]}),(0,w.jsxs)(`div`,{className:`text-[12.5px] text-ink-3 mt-0.5 truncate`,children:[i.length?i.map(e=>`${e.name} ${o(e.amountMinor,{compact:!0})}`).join(` · `):n(`nothing through the selected payment types`),e.paidOutMinor>0&&(0,w.jsxs)(`span`,{children:[` · `,n(`pay-outs −{amount}`,{amount:o(e.paidOutMinor,{compact:!0})})]}),e.netSalesMinor?(0,w.jsxs)(`span`,{children:[` · `,n(`net sales {amount}`,{amount:o(e.netSalesMinor,{compact:!0})})]}):null]})]}),(0,w.jsxs)(`div`,{className:`text-end shrink-0`,children:[(0,w.jsx)(`div`,{className:`num text-[15px] font-semibold text-revenue`,children:o(s)}),(0,w.jsx)(g,{size:`xs`,variant:t===0?`primary`:`secondary`,className:`mt-1`,loading:j===e.externalId,disabled:!!j,onClick:()=>N(e),children:e.pulled?.revenueId?n(`Re-pull`):n(`Pull`)})]})]},e.externalId)})}):(0,w.jsx)(s,{icon:(0,w.jsx)(S,{}),title:n(`No closed shifts yet`),description:n(`Close the shift in the Loyverse POS app, then pull it here.`)})})}export{S as n,E as t};
@@ -0,0 +1 @@
1
+ import{B as e,G as t,J as n,K as r,Q as i,U as a,X as o,et as s,gt as c,ot as l,pt as u,rt as d,st as f,ut as p}from"./badge-BTiDEJlh.js";var m=class extends t{#e;#t;#n;#r;constructor(e){super(),this.#e=e.client,this.mutationId=e.mutationId,this.#n=e.mutationCache,this.#t=[],this.state=e.state||h(),this.setOptions(e.options),this.scheduleGc()}setOptions(e){this.options=e,this.updateGcTime(this.options.gcTime)}get meta(){return this.options.meta}addObserver(e){this.#t.includes(e)||(this.#t.push(e),this.clearGcTimeout(),this.#n.notify({type:`observerAdded`,mutation:this,observer:e}))}removeObserver(e){this.#t=this.#t.filter(t=>t!==e),this.scheduleGc(),this.#n.notify({type:`observerRemoved`,mutation:this,observer:e})}optionalRemove(){this.#t.length||(this.state.status===`pending`?this.scheduleGc():this.#n.remove(this))}continue(){return this.#r?.continue()??(this.state.status===`pending`?this.execute(this.state.variables):Promise.resolve())}async execute(e){let t=()=>{this.#i({type:`continue`})},n={client:this.#e,meta:this.options.meta,mutationKey:this.options.mutationKey},i=this.#r=r({fn:()=>this.options.mutationFn?this.options.mutationFn(e,n):Promise.reject(Error(`No mutationFn found`)),onFail:(e,t)=>{this.#i({type:`failed`,failureCount:e,error:t})},onPause:()=>{this.#i({type:`pause`})},onContinue:t,retry:this.options.retry??0,retryDelay:this.options.retryDelay,networkMode:this.options.networkMode,canRun:()=>this.#n.canRun(this)}),a=this.state.status===`pending`,o=!i.canStart();try{if(a)t();else{this.#i({type:`pending`,variables:e,isPaused:o}),this.#n.config.onMutate&&await this.#n.config.onMutate(e,this,n);let t=await this.options.onMutate?.(e,n);t!==this.state.context&&this.#i({type:`pending`,context:t,variables:e,isPaused:o})}let r=await i.start();return await this.#n.config.onSuccess?.(r,e,this.state.context,this,n),await this.options.onSuccess?.(r,e,this.state.context,n),await this.#n.config.onSettled?.(r,null,this.state.variables,this.state.context,this,n),await this.options.onSettled?.(r,null,e,this.state.context,n),this.#i({type:`success`,data:r}),r}catch(t){try{await this.#n.config.onError?.(t,e,this.state.context,this,n)}catch(e){Promise.reject(e)}try{await this.options.onError?.(t,e,this.state.context,n)}catch(e){Promise.reject(e)}try{await this.#n.config.onSettled?.(void 0,t,this.state.variables,this.state.context,this,n)}catch(e){Promise.reject(e)}try{await this.options.onSettled?.(void 0,t,e,this.state.context,n)}catch(e){Promise.reject(e)}throw this.#i({type:`error`,error:t}),t}finally{this.#r===i&&(this.#r=void 0),this.#n.runNext(this)}}#i(e){let t=t=>{switch(e.type){case`failed`:return{...t,failureCount:e.failureCount,failureReason:e.error};case`pause`:return{...t,isPaused:!0};case`continue`:return{...t,isPaused:!1};case`pending`:return{...t,context:e.context,data:void 0,failureCount:0,failureReason:null,error:null,isPaused:e.isPaused,status:`pending`,variables:e.variables,submittedAt:Date.now()};case`success`:return{...t,data:e.data,failureCount:0,failureReason:null,error:null,status:`success`,isPaused:!1};case`error`:return{...t,data:void 0,error:e.error,failureCount:t.failureCount+1,failureReason:e.error,isPaused:!1,status:`error`}}};this.state=t(this.state),n.batch(()=>{this.#t.forEach(t=>{t.onMutationUpdate(e)}),this.#n.notify({mutation:this,type:`updated`,action:e})})}};function h(){return{context:void 0,data:void 0,error:null,failureCount:0,failureReason:null,isPaused:!1,status:`idle`,variables:void 0,submittedAt:0}}var g=class extends o{#e;#t=void 0;#n;#r;constructor(e,t){super(),this.#e=e,this.setOptions(t),this.bindMethods(),this.#i()}bindMethods(){this.mutate=this.mutate.bind(this),this.reset=this.reset.bind(this)}setOptions(e){let t=this.options;this.options=this.#e.defaultMutationOptions(e),l(this.options,t)||this.#e.getMutationCache().notify({type:`observerOptionsUpdated`,mutation:this.#n,observer:this}),t?.mutationKey&&this.options.mutationKey&&i(t.mutationKey)!==i(this.options.mutationKey)?this.reset():this.#n?.state.status===`pending`&&this.#n.setOptions(this.options)}onSubscribe(){this.listeners.size===1&&this.#n&&(this.#n.addObserver(this),this.#i())}onUnsubscribe(){this.hasListeners()||this.#n?.removeObserver(this)}onMutationUpdate(e){this.#i(),this.#a(e)}getCurrentResult(){return this.#t}reset(){this.#n?.removeObserver(this),this.#n=void 0,this.#i(),this.#a()}mutate(e,t){return this.#r=t,this.#n?.removeObserver(this),this.#n=this.#e.getMutationCache().build(this.#e,this.options),this.#n.addObserver(this),this.#n.execute(e)}#i(){let e=this.#n?.state??h();this.#t={...e,isPending:e.status===`pending`,isSuccess:e.status===`success`,isError:e.status===`error`,isIdle:e.status===`idle`,mutate:this.mutate,reset:this.reset}}#a(e){n.batch(()=>{let t=this.#r;if(t&&this.hasListeners()){let n=this.#t.variables,r=this.#t.context,i={client:this.#e,meta:this.options.meta,mutationKey:this.options.mutationKey};if(e?.type===`success`){try{t.onSuccess?.(e.data,n,r,i)}catch(e){Promise.reject(e)}try{t.onSettled?.(e.data,null,n,r,i)}catch(e){Promise.reject(e)}}else if(e?.type===`error`){try{t.onError?.(e.error,n,r,i)}catch(e){Promise.reject(e)}try{t.onSettled?.(void 0,e.error,n,r,i)}catch(e){Promise.reject(e)}}}this.listeners.forEach(e=>{e(this.#t)})})}},_=c(u(),1);function v(e,t){let r=p(t),[i]=_.useState(()=>new g(r,e));_.useEffect(()=>{i.setOptions(e)},[i,e]);let a=_.useSyncExternalStore(_.useCallback(e=>i.subscribe(n.batchCalls(e)),[i]),()=>i.getCurrentResult(),()=>i.getCurrentResult()),o=_.useCallback((...e)=>{i.mutate(e[0],e[1]).catch(d)},[i]);if(a.error&&f(i.options.throwOnError,[a.error]))throw a.error;return{...a,mutate:o,mutateAsync:a.mutate}}function y(e){return Array.isArray(e)?{items:e}:e}function b(){let e=p();return()=>Promise.all([e.invalidateQueries({queryKey:[`expenses`]}),e.invalidateQueries({queryKey:[`revenue`]}),e.invalidateQueries({queryKey:[`analytics`]}),e.invalidateQueries({queryKey:[`balances`]}),e.invalidateQueries({queryKey:[`distribution`]}),e.invalidateQueries({queryKey:[`budgets`]}),e.invalidateQueries({queryKey:[`settlements`]}),e.invalidateQueries({queryKey:[`stakeholders`]}),e.invalidateQueries({queryKey:[`categories`]}),e.invalidateQueries({queryKey:[`payment-methods`]}),e.invalidateQueries({queryKey:[`recurring`]}),e.invalidateQueries({queryKey:[`audit`]}),e.invalidateQueries({queryKey:[`project`]})])}var x=(t,n)=>a({queryKey:[`analytics`,t,n],queryFn:()=>e.get(`/analytics/overview`,{from:t,to:n}),placeholderData:s}),S=t=>a({queryKey:[`analytics`,`insights`,t],queryFn:()=>e.get(`/analytics/insights`,t),placeholderData:s}),C=()=>a({queryKey:[`stakeholders`],queryFn:()=>e.get(`/stakeholders`).then(e=>Array.isArray(e)?{items:e,shareTotal:e.filter(e=>e.active).reduce((e,t)=>e+t.sharePercent,0)}:e),staleTime:3e4}),w=(t,n)=>a({queryKey:[`balances`,t,n],queryFn:()=>e.get(`/stakeholders/balances`,{from:t,to:n}),placeholderData:s}),T=(t,n)=>a({queryKey:[`distribution`,t,n],queryFn:()=>e.get(`/stakeholders/distribution`,{from:t,to:n}),placeholderData:s});function E(){let t=b();return{create:v({mutationFn:t=>e.post(`/stakeholders`,t),onSuccess:t}),update:v({mutationFn:({id:t,...n})=>e.patch(`/stakeholders/${t}`,n),onSuccess:t}),remove:v({mutationFn:({id:t,force:n})=>e.delete(`/stakeholders/${t}`,{force:n}),onSuccess:t})}}var D=(t,n=!1)=>a({queryKey:[`categories`,t??`all`,n],queryFn:()=>e.get(`/categories`,{kind:t,includeArchived:n||void 0}).then(y),staleTime:3e4}),O=t=>a({queryKey:[`budgets`,t],queryFn:()=>e.get(`/categories/budgets`,{month:t}).then(e=>({month:(Array.isArray(e)?void 0:e.month)??t??new Date().toISOString().slice(0,7),items:Array.isArray(e)?e:e.items}))});function k(){let t=b();return{create:v({mutationFn:t=>e.post(`/categories`,t),onSuccess:t}),update:v({mutationFn:({id:t,...n})=>e.patch(`/categories/${t}`,n),onSuccess:t}),remove:v({mutationFn:t=>e.delete(`/categories/${t}`),onSuccess:t})}}var A=(t=!1)=>a({queryKey:[`payment-methods`,t],queryFn:()=>e.get(`/payment-methods`,{includeArchived:t||void 0}).then(y),staleTime:3e4});function j(){let t=b();return{create:v({mutationFn:t=>e.post(`/payment-methods`,t),onSuccess:t}),update:v({mutationFn:({id:t,...n})=>e.patch(`/payment-methods/${t}`,n),onSuccess:t}),remove:v({mutationFn:t=>e.delete(`/payment-methods/${t}`),onSuccess:t}),reorder:v({mutationFn:t=>e.post(`/payment-methods/reorder`,{ids:t}),onSuccess:t})}}var M=t=>a({queryKey:[`expenses`,t],queryFn:()=>e.get(`/expenses`,t),placeholderData:s}),N=t=>a({queryKey:[`revenue`,t],queryFn:()=>e.get(`/revenue`,t),placeholderData:s});function P(){let t=b();return{create:v({mutationFn:t=>e.post(`/expenses`,t),onSuccess:t}),update:v({mutationFn:({id:t,...n})=>e.patch(`/expenses/${t}`,n),onSuccess:t}),remove:v({mutationFn:t=>e.delete(`/expenses/${t}`),onSuccess:t}),bulkDelete:v({mutationFn:t=>e.post(`/expenses/bulk-delete`,{ids:t}),onSuccess:t}),recompute:v({mutationFn:t=>e.post(`/expenses/${t}/recompute-split`),onSuccess:t}),recomputeRange:v({mutationFn:t=>e.post(`/expenses/recompute-splits`,t),onSuccess:t}),setPayment:v({mutationFn:({id:t,paymentMethodId:n,amountMinor:r})=>e.put(`/expenses/${t}/payments/${n}`,{amountMinor:r}),onSuccess:t})}}function F(){let t=b();return{create:v({mutationFn:t=>e.post(`/revenue`,t),onSuccess:t}),update:v({mutationFn:({id:t,...n})=>e.patch(`/revenue/${t}`,n),onSuccess:t}),remove:v({mutationFn:t=>e.delete(`/revenue/${t}`),onSuccess:t}),bulkDelete:v({mutationFn:t=>e.post(`/revenue/bulk-delete`,{ids:t}),onSuccess:t}),setPayment:v({mutationFn:({id:t,paymentMethodId:n,amountMinor:r})=>e.put(`/revenue/${t}/payments/${n}`,{amountMinor:r}),onSuccess:t})}}var I=t=>a({queryKey:[`settlements`,t],queryFn:()=>e.get(`/settlements`,t),placeholderData:s});function L(){let t=b();return{create:v({mutationFn:t=>e.post(`/settlements`,t),onSuccess:t}),update:v({mutationFn:({id:t,...n})=>e.patch(`/settlements/${t}`,n),onSuccess:t}),remove:v({mutationFn:t=>e.delete(`/settlements/${t}`),onSuccess:t})}}var R=(t,n=!1)=>a({queryKey:[`custom-fields`,t??`all`,n],queryFn:()=>e.get(`/custom-fields`,{entity:t,includeArchived:n||void 0}).then(y),staleTime:6e4});function z(){let t=p(),n=()=>t.invalidateQueries({queryKey:[`custom-fields`]});return{create:v({mutationFn:t=>e.post(`/custom-fields`,t),onSuccess:n}),update:v({mutationFn:({id:t,...n})=>e.patch(`/custom-fields/${t}`,n),onSuccess:n}),remove:v({mutationFn:t=>e.delete(`/custom-fields/${t}`),onSuccess:n}),reorder:v({mutationFn:t=>e.post(`/custom-fields/reorder`,{ids:t}),onSuccess:n})}}var B=()=>a({queryKey:[`recurring`],queryFn:()=>e.get(`/recurring`).then(y)});function V(){let t=b();return{create:v({mutationFn:t=>e.post(`/recurring`,t),onSuccess:t}),update:v({mutationFn:({id:t,...n})=>e.patch(`/recurring/${t}`,n),onSuccess:t}),remove:v({mutationFn:t=>e.delete(`/recurring/${t}`),onSuccess:t}),run:v({mutationFn:t=>e.post(t?`/recurring/${t}/run`:`/recurring/run`),onSuccess:t})}}function H(){return{update:v({mutationFn:t=>e.patch(`/project`,t),onSuccess:b()})}}var U=t=>a({queryKey:[`audit`,t],queryFn:()=>e.get(`/audit`,t),placeholderData:s}),W=()=>a({queryKey:[`integrations`,`loyverse`],queryFn:()=>e.get(`/integrations/loyverse`),staleTime:3e4}),G=(t,n=!0)=>a({queryKey:[`integrations`,`loyverse`,`items`,t],queryFn:()=>e.get(`/integrations/loyverse/items`,t),placeholderData:s,enabled:n}),K=(t,n=10)=>a({queryKey:[`integrations`,`loyverse`,`shifts`,n],queryFn:()=>e.get(`/integrations/loyverse/shifts`,{limit:n}),enabled:t,staleTime:15e3}),q=t=>a({queryKey:[`integrations`,`loyverse`,`sales`,t],queryFn:()=>e.get(`/integrations/loyverse/shifts/${t}/sales`),enabled:!!t,staleTime:6e4});function J(){let t=p(),n=b(),r=()=>t.invalidateQueries({queryKey:[`integrations`]});return{connect:v({mutationFn:t=>e.post(`/integrations/loyverse/connect`,t),onSuccess:r}),disconnect:v({mutationFn:()=>e.delete(`/integrations/loyverse`),onSuccess:()=>Promise.all([r(),n()])}),settings:v({mutationFn:t=>e.put(`/integrations/loyverse/settings`,t),onSuccess:r}),syncItems:v({mutationFn:()=>e.post(`/integrations/loyverse/sync-items`),onSuccess:r}),pullShift:v({mutationFn:t=>e.post(`/integrations/loyverse/pull-shift`,t),onSuccess:()=>Promise.all([r(),n()])})}}export{F as C,E as D,q as E,C as O,N as S,I as T,j as _,k as a,B as b,T as c,S as d,W as f,x as g,K as h,D as i,m as k,P as l,J as m,w as n,z as o,G as p,O as r,R as s,U as t,M as u,A as v,L as w,V as x,H as y};
@@ -0,0 +1 @@
1
+ import{R as e,a as t,c as n,d as r,dt as i,f as a,g as o,gt as s,h as c,l,n as u,o as d,pt as f,s as p,v as m}from"./badge-BTiDEJlh.js";import{O as h,b as g,i as _,v,x as ee}from"./queries-IGiwF8nF.js";import{n as y}from"./project-Bgpq3nFR.js";import{a as b,i as x,n as S,o as C,r as w,t as T}from"./menu-BDGd2JUq.js";import{a as E,i as D,o as O,r as k,s as te}from"./media-Cr7juL5w.js";import{t as ne}from"./money-input-C8ZuBxvX.js";import{c as A,d as j,m as M,o as re,p as N,s as ie,u as ae,v as P,y as F}from"./index-DOwVPfdT.js";import{t as I}from"./money-Ch2MLu6J.js";var L={name:`pause`,size:24,node:[[`rect`,{x:`14`,y:`3`,width:`5`,height:`18`,rx:`1`,key:`kaeet6`}],[`rect`,{x:`5`,y:`3`,width:`5`,height:`18`,rx:`1`,key:`1wsw3u`}]]};L.node;var R=o(L),z={name:`play`,size:24,node:[[`path`,{d:`M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z`,key:`10ikf1`}]]};z.node;var B=o(z),V={name:`zap`,size:24,node:[[`path`,{d:`M15.914 4a1.5 1.5 0 00-2.474-1.561l-9 9A1.5 1.5 0 005.5 14h4.002a.5.5 0 01.471.666L8.086 20a1.5 1.5 0 002.475 1.56l9-9A1.5 1.5 0 0018.5 10h-3.997a.5.5 0 01-.472-.667z`,key:`1v7up4`}]]};V.node;var H=o(V),U=s(f(),1),W=i(),oe=[{id:`daily`,label:`Daily`},{id:`weekly`,label:`Weekly`},{id:`monthly`,label:`Monthly`},{id:`quarterly`,label:`Quarterly`},{id:`yearly`,label:`Yearly`}];function G({open:t,onClose:n,rule:r}){let i=M(),{t:o,name:s}=m(),{create:c,update:l}=ee(),u=h(),[d,f]=(0,U.useState)(`expense`),p=_(d),g=v(),[y,b]=(0,U.useState)(``),[x,S]=(0,U.useState)(``),[C,w]=(0,U.useState)(`monthly`),[T,A]=(0,U.useState)(1),[P,F]=(0,U.useState)(e()),[I,L]=(0,U.useState)(``),[R,z]=(0,U.useState)(!0),[B,V]=(0,U.useState)(``),[H,G]=(0,U.useState)(null),[K,q]=(0,U.useState)(``),[J,Y]=(0,U.useState)(``),[X,Z]=(0,U.useState)(``),[se,ce]=(0,U.useState)(``),[Q,le]=(0,U.useState)(`ownership`),[$,ue]=(0,U.useState)([]),[de,fe]=(0,U.useState)({});(0,U.useEffect)(()=>{t&&(f(r?.kind??`expense`),S(r?.name??``),w(r?.frequency??`monthly`),A(r?.interval??1),F(r?.startDate??e()),L(r?.endDate??``),z(r?.active??!0),V(r?.template.description??``),G(r?.template.amountMinor??null),q(r?.template.categoryId??``),Y(r?.template.partyStakeholderId??``),Z(r?.template.vendorOrSource??``),ce(r?.template.notes??``),le(r?.template.splitMode??`ownership`),ue(r?.template.customSplits??[]),fe(r?.template.customFields??{}),b(r?.template.paymentMethodId??``))},[t,r]),(0,U.useEffect)(()=>{if(!t||r||K)return;let e=p.data?.items.find(e=>e.isDefault&&!e.archived);e&&q(e.id)},[t,r,K,p.data]);let pe=x.trim()&&B.trim()&&H!==null&&H>0&&!!P&&(d===`revenue`||!!K)&&T>=1,me=c.isPending||l.isPending,he=async()=>{let e={kind:d,name:x.trim(),frequency:C,interval:T,startDate:P,endDate:I||null,active:R,template:{description:B.trim(),amountMinor:H,categoryId:K||null,partyStakeholderId:J||null,paymentMethodId:y||null,vendorOrSource:X.trim()||null,notes:se.trim()||null,splitMode:Q,customSplits:Q===`custom`?$:[],customFields:de}};try{if(r){let{kind:t,...n}=e;await l.mutateAsync({id:r.id,...n})}else await c.mutateAsync(e);i.success(o(r?`Rule updated`:`Recurring rule created`)),n()}catch(e){i.error(o(`Could not save rule`),N(e))}};return(0,W.jsx)(ae,{open:t,onClose:n,title:o(r?`Edit recurring rule`:`New recurring rule`),description:o(`Entries are generated automatically when they come due (checked hourly and on start).`),width:520,footer:(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(j,{variant:`ghost`,size:`md`,onClick:n,className:`max-md:hidden`,children:o(`Cancel`)}),(0,W.jsx)(j,{variant:`primary`,size:`lg`,onClick:he,loading:me,disabled:!pe,className:`w-full md:w-auto`,children:o(r?`Save`:`Create rule`)})]}),children:(0,W.jsxs)(`form`,{className:`space-y-4`,onSubmit:e=>{e.preventDefault(),pe&&he()},children:[!r&&(0,W.jsx)(a,{value:d,onChange:e=>{f(e),q(``)},items:[{id:`expense`,label:o(`Expense`)},{id:`revenue`,label:o(`Revenue`)}]}),(0,W.jsx)(k,{label:o(`Rule name`),required:!0,children:(0,W.jsx)(D,{value:x,onChange:e=>S(e.target.value),placeholder:o(`Office rent`),autoFocus:!r})}),(0,W.jsxs)(`div`,{className:`grid grid-cols-[1fr_80px] gap-3`,children:[(0,W.jsx)(k,{label:o(`Frequency`),children:(0,W.jsx)(E,{value:C,onChange:e=>w(e.target.value),children:oe.map(e=>(0,W.jsx)(`option`,{value:e.id,children:o(e.label)},e.id))})}),(0,W.jsx)(k,{label:o(`Every`),hint:o(`n`),children:(0,W.jsx)(D,{mono:!0,type:`number`,min:1,max:365,value:T,onChange:e=>A(Math.max(1,Number(e.target.value)||1))})})]}),(0,W.jsxs)(`div`,{className:`grid grid-cols-2 gap-3`,children:[(0,W.jsx)(k,{label:o(`First occurrence`),required:!0,children:(0,W.jsx)(D,{mono:!0,type:`date`,value:P,onChange:e=>F(e.target.value)})}),(0,W.jsx)(k,{label:o(`Ends`),hint:o(`optional`),children:(0,W.jsx)(D,{mono:!0,type:`date`,value:I,min:P,onChange:e=>L(e.target.value)})})]}),(0,W.jsx)(te,{checked:R,onChange:z,label:o(`Active`),description:o(R?`Generates entries when due`:`Paused: nothing is generated`)}),(0,W.jsx)(`div`,{className:`pt-4 mt-2 border-t border-line`,children:(0,W.jsx)(`span`,{className:`label`,children:o(`Entry template`)})}),(0,W.jsx)(k,{label:o(`Description`),required:!0,children:(0,W.jsx)(D,{value:B,onChange:e=>V(e.target.value)})}),(0,W.jsxs)(`div`,{className:`grid grid-cols-2 gap-3`,children:[(0,W.jsx)(k,{label:o(`Amount`),required:!0,children:(0,W.jsx)(ne,{value:H,onChange:G})}),(0,W.jsx)(k,{label:o(`Category`),required:d===`expense`,children:(0,W.jsxs)(E,{value:K,onChange:e=>q(e.target.value),children:[(0,W.jsx)(`option`,{value:``,children:o(d===`expense`?`Select…`:`Uncategorised`)}),p.data?.items.map(e=>(0,W.jsx)(`option`,{value:e.id,children:s(e)},e.id))]})})]}),(0,W.jsxs)(`div`,{className:`grid grid-cols-2 gap-3`,children:[(0,W.jsx)(k,{label:o(d===`expense`?`Paid by`:`Received by`),children:(0,W.jsxs)(E,{value:J,onChange:e=>Y(e.target.value),children:[(0,W.jsx)(`option`,{value:``,children:o(`Company pool`)}),u.data?.items.map(e=>(0,W.jsx)(`option`,{value:e.id,children:s(e)},e.id))]})}),(0,W.jsx)(k,{label:o(d===`expense`?`Vendor`:`Source`),children:(0,W.jsx)(D,{value:X,onChange:e=>Z(e.target.value)})})]}),(g.data?.items.length??0)>0&&(0,W.jsx)(k,{label:o(`Payment method`),hint:o(`blank = default`),children:(0,W.jsxs)(E,{value:y,onChange:e=>b(e.target.value),children:[(0,W.jsx)(`option`,{value:``,children:o(`Default method`)}),g.data?.items.map(e=>(0,W.jsx)(`option`,{value:e.id,children:s(e)},e.id))]})}),d===`expense`&&(0,W.jsx)(re,{stakeholders:u.data?.items??[],amountMinor:H,mode:Q,onMode:le,splits:$,onSplits:ue}),(0,W.jsx)(k,{label:o(`Notes`),children:(0,W.jsx)(O,{value:se,onChange:e=>ce(e.target.value)})}),(0,W.jsx)(ie,{entity:d,values:de,onChange:fe})]})})}var K={daily:`Every day`,weekly:`Every week`,monthly:`Every month`,quarterly:`Every quarter`,yearly:`Every year`},q={daily:`Every {n} days`,weekly:`Every {n} weeks`,monthly:`Every {n} months`,quarterly:`Every {n} quarters`,yearly:`Every {n} years`};function J(e,t){return e.interval===1?t(K[e.frequency]):t(q[e.frequency],{n:e.interval})}function Y(){let e=g(),{update:i,remove:a,run:o}=ee(),s=M(),{t:f}=m(),{date:h}=y(),[_,v]=(0,U.useState)(void 0),[E,D]=(0,U.useState)(null),O=e.data?.items??[],k=new Date().toISOString().slice(0,10);return(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(r,{title:f(`Recurring`),subtitle:f(`Rent, retainers, subscriptions: added automatically when due.`),actions:(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(j,{variant:`secondary`,size:`sm`,className:`rounded-full`,icon:(0,W.jsx)(H,{className:`size-4`}),onClick:async()=>{try{let e=await o.mutateAsync(void 0);s.success(e.generated.length?f(`Generated {n} entries`,{n:e.generated.length}):f(`Nothing due right now`))}catch(e){s.error(f(`Run failed`),N(e))}},loading:o.isPending,children:f(`Run due now`)}),(0,W.jsx)(j,{variant:`primary`,size:`sm`,className:`rounded-full`,icon:(0,W.jsx)(F,{className:`size-4`}),onClick:()=>v(null),children:f(`New rule`)})]})}),(0,W.jsx)(d,{flush:!0,children:e.isPending?(0,W.jsx)(l,{}):O.length?(0,W.jsx)(`ul`,{className:`divide-y divide-line`,children:O.map(e=>{let r=e.active&&e.nextRunAt<=k;return(0,W.jsxs)(`li`,{className:c(`flex items-center`,!e.active&&`opacity-60`),children:[(0,W.jsx)(n,{className:`flex-1`,leading:(0,W.jsx)(t,{color:e.kind===`expense`?`var(--s-expense)`:`var(--s-revenue)`,children:(0,W.jsx)(P,{className:`size-4`})}),title:(0,W.jsxs)(`span`,{className:`inline-flex items-center gap-2`,children:[e.name,e.active?r?(0,W.jsx)(u,{tone:`warning`,children:f(`due`)}):null:(0,W.jsx)(u,{children:f(`paused`)})]}),subtitle:`${J(e,f)} · ${f(`next {date}`,{date:h(e.nextRunAt)})}${e.endDate?` · ${f(`ends {date}`,{date:h(e.endDate)})}`:``} · ${f(`{n} generated`,{n:e.generatedCount})}`,trailing:(0,W.jsx)(I,{minor:e.template.amountMinor,tone:e.kind===`expense`?`expense`:`revenue`,className:`text-[15px] font-semibold`}),onClick:()=>v(e)}),(0,W.jsx)(`div`,{className:`pe-3`,children:(0,W.jsx)(T,{trigger:()=>(0,W.jsx)(`button`,{type:`button`,className:`size-9 inline-flex items-center justify-center rounded-full text-ink-3 hover:text-ink hover:bg-card-hover`,"aria-label":f(`Actions`),children:(0,W.jsx)(C,{className:`size-4`})}),children:t=>(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(S,{icon:(0,W.jsx)(b,{}),onClick:()=>{t(),v(e)},children:f(`Edit`)}),(0,W.jsx)(S,{icon:(0,W.jsx)(H,{}),onClick:async()=>{t();try{let t=await o.mutateAsync(e.id);s.success(t.generated.length?f(`Generated {n}`,{n:t.generated.length}):f(`Nothing due`))}catch(e){s.error(f(`Run failed`),N(e))}},children:f(`Run now`)}),(0,W.jsx)(S,{icon:e.active?(0,W.jsx)(R,{}):(0,W.jsx)(B,{}),onClick:async()=>{t();try{await i.mutateAsync({id:e.id,active:!e.active})}catch(e){s.error(f(`Failed`),N(e))}},children:f(e.active?`Pause`:`Resume`)}),(0,W.jsx)(w,{}),(0,W.jsx)(S,{icon:(0,W.jsx)(x,{}),danger:!0,onClick:()=>{t(),D(e)},children:f(`Delete`)})]})})})]},e.id)})}):(0,W.jsx)(p,{icon:(0,W.jsx)(P,{}),title:f(`No recurring rules`),description:f(`Create one for rent, salaries or retainers and ledgr adds the entries on schedule.`),action:(0,W.jsx)(j,{variant:`soft`,onClick:()=>v(null),children:f(`New rule`)})})}),(0,W.jsx)(G,{open:_!==void 0,onClose:()=>v(void 0),rule:_??null}),(0,W.jsx)(A,{open:!!E,onClose:()=>D(null),onConfirm:async()=>{try{await a.mutateAsync(E.id),s.success(f(`Rule deleted`)),D(null)}catch(e){s.error(f(`Delete failed`),N(e))}},loading:a.isPending,title:f(`Delete “{name}”?`,{name:E?.name??``}),description:f(`Entries already generated stay in the ledger.`)})]})}export{Y as RecurringPage};
@@ -0,0 +1 @@
1
+ import{H as e,d as t,dt as n,gt as r,h as i,i as a,n as ee,o,pt as s,r as te,s as ne,t as re,v as ie}from"./badge-BTiDEJlh.js";import{C as ae,O as oe,S as se,f as ce,i as le,s as ue,v as de}from"./queries-IGiwF8nF.js";import{n as fe}from"./project-Bgpq3nFR.js";import{a as c,i as l,n as u,o as pe,r as me,t as d}from"./table-DQsx5_iN.js";import{t as he}from"./download-CIyMPSgr.js";import{a as ge,i as f,n as p,o as m,r as _e,t as h}from"./menu-BDGd2JUq.js";import{a as g,i as ve,n as ye,r as be,t as xe}from"./ledger-toolbar-yj0u4-Rm.js";import{t as Se}from"./pull-shift-sheet-DTwTC0rg.js";import{n as _,t as Ce}from"./media-Cr7juL5w.js";import{c as v,d as y,f as we,i as Te,l as Ee,m as De,p as b,y as x}from"./index-DOwVPfdT.js";import{t as S}from"./money-Ch2MLu6J.js";import{t as C}from"./custom-cell-Wgh3D7lb.js";import{t as Oe}from"./shift-sales-B0yokKuf.js";var w=r(s(),1),T=n(),ke=50;function E(){let{t:n,name:r,label:s}=ie(),E=e=>r({name:e.name??``,nameAr:e.nameAr}),{range:D}=we(),{date:O,money:k}=fe(),A=ye(),j=De(),Ae=Ce(),je=le(`revenue`,!0),Me=oe(),Ne=ue(`revenue`),M=de(!0),N=!!ce().data?.connected,[Pe,Fe]=(0,w.useState)(!1),Ie=(0,w.useMemo)(()=>({from:D.from,to:D.to,q:A.q,categoryId:A.categoryId,stakeholderId:A.stakeholderId,paymentMethodId:A.paymentMethodId,sort:A.sort,order:A.order,page:A.page,pageSize:ke}),[D,A.q,A.categoryId,A.stakeholderId,A.paymentMethodId,A.sort,A.order,A.page]),P=se(Ie),{remove:Le,bulkDelete:Re}=ae(),[F,I]=(0,w.useState)(void 0),[L,R]=(0,w.useState)(null),[z,B]=(0,w.useState)(new Set),[V,H]=(0,w.useState)(!1),[ze,U]=(0,w.useState)(!1),[W,G]=(0,w.useState)(null),[Be,K]=(0,w.useState)(null),q=(0,w.useMemo)(()=>(M.data?.items??[]).filter(e=>!e.archived),[M.data]),J=P.data?.items??[],Y=Ne.data?.items??[],X=J.length>0&&J.every(e=>z.has(e.id)),Ve=()=>B(X?new Set:new Set(J.map(e=>e.id))),Z=e=>B(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n}),Q=e=>A.set({sort:e,order:A.sort===e&&A.order===`desc`?`asc`:`desc`}),$=e=>A.sort===e?A.order:null,He=(t=`xlsx`)=>e(`/export/revenue.${t}`,`revenue.${t}`,{from:D.from,to:D.to}).catch(e=>j.error(n(`Export failed`),b(e))),Ue=(0,w.useMemo)(()=>{let e=new Map;for(let t of J)e.set(t.date,[...e.get(t.date)??[],t]);return[...e.entries()]},[J]);return(0,T.jsxs)(T.Fragment,{children:[(0,T.jsx)(t,{title:n(`Revenue`),subtitle:P.data?(0,T.jsxs)(T.Fragment,{children:[(0,T.jsx)(S,{minor:P.data.totals.amountMinor,className:`text-ink font-medium`}),` `,n(`across {n} entries`,{n:P.data.totals.count})]}):n(`Loading…`),actions:(0,T.jsxs)(T.Fragment,{children:[(0,T.jsx)(h,{trigger:()=>(0,T.jsx)(y,{variant:`secondary`,size:`sm`,icon:(0,T.jsx)(m,{className:`size-4`}),className:`rounded-full`,children:n(`More`)}),title:n(`Revenue`),children:e=>(0,T.jsxs)(T.Fragment,{children:[(0,T.jsx)(p,{icon:V?(0,T.jsx)(g,{}):(0,T.jsx)(ve,{}),onClick:()=>{e(),H(e=>!e),B(new Set)},children:n(V?`Done selecting`:`Select entries`)}),(0,T.jsx)(_e,{}),(0,T.jsx)(p,{icon:(0,T.jsx)(f,{}),danger:!0,disabled:!z.size,onClick:()=>{e(),U(!0)},children:n(`Delete {n} selected`,{n:z.size||``})})]})}),N&&(0,T.jsx)(y,{variant:`primary`,size:`sm`,className:`rounded-full`,icon:(0,T.jsx)(he,{className:`size-4`}),onClick:()=>Fe(!0),children:n(`Pull last shift`)}),(0,T.jsx)(y,{variant:N?`secondary`:`primary`,size:`sm`,className:`rounded-full max-md:hidden`,icon:(0,T.jsx)(x,{className:`size-4`}),onClick:()=>I(null),children:n(`New revenue`)})]})}),(0,T.jsx)(`div`,{className:`mb-3`,children:(0,T.jsx)(xe,{categories:je.data?.items.filter(e=>!e.archived)??[],stakeholders:Me.data?.items??[],paymentMethods:M.data?.items.filter(e=>!e.archived)??[],stakeholderLabel:`Received by`,onExport:He})}),V&&J.length>0&&(0,T.jsxs)(`div`,{className:`mb-3 flex items-center justify-between gap-2 card px-4 py-2 fade-up`,children:[(0,T.jsx)(_,{label:n(X?`Deselect all on page`:`Select all on page`),checked:X,onChange:Ve}),(0,T.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,T.jsx)(y,{size:`xs`,variant:`ghost`,onClick:()=>{H(!1),B(new Set)},children:n(`Done`)}),(0,T.jsx)(y,{size:`xs`,variant:`danger`,disabled:!z.size,icon:(0,T.jsx)(f,{className:`size-3.5`}),onClick:()=>U(!0),children:n(`Delete {n}`,{n:z.size||``})})]})]}),Ae?(0,T.jsxs)(`div`,{className:`space-y-4`,children:[P.isPending&&(0,T.jsx)(o,{children:(0,T.jsx)(`div`,{className:`py-10 text-center text-ink-3`,children:n(`Loading…`)})}),!P.isPending&&!J.length&&(0,T.jsx)(o,{children:(0,T.jsx)(ne,{title:n(`No revenue`),description:n(`Nothing matches this period and filters.`)})}),Ue.map(([e,t])=>(0,T.jsxs)(`section`,{children:[(0,T.jsxs)(`div`,{className:`flex items-baseline justify-between px-1 mb-1.5`,children:[(0,T.jsx)(`span`,{className:`label`,children:O(e,`long`)}),(0,T.jsx)(`span`,{className:`num text-[12px] text-ink-3`,children:k(t.reduce((e,t)=>e+t.amountMinor,0))})]}),(0,T.jsx)(`ul`,{className:`card divide-y divide-line overflow-hidden`,children:t.map(e=>(0,T.jsx)(`li`,{children:(0,T.jsxs)(`button`,{type:`button`,onClick:()=>V?Z(e.id):G(e),className:i(`pressable w-full flex items-center gap-3 px-4 py-3 text-start`,z.has(e.id)&&`bg-accent-soft/50`),children:[V?(0,T.jsx)(`span`,{className:i(`size-6 rounded-full border-2 inline-flex items-center justify-center shrink-0`,z.has(e.id)?`bg-accent border-accent text-white`:`border-line-strong`),children:z.has(e.id)&&(0,T.jsx)(g,{className:`size-3.5`})}):(0,T.jsx)(`span`,{className:`inline-flex items-center justify-center size-10 rounded-[12px] shrink-0`,style:{background:`${e.category?.color??`var(--s-revenue)`}1f`},children:(0,T.jsx)(a,{color:e.category?.color??`var(--s-revenue)`,size:10})}),(0,T.jsxs)(`span`,{className:`flex-1 min-w-0`,children:[(0,T.jsxs)(`span`,{dir:`auto`,className:`block text-[15px] font-medium truncate`,children:[e.pos&&(0,T.jsx)(`span`,{className:`inline-block size-1.5 rounded-full bg-[#1e9e6a] me-1.5 align-middle`,title:`Loyverse`}),e.description]}),(0,T.jsxs)(`span`,{className:`block text-[12.5px] text-ink-3 truncate`,children:[e.payments.filter(e=>e.amountMinor>0).length?e.payments.filter(e=>e.amountMinor>0).map(e=>`${E(e)} ${k(e.amountMinor,{compact:!0})}`).join(` · `):e.category?r(e.category):n(`Uncategorised`),e.receivedBy?` · ${r(e.receivedBy)}`:``]})]}),(0,T.jsx)(S,{minor:e.amountMinor,tone:`revenue`,className:`text-[15px] font-semibold shrink-0`})]})},e.id))})]},e)),P.data&&(0,T.jsx)(`div`,{className:`card`,children:(0,T.jsx)(u,{page:P.data.page,pageSize:P.data.pageSize,total:P.data.total,onPage:e=>A.set({page:String(e)})})})]}):(0,T.jsxs)(o,{flush:!0,children:[(0,T.jsxs)(me,{children:[(0,T.jsx)(`thead`,{children:(0,T.jsxs)(`tr`,{children:[V&&(0,T.jsx)(c,{className:`w-10`,children:(0,T.jsx)(_,{checked:X,onChange:Ve,"aria-label":n(`Select all`)})}),(0,T.jsx)(c,{sortable:!0,sorted:$(`date`),onSort:()=>Q(`date`),className:`w-28`,children:n(`Date`)}),(0,T.jsx)(c,{sortable:!0,sorted:$(`description`),onSort:()=>Q(`description`),children:n(`Description`)}),(0,T.jsx)(c,{children:n(`Category`)}),(0,T.jsx)(c,{children:n(`Source`)}),(0,T.jsx)(c,{children:n(`Received by`)}),Y.map(e=>(0,T.jsx)(c,{align:e.type===`money`||e.type===`number`?`right`:`left`,children:s(e)},e.id)),q.map(e=>(0,T.jsx)(c,{align:`right`,children:(0,T.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,children:[(0,T.jsx)(a,{color:e.color}),r(e)]})},e.id)),(0,T.jsx)(c,{align:`right`,sortable:!0,sorted:$(`amountMinor`),onSort:()=>Q(`amountMinor`),className:`w-36`,children:q.length?n(`Total`):n(`Amount`)}),(0,T.jsx)(c,{className:`w-12`})]})}),(0,T.jsxs)(`tbody`,{children:[P.isPending&&(0,T.jsx)(d,{colSpan:8+Y.length+q.length,children:n(`Loading…`)}),!P.isPending&&!J.length&&(0,T.jsx)(d,{colSpan:8+Y.length+q.length,children:n(`No revenue in this period.`)}),J.map(e=>(0,T.jsxs)(pe,{selected:z.has(e.id),className:`cursor-pointer`,onClick:()=>V?Z(e.id):G(e),children:[V&&(0,T.jsx)(l,{onClick:e=>e.stopPropagation(),children:(0,T.jsx)(_,{checked:z.has(e.id),onChange:()=>Z(e.id),"aria-label":n(`Select`)})}),(0,T.jsx)(l,{className:`num text-ink-2 whitespace-nowrap`,children:O(e.date)}),(0,T.jsxs)(l,{children:[(0,T.jsx)(`div`,{dir:`auto`,className:`font-medium truncate max-w-[380px]`,children:e.description}),e.recurringRuleId&&(0,T.jsx)(`div`,{className:`text-[12px] text-ink-3`,children:n(`recurring`)}),e.pos&&(0,T.jsx)(`div`,{className:`text-[12px] text-ink-3`,children:n(`Loyverse shift · {n} receipts`,{n:e.pos.receipts})})]}),(0,T.jsx)(l,{children:e.category?(0,T.jsx)(te,{color:e.category.color,children:r(e.category)}):(0,T.jsx)(`span`,{className:`text-ink-4`,children:`—`})}),(0,T.jsx)(l,{className:`text-ink-2`,children:e.source??(0,T.jsx)(`span`,{className:`text-ink-4`,children:`—`})}),(0,T.jsx)(l,{children:e.receivedBy?(0,T.jsxs)(`span`,{className:`inline-flex items-center gap-2`,children:[(0,T.jsx)(re,{name:r(e.receivedBy),color:e.receivedBy.color,size:22}),r(e.receivedBy)]}):(0,T.jsx)(`span`,{className:`text-ink-3`,children:n(`Company`)})}),Y.map(t=>(0,T.jsx)(l,{align:t.type===`money`||t.type===`number`?`right`:`left`,children:(0,T.jsx)(C,{def:t,value:e.customFields?.[t.key]})},t.id)),q.map(t=>{let i=e.payments.find(e=>e.paymentMethodId===t.id);return(0,T.jsx)(l,{align:`right`,onClick:e=>e.stopPropagation(),children:i&&i.amountMinor>0?(0,T.jsx)(`button`,{type:`button`,className:`num hover:text-accent`,title:n(`Edit {method} amount`,{method:r(t)}),onClick:()=>K({kind:`revenue`,entry:e,method:t}),children:k(i.amountMinor)}):(0,T.jsxs)(`button`,{type:`button`,className:`inline-flex items-center gap-1 text-[12.5px] font-medium text-accent/80 hover:text-accent whitespace-nowrap`,onClick:()=>K({kind:`revenue`,entry:e,method:t}),children:[(0,T.jsx)(x,{className:`size-3.5`}),n(`Add {method}`,{method:r(t)})]})},t.id)}),(0,T.jsx)(l,{align:`right`,children:(0,T.jsx)(S,{minor:e.amountMinor,className:`font-semibold`})}),(0,T.jsx)(l,{onClick:e=>e.stopPropagation(),children:(0,T.jsx)(h,{trigger:()=>(0,T.jsx)(`button`,{type:`button`,className:`size-8 inline-flex items-center justify-center rounded-full text-ink-3 hover:text-ink hover:bg-card-hover`,"aria-label":n(`Actions`),children:(0,T.jsx)(m,{className:`size-4`})}),children:t=>(0,T.jsxs)(T.Fragment,{children:[(0,T.jsx)(p,{icon:(0,T.jsx)(ge,{}),onClick:()=>{t(),I(e)},children:n(`Edit`)}),(0,T.jsx)(_e,{}),(0,T.jsx)(p,{icon:(0,T.jsx)(f,{}),danger:!0,onClick:()=>{t(),R(e)},children:n(`Delete`)})]})})})]},e.id))]})]}),P.data&&(0,T.jsx)(u,{page:P.data.page,pageSize:P.data.pageSize,total:P.data.total,onPage:e=>A.set({page:String(e)})})]}),(0,T.jsx)(Ee,{open:!!W,onClose:()=>G(null),title:W?.description??``,description:W?`${O(W.date,`long`)} · ${W.category?r(W.category):n(`Uncategorised`)}`:``,width:460,footer:W&&(0,T.jsxs)(T.Fragment,{children:[(0,T.jsx)(y,{variant:`danger`,size:`md`,onClick:()=>R(W),children:n(`Delete`)}),(0,T.jsx)(y,{variant:`primary`,size:`md`,onClick:()=>{I(W),G(null)},children:n(`Edit`)})]}),children:W&&(0,T.jsxs)(`div`,{className:`space-y-4`,children:[(0,T.jsx)(`div`,{className:`num text-[32px] font-semibold tracking-tight text-revenue`,children:k(W.amountMinor)}),(0,T.jsxs)(`dl`,{className:`grid grid-cols-[auto_1fr] gap-x-4 gap-y-2 text-[14px]`,children:[W.payments.filter(e=>e.amountMinor>0).map(e=>(0,T.jsxs)(`span`,{className:`contents`,children:[(0,T.jsx)(`dt`,{className:`text-ink-3`,children:E(e)}),(0,T.jsx)(`dd`,{className:`num`,children:k(e.amountMinor)})]},e.paymentMethodId)),(0,T.jsx)(`dt`,{className:`text-ink-3`,children:n(`Received by`)}),(0,T.jsx)(`dd`,{className:`font-medium`,children:W.receivedBy?r(W.receivedBy):n(`Company account`)}),W.source&&(0,T.jsxs)(T.Fragment,{children:[(0,T.jsx)(`dt`,{className:`text-ink-3`,children:n(`Source`)}),(0,T.jsx)(`dd`,{children:W.source})]}),Y.map(e=>(0,T.jsxs)(`span`,{className:`contents`,children:[(0,T.jsx)(`dt`,{className:`text-ink-3`,children:s(e)}),(0,T.jsx)(`dd`,{children:(0,T.jsx)(C,{def:e,value:W.customFields?.[e.key]})})]},e.id)),W.notes&&(0,T.jsxs)(T.Fragment,{children:[(0,T.jsx)(`dt`,{className:`text-ink-3`,children:n(`Notes`)}),(0,T.jsx)(`dd`,{className:`whitespace-pre-wrap`,children:W.notes})]})]}),W.pos&&(0,T.jsxs)(`div`,{children:[(0,T.jsxs)(`div`,{className:`flex items-center gap-2 mb-2`,children:[(0,T.jsx)(ee,{tone:`revenue`,children:`Loyverse`}),(0,T.jsx)(`span`,{className:`text-[12.5px] text-ink-3`,children:n(`What sold this shift`)})]}),(0,T.jsx)(Oe,{shiftId:W.pos.shiftId})]})]})}),(0,T.jsx)(Te,{open:F!==void 0,onClose:()=>I(void 0),revenue:F??null}),(0,T.jsx)(be,{target:Be,onClose:()=>K(null)}),(0,T.jsx)(Se,{open:Pe,onClose:()=>Fe(!1)}),(0,T.jsx)(v,{open:!!L,onClose:()=>R(null),onConfirm:async()=>{try{await Le.mutateAsync(L.id),j.success(n(`Revenue deleted`)),R(null),G(null)}catch(e){j.error(n(`Delete failed`),b(e))}},loading:Le.isPending,title:n(`Delete this revenue entry?`),description:L?n(`{description} · {amount} on {date}`,{description:L.description,amount:k(L.amountMinor),date:O(L.date)}):``}),(0,T.jsx)(v,{open:ze,onClose:()=>U(!1),onConfirm:async()=>{try{await Re.mutateAsync([...z]),j.success(n(`{n} entries deleted`,{n:z.size})),B(new Set),H(!1),U(!1)}catch(e){j.error(n(`Delete failed`),b(e))}},loading:Re.isPending,title:n(`Delete {n} entries?`,{n:z.size}),description:n(`This cannot be undone.`)})]})}export{E as RevenuePage};
@@ -0,0 +1 @@
1
+ import{g as e}from"./badge-BTiDEJlh.js";var t={name:`refresh-cw`,size:24,node:[[`path`,{d:`M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8`,key:`v9h5vc`}],[`path`,{d:`M21 3v5h-5`,key:`1q7to0`}],[`path`,{d:`M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16`,key:`3uifl3`}],[`path`,{d:`M8 16H3v5`,key:`1cv678`}]]};t.node;var n=e(t),r={name:`search`,size:24,node:[[`path`,{d:`m21 21-4.34-4.34`,key:`14j7rj`}],[`circle`,{cx:`11`,cy:`11`,r:`8`,key:`4ej97u`}]]};r.node;var i=e(r);export{n,i as t};
@@ -0,0 +1,4 @@
1
+ import{I as e,b as t,c as n,d as r,dt as i,g as a,gt as o,h as s,l as c,n as l,o as u,p as d,pt as f,s as p,v as m,x as h}from"./badge-BTiDEJlh.js";import{o as g,s as _,t as v,y}from"./queries-IGiwF8nF.js";import{n as b}from"./project-Bgpq3nFR.js";import{n as x}from"./table-DQsx5_iN.js";import{a as S,i as C,n as w,o as T,r as E,t as D}from"./menu-BDGd2JUq.js";import{a as O,i as k,n as A,o as j,r as M}from"./media-Cr7juL5w.js";import{c as N,d as P,l as ee,m as F,n as I,p as L,t as R,y as te}from"./index-DOwVPfdT.js";import{n as z}from"./format-GDcQVAp4.js";var B={name:`arrow-down`,size:24,node:[[`path`,{d:`M12 5v14`,key:`s699le`}],[`path`,{d:`m19 12-7 7-7-7`,key:`1idqje`}]]};B.node;var V=a(B),H={name:`arrow-up`,size:24,node:[[`path`,{d:`m5 12 7-7 7 7`,key:`hav0vg`}],[`path`,{d:`M12 19V5`,key:`x0mq9r`}]]};H.node;var ne=a(H),U={name:`share`,size:24,node:[[`path`,{d:`M12 2v13`,key:`1km8f5`}],[`path`,{d:`m16 6-4-4-4 4`,key:`13yo43`}],[`path`,{d:`M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8`,key:`1b2hhj`}]]};U.node;var W=a(U),G={name:`smartphone`,size:24,node:[[`rect`,{width:`14`,height:`20`,x:`5`,y:`2`,rx:`2`,ry:`2`,key:`1yt0o3`}],[`path`,{d:`M12 18h.01`,key:`mhygvu`}]]};G.node;var K=a(G),q=o(f(),1),J=null;typeof window<`u`&&window.addEventListener(`beforeinstallprompt`,e=>{e.preventDefault(),J=e,window.dispatchEvent(new Event(`ledgr:installable`))});function Y(){let[e,t]=(0,q.useState)(!!J),[n,r]=(0,q.useState)(!1);return(0,q.useEffect)(()=>{let e=()=>t(!0),n=()=>{r(!0),t(!1)};return window.addEventListener(`ledgr:installable`,e),window.addEventListener(`appinstalled`,n),()=>{window.removeEventListener(`ledgr:installable`,e),window.removeEventListener(`appinstalled`,n)}},[]),{canInstall:e,install:async()=>{if(!J)return;await J.prompt();let{outcome:e}=await J.userChoice;e===`accepted`&&r(!0),J=null,t(!1)},installed:n,isIOS:/iphone|ipad|ipod/i.test(navigator.userAgent),isStandalone:window.matchMedia(`(display-mode: standalone)`).matches||navigator.standalone===!0}}var X=i(),re={text:`Text`,number:`Number`,money:`Money`,date:`Date`,boolean:`Yes / no`,select:`Select (options)`},ie={expense:`New expense field`,revenue:`New revenue field`,stakeholder:`New stakeholder field`};function ae({open:t,onClose:n,field:r,entity:i}){let a=F(),{t:o}=m(),{create:s,update:c}=g(),[l,u]=(0,q.useState)(``),[d,f]=(0,q.useState)(``),[p,_]=(0,q.useState)(``),[v,y]=(0,q.useState)(!1),[b,x]=(0,q.useState)(`text`),[S,C]=(0,q.useState)(``),[w,T]=(0,q.useState)(!1);(0,q.useEffect)(()=>{t&&(u(r?.label??``),f(r?.labelAr??``),_(r?.key??``),y(!!r),x(r?.type??`text`),C(r?.options.join(`
2
+ `)??``),T(r?.required??!1))},[t,r]),(0,q.useEffect)(()=>{v||_(e(l))},[l,v]);let E=S.split(`
3
+ `).map(e=>e.trim()).filter(Boolean),D=l.trim()&&/^[a-z][a-z0-9_]*$/.test(p)&&(b!==`select`||E.length>0),N=s.isPending||c.isPending,I=async()=>{try{if(r)await c.mutateAsync({id:r.id,label:l.trim(),labelAr:d.trim()||null,type:b,options:E,required:w});else{let e={entity:i,key:p,label:l.trim(),labelAr:d.trim()||null,type:b,options:E,required:w};await s.mutateAsync(e)}a.success(o(r?`Field updated`:`Field added`)),n()}catch(e){a.error(o(`Could not save field`),L(e))}};return(0,X.jsx)(ee,{open:t,onClose:n,title:o(r?`Edit custom field`:ie[i]),footer:(0,X.jsxs)(X.Fragment,{children:[(0,X.jsx)(P,{variant:`ghost`,size:`md`,onClick:n,children:o(`Cancel`)}),(0,X.jsx)(P,{variant:`primary`,size:`md`,onClick:I,loading:N,disabled:!D,children:o(r?`Save`:`Add field`)})]}),children:(0,X.jsxs)(`form`,{className:`space-y-4`,onSubmit:e=>{e.preventDefault(),D&&I()},children:[(0,X.jsxs)(`div`,{className:`grid grid-cols-2 gap-3`,children:[(0,X.jsx)(M,{label:o(`Label`),required:!0,children:(0,X.jsx)(k,{value:l,onChange:e=>u(e.target.value),autoFocus:!0,placeholder:o(`Invoice no.`)})}),(0,X.jsx)(M,{label:o(`Key`),hint:o(`CSV column id`),children:(0,X.jsx)(k,{mono:!0,value:p,disabled:!!r,onChange:e=>{y(!0),_(e.target.value)}})})]}),(0,X.jsx)(M,{label:o(`Arabic label`),hint:o(`optional`),children:(0,X.jsx)(k,{lang:`ar`,dir:`rtl`,value:d,onChange:e=>f(e.target.value)})}),(0,X.jsx)(M,{label:o(`Type`),children:(0,X.jsx)(O,{value:b,onChange:e=>x(e.target.value),children:h.map(e=>(0,X.jsx)(`option`,{value:e,children:o(re[e])},e))})}),b===`select`&&(0,X.jsx)(M,{label:o(`Options`),hint:o(`one per line`),children:(0,X.jsx)(j,{value:S,onChange:e=>C(e.target.value),placeholder:[o(`Direct`),`Upwork`,o(`Referral`)].join(`
4
+ `)})}),(0,X.jsx)(A,{label:o(`Required`),checked:w,onChange:e=>T(e.target.checked)}),r&&r.type!==b&&(0,X.jsx)(`p`,{className:`text-[11.5px] text-warning`,children:o(`Changing the type does not convert existing values; incompatible ones are shown as blank.`)})]})})}function oe(){let[e,t]=(0,q.useState)(`project`),{t:n}=m();return(0,X.jsxs)(X.Fragment,{children:[(0,X.jsx)(r,{title:n(`Settings`)}),(0,X.jsx)(d,{className:`mb-4`,value:e,onChange:t,items:[{id:`project`,label:n(`Project`)},{id:`phone`,label:n(`Phone`)},{id:`fields`,label:n(`Custom fields`)},{id:`audit`,label:n(`Audit log`)}]}),e===`project`&&(0,X.jsx)(le,{}),e===`phone`&&(0,X.jsx)(ue,{}),e===`fields`&&(0,X.jsx)(fe,{}),e===`audit`&&(0,X.jsx)(pe,{})]})}var se=[`Sunday`,`Monday`,`Tuesday`,`Wednesday`,`Thursday`,`Friday`,`Saturday`],ce=[`January`,`February`,`March`,`April`,`May`,`June`,`July`,`August`,`September`,`October`,`November`,`December`];function le(){let{project:e}=b(),{update:t}=y(),n=F(),{t:r}=m(),i=e.config,[a,o]=(0,q.useState)(i.name),[s,c]=(0,q.useState)(i.nameAr??``),[d,f]=(0,q.useState)(i.currency),[p,h]=(0,q.useState)(i.locale),[g,_]=(0,q.useState)(i.weekStartsOn),[v,x]=(0,q.useState)(i.fiscalYearStartMonth);(0,q.useEffect)(()=>{o(i.name),c(i.nameAr??``),f(i.currency),h(i.locale),_(i.weekStartsOn),x(i.fiscalYearStartMonth)},[i]);let S=a!==i.name||s!==(i.nameAr??``)||d!==i.currency||p!==i.locale||g!==i.weekStartsOn||v!==i.fiscalYearStartMonth,C=async()=>{try{await t.mutateAsync({name:a.trim(),nameAr:s.trim(),currency:d.toUpperCase(),locale:p,weekStartsOn:g,fiscalYearStartMonth:v}),n.success(r(`Project updated`))}catch(e){n.error(r(`Could not save`),L(e))}};return(0,X.jsxs)(`div`,{className:`grid grid-cols-1 xl:grid-cols-3 gap-4`,children:[(0,X.jsx)(u,{className:`xl:col-span-2`,title:r(`Project`),children:(0,X.jsxs)(`form`,{className:`space-y-4 max-w-lg`,onSubmit:e=>{e.preventDefault(),C()},children:[(0,X.jsx)(M,{label:r(`Name`),children:(0,X.jsx)(k,{value:a,onChange:e=>o(e.target.value)})}),(0,X.jsx)(M,{label:r(`Arabic name`),hint:r(`optional`),children:(0,X.jsx)(k,{lang:`ar`,dir:`rtl`,value:s,onChange:e=>c(e.target.value)})}),(0,X.jsxs)(`div`,{className:`grid grid-cols-2 gap-3`,children:[(0,X.jsx)(M,{label:r(`Currency`),hint:`ISO 4217`,children:(0,X.jsx)(k,{mono:!0,maxLength:3,value:d,onChange:e=>f(e.target.value.toUpperCase())})}),(0,X.jsx)(M,{label:r(`Locale`),hint:r(`formatting`),children:(0,X.jsx)(k,{mono:!0,value:p,onChange:e=>h(e.target.value),placeholder:`en-US`})})]}),(0,X.jsxs)(`div`,{className:`grid grid-cols-2 gap-3`,children:[(0,X.jsx)(M,{label:r(`Week starts on`),children:(0,X.jsx)(O,{value:g,onChange:e=>_(Number(e.target.value)),children:se.map((e,t)=>(0,X.jsx)(`option`,{value:t,children:r(e)},e))})}),(0,X.jsx)(M,{label:r(`Fiscal year starts`),children:(0,X.jsx)(O,{value:v,onChange:e=>x(Number(e.target.value)),children:ce.map((e,t)=>(0,X.jsx)(`option`,{value:t+1,children:r(e)},e))})})]}),d!==i.currency&&(0,X.jsx)(`p`,{className:`text-[13px] text-warning`,children:r(`Changing currency relabels amounts; it does not convert them.`)}),(0,X.jsx)(P,{type:`submit`,variant:`primary`,size:`md`,disabled:!S,loading:t.isPending,children:r(`Save changes`)})]})}),(0,X.jsxs)(`div`,{className:`space-y-4`,children:[(0,X.jsx)(u,{title:r(`Appearance`),children:(0,X.jsxs)(`div`,{className:`space-y-3`,children:[(0,X.jsxs)(`div`,{children:[(0,X.jsx)(`div`,{className:`label mb-1.5`,children:r(`Theme`)}),(0,X.jsx)(I,{})]}),(0,X.jsxs)(`div`,{children:[(0,X.jsx)(`div`,{className:`label mb-1.5`,children:r(`Language`)}),(0,X.jsx)(R,{})]})]})}),(0,X.jsxs)(u,{title:r(`About this project`),children:[(0,X.jsxs)(`dl`,{className:`grid grid-cols-[auto_1fr] gap-x-5 gap-y-2 text-[13.5px]`,children:[(0,X.jsx)(`dt`,{className:`text-ink-3`,children:r(`Auth`)}),(0,X.jsx)(`dd`,{children:i.auth.mode===`supabase`?(0,X.jsx)(l,{tone:`good`,children:r(`Supabase · admins only`)}):(0,X.jsx)(l,{tone:`warning`,children:r(`None · local only`)})}),(0,X.jsx)(`dt`,{className:`text-ink-3`,children:r(`Entries`)}),(0,X.jsx)(`dd`,{className:`num`,children:r(`{expenses} expenses · {revenue} revenue`,{expenses:e.stats.expenses,revenue:e.stats.revenue})}),(0,X.jsx)(`dt`,{className:`text-ink-3`,children:r(`Period`)}),(0,X.jsx)(`dd`,{className:`num`,children:r(`{from} → {to}`,{from:e.stats.firstEntryDate??`—`,to:e.stats.lastEntryDate??`—`})}),(0,X.jsx)(`dt`,{className:`text-ink-3`,children:r(`Version`)}),(0,X.jsxs)(`dd`,{className:`num`,children:[`ledgr `,e.version]})]}),(0,X.jsxs)(`p`,{className:`text-[12.5px] text-ink-3 mt-3 leading-relaxed`,children:[r(`Data lives in`),` `,(0,X.jsx)(`code`,{className:`mono`,children:`.ledgr/data.db`}),` `,r(`next to this project. Auth settings are in`),` `,(0,X.jsx)(`code`,{className:`mono`,children:`.ledgr/config.json`}),r(`; restart after changing them.`)]})]})]})]})}function ue(){let{canInstall:e,install:t,installed:n,isIOS:r,isStandalone:i}=Y(),{t:a}=m(),o=typeof window<`u`?window.location.origin:``;return(0,X.jsxs)(`div`,{className:`grid grid-cols-1 xl:grid-cols-3 gap-4`,children:[(0,X.jsx)(u,{className:`xl:col-span-2`,title:a(`Add ledgr to your home screen`),subtitle:a(`Works like an app: full screen, its own icon, quick-add shortcuts.`),children:(0,X.jsxs)(`div`,{className:`space-y-4 text-[14px]`,children:[i&&(0,X.jsx)(`div`,{className:`rounded-[14px] bg-good/10 p-4`,children:a(`You are already running ledgr as an installed app.`)}),!i&&e&&(0,X.jsxs)(`div`,{className:`flex items-center gap-3 flex-wrap`,children:[(0,X.jsx)(P,{variant:`primary`,size:`md`,icon:(0,X.jsx)(K,{className:`size-4`}),onClick:t,children:a(`Install ledgr`)}),(0,X.jsx)(`span`,{className:`text-ink-3 text-[13px]`,children:a(n?`Installed. Open it from your home screen.`:`One tap, no app store.`)})]}),!i&&!e&&(0,X.jsx)(`ol`,{className:`space-y-3 list-decimal ps-5 text-ink-2 leading-relaxed`,children:r?(0,X.jsxs)(X.Fragment,{children:[(0,X.jsxs)(`li`,{children:[a(`Open this page in`),` `,(0,X.jsx)(`strong`,{className:`text-ink`,children:`Safari`}),a(`, tap`),` `,(0,X.jsx)(W,{className:`inline size-4 -mt-0.5`}),` `,(0,X.jsx)(`strong`,{className:`text-ink`,children:a(`Share`)}),`.`]}),(0,X.jsxs)(`li`,{children:[a(`Choose`),` `,(0,X.jsx)(`strong`,{className:`text-ink`,children:a(`Add to Home Screen`)}),a(`, then`),` `,(0,X.jsx)(`strong`,{className:`text-ink`,children:a(`Add`)}),`.`]})]}):(0,X.jsxs)(X.Fragment,{children:[(0,X.jsxs)(`li`,{children:[a(`Open this page in Chrome, tap the`),` `,(0,X.jsx)(`strong`,{className:`text-ink`,children:a(`⋮ menu`)}),`.`]}),(0,X.jsxs)(`li`,{children:[a(`Choose`),` `,(0,X.jsx)(`strong`,{className:`text-ink`,children:a(`Add to Home screen`)}),` (`,a(`or`),` `,(0,X.jsx)(`strong`,{className:`text-ink`,children:a(`Install app`)}),`).`]})]})}),(0,X.jsxs)(`div`,{className:`rounded-[14px] border border-line p-4`,children:[(0,X.jsx)(`div`,{className:`font-medium mb-1`,children:a(`Quick-add shortcuts`)}),(0,X.jsxs)(`p`,{className:`text-ink-2 text-[13.5px] leading-relaxed`,children:[a(`On Android, long-press the installed icon to get the`),` `,(0,X.jsx)(`strong`,{className:`text-ink`,children:a(`Add expense`)}),` `,a(`and`),` `,(0,X.jsx)(`strong`,{className:`text-ink`,children:a(`Add revenue`)}),` `,a(`shortcuts.`),` `,a(`On iPhone, add these two links to your home screen the same way (Safari → Share → Add to Home Screen); each opens straight into the form, like a widget:`)]}),(0,X.jsx)(`ul`,{className:`mt-3 space-y-2`,children:[{path:`/add/expense`,label:`Add expense`,color:`var(--s-expense)`},{path:`/add/revenue`,label:`Add revenue`,color:`var(--s-revenue)`}].map(e=>(0,X.jsxs)(`li`,{className:`flex items-center justify-between gap-3 rounded-[12px] bg-sunken/60 px-3.5 py-2.5`,children:[(0,X.jsxs)(`span`,{className:`inline-flex items-center gap-2.5 min-w-0`,children:[(0,X.jsx)(`span`,{className:`size-7 rounded-[8px] inline-flex items-center justify-center text-white font-bold`,style:{background:e.color},children:`+`}),(0,X.jsxs)(`span`,{className:`truncate`,children:[(0,X.jsx)(`span`,{className:`font-medium`,children:a(e.label)}),` `,(0,X.jsxs)(`span`,{className:`mono text-[12px] text-ink-3`,children:[o,e.path]})]})]}),(0,X.jsx)(`a`,{href:e.path,className:`text-accent text-[13px] font-medium shrink-0`,children:a(`Open`)})]},e.path))}),(0,X.jsx)(`p`,{className:`text-[12.5px] text-ink-3 mt-3`,children:a(`iPhone Shortcuts app users can also create a shortcut that opens one of these URLs and place it as a real home-screen widget.`)})]})]})}),(0,X.jsx)(u,{title:a(`Why not a native widget?`),children:(0,X.jsx)(`p`,{className:`text-[13.5px] text-ink-2 leading-relaxed`,children:a(`True home-screen widgets need a native iOS/Android app. ledgr is a web app that runs anywhere you host it, so it offers the next best thing: an installable app icon, OS-level shortcuts on Android, and single-purpose links that behave like widgets on iPhone.`)})})]})}var de={expense:`Expense`,revenue:`Revenue`,stakeholder:`Stakeholder`},Z={expense:`No custom fields on expenses`,revenue:`No custom fields on revenues`,stakeholder:`No custom fields on stakeholders`};function fe(){let[e,r]=(0,q.useState)(`expense`),{t:i,label:a}=m(),o=_(e,!0),{remove:f,reorder:h}=g(),v=F(),[y,b]=(0,q.useState)(void 0),[x,O]=(0,q.useState)(null),k=(0,q.useMemo)(()=>[...o.data?.items??[]].sort((e,t)=>e.sortOrder-t.sortOrder),[o.data]),A=async(e,t)=>{let n=k.map(e=>e.id),r=e+t;if(!(r<0||r>=n.length)){[n[e],n[r]]=[n[r],n[e]];try{await h.mutateAsync(n)}catch(e){v.error(i(`Reorder failed`),L(e))}}};return(0,X.jsxs)(X.Fragment,{children:[(0,X.jsxs)(`div`,{className:`flex items-center justify-between gap-3 mb-4`,children:[(0,X.jsx)(d,{value:e,onChange:r,items:t.map(e=>({id:e,label:i(de[e])})),className:`md:w-auto`}),(0,X.jsx)(P,{variant:`primary`,size:`sm`,className:`rounded-full shrink-0`,icon:(0,X.jsx)(te,{className:`size-4`}),onClick:()=>b(null),children:i(`New field`)})]}),(0,X.jsx)(u,{flush:!0,children:o.isPending?(0,X.jsx)(c,{}):k.length?(0,X.jsx)(`ul`,{className:`divide-y divide-line`,children:k.map((e,t)=>(0,X.jsxs)(`li`,{className:s(`flex items-center`,e.archived&&`opacity-50`),children:[(0,X.jsxs)(`div`,{className:`ps-3 flex flex-col`,children:[(0,X.jsx)(`button`,{type:`button`,className:`size-7 inline-flex items-center justify-center rounded-full text-ink-3 hover:text-ink hover:bg-card-hover disabled:opacity-30`,disabled:t===0,onClick:()=>A(t,-1),"aria-label":i(`Move up`),children:(0,X.jsx)(ne,{className:`size-3.5`})}),(0,X.jsx)(`button`,{type:`button`,className:`size-7 inline-flex items-center justify-center rounded-full text-ink-3 hover:text-ink hover:bg-card-hover disabled:opacity-30`,disabled:t===k.length-1,onClick:()=>A(t,1),"aria-label":i(`Move down`),children:(0,X.jsx)(V,{className:`size-3.5`})})]}),(0,X.jsx)(n,{className:`flex-1`,title:(0,X.jsxs)(`span`,{className:`inline-flex items-center gap-2`,children:[a(e),e.required&&(0,X.jsx)(l,{tone:`accent`,children:i(`required`)}),e.archived&&(0,X.jsx)(l,{children:i(`archived`)})]}),subtitle:(0,X.jsxs)(`span`,{children:[(0,X.jsx)(`span`,{className:`mono`,children:e.key}),` · `,i(e.type),e.options.length?` · ${e.options.join(`, `)}`:``]}),onClick:()=>b(e)}),(0,X.jsx)(`div`,{className:`pe-3`,children:(0,X.jsx)(D,{trigger:()=>(0,X.jsx)(`button`,{type:`button`,className:`size-9 inline-flex items-center justify-center rounded-full text-ink-3 hover:text-ink hover:bg-card-hover`,"aria-label":i(`Actions`),children:(0,X.jsx)(T,{className:`size-4`})}),children:t=>(0,X.jsxs)(X.Fragment,{children:[(0,X.jsx)(w,{icon:(0,X.jsx)(S,{}),onClick:()=>{t(),b(e)},children:i(`Edit`)}),(0,X.jsx)(E,{}),(0,X.jsx)(w,{icon:(0,X.jsx)(C,{}),danger:!0,onClick:()=>{t(),O(e)},children:i(`Delete`)})]})})})]},e.id))}):(0,X.jsx)(p,{title:i(Z[e]),description:i(`Add columns like “Client”, “Invoice no.” or “Reimbursable”.`),action:(0,X.jsx)(P,{variant:`soft`,onClick:()=>b(null),children:i(`Add a field`)})})}),(0,X.jsx)(ae,{open:y!==void 0,onClose:()=>b(void 0),field:y??null,entity:e}),(0,X.jsx)(N,{open:!!x,onClose:()=>O(null),onConfirm:async()=>{try{await f.mutateAsync(x.id),v.success(i(`Field deleted`)),O(null)}catch(e){v.error(i(`Delete failed`),L(e))}},loading:f.isPending,title:i(`Delete field “{name}”?`,{name:x?a(x):``}),description:i(`Existing values stay in the records but are no longer shown or exported.`)})]})}function pe(){let[e,t]=(0,q.useState)(1),[n,r]=(0,q.useState)(``),[i,a]=(0,q.useState)(``),o=v({page:e,pageSize:50,entity:n||void 0,action:i||void 0}),[s,d]=(0,q.useState)(null),{t:f}=m(),{locale:h}=b();return(0,X.jsxs)(u,{title:f(`Audit log`),flush:!0,actions:(0,X.jsxs)(`div`,{className:`flex gap-2`,children:[(0,X.jsxs)(O,{compact:!0,className:`w-36`,value:n,onChange:e=>{r(e.target.value),t(1)},children:[(0,X.jsx)(`option`,{value:``,children:f(`All entities`)}),[`expense`,`revenue`,`stakeholder`,`category`,`settlement`,`customField`,`recurringRule`,`project`,`import`,`backup`].map(e=>(0,X.jsx)(`option`,{value:e,children:f(e)},e))]}),(0,X.jsxs)(O,{compact:!0,className:`w-32`,value:i,onChange:e=>{a(e.target.value),t(1)},children:[(0,X.jsx)(`option`,{value:``,children:f(`All actions`)}),[`create`,`update`,`delete`,`import`,`settle`,`recompute`,`generate`,`restore`].map(e=>(0,X.jsx)(`option`,{value:e,children:f(e)},e))]})]}),children:[o.isPending&&(0,X.jsx)(c,{}),o.data&&!o.data.items.length&&(0,X.jsx)(p,{title:f(`Nothing recorded yet`)}),(0,X.jsx)(`ul`,{className:`divide-y divide-line`,children:o.data?.items.map(e=>(0,X.jsx)(`li`,{children:(0,X.jsxs)(`button`,{type:`button`,onClick:()=>d(s===e.id?null:e.id),className:`w-full text-start px-4 md:px-5 py-3 row-hover`,children:[(0,X.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap text-[13.5px]`,children:[(0,X.jsx)(l,{tone:e.action===`delete`?`critical`:e.action===`create`||e.action===`import`?`good`:`neutral`,children:f(e.action)}),(0,X.jsx)(`span`,{className:`font-medium`,children:f(e.entity)}),(0,X.jsx)(`span`,{className:`text-ink-3 truncate`,children:e.actorEmail}),(0,X.jsx)(`span`,{className:`ms-auto text-ink-3 num text-[12.5px]`,title:new Date(e.at).toLocaleString(),children:z(e.at,h)})]}),(0,X.jsx)(`div`,{className:`text-[12.5px] text-ink-3 mt-1 truncate`,children:me(e.before,e.after,f)}),s===e.id&&(0,X.jsx)(`pre`,{className:`mono whitespace-pre-wrap max-h-64 overflow-auto text-[11.5px] bg-sunken rounded-[10px] p-3 mt-2`,children:JSON.stringify({before:e.before,after:e.after},null,2)})]})},e.id))}),o.data&&(0,X.jsx)(x,{page:o.data.page,pageSize:o.data.pageSize,total:o.data.total,onPage:t})]})}function me(e,t,n){let r=e??{},i=t??{};if(!e&&t)return Q(i);if(e&&!t)return Q(r);let a=Object.keys({...r,...i}).filter(e=>JSON.stringify(r[e])!==JSON.stringify(i[e])&&![`updatedAt`,`splits`].includes(e));return a.length?a.map(e=>`${e}: ${$(r[e])} → ${$(i[e])}`).join(` · `):n(`no visible change`)}function Q(e){return[`description`,`name`,`label`,`amountMinor`,`date`,`inserted`,`count`].filter(t=>t in e).map(t=>`${t}: ${$(e[t])}`).join(` · `)||JSON.stringify(e).slice(0,120)}function $(e){return e==null?`∅`:typeof e==`object`?JSON.stringify(e).slice(0,40):String(e).slice(0,40)}export{oe as SettingsPage};
@@ -0,0 +1 @@
1
+ import{dt as e,h as t,m as n,n as r,v as i,y as a}from"./badge-BTiDEJlh.js";import{E as o}from"./queries-IGiwF8nF.js";import{n as s}from"./project-Bgpq3nFR.js";import{t as c}from"./breakdown-D9nBrbad.js";var l=e();function u(e,t){return new Intl.NumberFormat(t,{maximumFractionDigits:Number.isInteger(e)?0:2}).format(e)}function d({sales:e,compact:n}){let{t:o}=i(),{money:d,locale:p}=s(),m=e.totals.netMinor,h=e.payments.filter(e=>e.pulled),g=e.payments.filter(e=>!e.pulled&&e.amountMinor!==0);return(0,l.jsxs)(`div`,{className:`space-y-4`,children:[(0,l.jsxs)(`div`,{className:`grid grid-cols-3 gap-2`,children:[(0,l.jsx)(f,{label:o(`Receipts`),value:`${e.totals.receipts}${e.totals.refunds?` · ${o(`{n} refunds`,{n:e.totals.refunds})}`:``}`}),(0,l.jsx)(f,{label:o(`Items sold`),value:u(e.totals.quantity,p)}),(0,l.jsx)(f,{label:o(`Net sales`),value:d(m,{compact:!0}),hint:e.totals.costMinor?o(`cost {amount}`,{amount:d(e.totals.costMinor,{compact:!0})}):void 0})]}),(h.length>0||g.length>0)&&(0,l.jsxs)(`div`,{className:`flex flex-wrap gap-1.5`,children:[h.map(e=>(0,l.jsxs)(r,{tone:`revenue`,children:[e.name,` · `,d(e.amountMinor,{compact:!0})]},e.paymentTypeId)),g.map(e=>(0,l.jsx)(`span`,{title:o(`Not pulled into the ledger`),children:(0,l.jsxs)(r,{className:`opacity-80`,children:[e.name,` · `,d(e.amountMinor,{compact:!0})]})},e.paymentTypeId))]}),e.payouts.length>0&&(0,l.jsxs)(`div`,{children:[(0,l.jsxs)(`div`,{className:`label mb-1.5`,children:[o(`Cash pay-outs`),` `,(0,l.jsxs)(`span`,{className:`num text-ink-3 font-normal normal-case tracking-normal`,children:[`−`,d(e.totals.paidOutMinor,{compact:!0}),e.totals.payoutsSubtracted?` · ${o(`taken off the cash amount`)}`:` · ${o(`not subtracted`)}`]})]}),(0,l.jsx)(`ul`,{className:`divide-y divide-line rounded-[12px] border border-line overflow-hidden`,children:e.payouts.map((e,t)=>(0,l.jsxs)(`li`,{className:`flex items-center gap-3 px-3 py-1.5 text-[13px]`,children:[(0,l.jsx)(`span`,{dir:`auto`,className:`flex-1 min-w-0 truncate`,children:e.comment??o(`Pay-out`)}),(0,l.jsxs)(`span`,{className:`num text-ink-2 shrink-0`,children:[`−`,d(e.amountMinor)]})]},t))})]}),e.byCategory.length>1&&(0,l.jsxs)(`div`,{children:[(0,l.jsx)(`div`,{className:`label mb-2`,children:o(`By category`)}),(0,l.jsx)(c,{max:6,items:e.byCategory.map((e,t)=>({id:e.name||null,name:e.name||o(`Uncategorised`),color:a[t%a.length],amountMinor:e.netMinor,pct:e.pct,count:Math.round(e.quantity)})),emptyLabel:o(`No sales`)})]}),(0,l.jsx)(`div`,{className:`label`,children:o(`Items`)}),(0,l.jsxs)(`ul`,{className:t(`divide-y divide-line rounded-[12px] border border-line overflow-hidden`,n&&`max-h-[320px] overflow-y-auto`),children:[e.lines.map((e,t)=>(0,l.jsxs)(`li`,{className:`flex items-center gap-3 px-3 py-2`,children:[(0,l.jsxs)(`span`,{className:`num w-10 text-end text-[13px] text-ink-3 shrink-0`,children:[u(e.quantity,p),`×`]}),(0,l.jsxs)(`span`,{className:`flex-1 min-w-0`,children:[(0,l.jsxs)(`span`,{dir:`auto`,className:`block text-[13.5px] font-medium truncate`,children:[e.itemName,e.variantName?(0,l.jsxs)(`span`,{className:`text-ink-3 font-normal`,children:[` · `,e.variantName]}):null]}),e.categoryName&&(0,l.jsx)(`span`,{className:`block text-[11.5px] text-ink-3 truncate`,children:e.categoryName})]}),(0,l.jsxs)(`span`,{className:`text-end shrink-0`,children:[(0,l.jsx)(`span`,{className:`num block text-[13.5px] font-medium`,children:d(e.netMinor)}),m>0&&(0,l.jsxs)(`span`,{className:`num block text-[11px] text-ink-3`,children:[Math.round(e.netMinor/m*100),`%`]})]})]},`${e.externalItemId??e.itemName}-${e.variantName??``}-${t}`)),!e.lines.length&&(0,l.jsx)(`li`,{className:`px-3 py-6 text-center text-[13px] text-ink-3`,children:o(`No item lines on these receipts.`)})]})]})}function f({label:e,value:t,hint:n}){return(0,l.jsxs)(`div`,{className:`rounded-[12px] bg-sunken px-3 py-2 min-w-0`,children:[(0,l.jsx)(`div`,{className:`text-[11px] uppercase tracking-wide text-ink-3 truncate`,children:e}),(0,l.jsx)(`div`,{className:`num text-[15px] font-semibold truncate`,children:t}),n&&(0,l.jsx)(`div`,{className:`text-[11px] text-ink-3 truncate`,children:n})]})}function p({shiftId:e}){let{t}=i(),r=o(e);return r.isPending?(0,l.jsx)(`div`,{className:`py-6 flex justify-center`,children:(0,l.jsx)(n,{className:`size-5`})}):r.isError?(0,l.jsx)(`div`,{className:`text-[13px] text-ink-3`,children:t(`Could not load the shift sales.`)}):(0,l.jsx)(d,{sales:r.data,compact:!0})}export{d as n,u as r,p as t};
@@ -0,0 +1 @@
1
+ import{P as e,c as t,d as n,dt as r,g as i,gt as a,h as o,l as s,n as c,o as l,p as u,pt as d,s as f,t as p,v as m,y as h,z as g}from"./badge-BTiDEJlh.js";import{D as _,O as v,T as y,c as b,n as x,s as S,w as C}from"./queries-IGiwF8nF.js";import{n as w}from"./project-Bgpq3nFR.js";import{n as T}from"./table-DQsx5_iN.js";import{a as E,i as D,n as O,o as k,r as A,t as j}from"./menu-BDGd2JUq.js";import{i as M,o as N,r as P,s as ee}from"./media-Cr7juL5w.js";import{D as F,c as I,d as L,f as R,l as z,m as B,p as V,r as H,s as U,u as W,y as G}from"./index-DOwVPfdT.js";import{t as K}from"./format-GDcQVAp4.js";import{t as te}from"./color-picker-DLlr-Cq6.js";import{t as q}from"./money-Ch2MLu6J.js";import{t as J}from"./custom-cell-Wgh3D7lb.js";var Y={name:`arrow-right`,size:24,node:[[`path`,{d:`M5 12h14`,key:`1ays0h`}],[`path`,{d:`m12 5 7 7-7 7`,key:`xquz4c`}]]};Y.node;var X=i(Y),Z=a(d(),1),Q=r();function $({open:e,onClose:t,stakeholder:n,suggestedShare:r}){let{t:i}=m(),a=B(),{create:o,update:s}=_(),[c,l]=(0,Z.useState)(``),[u,d]=(0,Z.useState)(``),[f,p]=(0,Z.useState)(``),[v,y]=(0,Z.useState)(`0`),[b,x]=(0,Z.useState)(!0),[S,C]=(0,Z.useState)(``),[w,T]=(0,Z.useState)(``),[E,D]=(0,Z.useState)(h[0]),[O,k]=(0,Z.useState)({}),[A,j]=(0,Z.useState)({});(0,Z.useEffect)(()=>{e&&(j({}),l(n?.name??``),d(n?.nameAr??``),p(n?.email??``),y(String(n?.sharePercent??r??0)),x(n?.active??!0),C(n?.joinedAt??``),T(n?.notes??``),D(n?.color??h[0]),k(n?.customFields??{}))},[e,n,r]);let F=Number(v),I=c.trim().length>0&&Number.isFinite(F)&&F>=0&&F<=100,R=o.isPending||s.isPending,z=async()=>{let e={name:c.trim(),nameAr:u.trim()||null,email:f.trim()||null,sharePercent:F,active:b,joinedAt:S||null,notes:w.trim()||null,color:E,customFields:O};try{n?await s.mutateAsync({id:n.id,...e}):await o.mutateAsync(e),a.success(i(n?`Stakeholder updated`:`Stakeholder added`)),t()}catch(e){e instanceof g&&e.code===`CUSTOM_FIELDS`&&Array.isArray(e.details)&&j(Object.fromEntries(e.details.map(e=>[e.key,e.message]))),a.error(i(`Could not save`),V(e))}};return(0,Q.jsx)(W,{open:e,onClose:t,title:i(n?`Edit stakeholder`:`New stakeholder`),description:i(`Ownership share drives default expense splits and profit distribution.`),footer:(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(L,{variant:`ghost`,size:`md`,onClick:t,className:`max-md:hidden`,children:i(`Cancel`)}),(0,Q.jsx)(L,{variant:`primary`,size:`lg`,onClick:z,loading:R,disabled:!I,className:`w-full md:w-auto`,children:i(n?`Save changes`:`Add stakeholder`)})]}),children:(0,Q.jsxs)(`form`,{className:`space-y-4`,onSubmit:e=>{e.preventDefault(),I&&z()},children:[(0,Q.jsxs)(`div`,{className:`grid grid-cols-[1fr_auto] gap-3 items-end`,children:[(0,Q.jsx)(P,{label:i(`Name`),required:!0,children:(0,Q.jsx)(M,{value:c,onChange:e=>l(e.target.value),autoFocus:!n})}),(0,Q.jsx)(te,{value:E,onChange:D})]}),(0,Q.jsx)(P,{label:i(`Arabic name`),hint:i(`optional`),children:(0,Q.jsx)(M,{lang:`ar`,dir:`rtl`,value:u,onChange:e=>d(e.target.value)})}),(0,Q.jsxs)(`div`,{className:`grid grid-cols-2 gap-3`,children:[(0,Q.jsx)(P,{label:i(`Ownership share`),required:!0,hint:`%`,children:(0,Q.jsx)(M,{mono:!0,type:`number`,step:`0.01`,min:0,max:100,value:v,onChange:e=>y(e.target.value)})}),(0,Q.jsx)(P,{label:i(`Joined`),children:(0,Q.jsx)(M,{mono:!0,type:`date`,value:S,onChange:e=>C(e.target.value)})})]}),(0,Q.jsx)(P,{label:i(`Email`),children:(0,Q.jsx)(M,{type:`email`,value:f,onChange:e=>p(e.target.value),placeholder:i(`Optional`)})}),(0,Q.jsx)(ee,{checked:b,onChange:x,label:i(`Active partner`),description:i(b?`Included in ownership splits and distribution`:`Kept for history, excluded from new splits`)}),(0,Q.jsx)(P,{label:i(`Notes`),children:(0,Q.jsx)(N,{value:w,onChange:e=>T(e.target.value),placeholder:i(`Optional`)})}),(0,Q.jsx)(U,{entity:`stakeholder`,values:O,onChange:k,errors:A})]})})}function ne(){let{t}=m(),[r,i]=F(),a=r.get(`tab`)||`ownership`,s=e=>i(t=>{let n=new URLSearchParams(t);return n.set(`tab`,e),n.delete(`page`),n},{replace:!0}),c=v(),[l,d]=(0,Z.useState)(void 0),[f,p]=(0,Z.useState)({open:!1}),h=c.data?.shareTotal??0,g=e(100-h);return(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(n,{title:t(`Stakeholders`),subtitle:c.data?(0,Q.jsxs)(Q.Fragment,{children:[t(`{n} active partners`,{n:c.data.items.filter(e=>e.active).length}),` · `,t(`ownership`),` `,(0,Q.jsx)(`span`,{className:o(`num font-medium`,Math.abs(g)>.01?`text-warning`:`text-ink`),children:K(h,2)})]}):t(`Loading…`),actions:(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(L,{variant:`secondary`,size:`sm`,className:`rounded-full`,icon:(0,Q.jsx)(X,{className:`size-4 rtl-flip`}),onClick:()=>p({open:!0}),children:t(`Record settlement`)}),(0,Q.jsx)(L,{variant:`primary`,size:`sm`,className:`rounded-full`,icon:(0,Q.jsx)(G,{className:`size-4`}),onClick:()=>d(null),children:t(`New stakeholder`)})]})}),c.data&&Math.abs(g)>.01&&c.data.items.length>0&&(0,Q.jsxs)(`div`,{className:`mb-4 rounded-[14px] bg-warning/10 px-4 py-3 text-[13.5px]`,children:[t(`Ownership adds up to`),` `,(0,Q.jsx)(`span`,{className:`num font-medium`,children:K(h,2)}),`. `,t(`Splits use the active total, but you probably want 100%.`),` `,g>0?t(`{pct}% is unassigned.`,{pct:g.toFixed(2)}):t(`It is {pct}% over.`,{pct:Math.abs(g).toFixed(2)})]}),(0,Q.jsx)(u,{className:`mb-4`,value:a,onChange:s,items:[{id:`ownership`,label:t(`Ownership`)},{id:`balances`,label:t(`Balances`)},{id:`settlements`,label:t(`Settlements`)},{id:`distribution`,label:t(`Profit`)}]}),a===`ownership`&&(0,Q.jsx)(re,{onEdit:e=>d(e)}),a===`balances`&&(0,Q.jsx)(ie,{onSettle:e=>p({open:!0,prefill:e})}),a===`settlements`&&(0,Q.jsx)(ae,{onEdit:e=>p({open:!0,settlement:e})}),a===`distribution`&&(0,Q.jsx)(oe,{}),(0,Q.jsx)($,{open:l!==void 0,onClose:()=>d(void 0),stakeholder:l??null,suggestedShare:l===null?Math.max(0,g):void 0}),(0,Q.jsx)(H,{open:f.open,onClose:()=>p({open:!1}),settlement:f.settlement,prefill:f.prefill})]})}function re({onEdit:e}){let{t:n,name:r,label:i}=m(),a=v(),o=S(`stakeholder`),{remove:u}=_(),d=B(),{date:h}=w(),[g,y]=(0,Z.useState)(null),[b,x]=(0,Z.useState)(!1),[C,T]=(0,Z.useState)(null),M=o.data?.items??[];if(a.isPending)return(0,Q.jsx)(s,{});let N=a.data?.items??[],P=Math.max(a.data?.shareTotal??0,100);return(0,Q.jsxs)(Q.Fragment,{children:[N.length>0&&(0,Q.jsxs)(`div`,{className:`card p-4 md:p-5 mb-4`,children:[(0,Q.jsx)(`div`,{className:`label mb-2`,children:n(`Cap table`)}),(0,Q.jsx)(`div`,{className:`flex h-8 rounded-[10px] overflow-hidden bg-sunken gap-[2px]`,children:N.filter(e=>e.active&&e.sharePercent>0).map(e=>(0,Q.jsx)(`div`,{className:`h-full flex items-center justify-center text-[12px] font-semibold text-white overflow-hidden`,style:{width:`${e.sharePercent/P*100}%`,background:e.color},title:`${r(e)} ${e.sharePercent}%`,children:(0,Q.jsx)(`span`,{className:`truncate px-1.5`,children:e.sharePercent>=12?`${r(e).split(` `)[0]} ${e.sharePercent}%`:e.sharePercent>=6?`${e.sharePercent}%`:``})},e.id))})]}),(0,Q.jsxs)(l,{flush:!0,children:[!N.length&&(0,Q.jsx)(f,{title:n(`No stakeholders yet`),description:n(`Add the partners and their ownership percentage.`)}),(0,Q.jsx)(`ul`,{className:`divide-y divide-line`,children:N.map(i=>(0,Q.jsxs)(`li`,{className:`flex items-center`,children:[(0,Q.jsx)(t,{className:`flex-1`,leading:(0,Q.jsx)(p,{name:r(i),color:i.color,size:40}),title:(0,Q.jsxs)(`span`,{className:`inline-flex items-center gap-2`,children:[r(i),!i.active&&(0,Q.jsx)(c,{children:n(`inactive`)})]}),subtitle:[i.email,i.joinedAt?n(`since {date}`,{date:h(i.joinedAt)}):null].filter(Boolean).join(` · `)||n(`No contact details`),trailing:(0,Q.jsxs)(`span`,{className:`num text-[17px] font-semibold`,children:[i.sharePercent.toFixed(i.sharePercent%1?2:0),`%`]}),onClick:()=>T(i)}),(0,Q.jsx)(`div`,{className:`pe-3`,children:(0,Q.jsx)(j,{trigger:()=>(0,Q.jsx)(`button`,{type:`button`,className:`size-9 inline-flex items-center justify-center rounded-full text-ink-3 hover:text-ink hover:bg-card-hover`,"aria-label":n(`Actions`),children:(0,Q.jsx)(k,{className:`size-4`})}),children:t=>(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(O,{icon:(0,Q.jsx)(E,{}),onClick:()=>{t(),e(i)},children:n(`Edit`)}),(0,Q.jsx)(A,{}),(0,Q.jsx)(O,{icon:(0,Q.jsx)(D,{}),danger:!0,onClick:()=>{t(),x(!1),y(i)},children:n(`Remove`)})]})})})]},i.id))})]}),(0,Q.jsx)(z,{open:!!C,onClose:()=>T(null),title:C?r(C):``,description:C?`${n(`{pct}% ownership`,{pct:C.sharePercent})} · ${C.active?n(`active`):n(`inactive`)}`:``,footer:C&&(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(L,{variant:`danger`,size:`md`,onClick:()=>{x(!1),y(C)},children:n(`Remove`)}),(0,Q.jsx)(L,{variant:`primary`,size:`md`,onClick:()=>{e(C),T(null)},children:n(`Edit`)})]}),children:C&&(0,Q.jsxs)(`dl`,{className:`grid grid-cols-[auto_1fr] gap-x-4 gap-y-2 text-[14px]`,children:[(0,Q.jsx)(`dt`,{className:`text-ink-3`,children:n(`Email`)}),(0,Q.jsx)(`dd`,{children:C.email??`—`}),(0,Q.jsx)(`dt`,{className:`text-ink-3`,children:n(`Joined`)}),(0,Q.jsx)(`dd`,{children:C.joinedAt?h(C.joinedAt):`—`}),M.map(e=>(0,Q.jsxs)(`span`,{className:`contents`,children:[(0,Q.jsx)(`dt`,{className:`text-ink-3`,children:i(e)}),(0,Q.jsx)(`dd`,{children:(0,Q.jsx)(J,{def:e,value:C.customFields?.[e.key]})})]},e.id)),C.notes&&(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(`dt`,{className:`text-ink-3`,children:n(`Notes`)}),(0,Q.jsx)(`dd`,{className:`whitespace-pre-wrap`,children:C.notes})]})]})}),(0,Q.jsx)(I,{open:!!g,onClose:()=>y(null),onConfirm:async()=>{if(g)try{await u.mutateAsync({id:g.id,force:b}),d.success(n(`Stakeholder removed`)),y(null),x(!1),T(null)}catch(e){e.code===`HAS_RECORDS`&&x(!0),d.error(n(`Could not remove`),V(e))}},loading:u.isPending,confirmLabel:n(b?`Remove anyway`:`Remove`),title:n(`Remove {name}?`,{name:g?r(g):``}),description:n(b?`This stakeholder has expense splits, payments or settlements. Removing them deletes their split rows and un-assigns what they paid. Prefer marking them inactive.`:`If they have history you will be asked to confirm again. Consider marking them inactive instead.`)})]})}function ie({onSettle:e}){let{t,name:n}=m(),{range:r}=R(),{money:i}=w(),a=x(r.from,r.to);if(a.isPending)return(0,Q.jsx)(s,{});if(a.isError)return(0,Q.jsx)(f,{title:t(`Could not load balances`),description:a.error.message});let c=a.data,u=Math.max(1,...c.balances.map(e=>Math.abs(e.netMinor)));return(0,Q.jsxs)(`div`,{className:`grid grid-cols-1 xl:grid-cols-3 gap-4`,children:[(0,Q.jsxs)(l,{className:`xl:col-span-2`,title:t(`Who owes whom`),subtitle:t(`Expenses {total} in this period · company paid {pool}`,{total:i(c.totalExpenseMinor,{compact:!0}),pool:i(c.poolPaidMinor,{compact:!0})}),flush:!0,children:[(0,Q.jsx)(`ul`,{className:`divide-y divide-line`,children:c.balances.map(e=>(0,Q.jsxs)(`li`,{className:`px-4 md:px-5 py-3`,children:[(0,Q.jsxs)(`div`,{className:`flex items-center gap-3`,children:[e.stakeholderId===`pool`?(0,Q.jsx)(`span`,{className:`size-10 rounded-full border border-dashed border-line-strong inline-flex items-center justify-center text-[12px] text-ink-3 shrink-0`,children:t(`Co`)}):(0,Q.jsx)(p,{name:n(e),color:e.color,size:40}),(0,Q.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,Q.jsxs)(`div`,{className:`text-[14.5px] font-medium truncate`,children:[e.stakeholderId===`pool`?t(e.name):n(e),e.stakeholderId!==`pool`&&(0,Q.jsxs)(`span`,{className:`num text-[12.5px] text-ink-3 font-normal`,children:[` · `,e.sharePercent,`%`]})]}),(0,Q.jsxs)(`div`,{className:`text-[12.5px] text-ink-3 truncate`,children:[t(`Share {share} · paid {paid}`,{share:i(e.owedMinor,{compact:!0}),paid:i(e.paidMinor,{compact:!0})}),e.settledOutMinor||e.settledInMinor?` · ${t(`settled {out} / {in}`,{out:i(e.settledOutMinor,{compact:!0}),in:i(e.settledInMinor,{compact:!0})})}`:``]})]}),(0,Q.jsxs)(`div`,{className:`text-end shrink-0`,children:[(0,Q.jsx)(q,{minor:e.netMinor,tone:`flow`,signed:!0,className:`text-[15px] font-semibold block`}),(0,Q.jsx)(`span`,{className:`text-[11.5px] text-ink-3`,children:e.netMinor>0?t(`is owed`):e.netMinor<0?t(`owes`):t(`settled`)})]})]}),(0,Q.jsxs)(`div`,{className:`relative h-1.5 mt-2.5 ms-[52px]`,children:[(0,Q.jsx)(`span`,{className:`absolute left-1/2 top-0 bottom-0 w-px bg-line-strong`}),(0,Q.jsx)(`span`,{className:o(`absolute top-0 bottom-0 rounded-full`,e.netMinor>=0?`left-1/2 bg-good/70`:`right-1/2 bg-critical/70`),style:{width:`${Math.abs(e.netMinor)/u*50}%`}})]})]},e.stakeholderId))}),(0,Q.jsx)(`p`,{className:`px-4 md:px-5 py-3 text-[12.5px] text-ink-3 border-t border-line`,children:t(`Net = paid − share of expenses + settlements paid − settlements received. The company row is the shared account. All rows sum to zero.`)})]}),(0,Q.jsx)(l,{title:t(`Settle up`),subtitle:t(`Fewest transfers to clear everything`),flush:!0,children:c.suggestions.length?(0,Q.jsx)(`ul`,{className:`divide-y divide-line`,children:c.suggestions.map((r,i)=>(0,Q.jsxs)(`li`,{className:`px-4 md:px-5 py-3 flex items-center gap-3`,children:[(0,Q.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,Q.jsxs)(`div`,{className:`text-[14px] flex items-center gap-1.5 min-w-0`,children:[(0,Q.jsx)(`span`,{className:`font-medium truncate`,children:r.fromStakeholderId===`pool`?t(r.fromName):n({name:r.fromName,nameAr:r.fromNameAr})}),(0,Q.jsx)(X,{className:`size-4 text-ink-3 shrink-0 rtl-flip`}),(0,Q.jsx)(`span`,{className:`font-medium truncate`,children:r.toStakeholderId===`pool`?t(r.toName):n({name:r.toName,nameAr:r.toNameAr})})]}),(0,Q.jsx)(q,{minor:r.amountMinor,className:`text-[16px] font-semibold`})]}),(0,Q.jsx)(L,{size:`sm`,variant:`soft`,className:`rounded-full`,onClick:()=>e(r),children:t(`Record`)})]},i))}):(0,Q.jsx)(f,{title:t(`All square`),description:t(`Nobody owes anyone for this period.`)})})]})}function ae({onEdit:e}){let{t:n,name:r}=m(),{range:i}=R(),{date:a}=w(),[o,c]=F(),u=Number(o.get(`page`)??`1`)||1,d=y((0,Z.useMemo)(()=>({from:i.from,to:i.to,page:u,pageSize:50}),[i,u])),{remove:h}=C(),g=B(),[_,v]=(0,Z.useState)(null);return(0,Q.jsxs)(l,{flush:!0,children:[d.isPending&&(0,Q.jsx)(s,{}),d.data&&!d.data.items.length&&(0,Q.jsx)(f,{title:n(`No settlements`),description:n(`Record one from the Balances tab when a partner pays someone back.`)}),(0,Q.jsx)(`ul`,{className:`divide-y divide-line`,children:d.data?.items.map(i=>(0,Q.jsxs)(`li`,{className:`flex items-center`,children:[(0,Q.jsx)(t,{className:`flex-1`,leading:i.from&&(0,Q.jsx)(p,{name:r(i.from),color:i.from.color,size:40}),title:(0,Q.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,children:[i.from?r(i.from):``,(0,Q.jsx)(X,{className:`size-4 text-ink-3 rtl-flip`}),i.to?r(i.to):n(`Company`)]}),subtitle:[a(i.date),i.note].filter(Boolean).join(` · `),trailing:(0,Q.jsx)(q,{minor:i.amountMinor,className:`text-[15px] font-semibold`})}),(0,Q.jsx)(`div`,{className:`pe-3`,children:(0,Q.jsx)(j,{trigger:()=>(0,Q.jsx)(`button`,{type:`button`,className:`size-9 inline-flex items-center justify-center rounded-full text-ink-3 hover:text-ink hover:bg-card-hover`,"aria-label":n(`Actions`),children:(0,Q.jsx)(k,{className:`size-4`})}),children:t=>(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(O,{icon:(0,Q.jsx)(E,{}),onClick:()=>{t(),e(i)},children:n(`Edit`)}),(0,Q.jsx)(A,{}),(0,Q.jsx)(O,{icon:(0,Q.jsx)(D,{}),danger:!0,onClick:()=>{t(),v(i)},children:n(`Delete`)})]})})})]},i.id))}),d.data&&(0,Q.jsx)(T,{page:d.data.page,pageSize:d.data.pageSize,total:d.data.total,onPage:e=>c(t=>{let n=new URLSearchParams(t);return n.set(`page`,String(e)),n},{replace:!0})}),(0,Q.jsx)(I,{open:!!_,onClose:()=>v(null),onConfirm:async()=>{try{await h.mutateAsync(_.id),g.success(n(`Settlement deleted`)),v(null)}catch(e){g.error(n(`Delete failed`),V(e))}},loading:h.isPending,title:n(`Delete this settlement?`)})]})}function oe(){let{t:e,name:t}=m(),{range:n}=R(),{money:r}=w(),i=b(n.from,n.to);if(i.isPending)return(0,Q.jsx)(s,{});if(i.isError)return(0,Q.jsx)(f,{title:e(`Could not load distribution`),description:i.error.message});let a=i.data;return(0,Q.jsxs)(`div`,{className:`space-y-4`,children:[(0,Q.jsx)(`div`,{className:`grid grid-cols-3 gap-3`,children:[{l:`Revenue`,v:a.revenueMinor,signed:!1},{l:`Expenses`,v:a.expenseMinor,signed:!1},{l:`Profit`,v:a.profitMinor,signed:!0}].map(t=>(0,Q.jsxs)(`div`,{className:`card p-4`,children:[(0,Q.jsx)(`div`,{className:`label`,children:e(t.l)}),(0,Q.jsx)(`div`,{className:o(`num text-[18px] md:text-[22px] font-semibold mt-1 tracking-tight`,t.signed&&t.v<0&&`text-critical`),children:r(t.v,{signed:t.signed,compact:!0})})]},t.l))}),(0,Q.jsxs)(l,{title:e(`Each partner's share`),subtitle:e(`By current ownership · shares total {pct}`,{pct:K(a.shareTotal,2)}),flush:!0,children:[(0,Q.jsxs)(`ul`,{className:`divide-y divide-line`,children:[a.items.map(n=>(0,Q.jsxs)(`li`,{className:`px-4 md:px-5 py-3 flex items-center gap-3`,children:[(0,Q.jsx)(p,{name:t(n),color:n.color,size:40}),(0,Q.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,Q.jsxs)(`div`,{className:`text-[14.5px] font-medium truncate`,children:[t(n),` `,(0,Q.jsxs)(`span`,{className:`num text-[12.5px] text-ink-3 font-normal`,children:[n.sharePercent,`%`]})]}),(0,Q.jsx)(`div`,{className:`text-[12.5px] text-ink-3 truncate`,children:e(`Revenue {rev} · expenses {exp}`,{rev:r(n.revenueShareMinor,{compact:!0}),exp:r(n.expenseShareMinor,{compact:!0})})})]}),(0,Q.jsxs)(`div`,{className:`text-end`,children:[(0,Q.jsx)(q,{minor:n.profitShareMinor,tone:`flow`,signed:!0,className:`text-[15px] font-semibold block`}),(0,Q.jsx)(`span`,{className:`text-[11.5px] text-ink-3`,children:e(`profit share`)})]})]},n.stakeholderId)),!a.items.length&&(0,Q.jsx)(`li`,{children:(0,Q.jsx)(f,{title:e(`No active stakeholders`)})})]}),(0,Q.jsx)(`p`,{className:`px-4 md:px-5 py-3 text-[12.5px] text-ink-3 border-t border-line`,children:e(`Uses current ownership shares for the selected period. Individual expense splits are snapshots and may differ if ownership changed.`)})]})]})}export{ne as StakeholdersPage};
@@ -0,0 +1 @@
1
+ import{g as e}from"./badge-BTiDEJlh.js";var t={name:`archive-restore`,size:24,node:[[`rect`,{width:`20`,height:`5`,x:`2`,y:`3`,rx:`1`,key:`1wp1u1`}],[`path`,{d:`M4 8v11a2 2 0 0 0 2 2h2`,key:`tvwodi`}],[`path`,{d:`M20 8v11a2 2 0 0 1-2 2h-2`,key:`1gkqxj`}],[`path`,{d:`m9 15 3-3 3 3`,key:`1pd0qc`}],[`path`,{d:`M12 12v9`,key:`192myk`}]]};t.node;var n=e(t),r={name:`archive`,size:24,node:[[`rect`,{width:`20`,height:`5`,x:`2`,y:`3`,rx:`1`,key:`1wp1u1`}],[`path`,{d:`M4 8v11a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8`,key:`1s80jp`}],[`path`,{d:`M10 12h4`,key:`a56b0p`}]]};r.node;var i=e(r),a={name:`star`,size:24,node:[[`path`,{d:`M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z`,key:`r04s7s`}]]};a.node;var o=e(a);export{i as n,n as r,o as t};
@@ -0,0 +1 @@
1
+ import{dt as e,g as t,h as n,v as r}from"./badge-BTiDEJlh.js";var i={name:`chevron-down`,size:24,node:[[`path`,{d:`m6 9 6 6 6-6`,key:`qrunsl`}]]};i.node;var a=t(i),o={name:`chevron-up`,size:24,node:[[`path`,{d:`m18 15-6-6-6 6`,key:`153udz`}]]};o.node;var s=t(o),c={name:`chevrons-up-down`,size:24,node:[[`path`,{d:`m7 15 5 5 5-5`,key:`1hf1tw`}],[`path`,{d:`m7 9 5-5 5 5`,key:`sgt6xg`}]]};c.node;var l=t(c),u=e();function d({className:e,children:t,...r}){return(0,u.jsx)(`div`,{className:`overflow-x-auto`,children:(0,u.jsx)(`table`,{className:n(`w-full border-collapse text-[14px]`,e),...r,children:t})})}function f({className:e,children:t,align:r=`left`,sortable:i,sorted:o,onSort:c,...d}){let f=o===`asc`?s:o===`desc`?a:l;return(0,u.jsx)(`th`,{className:n(`label h-10 px-4 border-b border-line bg-card sticky top-0 z-[1] whitespace-nowrap font-medium`,r===`right`&&`text-end`,r===`center`&&`text-center`,i&&`cursor-pointer select-none hover:text-ink`,e),onClick:i?c:void 0,"aria-sort":o?o===`asc`?`ascending`:`descending`:void 0,...d,children:(0,u.jsxs)(`span`,{className:n(`inline-flex items-center gap-1`,r===`right`&&`flex-row-reverse`),children:[t,i&&(0,u.jsx)(f,{className:n(`size-3.5`,o?`text-accent`:`text-ink-4`)})]})})}function p({className:e,children:t,align:r=`left`,...i}){return(0,u.jsx)(`td`,{className:n(`h-12 px-4 border-b border-line align-middle`,r===`right`&&`text-end`,r===`center`&&`text-center`,e),...i,children:t})}function m({className:e,selected:t,children:r,...i}){return(0,u.jsx)(`tr`,{className:n(`row-hover transition-colors last:[&>td]:border-b-0`,t&&`bg-accent-soft/60`,e),...i,children:r})}function h({colSpan:e,children:t}){return(0,u.jsx)(`tr`,{children:(0,u.jsx)(`td`,{colSpan:e,className:`h-36 text-center text-ink-3 text-[14px]`,children:t})})}function g({page:e,pageSize:t,total:n,onPage:i}){let{t:a}=r(),o=Math.max(1,Math.ceil(n/t)),s=n===0?0:(e-1)*t+1,c=Math.min(n,e*t);return n<=t?null:(0,u.jsxs)(`div`,{className:`flex items-center justify-between gap-3 px-4 h-12 border-t border-line text-[13px] text-ink-3`,children:[(0,u.jsx)(`span`,{className:`num`,children:a(`{from}–{to} of {total}`,{from:s,to:c,total:n})}),(0,u.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,u.jsx)(`button`,{type:`button`,className:`h-8 px-3 rounded-[9px] hover:bg-card-hover disabled:opacity-40 font-medium`,disabled:e<=1,onClick:()=>i(e-1),children:a(`Prev`)}),(0,u.jsxs)(`span`,{className:`num px-1`,children:[e,` / `,o]}),(0,u.jsx)(`button`,{type:`button`,className:`h-8 px-3 rounded-[9px] hover:bg-card-hover disabled:opacity-40 font-medium`,disabled:e>=o,onClick:()=>i(e+1),children:a(`Next`)})]})]})}export{f as a,p as i,g as n,m as o,d as r,a as s,h as t};