import logging from datetime import datetime from typing import Optional from from_root import from_root from rio import Column, Component, event, TextStyle, Text, Spacer, Row, Image, Tooltip, IconButton, Popup, Rectangle, Dropdown, ThemeContextSwitcher, Button from src.ezgg_lan_manager import ConfigurationService, TournamentService, UserService from src.ezgg_lan_manager.components.MainViewContentBox import MainViewContentBox from src.ezgg_lan_manager.types.DateUtil import weekday_to_display_text from src.ezgg_lan_manager.types.Participant import Participant from src.ezgg_lan_manager.types.Tournament import Tournament from src.ezgg_lan_manager.types.TournamentBase import TournamentStatus logger = logging.getLogger(__name__.split(".")[-1]) class ManageTournamentsPage(Component): tournaments: list[Tournament] = [] remove_participant_popup_open: bool = False cancel_options: dict[str, Optional[Participant]] = {"": None} tournament_id_selected_for_participant_removal: Optional[int] = None participant_selected_for_removal: Optional[Participant] = None @event.on_populate async def on_populate(self) -> None: self.tournaments = await self.session[TournamentService].get_tournaments() await self.session.set_title(f"{self.session[ConfigurationService].get_lan_info().name} - Turnier Verwaltung") async def on_start_pressed(self, tournament_id: int) -> None: logger.info(f"Starting tournament with ID {tournament_id}") await self.session[TournamentService].start_tournament(tournament_id) async def on_cancel_pressed(self, tournament_id: int) -> None: logger.info(f"Canceling tournament with ID {tournament_id}") await self.session[TournamentService].cancel_tournament(tournament_id) async def on_remove_participant_pressed(self, tournament_id: int) -> None: tournament = await self.session[TournamentService].get_tournament_by_id(tournament_id) if tournament is None: 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} except StopIteration as e: logger.error(f"Error trying to find user for participant: {e}") self.tournament_id_selected_for_participant_removal = tournament_id self.remove_participant_popup_open = True async def on_remove_participant_confirm_pressed(self) -> None: if self.participant_selected_for_removal is not None and self.tournament_id_selected_for_participant_removal is not None: logger.info(f"Removing participant with ID {self.participant_selected_for_removal.id} from tournament with ID {self.tournament_id_selected_for_participant_removal}") await self.session[TournamentService].unregister_user_from_tournament(self.participant_selected_for_removal.id, self.tournament_id_selected_for_participant_removal) await self.on_remove_participant_cancel_pressed() async def on_remove_participant_cancel_pressed(self) -> None: self.tournament_id_selected_for_participant_removal = None self.participant_selected_for_removal = None self.remove_participant_popup_open = False def build(self) -> Component: tournament_rows = [] for tournament in self.tournaments: start_time_color = self.session.theme.background_color if tournament.start_time < datetime.now() and tournament.status == TournamentStatus.OPEN: start_time_color = self.session.theme.warning_color tournament_rows.append( Row( Image(image=from_root(f"src/ezgg_lan_manager/assets/img/games/{tournament.game_title.image_name}"), min_width=1.5, margin_right=1), 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"), margin=1 ) ) return Column( Popup( anchor=MainViewContentBox( Column( Text( text="Turnier Verwaltung", style=TextStyle( fill=self.session.theme.background_color, font_size=1.2 ), margin_top=2, margin_bottom=2, align_x=0.5 ), *tournament_rows ) ), content=Rectangle( content=Row( ThemeContextSwitcher( content=Dropdown(options=self.cancel_options, min_width=20, selected_value=self.bind().participant_selected_for_removal), color=self.session.theme.hud_color ), Button(content="REMOVE", shape="rectangle", grow_x=False, on_press=self.on_remove_participant_confirm_pressed), Button(content="CANCEL", shape="rectangle", grow_x=False, on_press=self.on_remove_participant_cancel_pressed), margin=0.5 ), min_width=30, min_height=4, fill=self.session.theme.primary_color, margin_top=3.5, stroke_width=0.3, stroke_color=self.session.theme.neutral_color, ), is_open=self.remove_participant_popup_open, color="none" ), Spacer() )