diff --git a/it0_app/assets/icons/logo.svg b/it0_app/assets/icons/logo.svg index 0ca9fd0..73e7be7 100644 --- a/it0_app/assets/icons/logo.svg +++ b/it0_app/assets/icons/logo.svg @@ -1,7 +1,4 @@ - - - diff --git a/it0_app/lib/features/auth/presentation/pages/login_page.dart b/it0_app/lib/features/auth/presentation/pages/login_page.dart index 999b8d5..9888f81 100644 --- a/it0_app/lib/features/auth/presentation/pages/login_page.dart +++ b/it0_app/lib/features/auth/presentation/pages/login_page.dart @@ -24,81 +24,134 @@ class _LoginPageState extends ConsumerState { return Scaffold( backgroundColor: AppColors.background, body: Center( - child: Padding( - padding: const EdgeInsets.all(32), + child: SingleChildScrollView( + padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 48), child: Form( key: _formKey, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - SvgPicture.asset( - 'assets/icons/logo.svg', - width: 100, - height: 100, - ), - const SizedBox(height: 8), - const Text( - 'Operations Intelligent Agent', - style: TextStyle(color: AppColors.textSecondary), - ), - const SizedBox(height: 48), - TextFormField( - controller: _emailController, - keyboardType: TextInputType.emailAddress, - decoration: const InputDecoration( - labelText: 'Email', - prefixIcon: Icon(Icons.email), + child: ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 360), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SvgPicture.asset( + 'assets/icons/logo.svg', + width: 96, + height: 96, ), - validator: (value) { - if (value == null || value.isEmpty) { - return 'Please enter your email'; - } - if (!value.contains('@')) { - return 'Please enter a valid email'; - } - return null; - }, - ), - const SizedBox(height: 16), - TextFormField( - controller: _passwordController, - obscureText: true, - decoration: const InputDecoration( - labelText: 'Password', - prefixIcon: Icon(Icons.lock), + const SizedBox(height: 12), + const Text( + 'iAgent', + style: TextStyle( + color: AppColors.textPrimary, + fontSize: 28, + fontWeight: FontWeight.bold, + letterSpacing: 2, + ), + ), + const SizedBox(height: 4), + const Text( + '服务器集群运维智能体', + style: TextStyle( + color: AppColors.textSecondary, + fontSize: 14, + ), + ), + const SizedBox(height: 48), + TextFormField( + controller: _emailController, + keyboardType: TextInputType.emailAddress, + decoration: const InputDecoration( + labelText: '邮箱', + hintText: 'user@example.com', + prefixIcon: Icon(Icons.email_outlined), + ), + validator: (value) { + if (value == null || value.isEmpty) { + return '请输入邮箱地址'; + } + if (!value.contains('@')) { + return '请输入有效的邮箱地址'; + } + return null; + }, ), - validator: (value) { - if (value == null || value.isEmpty) { - return 'Please enter your password'; - } - return null; - }, - ), - if (authState.error != null) ...[ const SizedBox(height: 16), + TextFormField( + controller: _passwordController, + obscureText: true, + decoration: const InputDecoration( + labelText: '密码', + prefixIcon: Icon(Icons.lock_outline), + ), + validator: (value) { + if (value == null || value.isEmpty) { + return '请输入密码'; + } + return null; + }, + onFieldSubmitted: (_) => _handleLogin(), + ), + if (authState.error != null) ...[ + const SizedBox(height: 16), + Container( + padding: const EdgeInsets.symmetric( + horizontal: 12, + vertical: 8, + ), + decoration: BoxDecoration( + color: AppColors.error.withAlpha(25), + borderRadius: BorderRadius.circular(8), + ), + child: Row( + children: [ + const Icon(Icons.error_outline, + color: AppColors.error, size: 18), + const SizedBox(width: 8), + Expanded( + child: Text( + authState.error!, + style: const TextStyle( + color: AppColors.error, + fontSize: 13, + ), + ), + ), + ], + ), + ), + ], + const SizedBox(height: 24), + SizedBox( + width: double.infinity, + height: 48, + child: FilledButton( + onPressed: authState.isLoading ? null : _handleLogin, + child: authState.isLoading + ? const SizedBox( + height: 20, + width: 20, + child: CircularProgressIndicator( + strokeWidth: 2, + color: Colors.white, + ), + ) + : const Text( + '登录', + style: TextStyle(fontSize: 16), + ), + ), + ), + const SizedBox(height: 32), Text( - authState.error!, - style: const TextStyle(color: Colors.red), + '账号由管理员在后台创建或通过邀请链接注册', + style: TextStyle( + color: AppColors.textMuted, + fontSize: 12, + ), + textAlign: TextAlign.center, ), ], - const SizedBox(height: 24), - SizedBox( - width: double.infinity, - child: FilledButton( - onPressed: authState.isLoading ? null : _handleLogin, - child: authState.isLoading - ? const SizedBox( - height: 20, - width: 20, - child: CircularProgressIndicator( - strokeWidth: 2, - color: Colors.white, - ), - ) - : const Text('Login'), - ), - ), - ], + ), ), ), ),