update theme

This commit is contained in:
Phuoc Nguyen
2025-12-02 15:20:54 +07:00
parent 12bd70479c
commit 49a41d24eb
78 changed files with 3263 additions and 2756 deletions

View File

@@ -379,6 +379,9 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
@override
Widget build(BuildContext context) {
// Get color scheme at the start of build method
final colorScheme = Theme.of(context).colorScheme;
// Initialize data on first build
if (!_hasInitialized) {
// Use addPostFrameCallback to avoid calling setState during build
@@ -388,18 +391,18 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
}
return Scaffold(
backgroundColor: const Color(0xFFF4F6F8),
backgroundColor: colorScheme.surfaceContainerLowest,
appBar: AppBar(
backgroundColor: AppColors.white,
backgroundColor: colorScheme.surface,
elevation: AppBarSpecs.elevation,
leading: IconButton(
icon: const FaIcon(FontAwesomeIcons.arrowLeft, color: Colors.black, size: 20),
icon: FaIcon(FontAwesomeIcons.arrowLeft, color: colorScheme.onSurface, size: 20),
onPressed: () => context.pop(),
),
title: const Text(
title: Text(
'Đăng ký tài khoản',
style: TextStyle(
color: Colors.black,
color: colorScheme.onSurface,
fontSize: 18,
fontWeight: FontWeight.w600,
),
@@ -407,15 +410,15 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
centerTitle: false,
),
body: _isLoadingData
? const Center(
? Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircularProgressIndicator(),
SizedBox(height: AppSpacing.md),
const CircularProgressIndicator(),
const SizedBox(height: AppSpacing.md),
Text(
'Đang tải dữ liệu...',
style: TextStyle(color: AppColors.grey500),
style: TextStyle(color: colorScheme.onSurfaceVariant),
),
],
),
@@ -429,19 +432,19 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// Welcome section
const Text(
Text(
'Tạo tài khoản mới',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: AppColors.grey900,
color: colorScheme.onSurface,
),
textAlign: TextAlign.center,
),
const SizedBox(height: AppSpacing.xs),
const Text(
Text(
'Điền thông tin để bắt đầu',
style: TextStyle(fontSize: 14, color: AppColors.grey500),
style: TextStyle(fontSize: 14, color: colorScheme.onSurfaceVariant),
textAlign: TextAlign.center,
),
const SizedBox(height: AppSpacing.lg),
@@ -449,7 +452,7 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
// Form card
Container(
decoration: BoxDecoration(
color: AppColors.white,
color: colorScheme.surface,
borderRadius: BorderRadius.circular(AppRadius.card),
boxShadow: [
BoxShadow(
@@ -464,7 +467,7 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// Full Name
_buildLabel('Họ và tên *'),
_buildLabel('Họ và tên *', colorScheme),
TextFormField(
controller: _fullNameController,
focusNode: _fullNameFocus,
@@ -472,6 +475,7 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
decoration: _buildInputDecoration(
hintText: 'Nhập họ và tên',
prefixIcon: FontAwesomeIcons.user,
colorScheme: colorScheme,
),
validator: (value) => Validators.minLength(
value,
@@ -482,7 +486,7 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
const SizedBox(height: AppSpacing.md),
// Phone Number
_buildLabel('Số điện thoại *'),
_buildLabel('Số điện thoại *', colorScheme),
PhoneInputField(
controller: _phoneController,
focusNode: _phoneFocus,
@@ -491,7 +495,7 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
const SizedBox(height: AppSpacing.md),
// Email
_buildLabel('Email *'),
_buildLabel('Email *', colorScheme),
TextFormField(
controller: _emailController,
focusNode: _emailFocus,
@@ -500,13 +504,14 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
decoration: _buildInputDecoration(
hintText: 'Nhập email',
prefixIcon: FontAwesomeIcons.envelope,
colorScheme: colorScheme,
),
validator: Validators.email,
),
const SizedBox(height: AppSpacing.md),
// Password
_buildLabel('Mật khẩu *'),
_buildLabel('Mật khẩu *', colorScheme),
TextFormField(
controller: _passwordController,
focusNode: _passwordFocus,
@@ -515,12 +520,13 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
decoration: _buildInputDecoration(
hintText: 'Tạo mật khẩu mới',
prefixIcon: FontAwesomeIcons.lock,
colorScheme: colorScheme,
suffixIcon: IconButton(
icon: Icon(
_passwordVisible
? FontAwesomeIcons.eye
: FontAwesomeIcons.eyeSlash,
color: AppColors.grey500,
color: colorScheme.onSurfaceVariant,
),
onPressed: () {
setState(() {
@@ -533,28 +539,28 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
Validators.passwordSimple(value, minLength: 6),
),
const SizedBox(height: AppSpacing.xs),
const Text(
Text(
'Mật khẩu tối thiểu 6 ký tự',
style: TextStyle(
fontSize: 12,
color: AppColors.grey500,
color: colorScheme.onSurfaceVariant,
),
),
const SizedBox(height: AppSpacing.md),
// Role Selection (Customer Groups)
_buildLabel('Vai trò *'),
_buildCustomerGroupDropdown(),
_buildLabel('Vai trò *', colorScheme),
_buildCustomerGroupDropdown(colorScheme),
const SizedBox(height: AppSpacing.md),
// Verification Section (conditional)
if (_shouldShowVerification) ...[
_buildVerificationSection(),
_buildVerificationSection(colorScheme),
const SizedBox(height: AppSpacing.md),
],
// Company Name (optional)
_buildLabel('Tên công ty/Cửa hàng'),
_buildLabel('Tên công ty/Cửa hàng', colorScheme),
TextFormField(
controller: _companyController,
focusNode: _companyFocus,
@@ -562,13 +568,14 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
decoration: _buildInputDecoration(
hintText: 'Nhập tên công ty (không bắt buộc)',
prefixIcon: FontAwesomeIcons.building,
colorScheme: colorScheme,
),
),
const SizedBox(height: AppSpacing.md),
// City/Province
_buildLabel('Tỉnh/Thành phố *'),
_buildCityDropdown(),
_buildLabel('Tỉnh/Thành phố *', colorScheme),
_buildCityDropdown(colorScheme),
const SizedBox(height: AppSpacing.md),
// Terms and Conditions
@@ -582,7 +589,7 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
_termsAccepted = value ?? false;
});
},
activeColor: AppColors.primaryBlue,
activeColor: colorScheme.primary,
),
Expanded(
child: Padding(
@@ -593,23 +600,23 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
_termsAccepted = !_termsAccepted;
});
},
child: const Text.rich(
child: Text.rich(
TextSpan(
text: 'Tôi đồng ý với ',
style: TextStyle(fontSize: 13),
style: const TextStyle(fontSize: 13),
children: [
TextSpan(
text: 'Điều khoản sử dụng',
style: TextStyle(
color: AppColors.primaryBlue,
color: colorScheme.primary,
fontWeight: FontWeight.w500,
),
),
TextSpan(text: ''),
const TextSpan(text: ''),
TextSpan(
text: 'Chính sách bảo mật',
style: TextStyle(
color: AppColors.primaryBlue,
color: colorScheme.primary,
fontWeight: FontWeight.w500,
),
),
@@ -629,8 +636,8 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
child: ElevatedButton(
onPressed: _isLoading ? null : _handleRegister,
style: ElevatedButton.styleFrom(
backgroundColor: AppColors.primaryBlue,
foregroundColor: AppColors.white,
backgroundColor: colorScheme.primary,
foregroundColor: colorScheme.onPrimary,
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
@@ -639,13 +646,13 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
),
),
child: _isLoading
? const SizedBox(
? SizedBox(
height: 20,
width: 20,
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor: AlwaysStoppedAnimation<Color>(
AppColors.white,
colorScheme.onPrimary,
),
),
)
@@ -667,17 +674,17 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
Text(
'Đã có tài khoản? ',
style: TextStyle(fontSize: 13, color: AppColors.grey500),
style: TextStyle(fontSize: 13, color: colorScheme.onSurfaceVariant),
),
GestureDetector(
onTap: () => context.pop(),
child: const Text(
child: Text(
'Đăng nhập',
style: TextStyle(
fontSize: 13,
color: AppColors.primaryBlue,
color: colorScheme.primary,
fontWeight: FontWeight.w500,
),
),
@@ -694,15 +701,15 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
}
/// Build label widget
Widget _buildLabel(String text) {
Widget _buildLabel(String text, ColorScheme colorScheme) {
return Padding(
padding: const EdgeInsets.only(bottom: AppSpacing.xs),
child: Text(
text,
style: const TextStyle(
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
color: AppColors.grey900,
color: colorScheme.onSurface,
),
),
);
@@ -712,34 +719,35 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
InputDecoration _buildInputDecoration({
required String hintText,
required IconData prefixIcon,
required ColorScheme colorScheme,
Widget? suffixIcon,
}) {
return InputDecoration(
hintText: hintText,
hintStyle: const TextStyle(
hintStyle: TextStyle(
fontSize: InputFieldSpecs.hintFontSize,
color: AppColors.grey500,
color: colorScheme.onSurfaceVariant,
),
prefixIcon: Icon(
prefixIcon,
color: AppColors.primaryBlue,
color: colorScheme.primary,
size: AppIconSize.md,
),
suffixIcon: suffixIcon,
filled: true,
fillColor: AppColors.white,
fillColor: colorScheme.surface,
contentPadding: InputFieldSpecs.contentPadding,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(InputFieldSpecs.borderRadius),
borderSide: const BorderSide(color: AppColors.grey100, width: 1.0),
borderSide: BorderSide(color: colorScheme.surfaceContainerHighest, width: 1.0),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(InputFieldSpecs.borderRadius),
borderSide: const BorderSide(color: AppColors.grey100, width: 1.0),
borderSide: BorderSide(color: colorScheme.surfaceContainerHighest, width: 1.0),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(InputFieldSpecs.borderRadius),
borderSide: const BorderSide(color: AppColors.primaryBlue, width: 2.0),
borderSide: BorderSide(color: colorScheme.primary, width: 2.0),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(InputFieldSpecs.borderRadius),
@@ -753,7 +761,7 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
}
/// Build customer group dropdown
Widget _buildCustomerGroupDropdown() {
Widget _buildCustomerGroupDropdown(ColorScheme colorScheme) {
final customerGroupsAsync = ref.watch(customerGroupsProvider);
return customerGroupsAsync.when(
@@ -763,6 +771,7 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
decoration: _buildInputDecoration(
hintText: 'Chọn vai trò',
prefixIcon: FontAwesomeIcons.briefcase,
colorScheme: colorScheme,
),
items: groups
.map(
@@ -825,7 +834,7 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
}
/// Build city dropdown
Widget _buildCityDropdown() {
Widget _buildCityDropdown(ColorScheme colorScheme) {
final citiesAsync = ref.watch(citiesProvider);
return citiesAsync.when(
@@ -835,6 +844,7 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
decoration: _buildInputDecoration(
hintText: 'Chọn tỉnh/thành phố',
prefixIcon: Icons.location_city,
colorScheme: colorScheme,
),
items: cities
.map(
@@ -890,11 +900,11 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
}
/// Build verification section
Widget _buildVerificationSection() {
Widget _buildVerificationSection(ColorScheme colorScheme) {
return Container(
decoration: BoxDecoration(
color: const Color(0xFFF8FAFC),
border: Border.all(color: const Color(0xFFE2E8F0), width: 2),
color: colorScheme.surfaceContainerLowest,
border: Border.all(color: colorScheme.outlineVariant, width: 2),
borderRadius: BorderRadius.circular(AppRadius.lg),
),
padding: const EdgeInsets.all(AppSpacing.md),
@@ -905,28 +915,28 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(Icons.shield, color: AppColors.primaryBlue, size: 20),
Icon(Icons.shield, color: colorScheme.primary, size: 20),
const SizedBox(width: AppSpacing.xs),
const Text(
Text(
'Thông tin xác thực',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
color: AppColors.primaryBlue,
color: colorScheme.primary,
),
),
],
),
const SizedBox(height: AppSpacing.xs),
const Text(
Text(
'Thông tin này sẽ được dùng để xác minh tư cách chuyên môn của bạn',
style: TextStyle(fontSize: 12, color: AppColors.grey500),
style: TextStyle(fontSize: 12, color: colorScheme.onSurfaceVariant),
textAlign: TextAlign.center,
),
const SizedBox(height: AppSpacing.md),
// ID Number
_buildLabel('Số CCCD/CMND'),
_buildLabel('Số CCCD/CMND', colorScheme),
TextFormField(
controller: _idNumberController,
focusNode: _idNumberFocus,
@@ -935,12 +945,13 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
decoration: _buildInputDecoration(
hintText: 'Nhập số CCCD/CMND',
prefixIcon: Icons.badge,
colorScheme: colorScheme,
),
),
const SizedBox(height: AppSpacing.md),
// Tax Code
_buildLabel('Mã số thuế cá nhân/Công ty'),
_buildLabel('Mã số thuế cá nhân/Công ty', colorScheme),
TextFormField(
controller: _taxCodeController,
focusNode: _taxCodeFocus,
@@ -949,13 +960,14 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
decoration: _buildInputDecoration(
hintText: 'Nhập mã số thuế (không bắt buộc)',
prefixIcon: Icons.receipt_long,
colorScheme: colorScheme,
),
validator: Validators.taxIdOptional,
),
const SizedBox(height: AppSpacing.md),
// ID Card Upload
_buildLabel('Ảnh mặt trước CCCD/CMND'),
_buildLabel('Ảnh mặt trước CCCD/CMND', colorScheme),
FileUploadCard(
file: _idCardFile,
onTap: () => _pickImage(true),
@@ -967,7 +979,7 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
const SizedBox(height: AppSpacing.md),
// Certificate Upload
_buildLabel('Ảnh chứng chỉ hành nghề hoặc GPKD'),
_buildLabel('Ảnh chứng chỉ hành nghề hoặc GPKD', colorScheme),
FileUploadCard(
file: _certificateFile,
onTap: () => _pickImage(false),