From 9243fec9479e1736d937eff8b6ba7f10f58a3086 Mon Sep 17 00:00:00 2001 From: AG Date: Wed, 10 Dec 2025 18:40:54 +0200 Subject: [PATCH] Alternating option for Unilateral exercises --- playwright-report/index.html | 2 +- server/prisma/dev.db | Bin 184320 -> 204800 bytes specs/gymflow-test-plan.md | 3 ++- specs/requirements.md | 2 +- src/components/History.tsx | 27 ++++++++++++++++++++++++--- src/components/Tracker/SetLogger.tsx | 7 +++++++ src/hooks/useWorkoutForm.ts | 2 +- src/services/i18n.ts | 2 ++ src/types.ts | 2 +- tests/workout-tracking.spec.ts | 20 ++++++++++++++++++++ 10 files changed, 59 insertions(+), 8 deletions(-) diff --git a/playwright-report/index.html b/playwright-report/index.html index 5a53fdb..3b8cf4a 100644 --- a/playwright-report/index.html +++ b/playwright-report/index.html @@ -82,4 +82,4 @@ Error generating stack: `+n.message+`
- \ No newline at end of file + \ No newline at end of file diff --git a/server/prisma/dev.db b/server/prisma/dev.db index 3fb4f6cfa7a5b0793436e49864cfb74af4f1bb74..7db089899088b64d3a01574ee6b67522e4842987 100644 GIT binary patch delta 4359 zcmeHJYj6|S72dmANxRw?6blyu*fR1%4l8z7tCg0?fE}WozbV}%e+^Hf zS$>Hv24K^2;H65@G|y*?;b!wnFNL+TXzq6OG@YUkcl1n4;zfJ)9JeDD0}+p+>8c*r zQ-WfsaY2z3QHYCjN=S*pgqVYg7L!IFkWhn`oh-=ai7zQuo#`jtX(vT8yNlFS~ z6cU1O7=o6NLqbqXDxw?~<)kWR6Jl)Ir2OdgpXCPw$@r+6XvOeI&CqE@$Va=uN6Z5L4*FvK`8#Q@XqAO~hAgO9FCF`;fj?0>$Bs5vjltfYps1_F?HIzz-d6r=+ z9E|H?Kot^_h;Bz#5<*xKj20q@;%OGnEL21tpa*gm_R33MpNcMNO2Hlp<#XFB@9%oJLo9 zRZT^7czI1l)mT}SgMuUrl2{|D0|MHBfa+I5;ipA$fG9Ti>23j~I)Ua!!iH$5YS^$i zQV>u*E`+79f;d92N(`j5ke+xV&_+aLHb`?^(T@Cj3}Mi(Nr6s;z1`7=I$ftPxgKRMtFBVbC88%AEkcIsXZ;ZzLf% z22hG5f+$}?A&bMHkO-x8Augjgp9pEPuBWm|v230OM}EguyF2eXG(gn+VnBKTG+n!6 z9WCcFQH)pEq0CMGBsY+)=O(iM;9p^)oSUcFJZ3)sTdsv^<$uDy$s9pd620!URMv}W zwBAKFS)6MbW|KwTEyFA>Gw!ww3ls8_NzF;$Jj~7P>85vM%vfIHKIXpR;>-=YjVWZ? zIf34t=~V{S(@KDdc|bPh_0h$u>$t0{h2l^pJvGJJ= z=RlkZ+Gb;w*nJ0B0Pffd@OJ#K_$GWF(c5<2cF4BTHjh|q?@4@RpX%slzhvL%e9y7m zaoV{El2<@4oc=rXUIArr^%Za#F1Y}T;N~{)yydSHUfP5({P-#m;qSiyMYwG?{PYX3 z1&+7|iU{Y67y(&pdUg?BU?FwDVb?*mX%zYFE381Fumbnmv0ow%pfns5+7>MJ!4J*@ zAJMV<{!!q?v0s?=g3rFVV`c9#;Dvi{po6ZS1M^|oO%R2jzYDzPhlO_d!A;2^FCGr$KOJmXG(pr;S551{1!TzY`}a_I)x4@z70lM9K8tnmyy}$MRvIPHn@tG z@Kollc7R0L@|w+UV|z09?*N?m{<{9puB)H*y7KX2K;R|l5s4oBwv`ggGW`nhldMun zY{$r2auC_wdD(fuxz<_l9O}$-+;ALnY;??XR6C08-`J1Yx7eHQW9)vro%od44oMLo zmsu_1y$SR9^itT*gO_GX3UJ-lkxr;TFv3WH1YJ>3DN>W^ zBy}OPH;h;05%><*Q?Y)@*b(8I^B~j zZywS-&=sp_w!29(63Hg*zvUFR?F2a^s)o!OSv6Cc`~2W}(Pyh$h9*Y2FFHKL?4yRhwX;sS2a^Q)vfD;?jzt2Yw80< z%G~<{?r{FV$-aZ}TlgC89`|c5%HCz)NqbJWu%kyc4@8};)k1a6hVN`*tu&@(?jFGj zd}B)&#_G^j9;qD@jm$;SHj>frpu2?LBSzdc*(?w+C^>I!VzoK=vV3nh4%7+gr zj}B>e_Ho7fA>Y{3sEy60L9kkPvt>PHKDVx4%4&Z5lanz11iy`6!jI!+p5jh(8E!e3 z2XCO- zJk{FjwG^q#Ti1XSE?kE9#j!Q;@NHD_*Iz@myiYqan1IUr1Fc|o;pl|jaPckRH&+#S z;es}FY>U5BN(Q}QZNF|#^9b-@JNP;L-M{}_xXs$yXf7}ELC-bxceRN$X+ts6q@yE1 zAzc17Qk1VOkcUeIc>ZeyVAV~uey0rqIC>Sy;r&}cFg=AncpfQ`xxKis1Cr@!@H(&+ z9q~$Af!7}D7&b1%y`TYZy@UQfdjj;GIQx6{|M%?IV*GLbJ^p2WEZ?7ZaHqH(+-qE% z3v)bsf!)onW?y2<*j(nH%mHRCQ_l=#^5~oN5xSM0Pe*B=>%Qx_YpZLq>jjtSa!{X9 eY3fyKJQbo?@*Md`awS=davvu%pNRMy&VK>(y45xS delta 1649 zcmeHIYfl_i7@l+HwmX+|Fl^Oofn6A=yRx_{sidh~KGaLVx)LB7X+cda9~ugn#)Jx8 zwN_~=bUWZ{YLl*ZwXM=hoyKVsBQ!KkNJ>H>0wyLdv@rxP?e@Y&maVhX>^J{`etYts z=Y8JmIVUuvgd+06hxs9fVfP{Gfv5+j56vlIZtIHqr6uMM;>&B5LKj=A!iWAcDq4rh zL-~@6QL2@wdYEjd#ma6qM;)g7$SgUpyF*1rFx2J@N9s6R?ZR2j*tGv5|J4}IP$Ww? zOKxZ6c6CZ8k$_PinUgH4(f-YTj?Ltnba7z4Q4!e48BJ%8$Xcedz|dm#Ic0%PlTx*n zY*+uV0Ju7A}*w9(2iZMtOxkPDaQoc}=+^$CZ3_nfT4@ za&%Md%8N|ec^8=U(u4Q8z*^_b81eIr7lR42BXd<^YE(7%X$5S>9akaZgsLBT8v z!b;pi(ODGbylgGj-wkWfaupRqYytVrk*lag$xA6PKQYW*!K734H2r|q(1ljS zJO#Zs(4SDWf(zhy9K8&sN$i99FR=zM+(ZGr;ulR|j-}Fq&ePb!U)Z?$BdlTObBHIf z&rTXzx-6IL2`s>iw@?8bSjLaRcc0)q%zO$RD`{58fs|h#{IG7XC1W_0^3Q+-sW$Cy)k%caWgp_m0NzPVEfr>BJh} zZo`==q@i7~X#v&2nk3E#(`qbSOJXmmi)f3zW6-c@k#@lJ-&SV9gjLMsBJx6a68oWW zDNUm9Ax;0afQREt=%(K6@tc>H5yia2juYy(PIr2FlTDx``~TF_6Z{WO-Hq3ydlw_% z!AtgrnT5G{TIIGeV+@o8aDBkh{#UOs4 zaCC%mLuDE2v>#)=KRes}y#cQc-tTlI8CpVG)sxDMvQ~ac>T+IkB&{Fdn!`+0P!oFLU|!tliAR5LM(Is6Yat`a){ diff --git a/specs/gymflow-test-plan.md b/specs/gymflow-test-plan.md index 935cd99..0029b31 100644 --- a/specs/gymflow-test-plan.md +++ b/specs/gymflow-test-plan.md @@ -542,9 +542,10 @@ Comprehensive test plan for the GymFlow web application, covering authentication 4. Select 'Left' from the Side selector. 5. Click 'Log Set'. 6. Repeat for 'Right' side. + 7. Repeat for 'Alternately' side. **Expected Results:** - - Sets are logged with the correct 'Left'/'Right' indicators visible in the history. + - Sets are logged with the correct 'Left'/'Right'/'Alternately' indicators visible in the history. #### 3.15. C. Active Session - Log Special Type Set diff --git a/specs/requirements.md b/specs/requirements.md index e127559..4fb4db6 100644 --- a/specs/requirements.md +++ b/specs/requirements.md @@ -66,7 +66,7 @@ Users can structure their training via Plans. * `PLYOMETRIC`: Requires **Reps**. * **3.3.2 Custom Exercises** * User can create new exercises. - * **Unilateral Flag**: Boolean flag `isUnilateral`. If true, sets recorded for this exercise can specify a `side` (LEFT/RIGHT). + * **Unilateral Flag**: Boolean flag `isUnilateral`. If true, sets recorded for this exercise can specify a `side` (LEFT/RIGHT/ALTERNATELY). * **Bodyweight %**: For bodyweight-based calculations. ### 3.4. Workout Tracking (The "Tracker") diff --git a/src/components/History.tsx b/src/components/History.tsx index a8b4548..c52a585 100644 --- a/src/components/History.tsx +++ b/src/components/History.tsx @@ -76,7 +76,7 @@ const History: React.FC = ({ lang }) => { } }; - const handleUpdateSet = (setId: string, field: keyof WorkoutSet, value: number) => { + const handleUpdateSet = (setId: string, field: keyof WorkoutSet, value: number | string) => { if (!editingSession) return; const updatedSets = editingSession.sets.map(s => s.id === setId ? { ...s, [field]: value } : s @@ -454,6 +454,26 @@ const History: React.FC = ({ lang }) => { )} + {/* Side Selector - Full width on mobile, 1 col on desktop if space */} + {set.side && ( +
+ +
+ {(['LEFT', 'RIGHT', 'ALTERNATELY'] as const).map((sideOption) => ( + + ))} +
+
+ )} ))} @@ -466,8 +486,9 @@ const History: React.FC = ({ lang }) => { - )} - + ) + } + ); }; diff --git a/src/components/Tracker/SetLogger.tsx b/src/components/Tracker/SetLogger.tsx index 3d80d66..30bb41a 100644 --- a/src/components/Tracker/SetLogger.tsx +++ b/src/components/Tracker/SetLogger.tsx @@ -106,6 +106,13 @@ const SetLogger: React.FC = ({ tracker, lang, onLogSet, isSporad > {t('left', lang)} +