ezgg-lan-manager/src/ez_lan_manager/components/UserInfoAndLoginBox.py
David Rodenkirchen 3c3fd878c5 add seat booking
2024-09-06 14:12:33 +02:00

199 lines
8.1 KiB
Python

import logging
from random import choice
from typing import Optional
from rio import Component, Column, Text, Row, Rectangle, Button, TextStyle, Color, Spacer, TextInput, Link, event
from src.ez_lan_manager import UserService
from src.ez_lan_manager.components.UserInfoBoxButton import UserInfoBoxButton
from src.ez_lan_manager.services.AccountingService import AccountingService
from src.ez_lan_manager.services.TicketingService import TicketingService
from src.ez_lan_manager.services.SeatingService import SeatingService
from src.ez_lan_manager.types.Seat import Seat
from src.ez_lan_manager.types.Ticket import Ticket
from src.ez_lan_manager.types.User import User
from src.ez_lan_manager.types.SessionStorage import SessionStorage
logger = logging.getLogger(__name__.split(".")[-1])
class StatusButton(Component):
STYLE = TextStyle(fill=Color.from_hex("121212"), font_size=0.5)
label: str
target_url: str
enabled: bool
def build(self) -> Component:
return Link(
content=Button(
content=Text(self.label, style=self.STYLE, justify="center"),
shape="rectangle",
style="major",
color="success" if self.enabled else "danger",
grow_x=True,
margin_left=0.6,
margin_right=0.6,
margin_top=0.6
),
target_url=self.target_url,
align_y=0.5,
grow_y=False
)
class UserInfoAndLoginBox(Component):
TEXT_STYLE = TextStyle(fill=Color.from_hex("02dac5"), font_size=0.9)
show_login: bool = True
user: Optional[User] = None
user_balance: Optional[int] = 0
user_ticket: Optional[Ticket] = None
user_seat: Optional[Seat] = None
@event.on_populate
async def async_init(self) -> None:
if self.session[SessionStorage].user_id:
self.user = await self.session[UserService].get_user(self.session[SessionStorage].user_id)
self.user_balance = await self.session[AccountingService].get_balance(self.user.user_id)
self.user_ticket = await self.session[TicketingService].get_user_ticket(self.user.user_id)
self.user_seat = await self.session[SeatingService].get_user_seat(self.user.user_id)
@staticmethod
def get_greeting() -> str:
return choice(["Guten Tacho", "Tuten Gag", "Servus", "Moinjour", "Hallöchen", "Heyho", "Moinsen"])
# @FixMe: If the user logs out and then tries to log back in, it does not work
# If the user navigates to another page and then tries again. It works.
# When fixed, remove the workaround below.
async def logout(self) -> None:
self.show_login = True
await self.session[SessionStorage].clear()
await self.force_refresh()
# @FixMe: Workaround for the bug described above. Navigating to another page solves the issue.
# Yet, this is not desired behavior.
subpage = str(self.session.active_page_url)
if subpage.endswith("/") or subpage.endswith("news"):
self.session.navigate_to("./overview")
else:
self.session.navigate_to("./news")
async def _on_login_pressed(self) -> None:
user_name = self.user_name_input.text.lower()
if await self.session[UserService].is_login_valid(user_name, self.password_input.text):
self.user_name_input.is_valid = True
self.password_input.is_valid = True
self.login_button.is_loading = False
await self.session[SessionStorage].set_user_id((await self.session[UserService].get_user(user_name)).user_id)
await self.async_init()
self.show_login = False
else:
self.user_name_input.is_valid = False
self.password_input.is_valid = False
self.login_button.is_loading = False
def build(self) -> Component:
self.user_name_input = TextInput(
text="",
label="Benutzername",
accessibility_label="Benutzername",
min_height=0.5,
on_confirm=lambda _: self._on_login_pressed()
)
self.password_input = TextInput(
text="",
label="Passwort",
accessibility_label="Passwort",
is_secret=True,
on_confirm=lambda _: self._on_login_pressed()
)
self.login_button = Button(
Text("LOGIN", style=self.TEXT_STYLE, justify="center"),
shape="rectangle",
style="minor",
color="secondary",
margin_bottom=0.4,
on_press=self._on_login_pressed
)
self.register_button = Button(
Text("REG", style=self.TEXT_STYLE, justify="center"),
shape="rectangle",
style="minor",
color="secondary",
on_press=lambda: self.session.navigate_to("./register")
)
self.forgot_password_button = Button(
Text("LST PWD", style=self.TEXT_STYLE, justify="center"),
shape="rectangle",
style="minor",
color="secondary",
on_press=lambda: self.session.navigate_to("./forgot-password")
)
if self.user is None and self.session[SessionStorage].user_id is None:
return Rectangle(
content=Column(
self.user_name_input,
self.password_input,
Column(
Row(
self.login_button
),
Row(
self.register_button,
Spacer(),
self.forgot_password_button,
proportions=(49, 2, 49)
)
),
spacing=0.4
),
fill=Color.TRANSPARENT,
min_height=8,
min_width=12,
align_x=0.5,
margin_top=0.3,
margin_bottom=2
)
elif self.user is None and self.session[SessionStorage].user_id is not None:
return Rectangle(
content=Column(),
fill=Color.TRANSPARENT,
min_height=8,
min_width=12,
align_x=0.5,
margin_top=0.3,
margin_bottom=2
)
else:
return Rectangle(
content=Column(
Text(f"{self.get_greeting()},", style=TextStyle(fill=Color.from_hex("02dac5"), font_size=0.9), justify="center"),
Text(f"{self.user.user_name}", style=TextStyle(fill=Color.from_hex("02dac5"), font_size=1.2), justify="center"),
Row(
StatusButton(label="TICKET", target_url="./buy_ticket",
enabled=self.user_ticket is not None),
StatusButton(label="SITZPLATZ", target_url="./seating",
enabled=self.user_seat is not None),
proportions=(50, 50),
grow_y=False
),
UserInfoBoxButton("Profil bearbeiten", "./edit-profile"),
UserInfoBoxButton(f"Guthaben: {self.session[AccountingService].make_euro_string_from_int(self.user_balance)}", "./account"),
Button(
content=Text("Ausloggen", style=TextStyle(fill=Color.from_hex("02dac5"), font_size=0.6)),
shape="rectangle",
style="minor",
color="secondary",
grow_x=True,
margin_left=0.6,
margin_right=0.6,
margin_top=0.6,
on_press=self.logout
)
),
fill=Color.TRANSPARENT,
min_height=8,
min_width=12,
align_x=0.5,
margin_top=0.3,
margin_bottom=2
)