diff --git a/VERSION b/VERSION index 9325c3c..a2268e2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.3.0 \ No newline at end of file +0.3.1 \ No newline at end of file diff --git a/src/EzggLanManager.py b/src/EzggLanManager.py index ce50bc8..c6cc71f 100644 --- a/src/EzggLanManager.py +++ b/src/EzggLanManager.py @@ -157,6 +157,12 @@ if __name__ == "__main__": build=pages.ManageTournamentsPage, guard=team_guard ), + ComponentPage( + name="AdminNavigationPage", + url_segment="admin", + build=pages.AdminNavigationPage, + guard=team_guard + ), ComponentPage( name="DbErrorPage", url_segment="db-error", diff --git a/src/ezgg_lan_manager/components/AdminNavigationCard.py b/src/ezgg_lan_manager/components/AdminNavigationCard.py new file mode 100644 index 0000000..8a83ed2 --- /dev/null +++ b/src/ezgg_lan_manager/components/AdminNavigationCard.py @@ -0,0 +1,36 @@ +from rio import Component, Rectangle, Text, Column, Icon, TextStyle, PointerEventListener, PointerEvent + + +class AdminNavigationCard(Component): + icon_name: str + display_text: str + target_url: str + + def on_press(self, _: PointerEvent) -> None: + if self.target_url: + self.session.navigate_to(self.target_url) + + def build(self) -> Component: + return PointerEventListener( + Rectangle( + content=Column( + Icon( + self.icon_name, + min_width=3.5, + min_height=3.5, + fill="background", + margin=1 + ), + Text(self.display_text, style=TextStyle(fill=self.session.theme.background_color), justify="center", margin=1, margin_top=0) + ), + cursor="pointer", + stroke_width=0.2, + stroke_color=self.session.theme.background_color, + hover_stroke_width=0.2, + hover_stroke_color=self.session.theme.hud_color, + min_width=10, + min_height=10, + corner_radius=0.2 + ), + on_press=self.on_press + ) \ No newline at end of file diff --git a/src/ezgg_lan_manager/components/DesktopNavigation.py b/src/ezgg_lan_manager/components/DesktopNavigation.py index 2a97964..cb8b55d 100644 --- a/src/ezgg_lan_manager/components/DesktopNavigation.py +++ b/src/ezgg_lan_manager/components/DesktopNavigation.py @@ -43,7 +43,7 @@ class DesktopNavigation(Component): lan_info = self.session[ConfigurationService].get_lan_info() user_info_and_login_box = UserInfoAndLoginBox() self.force_login_box_refresh.append(user_info_and_login_box.force_refresh) - user_navigation = [ + navigation = [ DesktopNavigationButton("News", "./news"), Spacer(min_height=0.7), DesktopNavigationButton(f"Über {lan_info.name} {lan_info.iteration}", "./overview"), @@ -60,29 +60,16 @@ class DesktopNavigation(Component): DesktopNavigationButton("Die EZ GG e.V.", "https://ezgg-ev.de/about", open_new_tab=True), Spacer(min_height=0.7) ] - team_navigation = [ - Text("Verwaltung", align_x=0.5, margin_top=0.3, style=TextStyle(fill=Color.from_hex("F0EADE"), font_size=1.2)), - Text("Vorsichtig sein!", align_x=0.5, margin_top=0.3, style=TextStyle(fill=self.session.theme.danger_color, font_size=0.6)), - DesktopNavigationButton("News", "./manage-news", is_team_navigation=True), - DesktopNavigationButton("Benutzer", "./manage-users", is_team_navigation=True), - DesktopNavigationButton("Catering", "./manage-catering", is_team_navigation=True), - DesktopNavigationButton("Turniere", "./manage-tournaments", is_team_navigation=True), - Spacer(min_height=0.7), - Revealer( - header="Normale Navigation", - content=Column(*user_navigation), - header_style=TextStyle(fill=self.session.theme.primary_color, font_size=0.9) - ) - ] if self.user is not None and self.user.is_team_member else [] - nav_to_use = copy(team_navigation) if self.user is not None and self.user.is_team_member else copy(user_navigation) + if self.user is not None and self.user.is_team_member: + navigation.insert(0, DesktopNavigationButton("Adminbereich", "./admin", is_team_navigation=True)) return Card( Column( Text(lan_info.name, align_x=0.5, margin_top=0.3, style=TextStyle(fill=self.session.theme.hud_color, font_size=1.9)), Text(f"Edition {lan_info.iteration}", align_x=0.5, style=TextStyle(fill=self.session.theme.hud_color, font_size=1.2), margin_top=0.3, margin_bottom=2), user_info_and_login_box, - *nav_to_use, + *navigation, Text("Unsere Sponsoren", align_x=0.5, style=TextStyle(fill=self.session.theme.hud_color, font_size=0.9), margin_bottom=0.5, margin_top=1), NavigationSponsorBox(img_name="crackz", url="https://www.crackz.gg/"), align_y=0 diff --git a/src/ezgg_lan_manager/pages/AdminNavigationPage.py b/src/ezgg_lan_manager/pages/AdminNavigationPage.py new file mode 100644 index 0000000..8ba07a0 --- /dev/null +++ b/src/ezgg_lan_manager/pages/AdminNavigationPage.py @@ -0,0 +1,44 @@ +from rio import Column, Component, event, Text, TextStyle, Row + +from src.ezgg_lan_manager.components.AdminNavigationCard import AdminNavigationCard +from src.ezgg_lan_manager.components.MainViewContentBox import MainViewContentBox +from src.ezgg_lan_manager.services.ConfigurationService import ConfigurationService + + +class AdminNavigationPage(Component): + @event.on_populate + async def on_populate(self) -> None: + await self.session.set_title(f"{self.session[ConfigurationService].get_lan_info().name} - Admin") + + def build(self) -> Component: + return Column( + MainViewContentBox( + Text( + text="Admin", + style=TextStyle( + fill=self.session.theme.background_color, + font_size=1.2 + ), + margin_top=2, + margin_bottom=2, + align_x=0.5 + ) + ), + MainViewContentBox( + Column( + Row( + AdminNavigationCard(icon_name="material/supervised_user_circle", display_text="Nutzer", target_url="manage-users"), + AdminNavigationCard(icon_name="material/fastfood", display_text="Catering", target_url="manage-catering"), + spacing=1 + ), + Row( + AdminNavigationCard(icon_name="material/text_ad", display_text="News", target_url="manage-news"), + AdminNavigationCard(icon_name="material/trophy", display_text="Turniere", target_url="manage-tournaments"), + spacing=1 + ), + margin=1, + spacing=1 + ) + ), + align_y=0 + ) diff --git a/src/ezgg_lan_manager/pages/ManageTournamentsPage.py b/src/ezgg_lan_manager/pages/ManageTournamentsPage.py index b4dceb4..18a4c65 100644 --- a/src/ezgg_lan_manager/pages/ManageTournamentsPage.py +++ b/src/ezgg_lan_manager/pages/ManageTournamentsPage.py @@ -1,5 +1,6 @@ import logging from datetime import datetime +from functools import partial from typing import Optional from from_root import from_root @@ -40,7 +41,11 @@ class ManageTournamentsPage(Component): return users = await self.session[UserService].get_all_users() try: - self.cancel_options = {next(filter(lambda u: u.user_id == p.id, users)).user_name: p for p in tournament.participants} + cancel_options = {next(filter(lambda u: u.user_id == p.id, users)).user_name: p for p in tournament.participants} + if cancel_options: + self.cancel_options = cancel_options + else: + self.cancel_options = {"": None} except StopIteration as e: logger.error(f"Error trying to find user for participant: {e}") self.tournament_id_selected_for_participant_removal = tournament_id @@ -70,13 +75,12 @@ class ManageTournamentsPage(Component): Text(tournament.name, style=TextStyle(fill=self.session.theme.background_color, font_size=0.8), justify="left", margin_right=1.5), Text(f"{weekday_to_display_text(tournament.start_time.weekday())[:2]}.{tournament.start_time.strftime('%H:%M')} Uhr", style=TextStyle(fill=start_time_color, font_size=0.8), justify="left", margin_right=1), Spacer(), - Tooltip(anchor=IconButton("material/play_arrow", min_size=2, margin_right=0.5, on_press=lambda: self.on_start_pressed(tournament.id)), tip="Starten"), - Tooltip(anchor=IconButton("material/cancel_schedule_send", min_size=2, margin_right=0.5, on_press=lambda: self.on_cancel_pressed(tournament.id)), tip="Absagen"), - Tooltip(anchor=IconButton("material/person_cancel", min_size=2, on_press=lambda: self.on_remove_participant_pressed(tournament.id)), tip="Spieler entfernen"), + Tooltip(anchor=IconButton("material/play_arrow", min_size=2, margin_right=0.5, on_press=partial(self.on_start_pressed, tournament.id)), tip="Starten"), + Tooltip(anchor=IconButton("material/cancel_schedule_send", min_size=2, margin_right=0.5, on_press=partial(self.on_cancel_pressed, tournament.id)), tip="Absagen"), + Tooltip(anchor=IconButton("material/person_cancel", min_size=2, on_press=partial(self.on_remove_participant_pressed, tournament.id)), tip="Spieler entfernen"), margin=1 ) ) - return Column( Popup( anchor=MainViewContentBox( diff --git a/src/ezgg_lan_manager/pages/ManageUsersPage.py b/src/ezgg_lan_manager/pages/ManageUsersPage.py index e02ce2e..c62896f 100644 --- a/src/ezgg_lan_manager/pages/ManageUsersPage.py +++ b/src/ezgg_lan_manager/pages/ManageUsersPage.py @@ -3,7 +3,7 @@ from dataclasses import field from typing import Optional from rio import Column, Component, event, TextStyle, Text, TextInput, ThemeContextSwitcher, Grid, \ - PointerEventListener, PointerEvent, Rectangle, CursorStyle, Color, TextInputChangeEvent, Spacer, Row, Switch, \ + PointerEventListener, PointerEvent, Rectangle, Color, TextInputChangeEvent, Spacer, Row, Switch, \ SwitchChangeEvent, EventHandler from src.ezgg_lan_manager import ConfigurationService, UserService, AccountingService, SeatingService, MailingService @@ -42,7 +42,7 @@ class ClickableGridContent(Component): grow_x=True ), fill=Color.TRANSPARENT, - cursor=CursorStyle.POINTER + cursor="pointer" ), on_pointer_enter=self.on_mouse_enter, on_pointer_leave=self.on_mouse_leave, diff --git a/src/ezgg_lan_manager/pages/__init__.py b/src/ezgg_lan_manager/pages/__init__.py index e682fb2..e900b6f 100644 --- a/src/ezgg_lan_manager/pages/__init__.py +++ b/src/ezgg_lan_manager/pages/__init__.py @@ -24,3 +24,4 @@ from .TournamentDetailsPage import TournamentDetailsPage from .TournamentRulesPage import TournamentRulesPage from .ConwayPage import ConwayPage from .TeamsPage import TeamsPage +from .AdminNavigationPage import AdminNavigationPage