diff --git a/src/elm/pages/CateringAdminPage.py b/src/elm/pages/CateringAdminPage.py new file mode 100644 index 0000000..f903906 --- /dev/null +++ b/src/elm/pages/CateringAdminPage.py @@ -0,0 +1,129 @@ +from __future__ import annotations + +import logging +from functools import partial +from typing import Optional +from decimal import Decimal + +from beanie import PydanticObjectId, Document +from rio import Component, Column, Row, Text, Spacer, page, Rectangle, TextInput, GuardEvent, Button, TextInputChangeEvent, NumberInput, IconButton, FlowContainer, List, \ + PointerEventListener +from rio.event import on_populate + +from elm.types import UserSession, User, Transaction, Seat +from elm.services import AccountingService, MailingService +from elm.components import AccountInfoBox +from elm.types.CateringTypes import CateringOrder, CateringOrderStatus + +logger = logging.getLogger(__name__.split(".")[-1]) + +def catering_admin_page_guard(event: GuardEvent) -> Optional[str]: + try: + if event.session[UserSession].is_team_member: + return None + return "/" + except KeyError: + return "/" + +@page(name="Cateringverwaltung", url_segment="catering-admin", guard=catering_admin_page_guard) +class CateringAdminPage(Component): + open_orders: List[CateringOrder] = List() + all_users: list[User] = [] + all_seats: list[Seat] = [] + + @on_populate + async def on_populate(self) -> None: + self.all_users = await User.find_all().to_list() + self.all_seats = await Seat.find_all(fetch_links=True).to_list() + self.open_orders = List(await CateringOrder.find_many( + { + "status": { + "$nin": [ + CateringOrderStatus.COMPLETED, + CateringOrderStatus.CANCELED, + ] + } + } + ).to_list()) + + def get_name_for_user_id(self, id_: PydanticObjectId) -> str: + return next(filter(lambda user: user.id == id_ ,self.all_users)).user_name + + def get_seat_for_user_id(self, id_: PydanticObjectId) -> str: + try: + found_seat: Optional[Seat] = next(filter(lambda seat: seat.user is not None and seat.user.id == id_, self.all_seats), None) + if found_seat: + return found_seat.seat_id + return "-" + except Exception: + return "-" + + async def on_order_pressed(self, order: CateringOrder) -> None: + print("Pressed on order: ", str(order.id)[-5:]) + + def build(self) -> Component: + return Row( + Rectangle( + content=Column( + Rectangle( + content=Rectangle( + content=Text("Bestellungen", margin=0.5, selectable=False, overflow="wrap"), + fill=self.session.theme.header_box_background_color, + margin=0.4 + ), + stroke_width=0.1, + stroke_color=self.session.theme.box_border_color, + ), + FlowContainer( + *[PointerEventListener( + content=Rectangle( + content=Column( + Row(Text(f"ID:", font_size=1.2), Text(str(order.id)[-5:], justify="right", font_size=1.2)), + Row(Text("Nutzer:", font_size=1.2), Text(self.get_name_for_user_id(order.customer_id), font_size=1.2, justify="right")), + Row(Text(f"Sitzplatz:", font_size=1.2), Text(self.get_seat_for_user_id(order.customer_id), font_size=1.2, justify="right"), margin_bottom=2), + *[Text(item.name, overflow="ellipsize") for item in order.items], + margin=0.5, + spacing=0.2 + ), + stroke_color=self.session.theme.primary_color, + stroke_width=0.1, + cursor="pointer", + hover_stroke_color=self.session.theme.warning_color, + hover_stroke_width=0.1, + min_width=30 + ), + on_press=lambda event, order=order: self.on_order_pressed(order), + ) for order in self.open_orders], + Spacer(), + spacing=1, + margin=1 + ), + Spacer() + ), + fill=self.session.theme.box_color, + stroke_width=0.1, + stroke_color=self.session.theme.box_border_color, + min_width=25, + grow_x=True + ), + Rectangle( + content=Column( + Rectangle( + content=Rectangle( + content=Text("Speisekarte", margin=0.5, selectable=False, overflow="wrap"), + fill=self.session.theme.header_box_background_color, + margin=0.4 + ), + stroke_width=0.1, + stroke_color=self.session.theme.box_border_color, + ), + Spacer() + ), + fill=self.session.theme.box_color, + stroke_width=0.1, + stroke_color=self.session.theme.box_border_color, + min_width=25 + ), + margin=1, + spacing=1 + )