From c8bc967399cf255794f6d7acdba9022e0b4009c1 Mon Sep 17 00:00:00 2001 From: Dennis Eckerskorn Date: Sun, 25 May 2025 14:02:17 +0200 Subject: [PATCH] Added more improvements and also fixed some issues --- .../libs/memberflow-data-1.0-SNAPSHOT.jar | Bin 260984 -> 261746 bytes .../AssistanceController.java | 17 ++- .../TrainingGroupController.java | 27 ++++- .../TrainingGroupDTO.java | 9 ++ .../entities/class_managment/Membership.java | 15 +-- .../user_managment/users/Student.java | 2 +- .../MembershipRepository.java | 5 +- .../MembershipService.java | 9 +- .../TrainingGroupService.java | 2 - .../TrainingSessionService.java | 18 +++ .../src/components/forms/AssitanceForm.jsx | 73 ++++++++---- .../components/forms/MembershipCreateForm.jsx | 101 ---------------- .../components/forms/MembershipDetails.jsx | 112 ++++++++++++++++++ .../components/forms/TrainingGroupFrom.jsx | 15 ++- .../src/components/layout/MainLayout.jsx | 4 +- .../src/components/layout/SidebarAdmin.jsx | 4 +- .../components/lists/TrainingSessionList.jsx | 83 +++++++++---- .../src/components/styles/ContentArea.css | 23 ++++ 18 files changed, 339 insertions(+), 180 deletions(-) delete mode 100644 memberflow-frontend/src/components/forms/MembershipCreateForm.jsx create mode 100644 memberflow-frontend/src/components/forms/MembershipDetails.jsx diff --git a/memberflow-api/libs/memberflow-data-1.0-SNAPSHOT.jar b/memberflow-api/libs/memberflow-data-1.0-SNAPSHOT.jar index 0610f036bb8f499bcddd3a28cd6883d960a392cf..c9650ee02a3d3f4a1d5678258aa450f9b3a00cde 100644 GIT binary patch delta 15880 zcmZ9z1z1(j7cP9@(B0kLAuZkA9a7TWNFJp{x(?ml-Ka>ZbazWjNlN)0j=%5zuUDV_ z%zNJT&RT0`Z)e86XKt@Ce?4HLYbXQZPyhfV0HDsLBN3er_+0S516D(dc1mCkq*&s5 z{*{alBLFRH;TXUP^FZYPtLn2k6h;wh9*2>HmbkDA(9#rE4O-U0@_<`Mu$U!5=3x@&=MVnAvqHc`#F{5S~wwSc?hQkEydxLpk)laCRDot z&-L7ZWLyLmXeogp4lP3v)SvB5GYB>C7!Y7|X{2sj0uKPZ#Yj%T;RU~617bBzqt(Hq zKO0s2y1rT?0042x@i_7zV|`qGyeAA~xIQLAW=q*#J!(P+79+lPvx~Io;FC|xZd}OTJ4Sq-QQn}-TSCL z-Cms60T|9zu~g6CH}ofB2qNNy4@*ggtNi)XOg{BZ6G#uImpaaY;6gd^OwsdG3$#&E z+1V+x^haay+Cq>%w_!SKz%JBn0G5cy%3`J1`n+H9_`Mubwi#nO;I1{!EOF;a8>=ey zYsx=#Xq8BAfHyT@EI_aMI^kesEoH^b+4|lS(={%|bAJflsK`SY%jP zYo8fjRIq=etu;CuwCPnCC$tk{SP~E(rav2)k(KnLKBUY&%p%Xeg8nGU0ef1zRZ5xl z%;1Ycl^-{INj!@nLov`~JW7#UAb&$JmzonNRJRm8oRl~zNh%J8hL;g9yPwLBZn(yN zlY7aH$)v?vNU@MQ3>d`}W!cUk;e&@f_vJKgRs=ml3fVUSB!4p&HV?PQ49_j1eki~+ zHZ3RTv<{?*L*x$OfyvfAgB_bK*8I+5@1K_4$n2BaJ<7E|kl;ou*Tp0`&iV$KkO%{R zhAfZ&vf1I)G+Uz#qwn_zE-8xhb>-_*8D!ETc|*)x4UZR7C^#a9AM4kQ`<6UuMN ztfNU-waodZL0kTrLtDflIcFxB+b=maE3K?X#=3HW$>>pDA!stYI4>+#|XZp)ZRK?8rx*?KGnLsMnJ{UiAZ&G8_$V+*8!i zIjRmjBELE(i`Y=4Mu)_MiJ+^ZUdu?YESqz3Ny@n*9yH5}SN1MN)wJ@Ea!VU8!HKL0 z*Xq@$vUA0pIwI7{kM!BEG(O1YX3*FoqUt^lxt93{NKOB?G#sgmI_CEJ7GkEWoO$cR z@HiJC*YN2KF5pN&1e>Jt^o^X3{sL`Yg}+^pEPo?UK?He!Qz|!8nELT`y|l1{$*Y(L zi4Y#2`$EwE0@Gq!VeHkM7e@sD`xX1G9N|M2=WObO-23r!7k+2T>o+Z7XDmXKEACs1 z6XMqeR2m~BoYxT|IZSk+HZ7#1uLLjzW=ytad#7#m?i*NtcobnBRE#P%E_@pKTwEdm|co%0P;wJo4o|xmx z?lSAa#k05Vsxg=i1)J}_r%I>@GkzpmLVOhLT3-vn48297L_B*hI3!k*_OVM|b)DB^ zWw9~{)I3^gKg^`bbJw~w8kg@p*IjA*YegiHE5@W_;TEe3=KI)3{Rg@2qJ@HVy^G%| z4ELcp^9K)!Z5S>HXYhUBK3O{e%qDxM4N}xFjMHmXoV|X-80{Y3lf_~hPBEL?NMBQCw8^>m&uUhfQ6XcjKFA_K0tkxzZ-x<2b!z)dr@07^k z9IUgM-yK0pvEd>hxP=^yUKj8-V0A+~cSAs=H^}8Iit(1g#qaI?>V{{oIsOsd4g%up z1}cTQaJhZv@LPSF1uI)8x;p^*NxLf6b)nUv`>!P%99rQ|#4fZ)1GC4wnKZQrFHL;7 zxtt^}whp~LM{(v&$T_-nh)&*kUUhVE;Ld|mUz!Y&)sp=(HFtBK9<=U=#&9J;-yDfxqyiu56aF7_u9p*`NftD!C50dZ^pNZQHM$)D?SPjSG+ zymP0N;PryVHuA^VF+5GLzRQ5Hg5zlFS30d!B`_@0rj@NlIAdAZ z-^f1fW@@C_@1c@m3CCGXH(2*8F3v^iT&=XSI=bpwJ3G?vtoIvZ1ix3X7RGv`c^L0z zgje%;*kty2=^sM~gliE2Y9bQYg@XbZ zkxvNF3C@-61Lz%O4y(sX#>yZAYit6so9?A@|H`u!|NM23tEKywxi(n;3l_`_{yNBQ zW7Qde0{~W0ATuN#IBpAwnVcVh(Bx~g1P7fZxjzXkCm;g=w8^H9{-AIgCMG63O$iNb zyrUuq&AWQ0ttytg4}U(0e^?ieUtL`6LaqpYpccN#4H&!04mj~!Sq?rsJvzmnqGP=tvJ^Vw$ zv&@I)0FMf$gmu?@nVX&Kg#$7BL1=AoL78faPk~j5&GN=f3|T|I$l6Z>k`ewF zi0n-XzTmm?=CnEP%E{>%z1TGVmzIJeee8rc1gS11@!XZT*Ib}Z+e-$1ZtHvVwu%{9 z(#`hf0v-p<3YC`xPM#Sq`u4c1@5sjw(s=Ub$i~Y1UVC4XsmEk8vv*-yfdf7$xgT2K z4WF-&rHmf=z41q8)i!*?Y_)5kIXAFUImK^bqa9b~%_RK&qI4%JRajRkD%HTWiAu0` zr=1F9Qj!y5A}|DM;#gj+7kI6&J zxDc)R)#kNV0tPd0;gm&Z9UEcyg=KN}R3p5Yd-kLavEB{{dB`qi5I-R5qd)Vt{~52$FnmyuQ)xpJD~Fe!JDl z5NetrqqeIKHcDQ!=}9tjJsu;}ckrVg%`z0h5`~_0{+4v;4XRTmp(`5%N%W%Z7${D$ zt+cxt)5;1UiS-``-3jHS*_qkq&63|mEzT5i#W#+UUXby7zg`$2@Q8T(B7r+9a~rkE zRMZ~NqSON1BFHIaMTquj)tkdD*QSL1!4BQf#VXscmkd|D3cHZm*PT+F!-4l2kdu5* znJoiznd~>`(M0_4(~JphN;8hq1=p`OlT)0_&0A&;>YX_MrPO8XH#^R`7P<00s1pQW zSl3&9|2os%C|g}^c+bxtX|HHO@=9MTGiOTXyGu$}zwtF@wU3(@-t2JmuZv9glsy$X zd%jsIN4K}Cf@yBVJ+6LT@eD`i4Y(b~W~H1(cFCJhJFwrkN0$>$RetBnDyT*01Lc)H zJRH`aKzKx{_M`+U859MlIS>;GnaMsXBL%&vi<8^RZ+1B&4L=0}8&$ZXg4f(o^ z`|02_u0)Mbc#|+)tYJO>;!fm*`MqYKS%7?XQw|aKhHXl!!%Y}hiENWt%Qd! zh(J4Y<2(1;f0o~3T$5lN^eFrJB}Ngv8TFy#8Uov27P>R@HZP_oc9@K_;ipT*U#`9E zi^|xkLjfVzs=PFEuuvJk9|{LABeAr-_Ae-z(47(0R}-+Hixa5IJ2!Z(*koRE3-d}v z=TH6#Uia(?zSjAM7~$;JAM#hRR0>um&{Wq7B3#8-#o&QarVeZ{eLdeSL{|S0n|((ccx{b};au z@z3q}{784{GKtun5~VFy7l!%8_OjJYfoICl#g&9_6h3>o5WM+9@&-fuTd>pld^jeE zyV|-*an(_p7U87fBsqE+c zO^9bfSQn9kqZ8a%XEE2{d5dfNKym4o%X-zO%dcqmyaLk9Y#Z->Hq{IXsCtK#48Pu_ z^%B|WBVF8c^#1Jtx6Tk>CnqA$s_%=EJm4+>>bkd+I?gBkNx2|k!v zkEAs%qH4`&RxEs7%^d4^@SAg}WDwUKN4BnbP;V?QVd6&x^{!KLk&qx~@PXm`vxxFDn2IycOZ@k4zB;${I=5AqBJG7= z8p_YwWfp{&2_^1Hf?iqn?lOJVtbpGu2{?^KQCAK(OF?msM;TWL|3r&En?BuFvGPWJNPzo>m~En20fb9+MoTKQPT8?ec2}fVi)#p}*?08eii6<<#(1N0` zcyID(15h^|^?1sJitsl&>#~Eb&mI z-zO3dh!5^FUTS9yWEBzQMWzu}*`0S%7JcyeU|dA-39cGkW!|E1uo72FZ1BJn6U;H+ z$WpnZYv)%Jofe0}P9C)>G0e$Dk`Ge;XvTIf&V1|R+9NsIqrYEUa~tsC(2>(6C{Hi$ zy;vJMXx{E-pb&nvw*RPIvIpkawNuZ_k4cub^T7Fz-plI?0%|kK9e%mD&NNM+kj&}r zo$noeWyAce$Ehq!ofe^#Ze@c3BPXJ4+G8@F?{W722Z4#3^A3rt<9nH^i(Sy_$pZ;F zmh1}cF_OVux1Sl;>D6veZ(x_eI>m^hg1>Fq4y~h84$3a*M2Ecc?`v<06-HR03ezyX~Pd@ z*#V+7)d$p~Lf3j0k+480u!$ang#v-t>AwIy!St`mCD|ATY8pu)`D;2zBmN8EGjRR_ zk}NM+Xh0nm-W>oe0B{Xi_8BHm0_nkA2S5Q(jn1meG#8#2hm-ZIp+WH-`RH~MftG}g z2-qp}jQy0F>Wql~(H{(^Zdro8J_vrex#6f3ZzHA17)ez%8C6LM<4SPzPWNtaAMPHv z839h8w;6bmZY47(5|o*FF&Rt_6f5a;MU-2(DsW7usceiW8B`jXHmAtO9#%HLAvKAC zJ~+K0;mCAL{k)V;&O^dOJlShE0-O$$h2_-3*UVw2E}|X4dE(Q>C3(@eFZfz}Da6Ir z2}L2_o6hRCb%FDR8kOPAZsqO^^~30&2S9>7lbhV!REw~T?FNJ?+IpkJ`v~TyZ)hwF z#y3g3unlH|KguTdD@e3}N{3^QUb8TNSUd+h4=bl#4R9V83bb?=mQpxmZK zY1-PZ+3hdMWCP)9H;g_@Hb*rTBF}#wi=nqmz5n%XEh5$96GqjIZl1{nnafE)Z|i4xLeEO?sa{v8sK8QwhpA5#e* zgTbgMEy@MWDnlywWb;t$1{%yzcokViI>qDq07C>D+g6??rX{+dAB(Ze7s-#pGt0532q^BU2QU1y6}M zoPNB)<)Ybu;4SmP-uA^5b~&a2_t1?B1LDI+4EQV9qsS|J8YNbkm9m_GVghsn%02}A z*xM9|)vXR#-3UGx)Rj!4^qI1&;tJ!8AN51ozB2xCajM@_N2CpGc0ii7i(&d`5sDF>~ zg&k7O$I`60nQ0!Qji>>)tmtJ!;j<0QO==udvLsk#u6W4Xo`= zS=5h7Tj*^9Sr-ZhsmKI_n(qQSy@wk`*+&z!Mp&4lZdYH{To1X!(sHlVZNX&I#VEH^5lvT*7Hz|VNO2xVtrwyG`@27RU5;Z>&ouwtjF=#%_)+rn+E} zC4#LYrHT?*aqNhYDe!GHTuGn)nF3mTM;c`Ye(aG-S@BQcAV+F1g zrtP;`A&hpEG5tq`4dFlQqv;rl_l~t$atC>Ih90|T$wBe`N~o&_XGg?_iuX=R0>4A^ z4%fBLopW)@n0pASvK%IT;ah)S@U1F2CIy=m5%|Sz-@oCH*wc9cjH6bwZufG+yxOL) z-5isFlXm#hz%IOaEI=<|LKnXe$p?jI^`O}`3ecHqsRK3M`%RIYp{;B<2Q9o1GgHYKuXFE=6)zXv2 zuI?JKDQ@~lVp{?2Kll&PH{J7Fx9Gv7eX{tU`cB_h49K^Ly`;Y%LNI;%<-pmNx8B7^ z+B}U63!cJ&p)*UQfIoiXWWu>j(ccjPO&MdyZ^9iEG?Mb9n3}?0D2(taGDkO11WQnh zVhm;M2cC%tsnE@_@oyufD9t53#lngTNl`+YIKnncfe2stCD&$8__AW^<)dwX!)*5Y zbAz?5Kr(KVP!(Ty|Dz|ecjV1++9?q!4RJ0V&2uw(BBuUxs$cXiCZ3vVW6~7y`(_l;HC0zsI=v2xW*Y$0ii~ zRL|H{jmID;E|PbpdM_(5kQG&q1|qWxTo@B(UbH={bTy!9UKRN;)@AKl!U50eyvCIT z|7r?duD}`da=G7E(7$r;o~fnnEyl(z@bQx*$TiX)F22gyJ}1=9J_xZv`Kej?X+r64 z-tLyazk%F!YB|DOaP7g?{N>MQAp`^Io7n(wQql(HoL&Z6Ta_7%iZ zEUaDrrL4~yGK@S%m-km9XqY0jc zcTL4vp4cYGvL?sWhTtGnOZhPJ-k}LBGsc#XCBC04Ir1N2**yhc;pnfl-NUu0-v!T@ zzuDgdf>!bl+A@exRGx&<{9aIX#ASgDv$F=~#}M7cO{4GKZB%Q0NwXbH?5-^&Vw!Bj&vNdKZ%}moXsxa*KXizX}QP+|Nh1F+H z444@*%xFe-a(whkT%~VS8`-i2i$&B(al}t$ru~!~P#4>e#woqBq(oddXuxb-R`eM* zXQT-J?S9Mx_p|S)$dxlbx4ZjEaRQ`Zk8@t2QEP^({DmI`t6HJYu|4l15bPh|^9qje?~CQ<1=56D$C3l&!*2i?0HB#nJwpxtybL4;b6x;R zKrIHyzAH2MPgbPkZwj%N4fhjxGb9LHziA+a4N`9`xVyQ*z9+XWp#RGAOXfU=SAirM zkIB*4Zc)iT%d6}@sWohXdIG0YQu!um{pOm}&HwI|Vv(VUyHuc{7=@zx&FX#7&6@9N zfd6mMxEN+W;-A<8j4N#3azVsc6upva6VQvAtkTW>3inl?LH1>pmz|;(#a@hyJcsSA zXïz~TQ=+kZjOa}A(c8eLs$!+L7JT{I(k2b>;>ZN@8$`oH66^+M@<2H@13x1?^ zx6%e4x=`9n;i+Qx>x_g{Ze$)%7dK{Z{~We2P5X9G+Qk{j?c~^RX~Vy)M@n%T7NhMaS zsv%#9#FL2ae1y}s!jF2vB_0CLGS+v5$E!cCKVhE!IxQsCITW!OnLT56M8)H4D!>aI zYa;9~q26)n3Ae}Eo_}dcl{L#_)Cw9J!wXv}4P_QRB}pS5pn?CuvOuquX>a6WsiU4A z?!+Ga;=PZ+k}vYoHn?7(eYfjq6s z;9crvc#$gC3hR;sSKdoJ$*zzSVuScX?cOgrep8j?qP?w30}j1&23SI`A~--==Lp1^ zsgtX!mIo6OFGG~^no|Y_yu1emqLuOK?$CKeXQeDJH7xV%>}+eIhh^=(V!n`8a7TNi zq+K5v_8@fr>d>qPcjz-MXr8nKU_=Fy0kZBTA*hk8vFlFl_x8DSxJeqX^?Fs5OK-{- znCye&T$aw0>v!T4G3d|;3o>3je?Pf16YU50O5 zRYt9Li-S^F*$)r29s@Shk8%T4tt?R`19hFZ9W3{KsRRQpBXO4d%}%W>aB*B~9H;^B z?I^UkV{%Yva6aWarOg(yOK7>pI(baEnfQBxLw0)Z4^Spw$LL1tiYtJ)%hGWJbbbz8 zjfjG7@f2vz3i$hdl@ zCWaU^^@6le2;lrnXL3mC37m};`xhNp7i`0sr9|e z3zuc9O`JBY(Kc#T|4x}lBv&a`$7DRf8ExGDBgiu|Lru`--HB(}n*#KEGMbm8L!SkX)W~D85|d**d4x= zZ@@^ij`p3KFd{^~(kv7NJV#?R_OJ#r^uz|H(ssw#Z1EeSC~~G*F6>@wRa-%8Mh#cl zdWHy1f=5Ul+=N9%J`q{5a$bNbA2;{IF;&jDV-lhwByJVP!5Xa%2 z#t+l{=^qh3Fx9*UF;}?e*>ujc#hA+fsrITH_Zzj8yLKpbz%xq-_S5OD;n5XOUWEOj z+*lz<(zh*0(2L8G+plfXJWE<1>=M?KV};wNy^_q%d1G2cG;Tu5 zgM#EZnNU?S*yivX;L7Gipa#du)c)WVR9crXPO<{K{}e}^U7J5(oy zP5auxrMGnFSo`kR9kKhegfKf>p(H$6Ye>yGn*QfSuMc3)kqgb=QK4J z!*0MAPvzh}h&JLiSCXifIv=OZ3e!}>cIN0d%?)2^U(0~|rf&CqqfYy0&dGP-!OP$A zb*De*(!aReJ+7+|P}g1pMiLx7r1H#^nm3$=R1#X(+O1V~-Pc@tXJ&tSWfZlshmxiu zbnC9`E}JqZ4^m~<`c7l zUWju#?p!;C6Z<2N`~nRIxGh{_LLiv0jmU7-kl)U5JJluKKcy~RP(_Qczb@|yKvurL zQ(*Pg4KzS{_}2cgb-vQ8^tcb} z9q^wT!Y^`|yoJ<@^~ByS*0AR=ajt9=qg?(%az@$yPKs@?@kJl2bRX+E*+;1+vnv}`_pgMlawr4tNqtq)yuv_Ucgg9^ zBIILV`0HWhw&`HRpgBVu0g9zqM4thZlwa-?N&b^m!Y!Z6^x?#uae&_l-Q2%P(8|93 z@EuP86ds)gI}ja6jZ}|`u&{@G%_sYF$lVbBXF8)NvxS*nsh?@NAH~OrI>dwlX;_2A zRa^5Nt{S9sKFgh0dQ5NEV}IliR&GGVx=O~+Yoa;hmbi948^wS{4>q(lOPSkcRlK7~ zDTIrLcNX1AiTl0u3;Wc{w?0xncWAH!Il$G`E2 zd%NrdJ3m{nE$E}uRh&0Jnrksjh=~T8PQE878hi}IYI*m0mc7uU_{ZU@d{qiY(&pR? z@wPB0qY$LIZ;|bQgG32u%*WphuIMZ6W!{&9Q;b6SpQ3C!RKBE#`O&>`M08y(yp<#_ z_W@n{Je}l!vtTPTPFfh)I33ir(g~Tvl{z|KIjT#O<82;scDT-7{@g(N`wxw2p%2W1 zNF92&%RwM^Vl7Qr8xq{N_r@6n%X+F?akaSZWpR;>*1df}-V3vQ@9*`0w~?z;e_8gu zXbpRSjUZ@$_vzjsUd~W!3axSMlIV4#6%i2BC%wK&i!|wqJTbi5c24eLtT4#wS-tie zPdcdi0N+F}=fygD+RDuv-LuE0A8+V>+}ge0E}HfnIiIH+%8HtyW&x9-{t%RmLo}0) z6aS0}jEjdSo7Zy-1i=q+{CfH2PrR2ZF0c5i3w^<|!al~A&g7$8j=fX#I#)gt)jOsXVdjaRZ0{OKlf`cdWv zuzE)odWlta+Sh-fKwS4RLEr3a73YsxF+K%CRovoTvEN!mI+4msH6i#xIPs~`vFj{G z!^!^)In`tj0M$)OL7$$Z%l4`h_yes#fv)L){=|BQx_sNrTx2SaRF&P<10^ZlCA& zS8{sLh%qdE&qW98FX6emGsn}rEUtp!;iFTLOO&Utf7Z88O-Wd85ud{UP(6V(2>;Ix zi06fBygJE)I^->Q6nXM_1@ukc^CA@~`TjRP$k5lEbO--WkZID6vSk*X44q&IU7S-g zQWBn2_Pf`%g5Gkp+q?x5V^g-joqnsW=A^B<;O;A#Z&Oq1c-N_ z%~LQ<$C-~mMe}v(2vM31>2AS7YfR_zCr8(VDp{-+m@vE z#Ll3OKhkv-I0T~j;ItCrPE2km^#|%YW01L-x}vq1K~2~fWbx~?}G4rijlr}nTl!8K$ zGa3~Auu$PLquFBUbY2PkRQMFLzv%Tcj4Lx;7!`guWnz7bkVZVaWW$LKM=(f7)lml7 zkWR<^b+Z>8QoIc~N~&R-To&J;FrQfY8*SQ4r2^Nuw0h7lEdV?0QE7>I6#qLO&anjd zovp98Y0L&=w+@Zn+P|hcP{y`PI#WQ+0u8OwtKR^6D7<(w3T^bVFQW)GHuxR=8&l#G z{uC(q>Z?t|qv$m)Yyh0s6<&lI(AJkLms%@^g_ngI442I#UlP2Wkd~y#HZ2cXpsFu! zBl-+8NONc^cc2)ESAj7|ArIQGHS_S0+cP-UEgVQi?rO{d?_$S@zN`PwT zs|;+{>-BCoH6Mgil`$M$;!SF(7}b+AzCPb2#a{{Q`%xuhR9V_|av2GBH|&<(=(P8J zXAdsb$D$QhJ52dXbwwBr%A28e8PoO)O8p#eT+E@`2A}>Sk#F=%zt0ar9dDU4@}O9v zPEk8JvNlJ2wzIny;sV9Mv8cHbJCVC(eH5V{jv<6g-7Vqmouu9mzR8u&44qOvBn zU&>3FQfU-(QiHM<(G~!wjP~7%UlnO@4{K>Ds`wpUL1|a}r)hGS9uWB{+QuuCwb&bt zUiPN=7d**hMghfS41*j|F2afZOea6=x4F!E)O+vU359x-_+2;qtmA*B|CS77dW*^0 zPD)weAvEw%Mzc7%xV+k?Xnx2Sx*4R>D=H{8XZX9*Q_V0$9jDhceoGAgW*esR<6QA! zz~qH0LECL-hQJtbnjIubRuZ>juk=grMd2_o+;doF=~uz)6;ZKZmWb9Mwi64NyrGOQ zC3m&Ji)0bHpzj&-rN&eYRY;pWw@!d~mN#g5w7CSB3t0#6hWv~+Fp{!5z<43YRyA}1 zQ*NAY_Qd^VTi8V<@eHeKw2C8nvqc9U@;=38nLQ5Twl+n5f5bquGq-ET)s2XJg_~nj z>A9yodcv4EWBsx`y}Upf=ddX%?(SEkZ_=fM=gSy=tG=6MBqi!>%xIQ-o#Ry|@#hU- zoxniwpd+$L?Jf(Bh4*l)EOq0(wte?r>QZ~!6tl4^EKweBLQPI7?p$(h2YhT`lYPu> zyi%8%CdMr-%#}CDwn^pgrHkmmOSRnuHtuQ(l64OuuWH|J_tIsX3Le4{N>a?fFYVLh&<-~YmA%U)F(twr4fvc7u}dqBQx==Y_C4nvGMh)0JAzD3#`xUL zG>0xLT?F==auDa7jW!!aKeVg2EaG-3)_W*G5;1zlQ;S+n^+a3W{_}O^SMidu%HBUxZ(#pmZYTzK21bwV6gb|M zbF=ll8xGpI1POn44u93ZykEIqdHAilnc#+KkW2O`EO|LBw8u*C{V_QERyB&TFgX`- zD|7Toqtp94Oj(m6tHelO60;sB){3Ig7V}@ zs?PoH?gdw!3&^|cYFnJi3R{k0;Nk>_K1zUW3zMEWib2QNVG2J84_s=y$j!chVfLa2 z8i{#NCtTTPNuk7bbl0%5)2lxkm&e&ejHhZwp?$aa<;%srERhjarj7W+e~z zRK%|jli|lbEI}%QSG8l;=$_H<#xv{HS3I82o~DVZo0dg)M%gB9?p~4iY=~qSu`_zb z`|-(BcYhJtr9~{Wsv@8_bi_9;Egbgw>Ypgu6krA0M-a>faL1Pj7)_Qw1Z&dYmyWaJk}6w$ZGXvBhIl zkw(2jLEIA_2c86QX{KjKAegEk`BjRpz2RHpvZq0M6+cY z?Xb4^bJ`HiWk~a9rNoh-4`Ekvj zObq7qvfkNzoibhGGdGz(p6Y`)o<6F-or_nUE0$eJRo2Z}BDhOFx+9%>LO%h>&Q^NZ zjAppC2~$1P3k&4GMR58&F2cdVxx1ybyEWdU@&q4*`hfGvqxVCG6`dogC0!leOr7Z& zh|1I#&$SYEb)~iF*F&X{E-GxOulaJLkZ$DASsdT&5Z0=2obcRCnB$k(*Kb_gcTEG$ z(J0a9ClUjU`}kfHd9np0a7G%I)1H;GxX<(4>>ZnI;@wm+E6i_rnJCkBU^utu{yIdc zL=;HsbEUDQ9OPJ0x$GbynU!x1Vx@K|0=>L&e26G-jgDS-{kBEoKq`DL{IG`nJK;2g z`T+*yg=2>VDl}tN&?f_xHl@bJ)_dYTI~c~0~Lm^uT-5&npdv3Xr9P^_<+tq zG)mv-mnkzUP1@*HB)Yn*XR^vz_||(F6kIr1{eE`bzB6_=0Qoi=APhMo^m}`B#7So`CggQ8Lozn?^C}$~tU&^U1J1bw;~Mb8A&J1)|FwF_!Du2wxv%Ol zgMW321~6p^P)^tkrW1NHsO{DbCI)JajP!$nT(E7Ce!v{#=hHu6##vx36fDdFd7%Jv z4k-S-Ee5PP2jqPA1g=;Cl7e&Rfb>xMcnR`ra}LM`{e?9Tgr02zo6G~DXOh6}^FZi< zBQV+m&;Y8jT>zRw!Pf<#928(L0+pe_Y!Rpm1$B!+2Phz00$M`ByCtAK6hH#XL-T;d zA_Z$L1393-AVNr1%m3N-mmz1Ro|Bbb0a`$-L9&*BHt6RH@Ff&5uL9MfAYc_}2Gy*t z0!^SmWDRKl@A)Qh;~LP6^6x(L$DdA!0KivV06-G(zdyzAguqLegSpp%g2}4X=wOmPAR5#s-|dD_JH)3F59C*#eS5 zU3Nc{mj+N0X&XoYC8@U||cC=x1fJSuA{Vax@Y6_s)M=pc!IZMM7$v zKx%ORQ$sBFzZxX}Q}ZR4j}ia@0OaQf<{vd)0yLAHT_6oK6ZaCMG(;Expcrxq{iF0w zhA4@WvA`(FdCA1kCkxuo%zKcInojvY#>W(j|2=kOE7!KY5LZQz;G+MyI|DcD0aczo zr0qi-pk@634#493Kn7?o1ay3j&s*R&pSQsMQ<*voO#Kr`2R>T_k|#T4k$^Y$|Ld23 zw$1%hCq3tH9mqC1X{h_TysL|Sh@=LRpUFQ`%>4h$Jx2i&c;x^{4NdhBlB#>b|Eyrs zLm(@(8)BYK+(pkOq2%2{QfNw03)&IH0xJG%;VmZoU$SF-IF1;Q=>3pO?Vk+3mO$m; zwId)cG}$KAJrXvE%pTGo|4OCGo~3_BmA5}3p_a;@iI>R<<>dbh)pe)wlMGT{5K>?J zpHP04;DTeI1lar-NDU3ef!6_fy$S%dK%_?hND-=^rFMT?bpi=BT=TcC{mFl~%;W%d_;&TUVL9Tyq!F2s!&#tFH7HGWeQ%F4H#=lPD z>k-q={u>b}&me}!roZyQv;X?*skInI3gUGU(ujW(iEa5S{c{GSg0>f{><1$;IRF6G z006lD$yvNDdGmxAY;X>liJpi0x95;hr85wc3fyxJc_g06&1W)u6+#Mu1%5%oL&*PY z%iI5ZyD)d3m5>c^gwW9t=~?~!{TICU3rGNKcM7p;LoHB0|9j!~|K2vqJBU&e^5*UD zs0vMG@d8K+gh7A-bCbYugPAUYv`|{@5<+vL|3^bs0nnqw;7`vq204_L0gGP((V%Ls zD+t|12c@~d!B>#s^tqV@&ol$)fAr}UkP%7~Uqk4x0x;kL0~i6Y%QcV!O2LM`2&^AGBXg3g>h2np7RFX-prKw;oc6io6NJOP*@0@57zJII5nF$RP(Zg)Uw;JaC1vIYV@_~R-N3w(43 q#Dz}%F!vBYcnklR$!Qjd0a?kxL&jnNz!>s3gB}3rTY!v^fd3DEWbj%5 delta 15181 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 G>i+@oiV{Eo diff --git a/memberflow-api/src/main/java/com/denniseckerskorn/controllers/class_management_controllers/AssistanceController.java b/memberflow-api/src/main/java/com/denniseckerskorn/controllers/class_management_controllers/AssistanceController.java index 299952b..8a17be6 100644 --- a/memberflow-api/src/main/java/com/denniseckerskorn/controllers/class_management_controllers/AssistanceController.java +++ b/memberflow-api/src/main/java/com/denniseckerskorn/controllers/class_management_controllers/AssistanceController.java @@ -3,6 +3,9 @@ package com.denniseckerskorn.controllers.class_management_controllers; import com.denniseckerskorn.dtos.class_managment_dtos.AssistanceDTO; import com.denniseckerskorn.entities.class_managment.Assistance; +import com.denniseckerskorn.entities.class_managment.TrainingSession; +import com.denniseckerskorn.entities.user_managment.users.Student; +import com.denniseckerskorn.exceptions.BadRequestException; import com.denniseckerskorn.services.class_managment_services.AssistanceService; import com.denniseckerskorn.services.class_managment_services.TrainingSessionService; import com.denniseckerskorn.services.user_managment_services.StudentService; @@ -36,14 +39,20 @@ public class AssistanceController { @Operation(summary = "Create a new assistance record") @PostMapping("/create") public ResponseEntity create(@RequestBody AssistanceDTO dto) { - Assistance assistance = dto.toEntity( - studentService.findById(dto.getStudentId()), - trainingSessionService.findById(dto.getSessionId()) - ); + Student student = studentService.findById(dto.getStudentId()); + TrainingSession session = trainingSessionService.findById(dto.getSessionId()); + + if (!student.getTrainingGroups().contains(session.getTrainingGroup())) { + throw new BadRequestException("The student does not belong to the selected training group."); + } + + Assistance assistance = dto.toEntity(student, session); Assistance saved = assistanceService.save(assistance); + return ResponseEntity.ok(AssistanceDTO.fromEntity(saved)); } + @Operation(summary = "Update an existing assistance record", description = "Update an existing assistance record") @PutMapping("/update") public ResponseEntity update(@RequestBody AssistanceDTO dto) { diff --git a/memberflow-api/src/main/java/com/denniseckerskorn/controllers/class_management_controllers/TrainingGroupController.java b/memberflow-api/src/main/java/com/denniseckerskorn/controllers/class_management_controllers/TrainingGroupController.java index a4f9011..76dde1e 100644 --- a/memberflow-api/src/main/java/com/denniseckerskorn/controllers/class_management_controllers/TrainingGroupController.java +++ b/memberflow-api/src/main/java/com/denniseckerskorn/controllers/class_management_controllers/TrainingGroupController.java @@ -60,16 +60,15 @@ public class TrainingGroupController { group.setTeacher(teacher); TrainingGroup createdGroup = trainingGroupService.save(group); - TrainingSession trainingSession = new TrainingSession(); - trainingSession.setTrainingGroup(createdGroup); - trainingSession.setDate(createdGroup.getSchedule()); - trainingSession.setStatus(StatusValues.ACTIVE); - trainingSessionService.save(trainingSession); + int months = dto.getRecurrenceMonths() != null && dto.getRecurrenceMonths() > 0 + ? dto.getRecurrenceMonths() + : 1; + trainingSessionService.generateRecurringSession(createdGroup, months); return ResponseEntity.status(HttpStatus.CREATED).body(new TrainingGroupDTO(createdGroup)); - } + @Operation(summary = "Assign a student to a group") @PutMapping("/assign-student") public ResponseEntity assignStudent(@RequestParam Integer groupId, @RequestParam Integer studentId) { @@ -162,4 +161,20 @@ public class TrainingGroupController { return ResponseEntity.noContent().build(); } + + @Operation(summary = "Generate recurring training sessions for a group", description = "Generates recurring training sessions for a specified number of months") + @Transactional + @PostMapping("/generate-recurring-sessions") + public ResponseEntity generateRecurringSessions(@RequestBody TrainingGroupDTO dto) { + TrainingGroup group = trainingGroupService.findById(dto.getId()); + + int months = (dto.getRecurrenceMonths() != null && dto.getRecurrenceMonths() > 0) + ? dto.getRecurrenceMonths() + : 1; + + trainingSessionService.generateRecurringSession(group, months); + + return ResponseEntity.ok(new TrainingGroupDTO(group)); + } + } diff --git a/memberflow-api/src/main/java/com/denniseckerskorn/dtos/class_managment_dtos/TrainingGroupDTO.java b/memberflow-api/src/main/java/com/denniseckerskorn/dtos/class_managment_dtos/TrainingGroupDTO.java index b41d9b1..cbebef4 100644 --- a/memberflow-api/src/main/java/com/denniseckerskorn/dtos/class_managment_dtos/TrainingGroupDTO.java +++ b/memberflow-api/src/main/java/com/denniseckerskorn/dtos/class_managment_dtos/TrainingGroupDTO.java @@ -20,6 +20,7 @@ public class TrainingGroupDTO { private LocalDateTime schedule; private Integer teacherId; private Set studentIds = new HashSet<>(); + private Integer recurrenceMonths; public TrainingGroupDTO() { } @@ -107,4 +108,12 @@ public class TrainingGroupDTO { public void setStudentIds(Set studentIds) { this.studentIds = studentIds; } + + public Integer getRecurrenceMonths() { + return recurrenceMonths; + } + + public void setRecurrenceMonths(Integer recurrenceMonths) { + this.recurrenceMonths = recurrenceMonths; + } } diff --git a/memberflow-data/src/main/java/com/denniseckerskorn/entities/class_managment/Membership.java b/memberflow-data/src/main/java/com/denniseckerskorn/entities/class_managment/Membership.java index 10e6d3c..3c4af2c 100644 --- a/memberflow-data/src/main/java/com/denniseckerskorn/entities/class_managment/Membership.java +++ b/memberflow-data/src/main/java/com/denniseckerskorn/entities/class_managment/Membership.java @@ -6,7 +6,9 @@ import com.denniseckerskorn.enums.StatusValues; import jakarta.persistence.*; import java.time.LocalDate; +import java.util.HashSet; import java.util.Objects; +import java.util.Set; @Entity @Table(name = "MEMBERSHIPS") @@ -29,8 +31,8 @@ public class Membership { @Column(name = "status", nullable = false, length = 20) private StatusValues status; - @OneToOne(mappedBy = "membership") - private Student student; + @OneToMany(mappedBy = "membership") + private Set students = new HashSet<>(); public Integer getId() { return id; @@ -52,8 +54,8 @@ public class Membership { return status; } - public Student getStudent() { - return student; + public Set getStudents() { + return students; } public void setId(Integer id) { @@ -76,8 +78,8 @@ public class Membership { this.status = status; } - public void setStudent(Student student) { - this.student = student; + public void setStudents(Set students) { + this.students = students; } @Override @@ -102,7 +104,6 @@ public class Membership { ", startDate=" + startDate + ", endDate=" + endDate + ", status=" + status + - ", student=" + (student != null ? student.getId() : "null") + '}'; } } diff --git a/memberflow-data/src/main/java/com/denniseckerskorn/entities/user_managment/users/Student.java b/memberflow-data/src/main/java/com/denniseckerskorn/entities/user_managment/users/Student.java index bf12e50..b16af07 100644 --- a/memberflow-data/src/main/java/com/denniseckerskorn/entities/user_managment/users/Student.java +++ b/memberflow-data/src/main/java/com/denniseckerskorn/entities/user_managment/users/Student.java @@ -44,7 +44,7 @@ public class Student { @OneToMany(mappedBy = "student", cascade = CascadeType.ALL, orphanRemoval = true) private Set histories = new HashSet<>(); - @OneToOne + @ManyToOne @JoinColumn(name = "fk_membership") private Membership membership; diff --git a/memberflow-data/src/main/java/com/denniseckerskorn/repositories/class_managment_repositories/MembershipRepository.java b/memberflow-data/src/main/java/com/denniseckerskorn/repositories/class_managment_repositories/MembershipRepository.java index f7aaf03..d285639 100644 --- a/memberflow-data/src/main/java/com/denniseckerskorn/repositories/class_managment_repositories/MembershipRepository.java +++ b/memberflow-data/src/main/java/com/denniseckerskorn/repositories/class_managment_repositories/MembershipRepository.java @@ -3,6 +3,8 @@ package com.denniseckerskorn.repositories.class_managment_repositories; import com.denniseckerskorn.entities.class_managment.Membership; import com.denniseckerskorn.enums.MembershipTypeValues; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import java.time.LocalDate; @@ -15,7 +17,8 @@ public interface MembershipRepository extends JpaRepository Membership findByStatus(String status); - Membership findByStudentId(Integer studentId); + @Query("SELECT m FROM Membership m JOIN m.students s WHERE s.id = :studentId") + Membership findByStudentId(@Param("studentId") Integer studentId); boolean existsByType(MembershipTypeValues type); } diff --git a/memberflow-data/src/main/java/com/denniseckerskorn/services/class_managment_services/MembershipService.java b/memberflow-data/src/main/java/com/denniseckerskorn/services/class_managment_services/MembershipService.java index 7e367bd..e0656e5 100644 --- a/memberflow-data/src/main/java/com/denniseckerskorn/services/class_managment_services/MembershipService.java +++ b/memberflow-data/src/main/java/com/denniseckerskorn/services/class_managment_services/MembershipService.java @@ -82,13 +82,12 @@ public class MembershipService extends AbstractService { logger.info("Deleting membership by ID: {}", id); Membership membership = findById(id); - // Verificar si está asignado a un estudiante - Student student = membership.getStudent(); - if (student != null) { - logger.error("Cannot delete membership. It is assigned to student ID {}", student.getId()); - throw new InvalidDataException("Cannot delete membership because it is assigned to a student"); + if (!membership.getStudents().isEmpty()) { + logger.error("Cannot delete membership. It is assigned to {} student(s)", membership.getStudents().size()); + throw new InvalidDataException("Cannot delete membership because it is assigned to one or more students"); } + super.deleteById(id); logger.info("Membership with ID {} deleted", id); } diff --git a/memberflow-data/src/main/java/com/denniseckerskorn/services/class_managment_services/TrainingGroupService.java b/memberflow-data/src/main/java/com/denniseckerskorn/services/class_managment_services/TrainingGroupService.java index 7f2bf1a..864c6f8 100644 --- a/memberflow-data/src/main/java/com/denniseckerskorn/services/class_managment_services/TrainingGroupService.java +++ b/memberflow-data/src/main/java/com/denniseckerskorn/services/class_managment_services/TrainingGroupService.java @@ -13,7 +13,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; -import java.time.LocalDateTime; import java.util.List; @Service @@ -145,5 +144,4 @@ public class TrainingGroupService extends AbstractService { const [students, setStudents] = useState([]); const [sessions, setSessions] = useState([]); + const [filteredSessions, setFilteredSessions] = useState([]); const [formData, setFormData] = useState({ studentId: "", sessionId: "" @@ -19,7 +20,21 @@ const AssistanceForm = () => { }, []); const handleChange = (e) => { - setFormData({ ...formData, [e.target.name]: e.target.value }); + const { name, value } = e.target; + setFormData((prev) => ({ ...prev, [name]: value })); + + if (name === "studentId") { + const student = students.find((s) => s.id === parseInt(value)); + if (student) { + const groupIds = student.trainingGroups?.map((g) => g.id) || []; + const filtered = sessions.filter((s) => + groupIds.includes(s.trainingGroupId) + ); + setFilteredSessions(filtered); + } else { + setFilteredSessions([]); + } + } }; const handleSubmit = async (e) => { @@ -27,17 +42,17 @@ const AssistanceForm = () => { setErrorMsg(""); setSuccessMsg(""); - const payload = { - studentId: formData.studentId, - sessionId: formData.sessionId, - date: new Date(new Date().setHours(new Date().getHours() + 2)).toISOString() -}; - + const payload = { + studentId: formData.studentId, + sessionId: formData.sessionId, + date: new Date(new Date().setHours(new Date().getHours() + 2)).toISOString() + }; try { await api.post("/assistances/create", payload); setSuccessMsg("✅ Asistencia registrada correctamente."); setFormData({ studentId: "", sessionId: "" }); + setFilteredSessions([]); } catch (err) { console.error(err); const msg = err.response?.data?.message || "❌ Error al registrar asistencia."; @@ -48,14 +63,15 @@ const AssistanceForm = () => { return (

Registrar Asistencia

-
+ + - + + {formData.studentId && filteredSessions.length === 0 ? ( +

+ ⚠️ Este estudiante no tiene sesiones disponibles según sus grupos asignados. +

+ ) : ( + + )} + + - diff --git a/memberflow-frontend/src/components/forms/MembershipCreateForm.jsx b/memberflow-frontend/src/components/forms/MembershipCreateForm.jsx deleted file mode 100644 index ff6876c..0000000 --- a/memberflow-frontend/src/components/forms/MembershipCreateForm.jsx +++ /dev/null @@ -1,101 +0,0 @@ -import React, { use, useState } from "react"; -import api from "../../api/axiosConfig"; -import ErrorMessage from "../common/ErrorMessage"; -import "../styles/ContentArea.css"; - - -const MembershipForm = () => { - const [formData, setFormData] = useState({ - startDate: "", - endDate: "", - type: "BASIC", - status: "ACTIVE", - }); - - const [successMsg, setSuccessMsg] = useState(""); - const [errorMsg, setErrorMsg] = useState(""); - - const handleChange = (e) => { - setFormData({ ...formData, [e.target.name]: e.target.value }); - }; - - const handleSubmit = async (e) => { - e.preventDefault(); - setSuccessMsg(""); - setErrorMsg(""); - - try { - console.log("Payload:", formData); - - await api.post("/memberships/create", formData); - setSuccessMsg("✅ Membresía creada correctamente"); - setFormData({ - startDate: "", - endDate: "", - type: "BASIC", - status: "ACTIVE", - }); - } catch (err) { - console.error(err); - const msg = - err.response?.data?.message || "❌ Error al crear la membresía"; - setErrorMsg(msg); - } - }; - - return ( -
-

Crear Membresía nueva

-
- - - - - - - - - - - - -
- - -
- ); -}; - -export default MembershipForm; diff --git a/memberflow-frontend/src/components/forms/MembershipDetails.jsx b/memberflow-frontend/src/components/forms/MembershipDetails.jsx new file mode 100644 index 0000000..37da3b0 --- /dev/null +++ b/memberflow-frontend/src/components/forms/MembershipDetails.jsx @@ -0,0 +1,112 @@ +import React, { useEffect, useState } from "react"; +import api from "../../api/axiosConfig"; +import ErrorMessage from "../common/ErrorMessage"; +import "../styles/ContentArea.css"; + +const MembershipDetails = () => { + const [memberships, setMemberships] = useState([]); + const [errorMsg, setErrorMsg] = useState(""); + const [successMsg, setSuccessMsg] = useState(""); + + useEffect(() => { + fetchMemberships(); + }, []); + + const fetchMemberships = async () => { + try { + const res = await api.get("/memberships/getAll"); + setMemberships(res.data); + } catch (err) { + setErrorMsg("❌ Error al cargar las membresías"); + } + }; + + const handleInputChange = (id, field, value) => { + setMemberships((prev) => + prev.map((m) => (m.id === id ? { ...m, [field]: value } : m)) + ); + }; + + const handleUpdate = async (id) => { + const membership = memberships.find((m) => m.id === id); + if (!membership) return; + + try { + await api.put(`/memberships/update/${id}`, membership); + setSuccessMsg("✅ Membresía actualizada correctamente"); + setErrorMsg(""); + fetchMemberships(); + } catch (err) { + console.error(err); + setSuccessMsg(""); + setErrorMsg("❌ Error al actualizar la membresía"); + } + }; + + return ( +
+

Detalles de Membresías

+ + + + +
+ + + + + + + + + + + + + {memberships.map((m) => ( + + + + + + + + + ))} + +
IDTipoInicioFinEstadoAcciones
{m.id}{m.type} + + handleInputChange(m.id, "startDate", e.target.value) + } + /> + + + handleInputChange(m.id, "endDate", e.target.value) + } + /> + + + + +
+
+
+ ); +}; + +export default MembershipDetails; diff --git a/memberflow-frontend/src/components/forms/TrainingGroupFrom.jsx b/memberflow-frontend/src/components/forms/TrainingGroupFrom.jsx index f230380..5593341 100644 --- a/memberflow-frontend/src/components/forms/TrainingGroupFrom.jsx +++ b/memberflow-frontend/src/components/forms/TrainingGroupFrom.jsx @@ -8,6 +8,7 @@ const TrainingGroupForm = () => { level: "", schedule: "", teacherId: "", + recurrenceMonths: 1, // nuevo campo }); const [teachers, setTeachers] = useState([]); @@ -36,9 +37,10 @@ const TrainingGroupForm = () => { level: formData.level, schedule: formData.schedule, teacherId: parseInt(formData.teacherId), + recurrenceMonths: parseInt(formData.recurrenceMonths), // incluir }); setSuccessMsg("✅ Grupo de entrenamiento creado correctamente."); - setFormData({ name: "", level: "", schedule: "", teacherId: "" }); + setFormData({ name: "", level: "", schedule: "", teacherId: "", recurrenceMonths: 1 }); } catch (err) { console.error("Error al crear grupo", err); const backendMsg = @@ -80,6 +82,17 @@ const TrainingGroupForm = () => { required /> + + +