Refactor button color references to use 'primary' instead of 'buttonColor' across multiple files

- Updated AttendanceButtonHelper to rename getButtonColor to getprimary.
- Changed button color references in AttendanceActionButton, ReusableListCard, UserDocumentFilterBottomSheet, and various auth screens to use contentTheme.primary.
- Adjusted color references in employee detail, expense, and directory views to align with the new primary color scheme.
- Removed unused ThemeOption class in UserProfileBar and updated color references accordingly.
- Ensured consistency in color usage for buttons and icons throughout the application.
This commit is contained in:
Vaibhav Surve 2025-10-29 11:29:11 +05:30
parent 04da062f4f
commit 7007a86ac7
25 changed files with 426 additions and 580 deletions

View File

@ -2,38 +2,9 @@ import 'package:flutter/material.dart';
import 'package:marco/helpers/theme/theme_customizer.dart'; import 'package:marco/helpers/theme/theme_customizer.dart';
enum LeftBarThemeType { light, dark } enum LeftBarThemeType { light, dark }
enum ContentThemeType { light, dark } enum ContentThemeType { light, dark }
enum RightBarThemeType { light, dark } enum RightBarThemeType { light, dark }
enum ContentThemeColor {
primary,
secondary,
success,
info,
warning,
danger,
light,
dark,
pink,
red,
brand,
button;
Color get color {
return (AdminTheme.theme.contentTheme.getMappedIntoThemeColor[this]
?['color']) ??
Colors.black;
}
Color get onColor {
return (AdminTheme.theme.contentTheme.getMappedIntoThemeColor[this]
?['onColor']) ??
Colors.white;
}
}
class LeftBarTheme { class LeftBarTheme {
final Color background, onBackground; final Color background, onBackground;
final Color labelColor; final Color labelColor;
@ -50,11 +21,12 @@ class LeftBarTheme {
static final LeftBarTheme lightLeftBarTheme = LeftBarTheme(); static final LeftBarTheme lightLeftBarTheme = LeftBarTheme();
static final LeftBarTheme darkLeftBarTheme = LeftBarTheme( static final LeftBarTheme darkLeftBarTheme = LeftBarTheme(
background: const Color(0xff282c32), background: const Color(0xff282c32),
onBackground: const Color(0xffdcdcdc), onBackground: const Color(0xffdcdcdc),
labelColor: const Color(0xff32BFAE), labelColor: const Color(0xff32BFAE),
activeItemBackground: const Color(0x1532BFAE), activeItemBackground: const Color(0x1532BFAE),
activeItemColor: const Color(0xff32BFAE)); activeItemColor: const Color(0xff32BFAE),
);
static LeftBarTheme getThemeFromType(LeftBarThemeType leftBarThemeType) { static LeftBarTheme getThemeFromType(LeftBarThemeType leftBarThemeType) {
switch (leftBarThemeType) { switch (leftBarThemeType) {
@ -78,8 +50,9 @@ class TopBarTheme {
static final TopBarTheme lightTopBarTheme = TopBarTheme(); static final TopBarTheme lightTopBarTheme = TopBarTheme();
static final TopBarTheme darkTopBarTheme = TopBarTheme( static final TopBarTheme darkTopBarTheme = TopBarTheme(
background: const Color(0xff2c3036), background: const Color(0xff2c3036),
onBackground: const Color(0xffdcdcdc)); onBackground: const Color(0xffdcdcdc),
);
} }
class RightBarTheme { class RightBarTheme {
@ -94,16 +67,40 @@ class RightBarTheme {
}); });
static final RightBarTheme lightRightBarTheme = RightBarTheme( static final RightBarTheme lightRightBarTheme = RightBarTheme(
disabled: const Color(0xffffffff), disabled: const Color(0xffffffff),
onDisabled: const Color(0xffdee2e6), onDisabled: const Color(0xffdee2e6),
activeSwitchBorderColor: const Color(0xff727cf5), activeSwitchBorderColor: const Color(0xff727cf5),
inactiveSwitchBorderColor: const Color(0xffdee2e6)); inactiveSwitchBorderColor: const Color(0xffdee2e6),
);
static final RightBarTheme darkRightBarTheme = RightBarTheme( static final RightBarTheme darkRightBarTheme = RightBarTheme(
disabled: const Color(0xff444d57), disabled: const Color(0xff444d57),
activeSwitchBorderColor: const Color(0xff727cf5), activeSwitchBorderColor: const Color(0xff727cf5),
inactiveSwitchBorderColor: const Color(0xffdee2e6), inactiveSwitchBorderColor: const Color(0xffdee2e6),
onDisabled: const Color(0xff515a65)); onDisabled: const Color(0xff515a65),
);
}
enum ContentThemeColor {
primary,
secondary,
success,
info,
warning,
danger,
light,
dark,
pink,
green,
red;
Color get color {
return (AdminTheme.theme.contentTheme.getMappedIntoThemeColor[this]?['color']) ?? Colors.black;
}
Color get onColor {
return (AdminTheme.theme.contentTheme.getMappedIntoThemeColor[this]?['onColor']) ?? Colors.white;
}
} }
class ContentTheme { class ContentTheme {
@ -117,70 +114,39 @@ class ContentTheme {
final Color info, onInfo; final Color info, onInfo;
final Color light, onLight; final Color light, onLight;
final Color dark, onDark; final Color dark, onDark;
final Color purple, onPurple;
final Color pink, onPink; final Color pink, onPink;
final Color red, onRed; final Color red, onRed;
final Color brandColor, onBrandColor;
final Color buttonColor, onButtonColor;
final Color cardBackground, cardShadow, cardBorder, cardText, cardTextMuted; final Color cardBackground, cardShadow, cardBorder, cardText, cardTextMuted;
final Color title; final Color title;
final Color disabled, onDisabled; final Color disabled, onDisabled;
Map<ContentThemeColor, Map<String, Color>> get getMappedIntoThemeColor {
var c = this;
return {
ContentThemeColor.primary: {'color': c.primary, 'onColor': c.onPrimary},
ContentThemeColor.secondary: {
'color': c.secondary,
'onColor': c.onSecondary
},
ContentThemeColor.success: {'color': c.success, 'onColor': c.onSuccess},
ContentThemeColor.info: {'color': c.info, 'onColor': c.onInfo},
ContentThemeColor.warning: {'color': c.warning, 'onColor': c.onWarning},
ContentThemeColor.danger: {'color': c.danger, 'onColor': c.onDanger},
ContentThemeColor.light: {'color': c.light, 'onColor': c.onLight},
ContentThemeColor.dark: {'color': c.dark, 'onColor': c.onDark},
ContentThemeColor.pink: {'color': c.pink, 'onColor': c.onPink},
ContentThemeColor.red: {'color': c.red, 'onColor': c.onRed},
ContentThemeColor.brand: {
'color': c.brandColor,
'onColor': c.onBrandColor
},
ContentThemeColor.button: {
'color': c.buttonColor,
'onColor': c.onButtonColor
},
};
}
ContentTheme({ ContentTheme({
this.background = const Color(0xfffafbfe), this.background = const Color(0xfffafbfe),
this.onBackground = const Color(0xff313a46), this.onBackground = const Color(0xffF1F1F2),
this.primary = const Color(0xFF49BF3C), this.primary = const Color(0xff663399),
this.onPrimary = Colors.white, this.onPrimary = const Color(0xffffffff),
this.secondary = const Color(0xff6c757d), this.secondary = const Color(0xff6c757d),
this.onSecondary = Colors.white, this.onSecondary = const Color(0xffffffff),
this.success = const Color(0xff00be82), this.success = const Color(0xff00be82),
this.onSuccess = Colors.white, this.onSuccess = const Color(0xffffffff),
this.danger = const Color(0xffdc3545), this.danger = const Color(0xffdc3545),
this.onDanger = Colors.white, this.onDanger = const Color(0xffffffff),
this.warning = const Color(0xffffc107), this.warning = const Color(0xffffc107),
this.onWarning = const Color(0xff313a46), this.onWarning = const Color(0xff313a46),
this.info = const Color(0xff0dcaf0), this.info = const Color(0xff0dcaf0),
this.onInfo = Colors.white, this.onInfo = const Color(0xffffffff),
this.light = const Color(0xffeef2f7), this.light = const Color(0xffeef2f7),
this.onLight = const Color(0xff313a46), this.onLight = const Color(0xff313a46),
this.dark = const Color(0xff313a46), this.dark = const Color(0xff313a46),
this.onDark = Colors.white, this.onDark = const Color(0xffffffff),
this.pink = const Color(0xffFF1087), this.purple = const Color(0xff800080),
this.onPink = Colors.white, this.onPurple = const Color(0xffffffff),
this.red = const Color(0xffFF0000), this.pink = const Color(0xffff1087),
this.onRed = Colors.white, this.onPink = const Color(0xffffffff),
this.brandColor = const Color(0xffff0000), this.red = const Color(0xffff0000),
this.onBrandColor = Colors.white, this.onRed = const Color(0xffffffff),
this.buttonColor = const Color(0xFF2196F3),
this.onButtonColor = Colors.white,
this.cardBackground = const Color(0xffffffff), this.cardBackground = const Color(0xffffffff),
this.cardShadow = const Color(0xffffffff), this.cardShadow = const Color(0xffffffff),
this.cardBorder = const Color(0xffffffff), this.cardBorder = const Color(0xffffffff),
@ -191,55 +157,103 @@ class ContentTheme {
this.onDisabled = const Color(0xffffffff), this.onDisabled = const Color(0xffffffff),
}); });
// copyWith for dynamic updates Map<ContentThemeColor, Map<String, Color>> get getMappedIntoThemeColor {
return {
ContentThemeColor.primary: {'color': primary, 'onColor': onPrimary},
ContentThemeColor.secondary: {'color': secondary, 'onColor': onSecondary},
ContentThemeColor.success: {'color': success, 'onColor': onSuccess},
ContentThemeColor.info: {'color': info, 'onColor': onInfo},
ContentThemeColor.warning: {'color': warning, 'onColor': onWarning},
ContentThemeColor.danger: {'color': danger, 'onColor': onDanger},
ContentThemeColor.light: {'color': light, 'onColor': onLight},
ContentThemeColor.dark: {'color': dark, 'onColor': onDark},
ContentThemeColor.pink: {'color': pink, 'onColor': onPink},
ContentThemeColor.red: {'color': red, 'onColor': onRed},
};
}
ContentTheme copyWith({ ContentTheme copyWith({
Color? primary, Color? primary,
Color? brandColor, Color? onPrimary,
Color? buttonColor, Color? secondary,
Color? onSecondary,
Color? background,
Color? onBackground,
}) { }) {
return ContentTheme( return ContentTheme(
primary: primary ?? this.primary, primary: primary ?? this.primary,
brandColor: brandColor ?? this.brandColor, onPrimary: onPrimary ?? this.onPrimary,
buttonColor: buttonColor ?? this.buttonColor, secondary: secondary ?? this.secondary,
onSecondary: onSecondary ?? this.onSecondary,
background: background ?? this.background,
onBackground: onBackground ?? this.onBackground,
success: success,
onSuccess: onSuccess,
danger: danger,
onDanger: onDanger,
warning: warning,
onWarning: onWarning,
info: info,
onInfo: onInfo,
light: light,
onLight: onLight,
dark: dark,
onDark: onDark,
purple: purple,
onPurple: onPurple,
pink: pink,
onPink: onPink,
red: red,
onRed: onRed,
cardBackground: cardBackground,
cardShadow: cardShadow,
cardBorder: cardBorder,
cardText: cardText,
cardTextMuted: cardTextMuted,
title: title,
disabled: disabled,
onDisabled: onDisabled,
); );
} }
static final ContentTheme lightContentTheme = ContentTheme( static ContentTheme withColorTheme(
primary: Colors.indigo, ColorThemeType colorTheme, {
background: const Color(0xfffafbfe), ThemeMode mode = ThemeMode.light,
onBackground: const Color(0xff313a46), }) {
cardBorder: const Color(0xffe8ecf1), final baseTheme = mode == ThemeMode.light
cardBackground: const Color(0xffffffff), ? ContentTheme()
cardShadow: const Color(0xff9aa1ab), : ContentTheme(
cardText: const Color(0xff6c757d), primary: const Color(0xff32BFAE),
title: const Color(0xff6c757d), background: const Color(0xff343a40),
cardTextMuted: const Color(0xff98a6ad), onBackground: const Color(0xffF1F1F2),
brandColor: const Color(0xffff0000), cardBorder: const Color(0xff464f5b),
onBrandColor: Colors.white, cardBackground: const Color(0xff37404a),
); cardShadow: const Color(0xff01030E),
cardText: const Color(0xffaab8c5),
title: const Color(0xffaab8c5),
cardTextMuted: const Color(0xff8391a2),
);
static final ContentTheme darkContentTheme = ContentTheme( switch (colorTheme) {
primary: Colors.indigo, case ColorThemeType.purple:
background: const Color(0xff343a40), return baseTheme.copyWith(primary: const Color(0xff663399), onPrimary: Colors.white);
onBackground: const Color(0xffF1F1F2), case ColorThemeType.red:
disabled: const Color(0xff444d57), return baseTheme.copyWith(primary: const Color(0xffff0000), onPrimary: Colors.white);
onDisabled: const Color(0xff515a65), case ColorThemeType.green:
cardBorder: const Color(0xff464f5b), return baseTheme.copyWith(primary: const Color(0xff49BF3C), onPrimary: Colors.white);
cardBackground: const Color(0xff37404a), case ColorThemeType.blue:
cardShadow: const Color(0xff01030E), return baseTheme.copyWith(primary: const Color(0xff007bff), onPrimary: Colors.white);
cardText: const Color(0xffaab8c5), }
title: const Color(0xffaab8c5), }
cardTextMuted: const Color(0xff8391a2),
brandColor: const Color(0xffff0000),
onBrandColor: Colors.white,
);
} }
enum ColorThemeType { purple, red, green, blue }
class AdminTheme { class AdminTheme {
final ContentTheme contentTheme;
final LeftBarTheme leftBarTheme; final LeftBarTheme leftBarTheme;
final RightBarTheme rightBarTheme; final RightBarTheme rightBarTheme;
final TopBarTheme topBarTheme; final TopBarTheme topBarTheme;
final ContentTheme contentTheme;
AdminTheme({ AdminTheme({
required this.leftBarTheme, required this.leftBarTheme,
@ -249,42 +263,21 @@ class AdminTheme {
}); });
static AdminTheme theme = AdminTheme( static AdminTheme theme = AdminTheme(
leftBarTheme: LeftBarTheme.lightLeftBarTheme, leftBarTheme: LeftBarTheme.lightLeftBarTheme,
topBarTheme: TopBarTheme.lightTopBarTheme, topBarTheme: TopBarTheme.lightTopBarTheme,
rightBarTheme: RightBarTheme.lightRightBarTheme, rightBarTheme: RightBarTheme.lightRightBarTheme,
contentTheme: ContentTheme.lightContentTheme); contentTheme: ContentTheme.withColorTheme(ColorThemeType.purple, mode: ThemeMode.light),
);
static void setTheme() { static void setTheme() {
theme = AdminTheme( final themeMode = ThemeCustomizer.instance.theme;
leftBarTheme: ThemeCustomizer.instance.theme == ThemeMode.dark final colorTheme = ThemeCustomizer.instance.colorTheme;
? LeftBarTheme.darkLeftBarTheme
: LeftBarTheme.lightLeftBarTheme,
topBarTheme: ThemeCustomizer.instance.theme == ThemeMode.dark
? TopBarTheme.darkTopBarTheme
: TopBarTheme.lightTopBarTheme,
rightBarTheme: ThemeCustomizer.instance.theme == ThemeMode.dark
? RightBarTheme.darkRightBarTheme
: RightBarTheme.lightRightBarTheme,
contentTheme: ThemeCustomizer.instance.theme == ThemeMode.dark
? ContentTheme.darkContentTheme
: ContentTheme.lightContentTheme);
}
// Dynamic theme color update
static void updateThemeColors({
Color? primary,
Color? brandColor,
Color? buttonColor,
}) {
theme = AdminTheme( theme = AdminTheme(
leftBarTheme: theme.leftBarTheme, leftBarTheme: themeMode == ThemeMode.dark ? LeftBarTheme.darkLeftBarTheme : LeftBarTheme.lightLeftBarTheme,
topBarTheme: theme.topBarTheme, topBarTheme: themeMode == ThemeMode.dark ? TopBarTheme.darkTopBarTheme : TopBarTheme.lightTopBarTheme,
rightBarTheme: theme.rightBarTheme, rightBarTheme: themeMode == ThemeMode.dark ? RightBarTheme.darkRightBarTheme : RightBarTheme.lightRightBarTheme,
contentTheme: theme.contentTheme.copyWith( contentTheme: ContentTheme.withColorTheme(colorTheme, mode: themeMode),
primary: primary,
brandColor: brandColor,
buttonColor: buttonColor,
),
); );
} }
} }

View File

@ -24,7 +24,7 @@ class ThemeCustomizer {
ThemeMode leftBarTheme = ThemeMode.light; ThemeMode leftBarTheme = ThemeMode.light;
ThemeMode rightBarTheme = ThemeMode.light; ThemeMode rightBarTheme = ThemeMode.light;
ThemeMode topBarTheme = ThemeMode.light; ThemeMode topBarTheme = ThemeMode.light;
ColorThemeType colorTheme = ColorThemeType.purple;
bool rightBarOpen = false; bool rightBarOpen = false;
bool leftBarCondensed = false; bool leftBarCondensed = false;
@ -73,6 +73,11 @@ class ThemeCustomizer {
} }
} }
/// Public method to trigger theme updates externally
static void applyThemeChange() {
_notify();
}
static void notify() { static void notify() {
for (var value in _notifier) { for (var value in _notifier) {
value(oldInstance, instance); value(oldInstance, instance);

View File

@ -3,32 +3,53 @@ import 'package:get/get.dart';
import 'package:marco/helpers/widgets/my_text.dart'; import 'package:marco/helpers/widgets/my_text.dart';
import 'package:marco/helpers/widgets/wave_background.dart'; import 'package:marco/helpers/widgets/wave_background.dart';
import 'package:marco/helpers/theme/admin_theme.dart'; import 'package:marco/helpers/theme/admin_theme.dart';
import 'package:marco/helpers/theme/theme_customizer.dart';
class ThemeOption { class ThemeOption {
final String label; final String label;
final Color primary; final Color primary;
final Color button; final Color button;
final Color brand; final Color brand;
final ColorThemeType colorThemeType;
ThemeOption(this.label, this.primary, this.button, this.brand); ThemeOption(
this.label, this.primary, this.button, this.brand, this.colorThemeType);
} }
// Define your themes
final List<ThemeOption> themeOptions = [ final List<ThemeOption> themeOptions = [
ThemeOption("Theme 1", Colors.red, Colors.red, Colors.red), ThemeOption(
ThemeOption("Theme 2", const Color(0xFF49BF3C), const Color(0xFF49BF3C), const Color(0xFF49BF3C)), "Theme 1", Colors.red, Colors.red, Colors.red, ColorThemeType.red),
ThemeOption("Theme 3", const Color(0xFF3F51B5), const Color(0xFF3F51B5), const Color(0xFF3F51B5)), ThemeOption(
ThemeOption("Theme 4", const Color(0xFF40B7FF), const Color(0xFF40B7FF), const Color(0xFF40B7FF)), "Theme 2",
const Color(0xFF49BF3C),
const Color(0xFF49BF3C),
const Color(0xFF49BF3C),
ColorThemeType.green,
),
ThemeOption(
"Theme 3",
const Color(0xFF3F51B5),
const Color(0xFF3F51B5),
const Color(0xFF3F51B5),
ColorThemeType.blue,
),
ThemeOption(
"Theme 4",
const Color(0xFF663399),
const Color(0xFF663399),
const Color(0xFF663399),
ColorThemeType.purple,
),
]; ];
// Reactive controller
class ThemeController extends GetxController { class ThemeController extends GetxController {
RxInt selectedIndex = 0.obs; RxInt selectedIndex = 0.obs;
RxBool showApplied = false.obs; RxBool showApplied = false.obs;
void init() { void init() {
final currentPrimary = AdminTheme.theme.contentTheme.primary; final currentPrimary = AdminTheme.theme.contentTheme.primary;
int index = themeOptions.indexWhere((opt) => opt.primary.value == currentPrimary.value); int index = themeOptions
.indexWhere((opt) => opt.primary.value == currentPrimary.value);
selectedIndex.value = index == -1 ? 0 : index; selectedIndex.value = index == -1 ? 0 : index;
} }
@ -36,42 +57,48 @@ class ThemeController extends GetxController {
selectedIndex.value = index; selectedIndex.value = index;
showApplied.value = true; showApplied.value = true;
// Update AdminTheme ThemeCustomizer.instance.colorTheme = themeOptions[index].colorThemeType;
AdminTheme.updateThemeColors(
primary: themeOptions[index].primary, ThemeCustomizer.applyThemeChange();
buttonColor: themeOptions[index].button,
brandColor: themeOptions[index].brand,
);
await Future.delayed(const Duration(milliseconds: 600)); await Future.delayed(const Duration(milliseconds: 600));
showApplied.value = false; showApplied.value = false;
} }
} }
// Theme Editor Widget class ThemeEditorWidget extends StatefulWidget {
class ThemeEditorWidget extends StatelessWidget {
final VoidCallback onClose; final VoidCallback onClose;
ThemeEditorWidget({Key? key, required this.onClose}) : super(key: key);
const ThemeEditorWidget({super.key, required this.onClose});
@override
_ThemeEditorWidgetState createState() => _ThemeEditorWidgetState();
}
class _ThemeEditorWidgetState extends State<ThemeEditorWidget> {
final ThemeController themeController = Get.put(ThemeController()); final ThemeController themeController = Get.put(ThemeController());
@override @override
Widget build(BuildContext context) { void initState() {
super.initState();
themeController.init(); themeController.init();
}
@override
Widget build(BuildContext context) {
return Padding( return Padding(
padding: const EdgeInsets.all(12), padding: const EdgeInsets.all(12),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
// Header // Header row with title and close button
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
MyText.bodyLarge("Theme Customization", fontWeight: 600), MyText.bodyLarge("Theme Customization", fontWeight: 600),
IconButton( IconButton(
icon: const Icon(Icons.close), icon: const Icon(Icons.close),
onPressed: onClose, onPressed: widget.onClose,
tooltip: "Back", tooltip: "Back",
iconSize: 20, iconSize: 20,
), ),
@ -79,130 +106,56 @@ class ThemeEditorWidget extends StatelessWidget {
), ),
const SizedBox(height: 12), const SizedBox(height: 12),
// Theme Cards // Theme cards wrapped in reactive Obx widget
Center( Center(
child: Obx(() => Wrap( child: Obx(
spacing: 12, () => Wrap(
runSpacing: 12, spacing: 12,
alignment: WrapAlignment.center, runSpacing: 12,
children: List.generate(themeOptions.length, (i) { alignment: WrapAlignment.center,
final theme = themeOptions[i]; children: List.generate(themeOptions.length, (i) {
final isSelected = themeController.selectedIndex.value == i; return ThemeCard(
themeOption: themeOptions[i],
return SizedBox( isSelected: themeController.selectedIndex.value == i,
width: 80,
child: GestureDetector(
onTap: () => themeController.applyTheme(i), onTap: () => themeController.applyTheme(i),
child: AnimatedContainer( );
duration: const Duration(milliseconds: 250), }),
curve: Curves.easeInOut, ),
padding: const EdgeInsets.all(6), ),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: isSelected ? theme.brand : Colors.transparent,
width: 2,
),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 4,
offset: const Offset(0, 2),
),
],
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
height: 80,
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Stack(
fit: StackFit.expand,
children: [
CustomPaint(
painter: RedWavePainter(theme.brand, 0.15),
),
Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
"Hello, User!",
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.w600,
color: theme.primary,
fontSize: 12,
),
),
const SizedBox(height: 4),
SizedBox(
height: 18,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: theme.button,
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4),
),
elevation: 1,
textStyle: const TextStyle(fontSize: 10),
),
onPressed: () {},
child: const Text("Welcome"),
),
),
],
),
),
],
),
),
),
const SizedBox(height: 6),
Text(
theme.label,
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 12,
color: Colors.grey[700],
),
),
],
),
),
),
);
}),
)),
), ),
const SizedBox(height: 12), const SizedBox(height: 12),
// Applied Indicator // Applied indicator reactive widget
Obx(() => themeController.showApplied.value Obx(
? Padding( () => themeController.showApplied.value
padding: const EdgeInsets.only(top: 10), ? Padding(
child: Row( padding: const EdgeInsets.only(top: 10),
mainAxisAlignment: MainAxisAlignment.center, child: Row(
children: [ mainAxisAlignment: MainAxisAlignment.center,
Icon(Icons.check_circle, children: [
color: themeOptions[themeController.selectedIndex.value].brand, size: 20), Icon(
const SizedBox(width: 6), Icons.check_circle,
Text( color:
"Theme Applied!", themeOptions[themeController.selectedIndex.value]
style: TextStyle( .brand,
color: themeOptions[themeController.selectedIndex.value].brand, size: 20,
fontWeight: FontWeight.w700,
), ),
), const SizedBox(width: 6),
], Text(
), "Theme Applied!",
) style: TextStyle(
: const SizedBox()), color: themeOptions[
themeController.selectedIndex.value]
.brand,
fontWeight: FontWeight.w700,
),
),
],
),
)
: const SizedBox(),
),
const SizedBox(height: 16), const SizedBox(height: 16),
const Text( const Text(
@ -214,3 +167,105 @@ class ThemeEditorWidget extends StatelessWidget {
); );
} }
} }
class ThemeCard extends StatelessWidget {
final ThemeOption themeOption;
final bool isSelected;
final VoidCallback onTap;
const ThemeCard({
Key? key,
required this.themeOption,
required this.isSelected,
required this.onTap,
});
@override
Widget build(BuildContext context) {
return SizedBox(
width: 80,
child: Material(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
elevation: isSelected ? 4 : 1,
child: InkWell(
borderRadius: BorderRadius.circular(12),
onTap: onTap,
child: AnimatedContainer(
duration: const Duration(milliseconds: 250),
curve: Curves.easeInOut,
padding: const EdgeInsets.all(6),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: isSelected ? themeOption.brand : Colors.transparent,
width: 2,
),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
height: 80,
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Stack(
fit: StackFit.expand,
children: [
CustomPaint(
painter: RedWavePainter(themeOption.brand, 0.15)),
Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
"Hello, User!",
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.w600,
color: themeOption.primary,
fontSize: 12,
),
),
const SizedBox(height: 4),
SizedBox(
height: 18,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: themeOption.button,
padding: const EdgeInsets.symmetric(
horizontal: 8, vertical: 0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4),
),
elevation: 1,
textStyle: const TextStyle(fontSize: 10),
),
onPressed: () {},
child: const Text("Welcome"),
),
),
],
),
),
],
),
),
),
const SizedBox(height: 6),
Text(
themeOption.label,
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 12,
color: Colors.grey[700],
),
),
],
),
),
),
),
);
}
}

View File

@ -95,7 +95,7 @@ class AttendanceButtonHelper {
} }
} }
static Color getButtonColor({ static Color getprimary({
required bool isYesterday, required bool isYesterday,
required bool isTodayApproved, required bool isTodayApproved,
required int activity, required int activity,

View File

@ -235,7 +235,7 @@ class _AttendanceActionButtonState extends State<AttendanceActionButton> {
isTodayApproved: isTodayApproved, isTodayApproved: isTodayApproved,
); );
final buttonColor = AttendanceButtonHelper.getButtonColor( final primary = AttendanceButtonHelper.getprimary(
isYesterday: isYesterday, isYesterday: isYesterday,
isTodayApproved: isTodayApproved, isTodayApproved: isTodayApproved,
activity: emp.activity, activity: emp.activity,
@ -245,7 +245,7 @@ class _AttendanceActionButtonState extends State<AttendanceActionButton> {
isUploading: isUploading, isUploading: isUploading,
isButtonDisabled: isButtonDisabled, isButtonDisabled: isButtonDisabled,
buttonText: buttonText, buttonText: buttonText,
buttonColor: buttonColor, primary: primary,
onPressed: isButtonDisabled ? null : _handleButtonPressed, onPressed: isButtonDisabled ? null : _handleButtonPressed,
); );
}); });
@ -256,7 +256,7 @@ class AttendanceActionButtonUI extends StatelessWidget {
final bool isUploading; final bool isUploading;
final bool isButtonDisabled; final bool isButtonDisabled;
final String buttonText; final String buttonText;
final Color buttonColor; final Color primary;
final VoidCallback? onPressed; final VoidCallback? onPressed;
const AttendanceActionButtonUI({ const AttendanceActionButtonUI({
@ -264,7 +264,7 @@ class AttendanceActionButtonUI extends StatelessWidget {
required this.isUploading, required this.isUploading,
required this.isButtonDisabled, required this.isButtonDisabled,
required this.buttonText, required this.buttonText,
required this.buttonColor, required this.primary,
required this.onPressed, required this.onPressed,
}); });
@ -275,7 +275,7 @@ class AttendanceActionButtonUI extends StatelessWidget {
child: ElevatedButton( child: ElevatedButton(
onPressed: onPressed, onPressed: onPressed,
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: buttonColor, backgroundColor: primary,
padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 12), padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 12),
textStyle: const TextStyle(fontSize: 12), textStyle: const TextStyle(fontSize: 12),
), ),

View File

@ -15,7 +15,7 @@ class ReusableListCard<T> extends StatelessWidget {
final String Function(T item)? getOutTimeText; final String Function(T item)? getOutTimeText;
final bool Function(T item)? isUploading; final bool Function(T item)? isUploading;
final String Function(T item)? getButtonText; final String Function(T item)? getButtonText;
final Color Function(String buttonText)? getButtonColor; final Color Function(String buttonText)? getprimary;
const ReusableListCard({ const ReusableListCard({
Key? key, Key? key,
@ -30,7 +30,7 @@ class ReusableListCard<T> extends StatelessWidget {
this.getOutTimeText, this.getOutTimeText,
this.isUploading, this.isUploading,
this.getButtonText, this.getButtonText,
this.getButtonColor, this.getprimary,
}) : super(key: key); }) : super(key: key);
@override @override
@ -47,8 +47,8 @@ class ReusableListCard<T> extends StatelessWidget {
final item = items[index]; final item = items[index];
final buttonText = getButtonText?.call(item) ?? 'Action'; final buttonText = getButtonText?.call(item) ?? 'Action';
final uploading = isUploading?.call(item) ?? false; final uploading = isUploading?.call(item) ?? false;
final buttonColor = final primary =
getButtonColor?.call(buttonText) ?? Theme.of(context).primaryColor; getprimary?.call(buttonText) ?? Theme.of(context).primaryColor;
return Column( return Column(
children: [ children: [
@ -121,7 +121,7 @@ class ReusableListCard<T> extends StatelessWidget {
? null ? null
: () => onActionPressed(item), : () => onActionPressed(item),
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: buttonColor, backgroundColor: primary,
padding: const EdgeInsets.symmetric(horizontal: 12), padding: const EdgeInsets.symmetric(horizontal: 12),
textStyle: const TextStyle(fontSize: 12), textStyle: const TextStyle(fontSize: 12),
), ),

View File

@ -101,7 +101,7 @@ class UserDocumentFilterBottomSheet extends StatelessWidget with UIMixin {
vertical: 10), vertical: 10),
decoration: BoxDecoration( decoration: BoxDecoration(
color: docController.isUploadedAt.value color: docController.isUploadedAt.value
? contentTheme.buttonColor ? contentTheme.primary
: Colors.transparent, : Colors.transparent,
borderRadius: borderRadius:
const BorderRadius.horizontal( const BorderRadius.horizontal(
@ -132,7 +132,7 @@ class UserDocumentFilterBottomSheet extends StatelessWidget with UIMixin {
vertical: 10), vertical: 10),
decoration: BoxDecoration( decoration: BoxDecoration(
color: !docController.isUploadedAt.value color: !docController.isUploadedAt.value
? contentTheme.buttonColor ? contentTheme.primary
: Colors.transparent, : Colors.transparent,
borderRadius: borderRadius:
const BorderRadius.horizontal( const BorderRadius.horizontal(
@ -265,7 +265,7 @@ class UserDocumentFilterBottomSheet extends StatelessWidget with UIMixin {
onChanged: (val) => onChanged: (val) =>
docController.isVerified.value = val, docController.isVerified.value = val,
activeColor: activeColor:
contentTheme.buttonColor, contentTheme.primary,
materialTapTargetSize: materialTapTargetSize:
MaterialTapTargetSize.shrinkWrap, MaterialTapTargetSize.shrinkWrap,
), ),

View File

@ -94,7 +94,7 @@ class _EmailLoginFormState extends State<EmailLoginForm> with UIMixin {
MaterialStateProperty.resolveWith<Color>( MaterialStateProperty.resolveWith<Color>(
(states) => (states) =>
states.contains(WidgetState.selected) states.contains(WidgetState.selected)
? contentTheme.brandColor ? contentTheme.primary
: Colors.white, : Colors.white,
), ),
checkColor: contentTheme.onPrimary, checkColor: contentTheme.onPrimary,
@ -132,7 +132,7 @@ class _EmailLoginFormState extends State<EmailLoginForm> with UIMixin {
elevation: 2, elevation: 2,
padding: MySpacing.xy(80, 16), padding: MySpacing.xy(80, 16),
borderRadiusAll: 10, borderRadiusAll: 10,
backgroundColor: contentTheme.brandColor, backgroundColor: contentTheme.primary,
child: MyText.labelLarge( child: MyText.labelLarge(
isLoading ? 'Logging in...' : 'Login', isLoading ? 'Logging in...' : 'Login',
fontWeight: 700, fontWeight: 700,

View File

@ -60,7 +60,7 @@ class _ForgotPasswordScreenState extends State<ForgotPasswordScreen>
return Scaffold( return Scaffold(
body: Stack( body: Stack(
children: [ children: [
RedWaveBackground(brandRed: contentTheme.brandColor), RedWaveBackground(brandRed: contentTheme.primary),
SafeArea( SafeArea(
child: Center( child: Center(
child: Column( child: Column(
@ -231,8 +231,8 @@ class _ForgotPasswordScreenState extends State<ForgotPasswordScreen>
padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 16), padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 16),
borderRadiusAll: 10, borderRadiusAll: 10,
backgroundColor: _isLoading backgroundColor: _isLoading
? contentTheme.brandColor.withOpacity(0.6) ? contentTheme.primary.withOpacity(0.6)
: contentTheme.brandColor, : contentTheme.primary,
child: _isLoading child: _isLoading
? const SizedBox( ? const SizedBox(
height: 20, height: 20,
@ -254,10 +254,10 @@ class _ForgotPasswordScreenState extends State<ForgotPasswordScreen>
Widget _buildBackButton() { Widget _buildBackButton() {
return TextButton.icon( return TextButton.icon(
onPressed: () async => await LocalStorage.logout(), onPressed: () async => await LocalStorage.logout(),
icon: Icon(Icons.arrow_back, size: 18, color: contentTheme.brandColor,), icon: Icon(Icons.arrow_back, size: 18, color: contentTheme.primary,),
label: MyText.bodyMedium( label: MyText.bodyMedium(
'Back to Login', 'Back to Login',
color: contentTheme.brandColor, color: contentTheme.primary,
fontWeight: 600, fontWeight: 600,
fontSize: 14, fontSize: 14,
), ),

View File

@ -102,7 +102,7 @@ class _WelcomeScreenState extends State<WelcomeScreen>
return Scaffold( return Scaffold(
body: Stack( body: Stack(
children: [ children: [
RedWaveBackground(brandRed: contentTheme.brandColor), RedWaveBackground(brandRed: contentTheme.primary),
SafeArea( SafeArea(
child: Center( child: Center(
child: SingleChildScrollView( child: SingleChildScrollView(
@ -235,7 +235,7 @@ class _WelcomeScreenState extends State<WelcomeScreen>
), ),
), ),
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: contentTheme.brandColor, backgroundColor: contentTheme.primary,
foregroundColor: Colors.white, foregroundColor: Colors.white,
shape: shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(14)), RoundedRectangleBorder(borderRadius: BorderRadius.circular(14)),

View File

@ -53,7 +53,7 @@ class _MPINAuthScreenState extends State<MPINAuthScreen>
return Scaffold( return Scaffold(
body: Stack( body: Stack(
children: [ children: [
RedWaveBackground(brandRed: contentTheme.brandColor), RedWaveBackground(brandRed: contentTheme.primary),
SafeArea( SafeArea(
child: Center( child: Center(
child: Column( child: Column(
@ -283,8 +283,8 @@ class _MPINAuthScreenState extends State<MPINAuthScreen>
padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16), padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16),
borderRadiusAll: 10, borderRadiusAll: 10,
backgroundColor: controller.isLoading.value backgroundColor: controller.isLoading.value
? contentTheme.brandColor.withOpacity(0.6) ? contentTheme.primary.withOpacity(0.6)
: contentTheme.brandColor, : contentTheme.primary,
child: controller.isLoading.value child: controller.isLoading.value
? const SizedBox( ? const SizedBox(
height: 20, height: 20,
@ -318,10 +318,10 @@ class _MPINAuthScreenState extends State<MPINAuthScreen>
TextButton.icon( TextButton.icon(
onPressed: () => Get.toNamed('/dashboard'), onPressed: () => Get.toNamed('/dashboard'),
icon: Icon(Icons.arrow_back, icon: Icon(Icons.arrow_back,
size: 18, color: contentTheme.brandColor), size: 18, color: contentTheme.primary),
label: MyText.bodyMedium( label: MyText.bodyMedium(
'Back to Home Page', 'Back to Home Page',
color: contentTheme.brandColor, color: contentTheme.primary,
fontWeight: 600, fontWeight: 600,
fontSize: 14, fontSize: 14,
), ),
@ -333,7 +333,7 @@ class _MPINAuthScreenState extends State<MPINAuthScreen>
size: 18, color: Colors.redAccent), size: 18, color: Colors.redAccent),
label: MyText.bodyMedium( label: MyText.bodyMedium(
'Go back to Login Screen', 'Go back to Login Screen',
color: contentTheme.brandColor, color: contentTheme.primary,
fontWeight: 600, fontWeight: 600,
fontSize: 14, fontSize: 14,
), ),

View File

@ -81,7 +81,7 @@ class _OTPLoginScreenState extends State<OTPLoginScreen> with UIMixin {
elevation: 2, elevation: 2,
padding: MySpacing.xy(24, 16), padding: MySpacing.xy(24, 16),
borderRadiusAll: 10, borderRadiusAll: 10,
backgroundColor: isDisabled ? Colors.grey : contentTheme.brandColor, backgroundColor: isDisabled ? Colors.grey : contentTheme.primary,
child: controller.isSending.value child: controller.isSending.value
? SizedBox( ? SizedBox(
width: 20, width: 20,
@ -170,7 +170,7 @@ class _OTPLoginScreenState extends State<OTPLoginScreen> with UIMixin {
), ),
focusedBorder: OutlineInputBorder( focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(color: contentTheme.brandColor, width: 2), borderSide: BorderSide(color: contentTheme.primary, width: 2),
), ),
), ),
), ),
@ -220,7 +220,7 @@ class _OTPLoginScreenState extends State<OTPLoginScreen> with UIMixin {
elevation: 2, elevation: 2,
padding: MySpacing.xy(24, 16), padding: MySpacing.xy(24, 16),
borderRadiusAll: 10, borderRadiusAll: 10,
backgroundColor: contentTheme.brandColor, backgroundColor: contentTheme.primary,
child: MyText.labelMedium( child: MyText.labelMedium(
'Verify OTP', 'Verify OTP',
fontWeight: 600, fontWeight: 600,

View File

@ -182,10 +182,10 @@ class _OrganizationFormState extends State<_OrganizationForm> with UIMixin {
setState(() => _agreed = val ?? false), setState(() => _agreed = val ?? false),
fillColor: MaterialStateProperty.resolveWith( fillColor: MaterialStateProperty.resolveWith(
(states) => states.contains(MaterialState.selected) (states) => states.contains(MaterialState.selected)
? contentTheme.brandColor ? contentTheme.primary
: Colors.white), : Colors.white),
checkColor: Colors.white, checkColor: Colors.white,
side: BorderSide(color: contentTheme.brandColor, width: 2), side: BorderSide(color: contentTheme.primary, width: 2),
), ),
Flexible( Flexible(
child: Wrap( child: Wrap(
@ -196,7 +196,7 @@ class _OrganizationFormState extends State<_OrganizationForm> with UIMixin {
), ),
MyText( MyText(
'privacy policy & terms', 'privacy policy & terms',
color: contentTheme.brandColor, color: contentTheme.primary,
fontWeight: 600, fontWeight: 600,
), ),
], ],
@ -249,7 +249,7 @@ class _OrganizationFormState extends State<_OrganizationForm> with UIMixin {
fontWeight: 600, fontWeight: 600,
), ),
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: contentTheme.buttonColor, backgroundColor: contentTheme.primary,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
), ),
@ -266,12 +266,12 @@ class _OrganizationFormState extends State<_OrganizationForm> with UIMixin {
icon: Icon( icon: Icon(
Icons.arrow_back, Icons.arrow_back,
size: 18, size: 18,
color: contentTheme.brandColor, color: contentTheme.primary,
), ),
label: MyText.bodySmall( label: MyText.bodySmall(
'Back to log in', 'Back to log in',
fontWeight: 600, fontWeight: 600,
color: contentTheme.brandColor, color: contentTheme.primary,
), ),
), ),
), ),
@ -334,7 +334,7 @@ class _OrganizationFormState extends State<_OrganizationForm> with UIMixin {
), ),
focusedBorder: OutlineInputBorder( focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(color: contentTheme.brandColor, width: 1.5), borderSide: BorderSide(color: contentTheme.primary, width: 1.5),
), ),
errorBorder: OutlineInputBorder( errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
@ -411,7 +411,7 @@ class _OrganizationFormState extends State<_OrganizationForm> with UIMixin {
focusedBorder: OutlineInputBorder( focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
borderSide: borderSide:
BorderSide(color: contentTheme.brandColor, width: 1.5), BorderSide(color: contentTheme.primary, width: 1.5),
), ),
errorText: fieldState.errorText, errorText: fieldState.errorText,
), ),

View File

@ -127,7 +127,7 @@ class _DirectoryViewState extends State<DirectoryView> with UIMixin {
child: ElevatedButton( child: ElevatedButton(
onPressed: () => Navigator.pop(context, true), onPressed: () => Navigator.pop(context, true),
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: contentTheme.buttonColor, backgroundColor: contentTheme.primary,
foregroundColor: Colors.white, foregroundColor: Colors.white,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5), borderRadius: BorderRadius.circular(5),
@ -173,7 +173,7 @@ class _DirectoryViewState extends State<DirectoryView> with UIMixin {
backgroundColor: Colors.grey[100], backgroundColor: Colors.grey[100],
floatingActionButton: FloatingActionButton.extended( floatingActionButton: FloatingActionButton.extended(
heroTag: 'createContact', heroTag: 'createContact',
backgroundColor: contentTheme.buttonColor, backgroundColor: contentTheme.primary,
onPressed: _handleCreateContact, onPressed: _handleCreateContact,
icon: const Icon(Icons.person_add_alt_1, color: Colors.white), icon: const Icon(Icons.person_add_alt_1, color: Colors.white),
label: const Text("Add Contact", style: TextStyle(color: Colors.white)), label: const Text("Add Contact", style: TextStyle(color: Colors.white)),
@ -325,7 +325,7 @@ class _DirectoryViewState extends State<DirectoryView> with UIMixin {
SizedBox(width: 10), SizedBox(width: 10),
Expanded(child: Text("Create Bucket")), Expanded(child: Text("Create Bucket")),
Icon(Icons.chevron_right, Icon(Icons.chevron_right,
size: 20, color: contentTheme.buttonColor), size: 20, color: contentTheme.primary),
], ],
), ),
onTap: () { onTap: () {
@ -358,7 +358,7 @@ class _DirectoryViewState extends State<DirectoryView> with UIMixin {
SizedBox(width: 10), SizedBox(width: 10),
Expanded(child: Text("Manage Buckets")), Expanded(child: Text("Manage Buckets")),
Icon(Icons.chevron_right, Icon(Icons.chevron_right,
size: 20, color: contentTheme.buttonColor), size: 20, color: contentTheme.primary),
], ],
), ),
onTap: () { onTap: () {
@ -395,7 +395,7 @@ class _DirectoryViewState extends State<DirectoryView> with UIMixin {
child: Text('Show Deleted Contacts')), child: Text('Show Deleted Contacts')),
Switch.adaptive( Switch.adaptive(
value: !controller.isActive.value, value: !controller.isActive.value,
activeColor: contentTheme.buttonColor, activeColor: contentTheme.primary,
onChanged: (val) { onChanged: (val) {
controller.isActive.value = !val; controller.isActive.value = !val;
controller.fetchContacts(active: !val); controller.fetchContacts(active: !val);

View File

@ -135,7 +135,7 @@ class _NotesViewState extends State<NotesView> with UIMixin {
if (note.isActive) ...[ if (note.isActive) ...[
IconButton( IconButton(
icon: Icon(isEditing ? Icons.close : Icons.edit, icon: Icon(isEditing ? Icons.close : Icons.edit,
color: contentTheme.buttonColor, size: 18), color: contentTheme.primary, size: 18),
splashRadius: 18, splashRadius: 18,
onPressed: () { onPressed: () {
controller.editingNoteId.value = controller.editingNoteId.value =
@ -224,7 +224,7 @@ class _NotesViewState extends State<NotesView> with UIMixin {
fontWeight: 600, fontWeight: 600,
), ),
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: contentTheme.buttonColor, backgroundColor: contentTheme.primary,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
), ),

View File

@ -397,7 +397,7 @@ class _UserDocumentsPageState extends State<UserDocumentsPage> with UIMixin {
const Expanded(child: Text('Show Deleted Documents')), const Expanded(child: Text('Show Deleted Documents')),
Switch.adaptive( Switch.adaptive(
value: docController.showInactive.value, value: docController.showInactive.value,
activeColor: contentTheme.buttonColor, activeColor: contentTheme.primary,
onChanged: (val) { onChanged: (val) {
docController.showInactive.value = val; docController.showInactive.value = val;
docController.fetchDocuments( docController.fetchDocuments(
@ -616,7 +616,7 @@ class _UserDocumentsPageState extends State<UserDocumentsPage> with UIMixin {
color: Colors.white, color: Colors.white,
fontWeight: 600, fontWeight: 600,
), ),
backgroundColor: contentTheme.buttonColor, backgroundColor: contentTheme.primary,
) )
: SizedBox.shrink(); : SizedBox.shrink();
}), }),

View File

@ -254,7 +254,7 @@ class _EmployeeDetailPageState extends State<EmployeeDetailPage> with UIMixin {
), ),
IconButton( IconButton(
icon: icon:
Icon(Icons.edit, size: 24, color: contentTheme.buttonColor), Icon(Icons.edit, size: 24, color: contentTheme.primary),
onPressed: () async { onPressed: () async {
final result = final result =
await showModalBottomSheet<Map<String, dynamic>>( await showModalBottomSheet<Map<String, dynamic>>(
@ -315,7 +315,7 @@ class _EmployeeDetailPageState extends State<EmployeeDetailPage> with UIMixin {
), ),
); );
}, },
backgroundColor: contentTheme.buttonColor, backgroundColor: contentTheme.primary,
icon: const Icon(Icons.assignment), icon: const Icon(Icons.assignment),
label: const Text( label: const Text(
'Assign to Project', 'Assign to Project',

View File

@ -267,7 +267,7 @@ class _EmployeesScreenState extends State<EmployeesScreen> with UIMixin {
child: Container( child: Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
decoration: BoxDecoration( decoration: BoxDecoration(
color: contentTheme.buttonColor, color: contentTheme.primary,
borderRadius: BorderRadius.circular(28), borderRadius: BorderRadius.circular(28),
boxShadow: const [ boxShadow: const [
BoxShadow( BoxShadow(
@ -426,11 +426,11 @@ class _EmployeesScreenState extends State<EmployeesScreen> with UIMixin {
value: _employeeController.isAllEmployeeSelected.value, value: _employeeController.isAllEmployeeSelected.value,
onChanged: (_) => Navigator.pop(context, 'all_employees'), onChanged: (_) => Navigator.pop(context, 'all_employees'),
checkColor: Colors.white, checkColor: Colors.white,
activeColor: contentTheme.buttonColor, activeColor: contentTheme.primary,
side: const BorderSide(color: Colors.black, width: 1.5), side: const BorderSide(color: Colors.black, width: 1.5),
fillColor: MaterialStateProperty.resolveWith<Color>( fillColor: MaterialStateProperty.resolveWith<Color>(
(states) => states.contains(MaterialState.selected) (states) => states.contains(MaterialState.selected)
? contentTheme.buttonColor ? contentTheme.primary
: Colors.white), : Colors.white),
), ),
const Text('All Employees'), const Text('All Employees'),

View File

@ -196,7 +196,7 @@ final permissionController = Get.put(PermissionController());
await showAddExpenseBottomSheet(isEdit: true); await showAddExpenseBottomSheet(isEdit: true);
await controller.fetchExpenseDetails(); await controller.fetchExpenseDetails();
}, },
backgroundColor: contentTheme.buttonColor, backgroundColor: contentTheme.primary,
icon: const Icon(Icons.edit), icon: const Icon(Icons.edit),
label: MyText.bodyMedium( label: MyText.bodyMedium(
"Edit Expense", fontWeight: 600, color: Colors.white), "Edit Expense", fontWeight: 600, color: Colors.white),
@ -257,10 +257,10 @@ final permissionController = Get.put(PermissionController());
Widget _statusButton(BuildContext context, ExpenseDetailController controller, Widget _statusButton(BuildContext context, ExpenseDetailController controller,
ExpenseDetailModel expense, dynamic next) { ExpenseDetailModel expense, dynamic next) {
Color buttonColor = Colors.red; Color primary = Colors.red;
if (next.color.isNotEmpty) { if (next.color.isNotEmpty) {
try { try {
buttonColor = Color(int.parse(next.color.replaceFirst('#', '0xff'))); primary = Color(int.parse(next.color.replaceFirst('#', '0xff')));
} catch (_) {} } catch (_) {}
} }
DateTime onlyDate(DateTime date) { DateTime onlyDate(DateTime date) {
@ -271,7 +271,7 @@ final permissionController = Get.put(PermissionController());
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
minimumSize: const Size(100, 40), minimumSize: const Size(100, 40),
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12), padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12),
backgroundColor: buttonColor, backgroundColor: primary,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5)), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5)),
), ),
onPressed: () async { onPressed: () async {

View File

@ -46,7 +46,7 @@ class _ExpenseFilterBottomSheetState extends State<ExpenseFilterBottomSheet>
Get.back(); Get.back();
}, },
submitText: 'Submit', submitText: 'Submit',
submitColor: contentTheme.buttonColor, submitColor: contentTheme.primary,
submitIcon: Icons.check_circle_outline, submitIcon: Icons.check_circle_outline,
child: SingleChildScrollView( child: SingleChildScrollView(
controller: widget.scrollController, controller: widget.scrollController,

View File

@ -148,7 +148,7 @@ class _ExpenseMainScreenState extends State<ExpenseMainScreen>
return canUpload return canUpload
? FloatingActionButton.extended( ? FloatingActionButton.extended(
backgroundColor: contentTheme.buttonColor, backgroundColor: contentTheme.primary,
onPressed: showAddExpenseBottomSheet, onPressed: showAddExpenseBottomSheet,
icon: const Icon(Icons.add, color: Colors.white), icon: const Icon(Icons.add, color: Colors.white),
label: const Text( label: const Text(

View File

@ -41,7 +41,7 @@ class _OfflineScreenState extends State<OfflineScreen>
return Scaffold( return Scaffold(
body: Stack( body: Stack(
children: [ children: [
RedWaveBackground(brandRed: contentTheme.brandColor), RedWaveBackground(brandRed: contentTheme.primary),
SafeArea( SafeArea(
child: Center( child: Center(
child: Padding( child: Padding(

View File

@ -5,29 +5,12 @@ import 'package:marco/helpers/widgets/my_text.dart';
import 'package:marco/widgets/custom_switch.dart'; import 'package:marco/widgets/custom_switch.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
// typedef void OnLeftBarColorSchemeChange(LeftBarThemeType leftBarThemeType);
// typedef void OnTopBarColorSchemeChange(TopBarThemeType topBarThemeType);
// typedef void OnRightBarColorSchemeChange(RightBarThemeType topBarThemeType);
// typedef void OnContentSchemeChange(ContentThemeType contentThemeType);
class RightBar extends StatefulWidget { class RightBar extends StatefulWidget {
// final RightBarThemeType rightBarThemeType;
// final LeftBarThemeType leftBarThemeType;
// final TopBarThemeType topBarThemeType;
// final ContentThemeType contentThemeType;
// final OnLeftBarColorSchemeChange onLeftBarColorSchemeChange;
// final OnTopBarColorSchemeChange onTopBarColorSchemeChange;
// final OnRightBarColorSchemeChange onRightBarColorSchemeChange;
// final OnContentSchemeChange onContentSchemeChange;
const RightBar({ const RightBar({
super.key, // this.leftBarThemeType, super.key,
// this.topBarThemeType,
// this.contentThemeType,
// this.onLeftBarColorSchemeChange,
// this.onTopBarColorSchemeChange,
// this.onContentSchemeChange,
// this.onRightBarColorSchemeChange
}); });
@override @override
@ -116,194 +99,12 @@ class _RightBarState extends State<RightBar>
) )
], ],
), ),
// Spacing.height(8),
// Row(
// children: [
// CustomSwitch.small(
// value: widget.contentThemeType == ContentThemeType.dark,
// activeBorderColor: rightBarTheme.activeSwitchBorderColor,
// inactiveBorderColor: rightBarTheme.inactiveSwitchBorderColor,
// inactiveTrackColor: rightBarTheme.disabled,
// activeTrackColor: rightBarTheme.primary,
// inactiveThumbColor: rightBarTheme.onDisabled,
// activeThumbColor: rightBarTheme.onPrimary,
// onChanged: (value) {
// if (value && widget.onContentSchemeChange != null) {
// widget.onContentSchemeChange(ContentThemeType.dark);
// }
// },
// ),
// Spacing.width(12),
// Text(
// "Dark",
// style: AppTheme.getTextStyle(themeData.textTheme.bodyText2,
// color: rightBarTheme.onBackground),
// )
// ],
// ),
// Spacing.height(36),
// Text("Left Bar",
// style: AppTheme.getTextStyle(themeData.textTheme.bodyText1,
// color: rightBarTheme.onBackground, fontWeight: 600)),
Divider(), Divider(),
// Spacing.height(8),
// Row(
// children: [
// CustomSwitch.small(
// value: widget.leftBarThemeType == LeftBarThemeType.light,
// activeBorderColor: rightBarTheme.activeSwitchBorderColor,
// inactiveBorderColor: rightBarTheme.inactiveSwitchBorderColor,
// inactiveTrackColor: rightBarTheme.disabled,
// activeTrackColor: rightBarTheme.primary,
// inactiveThumbColor: rightBarTheme.onDisabled,
// activeThumbColor: rightBarTheme.onPrimary,
// onChanged: (value) {
// if (value && widget.onLeftBarColorSchemeChange != null) {
// widget.onLeftBarColorSchemeChange(LeftBarThemeType.light);
// }
// },
// ),
// Spacing.width(12),
// Text(
// "Light",
// style: AppTheme.getTextStyle(themeData.textTheme.bodyText2,
// color: rightBarTheme.onBackground),
// )
// ],
// ),
// Spacing.height(8),
// Row(
// children: [
// CustomSwitch.small(
// value: widget.leftBarThemeType == LeftBarThemeType.dark,
// activeBorderColor: rightBarTheme.activeSwitchBorderColor,
// inactiveBorderColor: rightBarTheme.inactiveSwitchBorderColor,
// inactiveTrackColor: rightBarTheme.disabled,
// activeTrackColor: rightBarTheme.primary,
// inactiveThumbColor: rightBarTheme.onDisabled,
// activeThumbColor: rightBarTheme.onPrimary,
// onChanged: (value) {
// if (value && widget.onLeftBarColorSchemeChange != null) {
// widget.onLeftBarColorSchemeChange(LeftBarThemeType.dark);
// }
// },
// ),
// Spacing.width(12),
// Text(
// "Dark",
// style: AppTheme.getTextStyle(themeData.textTheme.bodyText2,
// color: rightBarTheme.onBackground),
// )
// ],
// ),
// Spacing.height(36),
Text("Top Bar"), Text("Top Bar"),
Divider(), Divider(),
// Spacing.height(8),
// Row(
// children: [
// CustomSwitch.small(
// value: widget.topBarThemeType == TopBarThemeType.light,
// inactiveTrackColor: rightBarTheme.disabled,
// activeBorderColor: rightBarTheme.activeSwitchBorderColor,
// inactiveBorderColor: rightBarTheme.inactiveSwitchBorderColor,
// activeTrackColor: rightBarTheme.primary,
// inactiveThumbColor: rightBarTheme.onDisabled,
// activeThumbColor: rightBarTheme.onPrimary,
// onChanged: (value) {
// if (value && widget.onTopBarColorSchemeChange != null) {
// widget.onTopBarColorSchemeChange(TopBarThemeType.light);
// }
// },
// ),
// Spacing.width(12),
// Text(
// "Light",
// style: AppTheme.getTextStyle(themeData.textTheme.bodyText2,
// color: rightBarTheme.onBackground),
// )
// ],
// ),
// Spacing.height(8),
// Row(
// children: [
// CustomSwitch.small(
// value: widget.topBarThemeType == TopBarThemeType.dark,
// inactiveTrackColor: rightBarTheme.disabled,
// activeBorderColor: rightBarTheme.activeSwitchBorderColor,
// inactiveBorderColor: rightBarTheme.inactiveSwitchBorderColor,
// activeTrackColor: rightBarTheme.primary,
// inactiveThumbColor: rightBarTheme.onDisabled,
// activeThumbColor: rightBarTheme.onPrimary,
// onChanged: (value) {
// if (value && widget.onTopBarColorSchemeChange != null) {
// widget.onTopBarColorSchemeChange(TopBarThemeType.dark);
// }
// },
// ),
// Spacing.width(12),
// Text(
// "Dark",
// style: AppTheme.getTextStyle(themeData.textTheme.bodyText2,
// color: rightBarTheme.onBackground),
// )
// ],
// ),
// Spacing.height(36),
// Text("Right Bar",
// style: AppTheme.getTextStyle(themeData.textTheme.bodyText1,
// color: rightBarTheme.onBackground, fontWeight: 600)),
// Divider(),
// Spacing.height(8),
// Row(
// children: [
// CustomSwitch.small(
// value: widget.rightBarThemeType == RightBarThemeType.light,
// inactiveTrackColor: rightBarTheme.disabled,
// activeBorderColor: rightBarTheme.activeSwitchBorderColor,
// inactiveBorderColor: rightBarTheme.inactiveSwitchBorderColor,
// activeTrackColor: rightBarTheme.primary,
// inactiveThumbColor: rightBarTheme.onDisabled,
// activeThumbColor: rightBarTheme.onPrimary,
// onChanged: (value) {
// if (value && widget.onRightBarColorSchemeChange != null) {
// widget.onRightBarColorSchemeChange(RightBarThemeType.light);
// }
// },
// ),
// Spacing.width(12),
// Text(
// "Light",
// style: AppTheme.getTextStyle(themeData.textTheme.bodyText2,
// color: rightBarTheme.onBackground),
// )
// ],
// ),
// Spacing.height(8),
// Row(
// children: [
// CustomSwitch.small(
// value: widget.rightBarThemeType == RightBarThemeType.dark,
// inactiveTrackColor: rightBarTheme.disabled,
// activeBorderColor: rightBarTheme.activeSwitchBorderColor,
// inactiveBorderColor: rightBarTheme.inactiveSwitchBorderColor,
// activeTrackColor: rightBarTheme.primary,
// inactiveThumbColor: rightBarTheme.onDisabled,
// activeThumbColor: rightBarTheme.onPrimary,
// onChanged: (value) {
// if (value && widget.onRightBarColorSchemeChange != null) {
// widget.onRightBarColorSchemeChange(RightBarThemeType.dark);
// }
// },
// ),
// Spacing.width(12),
// Text(
// "Dark",
// style: AppTheme.getTextStyle(themeData.textTheme.bodyText2,
// color: rightBarTheme.onBackground),
// )
// ],
// ),
], ],
), ),
)) ))

View File

@ -15,14 +15,6 @@ import 'package:marco/view/tenant/tenant_selection_screen.dart';
import 'package:marco/controller/tenant/tenant_switch_controller.dart'; import 'package:marco/controller/tenant/tenant_switch_controller.dart';
import 'package:marco/helpers/theme/theme_editor_widget.dart'; import 'package:marco/helpers/theme/theme_editor_widget.dart';
class ThemeOption {
final String label;
final Color primary;
final Color button;
final Color brand;
ThemeOption(this.label, this.primary, this.button, this.brand);
}
class UserProfileBar extends StatefulWidget { class UserProfileBar extends StatefulWidget {
final bool isCondensed; final bool isCondensed;
@ -189,14 +181,14 @@ class _UserProfileBarState extends State<UserProfileBar>
? FontWeight.bold ? FontWeight.bold
: FontWeight.w600, : FontWeight.w600,
color: tenant.id == selectedTenant?.id color: tenant.id == selectedTenant?.id
? contentTheme.buttonColor ? contentTheme.primary
: Colors.black87, : Colors.black87,
), ),
), ),
), ),
if (tenant.id == selectedTenant?.id) if (tenant.id == selectedTenant?.id)
Icon(Icons.check_circle, Icon(Icons.check_circle,
color: contentTheme.buttonColor, size: 18), color: contentTheme.primary, size: 18),
], ],
), ),
); );
@ -206,7 +198,7 @@ class _UserProfileBarState extends State<UserProfileBar>
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Icon(Icons.swap_horiz, color: contentTheme.buttonColor), Icon(Icons.swap_horiz, color: contentTheme.primary),
Expanded( Expanded(
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 6), padding: const EdgeInsets.symmetric(horizontal: 6),
@ -215,12 +207,12 @@ class _UserProfileBarState extends State<UserProfileBar>
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: TextStyle( style: TextStyle(
color: contentTheme.buttonColor, color: contentTheme.primary,
fontWeight: FontWeight.bold), fontWeight: FontWeight.bold),
), ),
), ),
), ),
Icon(Icons.arrow_drop_down, color: contentTheme.buttonColor), Icon(Icons.arrow_drop_down, color: contentTheme.primary),
], ],
), ),
), ),
@ -415,9 +407,9 @@ class _UserProfileBarState extends State<UserProfileBar>
fontWeight: 700, fontWeight: 700,
), ),
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: contentTheme.buttonColor, backgroundColor: contentTheme.primary,
foregroundColor: Colors.white, foregroundColor: Colors.white,
shadowColor: contentTheme.buttonColor, shadowColor: contentTheme.primary,
padding: EdgeInsets.symmetric( padding: EdgeInsets.symmetric(
vertical: condensed ? 14 : 18, vertical: condensed ? 14 : 18,
horizontal: condensed ? 14 : 22, horizontal: condensed ? 14 : 22,
@ -440,7 +432,7 @@ class _UserProfileBarState extends State<UserProfileBar>
Widget _buildLogoutDialog(BuildContext context) { Widget _buildLogoutDialog(BuildContext context) {
final theme = Theme.of(context); final theme = Theme.of(context);
final primaryColor = contentTheme.buttonColor; final primaryColor = contentTheme.primary;
return Dialog( return Dialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24)), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24)),

View File

@ -64,7 +64,7 @@ class _TenantSelectionScreenState extends State<TenantSelectionScreen>
return Scaffold( return Scaffold(
body: Stack( body: Stack(
children: [ children: [
RedWaveBackground(brandRed: contentTheme.brandColor), RedWaveBackground(brandRed: contentTheme.primary),
SafeArea( SafeArea(
child: Center( child: Center(
child: Column( child: Column(
@ -234,10 +234,10 @@ class TenantCardList extends StatelessWidget with UIMixin {
await LocalStorage.logout(); await LocalStorage.logout();
}, },
icon: icon:
Icon(Icons.arrow_back, size: 20, color: contentTheme.brandColor,), Icon(Icons.arrow_back, size: 20, color: contentTheme.primary,),
label: MyText( label: MyText(
'Back to Login', 'Back to Login',
color: contentTheme.brandColor, color: contentTheme.primary,
fontWeight: 600, fontWeight: 600,
fontSize: 14, fontSize: 14,
), ),
@ -297,7 +297,7 @@ class _TenantCard extends StatelessWidget with UIMixin {
], ],
), ),
), ),
Icon(Icons.arrow_forward_ios, size: 24, color: contentTheme.brandColor,), Icon(Icons.arrow_forward_ios, size: 24, color: contentTheme.primary,),
], ],
), ),
), ),