From 69bc5675dc9187d0400e025bee8bcc0c8d7de0b2 Mon Sep 17 00:00:00 2001 From: abhishekbhakat Date: Sat, 20 Dec 2025 12:26:28 +0530 Subject: [PATCH] feat: add profile avatar selection and enhance sidebar UI with icons --- backend/src/handlers/users.rs | 10 ++ backend/src/models/user/user.rs | 3 + .../public/icons/general/icons8-cancel-50.png | Bin 0 -> 849 bytes .../icons/general/icons8-document-50.png | Bin 0 -> 450 bytes .../public/icons/general/icons8-idea-50.png | Bin 0 -> 1646 bytes .../icons/general/icons8-settings-50.png | Bin 0 -> 1456 bytes .../public/icons/general/icons8-sun-50.png | Bin 0 -> 539 bytes .../public/icons/general/icons8-user-50.png | Bin 0 -> 1473 bytes .../general/icons8-waxing-crescent-50.png | Bin 0 -> 1411 bytes .../icons/healthcare/icons8-powerchart-50.png | Bin 0 -> 800 bytes .../icons8-add-user-group-woman-man-50.png | Bin 0 -> 2004 bytes .../icons/user/icons8-male-user-50-2.png | Bin 0 -> 1132 bytes .../icons/user/icons8-male-user-50-3.png | Bin 0 -> 1185 bytes .../icons/user/icons8-male-user-50-4.png | Bin 0 -> 1154 bytes .../icons/user/icons8-male-user-50-5.png | Bin 0 -> 1238 bytes .../icons/user/icons8-male-user-50-6.png | Bin 0 -> 1204 bytes .../icons/user/icons8-male-user-50-7.png | Bin 0 -> 1124 bytes .../public/icons/user/icons8-male-user-50.png | Bin 0 -> 1231 bytes .../public/icons/user/icons8-user-50-2.png | Bin 0 -> 1468 bytes .../public/icons/user/icons8-user-50-3.png | Bin 0 -> 1341 bytes .../public/icons/user/icons8-user-50-4.png | Bin 0 -> 1326 bytes .../public/icons/user/icons8-user-50-5.png | Bin 0 -> 1295 bytes .../public/icons/user/icons8-user-50-7.png | Bin 0 -> 1473 bytes .../public/icons/user/icons8-user-50-8.png | Bin 0 -> 1407 bytes frontend/public/icons/user/icons8-user-50.png | Bin 0 -> 1452 bytes frontend/src/components/Layout.tsx | 44 ++++++--- frontend/src/index.css | 89 ++++++++++++++++++ frontend/src/pages/Profile.tsx | 35 ++++++- 28 files changed, 166 insertions(+), 15 deletions(-) create mode 100644 frontend/public/icons/general/icons8-cancel-50.png create mode 100644 frontend/public/icons/general/icons8-document-50.png create mode 100644 frontend/public/icons/general/icons8-idea-50.png create mode 100644 frontend/public/icons/general/icons8-settings-50.png create mode 100644 frontend/public/icons/general/icons8-sun-50.png create mode 100644 frontend/public/icons/general/icons8-user-50.png create mode 100644 frontend/public/icons/general/icons8-waxing-crescent-50.png create mode 100644 frontend/public/icons/healthcare/icons8-powerchart-50.png create mode 100644 frontend/public/icons/user/icons8-add-user-group-woman-man-50.png create mode 100644 frontend/public/icons/user/icons8-male-user-50-2.png create mode 100644 frontend/public/icons/user/icons8-male-user-50-3.png create mode 100644 frontend/public/icons/user/icons8-male-user-50-4.png create mode 100644 frontend/public/icons/user/icons8-male-user-50-5.png create mode 100644 frontend/public/icons/user/icons8-male-user-50-6.png create mode 100644 frontend/public/icons/user/icons8-male-user-50-7.png create mode 100644 frontend/public/icons/user/icons8-male-user-50.png create mode 100644 frontend/public/icons/user/icons8-user-50-2.png create mode 100644 frontend/public/icons/user/icons8-user-50-3.png create mode 100644 frontend/public/icons/user/icons8-user-50-4.png create mode 100644 frontend/public/icons/user/icons8-user-50-5.png create mode 100644 frontend/public/icons/user/icons8-user-50-7.png create mode 100644 frontend/public/icons/user/icons8-user-50-8.png create mode 100644 frontend/public/icons/user/icons8-user-50.png diff --git a/backend/src/handlers/users.rs b/backend/src/handlers/users.rs index 020f395..3c68875 100644 --- a/backend/src/handlers/users.rs +++ b/backend/src/handlers/users.rs @@ -35,6 +35,7 @@ pub struct UpdateUserRequest { pub smoking: Option, pub alcohol: Option, pub diet_id: Option, + pub avatar_url: Option, } /// Response for a user. @@ -50,6 +51,7 @@ pub struct UserResponse { pub smoking: Option, pub alcohol: Option, pub diet: Option, + pub avatar_url: Option, pub created_at: String, } @@ -95,6 +97,7 @@ pub async fn list_users( smoking: u.smoking, alcohol: u.alcohol, diet: u.diet_id.and_then(|id| diet_map.get(&id).cloned()), + avatar_url: u.avatar_url, created_at: u.created_at.to_string(), }) .collect(); @@ -141,6 +144,7 @@ pub async fn get_user( smoking: u.smoking, alcohol: u.alcohol, diet: diet_name, + avatar_url: u.avatar_url, created_at: u.created_at.to_string(), })) } @@ -188,6 +192,7 @@ pub async fn create_user( smoking: Set(req.smoking), alcohol: Set(req.alcohol), diet_id: Set(req.diet_id), + avatar_url: Set(None), // Default to None on create for now, unless we want to support it in CreateUserRequest created_at: Set(now), updated_at: Set(now), ..Default::default() @@ -223,6 +228,7 @@ pub async fn create_user( smoking: inserted.smoking, alcohol: inserted.alcohol, diet: diet_name, + avatar_url: inserted.avatar_url, created_at: inserted.created_at.to_string(), })) } @@ -270,6 +276,9 @@ pub async fn update_user( if req.diet_id.is_some() { active.diet_id = Set(req.diet_id); } + if req.avatar_url.is_some() { + active.avatar_url = Set(req.avatar_url); + } active.updated_at = Set(now); let updated = active @@ -307,6 +316,7 @@ pub async fn update_user( smoking: updated.smoking, alcohol: updated.alcohol, diet: diet_name, + avatar_url: updated.avatar_url, created_at: updated.created_at.to_string(), })) } diff --git a/backend/src/models/user/user.rs b/backend/src/models/user/user.rs index 3d7790f..73df11c 100644 --- a/backend/src/models/user/user.rs +++ b/backend/src/models/user/user.rs @@ -41,6 +41,9 @@ pub struct Model { /// Foreign key to diet types pub diet_id: Option, + /// URL to profile avatar icon + pub avatar_url: Option, + pub created_at: DateTime, pub updated_at: DateTime, } diff --git a/frontend/public/icons/general/icons8-cancel-50.png b/frontend/public/icons/general/icons8-cancel-50.png new file mode 100644 index 0000000000000000000000000000000000000000..30e49ee1bd9a78f394ae51458117d00156da1af8 GIT binary patch literal 849 zcmV-X1FrmuP)F{yV0r%uKjq37OkOzx=`Pseo(YA&b^_;Qbtb3No$IPFq#MiSmt1TU1pRY~xcgMU_p&-pR8dgjtEf>X{x(vNd^+^xbj zDX=L8?kYl0CwQ$SeBBW^$Ime_fL66|!vEy)r|z2%4`@k(TIN8q3bRt+*W>{EcL~0@ z0xzcy;GHiVkpxd{0}KHX*1b~ca4Hb(a(Rk#I&BCwfO*5_VHJWMMiG9>3PJ@T@MHUI z>7>ncTF)GUf^&mSD`}R+nb3fFoD8B0vy+BUe_hp z<89C1G=k{}oYPM$fz3D&fudmg5P?i#1g>cpKa(z&Q)HC7%S*#+mzPGbHAqP*a96A1 zv(1?v!cdrhc4lZNf;IK=si^h^&oimHRTPX(2<5w1Z7fJ{vWxNLQ7|?klz&d1>43b9 z{Q{aWi6DqUU}b!234EXEMaIA+hM-<*y~_w>F&w0k5r|5hTHz4ZV1!0$@s&-Q5LRFW zK26bn!!1^)&RDl!mx?nsAqH#g!E^*%{4ZLRw(cBna$7R8X^gPgA#mfS5negE>Ik?R zyN%bV6MdLCZ9EmPXoK+Z!b8k~8>|FueV?8_rVZk!7t~A-Vd^1p-Z2%EOM=f6fAi#r zB-q%jRE|1v6lXR`D_or!BubK?F=+@%@X$#rzOFQx;jM?jHLp@R13Er>(;+k*pp_2_0%B*JhGNfF_YnB8XiQOq?omnvL07A~f78kqC zxOKvYxSio^Og=xRUr%!b$i0(s+mW`|VR%-M0`KsZ4UeRQe;9xj{vAKo5qQD68|BKC b%Zbt-_N6~bXx?O#00000NkvXXu0mjfpq+;e literal 0 HcmV?d00001 diff --git a/frontend/public/icons/general/icons8-document-50.png b/frontend/public/icons/general/icons8-document-50.png new file mode 100644 index 0000000000000000000000000000000000000000..12db81dbd35e04faf7d3f2e03d54ba68e43736c9 GIT binary patch literal 450 zcmV;z0X_bSP);9I!(4!(r%;4DZeI=CpEs;CGS>=7ak zii=y27DXs7Y8|u*4n+h-PzeYHtyQtLxsrM$lum+>dvkBD@%-?UCCf+h=Poe}3MH9< z!z^&vt&A32e?5mdpa$YH8(fBQ*E;WA3y!~~1Ot*F)p~#%wNG^zkOZkUx_I^4RfhqI z5U>5E4g-=Q$}pe+(#LGd#HfOVy_Shl3GrlNR6{&jm?R+H4-8w>7E-kB6s$vrPtWaw45Wk!*?9ru19XTEv+DsmU9FM!U)0@ sg17`hg8UDNBkvcE2(^SE6pF!>ZyHQOnH2ZVMgRZ+07*qoM6N<$f@pWZod5s; literal 0 HcmV?d00001 diff --git a/frontend/public/icons/general/icons8-idea-50.png b/frontend/public/icons/general/icons8-idea-50.png new file mode 100644 index 0000000000000000000000000000000000000000..ad29b4ce4e26de1b469280655c4e8a2cf353648c GIT binary patch literal 1646 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 KMNUMnLSTXdp|ryQ literal 0 HcmV?d00001 diff --git a/frontend/public/icons/general/icons8-sun-50.png b/frontend/public/icons/general/icons8-sun-50.png new file mode 100644 index 0000000000000000000000000000000000000000..41657b5334e14bf4e300e19ad3f73e3f6127233f GIT binary patch literal 539 zcmV+$0_6RPP) zV3LkHp}qr)PCkG!ntbL^D_Cg*_1w0X+%Nf(Cfv69h2Hb;5?NVUSy^oeimupXve2bV zbm$EodWWJG84aNbE1L*|FocOPh=Rxy47${WqIQhOQ1lTAv4;7CqDkzty42JM;=cqb zxt$M?8wZ$`0I%YkuSbp{AcG=sUj>#8;Pqm=mvw&)ugxWhR{>tmqXEL^wR}%*Kzaq> z@nm;^upesvGcpHR)RIF4emcz<#H;)tBJjMND#-ZfMg8J_dt#S8Gx!w%Ci*h=X0qeR zBLxxot{P67E&XK&hf!&eWkX*%vlW7qois$?ks}WiSpd$C^?^)FvV~@B6)PF7!uBGP zWKx)1g1B@o`>${TnD(dTCWMHE;SH$^Wa!94q#u6k`XDk*h^{b1WQp=DS)!Z){i8LA ztEoiMUNqj851@?aekSvNq*w5pqofdvyfjwo+w(nJUEW`RKPO}l5(I$N@F6BN^KTrT zc&!oRppoNe>0lf*HEA5AMBO%HWa?%(G8G$Q>&n=v9xIpv5qr>M8pPJ4H&Y=F>M+#G d%F2qQ^#vu8$xTSlz*hhO002ovPDHLkV1f^W=?MS; literal 0 HcmV?d00001 diff --git a/frontend/public/icons/general/icons8-user-50.png b/frontend/public/icons/general/icons8-user-50.png new file mode 100644 index 0000000000000000000000000000000000000000..b9f33e1cff39c9e6b439c77688a766b2b20afcaa GIT binary patch literal 1473 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 Rrwjl9002ovPDHLkV1g1koGkzV literal 0 HcmV?d00001 diff --git a/frontend/public/icons/healthcare/icons8-powerchart-50.png b/frontend/public/icons/healthcare/icons8-powerchart-50.png new file mode 100644 index 0000000000000000000000000000000000000000..3d3fcaee2e37660c05467a5899c5c12361b75583 GIT binary patch literal 800 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 m!h@m8r26@E_js%R@9W=LQ4#}IK7yJ60000z literal 0 HcmV?d00001 diff --git a/frontend/public/icons/user/icons8-male-user-50-2.png b/frontend/public/icons/user/icons8-male-user-50-2.png new file mode 100644 index 0000000000000000000000000000000000000000..030cee95df10a4338d9bcf62f860c45a0daee351 GIT binary patch literal 1132 zcmV-y1e5!TP)?Lhzwow}2XPCcX^+0UJGc zMv}&e50hk;1tbm4>!ZMl}K{0lRm-H)hmGdOJrr>7v%OOV6} zBylREr^R<|5Ez2O17{ip; zQ96XTy=mcTAl@IA4w1wm!vfwo1pKjI&DhH&BE0v3(|>gj|JyF$mp1^`0EAx!uCx?> zye5u3q#Y9V)fy6>32EH`j5p_BBT6@Fhj8B>&EX?*_}#$h_8j4}^!Xj~7h#Sy+uqg= zk?2u<-+2{1x*eEm&9XjiFX2SwU*b#%pWbKPz~sSn$gvV2;-G2a(|cqaF!6r!z61JP zy%7__v$Ve0lzejy=>w4$H6uJT0urUHY#`A#rVSCOuE1F1Y}r7@8fVeDVP)|UzukjA zCvbJQ^^mK3fW9iA$I+w#;uwJ60ram2CimxroD*yC>FaCJ)m(+Y`?shLdHcsYoY?79 z=8pPmazi2qfc~eTWbr%ti-+{uL-EPL@K)gbTNxY8oOlr*Y+0S?z~1$$A%T{4DRXaj zy_7jl-gDTsgpfO^+pc)eC+^Ecv=YGAzuB?S@W0xSkjz1Bo zexzuKg6VNM;kRGHV0MVyu@J#*_sh6DP+#O6BlcZYfv#4@=0^y>8iG(DVb^mA2@ClG z#QaZVzT+Ouci3`vtoO-6hy^h6ykQUp!-S6uJrWB))L{PeicG}ORmy8BZmN$AMJN!j z_g;j^V8JlKdgYyu9b2>5@+kyWeEWxlFamCK{;w!siD1Id`hU2|2tsuan}SGS0`3)H zlbHFw(4qQjfTfu<(whr;x8O?AicE y-UB0kFmgc&tN_Wy_|N3mp2@q&axIswZ0dh6B(& literal 0 HcmV?d00001 diff --git a/frontend/public/icons/user/icons8-male-user-50-3.png b/frontend/public/icons/user/icons8-male-user-50-3.png new file mode 100644 index 0000000000000000000000000000000000000000..ed869c1d1eed1b2e82def5a014fd14706e189d0f GIT binary patch literal 1185 zcmV;S1YY}zP)Ys?z!g- z%@W)_gDBY|n;0fUluXVob4>&TuA`lqwyBv|M_|1dAs8nlkZ5>@7MDuZHCZ%%tz(N+l(#bZB&#QIm8(~%^A5W zGddwNax+K1g(@xNcD#x+GQuS?DKiR2l1uci{Ia+lRYLS`6CUS`jB$xf8wF%y$YsV@ zby*QyqD*G=wi!SMhS3ZACDQHMLKZuZVDwHOkR)hX`R>*s$Ll_;mtHC236h7)EMj+QqLbyAd9+DZk zXLa-AE&{&>L`W(a;$aM9`$)m<)!W*-$TVbs`{w8EXdcwe)Sg}F7Yo&CG7XU>y2o_$ zofN*73H;*E-F&XRHXuUZ)_gTvUN;Tlj1F1($s5U=pI~_Zm0b17p;90xoM=8f{~E#I zc`ftYaEW|o8X_}#)~V*R^UiS${x|N&kTaHCy@xx9?af10UOxQ)1)%j}2}CREMDt(= z#MMsDR|>?{PR^S`fE(2)J*y*?0#SCYjzADCC>oORqMcE16$HE1l^x>Wu^#Rnt%8IX zbr%oup)&~|f=N#ecshl=knawx0S|i;Lfy466?(yNlary1@Of9QKKD}Jn!Jz?J22cH zr~$2)gcp5jW<}2FlYI#O9Il7!gR>#Oef%tNvN)aU?iGe1>h7mA=Kk(~Zq}G<9uXqL z^(jOO@{O4l>7OZ(46TIe99Qm*!Sxx<9P3(U7;{fMmH6GnC~3l1h)c>dX0QzlA#samiiuisLm8319Y-+ z)ae@wX7Xg?7bOGI5LMV$Hi#laFp3|x43fg&@iMH) zSC%4l$SLt9$01>1v*i#SqYB^7`C_FRqJcVy`fCehoj$g}wz^~sA_WoGfr68BH4yuB z6->DwfGKx%-i!qce3enOcQij^8zhCnM+$9;_((nceQ@C{fc7jtlKTr{R(@bBLWj8B zRoWpe)J!tGQUB!c4lU6$7F?-6D~M2pbD%o(e?>Ukx(HN!(S`$lQLF6;B8^d5wUKRR zJcS?x8;bu0Xc;Kn+y<&JQ3B#eQ1KR22?4=|1)$(JLBT&62BgOJlyw#63OFUK1r@&w zst^W6xS}_#r}non1}g3aRcx5E$b8HPs+jl}Ww70|hvmWO00000NkvXXu0mjfBpnxU literal 0 HcmV?d00001 diff --git a/frontend/public/icons/user/icons8-male-user-50-4.png b/frontend/public/icons/user/icons8-male-user-50-4.png new file mode 100644 index 0000000000000000000000000000000000000000..9d2f325d1ca1417f61cbab31c433a111e6cf66fe GIT binary patch literal 1154 zcmV-|1bzF7P)Ts;rdewe4H8tH00IdLU6cNuM;w40! z2Y{dQgNQFWYOOeq+XeuG0B{o#Nn`%yIL_m!h4TCTTLB;j0O<+w0=0{~wl;{KMFmMwN5`t$+{B!h_Kfk5D4OAr9iZvtZV4lVk8z8+H%h}df;0(0}O zDF}|^b|B)Cg%AROsG$f^6zdT22P+Y1#ud%;{L3~V=+>^BF$56`g*GALbsHgRp66Xg z>_(Se2)vDXLpKBwXUuAFPX|xW?DlIJdqo$5zG6NFuqg*SHfFIymd4yf8|nC-hv?LE z_4L=-pynoTeiovUZjU4jphvz0?8oYJky^z$%BbMLK%{5k^k zYH&+7@s}Ra42kz{%bEMzDO@vVwm(eQ2Duf4l0-E-ayYxdw3pHauH5fG^yV}(-0jf} z8IHPh<|=DZ-Wc^Wr@gl!6VBHwhn)7@Pci4h3ZzgosToEmpLVK^9A*#DwU2$8A@c*A zI!BrN(LSfT78M%10-13APVt8ODu$?-ahHc;&P&B0%TJBb!YEJwOjdpw{QY^Du8;cF zHHwa#_9{E^4aME=st`G#L}=9N8;e#Vg-+`RWFbl675gAUuW=AL60{AH6avOU&Wrbw z#Fngwutk~;++!F-#Yk+%`eVhW4MnJsq`<6)MA{68s2GWTRq}%q5lW9WQ2LYlGHFo9 zmN`}zOhKrSWaM#@giNUh(y_-V)qe-2`W;1+o_Ms(P6!#2*%PKgRE*5tDR(3?pEgqJ z{kpY?6PwicG<-MSG8LghjvTpD`4X0GCJ|Pje0u1?SEQ--%_Olo z6K<(FWo=6kSxj8qpyilp4;!G%(aQe<%Sg?yGSyNk<1R#Y-D@MMb>M*95qw_1Fw>X UTy2qzz5oCK07*qoM6N<$f;-wFf&c&j literal 0 HcmV?d00001 diff --git a/frontend/public/icons/user/icons8-male-user-50-5.png b/frontend/public/icons/user/icons8-male-user-50-5.png new file mode 100644 index 0000000000000000000000000000000000000000..882c07e23979c0add9d020d5b30000e3201b01a9 GIT binary patch literal 1238 zcmV;{1S$K8P)bEW<2nQJJqgPthHe;1YqyA|>cO%HzwF z$JYdcew=SFkNixg$;Z3xl*dN}f+i`!5U2kZh&zwT1bH_<`Jg~>kHDkp1ORSY;PH^h zV3k3b6clcvFi{R33C&(fPzqC4_>-ooGZm)*Tk1k6Zq^1-X8xdZSLajb~ zXID{-I>?i63q zD=X`!Yc}M@4f0}1Zphq=wYIP^7yN7B)0b9i88lPNhY5oOsde9t0^c=d!`K2>?#W&G zAz>7^L63%o6ljm06I51OD8?0a=@^17E1HZ?WdfA}29M3j)k7vc#Q< z6=uBMsdfIZqcxf*j(D_ZF(D-OJe)M?e?|35R7CEg-iKQjxxU{6h07T;rFKo0xC6RD zNL=@Dw=?lCK)s}hj%O5+{XTgJ_6M~FlL;E`b}o@c?gcGWyZ|b^XcyAD3ehy)&N^k0 zZBRtEN0GRp+0|0J&VH#ryZ&22)FO*o6q7Of4`f}hNn}l+#Q*>R07*qoM6N<$f{P|j A82|tP literal 0 HcmV?d00001 diff --git a/frontend/public/icons/user/icons8-male-user-50-6.png b/frontend/public/icons/user/icons8-male-user-50-6.png new file mode 100644 index 0000000000000000000000000000000000000000..9f40bf893086a26f2e46d6b82413312c21230574 GIT binary patch literal 1204 zcmV;l1WWsgP)=$q&ch$M@oMEPGl6q( zG8(to69i?NUnQN6V=lQYuFMdH^A2*wZ( zV{BeZ5nQB9Vsu;&APB=~PmM^*YqyXk)*~2wCs{y*oZ^fguVY0yRv`|VfS9#I3&=8RrX6@-h#&z~#FOMW**`a3g;G@c?v_LK=h1mPj z`UMgrlSVi1d~YpW>wE~NWDIvaHfXJXJnr$T-n@CCZb(hprYFp39=yS+JnMP?(Rg*% z>xM`otZ7T(sTIX zSywQ18Uj&@TG2e10jVvc-RT0UEu-DK5a7t4f2?lZaJoQ_)vX(b3k4YoLwslO_8Yx6 zXxjB;${`=`+yEmzHt@M{dEyW^>hQTS44qm52g^4`g`7Q<1C7rwg_f#p_{*KAxycC^ zf+JPg>fCc5g??*a4xB8RNe5r1 z8RDo}7BqM0L~huai%0D6YuD-k!i{0fg-#_7apC&u0+Zih@XNNag?>013~An(r5Vz^ zBP(dGQVT-HC~GQf&p_O0Pr{IiUcAWX#>3N)NX^_ikD+N>prQI_GU4a8@MfarVC!;q zjxzU?iU-wN5MkUb$nWD{<=-#piP5up*yq9n(IA1hhGDoX7yj-;34hEt`w(33%2jJb z8#5Vzct_m`3CV`vgO6H$W5M)`@}SQJqXJ~~Myep-#k-A!kd#3NaFKD4@AK~i8Qr!V zA){OH?dp3CgQyrUa#|0;U4|l5h>V}M{#e;I84gh~UVJ9j!v1~)BaX%JhvR{mIr7C~ zb!==1I%f((g$(3A0y3V8)qt;aDO`Ft11{~4o}(R^@s89K$oMhSAS%X-8sZ&^Kb=|d zUE_is=HK&q>YKmTvPjLb6PfBW4T#g=5UlyXB7BV& zf{c2Nzok&GQri;548|eM({jubxM~mU`UPkh$csurMuYkh=qHfz79kx1E)-;d7w-Ts zx{?4u8C#jsU5FJRBRlll-UJ!7fsFbC4WldS-!f_iFRF%qToAL!T+D@#Ht`;G0=*-QHxsJZECmdObg`_EVT)g&Jr-Ga_MEJYB9V4 zfhd^vZ)UdL?5(@AJGXu4m;7Hg=kopLoSkH|F4tVmRpuAmPc8tLT>wUFz=#iwNZ`mY z7#WQTN8fX0T7l7(VDuX>avL0lt}yx!wk%!Y%7nt^r=9>uykK-vHy|?S;dae)7QqoW zIC?8hK={d=0wX)Hb;)8U5C;qcVlxFsTi{+oY(mgaEkJ~Y+y^5i)*=`!wH86ct{kbi z2Ce$&JJ8nv$O16p18O%Vzg~sQ z7a2H>>=!L*UJ)aseoyoNjbB?FLUyA3tpunp)v7{B>=@$CoRczQO-+Xf)yps7z@ zPtJS>Y+D)cdesSdG!{pvc7pG zD&F$&tJQ4|L|xR5<`pX-TXK3b2Ex&v^bkY*d{pO8WDKM_e*ytdR_c(8d=V~G0{e2E zhm^el3{(ICen;vMiSI<93h4g`C|*4)r1z^5eDdaV_-LcFmv5Q+Z_=lI7` zhD@Kz3P@EFuEvL`nH=+DqW>`N4S7@kGT$9)#f|>M+8VQtyQ)I?K@3(ePYV$N8u9&L z`x{G{&S=N?h5;dnEbMg*A`7MFLB_f^ItCdR^38+XY+ndPeBc1&KK?%WsA&)lBa7Yk zUn@~C6`?^C;Z^$~U9Xr931Y;b6K*^v00Ygy`6N-tsACgD`Yb_ckkPJnkcFv)4Fp<& zjzhpt2{PD{C#_$Arhyc3 z6J&8XeS~lga@T9FOeh3ASy04xAq&^_pMY>3vRLBiDI_Y4``1Dd-iIQzK@kUn4Qs#w qD54jNSdQ`TH3=7)tGRMzO#Kf|2ba#FEWo`00000HeSq literal 0 HcmV?d00001 diff --git a/frontend/public/icons/user/icons8-male-user-50.png b/frontend/public/icons/user/icons8-male-user-50.png new file mode 100644 index 0000000000000000000000000000000000000000..177d6e98429066d153397873418ad46389f6db03 GIT binary patch literal 1231 zcmV;=1Tg!FP)RUF4}G@BY}7kY1DvH^kpfk5vu+dZWS3&cd+ zg4_eN79C^5ZLBJAFX%FO5!o_GjQZdnbir*FB+8vpG05v zNk=k%=3G`%+EV)G-rGL#O}SSCe!p1Mh=4c(?sC^As9hi7SO*9f}@nl1d(mq@93z4hL$= z;%ToRQ-Y|iEqsz-^q=10kC9CG5s2yyZ?Mubg)5#x71>_?=cRn6}*1iE+ zDjm_#)q!BwNlY+SDW!6fy#j}|L(p^(LJK|&3Bn;wr zuk($%*TI46t!W3@UtIz;i~r@Uj)XzRJl0Eoj}=CmvZ1Z2Y*~=L`VHW66hf0LAFlZ9 zafiI@vqPgRUz^)spSLVXYgIXnG-m_N;`dm-NF2m%y|ysf3g_B#;NXSEt!Cqrx&D2*5o11iwE)K3avniwzM2fkyTJm1j%-lm$lX5i%K9Z?h$|9y zIn%MBb7?I#Yz$qKuDuB2w!V`v$as^5^?R(dL6B%+Zgz9oiRGIrW*21@X zb75wv4t^ir8PhYz>$I`4+lo~UfzUv@Z54{l&BqGx>(Lzmqk{mWN2B}9AWR>tUFjs| zm7eV9353DzROv#7@TzA+ghn%yy>r6k=(ri^Yn}_9+s3L6NvS8XOHR tad#Anolv{kBe!Huh*@M+t70-n{{uCiAX4uH_Cx>x002ovPDHLkV1l0QM8p69 literal 0 HcmV?d00001 diff --git a/frontend/public/icons/user/icons8-user-50-2.png b/frontend/public/icons/user/icons8-user-50-2.png new file mode 100644 index 0000000000000000000000000000000000000000..20739bb79b8a514ca1f99dc2ff025826a2933d9b GIT binary patch literal 1468 zcmV;t1w;CYP)8 zlms+W^|aX%N{30JA%y`w&VW2%K+&EgpdAtzf>cj~0l@PNXa)n?%oBWXk@MLAFL)F} znicIQiL~B10IST@Nh263HJ-Bny`V4DUY(ktWOa z-ER>+>fHrvo zf_01h$C9Yv5(opb#kwq8HPIfz7qS^{#<(-7>jGDR}qDG*5{d-^M=oH+(u zpEk|WahDy=ij+8gY=3OEtC9(RyCw{8)%as`xqu(fCJv3ynn~jv0%1V6xD#OIEQ;T( z4#$700uaxryY=IaiH`az;f6?04;soua@}1JyFPjcuayc`0G9fSO?AK@xsx3m`w|z3 zoIZB}TsbsB5x}h5CjxL?N))$W2@I68tVoe70Na&s=M?Sg!<)W>Sf)sk^f7G)zJ2m`v@PUVyD-RiN}Xd2NAprK$m zwjEYJ!dyS9#*7&IA6N1<71wQjmKZ%(66swfNAsh?JCmnqv7yMuG5)j~+mHC*-}_&~ zt3@NR^^iAq)+wKiZ&YY-iBXHGk)d{8x*UAAlb^=q3$Z>kLc(twbpj@a2zX+f>)#}o zztdovK|tAON~B^&Zm=X8sdDyl^U>R&wbOJmrA3}pR(!C4rlkScR^>Rr{aQ61%niVq z;g5V7Wsr#8AQF&sDSdL?Ozs=`a!huI6)Um~4JreJC%We5<2!x0(AUBSv3uo;XgYy>HZMPa1Vv zlTr6(N__Byx2Ui0FeM*)y?)4yV8PF*6OxTV+JZQpwmL3Id&lf=!L+cm@*8Dl5{Xy! zr)4FOQRz`(+vULH-WFoP-+zRwJ|QGzcwDeRjX^?TYDC!PRY1nOC)z<9v_Vrnw*LW0 W?uXAZvZkv50000TFnUB$tgO- z2p(V*4^9=QxW;t7MPpdHgApI&6n)7lj&X`XUFeUeDm?d@u7`+*!?$pPHZy|9wM{-% zjN%VWCesb`3c*8O7bEEVbO2IB&_|4-y`175EFe9~{nEX22El?-9jEwj!w~Y78e~CS z9hIb;XAL4kaD#Rq7_QcLk)W?&wkk0<5cG0&2>z>y;LyxL5Z~h2Tu#a`=${C|0mBfj zq0&1ULFeZKf?uu7cw+$HZ>$;=bfVho*xV{8_OA{cWUpoq+ z;}MS*pIlG}p?ITKfK4kUIMlcV&UX|V0!UV0gQlv)8YsO@1q2;XOSB<`;LRu8@N@gj z0q6t)@tjixVHBTLOCknK9z43r22Pt9{3TWx*yL25?1@$vxw{$?j+Wo2Da4a!ypStDhq^yzQTO9KQo%7Tc0WLlCWgS^l4QYKYZYE=cPDoX`9 z!u5l2ig(B_s{pRl3nK1R>+s~n3hd^TNy$mT=iAKjKJ~url)GJ@RuF=BD;d2>FGxb) zY;nRb&uKTcXnSVswSMZ;41)H{SA^j0>4MDlU5gWZSRQ0@k7+@GFp7@JFD-%(FBlMl zzf!75|AGOb_**593@jj!vkDc#UoR98PSFoa9yw9Il1;pHL^hAWvH_b0>3o zWk483C)Tg<+-))v)A=SDB%x4|6<)7#z)&<_9Uz(y`)VEWK2!6oodTlS4_ZU`MtpdY z14-z?JS#Aq6MJ>Fed66G^Tzrkj&UJzEY3BdoLISI`o7*I5Ju5O-G0#Pn`97=&3w^o zGavKX%w1BBrKT*`lIL(ZWUrw3O|qMvqOI3v=@xw_b0mQf1AfpNVy#w}J<#LHvGjPe z&4Gss3T`)=Q{)i2JUNygk=w8zGLeZ)n5M@6Ppx`DXTMuX00000NkvXXu0mjf7ZPp1 literal 0 HcmV?d00001 diff --git a/frontend/public/icons/user/icons8-user-50-4.png b/frontend/public/icons/user/icons8-user-50-4.png new file mode 100644 index 0000000000000000000000000000000000000000..baf677a131bd2804c09b43bb4326be6773d6eb70 GIT binary patch literal 1326 zcmV+}1=0G6P)Kv2Cv1DTt=N6hR8HG)zF^ihGXiPR26Sg=V zcHm;bLcit;1zLL7_j-k5(kJ;Q&E37s#Gm_Y6DN3!IRSv z=+_X))wxQk;TBt$XD|=sh87%>QtrUeozj<>kH=v;Dt1xIS)8j4t$Uw zhKJsy5QLtKD1dnN-(3%USq3=FGiu0I=tYjQLs(NE2T%Tu2tb7%Xv_gVFYyQPNd&9S zP~tfREB62!$mD8P9e|Aj^=p9>TY>}3)@Q{)rJmi}s?TFAD>9%8VpkT>SsWT*wpvU| z%Bz8)tmrZb#2psEj!fX_W@P|A^_YP-*RY+3r)L<-D#fB0;FVRtp^cN1ai~ytDezJ{ zOGXA+%BnT2Td5j=+1kyN6%Wc2<3fPYZKlC)$gf8V{3i9uw)Bu7hqtBsjk$TGaAyBo zj35FzAPpjrI;9{UM>&q|G}|(9t#&FVrpRR5qegxw0ffs@;38oxL>BU$hD}0yu%2> zlkenu&w+qYl!@2*T5!_#1=3T73HwS+bfn75zS4Va zP>;Q=AmqASY5mM%GFG?xw$v5%bghHCWhvb6alzHH6rK~(86A7gz*gQoaY%z$(jNg& zyF!@^S+ti%+6yEn<2h}@cw77&2yvU|)CS3Me}7sC*YioCSKmDO7*@kWk{~lHU|KKt zuJ^9_slF@EF2{Yl%+p{`89XO*F=0>h%9{nLa&nk)-(H9-Ma$tb>tr6Y#m^b~T3LX( z{h}`bPwq&8IE@-y-uNh7ALgrWaMz({yk1VD2CnC{!CwmU^cM3=hafPzsc(ZpK}7ZE zCE!M#0pn*%6$7}xD8=C@On8#5R3M5kWv~zRZ?PD5CPu`+oeE!8rb|82KQyd z-CYtIpt}TvO>4bl0)74p1Yzk1h1sd~eR2y1GMypQGJIc=HHly_`l( ktLUw|A7T-USa5;y9~@RN&w}@>&;S4c07*qoM6N<$f;~B9*#H0l literal 0 HcmV?d00001 diff --git a/frontend/public/icons/user/icons8-user-50-5.png b/frontend/public/icons/user/icons8-user-50-5.png new file mode 100644 index 0000000000000000000000000000000000000000..f5f0a80d5a8bd9ce2a932b126344999411bccf9c GIT binary patch literal 1295 zcmV+q1@QWbP)&bCAz&^c_JYxWO+(1TIUpwQ0fZ&92hm9nXwQLJAku_(VcqO> zVy+FA6D+&BW%9stg72dWbcc%+2u z?MC*D0(1y~;|-vEJ7C}TzZ%}w>-D8}h_>|mjo(8}*$!ii{eH(}0JnH&S`TUW6X^g@ zc&|1PMqZu~fNSpnKfW?OfTw=gIo2_z6^1;caa)lBQxLzt3sme@2k_L-d-Z@ER)>J# z2a)z00%$o1{Pe0m08ce)%!^1$G~S}?1ZX=vb_KG>7>D30=XrTw3rLrie7tAqQfdak zQ+0`2KwRh+9#HE@p{f!8B6B1HDZS|i}ZsICcketL-lg4!CMi>Ek zQy!#USf|Ov1Ek}`=1GhCV*d(NknH^{CXEqKY%u^r)0FbDLobNS{vy6kS}iSz!~{%U zl#Doha!i0UCNF7?&=GoZ(SV5b7p1LLvuHpVX;$h;!{Py<*Ofq8Oo5a| zV>CAuqdCi!l^ZG@Yx1gfLkXlzi^*`!>#}Fmb>=CI9QDJv;_S)e?KD&G6B>{ zUsHP4`{%`-qt~)SFkJGS{9Z4MhO00Pqq!lHq%O#9C;K)Ge;0|X*`boR0>oYZMnDz7 z3uc4dGvA(y-TydjRx})6j-hX#H68GwZ?;HY4x1G{m9e*Ey3nopp~DoIwvQeLBNg7J zeN}t<_@rEQwjgxnZ-i6fY|F`cE*dxU!cdnLBzZY(R_@(9O|YxMQvD4&E5-et3E3j*H5i= z{c-x~p~2$K1Gmmb407?m`Dd-C*1GCFI^eB=>V)xMsN|0BJm}5MK+V27_r$ffz&o{> z)+$G4;AdAd1LH4$9=xWhaJB3iaAx36Pq7b*A#58HT0$_f*Da zI&9YTT3b+5<5!O?HS5VexR=9bP3PXG^WZCA`O4y5{{dmOxzg)pE)f6#002ovPDHLk FV1m2PUXuU- literal 0 HcmV?d00001 diff --git a/frontend/public/icons/user/icons8-user-50-7.png b/frontend/public/icons/user/icons8-user-50-7.png new file mode 100644 index 0000000000000000000000000000000000000000..b9f33e1cff39c9e6b439c77688a766b2b20afcaa GIT binary patch literal 1473 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 item.disabled && e.preventDefault()} > - {item.icon} + + {item.label} + {item.label} {item.disabled && Soon} @@ -105,7 +108,9 @@ export function Layout({ children }: LayoutProps) { to="/admin" className={`sidebar-link ${location.pathname === '/admin' ? 'active' : ''}`} > - ⚙️ + + Admin + Manage Users @@ -113,11 +118,20 @@ export function Layout({ children }: LayoutProps) {
-
{displayName}
-
- - {user.role} - +
+ {user.avatar_url ? ( + {displayName} + ) : ( +
{displayName[0].toUpperCase()}
+ )} +
+
+
{displayName}
+
+ + {user.role} + +
@@ -126,14 +140,18 @@ export function Layout({ children }: LayoutProps) { onClick={toggleTheme} title={theme === 'dark' ? 'Light mode' : 'Dark mode'} > - {theme === 'dark' ? '☀️' : '🌙'} + {theme === 'dark' ? ( + Light + ) : ( + Dark + )}
diff --git a/frontend/src/index.css b/frontend/src/index.css index d62e6d6..ad1d61a 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -549,6 +549,42 @@ select.input { display: flex; align-items: center; gap: var(--space-sm); + flex: 1; +} + +.sidebar-avatar { + width: 32px; + height: 32px; + flex-shrink: 0; +} + +.avatar-img { + width: 100%; + height: 100%; + border-radius: 50%; + object-fit: cover; + border: 1px solid var(--border); +} + +.avatar-placeholder { + width: 100%; + height: 100%; + border-radius: 50%; + background: var(--accent); + color: white; + display: flex; + align-items: center; + justify-content: center; + font-weight: 600; + font-size: 14px; +} + +.sidebar-user-info { + min-width: 0; + display: flex; + flex-direction: row; + align-items: center; + gap: var(--space-xs); } .sidebar-user-name { @@ -559,6 +595,43 @@ select.input { white-space: nowrap; } +/* Avatar Picker in Profile */ +.avatar-picker { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(60px, 1fr)); + gap: var(--space-sm); + margin-top: var(--space-xs); +} + +.avatar-option { + width: 60px; + height: 60px; + padding: 4px; + border: 2px solid transparent; + border-radius: var(--radius-md); + cursor: pointer; + transition: border-color 0.2s, transform 0.1s; + display: flex; + align-items: center; + justify-content: center; +} + +.avatar-option:hover { + background: var(--bg-primary); + transform: scale(1.05); +} + +.avatar-option.selected { + border-color: var(--accent); + background: var(--bg-primary); +} + +.avatar-option img { + width: 100%; + height: 100%; + object-fit: contain; +} + .sidebar-actions { display: flex; gap: var(--space-xs); @@ -578,6 +651,22 @@ select.input { background: var(--bg-primary); } +.theme-icon { + width: 18px; + height: 18px; + display: block; +} + +/* Invert icons in dark mode if they are dark-oriented */ +[data-theme='dark'] .theme-icon { + filter: invert(1) brightness(2); +} + +.sidebar-icon img { + width: 20px; + height: 20px; +} + /* Main Content */ .main-content { flex: 1; diff --git a/frontend/src/pages/Profile.tsx b/frontend/src/pages/Profile.tsx index 4c70117..ff95192 100644 --- a/frontend/src/pages/Profile.tsx +++ b/frontend/src/pages/Profile.tsx @@ -17,6 +17,7 @@ interface UserProfile { smoking: boolean | null alcohol: boolean | null diet: string | null + avatar_url: string | null } export function ProfilePage() { @@ -35,6 +36,12 @@ export function ProfilePage() { const [smoking, setSmoking] = useState(null) const [alcohol, setAlcohol] = useState(null) const [dietId, setDietId] = useState(null) + const [avatarUrl, setAvatarUrl] = useState(null) + + const avatarOptions = [ + ...[1, 2, 3, 4, 5, 6, 7].map(i => `/icons/user/icons8-male-user-50${i === 1 ? '' : `-${i}`}.png`), + ...['', '-2', '-3', '-4', '-5', '-7', '-8'].map(s => `/icons/user/icons8-user-50${s}.png`), + ] useEffect(() => { // Fetch current user and diets (Layout already ensures auth) @@ -61,9 +68,17 @@ export function ProfilePage() { // Find diet ID from name const diet = dietsData.find((d: Diet) => d.name === profile.diet) setDietId(diet?.id || null) + setAvatarUrl(profile.avatar_url) }) }) - .finally(() => setLoading(false)) + .finally(() => { + setLoading(false) + // Show success message if we just saved + if (localStorage.getItem('profileSaved') === 'true') { + setMessage({ type: 'success', text: 'Profile updated successfully' }) + localStorage.removeItem('profileSaved') + } + }) }, []) const handleSubmit = async (e: React.FormEvent) => { @@ -86,11 +101,13 @@ export function ProfilePage() { smoking, alcohol, diet_id: dietId, + avatar_url: avatarUrl, }), }) if (res.ok) { - setMessage({ type: 'success', text: 'Profile updated successfully' }) + localStorage.setItem('profileSaved', 'true') + window.location.reload() } else { setMessage({ type: 'error', text: 'Failed to update profile' }) } @@ -131,6 +148,20 @@ export function ProfilePage() { placeholder="Your full name" />
+
+ +
+ {avatarOptions.map(option => ( +
setAvatarUrl(option)} + > + Avatar option +
+ ))} +
+
{/* Physical Info */}