Files
nj/app/lib/features/auth/views/role_selection_page.dart

213 lines
6.3 KiB
Dart

// 角色选择页面 — 注册后选择身份角色
//
// 暖记四种角色:
// - 🎓 老师 — 创建班级、布置主题、点评日记
// - ✏️ 学生 — 加入班级、写日记、查看点评
// - 👨‍👩‍👧 家长 — 查看孩子日记、管理数据
// - 📖 独立用户 — 个人日记、不加入班级
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';
import '../../../core/constants/design_tokens.dart';
import '../../../core/theme/app_radius.dart';
import '../../../data/models/user.dart';
import '../bloc/auth_bloc.dart';
/// 角色卡片数据
class _RoleCard {
final UserRoleType type;
final String title;
final String subtitle;
final IconData icon;
final Color color;
const _RoleCard({
required this.type,
required this.title,
required this.subtitle,
required this.icon,
required this.color,
});
}
/// 角色选择页面
class RoleSelectionPage extends StatelessWidget {
const RoleSelectionPage({super.key});
static const _roles = [
_RoleCard(
type: UserRoleType.student,
title: '我是学生',
subtitle: '加入班级,记录每一天',
icon: Icons.school_rounded,
color: Color(0xFF81B29A), // 鼠尾草绿
),
_RoleCard(
type: UserRoleType.teacher,
title: '我是老师',
subtitle: '创建班级,陪伴学生成长',
icon: Icons.auto_stories_rounded,
color: Color(0xFFE07A5F), // 珊瑚色
),
_RoleCard(
type: UserRoleType.parent,
title: '我是家长',
subtitle: '关注孩子的成长记录',
icon: Icons.family_restroom_rounded,
color: Color(0xFFF2CC8F), // 暖金
),
_RoleCard(
type: UserRoleType.independent,
title: '独立使用',
subtitle: '个人日记,随心记录',
icon: Icons.menu_book_rounded,
color: Color(0xFFD4A5A5), // 玫瑰粉
),
];
@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
return Scaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: DesignTokens.spacing24,
vertical: DesignTokens.spacing32,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 标题
Text(
'你好!👋',
style: Theme.of(context).textTheme.headlineMedium?.copyWith(
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: DesignTokens.spacing8),
Text(
'告诉我你的身份,我会为你定制体验',
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
color: colorScheme.onSurface.withValues(alpha: 0.7),
),
),
const SizedBox(height: DesignTokens.spacing32),
// 角色卡片网格
Expanded(
child: GridView.count(
crossAxisCount: 2,
mainAxisSpacing: DesignTokens.spacing16,
crossAxisSpacing: DesignTokens.spacing16,
childAspectRatio: 0.85,
children: _roles.map((role) => _RoleCardWidget(
role: role,
onTap: () => _selectRole(context, role.type),
)).toList(),
),
),
],
),
),
),
);
}
void _selectRole(BuildContext context, UserRoleType role) {
context.read<AuthBloc>().add(RoleSelected(role));
final state = context.read<AuthBloc>().state;
if (state is Authenticated) {
if (state.needsClassCode) {
context.go('/class-code');
} else {
context.go('/home');
}
}
}
}
/// 角色卡片组件
class _RoleCardWidget extends StatelessWidget {
final _RoleCard role;
final VoidCallback onTap;
const _RoleCardWidget({
required this.role,
required this.onTap,
});
@override
Widget build(BuildContext context) {
return Material(
color: Colors.transparent,
child: InkWell(
onTap: onTap,
borderRadius: AppRadius.lgBorder,
child: Ink(
decoration: BoxDecoration(
color: role.color.withValues(alpha: 0.12),
borderRadius: AppRadius.lgBorder,
border: Border.all(
color: role.color.withValues(alpha: 0.3),
width: 2,
),
),
child: Padding(
padding: const EdgeInsets.all(DesignTokens.spacing16),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// 图标
Container(
width: 56,
height: 56,
decoration: BoxDecoration(
color: role.color.withValues(alpha: 0.2),
shape: BoxShape.circle,
),
child: Icon(
role.icon,
size: 28,
color: role.color,
),
),
const SizedBox(height: DesignTokens.spacing12),
// 标题
Text(
role.title,
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
color: role.color,
),
textAlign: TextAlign.center,
),
const SizedBox(height: DesignTokens.spacing4),
// 副标题
Text(
role.subtitle,
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: Theme.of(context)
.colorScheme
.onSurface
.withValues(alpha: 0.6),
),
textAlign: TextAlign.center,
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
],
),
),
),
),
);
}
}