From 9f5725bf01c353ff8e2c2ae0d2a233ee4471a42e Mon Sep 17 00:00:00 2001 From: Tiago Yamamoto Date: Mon, 23 Feb 2026 18:56:06 -0600 Subject: [PATCH] feat: improve tickets dialog, navbar buttons, hero section, and fix button bleeding --- frontend/build_errors.txt | Bin 0 -> 65854 bytes frontend/fix-lines.js | 83 ++++++++++++++++++++ frontend/fix.js | 56 +++++++++++++ frontend/src/app/dashboard/tickets/page.tsx | 20 +++-- frontend/src/app/jobs/page.tsx | 1 + frontend/src/app/page.tsx | 11 --- frontend/src/components/job-card.tsx | 16 ++-- frontend/src/components/navbar.tsx | 22 +++--- frontend/src/i18n/en.json | 12 ++- frontend/src/i18n/es.json | 12 ++- frontend/src/i18n/pt-BR.json | 12 ++- frontend/tsc2.txt | 1 + frontend/tsc3.txt | 6 ++ frontend/tsc_errors.txt | 1 + 14 files changed, 216 insertions(+), 37 deletions(-) create mode 100644 frontend/build_errors.txt create mode 100644 frontend/fix-lines.js create mode 100644 frontend/fix.js create mode 100644 frontend/tsc2.txt create mode 100644 frontend/tsc3.txt create mode 100644 frontend/tsc_errors.txt diff --git a/frontend/build_errors.txt b/frontend/build_errors.txt new file mode 100644 index 0000000000000000000000000000000000000000..0f46bdcd7ff459de4502c437276d616a76a91bb7 GIT binary patch literal 65854 zcmeI5>uwy!a)1ZOzW{lHoF5w@wkX@AEQ&YDv>aKoa|HPKIF@1{u$+h@sf$HY47s{6 zvhxz>ZSpL6k_1RnU)Pqpd%9jVNdJ2O2!Rn^sX>*|{S{hz<8{<6AJjjF@y ztXi&KR-elM$JI&oy!yG?uXd|(^>=b@rMe=2pGv!j)r;zBbx`e9_T-VYdoAti_qacD z|NitB|6Tp*gHiSEq~(hAeJXdZRO`|!e^;ti*PpgumU~}SM*_`L2g#8@w=d^odFr~{ zTXAPE<#-@)?p8Z;rc!BLx zX+ukoC-37Qy&uWlJ$ViYUd!Le!Sl8B4o$Sbv9uYv*1PiSQ2N(<+QUtG$4J@&*SX??QD;uHCP`b5wXN|L;hDqw4EPkEe1kgbJ!&PGGzc^z@Ie z{i(e9MB3i3ZVEQg;z<5Z1v1_M{3q_-vA|CMx82npxfap_DF40VKYHofmUi#fo~MR7(VO}R}Q`8diL#qtbVFKk!#<}8x9=|`!Xk93k>@L3w&yj0u4NCP;s5H`C2&o zK>nRo{~*7ZBTofuh4?GE@7tdU6j0`ln-7Y$&YhR?wp((KKCS(sz{70X6L{=Ny~qFj ztq2#M%Dr7V?g+HUa@><&r^4qCr8jtePp&hOefs!gmMnVT95N~HrGbf=C^5m7Y zK`uOzBT|Gm`ab^uMC9X-lQ(ZvpUK-ltJb7novFwM+P{>!0=GSpKW5s#NWABQFLUmZ zTw%O`2P)G3zTAOc_XP^*bw5L|`;K0_u6<0e`w6{_8rLUsb-mhj(&eWKHr!tos8>b$ zt_8IFCBRg1R_uSxJh$HPoIVl0VWXjC_y%~BS;PqJ2=;zfyve+Kv(_VTyDGRa9*3^| zCvRKC_m(r)ftcrRyuIhg+kVjoZtz^Sl!0q2=mA>tRQf)>`dKPv6)eB06C<)oio zp$&8BRAdr*V88lYG{hshiZ0T3J)Lm*scZ)Kqh9$kqH9h9hHRFbwb1bsO;ZqbKql81ivlU&1*t zJY94{7oC7)+;P%<*~$40C%KgOLx}2n`Fs%B2zP<(U9{Chk=A2pouSuq+G#_q9Ppc$ z{Hvz_6KvCIyv$bErR z$CxK>xvTi4pI2|hE5SSeT*jEljru1#Pk=g}D@$TOV-Mi-T@uSj`wThQbMG`7)orBt z(#U8cdkUtUpU$sJxO}!>9u&LJ^IXMRUpSerdNhqsnLNnP-MWp%EJ#Ovt2Z5Bn0+JC3oj-2?z(+G-`PiRp2GK>Y<=va zcElTywg*COPhHx_5kM$LY&pIPmw_Ga8N0aW9G-O_bT~YZ1!vxljyZK4@ts`JGsCNn z6YWp3qpmwaJ0?(+4T(63bo}{Z+?_XE!Gq)0#5852vUg=%Z2&KSC` z?2X8-k0$sqKkyUKK7SPKmJ)Wx&FPkriqShJY1J%RpEu3mS3Ecc0M)BH>IQ-FbxQFZa!nLf*z{71GO&s5`vt@aTbv0JqRHk-YpNJzq`rf+T zMNY!;B!Zu_z^)~cX7GD=kJ!_z{>#(P?sz)ha};33rj3fwNMkyu!r|J|M|4>E!Qy{0 z(N*_^wn!R_{on~9ZH}Dvh1M|c@^8=aS-%?DXyK1JI_c<|$DX&mJ#}6?*{bLCMr@}k z4rDPPc;s(o#?hWtY9gga8SCp>&mNx=>OO119?`nGmyHv+KzSV z$M%7ok$pn@i{hC+k&(l`^DS)5auMNcJzID6(NZ||YA93M=j&DBy!ozUr*Oqrpk@eP zU4j5nzp;!M9;KU?Z#j7SjXBieiAU1(d8iw-MP6f?9j0yUY&ffo@$5IY(MCVJ=f~IE zMQv2{+M$b8c2lH0nKoErBa!qPYb5rwEAon{33t&Mx`Je5>S1A4q6c%-=qJ`E1ZcrC>P&KV@|$*R$8q8 z$%(Kz$v84A^D}ZJHkjpaecEb;LAQQmN^Lx7_lB^-P8+D_?J;QVZL-uJtM{PNK&7JZ z<%!TAd11B|t;o^c7wPjr?qH8y6gfn;FBTrQy2|lzyqoPZMzG(gn~jn`f`gugQe>K4 zc10kab&buxlVAS5@%8)}twZ=y$#!MI>@xO|l%!BdQEyL#+Mvy%FiT9^*x8VF*_HRe zF4IUEysMT)94%vxu_uS953zW&zG$y8SZ{&l_3;eku~# zY%y}VsY#(xbRQj?9vQnjpg!|9%Wa2GeTDUg)Va}0Hsm3aXZ*Vl{zLx$OU_2}gxaB+ zp{q4g$j}MfKoMGE0YEe8s&re4WN_2_X&+0cvR=FLLDvY{+8~YLI~UC(%LyRq`gIt>D%M`^|R*oA=KZ?tbCQFZok^N z4y{Us^lEq|g!}hSDrlbc4XKS}vI04Qopw)-4_%&wjSKY1aZwp9?D1$G7i-gur|ojU zpU-2N!*I9=y8LW3Af9myu^g!Vooh>V`c5{Vf*yXxjdckFy%8uXsyjr#cKC^LKx zhEXOS&E{FT2-y$0*_GRQc2(kEWi@Y3iiCXjrAWIy$res|VZE>x&OvIt0JpypAHKeZ zvm&#e{quPDO9C$y>u9?!F-dZwsR6Jg|H3EFg5C7>eMfj8Wqek{tPN{xQ;1@yV@?VBi;!(#F5mmHPSQ42jIvMDsnUNNT*#-7{f+r%Re zzIa%iHr1(Lupg*ZiiQmOed~^@(eecxXAk%9*xTd?zd6sMr+G|}8 zYHu(b@nrE_wQ}2c?#MxU#F5qu#YFr_0GB^&`(+q(n?s9da~W=mM~X!g zN725?_EPE*^`!C#`ebn|D#JHED#Y+L)o83@&8cuT6^g0xNWQu4ekOWh9IxDt-T7SF zV0)@gg7a@p^m1CkhFZhS41Cy|Zq`t7R3jr=?bX&f&JxY75**D&%rz(DhPMV|>ekPc z+IE%5(Gw>v&YQ^&&2yRQ>kD9K8kYH^@m+i68X~J@*EPCWWQGwq#C}S%6_M5}@ zuL#(s0-wEm`Z4CUT>BLMCO<2!v^gB~m)z`E?7XB+D|MEKFy@73--@c1C054#m@Bn7 zk6}z@=tg0S1IU1>Yy5Si&{|6!t{kPx=yrv~=+k7CU~#7FRac#jtD_&zm9ly=#=zo_ z`3T9zfSN0YGhDB_Db^9|%h*S1|EQk$-f3@JuL}7%e7a8mzG^f2`Ck8}5a|3jPHI{$ z`rQZr>FhEpl~H{f>yG;LL|Lf+&3S#@iT=5pu6?DrmyNLS{%~B{xv%fakhyX3>xZ|5 zw!SV=DseUkTr=sCEl|&y+{#Ly%>lKa(I2jOBRp-h8jkK3OZ3n9s+?&YvG0nHhKE1u zJoD%NS3Gh)V(2lkXraoqF1xs!D(R#(aL7McJl{X2Ngm@vr%$ccQ=PZ9if=02%Gd;c zbeqTBx6xnScWF-BVNP`lU7ym*AV#DKc*?;udlkNbr}5lbnfXcagfW{nJSI*>l;?V zfIWtu%YZ^FcXg>lrC+uQwE$5#X7=fX7n^Jy0FR-x!b9j??C-|E?_Y3J*HtPI0i*FsL+&Vx38Wa}JRm%Jm)MeM8QsAW0S zu~1nOS9_&yGOH5QOm4G*>o#DnhUZm@U-TQX?xIO-H@{+2|MC{L*k0B*D^-6~IW1mu zYFam(I~=OLMcL|-O+btQ6J69@miTkfR2L2Iol(C z*9x!D$FPM_V&h%g4eO z;e0r=A@PZ)jppzLp#!eY2)}T z?FwyL{?%O^M2mpi zT6YD*OT zbEFWq$1F-$@eAc_Ov!L{>5Xv3-o%yzBlyHPj5T-Nk$v&)s=W4UEiTG^Rw& zeIFy_un+>?8qTp&wFOOA>NsAGX27(OEUT9kLPqJOP%7{3_-cN%4!>r5ED`B^bvx=b z4Y#(@CD$d7)oLcc1zgH#J>#2je%Uo0sc%H0@`YI<6ybVDc%7Cp*AE|c*sku#{6BU% zs)}8hOXVXi=DV#(Ypb}S?bVNn_05t{!bcgwyUi2ie(Vj}+sNFp_aSp=xi4+U0>g>Z zZeuy~5Nl=)U-(IPQNt~>TLU)Adejk&ueF`|_Sh*pn^P-g$eNDxpOIy31y6NPW4pF3 z-$nJav7Ws^d;KaDV-mL1o@`$w{8HAs$Vr!YetJ&Fs?#cz2ZHO-+r0!U!ezNU3g!g( z^*vj8M;?NApTDfC4Y|*{Y5o#791bqC5ukiGJAsVG^!xVSe#k{e7o!^G?6^`hjLgG4 zPQzJ3Cadho=*4m?&M(l}>$6d($*#2pu#611ScZY=SnN|gT)HzFio$ltL`&{dl>SyVV)%PWdy%HI@_;xQ4(kAXD*F#CE zSjY9<<>C5(7Hzw{DQm6id~B1;WusgQ&u!sM+p`AO^R>==9_NrXH0yOSft{F2Tm$nw zxiZ~X*p@^NKq;Qkj0ydsDH4F1Ob6lzPRm(YFSH_O5>e&3p4DlX=8+H!hO$-{^sby! z_19LASYxznhAZu@UTGR3EnWXoc{*MnYUk=wbuDv{ON6U4rW1({|jQmo=m#nU*E{002vnD^McCfIkC$mU(7 z#1hKrE9Di-6=`4X-6)&~8p9T@l=DRt8|jf-t3$8So^?{JaKDyexP{NB+*>vp&}}Da zxHncIJ{9lcq40UV0-@F}M6>9;z`r;Xds*vIahJFdRy!GwnuMz#Eq7Pj#P-_w> zcQW&7tFRpu@*Xg$^i1c(R^e3&c&;6u*}Z(@5IypS_)6}~;KE?Fc8kHBr}|>dmF-;H7K7=lYGVwa zX&&Rz_83gxbr;)V3u7pE#e1-k9#tPsG$dH;iXK$!KAd~uvvtlbRguxK>mGjr4~s2f z5vXURw&AJR1?g8JG%^B)8ll3|VKpF?J*BD=0!ug&(>Sc8o-nSDqa!(5^{XX}Gwi4| zGtVe5!Q%R(OzoJ8~mdCW4)V z%C2b@`=-$Y3uY$1EpZJ-o2*M{d`oP9B366i&*Ago&nea>;r88}%6appt1X5WX^c4# z=dq8YR#s`9_DT(^vqO<(!C(DaBI_2zgF@d4b!e|UPKX`ZS8P=SXq=CT4Urwohk4|B zITX&ZxDM@zENPTEPtW1J%QlPp+JHXX`8;=`X!_ksMve-;`t8cFt^wn!W9m6wchl;a z+j#rC(5TIS)bG%i+zSA9%_9dqW%ec*9Nn}WaP_;NGPDBf5}UWruKB^xN9yULUp?Jy zuk-GHd^wY;cGOX|F>SM^fT^q&jA09HZah)q?W!%pwMC2Rhujf9nT~Op2&UrVz4vL9 zE~6!43b)&>jDMLG(2zIZh&=vC#`$~Es;s1_FE*01*YX>m&8~op=L?Nhpso4#5p~wl z5JWYJhjNwneBFrkWOTZ&Det)z9IS+q=o2hjTQS2Xwv}cg^tyh%EJt05R?kTL{Yap; zstp#?AZxko?lv9WS?qrE0+xkVd|75B7UZ6+I{53@O|RrSef#}nw0k&-5vQ_v$f}9y z&LqvEB@d79U>~^AKXI!b-^w*`Q!cWsn=miujqm`HM^_-pz_q>0=gGX)_gG*4>jt`0 zI(`%DiuSH|&9sFR`_;`hgZ&YH(X(w?>(ok9+l(^=X+ru;pjE_L1USCDqJ&-+)p`lHzlz7K6b4o1K-)N^yoGGN1Tv>C=u ze)M(77cq1>diHCZrBt0p&uQB8N+FBRL!Lrx_qgLnl6iQ?%`kk~P~KgTS!2CShO@v`T0BURRFY?~?F@y2p^>E;BoiWtE+?uun^hrHT`dl~D}#&tfpV^wK>H$FAE z-*s0wtIyLm+{@UoZMf@r$C73GJS}VGhGSNzZaSNWtVCFk(^&i^j=ey0+ZPblk5X#~ z-Hk+Vu7W+JT(~`u!pL&+Dl}d45{%!l=3_@85HL+#csC zT|v=!RqgfM$d|R*6duMv$0-NVa5jyt=%@?-+Bz8%~$MXA846~ zkB2OU)9!`v8g+I2bxtCuJZHo$!U)=G;fPTvOAQx0HseI}E3`|yW4Acky%{^z-R$M< z`fUq%ad_R`Hf}o3c`d+5Y7VpdH)KyGss*&mP~cN6G;rpSKrewXohlk$O@1K zza2x0E9WY<{u>{PPtzAZ7>(h5eZ$6%AyyjOz%!&aq>Wh^8;oU5++MY?j}l*9AUj|d zZ0nIR|7{8|R2#CX!a8HTI8lOGuqHo%H3)V;Ypn;c#ZzMc39+@N+OE1|NWZIy-^2d4 zWf^=wrkva!=q@HVP(UejpMK5seX^w;88M~1H*jr$n!vBb;S7uo$AB9Gmg2=O0_ z&89y7QlNRlT#I|o#$u)IvGCgdB(mL7Mw=1l3`Nv&v%HHCv9=k+ulDqudMXkZXhP3mZO)!OIZWsXawA!-rKTx+ z6ZIPu@tgbcqlqQk{y0{U|3?0i(V-B;-!tOd2WeggHdh~W)^z7{flzCms_tY=bPbwc zx(*)jw_Vim9Yh4KiWB{b5Qmpx3RmiYqiR(u1u^_$k;G^84wAWl-c*<6@kEDW|#*ad7?yHKO!IRd-VAt+F zw;RRs-pqn$oUm)L`i}%FvMR{QSM0P>0d2@j&S5fN?U2^xUl%z)-`I9{sk7dbUpWt{ zGhexHwv*0Xa^CurI{o-R3OWCqHhDLx(~rIxQtI?ogRH#NnRmsqoYa|DO)@O1rd8RE z#NNk}AcpsuWZ7x`g$Hk~i}>Dh<~k$6b2r}Jvw1xd3xKh6cK$$OOZrdy z&|ZkdAIfTpw|=-w-GF1U=E#aAcEF6(j9V(Y6YpZ5i}j;#_(XdD(e*#~Djc9?$DCKD38^*9F#}CfGoSRe>6!AxL)H#4m#hCy8`R%yJ*u=cTJ-jHbV?!OChmuFBl}HR8_RkV=)XF$t z$(S*gCk{uRzaum~c2}@XsC2`KVWH@bETsk<_pkCE_)d9@ykh(bEa3ggJ6B{jDpycL z0j^+n*16)c;|ktQ)>6n7RIQ1*f>!oNT$Q{Kc6xy;l{|IVmsJqLvclF(null)')) { + lines.splice(i + 1, 0, ' const [deletePlanId, setDeletePlanId] = useState(null)'); + break; + } +} + +// 3. Replace handleDeletePlan block +let startIdx = -1; +let endIdx = -1; +for (let i = 0; i < lines.length; i++) { + if (lines[i].includes('const handleDeletePlan = async (id: string) => {')) { + startIdx = i; + } + if (startIdx !== -1 && i > startIdx && lines[i].includes('} catch (error) {')) { + // found end of try block + } + if (startIdx !== -1 && i > startIdx && lines[i].trim() === '}') { + endIdx = i; + break; + } +} + +if (startIdx !== -1 && endIdx !== -1) { + const newFunc = [ + ' const handleDeletePlan = async (id: string) => {', + ' setDeletePlanId(id)', + ' }', + '', + ' const confirmDeletePlan = async () => {', + ' if (!deletePlanId) return', + ' try {', + ' await plansApi.delete(deletePlanId)', + ' toast.success("Plan deleted")', + ' loadBackoffice(true)', + ' } catch (error) {', + ' toast.error("Failed to delete plan")', + ' } finally {', + ' setDeletePlanId(null)', + ' }', + ' }' + ].map(l => l + (lines[0].endsWith('\\r') ? '\\r' : '')); + + lines.splice(startIdx, endIdx - startIdx + 1, ...newFunc); +} + +// 4. Add ConfirmModal before last closing +let lastDivIdx = -1; +for (let i = lines.length - 1; i >= 0; i--) { + if (lines[i].includes('')) { + lastDivIdx = i; + break; + } +} + +if (lastDivIdx !== -1) { + const modal = [ + ' setDeletePlanId(null)}', + ' onConfirm={confirmDeletePlan}', + ' title="Are you sure you want to delete this plan?"', + ' description="This action cannot be undone."', + ' />' + ].map(l => l + (lines[0].endsWith('\\r') ? '\\r' : '')); + lines.splice(lastDivIdx, 0, ...modal); +} + +fs.writeFileSync('c:/dev/gohorsejobs/frontend/src/app/dashboard/backoffice/page.tsx', lines.join('\n')); +console.log('done lines edit'); diff --git a/frontend/fix.js b/frontend/fix.js new file mode 100644 index 0000000..0ddbdd4 --- /dev/null +++ b/frontend/fix.js @@ -0,0 +1,56 @@ +const fs = require('fs'); + +let content = fs.readFileSync('c:/dev/gohorsejobs/frontend/src/app/dashboard/backoffice/page.tsx', 'utf8'); + +content = content.replace( + 'import { Archive, CheckCircle, Copy, ExternalLink, PauseCircle, Plus, RefreshCw, XCircle } from "lucide-react"', + 'import { Archive, CheckCircle, Copy, ExternalLink, PauseCircle, Plus, RefreshCw, XCircle } from "lucide-react"\r\nimport { ConfirmModal } from "@/components/confirm-modal"' +); + +content = content.replace( + 'const [editingPlanId, setEditingPlanId] = useState(null)', + 'const [editingPlanId, setEditingPlanId] = useState(null)\r\n const [deletePlanId, setDeletePlanId] = useState(null)' +); + +const oldFunction = ` const handleDeletePlan = async (id: string) => {\r + if (!confirm("Delete this plan?")) return\r + try {\r + await plansApi.delete(id)\r + toast.success("Plan deleted")\r + loadBackoffice(true)\r + } catch (error) {\r + toast.error("Failed to delete plan")\r + }\r + }`; + +const newFunction = ` const handleDeletePlan = async (id: string) => {\r + setDeletePlanId(id)\r + }\r +\r + const confirmDeletePlan = async () => {\r + if (!deletePlanId) return\r + try {\r + await plansApi.delete(deletePlanId)\r + toast.success("Plan deleted")\r + loadBackoffice(true)\r + } catch (error) {\r + toast.error("Failed to delete plan")\r + } finally {\r + setDeletePlanId(null)\r + }\r + }`; + +content = content.replace(new RegExp(oldFunction.replace(/[.*+?^$\\{\\}()|[\\]\\\\]/g, '\\\\$&').replace(/\\r\\n/g, '\\r?\\n'), 'g'), newFunction); + +content = content.replace( + ' \r\n \r\n \r\n )\r\n}', + ' \r\n \r\n setDeletePlanId(null)}\r\n onConfirm={confirmDeletePlan}\r\n title="Are you sure you want to delete this plan?"\r\n description="This action cannot be undone."\r\n />\r\n \r\n )\r\n}' +); + +content = content.replace( + ' \n \n \n )\n}', + ' \n \n setDeletePlanId(null)}\n onConfirm={confirmDeletePlan}\n title="Are you sure you want to delete this plan?"\n description="This action cannot be undone."\n />\n \n )\n}' +); + +fs.writeFileSync('c:/dev/gohorsejobs/frontend/src/app/dashboard/backoffice/page.tsx', content); +console.log('done'); diff --git a/frontend/src/app/dashboard/tickets/page.tsx b/frontend/src/app/dashboard/tickets/page.tsx index e90151c..e8ea3fd 100644 --- a/frontend/src/app/dashboard/tickets/page.tsx +++ b/frontend/src/app/dashboard/tickets/page.tsx @@ -322,14 +322,24 @@ export default function AdminTicketsPage() { - Bug - Feature Request - Support - Billing - Other + {t("ticketsPage.category.bug")} + {t("ticketsPage.category.feature")} + {t("ticketsPage.category.support")} + {t("ticketsPage.category.billing")} + {t("ticketsPage.category.other")} +
+ +