From 93ffdf3c862a2c795a8484d5f2bfe3a828232679 Mon Sep 17 00:00:00 2001 From: Sean O'Connor Date: Fri, 1 Aug 2025 14:21:10 -0400 Subject: [PATCH] Add global animation system and entrance effects to UI --- public/beenvoice.afdesign | Bin 0 -> 22216 bytes .../_components/animated-stats-card.tsx | 84 +++ src/app/dashboard/businesses/page.tsx | 6 +- src/app/dashboard/clients/page.tsx | 6 +- src/app/dashboard/invoices/[id]/page.tsx | 14 +- .../_components/invoices-data-table.tsx | 15 +- src/app/dashboard/invoices/page.tsx | 8 +- src/app/dashboard/page.tsx | 103 +-- .../settings/_components/settings-content.tsx | 70 +- src/app/dashboard/settings/page.tsx | 4 +- src/components/data/data-table.tsx | 2 +- src/components/data/status-badge.tsx | 10 +- src/components/forms/invoice-form.tsx | 11 +- src/components/layout/floating-action-bar.tsx | 10 +- src/components/layout/page-header.tsx | 22 +- src/components/ui/skeletons.tsx | 352 ++++++++++ src/hooks/useCountUp.ts | 133 ++++ src/styles/globals.css | 637 ++++++++++++++++++ 18 files changed, 1363 insertions(+), 124 deletions(-) create mode 100644 public/beenvoice.afdesign create mode 100644 src/app/dashboard/_components/animated-stats-card.tsx create mode 100644 src/components/ui/skeletons.tsx create mode 100644 src/hooks/useCountUp.ts diff --git a/public/beenvoice.afdesign b/public/beenvoice.afdesign new file mode 100644 index 0000000000000000000000000000000000000000..94d76175ba871f0c3492f56a9e93122ca1ed229e GIT binary patch literal 22216 zcmeGD^;;ER*aeIqy1ToirMp8yLb_49Q@W(3Lpr5PN?HYJ=~lW!NwxysI7MOg#fZ$&~mbfi131U}9w9JOsf zdKL!+P4bb!$2idDAz3hh;G*h|!vn3^sp8~Lmy1T+&!#J~NwB&n`rTuhTsiA!-QQR=GT>za%?r!QBFR&(Zm0RqMHp=9&ZT|ou^^j*O)a0WE~kjZ zoBK2*Duurm&@lusRYJiK1kx<<-Zhu%Lxw7w^Atm z4VHu0)bNE!8X{qjkiss!3$C!i(ZmrsawvhBN~xX0J&rVl@FtvEuRauQ28tl9Zi#WV z2-DqsHFP!^SVubA6-(hbsuDc)swPageN`xBIgnuypWqAcPke3%NxWzHGAx%p(!~qN zZPLZ8kHKl^iW=iRXfnB`)`+Qo4bOUpD;X9lBO3pq66eFb3vM0Gz}r&J15D_c4c`xWZ4voUk~YOD+i z_p1sSgSZ#*!jZ%*Sh~TRQv-v-2PxE4Qg*|uJXS@4F6D9N{8#(`R7J?46b)T`>=XCb z-J*g;U3^|Tu(*YF8Pgg2v{Yz`;J^F$rS8wxGrJ9qniObbYY7)Ii_f(8W}M!-v+e(( zr(D+WV%+B%spg?4ZV6>ckd$|3J}emQ9K#j!Mps=ir~4uoTRsp`{H^OXi@(hCuc03Y zoS7YisqWXaT8p-}i%xmMq!Q8!P@h61j?)Z@?Gviaz{%di%e-9nzYT8WhkxMiX85ZF z2J_i&emzPga4guGrV498S=sVVoz8OllE0Q~)^gx9%Hj{Bh6&L<3!;1q{ZYrWs#Yc* zy)RQ0CX6vK>7%Y^$>O~)X!@&dj%Wq}sIePRtrm_tQ?uWjdgn)@>(qy3<}s(BP{4Ed z()V)=yhyl0Ipz{mf9h=$&bJ6e$;?W^3H2}CO1gNc9jq*ajp+MR_mHsc3aR`O`3t+4 z&K;ri2C26#%`n{>ME$-3_aeKyr;AkxZaucDtQp>xbN;|MVa2yI2oFu|<7wd?yIHlm z*ptQEHBDX2xvgk`#bzLini-AU>|k=6_0j2U zYDW5Ir+Q;&v7CRh*+;;sdh-@O7LQP}nc3{iFM?NZrSL0Hnj6Hm=d@Glj5i+r%NFkx z7lTzqEaC7#%qkZZ4b z5@axp*QH;R#E{=4tah1D&~12IO43tP8}p)b{_8Tc!(B7S`o zrcDZ-VB9Kv$h1?VAeeSxoVKWqeO7&?O_nnqDI5Gfz3OrOXdtHeN->m0(##58KoSCv zCI^X0#FXBEGd?tng0aRP(I7%~bw0A3`8LdBO@5G7`IJ?89P$W zJ;2ZUi$0s%;@YP^YnaI&ii8>*s6-yczjY$i^GD|^Q}w-p-?!mY0DY?zf;+SWq4P&w z6?dY3`*kR>8&cyL;u+y2rtDer>+UhA&l*Uj^G}% z?Q&~8~9N?JZxg7jTf0C)Lt+4_RIRiTSjw@-$ zG@D}L;iC}?#jty~3-!=Jk388&5;mpVNhK}B=oz+mvv28;%y0jBy2xb&tM5gkXEa?V zZ)Lq-3CY?PPI-QY=$^Bogs?4DeD8og3PQ(h^b&gG^R{>_Zb$JnDea)5nvMlw=tbi! zIe%I0+|6Vq1RF_tSI_a2^fSv5`B*3b=BJL%6tjF502d5Hffx)FiqhmcCiuP)xdCC9$Ff7*4k# zm(lRH4{~%{7{uuEbe}UsN@E!sB6U%#XWE-PHh@q9tu|xYMi&(RcJcq-tB0ECj^pb@Tz8E?c^3e;?v=9~Eyd`8KYa8e1467jr z@7^=^Y;Ab7vlj?jLEN-lDVGTCbjIr+Jf54@Yp@WaU+&|{&(gU{f+moW57%cD4U6`0 z5Tb`hUr2Y0+=T>s#pg-B=9pGg!AQ!Wl`af{N5?`MM6b~+c31y2!F^e+YP>ZqHH%s<0a?- zrftf8lIIt?C%Tc%3N%E*U~(`!z!~C zoU2*u^uWc!tmhj8Asah6QzI&n<#?(yN)1e$gqdX(|1EH001_!=3*auAEr+WLg69oW z3P{Z9?o2(ye_74)#t^;2LsaRr=V%aR#$dj;-ul)&D`NWj$a*VYsb=D~cX;15%7Ywc zdA0uchvq3|el4$~$%nhs)L2~62p{1*O~=he${6&fx+<)QjEmIG&8QD)Y{0w9viifk zWsGgA4~0yhQx*1(T8*vXD`q|Ce{$+*P+d_sBI8>}Pwu}hyh@11i(OUcx}QJZIm{C8 zrdKWYwyV9ls?<5)caXE*rm-pKJL4Kt6?$~VK*(hkxWhnT?|4+X=en+9#({EZxo-=sNl<586zQl$H$@w*+Lw!dgT=|F@Fa@yJ>hiba%wtw)GdiR%p-o%zNpsSVDRC zKDZbM??=Tz0Ys?#z}4)(Sei1q*u6bP&19vC$=o|OCubci=WLtjuWI>*XGdH^v<}42 z{L*+I2S`$T{dq0+G70t4@#a5imJIBj-+ltiRH00GHOjpJ0KTD|_@gJ$wcb!{Ft*4$Z1nf5z--G>4r?u0#c z!~P9}#rI1NGxnZ=k7+sv<$B%-{hC)S)=4JTV|%XeWc;?YGDAuGi@ido+0d3eEt^z?-$Dl9AL<-BTV10Sj;H6wH_V09dnY&#K>?K=;ATfXNg_RpA}E(;1e=&Xr1vZwZ22sb9YMM z4o;Xw*E1gDez9XuhQXJpTSCw1km80_y-!~5>EXF8^0~dF#)9!1{foJuj}8WP0(!^6 zRIgdSNHVzS43qwOy9^_}U;hzdao7ap(r}^!ma|POG_Iiw+5a1$Amyy;mR~A7_c;Acio{;{) zwOGJIrt8M-Bk}a5QzQx5=-pcAeH3c0FXY6yA0-nMeeUEF@kZ{TramrhziLY4&!?$Z zMX9nR5zw7@Y;^H_?)L<1Ki@~7GN3ZmSfYt^LuAni6*Ce2OJ4LoPD8vD7hukw3Jc_K z@Fc15blSMCTu}3H+h{$d_k*Sc7SXGpD;Suh>5l`hUTtkiZ)d|bzMuv5*wD{)Dm3^S zoX;RF2?OXo%DhQHbq%hGs9rcI$+!!KZ9zb;011lWuE>Q^;JDyX)Y#x$ho%LaY| z1N8n|u&*cE(#2>GUCfr#@U{A}0t6hJeK7>gYE@GWiCNP0=|lY?W9%#>vBe51Y*Y<9 zIb@j_&$J}4_fg*VyBD!I(B59_9UcJgUtv(Oz`&6)jw2a$bH_C?bOt1oK#YzOZ+-`-2{u47mg zbyer$U(+nFD<~1Ve!Ih2p2fQUHJAEFZ86|Ll{-M>hh-rBe!)fF#@@PRO!bF9?8!F; zGVnPCJE8<*Hm^Su#IQ0Y)Y5Ced!&l7OrAU(j@LOH_N>Y{{)V3k)I@84J-S3p{JLgp4Rd4G=iQ5`N630vdZt7 zSmT+r)GI2(GCj3CMZKlYqnh5v_rLu7OcQ>>b+FD^2FmYCk-PPox_9F5l%n$#EN%r| z42ADgtYWyg)%U7=AWoWsLnAB--zQ_zvnrHZN(H-~J*Ieqa|65F^a3eYX^Xa%xWf7TFv$)NR`{7*D2FUMx z%Y^?1Tm2crNDuMsvq<2m*3;X>Kr%v3gJT{bJqz{vLYu&W#m`1LepGj3Z(l>__E2Hb zp+(t}Gh<+MyKW&+kdT?T4qss5Tz7=WuG?}wb~|yjK7Uxl?%1aMG5#@wtMMT-?)a@% zsrOg6XU7w>F-yUFMw>McKC5hB&bkaAlo-R6Z?8)al-Xe>P_{{m(YRr~P}}jpsyIyd zUY_Nn_YVPOhFgEYA_Dx0y_Cd1_OP{^bn%j*Y^`NdCro1G`>?=Jj5)^y-DM8%uM6v6 zkw#}59PX@8-5!4!wbIWQDS?KI)SO~Oa3mq!n`68VMb`=m zBgiU5ytlFosw4RW6^I?OprL&6u?{o229MA@h_-$K=Mc41mcTPY=w-e7oN~TY0^U)u zjZ(f87G8~-qyuRf^vC(kt!yFt)p%0Pt+wuiP*XCY9&WRa=$eQ-pl*rObPF+FlYCE|W{&WD=*I2SRrNO+GB)ge8!Igq z)+_B0MBZ4tZb|HKES5+#v@ei3xfxJjXPy2QJ`SKob~x!Fwt8UWxtG%jC6_(vCoK=8 z|0Ip2|Bh#%u6H=?-8M_;B5YQkRH&{lQnh}!E7@{cs3!-ISMnH>Xt@UUNG1~VcF*=M z1-utmldhO<-%v|1Lu;q>Cvh(^dP1OFRtX}Yzupv*f&NRaVOWI9p)N9;Z~B}=*))!V z>yj>^{P_l6k`6IvT6>S84U=Yrm}H;2<7rU*VoNjG0ZbHHr|q8*sMb3u2>2gHXNu3>p~*@L_vMbJ})@J zjW0Yrd;UXrEb|+KhTq~AL3MLCMemdBM6;v@@#$X5#?qqgl(j*v7ioGXQrSC6Um%L9 z2T{C~OfE-~lU<9Km6e`D%_+ptxfNFb^&Bcs31=x~u)m&db;~uP;syJBgwuD(9(>}7 zb#khCI*r?f7q#;swA?jt$gWO(7k8#53}b6x$;kX=)15?DC1LS_RJK)vPyp#!GUOTV z)Ne>p9=Vx5#5jbp8`})2o+1P)Vd3>-7K+r}W|H1l`6ytazoJq`<(Mpwi?{Vsld|jV zLEEe^6EiM(b*JIQQ6dq2DFf=qWd6h3>h5SRvW(ee%TNPKVFr7>fBLNru-wo`wL%yw z3roL(N5iR(=aH>~H7fb{0zqpMo(2x(gff2bmZ?X0Q$?Jiizp~g7=iJgEmZpc zZRB32cBk1R`8!a*fBA$x7riQsdQ;lxSLnN75ck?o;0uiEDwqsc&rn#4(9mF@u#5CU z5dnI(PAFERtRDp(l@8{e3dX!3L4f{{4(6VMVO(6pL%&N0b4~?gT+G8mo1}xEPr=YH zzQRMRrGuF-D&V0N(!s1#Qs@^^@X!M3sKOtQuL^@nFKpqVncxWfb%=M&p^q;MVR-wl zh<7BRk8*`Dk_#GmXoNJ3c8Uh|0tN@oohpcWlq{6O+3!NQI}CX=nUX@e_!sslTnNM3 zcSX3H4|(J-gkkP;A>4V$z(}WPkS~Japl_sM9Q*6=caAc_Oc%CrP$hg%lk0 zl{5^0N($r7QYILGN?zG1=f@*U&_>_f?PfdHiYfMeouG!epYk^H-{1k4LW7nLN?xU_ z=_il2`H?%D5@aZBc-!Dcu=M$;o=YRFZF*JXI~r`PKWKPkaQsl(8Pq z-V@3Uk-jISr_X`=L25>bg3qX0I=6*D072^0Xl!_fjWQ;SJ3xo~gVYKa+*^dlsK%UP4haG2&Xw8lRI5 zeuGW1ts}c48VQl{m{}LmQ01Sk!`mH}VlmQ}f*v`c;}&{e_Jp6W?&%tBw5>S#3CwPp zWIn%rwjB4p+(d0)`Tl+9&A7m@W#KfH;S}w@t#e0Frsk}bQ&5w{Tio0w6U|(qJ~@=< z-*>db)O(ZM+9Jw&mApuZDh_{5P8qy6@;T+x%X-V~tYc-} z06sQO{jnDxZ5Cw{ruZX5J-#E!Zw?9e2^NK0T9*Wht>o_}?KK=>>o5lhdZBuKIQ4=f z@jiUiz^R(y8#gj0qs?c>_f1cA)?Az&qlfR_rPso2_z*}VY$yI*GT~^LiOj2kOIY3} zZwciWQ)Ez>lr2i|0uh&en5_VJ*hx&HE1gBgTXg#r-?j(8Qd~>OaW}a&W^7UXK~MPb zC8RMtW(Ok5)ANC@UXhVMd*qMDd-L5GtKa5d#e>uAq!VIb6$!~(@q#u5LUC&Ly>2cb@x1tK=J&dMBl73B*s2wum3Vo;4VKWJkvDQ{X|Ph zr*POf_}K~}@m$o@!|D6yWu~|q$uDW)ZnjAn$@SyATURWlMF)SOEM(^ru!`lQV;~w5 zCw00ieOejmeCg5PD6ytMMeVq>9ImKTN?kN(EMn+PzQE>?Z7H^!C`gU9c0oPHH_0A` z7X5LR9^;>mmn0!2e+V@j{yH7JYPQ7d*Ize(?J~EO9nc>ARE^Q2CYpQXEnG(BEL5ZF~4{t@>Tx7imM+Q42F21D_M+YN4_@J}ZV~q}aZG zyeRN5;+hGoN#&Tl+s+a}3b=sZD%cAhmza6|i>S7&kE)4!blK^P?XjlMp$XQXzvyCA(P6z*7vfGpR1s~B^1ia8SP+uOh%^rS$wpt z>(IdPF#s*6$NO&`r)@-L-cjSsh5ww_S3|qBWi8_=BGLZx8R{8cH>^s+pV)Y+yepIy zA!T`sx%zN6rrSjgwDckGM7N4_HDv3zuZ#(Aw1$2op;39qlMxnezy31AL^66}Ct0k& zv|b}lKT5V?4MQK9KwW~~iT5|aDY=|~yQ)!++w|ALjE+<{%!wSSpy_(h`D#u)DvpDv zZoZC~fIjjs>N>cg^$(jcvb*>Gr;b;88{~m+3d3>!el}Zi<9znFC}a793hmcIf2d8nC&G6VbI!;@zbL2AaRReF&WW9M^-NdV6 z5w-cWDk?p-vAXM0_sz53u*Vs5#M_f7-jO@x*FSc5O4*c&4=|4HRvbPFC?_y}`!%v` zuVlS`JJ$6ix}*hZMRsQB1cl(t?zY-;gH06|xWIIEtq}mIj^KLw3XT zqK*x>$OhXt$tBi_UrgD5EhQqVG%Zj3D5shco55Cdwa7tT{h~zoKDyoQ6+E(#|MA~W z|DC_NW)YAAuQWt!x-H!-$?ua(+YxE@eR?5ts;;3P_!`aLoz2-3LS2fs;@xCiz5R@^ zA8Mj!JC#(8-svLcD?7y1ss*TYa87!Nw<+>pF?wX;>}+P%Ga`A$7_>1A$Rg9iBr8M( zcBLGse5R#scNEMAVrW%Dh<}KkQP2N&A+GAS$9EQKb3!yuOzxLffb&>$QJInoYr$V! zj*@S4l1Wz5S9|HNN#G{c#wI|BK89N8{Q7xC-MLZtFt+pgKkKxdznAqd?zA7hlljI8p}q8o$x#|xiCkwvB`6P*dRnd^8yf?A(B zr2r3coOXq5n)p*=1U=iMpo0Ll!Za@z=O}$t&Uc=iTV72}@bNpX82?DWkA%S)>n!(i zlLwkHbXR_p3-hU$UPaMsouFaSHtS#f{`-du#`EFoW`x`HQ@Suu@zWj1>jj)-5?yzc zg$&t4g|`Hy<`E1Q=keTcm-1?^v)GUAX1ZqDp9y>Un8tO;wZFZ=x9-w5>NneA-}cS- ztxUd65$4TK%@s3L6rooA7hWs&uHlgB&xM&P5rLa;RMoHF$t7K7OeB^!0T#oj+~uQG z+$@B$(sUxbOjC}Y`d-8HA{w!5dXR!}An%;I8ZV+~Rx_ zt76UmD*kS|Lf#1CnS2TNX5kxa(z>(l<*}<<(02n=|C=v^UkBTDO3C>{ z`P$_A#=RfZISF&`FDLB!J#T5`i{x=yj>$PTkzrtAP|)EA6S)3c{%>~I|J&>@xc}Wx z9elz=;Qw2F`M=xtlmF+-|IHZFDfHrjCkNZC`@3#{0&}(Gv@-XE2OIwHD3)ALYw7>< zH;5J2Q)_hWoGqSyf6fhoQ2p;OG~hd2jE0&b7CJdP*oLL_Qcmls0br>@MF#K7X4l5x z1MTfgLk|c9yYJ}*m(Gq&0fEp$l;mV|d_Nwq`WfiXK1!WjoA1(&JljA;kH)2C2``kj zDqlk;x-?0TBIM)g$nX=W{VejDudcNG+ToK(sbQtPgUB{w>6(Vkb3!5=S(y#)Az$3d z$Hz^a;OK6{fPz5mp~v?8!HTq&Ym+#>qe+t=w!^}Szok*>-s39$bUZ}Il|`kKyJmsV zzQ>h)77Y)1S`GXER{#I>#*p+8fu63e`FdyI_~Y2*Bu;*QzJ+PZQwNI2P(xVKm7hI( z#(&>r(&4WOdFtS11b)P)&zHDJ5OBO`#Q)j+|GS#BUkwq3PyC%VI%37kF$eZ+<`NVn zzP-J57>$UGEH?h?BKisMCsG1DB=Ps#>%VVG%ggDRnNe`4#k&iF9~Uid5m2yc1q6sP zGBV!!_(Xm9fV1u1%A`AmUZ#bnt*za%v$DE+I!F_|U#RdNw^)LVj7)Xi8UY!z5K@S+ zNdJ1$GN+Ju6f@a&kE6~)Diai zOPNS10$-+8nI5a7um8Kcu2WV)0l8c?`xj>vGT1RGQPvrvp{*T`MIlJb%&bUq*|Rg6 z=?1;?QZ10Ag5F=x4-24yvsc=Ck!_SHeyFz|CC*!Yph!zkH~&45@Xcc{QLRqpslVmp z;2?u;3*UXXc=`Ce3=5bK4i6jr&TYhfPYPdsRtLLyT5%vlD%1-GA}~li4Kr=iGBW6y zn2;|oFP)8WK&wkj?7gw2ot-&?9&c^m%$FGoxvupUy@)!Q?|N*htpf%9Xc^F5gi?k+fJ5P zR76*jRL399|W!ym)LXo2@v@?f8(Hh+#SVQlmW_^+<( z17MdTt;&u4eN;t7MbG1<%hpA-dhy{D#2Ry$k%{47yq;oyjnEt0mkXH|Xm%G}u*%hA!Xe7rCE1`NKYmR49w z3O*QRSed| z7cY2R*V+YF?W;e3#s;G?_z1mEPE8G8{_0v%RaLdvSYBTK*3j|+eI}s@qxYYh>6Q*y^q#9jE@nQPfp%uWoHZA zH%Y-B2%>Ok1~z|0;nC21Q2anGU_1fF#l^)XOCms!o}S*!!lKx1H8nNW_?;BLjk9wC ziHWbw??VAy6O+V?3(xXKYHI5G#zy?hyZ-+E=no$hK{$Zk7#SHcS`lrhBdu?0dSPZp zD=seH?0T&`@vUB|v?JcfL5TcPxs z(`s9KWp6>?6c%*X@R*~Y868WypJaIq#C~PV%V>MG#8prw1MAlMxiNBvxcwxcdb*p<> ze{P&82rA#xei9zf{VC#bu~+qvF8l%xGc4~TBJ81}wVIVWFI7}tI5|CUY-~g<7+hK+ z@9gY+f(lWezt1hO76DZE4Ge7cMqqGA7Jiy;anyew8A;E=@^b1PTB*)5=mv5}Hy~+Y z^b{GBwEMxjr_H^P<8|jdGEi9h0DSqbKZFjdZ!CXt4zI3ee?kUF)^gmkva&46KvDne zzX@e3ndqIj2+~18l9IRE1Q&l-Dfn#0q^+&Xq6M7uWQ)3+?Wd={`?x+g?Rh3*v|&wgSp^c7zk@VoKt})uZoG- zSoGIjL2pjHj8f9l`gA6yr?t~^gO!!hGoBlUJyi_`h8N)Qz7N!36lf)HHW1#Oj|&+s z>(ny*7RGL9Xt+7~frCdtQ1bI>r<{kgQLdZqRQ0!~Tk;7erjp9a%D4ms;U6ULP%G5( z@ZX)IgcKLkAFX%M#1V7!;z&Jo-`{Ume*dh>WEra#v9e-hX=fJ=sy$CSzyqSoC5sJV zY~wFZJ@w{4yBqLynX>?ss!S7X-c3f4Ec+;%d*A6&fK`R=RQ zHw=J-1O)|s^Zb)C_xY#J3&_du4^kFq+ru1*=NQQ#D>gRFWC~0HqDVDjDz{k1g+Dymm&6!GxzuKa9L6~4K-S?7McT&oh7gd}R- zB;b_+NA43`$5V+BGchqu0Z2P;U&_eIiS;|*wLgAPQc^<2#vW+(*z?^pwwp+#62m1T zDoceD0qDRZCy%Y`yhF#s!z<1Y0Qm#}`it6<8|*Rg{rmT3pdw|7`!&wh>Feu90gR!e zr#Ve|=S78e(b$F0q=An)G2GqbXKwoeXfYObKO ztcgi};qO~eHv2#>;Zjp40_t+GoimvWxTN{{?l=n<*ZlCMgQFt=6;rd#-iYE?L%YJ* z%xWLILAuF{6o>*IcyrV=`P6i8-oJbjkeWB|x*pErKK-nYi9s718_TcG4YsysWK#Rc za+eyc4Klg^;r3iWauPgla587?`p46wtgTH{HCGS|4Gpb0?|dkk0pxnQ+H#Q&8@T=+ zaqQYZEs~EnmbDX72H(AF3-eO}#213{rE1-O_lA`aeV6Pn92{KO=hOY43{UVZ`u$d@ z^Dl^g0qV)W(V#%h)tS~cFd406DMnNo@Xa&vRT z{YJV{$KppM)=O2@nZ@mxD<&bKOcA$~^3MCeVh?wRbzvX4I5_&3UAs6e5*8|T*q)j# zARs_qpi-nk%f_bs-stoiv_dscRQHhJ+f(40&wqYn)S>X^4HfZo1KNFqIUetZ0TIK3 zM}P%CyMlvd=7m9!dTb*h;6A>YtLr2`L%VtL%wm)6Q_-I;bDRwS{N{V_=qLstQ4!(c2w?EsfEECf zW8+}9x_wf}=kM!h%*+_d-Tba=;=67|$ai;lZ{6HNzke57Sy?I6s(h*`)%tZ?yW_d- z1HMg-jrCT;`0pNX_uf@Mrh#xh%g41fGds}{1BA)#@<7+h#)e)@ELUF)kmv@_KUy^= z9XYPE*)7f484(dkYwylqwcj070}dnifm$LdH#cr(MhB<}3!snMnVvshOsli7vTk;m ztO2Pc^>|aV@ZbthaO-PqAt50HBco!Ey@^k? zweo)8Ne>SXKXpo77DC~-8zCD-yeKFr?H9jP!V-}}E-o&-1z1m4T0O%2<;laOF)%Q) za&t>SZX+QffkM6^;U^&_MMJ{*TKeTn)PMev58+vLU5`1}2;rfja7RZ+Qyl?53(Lzd zDs||=en4%3xxVdT2NXgs8{nX%lJ9)a=N;~F0RIDV^P8w;dwY8WP@kxlmP@|F%(9`` zSt3vtWPN>on|>!#4$?6&AgE+=_9rtaW=-ZMCx<#Oe|e%2o4N%+t5{tBT^-vQ9~-N8 zTI3ze6C(jgHJ(uk5)=#`9u?KNIAWvAs%SigklI_p!52~3o8SL+T5_&eYBSduG{866 zPP(*ERqNIE?iB=2w8zqlijrFnCO*Mt_F=E0ynMfQaOSX;L7OKlG3V=>u`@x?mET%h z%}3H$Z#KelPQG?Qu|WM(od;Y&*zfEaP+h&%L4tyUZ$TM3fGR5~{bYdv79g*thOKQ# z*91ERiU~Y7WFlh*TK)ug;AkzR@g&5=TStpc(Q$E>kG+z?kKzD%Ha0hVUS}d>{X-}M zfmUxn&D1j($0{XN;G>3MYirwnIzX{MUuPPpG6D#344@Pz%2}Ql`p5?y_Bv(;x`ga}!> zyR(A5@nZS7r@#g!g_xOP*oqgElp6w~jluh9q35u2Cskc?Q{d{2q2X}#=)09~Zr}Vb z*+9ZhZM`D!edqC})txa22EDdP6%&a1Eev$#o2esELEOi31mapBK#SfUF9|%6H;3g0 zfWQCoF_u==bmfSzYyK+CFHC`u=sEp8_>>gtnv0b5Sa&OCl+R)Cf!>8E6`e)l=_ zbWsVIp1PbQk3anLN8(oE`rmrj>^ok-v<=#QdCJubCRXB%G&MuP>3GtepExlv1gtov zJohzfUbo`Eh{UvS!LqTjLB+utRHO;)d#Hz=Y`!>J{r+{aKp=pz^>re^7RQf=U6p_m zV|SFS+ZF^y&Q|O5F$<&&TSdpm%c-hjo(sgr#rbgngYkyjBdh>Ca<&0NZcKzMWblQ; zU?SBIFcUay#1wF{sbAe-pepmGewl${4bl~IZY8kcRyPhhXY=@YTt||RPn%fXDQb;#jCJNy1yU)Kl zyK_Q-D7!IkK*{dSjxTcOSE;=a<5wcy+1w0GXV>RVU;XM@@JY#^e0qL(=U?))1~bX)8yd{na&vN)iUO34i?u4V zQlY?S+Dz9s`MK}^d+>uT^}+5myT`vZiE^i0WMt$l9?M7tiQ~_oKl=hokUb)J9i$&% zO9R9XF^5s#!|u+DGObMjstavi>`$@)*dw)dmGhCnF|lu#Nv^BoI^X^V03w`q{4Zcd zSuV{#qHyNzkln(4*8HOW{AsPP$2~ng9ou`75Yq|XAWxs9SN7y`iipQ9cOVOe4VvSR z|Jon_R0AXeuB_PD`5`A)S2jx`nnfC@Mizrh9<)}+QiE<|e&|QX#{wgqsN&SsyXSp= zJ0nC1pRdJ1>{?8ukl^DN{~XZk{yqP`1tnA+(oJpv=v^Toeq(#iXpRt2Q}4&#a!;28 z7Dxs@6>CIfWC!Q_J|Ie-oVO<&0QS`09uqtO@&RMl4#ttz8!JMqKS*YIJg|f6I$qPS z0#B6q^3s}Zbg2wyzmv+n^`i(4a)I{=ox*_392ZFuTnONEPqI%Z!&R#gUjp@{moHzMC6?X}jgI~p zNoRj@L~F0a?HoWf73Yn1cSC@^p$Zq$Ms^C=imGWL@FI$t-lBs`WXmilz)Ac))A_k( zI1bd)sS0(P^2X<&eLz+sx9mJsj~VRFzM&VK3fIM=z_|e}bSOxSjg374fA*mz$jcV0Yb<7>Z&RYQ&X-x<(jJl;FXQ7!g8209F+H;weQxiVZ3?$8gYl% z4uss)MIhJB>TH<`2>=~)P%nqZ$K{`l-RWuh@v=8SmH^3DR9FZBlC(HaU$v;Hs5t+F z*NWa7NO#+p*0whCRHj!JY@=b9aV^02Vq|1=C|EOC*3{Iba}YC-8Umc!_hbXE&GQfa zQp@GV1wT2=m3GdCsg{SEySqCSA$wOASe@Lf5Oy}UEbpqB>1j)ope4e?L-uDh%8oax z%^X0v_`3W&4^!`iT|J1I2b!j*rI`UGCEDd;Xt=12^PD^?^M5?Mw{PEe1GISidjJbK zK#u-P6(51ul9-rCD*U$a(;gARA(rvcdF7#vMTgs3M}Yp}=%P_dK>?Q$Bq=jLqEeSCZX>*Skn;+dmJWMa4Em!Ls{ zj5|(t5zKiL5)-562b9DB(Jfo4Bl#x~*EMh*R#Ho13#3E4NB3daf+=pz?=J`bkegko zE5>uLBbMX+A;AB$2CM*`&5r!qyb8ss57vxZMKE)5nV?*;x3p{NVB_GhW&@97F)!V8 z3GVyv$TdSUfy-ZzQmO)EaXQO)}H<|s^}V)2}d>`h$jQujbkn7-g&J9Nkl~C_+V7;hzliTy{~r8`=7-t z*m8z}$!Ov)(Cw4NJ+bBbEvoIM+b~JQD5%*2{#&S9_%dZ4yvlyb{lIiOQT!(HFFJ?mNb`s{=5WPvA8;r zGcq~p+M=&WvI={*t6=w=Z^B<~Zf1!J&e6E#)Ia))*ZuHH~>VS4-fvdJg!MhLKS$@Fc4_jJ34jfuo&1)AtUX zsHm|~>qK>Xw;mY+(7v`4x#k7h+S*z%)6^z|u&{wM*_<~fr7$i)ueoOBFiZ-;npdBf z*FZS@t|$o7GUjAtL;~{Xjt>TqXCm#)50qZ=$&QBldNcp5pU;%EJPr;HvI64szvjj; z87v#Ud6TfTWTZJi6&E9r^k=@VVE-1=Kw$0oa=2n>YAT79KwDRr2w;w!Va1985Lm$G z7`WJEVP|(FfrFfUBPry7hj?`b&oKi}LyXTgXqwny8DPfG&&za3z_tgusqtOC9}r#O z=%1)&sK4=q3GM$X!_bD%dgDL}LS&WUAO)?&=n=A0yXtM-cR7HWnIA1Q7=2FgSHD~R z?sYh@f>n^3%HS{m6tm|;Un^pWWxt9()y*m3(dz|I+--jZ+`EP9xUYLDaW7DDI5Eu2 zGQYe4kPUL6ZL1_EfLWC`mR@5zV{r{RL1S4ucNc0n#eyuc&v~zO1{!}SGQTKA=>}*G zTCB>K10=KD=!aEO$2!>nBL}ywJ~Y*j!kW$J4S#dWIU#0&?k)!2Wy4ujf(>6v%+E=I ziNi4;-8=vcA{1;&4KX1m5s}-L-5Z`i!$OGh%=)fj(i2@Mu;HKTDd6&tj zyBBtLL(OO(+bCJy0mBd*aArRnu8{KJuV23CiCuKxb+WOrNWXfOP{?>{;qO3O3mi06 zIB5$D`v2S*iZlU#i^X&>6C+=o)rj*3cs@M;qRTik zW-!VNxp;Vz;X?#%%+29Iqgxzr&(F>@3=D3b?a%Mdb&Z>^T0Q6D!T}Pw_?3b+^xg8} zV#_jAy;+7SwFrA(!s|np8By)7_1d% z<|REMgU19X*Cg;c;D4rDa)4zFlxgteGMegef;mTN*QS@H7S<-R#JEmVoUm=rxVjc( zPKsS}KaexI(OIMu{tsg25YjPMPC69^r9T;_B^0b&# zSQ{6;fea%i-=xrtb5aGjXRNe!b??uo<>us20uFH6ivA?#?XJZx=QKRmu8V<}Tnr6mG8Y`wKA3L_c zxVYGHt2Xp@W~P+oOAo!LUI!&4h9C#I+DnGv&;;eTov$Cc1qvfBE1TDG3u;hGTKety z$IUvNFm!BUKVlve&vvxhiPKgb=P>yLPchK6Wn+(5z=CLZP52O-aWaM=o_ufwCxV zKZILex(lvubr(&#ARR}@Pm`WITelBk?!J1u1cia4-GJ3`W;4Q8dJQ{ZFqga@7)a?F z)6qBgjp66#Pk2O9RZ+SB$3i!Yb-`1)fv_ypn5>uiT0hiCzIj(k({OZj zeI{tJ{x5fzWntlW~4C8eBfx*#|2 zmtPLX1$eg5)ld2?Wa^$R7#bdS1EI-y0rltW%*VAc zA73dS{{-j5y(dy*LqPb1^WZw!?BYdAV}b&FMmy=v_xDKi0lQZil)0hWvB;{ zBGmOyU5UlT+wK;fk!CWP2|igyk55)F96GYtrZKzeD{T&&{Ti;#jNgVF zXvL37XJZ!)xUQh|$`lH++?H3yQhpCu_vtsT^7i%)4GXKr=}wGv$Z>W#GTmPhj*m;2 zO9qsrcsc8kloV2QbaX<#0$e#Ompb?yqXUT-vTB&#oIU*fL0D}?QTOq;hnVw!$}|oq zL%j+p-xM+FsSDX9nC>-12}ZMJu1%K{yC>?&lO_)XEv+wz^D=tWA2TMw&j2^7I++`_Wsuf`zEkGpxX=lR&Hgakp|~{BR%)BImhA8~@dw34VG7LU|CGf$KSCO3ResP`GeMTp^HvF5C$s2m_ zw&H!AKQVL5)3bwYrUvBvi8oZ6bx~My|9FFgNfTFxSf+m^R@<=f}jE%jE zb82P$%*@OzXmoFuX|`Djk6ks{__qs(sb|C}6iS9zVddu$Il#&*f0Ut(Tty-LFi@$% zvs;LpfZyikRnVrG_OKd+nTkC%i{Q>|w)?qrd-6re!U6&U;*irR0jq~OxBYy4RBrZ` zZo&Iq_|Q6BPXZY-{pqK)(oz9HTfz_K%w%Yut*BFc{`0vLGBUiAUHL8-dpc}e=y@@M zT~G+=lJ>x<+K}U%1QU0l<2O#vzo!iNadtz>a$5^id#`8feZ>O?g@I|F9g&v>`S-1& z;)U6{z|kpCT@pc0&4T+Lb+g&ohBj}(t49z0o)`AuLEUzeUuto0ymdg>r9xW=zlsb~ z>928xOg9S{$oIcJ6B25gW7pBuMd`@?i5c=fDY{`K6YXQ7)xI95h8l5P8Ou~f+g!7* z?&^pGjZnHhGd4ChY`wV}uUl!1)$D)0H9}BGXz1_%X=silX*8=b`^f6Y%3MyWs#0KU zHSt)>o_>W*rkH=AYa59~0v%4x%bAOX>nZv~#q*l91(}@P8gB365=qT+?o>!06M~FA0e?sM1W8W zpVrdj&DP|hNsf|7WerQq%ZH~*25#Qo_Z%D5`*uC=Csd=SI4D7pfScH`;r3ys%WUX7 zsV$EUBwlysS-f*rio!UpWGr$Z$!?mnu+Xlj-wP_~==XYWHV(zq#MPV%xEd!>1lj*& z6Aq-GH98Nz%@>AmRREcgd9WZrI7I0t zS2Tz07KX3*e9jx>`e8ysXlknXUdLKp+_O%2&m%wD6W1i%HV4=2{QO9qnxY=VA@2^* zj0lM$2g)MttnM!Ycff4N7s^L}{>G{bAYa=sv-3O-dm~*v*?T_Uye^U?HxU&BvT}O$ z!-3YfdWG^pt+|&9+a;DvRKx3WRxm+nQmLiQqWdY3V7} zNL5(V){po5FI{eJcCfR%hgEb?d(ixHh{1A8An zd`RYNBtj;j`Bta&&3oAFYiMnaD_f3zi)0*a!!KjymO)zrgf+GZ0re1;uo&K%O>uGx zhY44_#`nXSJ|tM&MjHj;LK-sMg@Hps-N|Lug2KWS!oD90mt&lW>1%13(cAgc4J>#y zyukvmDRN%X0da9IM6BLY`|rf=@V~z_H|G#j_75W?qva1zBN>aAyX4RK4b_A(qVJvu zHii?DT2$3oTe}UkTgTo$voj>g(9lr9u36+4q2u~8W81~};%T4fScFX^-7?u{hl7GT zNx@%GBab)Bri=pFN{sCo-eWi|UYMft~#dS4;_Cy5`#n z%dV*W;)!RnVSPG-%aD;9 zb*oGSZ0c3eHeQeDYgX8(kfVR+K?DS($oV0#G;JFb?kx5DMqX4UTk>Rn#c~6^JA*z9 zwUpSEpnM%N291a6?LEhK)l7!!NKD^^K0A^8sD#1Tk4D2n4I%v#g5z=KHxL8$k*1%1a_y_On(G^t}wFSMH*8w zsM(jiylwib$ZvMoien7-jecjbk5~~9ijGGXg|-oy6&IVprFRkYk!3$XLc=3jCuQR| zm`}CP0MJ0FEsHZ9Io}|V_I_q2e@;4K6t$d4fe@Vkf*}f!X4f)Qi!6Hyv;UjMMs2+A zxnN3EEl7%>qlvSJ~zieh!(;6ZNailEanL0bds zQ0HG17802TSf-35eNPOxA9~A_0R6szyoBdkQr@$EEh|5t1(g&|m zqrRBkel#+I$)Zem_`%cj_>m(==!~cD8>$8dD*K9p8FF|nvZ7zX*-BY8A(MBaYj$^c zt9@bt{sNeOC>U^?($v%2f$SRH+fYo6%2j5$VKZiQ_Uu_?)2b0VT2PZqx{zgB3Wo-v zj + +
+
+ +

{title}

+
+
+ + {change} +
+
+
+

{displayValue}

+

{description}

+
+
+ + ); +} diff --git a/src/app/dashboard/businesses/page.tsx b/src/app/dashboard/businesses/page.tsx index 77cffa8..cfac894 100644 --- a/src/app/dashboard/businesses/page.tsx +++ b/src/app/dashboard/businesses/page.tsx @@ -16,13 +16,13 @@ async function BusinessesTable() { export default async function BusinessesPage() { return ( - <> +
-
); } diff --git a/src/app/dashboard/clients/page.tsx b/src/app/dashboard/clients/page.tsx index f61337c..a846349 100644 --- a/src/app/dashboard/clients/page.tsx +++ b/src/app/dashboard/clients/page.tsx @@ -7,13 +7,13 @@ import { ClientsTable } from "./_components/clients-table"; export default async function ClientsPage() { return ( - <> +
-
); } diff --git a/src/app/dashboard/invoices/[id]/page.tsx b/src/app/dashboard/invoices/[id]/page.tsx index 0ebcdfb..ab903e0 100644 --- a/src/app/dashboard/invoices/[id]/page.tsx +++ b/src/app/dashboard/invoices/[id]/page.tsx @@ -123,14 +123,18 @@ function InvoiceViewContent({ invoiceId }: { invoiceId: string }) { }; return ( -
+
- - -
); } diff --git a/src/app/dashboard/page.tsx b/src/app/dashboard/page.tsx index b32a175..db81690 100644 --- a/src/app/dashboard/page.tsx +++ b/src/app/dashboard/page.tsx @@ -3,14 +3,10 @@ import { ArrowUpRight, BarChart3, Calendar, - Clock, - DollarSign, Edit, Eye, FileText, Plus, - TrendingDown, - TrendingUp, Users, } from "lucide-react"; import Link from "next/link"; @@ -26,6 +22,7 @@ import type { StoredInvoiceStatus } from "~/types/invoice"; import { RevenueChart } from "~/app/dashboard/_components/revenue-chart"; import { InvoiceStatusChart } from "~/app/dashboard/_components/invoice-status-chart"; import { MonthlyMetricsChart } from "~/app/dashboard/_components/monthly-metrics-chart"; +import { AnimatedStatsCard } from "~/app/dashboard/_components/animated-stats-card"; // Hero section with clean mono design function DashboardHero({ firstName }: { firstName: string }) { @@ -160,80 +157,79 @@ async function DashboardStats() { return value > 0 ? `+${value.toFixed(1)}%` : `${value.toFixed(1)}%`; }; + // Debug logging to see actual values + console.log("Dashboard Stats Debug:", { + totalRevenue, + pendingAmount, + totalClients, + overdueInvoices: overdueInvoices.length, + revenueChange, + pendingChange, + clientChange, + overdueChange, + paidInvoicesCount: paidInvoices.length, + pendingInvoicesCount: pendingInvoices.length, + }); + const stats = [ { title: "Total Revenue", value: `$${totalRevenue.toLocaleString("en-US", { minimumFractionDigits: 2 })}`, + numericValue: totalRevenue, + isCurrency: true, change: formatTrend(revenueChange), trend: revenueChange >= 0 ? ("up" as const) : ("down" as const), - icon: DollarSign, + iconName: "DollarSign" as const, description: `From ${paidInvoices.length} paid invoices`, }, { title: "Pending Amount", value: `$${pendingAmount.toLocaleString("en-US", { minimumFractionDigits: 2 })}`, + numericValue: pendingAmount, + isCurrency: true, change: formatTrend(pendingChange), trend: pendingChange >= 0 ? ("up" as const) : ("down" as const), - icon: Clock, + iconName: "Clock" as const, description: `${pendingInvoices.length} invoices awaiting payment`, }, { title: "Active Clients", value: totalClients.toString(), + numericValue: totalClients, + isCurrency: false, change: formatTrend(clientChange, true), trend: clientChange >= 0 ? ("up" as const) : ("down" as const), - icon: Users, + iconName: "Users" as const, description: "Total registered clients", }, { title: "Overdue Invoices", value: overdueInvoices.length.toString(), + numericValue: overdueInvoices.length, + isCurrency: false, change: formatTrend(overdueChange, true), trend: overdueChange <= 0 ? ("up" as const) : ("down" as const), - icon: TrendingDown, + iconName: "TrendingDown" as const, description: "Invoices past due date", }, ]; return (
- {stats.map((stat) => { - const Icon = stat.icon; - const TrendIcon = stat.trend === "up" ? TrendingUp : TrendingDown; - const isPositive = stat.trend === "up"; - - return ( - - -
-
- -

- {stat.title} -

-
-
- - {stat.change} -
-
-
-

{stat.value}

-

- {stat.description} -

-
-
-
- ); - })} + {stats.map((stat, index) => ( + + ))}
); } @@ -327,7 +323,7 @@ function QuickActions() {
- -
) : (
- {recentInvoices.map((invoice) => ( + {recentInvoices.map((invoice, _index) => ( -
+
@@ -627,7 +628,7 @@ export default async function DashboardPage() { const firstName = session?.user?.name?.split(" ")[0] ?? "User"; return ( -
+
diff --git a/src/app/dashboard/settings/_components/settings-content.tsx b/src/app/dashboard/settings/_components/settings-content.tsx index 1071c0a..a8eaf8a 100644 --- a/src/app/dashboard/settings/_components/settings-content.tsx +++ b/src/app/dashboard/settings/_components/settings-content.tsx @@ -1,26 +1,38 @@ "use client"; -import { useState } from "react"; -import * as React from "react"; -import { useSession } from "next-auth/react"; import { + AlertTriangle, + Building, + ChevronDown, + Database, Download, + Eye, + EyeOff, + FileText, + FileUp, + Info, + Key, + Shield, Upload, User, - Database, - AlertTriangle, - Shield, - FileText, Users, - Building, - Key, - Eye, - FileUp, - ChevronDown, - Info, } from "lucide-react"; +import { useSession } from "next-auth/react"; +import * as React from "react"; +import { useState } from "react"; -import { api } from "~/trpc/react"; +import { toast } from "sonner"; +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, + AlertDialogTrigger, +} from "~/components/ui/alert-dialog"; import { Button } from "~/components/ui/button"; import { Card, @@ -34,22 +46,6 @@ import { CollapsibleContent, CollapsibleTrigger, } from "~/components/ui/collapsible"; -import { Input } from "~/components/ui/input"; -import { Label } from "~/components/ui/label"; -import { Textarea } from "~/components/ui/textarea"; -import { Badge } from "~/components/ui/badge"; -import { toast } from "sonner"; -import { - AlertDialog, - AlertDialogAction, - AlertDialogCancel, - AlertDialogContent, - AlertDialogDescription, - AlertDialogFooter, - AlertDialogHeader, - AlertDialogTitle, - AlertDialogTrigger, -} from "~/components/ui/alert-dialog"; import { Dialog, DialogContent, @@ -59,6 +55,10 @@ import { DialogTitle, DialogTrigger, } from "~/components/ui/dialog"; +import { Input } from "~/components/ui/input"; +import { Label } from "~/components/ui/label"; +import { Textarea } from "~/components/ui/textarea"; +import { api } from "~/trpc/react"; export function SettingsContent() { const { data: session } = useSession(); @@ -300,7 +300,7 @@ export function SettingsContent() { {/* Profile & Account Overview */}
{/* Profile Section */} - + @@ -337,6 +337,7 @@ export function SettingsContent() { type="submit" disabled={updateProfileMutation.isPending} variant="default" + className="hover-lift" > {updateProfileMutation.isPending ? "Updating..." @@ -347,7 +348,7 @@ export function SettingsContent() { {/* Data Overview */} - + @@ -359,12 +360,13 @@ export function SettingsContent() {
- {dataStatItems.map((item) => { + {dataStatItems.map((item, index) => { const Icon = item.icon; return (
diff --git a/src/app/dashboard/settings/page.tsx b/src/app/dashboard/settings/page.tsx index 4308288..6540398 100644 --- a/src/app/dashboard/settings/page.tsx +++ b/src/app/dashboard/settings/page.tsx @@ -6,7 +6,7 @@ import { SettingsContent } from "./_components/settings-content"; export default async function SettingsPage() { return ( - <> +
- +
); } diff --git a/src/components/data/data-table.tsx b/src/components/data/data-table.tsx index 0abfd77..a655e72 100644 --- a/src/components/data/data-table.tsx +++ b/src/components/data/data-table.tsx @@ -361,7 +361,7 @@ export function DataTable({ key={row.id} data-state={row.getIsSelected() && "selected"} className={cn( - "hover:bg-muted/20 data-[state=selected]:bg-muted/50 border-border/40 border-b transition-colors", + "hover:bg-muted/20 data-[state=selected]:bg-muted/50 border-border/40 table-row border-b transition-colors", onRowClick && "cursor-pointer", )} onClick={(event) => diff --git a/src/components/data/status-badge.tsx b/src/components/data/status-badge.tsx index 3b16c64..d3ded76 100644 --- a/src/components/data/status-badge.tsx +++ b/src/components/data/status-badge.tsx @@ -51,7 +51,15 @@ export function StatusBadge({ const label = children ?? statusLabelMap[status]; return ( - + {label} ); diff --git a/src/components/forms/invoice-form.tsx b/src/components/forms/invoice-form.tsx index 2c6561e..0e491f5 100644 --- a/src/components/forms/invoice-form.tsx +++ b/src/components/forms/invoice-form.tsx @@ -493,7 +493,7 @@ export default function InvoiceForm({ invoiceId }: InvoiceFormProps) { return ( <> -
+
Delete Invoice )} -