update theme
This commit is contained in:
@@ -121,19 +121,21 @@ class _BusinessUnitSelectionPageState extends State<BusinessUnitSelectionPage> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: AppColors.white,
|
||||
backgroundColor: colorScheme.surface,
|
||||
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(
|
||||
'Đơn vị kinh doanh',
|
||||
style: TextStyle(
|
||||
color: Colors.black,
|
||||
color: colorScheme.onSurface,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
@@ -141,7 +143,7 @@ class _BusinessUnitSelectionPageState extends State<BusinessUnitSelectionPage> {
|
||||
centerTitle: false,
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const FaIcon(FontAwesomeIcons.circleInfo, color: Colors.black, size: 20),
|
||||
icon: FaIcon(FontAwesomeIcons.circleInfo, color: colorScheme.onSurface, size: 20),
|
||||
onPressed: _showInfoDialog,
|
||||
),
|
||||
const SizedBox(width: AppSpacing.sm),
|
||||
@@ -164,20 +166,20 @@ class _BusinessUnitSelectionPageState extends State<BusinessUnitSelectionPage> {
|
||||
),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
child: const Column(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
'DBIZ',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
color: colorScheme.onPrimary,
|
||||
fontSize: 32,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'Worker App',
|
||||
style: TextStyle(color: Colors.white, fontSize: 12),
|
||||
style: TextStyle(color: colorScheme.onPrimary, fontSize: 12),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -187,22 +189,22 @@ class _BusinessUnitSelectionPageState extends State<BusinessUnitSelectionPage> {
|
||||
const SizedBox(height: AppSpacing.xl),
|
||||
|
||||
// Welcome Message
|
||||
const Text(
|
||||
Text(
|
||||
'Chọn đơn vị kinh doanh để tiếp tục',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(color: AppColors.grey500, fontSize: 14),
|
||||
style: TextStyle(color: colorScheme.onSurfaceVariant, fontSize: 14),
|
||||
),
|
||||
|
||||
const SizedBox(height: 40),
|
||||
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: AppSpacing.sm),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.sm),
|
||||
child: Text(
|
||||
'Đơn vị kinh doanh',
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: AppColors.grey900,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -227,11 +229,11 @@ class _BusinessUnitSelectionPageState extends State<BusinessUnitSelectionPage> {
|
||||
bottom: isLast ? 0 : AppSpacing.xs,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.white,
|
||||
color: colorScheme.surface,
|
||||
border: Border.all(
|
||||
color: isSelected
|
||||
? AppColors.primaryBlue
|
||||
: AppColors.grey100,
|
||||
? colorScheme.primary
|
||||
: colorScheme.surfaceContainerHighest,
|
||||
width: isSelected ? 2 : 1,
|
||||
),
|
||||
borderRadius: BorderRadius.vertical(
|
||||
@@ -249,7 +251,7 @@ class _BusinessUnitSelectionPageState extends State<BusinessUnitSelectionPage> {
|
||||
boxShadow: isSelected
|
||||
? [
|
||||
BoxShadow(
|
||||
color: AppColors.primaryBlue.withValues(
|
||||
color: colorScheme.primary.withValues(
|
||||
alpha: 0.1,
|
||||
),
|
||||
blurRadius: 8,
|
||||
@@ -289,17 +291,17 @@ class _BusinessUnitSelectionPageState extends State<BusinessUnitSelectionPage> {
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: isSelected
|
||||
? AppColors.primaryBlue.withValues(
|
||||
? colorScheme.primary.withValues(
|
||||
alpha: 0.1,
|
||||
)
|
||||
: AppColors.grey50,
|
||||
: colorScheme.surfaceContainerLowest,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Icon(
|
||||
FontAwesomeIcons.building,
|
||||
color: isSelected
|
||||
? AppColors.primaryBlue
|
||||
: AppColors.grey500,
|
||||
? colorScheme.primary
|
||||
: colorScheme.onSurfaceVariant,
|
||||
size: 20,
|
||||
),
|
||||
),
|
||||
@@ -317,17 +319,17 @@ class _BusinessUnitSelectionPageState extends State<BusinessUnitSelectionPage> {
|
||||
? FontWeight.w600
|
||||
: FontWeight.w500,
|
||||
color: isSelected
|
||||
? AppColors.primaryBlue
|
||||
: AppColors.grey900,
|
||||
? colorScheme.primary
|
||||
: colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
if (unit.description != null) ...[
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
unit.description!,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: AppColors.grey500,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -342,19 +344,19 @@ class _BusinessUnitSelectionPageState extends State<BusinessUnitSelectionPage> {
|
||||
shape: BoxShape.circle,
|
||||
border: Border.all(
|
||||
color: isSelected
|
||||
? AppColors.primaryBlue
|
||||
: AppColors.grey500,
|
||||
? colorScheme.primary
|
||||
: colorScheme.onSurfaceVariant,
|
||||
width: 2,
|
||||
),
|
||||
color: isSelected
|
||||
? AppColors.primaryBlue
|
||||
? colorScheme.primary
|
||||
: Colors.transparent,
|
||||
),
|
||||
child: isSelected
|
||||
? const Icon(
|
||||
? Icon(
|
||||
FontAwesomeIcons.solidCircle,
|
||||
size: 10,
|
||||
color: AppColors.white,
|
||||
color: colorScheme.onPrimary,
|
||||
)
|
||||
: null,
|
||||
),
|
||||
@@ -376,8 +378,8 @@ class _BusinessUnitSelectionPageState extends State<BusinessUnitSelectionPage> {
|
||||
child: ElevatedButton(
|
||||
onPressed: _handleContinue,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: AppColors.primaryBlue,
|
||||
foregroundColor: Colors.white,
|
||||
backgroundColor: colorScheme.primary,
|
||||
foregroundColor: colorScheme.onPrimary,
|
||||
elevation: 0,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(
|
||||
|
||||
@@ -137,10 +137,12 @@ class _ForgotPasswordPageState extends ConsumerState<ForgotPasswordPage> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: const Color(0xFFF4F6F8),
|
||||
backgroundColor: colorScheme.surfaceContainerLowest,
|
||||
appBar: AppBar(
|
||||
backgroundColor: AppColors.white,
|
||||
backgroundColor: colorScheme.surface,
|
||||
elevation: AppBarSpecs.elevation,
|
||||
title: const Text(
|
||||
'Quên mật khẩu',
|
||||
@@ -166,27 +168,27 @@ class _ForgotPasswordPageState extends ConsumerState<ForgotPasswordPage> {
|
||||
const SizedBox(height: AppSpacing.xl),
|
||||
|
||||
// Icon
|
||||
_buildIcon(),
|
||||
_buildIcon(colorScheme),
|
||||
|
||||
const SizedBox(height: AppSpacing.xl),
|
||||
|
||||
// Title & Instructions
|
||||
_buildInstructions(),
|
||||
_buildInstructions(colorScheme),
|
||||
|
||||
const SizedBox(height: AppSpacing.xl),
|
||||
|
||||
// Form Card
|
||||
_buildFormCard(),
|
||||
_buildFormCard(colorScheme),
|
||||
|
||||
const SizedBox(height: AppSpacing.lg),
|
||||
|
||||
// Back to Login Link
|
||||
_buildBackToLoginLink(),
|
||||
_buildBackToLoginLink(colorScheme),
|
||||
|
||||
const SizedBox(height: AppSpacing.xl),
|
||||
|
||||
// Support Link
|
||||
_buildSupportLink(),
|
||||
_buildSupportLink(colorScheme),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -196,45 +198,45 @@ class _ForgotPasswordPageState extends ConsumerState<ForgotPasswordPage> {
|
||||
}
|
||||
|
||||
/// Build icon
|
||||
Widget _buildIcon() {
|
||||
Widget _buildIcon(ColorScheme colorScheme) {
|
||||
return Center(
|
||||
child: Container(
|
||||
width: 100,
|
||||
height: 100,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.primaryBlue.withValues(alpha: 0.1),
|
||||
color: colorScheme.primary.withValues(alpha: 0.1),
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: const Icon(
|
||||
child: Icon(
|
||||
FontAwesomeIcons.key,
|
||||
size: 50,
|
||||
color: AppColors.primaryBlue,
|
||||
color: colorScheme.primary,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Build instructions
|
||||
Widget _buildInstructions() {
|
||||
return const Column(
|
||||
Widget _buildInstructions(ColorScheme colorScheme) {
|
||||
return Column(
|
||||
children: [
|
||||
Text(
|
||||
'Đặt lại mật khẩu',
|
||||
style: TextStyle(
|
||||
fontSize: 28.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: AppColors.grey900,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
SizedBox(height: AppSpacing.sm),
|
||||
const SizedBox(height: AppSpacing.sm),
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: AppSpacing.md),
|
||||
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.md),
|
||||
child: Text(
|
||||
'Nhập số điện thoại đã đăng ký. Chúng tôi sẽ gửi mã OTP để xác nhận và đặt lại mật khẩu của bạn.',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 15.0,
|
||||
color: AppColors.grey500,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
height: 1.5,
|
||||
),
|
||||
),
|
||||
@@ -244,11 +246,11 @@ class _ForgotPasswordPageState extends ConsumerState<ForgotPasswordPage> {
|
||||
}
|
||||
|
||||
/// Build form card
|
||||
Widget _buildFormCard() {
|
||||
Widget _buildFormCard(ColorScheme colorScheme) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(AppSpacing.lg),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.white,
|
||||
color: colorScheme.surface,
|
||||
borderRadius: BorderRadius.circular(AppRadius.card),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
@@ -282,23 +284,23 @@ class _ForgotPasswordPageState extends ConsumerState<ForgotPasswordPage> {
|
||||
child: ElevatedButton(
|
||||
onPressed: _isLoading ? null : _handleSubmit,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: AppColors.primaryBlue,
|
||||
foregroundColor: AppColors.white,
|
||||
disabledBackgroundColor: AppColors.grey100,
|
||||
disabledForegroundColor: AppColors.grey500,
|
||||
backgroundColor: colorScheme.primary,
|
||||
foregroundColor: colorScheme.onPrimary,
|
||||
disabledBackgroundColor: colorScheme.surfaceContainerHighest,
|
||||
disabledForegroundColor: colorScheme.onSurfaceVariant,
|
||||
elevation: ButtonSpecs.elevation,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(ButtonSpecs.borderRadius),
|
||||
),
|
||||
),
|
||||
child: _isLoading
|
||||
? const SizedBox(
|
||||
? SizedBox(
|
||||
height: 20.0,
|
||||
width: 20.0,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2.0,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
AppColors.white,
|
||||
colorScheme.onPrimary,
|
||||
),
|
||||
),
|
||||
)
|
||||
@@ -317,21 +319,21 @@ class _ForgotPasswordPageState extends ConsumerState<ForgotPasswordPage> {
|
||||
}
|
||||
|
||||
/// Build back to login link
|
||||
Widget _buildBackToLoginLink() {
|
||||
Widget _buildBackToLoginLink(ColorScheme colorScheme) {
|
||||
return Center(
|
||||
child: RichText(
|
||||
text: TextSpan(
|
||||
text: 'Nhớ mật khẩu? ',
|
||||
style: const TextStyle(fontSize: 14.0, color: AppColors.grey500),
|
||||
style: TextStyle(fontSize: 14.0, color: colorScheme.onSurfaceVariant),
|
||||
children: [
|
||||
WidgetSpan(
|
||||
child: GestureDetector(
|
||||
onTap: () => context.pop(),
|
||||
child: const Text(
|
||||
child: Text(
|
||||
'Đăng nhập',
|
||||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
color: AppColors.primaryBlue,
|
||||
color: colorScheme.primary,
|
||||
fontWeight: FontWeight.w500,
|
||||
decoration: TextDecoration.none,
|
||||
),
|
||||
@@ -345,20 +347,20 @@ class _ForgotPasswordPageState extends ConsumerState<ForgotPasswordPage> {
|
||||
}
|
||||
|
||||
/// Build support link
|
||||
Widget _buildSupportLink() {
|
||||
Widget _buildSupportLink(ColorScheme colorScheme) {
|
||||
return Center(
|
||||
child: TextButton.icon(
|
||||
onPressed: _showSupport,
|
||||
icon: const Icon(
|
||||
icon: Icon(
|
||||
FontAwesomeIcons.headset,
|
||||
size: AppIconSize.sm,
|
||||
color: AppColors.primaryBlue,
|
||||
color: colorScheme.primary,
|
||||
),
|
||||
label: const Text(
|
||||
label: Text(
|
||||
'Hỗ trợ khách hàng',
|
||||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
color: AppColors.primaryBlue,
|
||||
color: colorScheme.primary,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -166,9 +166,10 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
// Watch auth state for loading indicator
|
||||
final authState = ref.watch(authProvider);
|
||||
final isPasswordVisible = ref.watch(passwordVisibilityProvider);
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: const Color(0xFFF4F6F8),
|
||||
backgroundColor: colorScheme.surfaceContainerLowest,
|
||||
body: SafeArea(
|
||||
child: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(AppSpacing.lg),
|
||||
@@ -185,22 +186,22 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
const SizedBox(height: AppSpacing.xl),
|
||||
|
||||
// Welcome Message
|
||||
_buildWelcomeMessage(),
|
||||
_buildWelcomeMessage(colorScheme),
|
||||
|
||||
const SizedBox(height: AppSpacing.xl),
|
||||
|
||||
// Login Form Card
|
||||
_buildLoginForm(authState, isPasswordVisible),
|
||||
_buildLoginForm(authState, isPasswordVisible, colorScheme),
|
||||
|
||||
const SizedBox(height: AppSpacing.lg),
|
||||
|
||||
// Register Link
|
||||
_buildRegisterLink(),
|
||||
_buildRegisterLink(colorScheme),
|
||||
|
||||
const SizedBox(height: AppSpacing.xl),
|
||||
|
||||
// Support Link
|
||||
_buildSupportLink(),
|
||||
_buildSupportLink(colorScheme),
|
||||
|
||||
],
|
||||
),
|
||||
@@ -228,7 +229,7 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
Text(
|
||||
'EUROTILE',
|
||||
style: TextStyle(
|
||||
color: AppColors.white,
|
||||
color: Colors.white,
|
||||
fontSize: 32.0,
|
||||
fontWeight: FontWeight.w700,
|
||||
letterSpacing: 1.5,
|
||||
@@ -238,7 +239,7 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
Text(
|
||||
'Worker App',
|
||||
style: TextStyle(
|
||||
color: AppColors.white,
|
||||
color: Colors.white,
|
||||
fontSize: 12.0,
|
||||
letterSpacing: 0.5,
|
||||
),
|
||||
@@ -250,21 +251,21 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
}
|
||||
|
||||
/// Build welcome message
|
||||
Widget _buildWelcomeMessage() {
|
||||
return const Column(
|
||||
Widget _buildWelcomeMessage(ColorScheme colorScheme) {
|
||||
return Column(
|
||||
children: [
|
||||
Text(
|
||||
'Xin chào!',
|
||||
style: TextStyle(
|
||||
fontSize: 32.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: AppColors.grey900,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
SizedBox(height: AppSpacing.xs),
|
||||
const SizedBox(height: AppSpacing.xs),
|
||||
Text(
|
||||
'Đăng nhập để tiếp tục',
|
||||
style: TextStyle(fontSize: 16.0, color: AppColors.grey500),
|
||||
style: TextStyle(fontSize: 16.0, color: colorScheme.onSurfaceVariant),
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -274,13 +275,14 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
Widget _buildLoginForm(
|
||||
AsyncValue<dynamic> authState,
|
||||
bool isPasswordVisible,
|
||||
ColorScheme colorScheme,
|
||||
) {
|
||||
final isLoading = authState.isLoading;
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(AppSpacing.lg),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.white,
|
||||
color: colorScheme.surface,
|
||||
borderRadius: BorderRadius.circular(AppRadius.card),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
@@ -314,30 +316,30 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
enabled: !isLoading,
|
||||
obscureText: !isPasswordVisible,
|
||||
textInputAction: TextInputAction.done,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: InputFieldSpecs.fontSize,
|
||||
color: AppColors.grey900,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Mật khẩu',
|
||||
labelStyle: const TextStyle(
|
||||
labelStyle: TextStyle(
|
||||
fontSize: InputFieldSpecs.labelFontSize,
|
||||
color: AppColors.grey500,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
hintText: 'Nhập mật khẩu',
|
||||
hintStyle: const TextStyle(
|
||||
hintStyle: TextStyle(
|
||||
fontSize: InputFieldSpecs.hintFontSize,
|
||||
color: AppColors.grey500,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
prefixIcon: const Icon(
|
||||
prefixIcon: Icon(
|
||||
FontAwesomeIcons.lock,
|
||||
color: AppColors.primaryBlue,
|
||||
color: colorScheme.primary,
|
||||
size: AppIconSize.md,
|
||||
),
|
||||
suffixIcon: IconButton(
|
||||
icon: Icon(
|
||||
isPasswordVisible ? FontAwesomeIcons.eye : FontAwesomeIcons.eyeSlash,
|
||||
color: AppColors.grey500,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
size: AppIconSize.md,
|
||||
),
|
||||
onPressed: () {
|
||||
@@ -345,14 +347,14 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
},
|
||||
),
|
||||
filled: true,
|
||||
fillColor: AppColors.white,
|
||||
fillColor: colorScheme.surface,
|
||||
contentPadding: InputFieldSpecs.contentPadding,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(
|
||||
InputFieldSpecs.borderRadius,
|
||||
),
|
||||
borderSide: const BorderSide(
|
||||
color: AppColors.grey100,
|
||||
borderSide: BorderSide(
|
||||
color: colorScheme.surfaceContainerHighest,
|
||||
width: 1.0,
|
||||
),
|
||||
),
|
||||
@@ -360,8 +362,8 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
borderRadius: BorderRadius.circular(
|
||||
InputFieldSpecs.borderRadius,
|
||||
),
|
||||
borderSide: const BorderSide(
|
||||
color: AppColors.grey100,
|
||||
borderSide: BorderSide(
|
||||
color: colorScheme.surfaceContainerHighest,
|
||||
width: 1.0,
|
||||
),
|
||||
),
|
||||
@@ -369,8 +371,8 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
borderRadius: BorderRadius.circular(
|
||||
InputFieldSpecs.borderRadius,
|
||||
),
|
||||
borderSide: const BorderSide(
|
||||
color: AppColors.primaryBlue,
|
||||
borderSide: BorderSide(
|
||||
color: colorScheme.primary,
|
||||
width: 2.0,
|
||||
),
|
||||
),
|
||||
@@ -424,7 +426,7 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
_rememberMe = value ?? false;
|
||||
});
|
||||
},
|
||||
activeColor: AppColors.primaryBlue,
|
||||
activeColor: colorScheme.primary,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(4.0),
|
||||
),
|
||||
@@ -437,11 +439,11 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
_rememberMe = !_rememberMe;
|
||||
});
|
||||
},
|
||||
child: const Text(
|
||||
child: Text(
|
||||
'Ghi nhớ đăng nhập',
|
||||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
color: AppColors.grey500,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -455,7 +457,7 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
'Quên mật khẩu?',
|
||||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
color: isLoading ? AppColors.grey500 : AppColors.primaryBlue,
|
||||
color: isLoading ? colorScheme.onSurfaceVariant : colorScheme.primary,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
@@ -471,23 +473,23 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
child: ElevatedButton(
|
||||
onPressed: isLoading ? null : _handleLogin,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: AppColors.primaryBlue,
|
||||
foregroundColor: AppColors.white,
|
||||
disabledBackgroundColor: AppColors.grey100,
|
||||
disabledForegroundColor: AppColors.grey500,
|
||||
backgroundColor: colorScheme.primary,
|
||||
foregroundColor: colorScheme.onPrimary,
|
||||
disabledBackgroundColor: colorScheme.surfaceContainerHighest,
|
||||
disabledForegroundColor: colorScheme.onSurfaceVariant,
|
||||
elevation: ButtonSpecs.elevation,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(ButtonSpecs.borderRadius),
|
||||
),
|
||||
),
|
||||
child: isLoading
|
||||
? const SizedBox(
|
||||
? SizedBox(
|
||||
height: 20.0,
|
||||
width: 20.0,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2.0,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
AppColors.white,
|
||||
colorScheme.onPrimary,
|
||||
),
|
||||
),
|
||||
)
|
||||
@@ -506,21 +508,21 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
}
|
||||
|
||||
/// Build register link
|
||||
Widget _buildRegisterLink() {
|
||||
Widget _buildRegisterLink(ColorScheme colorScheme) {
|
||||
return Center(
|
||||
child: RichText(
|
||||
text: TextSpan(
|
||||
text: 'Chưa có tài khoản? ',
|
||||
style: const TextStyle(fontSize: 14.0, color: AppColors.grey500),
|
||||
style: TextStyle(fontSize: 14.0, color: colorScheme.onSurfaceVariant),
|
||||
children: [
|
||||
WidgetSpan(
|
||||
child: GestureDetector(
|
||||
onTap: _navigateToRegister,
|
||||
child: const Text(
|
||||
child: Text(
|
||||
'Đăng ký ngay',
|
||||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
color: AppColors.primaryBlue,
|
||||
color: colorScheme.primary,
|
||||
fontWeight: FontWeight.w500,
|
||||
decoration: TextDecoration.none,
|
||||
),
|
||||
@@ -534,20 +536,20 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
||||
}
|
||||
|
||||
/// Build support link
|
||||
Widget _buildSupportLink() {
|
||||
Widget _buildSupportLink(ColorScheme colorScheme) {
|
||||
return Center(
|
||||
child: TextButton.icon(
|
||||
onPressed: _showSupport,
|
||||
icon: const Icon(
|
||||
icon: Icon(
|
||||
FontAwesomeIcons.headset,
|
||||
size: AppIconSize.sm,
|
||||
color: AppColors.primaryBlue,
|
||||
color: colorScheme.primary,
|
||||
),
|
||||
label: const Text(
|
||||
label: Text(
|
||||
'Hỗ trợ khách hàng',
|
||||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
color: AppColors.primaryBlue,
|
||||
color: colorScheme.primary,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -14,7 +14,7 @@ import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'package:worker/core/constants/ui_constants.dart';
|
||||
import 'package:worker/core/router/app_router.dart';
|
||||
import 'package:worker/core/theme/colors.dart';
|
||||
import 'package:worker/core/theme/colors.dart'; // Keep for status colors and brand gradients
|
||||
|
||||
/// OTP Verification Page
|
||||
///
|
||||
@@ -237,19 +237,21 @@ class _OtpVerificationPageState extends ConsumerState<OtpVerificationPage> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: AppColors.grey50,
|
||||
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(
|
||||
'Xác thực OTP',
|
||||
style: TextStyle(
|
||||
color: Colors.black,
|
||||
color: colorScheme.onSurface,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
@@ -276,14 +278,14 @@ class _OtpVerificationPageState extends ConsumerState<OtpVerificationPage> {
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
colors: [AppColors.primaryBlue, AppColors.lightBlue],
|
||||
colors: [AppColors.primaryBlue, AppColors.lightBlue], // Keep brand colors
|
||||
),
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: const Icon(
|
||||
child: Icon(
|
||||
FontAwesomeIcons.shieldHalved,
|
||||
size: 36,
|
||||
color: AppColors.white,
|
||||
color: colorScheme.onPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -291,24 +293,24 @@ class _OtpVerificationPageState extends ConsumerState<OtpVerificationPage> {
|
||||
const SizedBox(height: AppSpacing.lg),
|
||||
|
||||
// Instructions
|
||||
const Text(
|
||||
Text(
|
||||
'Nhập mã xác thực',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColors.grey900,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 12),
|
||||
|
||||
const Text(
|
||||
Text(
|
||||
'Mã OTP đã được gửi đến số điện thoại',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: AppColors.grey500,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -317,10 +319,10 @@ class _OtpVerificationPageState extends ConsumerState<OtpVerificationPage> {
|
||||
Text(
|
||||
_formatPhoneNumber(widget.phoneNumber),
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColors.primaryBlue,
|
||||
color: colorScheme.primary,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -329,7 +331,7 @@ class _OtpVerificationPageState extends ConsumerState<OtpVerificationPage> {
|
||||
// OTP Input Card
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.white,
|
||||
color: colorScheme.surface,
|
||||
borderRadius: BorderRadius.circular(AppRadius.card),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
@@ -351,7 +353,7 @@ class _OtpVerificationPageState extends ConsumerState<OtpVerificationPage> {
|
||||
padding: EdgeInsets.only(
|
||||
left: index > 0 ? 8 : 0,
|
||||
),
|
||||
child: _buildOtpInput(index),
|
||||
child: _buildOtpInput(index, colorScheme),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -365,8 +367,8 @@ class _OtpVerificationPageState extends ConsumerState<OtpVerificationPage> {
|
||||
child: ElevatedButton(
|
||||
onPressed: _isLoading ? null : _handleVerifyOtp,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: AppColors.primaryBlue,
|
||||
foregroundColor: AppColors.white,
|
||||
backgroundColor: colorScheme.primary,
|
||||
foregroundColor: colorScheme.onPrimary,
|
||||
elevation: 0,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(
|
||||
@@ -375,13 +377,13 @@ class _OtpVerificationPageState extends ConsumerState<OtpVerificationPage> {
|
||||
),
|
||||
),
|
||||
child: _isLoading
|
||||
? const SizedBox(
|
||||
? SizedBox(
|
||||
height: 20,
|
||||
width: 20,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
AppColors.white,
|
||||
colorScheme.onPrimary,
|
||||
),
|
||||
),
|
||||
)
|
||||
@@ -405,9 +407,9 @@ class _OtpVerificationPageState extends ConsumerState<OtpVerificationPage> {
|
||||
child: Text.rich(
|
||||
TextSpan(
|
||||
text: 'Không nhận được mã? ',
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: AppColors.grey500,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
children: [
|
||||
WidgetSpan(
|
||||
@@ -421,8 +423,8 @@ class _OtpVerificationPageState extends ConsumerState<OtpVerificationPage> {
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: _countdown > 0
|
||||
? AppColors.grey500
|
||||
: AppColors.primaryBlue,
|
||||
? colorScheme.onSurfaceVariant
|
||||
: colorScheme.primary,
|
||||
decoration: _countdown == 0
|
||||
? TextDecoration.none
|
||||
: TextDecoration.none,
|
||||
@@ -445,7 +447,7 @@ class _OtpVerificationPageState extends ConsumerState<OtpVerificationPage> {
|
||||
}
|
||||
|
||||
/// Build single OTP input box
|
||||
Widget _buildOtpInput(int index) {
|
||||
Widget _buildOtpInput(int index, ColorScheme colorScheme) {
|
||||
return SizedBox(
|
||||
width: 48,
|
||||
height: 48,
|
||||
@@ -455,10 +457,10 @@ class _OtpVerificationPageState extends ConsumerState<OtpVerificationPage> {
|
||||
textAlign: TextAlign.center,
|
||||
keyboardType: TextInputType.number,
|
||||
maxLength: 1,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColors.grey900,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.digitsOnly,
|
||||
@@ -468,20 +470,20 @@ class _OtpVerificationPageState extends ConsumerState<OtpVerificationPage> {
|
||||
contentPadding: EdgeInsets.zero,
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: const BorderSide(
|
||||
color: AppColors.grey100,
|
||||
borderSide: BorderSide(
|
||||
color: colorScheme.surfaceContainerHighest,
|
||||
width: 2,
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: const BorderSide(
|
||||
color: AppColors.primaryBlue,
|
||||
borderSide: BorderSide(
|
||||
color: colorScheme.primary,
|
||||
width: 2,
|
||||
),
|
||||
),
|
||||
filled: false,
|
||||
fillColor: AppColors.white,
|
||||
fillColor: colorScheme.surface,
|
||||
),
|
||||
onChanged: (value) => _onOtpChanged(index, value),
|
||||
onTap: () {
|
||||
|
||||
@@ -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: ' và '),
|
||||
const TextSpan(text: ' và '),
|
||||
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),
|
||||
|
||||
@@ -15,8 +15,10 @@ class SplashPage extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: AppColors.white,
|
||||
backgroundColor: colorScheme.surface,
|
||||
body: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
@@ -37,7 +39,7 @@ class SplashPage extends StatelessWidget {
|
||||
Text(
|
||||
'EUROTILE',
|
||||
style: TextStyle(
|
||||
color: AppColors.white,
|
||||
color: Colors.white,
|
||||
fontSize: 32.0,
|
||||
fontWeight: FontWeight.w700,
|
||||
letterSpacing: 1.5,
|
||||
@@ -47,7 +49,7 @@ class SplashPage extends StatelessWidget {
|
||||
Text(
|
||||
'Worker App',
|
||||
style: TextStyle(
|
||||
color: AppColors.white,
|
||||
color: Colors.white,
|
||||
fontSize: 12.0,
|
||||
letterSpacing: 0.5,
|
||||
),
|
||||
@@ -59,19 +61,19 @@ class SplashPage extends StatelessWidget {
|
||||
const SizedBox(height: 48.0),
|
||||
|
||||
// Loading Indicator
|
||||
const CircularProgressIndicator(
|
||||
valueColor: AlwaysStoppedAnimation<Color>(AppColors.primaryBlue),
|
||||
CircularProgressIndicator(
|
||||
valueColor: AlwaysStoppedAnimation<Color>(colorScheme.primary),
|
||||
strokeWidth: 3.0,
|
||||
),
|
||||
|
||||
const SizedBox(height: 16.0),
|
||||
|
||||
// Loading Text
|
||||
const Text(
|
||||
Text(
|
||||
'Đang tải...',
|
||||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
color: AppColors.grey500,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user