theme changes

This commit is contained in:
Surendiran 2026-07-17 14:35:10 +05:30
parent 4360931be4
commit 03486ea3f4
21 changed files with 230 additions and 67 deletions

View File

@ -162,6 +162,20 @@ class AppTheme {
), ),
elevatedButtonTheme: ElevatedButtonThemeData( elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: colorScheme.primary,
foregroundColor: colorScheme.onPrimary,
disabledBackgroundColor: colorScheme.onSurface.withValues(alpha: 0.12),
disabledForegroundColor: colorScheme.onSurface.withValues(alpha: 0.38),
minimumSize: const Size(0, 48),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
textStyle: textTheme.labelLarge,
),
),
filledButtonTheme: FilledButtonThemeData(
style: FilledButton.styleFrom(
backgroundColor: colorScheme.primary,
foregroundColor: colorScheme.onPrimary,
minimumSize: const Size(0, 48), minimumSize: const Size(0, 48),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
@ -170,18 +184,30 @@ class AppTheme {
), ),
outlinedButtonTheme: OutlinedButtonThemeData( outlinedButtonTheme: OutlinedButtonThemeData(
style: OutlinedButton.styleFrom( style: OutlinedButton.styleFrom(
foregroundColor: colorScheme.secondary,
minimumSize: const Size(0, 48), minimumSize: const Size(0, 48),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
side: BorderSide(color: colorScheme.secondary.withValues(alpha: 0.55)),
textStyle: textTheme.labelLarge, textStyle: textTheme.labelLarge,
), ),
), ),
textButtonTheme: TextButtonThemeData( textButtonTheme: TextButtonThemeData(
style: TextButton.styleFrom( style: TextButton.styleFrom(
foregroundColor: colorScheme.secondary,
minimumSize: const Size(0, 48), minimumSize: const Size(0, 48),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
textStyle: textTheme.labelLarge, textStyle: textTheme.labelLarge,
), ),
), ),
iconButtonTheme: IconButtonThemeData(
style: IconButton.styleFrom(
foregroundColor: colorScheme.secondary,
),
),
floatingActionButtonTheme: FloatingActionButtonThemeData(
backgroundColor: colorScheme.primary,
foregroundColor: colorScheme.onPrimary,
),
navigationRailTheme: NavigationRailThemeData( navigationRailTheme: NavigationRailThemeData(
backgroundColor: isDark ? AppColors.darkSurface : AppColors.lightSurface, backgroundColor: isDark ? AppColors.darkSurface : AppColors.lightSurface,
selectedIconTheme: IconThemeData(color: colorScheme.primary), selectedIconTheme: IconThemeData(color: colorScheme.primary),
@ -215,7 +241,17 @@ class AppTheme {
dataTextStyle: textTheme.bodyMedium, dataTextStyle: textTheme.bodyMedium,
), ),
chipTheme: ChipThemeData( chipTheme: ChipThemeData(
labelStyle: textTheme.labelSmall, backgroundColor: colorScheme.secondaryContainer.withValues(alpha: 0.55),
selectedColor: colorScheme.secondary.withValues(alpha: 0.18),
disabledColor: colorScheme.onSurface.withValues(alpha: 0.08),
labelStyle: textTheme.labelSmall?.copyWith(
color: colorScheme.onSecondaryContainer,
),
secondaryLabelStyle: textTheme.labelSmall?.copyWith(
color: colorScheme.secondary,
),
side: BorderSide(color: colorScheme.secondary.withValues(alpha: 0.28)),
iconTheme: IconThemeData(color: colorScheme.secondary, size: 18),
), ),
dialogTheme: DialogThemeData( dialogTheme: DialogThemeData(
titleTextStyle: textTheme.titleLarge, titleTextStyle: textTheme.titleLarge,

View File

@ -1088,6 +1088,9 @@ class _AssetFormPanelState extends ConsumerState<AssetFormPanel> {
}, },
icon: const Icon(Icons.add, size: 18), icon: const Icon(Icons.add, size: 18),
label: const Text('Add Item'), label: const Text('Add Item'),
style: TextButton.styleFrom(
foregroundColor: theme.colorScheme.primary,
),
), ),
], ],
), ),

View File

@ -339,7 +339,7 @@ class _FiltersBar extends StatelessWidget {
); );
final theme = Theme.of(context); final theme = Theme.of(context);
final iconColor = theme.colorScheme.primary; final iconColor = theme.colorScheme.secondary;
final resetButton = IconButton( final resetButton = IconButton(
tooltip: 'Reset', tooltip: 'Reset',
color: iconColor, color: iconColor,

View File

@ -45,13 +45,13 @@ class DashboardScreen extends StatelessWidget {
title: 'Allocated', title: 'Allocated',
value: '', value: '',
icon: Icons.assignment_ind_outlined, icon: Icons.assignment_ind_outlined,
color: Colors.blue, color: Theme.of(context).colorScheme.primary,
), ),
KpiCard( KpiCard(
title: 'Available', title: 'Available',
value: '', value: '',
icon: Icons.check_circle_outline, icon: Icons.check_circle_outline,
color: Colors.green, color: Theme.of(context).colorScheme.secondary,
), ),
KpiCard( KpiCard(
title: 'Under Maintenance', title: 'Under Maintenance',

View File

@ -17,7 +17,8 @@ class GrnStatusChip extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final (color, label) = _resolveStatus(status); final secondary = Theme.of(context).colorScheme.secondary;
final (color, label) = _resolveStatus(status, secondary);
if (forTable) { if (forTable) {
return TableStatusBadge( return TableStatusBadge(
label: label, label: label,
@ -43,14 +44,14 @@ class GrnStatusChip extends StatelessWidget {
); );
} }
(Color, String) _resolveStatus(String raw) { (Color, String) _resolveStatus(String raw, Color secondary) {
switch (raw.toUpperCase()) { switch (raw.toUpperCase()) {
case 'POSTED': case 'POSTED':
return (Colors.green.shade700, grnStatusLabel(raw)); return (secondary, grnStatusLabel(raw));
case 'CANCELLED': case 'CANCELLED':
return (Colors.grey.shade700, grnStatusLabel(raw)); return (Colors.grey.shade700, grnStatusLabel(raw));
default: default:
return (Colors.blueGrey, grnStatusLabel(raw)); return (secondary, grnStatusLabel(raw));
} }
} }
} }

View File

@ -17,7 +17,8 @@ class PoStatusChip extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final (color, label) = _resolveStatus(status); final secondary = Theme.of(context).colorScheme.secondary;
final (color, label) = _resolveStatus(status, secondary);
if (forTable) { if (forTable) {
return TableStatusBadge( return TableStatusBadge(
label: label, label: label,
@ -29,7 +30,7 @@ class PoStatusChip extends StatelessWidget {
return _PoBadge(label: label, color: color, compact: compact); return _PoBadge(label: label, color: color, compact: compact);
} }
(Color, String) _resolveStatus(String raw) { (Color, String) _resolveStatus(String raw, Color secondary) {
switch (raw.toUpperCase()) { switch (raw.toUpperCase()) {
case 'DRAFT': case 'DRAFT':
return (const Color(0xFF546E7A), poStatusLabel(raw)); return (const Color(0xFF546E7A), poStatusLabel(raw));
@ -38,17 +39,17 @@ class PoStatusChip extends StatelessWidget {
case 'PENDING': case 'PENDING':
return (const Color(0xFFE65100), poStatusLabel(raw)); return (const Color(0xFFE65100), poStatusLabel(raw));
case 'APPROVED': case 'APPROVED':
return (const Color(0xFF2E7D32), poStatusLabel(raw)); return (secondary, poStatusLabel(raw));
case 'REJECTED': case 'REJECTED':
return (const Color(0xFFC62828), poStatusLabel(raw)); return (const Color(0xFFC62828), poStatusLabel(raw));
case 'CANCELLED': case 'CANCELLED':
return (const Color(0xFF616161), poStatusLabel(raw)); return (const Color(0xFF616161), poStatusLabel(raw));
case 'PARTIALLY_RECEIVED': case 'PARTIALLY_RECEIVED':
return (const Color(0xFF00695C), poStatusLabel(raw)); return (secondary, poStatusLabel(raw));
case 'FULLY_RECEIVED': case 'FULLY_RECEIVED':
return (const Color(0xFF283593), poStatusLabel(raw)); return (secondary, poStatusLabel(raw));
default: default:
return (const Color(0xFF546E7A), poStatusLabel(raw)); return (secondary, poStatusLabel(raw));
} }
} }
} }
@ -67,7 +68,7 @@ class PoRevisionChip extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return _PoBadge( return _PoBadge(
label: 'Revision $revisionNo', label: 'Revision $revisionNo',
color: const Color(0xFF607D8B), color: Theme.of(context).colorScheme.secondary,
compact: compact, compact: compact,
); );
} }

View File

@ -1511,18 +1511,34 @@ class _PermissionMatrixTable extends ConsumerWidget {
alignment: Alignment.center, alignment: Alignment.center,
enableSearch: false, enableSearch: false,
cellBuilder: (context, module) { cellBuilder: (context, module) {
final moduleCatalog = catalog
?.where(
(entry) =>
entry.id == module.moduleId ||
normalizePermissionModuleCode(entry.code) ==
normalizePermissionModuleCode(module.code),
)
.firstOrNull;
final applicable = isPermissionActionApplicable(
module.code,
action,
catalogActions: moduleCatalog?.actions,
columnActions: actionColumns,
);
final checked = module.granted[action] ?? false; final checked = module.granted[action] ?? false;
return Checkbox( return Checkbox(
value: checked, value: applicable ? checked : false,
visualDensity: VisualDensity.compact, visualDensity: VisualDensity.compact,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
onChanged: (value) => ref onChanged: applicable
.read(permissionMatrixProvider(roleId).notifier) ? (value) => ref
.toggleAction( .read(permissionMatrixProvider(roleId).notifier)
module.moduleId, .toggleAction(
action, module.moduleId,
value ?? false, action,
), value ?? false,
)
: null,
); );
}, },
), ),

View File

@ -126,11 +126,11 @@ class RoleBadge extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final primary = Theme.of(context).colorScheme.primary; final secondary = Theme.of(context).colorScheme.secondary;
return Container( return Container(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5), padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
decoration: BoxDecoration( decoration: BoxDecoration(
color: primary.withValues(alpha: 0.08), color: secondary.withValues(alpha: 0.08),
borderRadius: BorderRadius.circular(20), borderRadius: BorderRadius.circular(20),
), ),
child: Row( child: Row(
@ -139,7 +139,7 @@ class RoleBadge extends StatelessWidget {
Container( Container(
width: 6, width: 6,
height: 6, height: 6,
decoration: BoxDecoration(color: primary, shape: BoxShape.circle), decoration: BoxDecoration(color: secondary, shape: BoxShape.circle),
), ),
const SizedBox(width: 6), const SizedBox(width: 6),
Flexible( Flexible(
@ -148,7 +148,7 @@ class RoleBadge extends StatelessWidget {
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.labelSmall?.copyWith( style: Theme.of(context).textTheme.labelSmall?.copyWith(
color: primary, color: secondary,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
), ),
), ),

View File

@ -515,7 +515,7 @@ class _FiltersBarState extends State<_FiltersBar> {
? (_moreOpen ? 'Less filters ($moreCount)' : 'More filters ($moreCount)') ? (_moreOpen ? 'Less filters ($moreCount)' : 'More filters ($moreCount)')
: (_moreOpen ? 'Less filters' : 'More filters'); : (_moreOpen ? 'Less filters' : 'More filters');
final iconColor = theme.colorScheme.primary; final iconColor = theme.colorScheme.secondary;
final moreButton = IconButton( final moreButton = IconButton(
tooltip: moreTooltip, tooltip: moreTooltip,

View File

@ -164,6 +164,13 @@ class PermissionMatrixNotifier
final updated = current.modules.map((row) { final updated = current.modules.map((row) {
if (row.moduleId != moduleId) return row; if (row.moduleId != moduleId) return row;
if (!isPermissionActionApplicable(
row.code,
action,
columnActions: current.actionColumns,
)) {
return row;
}
final granted = Map<String, bool>.from(row.granted); final granted = Map<String, bool>.from(row.granted);
granted[action] = value; granted[action] = value;
return row.copyWith(granted: granted); return row.copyWith(granted: granted);

View File

@ -100,14 +100,23 @@ class _MatrixGrid extends ConsumerWidget {
flex: 1, flex: 1,
alignment: Alignment.center, alignment: Alignment.center,
enableSearch: false, enableSearch: false,
cellBuilder: (_, row) => Checkbox( cellBuilder: (_, row) {
value: row.granted[action] ?? false, final applicable = isPermissionActionApplicable(
visualDensity: VisualDensity.compact, row.code,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, action,
onChanged: (checked) => ref columnActions: matrix.actionColumns,
.read(permissionMatrixProvider(roleId).notifier) );
.toggleAction(row.moduleId, action, checked ?? false), return Checkbox(
), value: applicable ? (row.granted[action] ?? false) : false,
visualDensity: VisualDensity.compact,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
onChanged: applicable
? (checked) => ref
.read(permissionMatrixProvider(roleId).notifier)
.toggleAction(row.moduleId, action, checked ?? false)
: null,
);
},
), ),
), ),
], ],
@ -134,13 +143,22 @@ class _MatrixCardList extends ConsumerWidget {
title: Text(row.name), title: Text(row.name),
children: matrix.actionColumns children: matrix.actionColumns
.map( .map(
(action) => _PermissionSwitch( (action) {
label: permissionActionLabel(action), final applicable = isPermissionActionApplicable(
value: row.granted[action] ?? false, row.code,
onChanged: (v) => ref action,
.read(permissionMatrixProvider(roleId).notifier) columnActions: matrix.actionColumns,
.toggleAction(row.moduleId, action, v), );
), return _PermissionSwitch(
label: permissionActionLabel(action),
value: applicable ? (row.granted[action] ?? false) : false,
onChanged: applicable
? (v) => ref
.read(permissionMatrixProvider(roleId).notifier)
.toggleAction(row.moduleId, action, v)
: null,
);
},
) )
.toList(), .toList(),
), ),
@ -159,7 +177,7 @@ class _PermissionSwitch extends StatelessWidget {
final String label; final String label;
final bool value; final bool value;
final ValueChanged<bool> onChanged; final ValueChanged<bool>? onChanged;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View File

@ -32,6 +32,54 @@ List<String> sortPermissionActions(Iterable<String> actions) {
return permissionMatrixActionOrder.where(set.contains).toList(); return permissionMatrixActionOrder.where(set.contains).toList();
} }
String normalizePermissionModuleCode(String code) =>
code.trim().toLowerCase().replaceAll('-', '_').replaceAll(' ', '_');
/// Actions that apply to a module in the permission matrix UI.
///
/// Restricted modules omit actions that are not meaningful for them.
/// For other modules, [catalogActions] (when provided) limits the set.
List<String> applicablePermissionActionsForModule(
String code, {
List<String>? catalogActions,
List<String> columnActions = permissionMatrixActionOrder,
}) {
final normalized = normalizePermissionModuleCode(code);
final columns = sortPermissionActions(columnActions);
final restricted = switch (normalized) {
'settings' || 'setting' || 'settings_module' => const ['view', 'edit'],
'reports' || 'report' => const ['view', 'export'],
'audit_logs' || 'audit_log' || 'audit' => const ['view', 'export'],
_ => null,
};
if (restricted != null) {
return columns.where(restricted.contains).toList();
}
if (catalogActions != null && catalogActions.isNotEmpty) {
final catalogSet =
catalogActions.map((action) => action.toLowerCase()).toSet();
return columns.where(catalogSet.contains).toList();
}
return columns;
}
bool isPermissionActionApplicable(
String moduleCode,
String action, {
List<String>? catalogActions,
List<String> columnActions = permissionMatrixActionOrder,
}) {
return applicablePermissionActionsForModule(
moduleCode,
catalogActions: catalogActions,
columnActions: columnActions,
).contains(action.toLowerCase());
}
/// Module row from `GET /roles/permissions`. /// Module row from `GET /roles/permissions`.
class PermissionModuleCatalog { class PermissionModuleCatalog {
const PermissionModuleCatalog({ const PermissionModuleCatalog({
@ -181,12 +229,19 @@ class RolePermissionMatrix {
return { return {
'matrix': modules 'matrix': modules
.map( .map(
(module) => { (module) {
'module_id': int.tryParse(module.moduleId) ?? module.moduleId, final applicable = applicablePermissionActionsForModule(
'actions': { module.code,
for (final action in actionColumns) columnActions: actionColumns,
action: module.granted[action] ?? false, ).toSet();
}, return {
'module_id': int.tryParse(module.moduleId) ?? module.moduleId,
'actions': {
for (final action in actionColumns)
action: applicable.contains(action) &&
(module.granted[action] ?? false),
},
};
}, },
) )
.toList(), .toList(),

View File

@ -20,11 +20,19 @@ class AppButton extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final theme = Theme.of(context);
final primary = theme.colorScheme.primary;
final onPrimary = theme.colorScheme.onPrimary;
final secondary = theme.colorScheme.secondary;
final child = isLoading final child = isLoading
? const SizedBox( ? SizedBox(
height: 20, height: 20,
width: 20, width: 20,
child: CircularProgressIndicator(strokeWidth: 2), child: CircularProgressIndicator(
strokeWidth: 2,
color: isOutlined ? secondary : onPrimary,
),
) )
: Row( : Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
@ -36,8 +44,22 @@ class AppButton extends StatelessWidget {
); );
final button = isOutlined final button = isOutlined
? OutlinedButton(onPressed: isLoading ? null : onPressed, child: child) ? OutlinedButton(
: ElevatedButton(onPressed: isLoading ? null : onPressed, child: child); onPressed: isLoading ? null : onPressed,
style: OutlinedButton.styleFrom(
foregroundColor: secondary,
side: BorderSide(color: secondary.withValues(alpha: 0.55)),
),
child: child,
)
: ElevatedButton(
onPressed: isLoading ? null : onPressed,
style: ElevatedButton.styleFrom(
backgroundColor: primary,
foregroundColor: onPrimary,
),
child: child,
);
return expand ? SizedBox(width: double.infinity, child: button) : button; return expand ? SizedBox(width: double.infinity, child: button) : button;
} }

View File

@ -453,7 +453,7 @@ class _ColumnSearchField extends StatelessWidget {
Icons.search_rounded, Icons.search_rounded,
size: 16, size: 16,
color: hasQuery color: hasQuery
? theme.colorScheme.primary ? theme.colorScheme.secondary
: theme.colorScheme.onSurfaceVariant.withValues(alpha: 0.7), : theme.colorScheme.onSurfaceVariant.withValues(alpha: 0.7),
), ),
prefixIconConstraints: const BoxConstraints( prefixIconConstraints: const BoxConstraints(

View File

@ -63,7 +63,7 @@ class AppFilterDateField extends StatelessWidget {
height: 24, height: 24,
child: Row( child: Row(
children: [ children: [
Icon(icon, size: 16, color: theme.colorScheme.primary), Icon(icon, size: 16, color: theme.colorScheme.secondary),
const SizedBox(width: 8), const SizedBox(width: 8),
Expanded( Expanded(
child: Text( child: Text(

View File

@ -14,7 +14,7 @@ class AppSearchFilterButton extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final theme = Theme.of(context); final theme = Theme.of(context);
final activeColor = theme.colorScheme.primary; final activeColor = theme.colorScheme.secondary;
return OutlinedButton( return OutlinedButton(
onPressed: onPressed, onPressed: onPressed,

View File

@ -391,7 +391,7 @@ class _SearchableDropdownPanelState<T>
? Icon( ? Icon(
Icons.check, Icons.check,
size: 20, size: 20,
color: theme.colorScheme.primary, color: theme.colorScheme.secondary,
) )
: null, : null,
selected: isSelected, selected: isSelected,
@ -409,6 +409,9 @@ class _SearchableDropdownPanelState<T>
onPressed: () => widget.onAddNew?.call(), onPressed: () => widget.onAddNew?.call(),
icon: const Icon(Icons.add, size: 18), icon: const Icon(Icons.add, size: 18),
label: Text(addLabel), label: Text(addLabel),
style: TextButton.styleFrom(
foregroundColor: theme.colorScheme.primary,
),
), ),
], ],
], ],

View File

@ -72,7 +72,8 @@ class AppStatusChip extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final (color, label) = _resolveStatus(status); final secondary = Theme.of(context).colorScheme.secondary;
final (color, label) = _resolveStatus(status, secondary);
if (forTable) { if (forTable) {
return TableStatusBadge( return TableStatusBadge(
label: label, label: label,
@ -98,26 +99,26 @@ class AppStatusChip extends StatelessWidget {
); );
} }
(Color, String) _resolveStatus(String raw) { (Color, String) _resolveStatus(String raw, Color secondary) {
final normalized = raw.trim().toLowerCase().replaceAll(' ', '_'); final normalized = raw.trim().toLowerCase().replaceAll(' ', '_');
switch (normalized) { switch (normalized) {
case 'active': case 'active':
return (Colors.green.shade700, EntityStatus.active.label); return (secondary, EntityStatus.active.label);
case 'inactive': case 'inactive':
return (Colors.grey.shade700, EntityStatus.inactive.label); return (Colors.grey.shade700, EntityStatus.inactive.label);
case 'locked': case 'locked':
return (Colors.orange.shade800, 'Locked'); return (Colors.orange.shade800, 'Locked');
case 'in_use': case 'in_use':
return (const Color(0xFF16A34A), 'In Use'); return (secondary, 'In Use');
case 'under_maintenance': case 'under_maintenance':
return (const Color(0xFFCA8A04), 'Under Maintenance'); return (const Color(0xFFCA8A04), 'Under Maintenance');
case 'available': case 'available':
return (const Color(0xFF2563EB), 'Available'); return (secondary, 'Available');
case 'disposed': case 'disposed':
case 'scrapped': case 'scrapped':
return (Colors.grey.shade700, _humanizeStatus(raw)); return (Colors.grey.shade700, _humanizeStatus(raw));
default: default:
return (Colors.blueGrey, _humanizeStatus(raw)); return (secondary, _humanizeStatus(raw));
} }
} }

View File

@ -314,7 +314,7 @@ class _AttachmentRow extends StatelessWidget {
Icon( Icon(
_fileIcon(attachment), _fileIcon(attachment),
size: 22, size: 22,
color: theme.colorScheme.primary, color: theme.colorScheme.secondary,
), ),
const SizedBox(width: 12), const SizedBox(width: 12),
Expanded( Expanded(

View File

@ -20,7 +20,7 @@ class KpiCard extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final cardColor = color ?? Theme.of(context).colorScheme.primary; final cardColor = color ?? Theme.of(context).colorScheme.secondary;
return AppCard( return AppCard(
onTap: onTap, onTap: onTap,

View File

@ -325,7 +325,7 @@ class _MasterInlineQuickAddFormState
Row( Row(
children: [ children: [
Icon(Icons.add_circle_outline, Icon(Icons.add_circle_outline,
size: 16, color: theme.colorScheme.primary), size: 16, color: theme.colorScheme.secondary),
const SizedBox(width: 6), const SizedBox(width: 6),
Expanded( Expanded(
child: Text( child: Text(