// auth_screen.dart — 登录 / 注册页 import 'package:flutter/material.dart'; import '../pangolin_theme.dart'; import 'pangolin_icons.dart'; import 'pangolin_button.dart'; import 'pangolin_logo.dart'; enum _AuthMode { login, register } class AuthScreen extends StatefulWidget { const AuthScreen({super.key, required this.onDone, this.zh = true}); final VoidCallback onDone; final bool zh; @override State createState() => _AuthScreenState(); } class _AuthScreenState extends State { _AuthMode _mode = _AuthMode.login; int _step = 0; bool _sent = false; final _email = TextEditingController(); final _code = TextEditingController(); final _pw = TextEditingController(); bool get _emailValid => RegExp(r'\S+@\S+\.\S+').hasMatch(_email.text); String _t(String zh, String en) => widget.zh ? zh : en; @override void dispose() { _email.dispose(); _code.dispose(); _pw.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final c = context.pangolin; return Scaffold( backgroundColor: c.bg, body: SafeArea( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 28), child: Column( children: [ const SizedBox(height: 18), Column(children: [ const PangolinMark(size: 52), const SizedBox(height: 12), Text(widget.zh ? '穿山甲' : 'Pangolin', style: PangolinText.h1.copyWith(color: c.fg1)), const SizedBox(height: 4), Text(_t('极速 · 稳定 · 省心', 'Fast · Stable · Effortless'), style: PangolinText.sm.copyWith(color: c.accent, fontWeight: FontWeight.w600)), ]), const SizedBox(height: 28), Row(children: [ _tab(_AuthMode.login, _t('登录', 'Log in'), c), _tab(_AuthMode.register, _t('注册', 'Sign up'), c), ]), Divider(height: 1, color: c.border), const SizedBox(height: 22), Expanded(child: _mode == _AuthMode.login ? _login(c) : _register(c)), Padding( padding: const EdgeInsets.symmetric(vertical: 20), child: Text( _t('继续即代表同意《服务条款》与《隐私政策》', 'By continuing you agree to our Terms & Privacy Policy'), textAlign: TextAlign.center, style: PangolinText.caption.copyWith(color: c.fg3, fontWeight: FontWeight.w400), ), ), ], ), ), ), ); } Widget _tab(_AuthMode m, String label, PangolinScheme c) { final on = _mode == m; return Expanded( child: GestureDetector( onTap: () => setState(() { _mode = m; _step = 0; _sent = false; }), child: Container( padding: const EdgeInsets.symmetric(vertical: 10), decoration: BoxDecoration(border: Border(bottom: BorderSide(color: on ? c.accent : Colors.transparent, width: 2))), child: Center(child: Text(label, style: PangolinText.body.copyWith(color: on ? c.fg1 : c.fg3, fontWeight: on ? FontWeight.w700 : FontWeight.w500))), ), ), ); } Widget _field(PangolinScheme c, {required IconData icon, required String label, required Widget child}) { return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(label, style: PangolinText.caption.copyWith(color: c.fg2, fontWeight: FontWeight.w600)), const SizedBox(height: 7), Container( padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 2), decoration: BoxDecoration(color: c.surface, borderRadius: BorderRadius.circular(PangolinRadius.md), border: Border.all(color: c.borderStrong, width: 1.5)), child: Row(children: [Icon(icon, size: 18, color: c.fg3), const SizedBox(width: 10), Expanded(child: child)]), ), ]); } InputDecoration get _bare => const InputDecoration(border: InputBorder.none, isCollapsed: true, contentPadding: EdgeInsets.symmetric(vertical: 12)); Widget _login(PangolinScheme c) { return Column(children: [ _field(c, icon: PangolinIcons.mail, label: _t('邮箱', 'Email'), child: TextField(controller: _email, decoration: _bare.copyWith(hintText: 'your@email.com'), onChanged: (_) => setState(() {}))), const SizedBox(height: 16), _field(c, icon: PangolinIcons.lock, label: _t('密码', 'Password'), child: TextField(controller: _pw, obscureText: true, decoration: _bare.copyWith(hintText: _t('输入密码', 'Enter password')), onChanged: (_) => setState(() {}))), Align(alignment: Alignment.centerRight, child: Padding( padding: const EdgeInsets.only(top: 8), child: Text(_t('忘记密码?', 'Forgot password?'), style: PangolinText.sm.copyWith(color: c.accent, fontWeight: FontWeight.w600)), )), const SizedBox(height: 18), PangolinButton(label: _t('登录', 'Log in'), expand: true, onPressed: (_emailValid && _pw.text.isNotEmpty) ? widget.onDone : null), ]); } Widget _register(PangolinScheme c) { if (_step == 0) { return Column(children: [ _field(c, icon: PangolinIcons.mail, label: _t('邮箱', 'Email'), child: Row(children: [ Expanded(child: TextField(controller: _email, decoration: _bare.copyWith(hintText: 'your@email.com'), onChanged: (_) => setState(() {}))), GestureDetector( onTap: _emailValid ? () => setState(() => _sent = true) : null, child: Text(_sent ? _t('重新发送', 'Resend') : _t('发送验证码', 'Send code'), style: PangolinText.caption.copyWith(color: _emailValid ? c.accent : c.fg3, fontWeight: FontWeight.w700)), ), ])), if (_sent) Padding(padding: const EdgeInsets.only(top: 8), child: Row(children: [ Icon(PangolinIcons.checkCircle, size: 14, color: c.success), const SizedBox(width: 6), Text('${_t('验证码已发送至', 'Code sent to')} ${_email.text}', style: PangolinText.caption.copyWith(color: c.success, fontWeight: FontWeight.w400)), ])), const SizedBox(height: 16), _field(c, icon: PangolinIcons.shieldCheck, label: _t('邮箱验证码', 'Verification code'), child: TextField(controller: _code, keyboardType: TextInputType.number, maxLength: 6, style: PangolinText.mono.copyWith(letterSpacing: 6, color: c.fg1), decoration: _bare.copyWith(counterText: '', hintText: '······'), onChanged: (_) => setState(() {}))), const SizedBox(height: 8), PangolinButton(label: _t('下一步', 'Next'), expand: true, onPressed: (_sent && _code.text.length == 6) ? () => setState(() => _step = 1) : null), ]); } return Column(children: [ Row(children: [Icon(PangolinIcons.checkCircle, size: 15, color: c.success), const SizedBox(width: 7), Text(_email.text, style: PangolinText.sm.copyWith(color: c.fg2))]), const SizedBox(height: 16), _field(c, icon: PangolinIcons.lock, label: _t('密码', 'Password'), child: TextField(controller: _pw, obscureText: true, decoration: _bare.copyWith(hintText: _t('设置登录密码(用于多端登录)', 'Set a password (multi-device)')), onChanged: (_) => setState(() {}))), const SizedBox(height: 18), PangolinButton(label: _t('创建账户', 'Create account'), expand: true, onPressed: _pw.text.length >= 6 ? widget.onDone : null), ]); } }