import asyncio import flet as ft import designer as ds import api_client class MyTestsPage(ft.Column): def __init__(self, page: ft.Page): self._page = page self._loading = ft.ProgressRing(width=ds.s(40), height=ds.s(40), color=ds.colors.secondary_light) super().__init__( alignment=ft.MainAxisAlignment.START, horizontal_alignment=ft.CrossAxisAlignment.STRETCH, spacing=ds.s(8), controls=[ ft.Row( alignment=ft.MainAxisAlignment.CENTER, controls=[self._loading], ) ], ) async def load(self): user_id = self._page.session.store.get("user_id") if not user_id: self.controls = [ds.CastomText(text="Нет данных пользователя", size=14)] self.update() return responses = await api_client.get_user_responses(user_id) if not responses: self.controls = [ds.CastomText(text="Вы ещё не проходили тесты", size=14)] self.update() return # Подгружаем названия опросов параллельно poll_ids = list({r["poll_id"] for r in responses}) polls_list = await asyncio.gather(*[api_client.get_poll(pid) for pid in poll_ids]) polls_map = {p["id"]: p for p in polls_list if p} self._render(responses, polls_map) self.update() def _render(self, responses: list, polls_map: dict): url_key = self._page.session.store.get("url_key") or "" # Сортируем по дате — новые вверху responses = sorted(responses, key=lambda r: r["submitted_at"], reverse=True) cards = [] for r in responses: poll = polls_map.get(r["poll_id"]) title = poll["title"] if poll else "Неизвестный тест" submitted_at = r["submitted_at"][:19].replace("T", " ") cards.append( ft.Container( border_radius=ds.s(12), padding=ds.s(16), bgcolor=ds.colors.surface, content=ft.Row( alignment=ft.MainAxisAlignment.SPACE_BETWEEN, controls=[ ft.Column( spacing=ds.s(4), expand=True, controls=[ ds.CastomText( text=title, size=15, weight=ft.FontWeight.BOLD, ), ds.CastomText( text=f"Пройден: {submitted_at}", size=12, ), ], ), ft.Icon(ft.Icons.CHEVRON_RIGHT, color=ds.colors.primary), ], ), on_click=lambda e, rid=r["id"]: self._page.go( f"/response/{url_key}/{rid}" ), ink=True, ) ) self.controls = cards