fix: 移除logo白色背景 + 优化登录页面UI和中文化
Logo修复: - 移除 logo.svg 中的白色背景矩形 (fill="#ffffff") - Logo 现在为透明背景,在深色主题上正确显示 登录页面优化: - 添加 "iAgent" 品牌标题 (28px, bold, 带字间距) - 副标题改为中文 "服务器集群运维智能体" - 表单中文化: 邮箱/密码/登录 - 错误提示改为带背景色的卡片样式 (红色图标+文字) - 添加邮箱输入框 placeholder (user@example.com) - 密码框支持回车提交 - 底部提示: "账号由管理员在后台创建或通过邀请链接注册" - 限制表单最大宽度 360px,外层改用 SingleChildScrollView 防溢出 用户账号说明: App 端不提供自助注册功能,用户账号通过以下方式创建: 1. 管理员在 Web 后台 (用户管理页) 直接创建 2. 管理员发送邀请链接,用户通过链接注册 3. 通过 Web 端自助注册 (可选填公司名创建新租户) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
5d12ada262
commit
68d0c9d6f7
|
|
@ -1,7 +1,4 @@
|
|||
<svg width="400" height="400" viewBox="0 0 400 400" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- Background -->
|
||||
<rect width="400" height="400" fill="#ffffff"/>
|
||||
|
||||
<!-- Antenna stick -->
|
||||
<line x1="200" y1="88" x2="200" y2="58" stroke="#3CC98C" stroke-width="7" stroke-linecap="round"/>
|
||||
<!-- Antenna ball -->
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.4 KiB |
|
|
@ -24,81 +24,134 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
|||
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'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
Loading…
Reference in New Issue