refactor: enhance widget visibility logic and improve UI consistency across multiple components
This commit is contained in:
@@ -74,14 +74,21 @@ class ClientHomePage extends StatelessWidget {
|
|||||||
|
|
||||||
/// Builds the widget list in normal mode with visibility filters.
|
/// Builds the widget list in normal mode with visibility filters.
|
||||||
Widget _buildNormalModeList(ClientHomeState state) {
|
Widget _buildNormalModeList(ClientHomeState state) {
|
||||||
|
final List<String> visibleWidgets = state.widgetOrder.where((String id) {
|
||||||
|
if (id == 'reorder' && state.reorderItems.isEmpty) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return state.widgetVisibility[id] ?? true;
|
||||||
|
}).toList();
|
||||||
|
|
||||||
return ListView.separated(
|
return ListView.separated(
|
||||||
padding: const EdgeInsets.only(bottom: 100),
|
padding: const EdgeInsets.only(bottom: 100),
|
||||||
separatorBuilder: (BuildContext context, int index) {
|
separatorBuilder: (BuildContext context, int index) {
|
||||||
return const Divider(color: UiColors.border, height: 0.2);
|
return const Divider(color: UiColors.border, height: 0.2);
|
||||||
},
|
},
|
||||||
itemCount: state.widgetOrder.length,
|
itemCount: visibleWidgets.length,
|
||||||
itemBuilder: (BuildContext context, int index) {
|
itemBuilder: (BuildContext context, int index) {
|
||||||
final String id = state.widgetOrder[index];
|
final String id = visibleWidgets[index];
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
|
|||||||
@@ -26,6 +26,20 @@ class CoverageWidget extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
Color backgroundColor;
|
||||||
|
Color textColor;
|
||||||
|
|
||||||
|
if (coveragePercent == 100) {
|
||||||
|
backgroundColor = UiColors.tagActive;
|
||||||
|
textColor = UiColors.textSuccess;
|
||||||
|
} else if (coveragePercent >= 40) {
|
||||||
|
backgroundColor = UiColors.tagPending;
|
||||||
|
textColor = UiColors.textWarning;
|
||||||
|
} else {
|
||||||
|
backgroundColor = UiColors.tagError;
|
||||||
|
textColor = UiColors.textError;
|
||||||
|
}
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
@@ -46,13 +60,13 @@ class CoverageWidget extends StatelessWidget {
|
|||||||
2, // 2px is not in metrics, using hardcoded for small tweaks or space0/space1
|
2, // 2px is not in metrics, using hardcoded for small tweaks or space0/space1
|
||||||
),
|
),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: UiColors.tagActive,
|
color: backgroundColor,
|
||||||
borderRadius: UiConstants.radiusLg,
|
borderRadius: UiConstants.radiusLg,
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
'$coveragePercent% Covered',
|
'$coveragePercent% Covered',
|
||||||
style: UiTypography.footnote2b.copyWith(
|
style: UiTypography.footnote2b.copyWith(
|
||||||
color: UiColors.textSuccess,
|
color: textColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -64,7 +78,7 @@ class CoverageWidget extends StatelessWidget {
|
|||||||
style: UiTypography.body2r.textSecondary,
|
style: UiTypography.body2r.textSecondary,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
const SizedBox(height: UiConstants.space2),
|
const SizedBox(height: UiConstants.space6),
|
||||||
Row(
|
Row(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Expanded(
|
Expanded(
|
||||||
@@ -76,7 +90,7 @@ class CoverageWidget extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: UiConstants.space2),
|
const SizedBox(width: UiConstants.space2),
|
||||||
Expanded(
|
if (totalConfirmed != 0) Expanded(
|
||||||
child: _MetricCard(
|
child: _MetricCard(
|
||||||
icon: UiIcons.success,
|
icon: UiIcons.success,
|
||||||
iconColor: UiColors.iconSuccess,
|
iconColor: UiColors.iconSuccess,
|
||||||
|
|||||||
@@ -130,13 +130,12 @@ class _LiveActivityWidgetState extends State<LiveActivityWidget> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
if (widget.subtitle != null) ...<Widget>[
|
if (widget.subtitle != null) ...<Widget>[
|
||||||
const SizedBox(height: UiConstants.space1),
|
|
||||||
Text(
|
Text(
|
||||||
widget.subtitle!,
|
widget.subtitle!,
|
||||||
style: UiTypography.body2r.textSecondary,
|
style: UiTypography.body2r.textSecondary,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
const SizedBox(height: UiConstants.space2),
|
const SizedBox(height: UiConstants.space6),
|
||||||
FutureBuilder<_LiveActivityData>(
|
FutureBuilder<_LiveActivityData>(
|
||||||
future: _liveActivityFuture,
|
future: _liveActivityFuture,
|
||||||
builder: (BuildContext context,
|
builder: (BuildContext context,
|
||||||
|
|||||||
@@ -24,6 +24,10 @@ class ReorderWidget extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
if (orders.isEmpty) {
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
}
|
||||||
|
|
||||||
final TranslationsClientHomeReorderEn i18n = t.client_home.reorder;
|
final TranslationsClientHomeReorderEn i18n = t.client_home.reorder;
|
||||||
|
|
||||||
final List<ReorderItem> recentOrders = orders;
|
final List<ReorderItem> recentOrders = orders;
|
||||||
|
|||||||
@@ -43,13 +43,12 @@ class SpendingWidget extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (subtitle != null) ...<Widget>[
|
if (subtitle != null) ...<Widget>[
|
||||||
const SizedBox(height: UiConstants.space1),
|
|
||||||
Text(
|
Text(
|
||||||
subtitle!,
|
subtitle!,
|
||||||
style: UiTypography.body2r.textSecondary,
|
style: UiTypography.body2r.textSecondary,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
const SizedBox(height: UiConstants.space2),
|
const SizedBox(height: UiConstants.space6),
|
||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.all(UiConstants.space3),
|
padding: const EdgeInsets.all(UiConstants.space3),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@@ -125,58 +124,6 @@ class SpendingWidget extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: UiConstants.space3),
|
|
||||||
Container(
|
|
||||||
padding: const EdgeInsets.only(top: UiConstants.space3),
|
|
||||||
decoration: const BoxDecoration(
|
|
||||||
border: Border(top: BorderSide(color: Colors.white24)),
|
|
||||||
),
|
|
||||||
child: Row(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: <Widget>[
|
|
||||||
Container(
|
|
||||||
width: 24,
|
|
||||||
height: 24,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.white.withValues(alpha: 0.2),
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
),
|
|
||||||
child: const Center(
|
|
||||||
child: Icon(
|
|
||||||
UiIcons.sparkles,
|
|
||||||
color: UiColors.white,
|
|
||||||
size: 14,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: UiConstants.space2),
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: <Widget>[
|
|
||||||
Text(
|
|
||||||
'💡 ' +
|
|
||||||
i18n.dashboard.insight_lightbulb(amount: '180'),
|
|
||||||
style: const TextStyle(
|
|
||||||
color: Colors.white,
|
|
||||||
fontSize: 10,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 1),
|
|
||||||
Text(
|
|
||||||
i18n.dashboard.insight_tip,
|
|
||||||
style: TextStyle(
|
|
||||||
color: Colors.white.withValues(alpha: 0.8),
|
|
||||||
fontSize: 9,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -308,14 +308,15 @@ class _ViewOrderCardState extends State<ViewOrderCard> {
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Row(
|
Row(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
|
if (order.workersNeeded != 0)
|
||||||
const Icon(
|
const Icon(
|
||||||
UiIcons.success,
|
UiIcons.error,
|
||||||
size: 16,
|
size: 16,
|
||||||
color: UiColors.textSuccess,
|
color: UiColors.textError,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
Text(
|
Text(
|
||||||
'${order.workersNeeded} Workers Filled',
|
'${order.workersNeeded} Workers Needed',
|
||||||
style: UiTypography.body2m.textPrimary,
|
style: UiTypography.body2m.textPrimary,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
Reference in New Issue
Block a user