UNPKG

@accounter/client

Version:
1 lines • 14.1 kB
import{t as e}from"./pencil-DlKYz-XX.js";import{a as t,c as n,i as r,o as i,r as a,s as o,t as s}from"./alert-dialog-BzvhmN97.js";import{An as c,Ci as l,Dn as u,Du as d,Ea as f,Ei as p,En as m,Fi as h,Gu as g,Ii as _,Jl as v,Kl as y,Li as b,Mi as x,Ml as S,Nd as C,Ni as w,Oi as T,On as E,Pi as D,Rd as O,Ri as ee,Ti as te,Tu as k,Vu as A,Xt as j,Yl as M,Yt as ne,Zt as re,_i as N,bs as ie,cd as ae,er as oe,hd as se,ji as ce,jl as P,kn as F,ma as I,qu as L,sn as R,vi as z,xd as B}from"./index-DJOqGznr.js";import{t as V}from"./page-layout-YyDTnnkE.js";import{t as H}from"./spinner-C2uZGztb.js";var U=B(`tag`,[[`path`,{d:`M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z`,key:`vktsd0`}],[`circle`,{cx:`7.5`,cy:`7.5`,r:`.5`,fill:`currentColor`,key:`kqv944`}]]),W=O(C(),1),G=`addTag`,K=()=>{let[{fetching:e},t]=P(I);return{fetching:e,addTag:(0,W.useCallback)(async e=>{let n=`Error adding new tag [${e.tagName}]`,r=`${G}-${e.tagName}`;z.loading(`Adding tag`,{id:r});try{N(await t(e),n,r)&&z.success(`Success`,{id:r,description:`"${e.tagName}" tag was successfully added`})}catch(e){console.error(`${n}: ${e}`),z.error(`Error`,{id:r,description:n,duration:1e5,closeButton:!0})}},[t])}},q=k();function le({className:e,...t}){return(0,q.jsx)(`div`,{"data-slot":`field-group`,className:v(`group/field-group @container/field-group flex w-full flex-col gap-7 data-[slot=checkbox-group]:gap-3 [&>[data-slot=field-group]]:gap-4`,e),...t})}var ue=d(`group/field data-[invalid=true]:text-red-500 flex w-full gap-3 dark:data-[invalid=true]:text-red-900`,{variants:{orientation:{vertical:[`flex-col [&>*]:w-full [&>.sr-only]:w-auto`],horizontal:[`flex-row items-center`,`[&>[data-slot=field-label]]:flex-auto`,`has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px has-[>[data-slot=field-content]]:items-start`],responsive:[`@md/field-group:flex-row @md/field-group:items-center @md/field-group:[&>*]:w-auto flex-col [&>*]:w-full [&>.sr-only]:w-auto`,`@md/field-group:[&>[data-slot=field-label]]:flex-auto`,`@md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px`]}},defaultVariants:{orientation:`vertical`}});function J({className:e,orientation:t=`vertical`,...n}){return(0,q.jsx)(`div`,{role:`group`,"data-slot":`field`,"data-orientation":t,className:v(ue({orientation:t}),e),...n})}function Y({className:e,...t}){return(0,q.jsx)(ce,{"data-slot":`field-label`,className:v(`group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50`,`has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col has-[>[data-slot=field]]:rounded-md has-[>[data-slot=field]]:border [&>[data-slot=field]]:p-4`,`has-data-[state=checked]:bg-gray-900/5 has-data-[state=checked]:border-gray-900 dark:has-data-[state=checked]:bg-gray-900/10 dark:has-data-[state=checked]:bg-gray-50/5 dark:has-data-[state=checked]:border-gray-50 dark:dark:has-data-[state=checked]:bg-gray-50/10`,e),...t})}function X({open:e,onOpenChange:t,tag:n,onSave:r,isSaving:i}){let[a,o]=(0,W.useState)(``),[s,l]=(0,W.useState)(null),[{data:d,fetching:p},g]=S({query:f,pause:!0});(0,W.useEffect)(()=>{e&&g()},[e,g]);let v=(0,W.useMemo)(()=>d?.allTags??[],[d]);(0,W.useEffect)(()=>{e&&(n?(o(n.name),l(n.parent?.id??null)):(o(``),l(null)))},[n,e]);let C=async()=>{a.trim()&&!i&&(await r(a.trim(),s),t(!1))},T=(0,W.useMemo)(()=>{if(!n)return v;let e=new Set,t=[n.id],r=v.reduce((e,t)=>{if(t.parent?.id){let n=e.get(t.parent.id)??[];n.push(t.id),e.set(t.parent.id,n)}return e},new Map);for(;t.length>0;){let n=t.shift();if(!e.has(n)){e.add(n);let i=r.get(n)??[];t.push(...i)}}return v.filter(t=>!e.has(t.id))},[v,n]),O=M(a);return(0,q.jsx)(w,{open:e,onOpenChange:i?void 0:t,children:(0,q.jsx)(D,{className:`max-w-[calc(100vw-2rem)] sm:max-w-lg`,children:p&&v.length===0?(0,q.jsxs)(`div`,{className:`flex flex-col items-center justify-center py-10 gap-3`,children:[(0,q.jsx)(H,{className:`size-8`}),(0,q.jsx)(`p`,{className:`text-muted-foreground text-sm`,children:`Loading tags...`})]}):(0,q.jsxs)(q.Fragment,{children:[(0,q.jsxs)(b,{children:[(0,q.jsx)(ee,{children:n?`Edit Tag`:`Create Tag`}),(0,q.jsx)(h,{children:n?`Update the tag name and parent category.`:`Add a new tag to organize your finances.`})]}),(0,q.jsxs)(le,{children:[(0,q.jsxs)(J,{children:[(0,q.jsx)(Y,{htmlFor:`tag-name`,children:`Name`}),(0,q.jsx)(x,{id:`tag-name`,value:a,onChange:e=>o(e.target.value),placeholder:`Enter tag name`,dir:O?`rtl`:`ltr`,disabled:i,onKeyDown:e=>{e.key===`Enter`&&C()}})]}),(0,q.jsxs)(J,{children:[(0,q.jsx)(Y,{htmlFor:`tag-parent`,children:`Parent Tag (optional)`}),(0,q.jsxs)(m,{value:s??`none`,onValueChange:e=>l(e===`none`?null:e),disabled:i,children:[(0,q.jsx)(F,{id:`tag-parent`,children:(0,q.jsx)(c,{placeholder:`Select parent tag`})}),(0,q.jsxs)(u,{children:[(0,q.jsx)(E,{value:`none`,children:`No Parent`}),T.map(e=>{let t=e.namePath&&e.namePath.length>0?`${e.namePath.join(` / `)} / ${e.name}`:e.name;return(0,q.jsx)(E,{value:e.id,dir:M(e.name)?`rtl`:`ltr`,children:t},e.id)})]})]})]})]}),(0,q.jsxs)(_,{className:`flex-col gap-2 sm:flex-row`,children:[(0,q.jsx)(y,{variant:`outline`,onClick:()=>t(!1),className:`w-full sm:w-auto`,disabled:i,children:`Cancel`}),(0,q.jsx)(y,{onClick:C,disabled:!a.trim()||i,className:`w-full sm:w-auto`,children:i?(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(H,{className:`size-4 me-2`}),`Saving...`]}):n?`Save Changes`:`Create Tag`})]})]})})})}function Z({onDone:e,children:t}){let[n,r]=(0,W.useState)(!1),[i,a]=(0,W.useState)(!1),{addTag:o}=K(),s=(0,W.useCallback)(async(t,n)=>{a(!0);try{await o({tagName:t,parentTag:n}),await e()}finally{a(!1)}},[o,e]);return(0,q.jsxs)(q.Fragment,{children:[t?(0,q.jsx)(y,{asChild:!0,onClick:()=>r(!0),children:t}):(0,q.jsxs)(y,{onClick:()=>r(!0),className:`w-full sm:w-auto`,children:[(0,q.jsx)(L,{className:`size-4 me-2`}),`Create Tag`]}),(0,q.jsx)(X,{open:n,onOpenChange:r,tag:null,onSave:s,isSaving:i})]})}function de({className:e,...t}){return(0,q.jsx)(`div`,{"data-slot":`empty`,className:v(`flex min-w-0 flex-1 flex-col items-center justify-center gap-6 text-balance rounded-lg border-dashed p-6 text-center md:p-12`,e),...t})}var fe=d(`mb-2 flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0`,{variants:{variant:{default:`bg-transparent`,icon:`bg-gray-100 text-gray-950 flex size-10 shrink-0 items-center justify-center rounded-lg [&_svg:not([class*='size-'])]:size-6 dark:bg-gray-800 dark:text-gray-50`}},defaultVariants:{variant:`default`}});function pe({className:e,variant:t=`default`,...n}){return(0,q.jsx)(`div`,{"data-slot":`empty-icon`,"data-variant":t,className:v(fe({variant:t,className:e})),...n})}function me({className:e,...t}){return(0,q.jsx)(`div`,{"data-slot":`empty-title`,className:v(`text-lg font-medium tracking-tight`,e),...t})}function Q({className:e,...t}){return(0,q.jsx)(`div`,{"data-slot":`empty-description`,className:v(`text-gray-500 [&>a:hover]:text-gray-900 text-sm/relaxed [&>a]:underline [&>a]:underline-offset-4 dark:text-gray-400 dark:[&>a:hover]:text-gray-50`,e),...t})}function he({className:e,...t}){return(0,q.jsx)(`div`,{"data-slot":`empty-content`,className:v(`flex w-full min-w-0 max-w-sm flex-col items-center gap-4 text-balance text-sm`,e),...t})}var ge=`deleteTag`,_e=()=>{let[{fetching:e},t]=P(ie);return{fetching:e,deleteTag:(0,W.useCallback)(async e=>{let n=`Error deleting new tag [${e.name}]`,r=`${ge}-${e.tagId}`;z.loading(`Deleting tag [${e.name}]`,{id:r});try{N(await t(e),n,r)&&z.success(`Tag Deleted`,{id:r,description:`[${e.name}] tag was successfully removed`})}catch(e){console.error(`${n}: ${e}`),z.error(`Error`,{id:r,description:n,duration:1e5,closeButton:!0})}},[t])}};function ve({open:e,onOpenChange:c,tag:l,onConfirm:u,isDeleting:d}){if(!l)return null;let f=M(l.name);return(0,q.jsx)(s,{open:e,onOpenChange:d?void 0:c,children:(0,q.jsxs)(r,{className:`max-w-[calc(100vw-2rem)] sm:max-w-lg`,children:[(0,q.jsxs)(o,{children:[(0,q.jsx)(n,{children:`Delete Tag`}),(0,q.jsxs)(t,{children:[`Are you sure you want to delete the tag`,` `,(0,q.jsxs)(`span`,{className:`font-semibold text-foreground`,dir:f?`rtl`:`ltr`,children:[`"`,l.name,`"`]}),`? This action cannot be undone.`]})]}),(0,q.jsxs)(i,{className:`flex-col gap-2 sm:flex-row`,children:[(0,q.jsx)(a,{className:`w-full sm:w-auto`,disabled:d,children:`Cancel`}),(0,q.jsx)(y,{onClick:u,disabled:d,variant:`destructive`,className:`w-full sm:w-auto`,children:d?(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(H,{className:`size-4 me-2`}),`Deleting...`]}):`Delete`})]})]})})}function ye({tag:t,depth:n,hasChildren:r,isCollapsed:i,onToggleCollapse:a,onEdit:o,onDelete:s}){let c=M(t.name);return(0,q.jsxs)(`div`,{className:v(`group flex items-center justify-between gap-2 px-3 py-3 border-b border-border`,`hover:bg-secondary/50 transition-colors`,`sm:px-4`),children:[(0,q.jsxs)(`div`,{className:`flex items-center gap-2 min-w-0 flex-1`,style:{paddingInlineStart:`${n*20}px`},children:[r?(0,q.jsx)(`button`,{type:`button`,onClick:()=>a(t.id),className:`p-0.5 rounded hover:bg-secondary transition-colors shrink-0`,"aria-expanded":!i,"aria-label":i?`Expand`:`Collapse`,children:(0,q.jsx)(se,{className:v(`size-4 text-muted-foreground transition-transform rtl:rotate-180`,!i&&`rotate-90 rtl:rotate-90`)})}):n>0?(0,q.jsx)(`span`,{className:`size-4 shrink-0`,"aria-hidden":`true`}):null,(0,q.jsx)(`span`,{className:v(`text-foreground font-medium truncate`,c&&`text-right`),dir:c?`rtl`:`ltr`,children:t.name}),t.namePath&&t.namePath.length>0&&(0,q.jsxs)(`span`,{className:`text-muted-foreground text-sm hidden sm:inline truncate shrink-0`,children:[`(`,t.namePath.join(` / `),`)`]})]}),(0,q.jsxs)(l,{children:[(0,q.jsx)(T,{asChild:!0,children:(0,q.jsxs)(y,{variant:`ghost`,size:`sm`,className:`opacity-100 sm:opacity-0 sm:group-hover:opacity-100 transition-opacity shrink-0`,children:[(0,q.jsx)(ae,{className:`size-4`}),(0,q.jsx)(`span`,{className:`sr-only`,children:`Actions`})]})}),(0,q.jsxs)(te,{align:`end`,children:[(0,q.jsxs)(p,{onClick:()=>o(t),children:[(0,q.jsx)(e,{className:`size-4 me-2`}),`Edit`]}),(0,q.jsxs)(p,{onClick:()=>s(t),className:`text-destructive focus:text-destructive`,children:[(0,q.jsx)(A,{className:`size-4 me-2`}),`Delete`]})]})]})]})}function be(e){let t=new Map,n=[];e.map(e=>{t.set(e.id,{tag:e,children:[]})}),e.map(e=>{let r=t.get(e.id);if(e.parent){let i=t.get(e.parent.id);i?i.children.push(r):n.push(r)}else n.push(r)});let r=e=>e.sort((e,t)=>e.tag.name.localeCompare(t.tag.name)).map(e=>({...e,children:r(e.children)}));return r(n)}function $(e,t,n=0){let r=[];return e.map(e=>{let i=e.children.length>0;r.push({tag:e.tag,depth:n,hasChildren:i}),i&&!t.has(e.tag.id)&&r.push(...$(e.children,t,n+1))}),r}function xe({search:e,allTags:t,onChange:n}){let[r,i]=(0,W.useState)(new Set),[a,o]=(0,W.useState)(!1),[s,c]=(0,W.useState)(!1),[l,u]=(0,W.useState)(null),[d,f]=(0,W.useState)(!1),[p,m]=(0,W.useState)(!1),{addTag:h}=K(),{deleteTag:g}=_e(),{updateTag:_}=R(),v=(0,W.useMemo)(()=>{if(!e.trim())return t;let n=e.toLowerCase();return t.filter(e=>e.name.toLowerCase().includes(n)||e.namePath?.some(e=>e.toLowerCase().includes(n)))},[t,e]),b=(0,W.useMemo)(()=>$(be(v),r),[v,r]);(0,W.useEffect)(()=>{e.trim()&&i(new Set)},[e]);let x=(0,W.useCallback)(e=>{i(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},[]),S=(0,W.useCallback)(e=>{u(e),o(!0)},[]),C=(0,W.useCallback)(e=>{u(e),c(!0)},[]),w=(0,W.useCallback)(async(e,t)=>{f(!0);try{l?await _({tagId:l.id,fields:{name:e,parentId:t}}):await h({tagName:e,parentTag:t}),await n(),u(null)}finally{f(!1)}},[h,l,n,_]),T=(0,W.useCallback)(async()=>{if(l){m(!0);try{await g({tagId:l.id,name:l.name}),await n(),u(null),c(!1)}finally{m(!1)}}},[g,l,n]);return(0,q.jsxs)(`div`,{className:`min-h-screen bg-background`,children:[(0,q.jsxs)(`div`,{className:`max-w-4xl mx-auto px-4 py-6 sm:py-8`,children:[(0,q.jsx)(`div`,{className:`rounded-lg border border-border bg-card overflow-hidden`,children:b.length>0?b.map(({tag:e,depth:t,hasChildren:n})=>(0,q.jsx)(ye,{tag:e,depth:t,hasChildren:n,isCollapsed:r.has(e.id),onToggleCollapse:x,onEdit:S,onDelete:C},e.id)):(0,q.jsxs)(de,{className:`py-8 sm:py-12`,children:[(0,q.jsx)(pe,{children:(0,q.jsx)(U,{className:`size-8 sm:size-10 text-muted-foreground`})}),(0,q.jsx)(me,{children:e?`No tags found`:`No tags yet`}),(0,q.jsx)(Q,{children:e?`Try adjusting your search query.`:`Create your first tag to start organizing your finances.`}),!e&&(0,q.jsx)(he,{children:(0,q.jsx)(Z,{onDone:n,children:(0,q.jsxs)(y,{children:[(0,q.jsx)(L,{className:`size-4 me-2`}),`Create Tag`]})})})]})}),t.length>0&&(0,q.jsxs)(`p`,{className:`text-muted-foreground text-sm mt-4 text-center`,children:[v.length,` of `,t.length,` tag`,t.length===1?``:`s`]})]}),(0,q.jsx)(X,{open:a,onOpenChange:o,tag:l,onSave:w,isSaving:d}),(0,q.jsx)(ve,{open:s,onOpenChange:c,tag:l,onConfirm:T,isDeleting:p})]})}var Se=()=>{let[e,t]=(0,W.useState)(``),{setFiltersContext:n}=(0,W.useContext)(oe);(0,W.useEffect)(()=>{n(null)},[n]);let[{data:r,fetching:i},a]=S({query:f}),o=(0,W.useMemo)(()=>r?.allTags??[],[r]);return i&&o.length===0?(0,q.jsx)(`div`,{className:`min-h-screen bg-background flex items-center justify-center`,children:(0,q.jsxs)(`div`,{className:`flex flex-col items-center gap-3`,children:[(0,q.jsx)(H,{className:`size-8`}),(0,q.jsx)(`p`,{className:`text-muted-foreground text-sm`,children:`Loading tags...`})]})}):(0,q.jsx)(V,{title:`Tags`,description:`Manage your charges tags.`,headerActions:(0,q.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,q.jsxs)(ne,{className:`max-w-xs`,children:[(0,q.jsx)(re,{placeholder:`Search tags...`,value:e,onChange:e=>t(e.target.value),className:`ps-10`}),(0,q.jsx)(j,{children:(0,q.jsx)(g,{})})]}),(0,q.jsx)(Z,{onDone:async()=>{await a()},children:(0,q.jsxs)(y,{className:`w-full sm:w-auto`,children:[(0,q.jsx)(L,{className:`size-4 me-2`}),`Create Tag`]})})]}),children:(0,q.jsx)(xe,{search:e,allTags:o,onChange:async()=>{await a()}})})};export{Se as TagsManager};