refactor: Standardize shift details UI by adopting UiButton and UiChip components, adjusting layout, and refining chip styling.

This commit is contained in:
Achintha Isuru
2026-02-22 19:59:22 -05:00
parent c48d981ddb
commit 68d6e7c5e3
4 changed files with 17 additions and 60 deletions

View File

@@ -29,7 +29,6 @@ enum UiChipVariant {
/// A custom chip widget with supports for different sizes, themes, and icons.
class UiChip extends StatelessWidget {
/// Creates a [UiChip].
const UiChip({
super.key,
@@ -42,6 +41,7 @@ class UiChip extends StatelessWidget {
this.onTrailingIconTap,
this.isSelected = false,
});
/// The text label to display.
final String label;
@@ -99,7 +99,7 @@ class UiChip extends StatelessWidget {
padding: padding,
decoration: BoxDecoration(
color: backgroundColor,
borderRadius: UiConstants.radiusFull,
borderRadius: UiConstants.radiusMd,
border: _getBorder(),
),
child: content,

View File

@@ -140,8 +140,6 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
children: [
ShiftDetailsHeader(shift: displayShift),
const Divider(height: 1, thickness: 0.5),
ShiftScheduleSummarySection(shift: displayShift),
const Divider(height: 1, thickness: 0.5),
ShiftStatsRow(
estimatedTotal: estimatedTotal,
hourlyRate: displayShift.hourlyRate,
@@ -160,6 +158,8 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
clockOutLabel: i18n.end_time,
),
const Divider(height: 1, thickness: 0.5),
ShiftScheduleSummarySection(shift: displayShift),
const Divider(height: 1, thickness: 0.5),
if (displayShift.breakInfo != null &&
displayShift.breakInfo!.duration !=
BreakDuration.none) ...[

View File

@@ -1,21 +1,21 @@
import 'package:core_localization/core_localization.dart';
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter_modular/flutter_modular.dart';
import 'package:krow_domain/krow_domain.dart';
import 'package:core_localization/core_localization.dart';
import 'package:krow_core/core.dart';
import 'package:krow_domain/krow_domain.dart';
/// A bottom action bar containing contextual buttons based on shift status.
class ShiftDetailsBottomBar extends StatelessWidget {
/// The current shift.
final Shift shift;
/// Callback for applying/booking a shift.
final VoidCallback onApply;
/// Callback for declining a shift.
final VoidCallback onDecline;
/// Callback for accepting a shift.
final VoidCallback onAccept;
@@ -57,19 +57,9 @@ class ShiftDetailsBottomBar extends StatelessWidget {
Widget _buildButtons(String status, dynamic i18n, BuildContext context) {
if (status == 'confirmed') {
return SizedBox(
width: double.infinity,
child: ElevatedButton(
return Expanded(
child: UiButton.primary(
onPressed: () => Modular.to.toClockIn(),
style: ElevatedButton.styleFrom(
backgroundColor: UiColors.success,
foregroundColor: UiColors.white,
padding: const EdgeInsets.symmetric(vertical: UiConstants.space4),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(UiConstants.radiusBase),
),
elevation: 0,
),
child: Text(i18n.clock_in, style: UiTypography.body2b.white),
),
);
@@ -79,36 +69,15 @@ class ShiftDetailsBottomBar extends StatelessWidget {
return Row(
children: [
Expanded(
child: OutlinedButton(
child: UiButton.secondary(
onPressed: onDecline,
style: OutlinedButton.styleFrom(
foregroundColor: UiColors.destructive,
padding: const EdgeInsets.symmetric(
vertical: UiConstants.space4,
),
side: const BorderSide(color: UiColors.destructive),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(UiConstants.radiusBase),
),
),
child: Text(i18n.decline, style: UiTypography.body2b.textError),
),
),
const SizedBox(width: UiConstants.space4),
Expanded(
child: ElevatedButton(
child: UiButton.primary(
onPressed: onAccept,
style: ElevatedButton.styleFrom(
backgroundColor: UiColors.primary,
foregroundColor: UiColors.white,
padding: const EdgeInsets.symmetric(
vertical: UiConstants.space4,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(UiConstants.radiusBase),
),
elevation: 0,
),
child: Text(i18n.accept_shift, style: UiTypography.body2b.white),
),
),
@@ -117,17 +86,9 @@ class ShiftDetailsBottomBar extends StatelessWidget {
}
if (status == 'open' || status == 'available') {
return ElevatedButton(
return UiButton.primary(
onPressed: onApply,
style: ElevatedButton.styleFrom(
backgroundColor: UiColors.primary,
foregroundColor: UiColors.white,
padding: const EdgeInsets.symmetric(vertical: UiConstants.space4),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(UiConstants.radiusBase),
),
elevation: 0,
),
fullWidth: true,
child: Text(i18n.apply_now, style: UiTypography.body2b.white),
);
}

View File

@@ -41,14 +41,10 @@ class ShiftScheduleSummarySection extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Shift Type Title
Text(
typeLabel.toUpperCase(),
style: UiTypography.titleUppercase4b.textSecondary,
),
UiChip(label: typeLabel, variant: UiChipVariant.secondary),
const SizedBox(height: UiConstants.space2),
if (isMultiDay) ...[
const SizedBox(height: UiConstants.space3),
// Date Range
if (shift.startDate != null && shift.endDate != null)
Row(