import asyncio import flet as ft import designer as ds from info import AuthService class RegView(ft.View): def __init__(self, page: ft.Page): self._auth = AuthService(page) self._orgs: list = [] self._first_name = ds.CastomTextField_input( label="Имя", hint_text="Введите имя...", prefix_icon=ft.Icons.PERSON, ) self._last_name = ds.CastomTextField_input( label="Фамилия", hint_text="Введите фамилию...", prefix_icon=ft.Icons.PERSON_OUTLINE, ) self._username = ds.CastomTextField_input( label="Логин", hint_text="Введите логин...", prefix_icon=ft.Icons.ALTERNATE_EMAIL, ) self._password = ds.CastomTextField_input( label="Пароль", hint_text="Введите пароль...", prefix_icon=ft.Icons.LOCK, password=True, can_reveal_password=True, ) self._org_dropdown = ds.SearchableDropdown( label="Организация", hint_text="Загрузка...", ) self._org_dropdown.on_select = self._on_org_change self._group_dropdown = ds.SearchableDropdown( label="Группа", hint_text="Загрузка...", ) self._error = ft.Text("", color=ft.Colors.RED_400, size=ds.s(14), visible=False) self._btn = ds.CastomButton( text="Зарегистрироваться", on_click=lambda e: page.run_task(self._do_register), ) self._btn_cansel = ds.CastomButton( text="Назад", on_click=lambda e: page.run_task(self._do_cancel), ) super().__init__( route="/reg", bgcolor=ds.colors.background, horizontal_alignment=ft.CrossAxisAlignment.STRETCH, vertical_alignment=ft.MainAxisAlignment.CENTER, padding=ft.padding.symmetric(horizontal=ds.s(16), vertical=ds.s(24)), scroll=ft.ScrollMode.AUTO, ) self.controls = [ ft.Text("COPP", color=ds.colors.primary, size=ds.s(30), weight=ft.FontWeight.BOLD, text_align=ft.TextAlign.CENTER), ft.Container(height=ds.s(8)), ft.Text("Регистрация в системе", color=ds.colors.primary, size=ds.s(16), text_align=ft.TextAlign.CENTER), ft.Container(height=ds.s(24)), ft.Container( padding=ft.padding.all(ds.s(24)), bgcolor=ds.colors.surface_alt, border_radius=ds.s(16), content=ft.Column( spacing=ds.s(16), controls=[ self._first_name, self._last_name, self._username, self._password, self._org_dropdown, self._group_dropdown, self._error, ft.Row( wrap=True, spacing=ds.s(8), run_spacing=ds.s(8), controls=[ self._btn_cansel, self._btn, ], ) ], ), ), ] def did_mount(self): self.page.run_task(self._load_data) async def _load_data(self): orgs, groups = await asyncio.gather( self._auth.get_organizations(), self._auth.get_groups(), ) self._orgs = orgs or [] _opt_style = ft.ButtonStyle(color=ds.colors.text_primary) self._org_dropdown.options = [ ft.DropdownOption(key=o["id"], text=o["name_organization"], style=_opt_style) for o in self._orgs ] self._org_dropdown.hint_text = "Выберите организацию..." self._group_dropdown.options = [ ft.DropdownOption(key=g["id"], text=g["name_group"], style=_opt_style) for g in (groups or []) ] self._group_dropdown.hint_text = "Выберите группу..." self.update() def _on_org_change(self, e): # Автоматически выбираем группу, к которой привязана организация selected_id = e.control.value for o in self._orgs: if o["id"] == selected_id: self._group_dropdown.value = o.get("group_id") break self.update() async def _do_cancel(self): await self.page.push_route("/login") async def _do_register(self): first_name = self._first_name.value.strip() if self._first_name.value else "" last_name = self._last_name.value.strip() if self._last_name.value else "" username = self._username.value.strip() if self._username.value else "" password = self._password.value or "" if not all([first_name, last_name, username, password]): self._show_error("Заполните все обязательные поля") return self._btn.disabled = True self._error.visible = False self.update() error = await self._auth.register( username=username, password=password, first_name=first_name, last_name=last_name, group_id=self._group_dropdown.value, organization_id=self._org_dropdown.value, ) if error: self._btn.disabled = False self._show_error(error) else: await self.page.push_route("/login") def _show_error(self, message: str): self._error.value = message self._error.visible = True self.update()