"""登录页与应用外壳(顶栏 + 标签页导航)。 外壳把各分区(我的数据 / 管理)组装起来,按钮均在静态区,id 稳定。 """ from __future__ import annotations from typing import Any from shiny import ui from . import config, theme from .view_admin import _admin_panel from .view_me import _my_panel def login_view() -> ui.Tag: return ui.div( ui.div( theme.crest(96), ui.div(config.TEAM_NAME, class_="zh"), ui.div(config.TEAM_NAME_EN, class_="en"), ui.div(f"{config.TEAM_CITY} · EST. {config.EST_YEAR}", class_="city"), theme.card( "球员登录", ui.input_text("in_user", "用户名", placeholder="如 leo / hakimi / admin"), ui.input_password("in_pw", "密码", placeholder="请输入密码"), ui.input_action_button("btn_login", "登 录", class_="btn-primary"), icon="🔐", ), ui.div( ui.HTML( "球员用球队分配的用户名登录,初始密码请向领队索取;" "首次登录后请到『我的数据』页修改密码。" ), class_="sde-login-hint", ), class_="sde-login", ), class_="sde-login-wrap", ) def app_shell( user: dict[str, Any], user_choices: dict[str, str], seasons: list[int], ) -> ui.Tag: top = ui.div( ui.div( theme.crest(52), ui.div( ui.div(config.TEAM_NAME, class_="zh"), ui.div(config.TEAM_NAME_EN, class_="en"), ), class_="sde-brand", ), ui.div(class_="sde-spacer"), ui.span(ui.HTML(f'欢迎,{user["display_name"]}'), class_="sde-welcome"), ui.input_action_button("btn_logout", "退出", class_="btn-outline-light btn-sm"), class_="sde-topbar", ) season_choices = {"all": "全部赛季", **{str(y): f"{y} 赛季" for y in seasons}} panels = [ ui.nav_panel( "🏆 主页", ui.div( ui.download_button("dl_leaderboard", "📷 导出榜单图", class_="btn-outline-light btn-sm"), ui.input_select("home_season", "赛季", season_choices, selected="all", width="150px"), class_="sde-season-bar", ), ui.output_ui("home_content"), value="home", ), ui.nav_panel("📝 我的数据", _my_panel(), value="me"), ] if user["is_admin"]: panels.append(ui.nav_panel("⚙️ 管理", _admin_panel(user_choices), value="admin")) return ui.div( top, ui.navset_tab(*panels, id="main_tabs"), ui.div( ui.HTML(f"肆带贰足球俱乐部 · {config.TEAM_NAME_EN}"), class_="sde-foot", ), class_="sde-shell", )