diff --git a/requirements.txt b/requirements.txt index 8fd7c0f..efe7f09 100644 --- a/requirements.txt +++ b/requirements.txt @@ -48,7 +48,7 @@ qrcode==8.2 RapidFuzz==3.14.5 readchar==4.2.2 revel==0.9.2.post1 -rio-ui==0.12.1 +rio-ui==0.12.2 sentinel==1.0.0 six==1.17.0 starlette==0.52.1 diff --git a/src/elm/pages/MyOrdersPage.py b/src/elm/pages/MyOrdersPage.py new file mode 100644 index 0000000..148bfe7 --- /dev/null +++ b/src/elm/pages/MyOrdersPage.py @@ -0,0 +1,75 @@ +from __future__ import annotations + +from typing import Optional + +from rio import Component, Column, Spacer, page, GuardEvent, Rectangle, Text, FlowContainer, Color, ProgressCircle +from rio.event import on_populate + +from elm.services import UserService +from elm.types import UserSession +from elm.types.CateringTypes import CateringOrder, CateringOrderStatus + + +def my_orders_page_guard(event: GuardEvent) -> Optional[str]: + try: + _ = event.session[UserSession].user_name + return None + except KeyError: + return "/" + +@page(name="My Orders", url_segment="my-orders", guard=my_orders_page_guard) +class MyOrdersPage(Component): + orders: list[CateringOrder] = [] + is_loading: bool = True + + @on_populate + async def on_populate(self) -> None: + user = await self.session[UserService].get_user(self.session[UserSession].user_name) + if not user: + self.is_loading = False + return + + self.orders = await CateringOrder.find_many(CateringOrder.customer_id == user.id).to_list() + self.is_loading = False + + def get_status_color(self, status: CateringOrderStatus) -> Color: + color = self.session.theme.warning_color + if status == CateringOrderStatus.DELAYED or status == CateringOrderStatus.CANCELED: + color = self.session.theme.danger_color + elif status == CateringOrderStatus.COMPLETED: + color = self.session.theme.success_color + return color + + def build(self) -> Component: + if self.is_loading: + return ProgressCircle(margin=self.session.screen_width // 5) + return Column( + FlowContainer( + *[Rectangle( + content=Column( + Rectangle( + content=Rectangle( + content=Text(f"Bestellung\n\n{str(order.id)[-5:]}", margin=0.5, selectable=False, overflow="wrap", justify="center"), + fill=self.session.theme.header_box_background_color, + margin=0.4 + ), + stroke_width=0.1, + stroke_color=self.session.theme.box_border_color, + ), + Column( + *[Text(item.name, overflow="wrap") for item in order.items], + spacing=1, + margin=1 + ), + Spacer(), + Text(CateringOrder.translate_order_status(order.status), fill=self.get_status_color(order.status), margin=1, font_weight="bold", font_size=1, justify="center"), + ), + fill=self.session.theme.box_color, + min_width=18 + ) for order in self.orders], + spacing=1 + ), + Spacer(), + spacing=1, + margin=1 + ) diff --git a/src/elm/types/CateringTypes.py b/src/elm/types/CateringTypes.py index 6aa7f56..d837dbf 100644 --- a/src/elm/types/CateringTypes.py +++ b/src/elm/types/CateringTypes.py @@ -183,3 +183,20 @@ class CateringOrder(Document): class Settings: name = "catering_orders" + + @staticmethod + def translate_order_status(status: CateringOrderStatus) -> str: + if status == CateringOrderStatus.RECEIVED: + return "Eingegangen" + elif status == CateringOrderStatus.DELAYED: + return "Verzögert" + elif status == CateringOrderStatus.READY_FOR_PICKUP: + return "Abholbereit" + elif status == CateringOrderStatus.EN_ROUTE: + return "In Zustellung" + elif status == CateringOrderStatus.COMPLETED: + return "Abgeschlossen" + elif status == CateringOrderStatus.CANCELED: + return "Storniert" + else: + raise RuntimeError("Unknown CateringOrderStatus:", status)