fix theme

This commit is contained in:
Phuoc Nguyen
2025-10-03 15:57:56 +07:00
parent deb7aeb850
commit 762395ce50
4 changed files with 115 additions and 63 deletions

View File

@@ -17,7 +17,7 @@ class EnvironmentConfig {
static String get baseUrl { static String get baseUrl {
switch (currentEnvironment) { switch (currentEnvironment) {
case Environment.development: case Environment.development:
return 'http://localhost:3000'; return 'http://103.188.82.191:4003';
case Environment.staging: case Environment.staging:
return 'https://api-staging.example.com'; return 'https://api-staging.example.com';
case Environment.production: case Environment.production:

View File

@@ -16,8 +16,11 @@ class AppTheme {
useMaterial3: true, useMaterial3: true,
colorScheme: AppColors.lightScheme, colorScheme: AppColors.lightScheme,
// Typography // Typography - Apply theme colors to text styles
textTheme: AppTypography.textTheme, textTheme: AppTypography.textTheme.apply(
bodyColor: AppColors.lightScheme.onSurface,
displayColor: AppColors.lightScheme.onSurface,
),
// App bar theme // App bar theme
appBarTheme: _lightAppBarTheme, appBarTheme: _lightAppBarTheme,
@@ -40,7 +43,7 @@ class AppTheme {
floatingActionButtonTheme: _lightFabTheme, floatingActionButtonTheme: _lightFabTheme,
// Input field themes // Input field themes
inputDecorationTheme: _inputDecorationTheme, inputDecorationTheme: _getInputDecorationTheme(AppColors.lightScheme),
// Other component themes // Other component themes
bottomNavigationBarTheme: _lightBottomNavTheme, bottomNavigationBarTheme: _lightBottomNavTheme,
@@ -52,14 +55,18 @@ class AppTheme {
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: AppSpacing.dialogRadius, borderRadius: AppSpacing.dialogRadius,
), ),
titleTextStyle: AppTypography.headlineSmall, titleTextStyle: AppTypography.headlineSmall.copyWith(
contentTextStyle: AppTypography.bodyMedium, color: AppColors.lightScheme.onSurface,
),
contentTextStyle: AppTypography.bodyMedium.copyWith(
color: AppColors.lightScheme.onSurfaceVariant,
),
), ),
bottomSheetTheme: _bottomSheetTheme, bottomSheetTheme: _bottomSheetTheme,
snackBarTheme: _snackBarTheme, snackBarTheme: _getSnackBarTheme(AppColors.lightScheme),
chipTheme: _lightChipTheme, chipTheme: _lightChipTheme,
dividerTheme: _dividerTheme, dividerTheme: _dividerTheme,
listTileTheme: _listTileTheme, listTileTheme: _getListTileTheme(AppColors.lightScheme),
switchTheme: _lightSwitchTheme, switchTheme: _lightSwitchTheme,
checkboxTheme: _lightCheckboxTheme, checkboxTheme: _lightCheckboxTheme,
radioTheme: _lightRadioTheme, radioTheme: _lightRadioTheme,
@@ -92,8 +99,11 @@ class AppTheme {
useMaterial3: true, useMaterial3: true,
colorScheme: AppColors.darkScheme, colorScheme: AppColors.darkScheme,
// Typography // Typography - Apply theme colors to text styles
textTheme: AppTypography.textTheme, textTheme: AppTypography.textTheme.apply(
bodyColor: AppColors.darkScheme.onSurface,
displayColor: AppColors.darkScheme.onSurface,
),
// App bar theme // App bar theme
appBarTheme: _darkAppBarTheme, appBarTheme: _darkAppBarTheme,
@@ -116,7 +126,7 @@ class AppTheme {
floatingActionButtonTheme: _darkFabTheme, floatingActionButtonTheme: _darkFabTheme,
// Input field themes // Input field themes
inputDecorationTheme: _inputDecorationTheme, inputDecorationTheme: _getInputDecorationTheme(AppColors.darkScheme),
// Other component themes // Other component themes
bottomNavigationBarTheme: _darkBottomNavTheme, bottomNavigationBarTheme: _darkBottomNavTheme,
@@ -128,14 +138,18 @@ class AppTheme {
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: AppSpacing.dialogRadius, borderRadius: AppSpacing.dialogRadius,
), ),
titleTextStyle: AppTypography.headlineSmall, titleTextStyle: AppTypography.headlineSmall.copyWith(
contentTextStyle: AppTypography.bodyMedium, color: AppColors.darkScheme.onSurface,
),
contentTextStyle: AppTypography.bodyMedium.copyWith(
color: AppColors.darkScheme.onSurfaceVariant,
),
), ),
bottomSheetTheme: _bottomSheetTheme, bottomSheetTheme: _bottomSheetTheme,
snackBarTheme: _snackBarTheme, snackBarTheme: _getSnackBarTheme(AppColors.darkScheme),
chipTheme: _darkChipTheme, chipTheme: _darkChipTheme,
dividerTheme: _dividerTheme, dividerTheme: _dividerTheme,
listTileTheme: _listTileTheme, listTileTheme: _getListTileTheme(AppColors.darkScheme),
switchTheme: _darkSwitchTheme, switchTheme: _darkSwitchTheme,
checkboxTheme: _darkCheckboxTheme, checkboxTheme: _darkCheckboxTheme,
radioTheme: _darkRadioTheme, radioTheme: _darkRadioTheme,
@@ -285,7 +299,7 @@ class AppTheme {
), ),
); );
static InputDecorationTheme get _inputDecorationTheme => InputDecorationTheme( static InputDecorationTheme _getInputDecorationTheme(ColorScheme colorScheme) => InputDecorationTheme(
filled: true, filled: true,
contentPadding: const EdgeInsets.all(AppSpacing.fieldPadding), contentPadding: const EdgeInsets.all(AppSpacing.fieldPadding),
border: OutlineInputBorder( border: OutlineInputBorder(
@@ -308,35 +322,65 @@ class AppTheme {
borderRadius: AppSpacing.fieldRadius, borderRadius: AppSpacing.fieldRadius,
borderSide: const BorderSide(width: AppSpacing.borderWidthThick), borderSide: const BorderSide(width: AppSpacing.borderWidthThick),
), ),
errorStyle: AppTypography.errorText, errorStyle: AppTypography.errorText.copyWith(color: colorScheme.error),
hintStyle: AppTypography.hintText, hintStyle: AppTypography.hintText.copyWith(color: colorScheme.onSurfaceVariant),
labelStyle: AppTypography.bodyMedium, labelStyle: AppTypography.bodyMedium.copyWith(color: colorScheme.onSurfaceVariant),
); );
static BottomNavigationBarThemeData get _lightBottomNavTheme => const BottomNavigationBarThemeData( static BottomNavigationBarThemeData get _lightBottomNavTheme => BottomNavigationBarThemeData(
type: BottomNavigationBarType.fixed, type: BottomNavigationBarType.fixed,
elevation: AppSpacing.elevationMedium, elevation: AppSpacing.elevationMedium,
selectedLabelStyle: AppTypography.labelSmall, selectedLabelStyle: AppTypography.labelSmall.copyWith(
unselectedLabelStyle: AppTypography.labelSmall, color: AppColors.lightScheme.primary,
),
unselectedLabelStyle: AppTypography.labelSmall.copyWith(
color: AppColors.lightScheme.onSurfaceVariant,
),
); );
static BottomNavigationBarThemeData get _darkBottomNavTheme => const BottomNavigationBarThemeData( static BottomNavigationBarThemeData get _darkBottomNavTheme => BottomNavigationBarThemeData(
type: BottomNavigationBarType.fixed, type: BottomNavigationBarType.fixed,
elevation: AppSpacing.elevationMedium, elevation: AppSpacing.elevationMedium,
selectedLabelStyle: AppTypography.labelSmall, selectedLabelStyle: AppTypography.labelSmall.copyWith(
unselectedLabelStyle: AppTypography.labelSmall, color: AppColors.darkScheme.primary,
),
unselectedLabelStyle: AppTypography.labelSmall.copyWith(
color: AppColors.darkScheme.onSurfaceVariant,
),
); );
static NavigationBarThemeData get _lightNavigationBarTheme => NavigationBarThemeData( static NavigationBarThemeData get _lightNavigationBarTheme => NavigationBarThemeData(
height: 80, height: 80,
elevation: AppSpacing.elevationMedium, elevation: AppSpacing.elevationMedium,
labelTextStyle: WidgetStateProperty.all(AppTypography.labelSmall), labelTextStyle: WidgetStateProperty.resolveWith<TextStyle?>(
(Set<WidgetState> states) {
if (states.contains(WidgetState.selected)) {
return AppTypography.labelSmall.copyWith(
color: AppColors.lightScheme.primary,
);
}
return AppTypography.labelSmall.copyWith(
color: AppColors.lightScheme.onSurfaceVariant,
);
},
),
); );
static NavigationBarThemeData get _darkNavigationBarTheme => NavigationBarThemeData( static NavigationBarThemeData get _darkNavigationBarTheme => NavigationBarThemeData(
height: 80, height: 80,
elevation: AppSpacing.elevationMedium, elevation: AppSpacing.elevationMedium,
labelTextStyle: WidgetStateProperty.all(AppTypography.labelSmall), labelTextStyle: WidgetStateProperty.resolveWith<TextStyle?>(
(Set<WidgetState> states) {
if (states.contains(WidgetState.selected)) {
return AppTypography.labelSmall.copyWith(
color: AppColors.darkScheme.primary,
);
}
return AppTypography.labelSmall.copyWith(
color: AppColors.darkScheme.onSurfaceVariant,
);
},
),
); );
static NavigationRailThemeData get _lightNavigationRailTheme => const NavigationRailThemeData( static NavigationRailThemeData get _lightNavigationRailTheme => const NavigationRailThemeData(
@@ -369,13 +413,15 @@ class AppTheme {
), ),
); );
static SnackBarThemeData get _snackBarTheme => SnackBarThemeData( static SnackBarThemeData _getSnackBarTheme(ColorScheme colorScheme) => SnackBarThemeData(
elevation: AppSpacing.elevationMedium, elevation: AppSpacing.elevationMedium,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: AppSpacing.radiusSM, borderRadius: AppSpacing.radiusSM,
), ),
behavior: SnackBarBehavior.floating, behavior: SnackBarBehavior.floating,
contentTextStyle: AppTypography.bodyMedium, contentTextStyle: AppTypography.bodyMedium.copyWith(
color: colorScheme.onInverseSurface,
),
); );
static ChipThemeData get _lightChipTheme => ChipThemeData( static ChipThemeData get _lightChipTheme => ChipThemeData(
@@ -383,7 +429,9 @@ class AppTheme {
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: AppSpacing.radiusSM, borderRadius: AppSpacing.radiusSM,
), ),
labelStyle: AppTypography.labelMedium, labelStyle: AppTypography.labelMedium.copyWith(
color: AppColors.lightScheme.onSurfaceVariant,
),
); );
static ChipThemeData get _darkChipTheme => ChipThemeData( static ChipThemeData get _darkChipTheme => ChipThemeData(
@@ -391,7 +439,9 @@ class AppTheme {
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: AppSpacing.radiusSM, borderRadius: AppSpacing.radiusSM,
), ),
labelStyle: AppTypography.labelMedium, labelStyle: AppTypography.labelMedium.copyWith(
color: AppColors.darkScheme.onSurfaceVariant,
),
); );
static const DividerThemeData _dividerTheme = DividerThemeData( static const DividerThemeData _dividerTheme = DividerThemeData(
@@ -399,13 +449,17 @@ class AppTheme {
space: AppSpacing.dividerSpacing, space: AppSpacing.dividerSpacing,
); );
static ListTileThemeData get _listTileTheme => const ListTileThemeData( static ListTileThemeData _getListTileTheme(ColorScheme colorScheme) => ListTileThemeData(
contentPadding: EdgeInsets.symmetric( contentPadding: const EdgeInsets.symmetric(
horizontal: AppSpacing.listItemPadding, horizontal: AppSpacing.listItemPadding,
vertical: AppSpacing.listItemMargin, vertical: AppSpacing.listItemMargin,
), ),
titleTextStyle: AppTypography.titleMedium, titleTextStyle: AppTypography.titleMedium.copyWith(
subtitleTextStyle: AppTypography.bodyMedium, color: colorScheme.onSurface,
),
subtitleTextStyle: AppTypography.bodyMedium.copyWith(
color: colorScheme.onSurfaceVariant,
),
); );
static SwitchThemeData get _lightSwitchTheme => SwitchThemeData( static SwitchThemeData get _lightSwitchTheme => SwitchThemeData(
@@ -463,7 +517,11 @@ class AppTheme {
/// Create responsive theme based on screen size /// Create responsive theme based on screen size
static ThemeData responsiveTheme(BuildContext context, {required bool isDark}) { static ThemeData responsiveTheme(BuildContext context, {required bool isDark}) {
final baseTheme = isDark ? darkTheme : lightTheme; final baseTheme = isDark ? darkTheme : lightTheme;
final responsiveTextTheme = AppTypography.responsiveTextTheme(context); final colorScheme = isDark ? AppColors.darkScheme : AppColors.lightScheme;
final responsiveTextTheme = AppTypography.responsiveTextTheme(context).apply(
bodyColor: colorScheme.onSurface,
displayColor: colorScheme.onSurface,
);
return baseTheme.copyWith( return baseTheme.copyWith(
textTheme: responsiveTextTheme, textTheme: responsiveTextTheme,

View File

@@ -284,7 +284,7 @@ class _LoginPageState extends ConsumerState<LoginPage>
) { ) {
return AnimatedContainer( return AnimatedContainer(
duration: AppSpacing.animationNormal, duration: AppSpacing.animationNormal,
height: isKeyboardVisible ? 120 : 180, height: isKeyboardVisible ? 120 : 190,
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [

View File

@@ -575,38 +575,32 @@ class ThemeSettingsPage extends ConsumerWidget {
body: Column( body: Column(
children: [ children: [
const SizedBox(height: 16), const SizedBox(height: 16),
RadioListTile<ThemeMode>( RadioGroup<ThemeMode>(
title: const Text('Light'),
subtitle: const Text('Use light theme'),
value: ThemeMode.light,
groupValue: themeMode, groupValue: themeMode,
onChanged: (value) { onChanged: (value) {
if (value != null) { if (value != null) {
ref.read(themeModeProvider.notifier).setThemeMode(value); ref.read(themeModeProvider.notifier).setThemeMode(value);
} }
}, },
child: Column(
children: [
RadioListTile<ThemeMode>(
title: const Text('Light'),
subtitle: const Text('Use light theme'),
value: ThemeMode.light,
), ),
RadioListTile<ThemeMode>( RadioListTile<ThemeMode>(
title: const Text('Dark'), title: const Text('Dark'),
subtitle: const Text('Use dark theme'), subtitle: const Text('Use dark theme'),
value: ThemeMode.dark, value: ThemeMode.dark,
groupValue: themeMode,
onChanged: (value) {
if (value != null) {
ref.read(themeModeProvider.notifier).setThemeMode(value);
}
},
), ),
RadioListTile<ThemeMode>( RadioListTile<ThemeMode>(
title: const Text('System'), title: const Text('System'),
subtitle: const Text('Follow system theme'), subtitle: const Text('Follow system theme'),
value: ThemeMode.system, value: ThemeMode.system,
groupValue: themeMode, ),
onChanged: (value) { ],
if (value != null) { ),
ref.read(themeModeProvider.notifier).setThemeMode(value);
}
},
), ),
const SizedBox(height: 32), const SizedBox(height: 32),
Padding( Padding(