@@ -12,11 +12,34 @@ use crate::{
1212 HackathonRoleType , JUDGE_ROLES , JUDGING_ADMIN_ROLES , PEOPLE_ROLES , PRIZE_TRACKS_ROLES ,
1313 RESULTS_ROLES , SCHEDULE_ROLES , SETTINGS_ROLES , SUBMISSION_ROLES , TEAM_ROLES , has_access,
1414 } ,
15- domain:: applications:: handlers:: get_application,
15+ domain:: { applications:: handlers:: get_application, meta :: handlers :: get_public_config } ,
1616 ui:: foundation:: components:: { Header , HeaderSize } ,
1717} ;
1818// SidebarItem is defined below in this file
1919
20+ #[ component]
21+ pub fn ExternalSidebarItem < I : IconShape + Clone + PartialEq + ' static > (
22+ label : String ,
23+ icon : I ,
24+ href : String ,
25+ ) -> Element {
26+ rsx ! {
27+ a { class: "block w-full" , href: "{href}" , target: "_blank" ,
28+ div { class: "bg-background-neutral-primary flex gap-2.5 items-center px-3 py-2 rounded-[24px] w-full cursor-pointer" ,
29+ Icon {
30+ width: 20 ,
31+ height: 20 ,
32+ icon,
33+ class: "text-foreground-neutral-primary" ,
34+ }
35+ p { class: "font-semibold text-sm leading-5 text-foreground-neutral-primary whitespace-nowrap" ,
36+ "{label}"
37+ }
38+ }
39+ }
40+ }
41+ }
42+
2043/// Shared navigation items component to avoid duplication between mobile and desktop
2144#[ component]
2245fn NavItems (
@@ -35,6 +58,8 @@ fn NavItems(
3558 has_results : bool ,
3659 has_settings : bool ,
3760 include_settings_in_nav : bool ,
61+ oidc_issuer : Option < String > ,
62+ include_account_in_nav : bool ,
3863 on_item_click : Option < EventHandler < ( ) > > ,
3964) -> Element {
4065 let handle_click = move |_| {
@@ -178,6 +203,17 @@ fn NavItems(
178203 }
179204 }
180205 }
206+ if let Some ( oidc_issuer) = oidc_issuer {
207+ if include_account_in_nav {
208+ div { onclick: handle_click,
209+ ExternalSidebarItem {
210+ label: "Manage Account" . to_string( ) ,
211+ icon: LdUser ,
212+ href: format!( "{}/account" , oidc_issuer) ,
213+ }
214+ }
215+ }
216+ }
181217 if has_settings && include_settings_in_nav {
182218 div { onclick: handle_click,
183219 SidebarItem {
@@ -215,6 +251,12 @@ pub fn Sidebar(
215251 async move { get_application ( slug) . await . ok ( ) }
216252 } ) ;
217253
254+ let public_config = use_server_future ( get_public_config) ?;
255+ let oidc_issuer = match & * public_config. read ( ) {
256+ Some ( Ok ( config) ) => config. oidc_issuer . clone ( ) ,
257+ _ => None ,
258+ } ;
259+
218260 let mut menu_open = use_signal ( || false ) ;
219261
220262 // Check if user has submitted application (status != "draft")
@@ -291,6 +333,8 @@ pub fn Sidebar(
291333 has_results,
292334 has_settings,
293335 include_settings_in_nav: true ,
336+ oidc_issuer: oidc_issuer. clone( ) ,
337+ include_account_in_nav: true ,
294338 on_item_click: move |_| menu_open. set( false ) ,
295339 }
296340 }
@@ -327,12 +371,21 @@ pub fn Sidebar(
327371 has_results,
328372 has_settings,
329373 include_settings_in_nav: false ,
374+ oidc_issuer: oidc_issuer. clone( ) ,
375+ include_account_in_nav: false ,
330376 on_item_click: None ,
331377 }
332378 }
333379
334- if has_settings {
335- div { class: "mt-auto w-full" ,
380+ div { class: "mt-auto w-full flex flex-col gap-1" ,
381+ if let Some ( oidc_issuer) = oidc_issuer {
382+ ExternalSidebarItem {
383+ label: "Manage Account" . to_string( ) ,
384+ icon: LdUser ,
385+ href: format!( "{}/account" , oidc_issuer) ,
386+ }
387+ }
388+ if has_settings {
336389 SidebarItem {
337390 label: "Settings" . to_string( ) ,
338391 icon: LdSettings ,
0 commit comments