implement light and dark theme

This commit is contained in:
amirrezaghabeli
2025-08-06 14:14:07 +03:30
parent 337fcdbcbc
commit da7b10f0d0
24 changed files with 407 additions and 118 deletions
+5 -1
View File
@@ -1,5 +1,6 @@
import 'package:provider/provider.dart';
import 'package:provider/single_child_widget.dart';
import 'package:tm_app/core/theme/theme_provider.dart';
import '../../data/repositories/auth_repository.dart';
import '../../data/services/auth_service.dart';
@@ -11,7 +12,10 @@ List<SingleChildWidget> get providersRemote {
}
List<SingleChildWidget> get cores {
return [Provider(create: (context) => NetworkManager())];
return [
Provider(create: (context) => NetworkManager()),
ChangeNotifierProvider(create: (context) => ThemeProvider()),
];
}
List<SingleChildWidget> get apiClients {
-51
View File
@@ -1,51 +0,0 @@
import 'package:flutter/material.dart';
class AppColors {
static const Color mainBlue = Color(0xff0164FF);
static const Color borderBlue = Color(0xffA1C6FF);
// Primary Colors
static const Color primaryColor = Color(0xFF007BFF);
static const Color accentColor = Color(0xFFE83E8C);
// Backgrounds
static const Color lightBackgroundColor = Color(0xFFFFFFFF);
static const Color darkBackgroundColor = Color(0xFF222222);
// Text Colors
static const Color primaryTextColor = Color(0xFF212529);
static const Color secondaryTextColor = Color(0xFF6C757D);
static const Color linkTextColor = primaryColor;
// Status Colors
static const Color successColor = Color(0xFF28A745);
static const Color errorColor = Color(0xFFDC3545);
static const Color warningColor = Color(0xFFFFC107);
static const Color jellyBean = Color(0xFF34BCCB);
static const Color grey = Color(0xFF555555);
static const Color grey20 = Color(0xFFE4E4E4);
static const Color grey40 = Color(0xFFDADADA);
static const Color grey50 = Color(0xFF9E9E9E);
static const Color grey60 = Color(0xFF777777);
static const Color grey70 = Color(0xFF444444);
static const Color grey80 = Color(0xFF222222);
static const Color grey10 = Color(0xFFF4F4F4);
// static const Color grey20 = Color(0xFFE3E3E3);
static const Color grey0 = Color(0xFFFCFCFC);
static const Color backgroundColor = Color(0xFFFFFFFF);
static const Color borderColor = Color(0xFFE1E1E1);
static const Color primary2 = Color(0xFFE5EFFF);
static const Color dividerColor = Color(0xFFE1E1E1);
static const Color gren0 = Color(0xFFF9FCF8);
static const Color green10 = Color(0xFFE0F0DC);
static const Color gren20 = Color(0xFFDAF8D6);
static const Color gren30 = Color(0xFF289744);
static const Color red0 = Color(0xFFF8D6D6);
static const Color red10 = Color(0xFFC02525);
static const Color paleOrange = Color(0xFFfff7ee);
// static const Color red10 = Color(0xFFC02525);
static const Color lightBlue = Color(0xFFe8ecfc);
static const Color cyanAqua = Color(0xFFd6f4f8);
static const Color cyanTeal = Color(0xFF24A6B4);
}
+3 -4
View File
@@ -4,6 +4,7 @@ import 'package:flutter_svg/svg.dart';
import 'package:go_router/go_router.dart';
import '../constants/assets.dart';
import '../theme/colors.dart';
import '../utils/size_config.dart';
class AppShellScreen extends StatelessWidget {
@@ -26,10 +27,8 @@ class AppShellScreen extends StatelessWidget {
bottomNavigationBar: Container(
height: 72.0.h(),
decoration: BoxDecoration(
color: const Color(0xFFE3E3E3),
border: Border.fromBorderSide(
BorderSide(color: const Color(0xFFE3E3E3)),
),
color: AppColors.grey10,
border: Border.fromBorderSide(BorderSide(color: AppColors.grey30)),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
+117
View File
@@ -0,0 +1,117 @@
import 'package:flutter/material.dart';
class AppColors {
// Theme mode tracking
static bool _isDarkMode = false;
static void setDarkMode(bool isDark) {
_isDarkMode = isDark;
}
static bool get isDarkMode => _isDarkMode;
// Theme-aware colors
static Color get primaryTextColor =>
_isDarkMode ? const Color(0xFFFFFFFF) : const Color(0xFF212529);
static Color get secondaryTextColor =>
_isDarkMode ? const Color(0xFFFFFFFF) : const Color(0xFF24848E);
static Color get backgroundColor =>
_isDarkMode ? const Color(0xFF222222) : const Color(0xFFFFFFFF);
static Color get surfaceColor =>
_isDarkMode ? const Color(0xFF2C2C2C) : const Color(0xFFFFFFFF);
static Color get cardBackground =>
_isDarkMode ? const Color(0xFF2B2B2B) : const Color(0xFFFFFFFF);
static Color get borderColor =>
_isDarkMode ? const Color(0xFF3C3C3C) : const Color(0xFFE1E1E1);
static Color get dividerColor =>
_isDarkMode ? const Color(0xFF3C3C3C) : const Color(0xFFE1E1E1);
static Color get inputFillColor =>
_isDarkMode ? const Color(0xFF2C2C2C) : const Color(0xFFF5F5F5);
// Static colors that don't change with theme
static const Color mainBlue = Color(0xff0164FF);
static const Color borderBlue = Color(0xffA1C6FF);
static const Color primaryColor = Color(0xFF007BFF);
static const Color accentColor = Color(0xFFE83E8C);
// Link color
static const Color linkTextColor = primaryColor;
// Status Colors (usually don't change with theme)
static const Color successColor = Color(0xFF28A745);
static const Color errorColor = Color(0xFFDC3545);
static const Color warningColor = Color(0xFFFFC107);
static const Color jellyBean = Color(0xFF34BCCB);
static const Color grey = Color(0xFF555555);
// Grey scale with theme awareness
static Color get grey10 =>
_isDarkMode ? const Color(0xFF292929) : const Color(0xFFF4F4F4);
static Color get grey20 =>
_isDarkMode ? const Color(0xFF333333) : const Color(0xFFE3E3E3);
static Color get grey30 =>
_isDarkMode ? const Color(0xFF494949) : const Color(0xFFE1E1E1);
static Color get grey40 =>
_isDarkMode ? const Color(0xFF484848) : const Color(0xFFDADADA);
static Color get grey50 =>
_isDarkMode ? const Color(0xFF707070) : const Color(0xFF9E9E9E);
static Color get grey60 =>
_isDarkMode ? const Color(0xFF777777) : const Color(0xFF777777);
static Color get grey70 =>
_isDarkMode ? const Color(0xFF9E9E9E) : const Color(0xFF444444);
static Color get grey80 =>
_isDarkMode ? const Color(0xFFFFFFFF) : const Color(0xFF222222);
static Color get grey0 =>
_isDarkMode ? const Color(0xFF262626) : const Color(0xFFFCFCFC);
static Color get titleColor =>
_isDarkMode ? const Color(0xFFFCFCFC) : const Color(0xFF222222);
static Color get green20 =>
_isDarkMode ? const Color(0xFF4E5D4C) : const Color(0xFFDAF8D6);
static Color get green30 =>
_isDarkMode ? const Color(0xFF80C491) : const Color(0xFF289744);
static Color get textBlue =>
_isDarkMode ? const Color(0xFF3A87FF) : const Color(0xFF0164FF);
static Color get primary20 =>
_isDarkMode
? const Color(0x7386a533).withValues(alpha: 0.2)
: const Color(0xFFE5EFFF);
// Primary color variations
static const Color primary2 = Color(0xFFE5EFFF);
static const Color secondary50 = Color(0xFF34BCCB);
// Green variations (status colors)
static const Color gren0 = Color(0xFFF9FCF8);
static const Color green10 = Color(0xFFE0F0DC);
static const Color gren30 = Color(0xFF289744);
// Red variations (status colors)
static const Color red0 = Color(0xFFF8D6D6);
static const Color red10 = Color(0xFFC02525);
// Other colors
static const Color paleOrange = Color(0xFFfff7ee);
static const Color lightBlue = Color(0xFFe8ecfc);
static const Color cyanAqua = Color(0xFFd6f4f8);
static const Color cyanTeal = Color(0xFF24A6B4);
}
+82
View File
@@ -0,0 +1,82 @@
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'colors.dart';
class ThemeProvider extends ChangeNotifier {
static const String _themeKey = 'theme_mode';
static BuildContext? _context;
bool _isDarkMode = false;
bool get isDarkMode => _isDarkMode;
// Set the app context for rebuilding
static void setContext(BuildContext context) {
_context = context;
}
ThemeProvider() {
_loadThemeFromPrefs();
}
static void _rebuildAllChildren() {
void rebuild(Element el) {
el.markNeedsBuild();
el.visitChildren(rebuild);
}
if (_context != null) {
(_context as Element).visitChildren(rebuild);
}
}
Future<void> _loadThemeFromPrefs() async {
final prefs = await SharedPreferences.getInstance();
_isDarkMode = prefs.getBool(_themeKey) ?? false;
// Update AppColors
AppColors.setDarkMode(_isDarkMode);
// Notify listeners after loading
notifyListeners();
}
Future<void> toggleTheme() async {
_isDarkMode = !_isDarkMode;
// Update AppColors
AppColors.setDarkMode(_isDarkMode);
// Save to preferences
final prefs = await SharedPreferences.getInstance();
await prefs.setBool(_themeKey, _isDarkMode);
// Notify all listeners to rebuild
notifyListeners();
// Force rebuild all children for immediate theme update
_rebuildAllChildren();
}
Future<void> setDarkMode(bool isDark) async {
if (_isDarkMode == isDark) {
return;
}
_isDarkMode = isDark;
// Update AppColors
AppColors.setDarkMode(_isDarkMode);
// Save to preferences
final prefs = await SharedPreferences.getInstance();
await prefs.setBool(_themeKey, _isDarkMode);
// Notify all listeners to rebuild
notifyListeners();
// Force rebuild all children for immediate theme update
_rebuildAllChildren();
}
}