refactor: Standardize shift details UI by adopting UiButton and UiChip components, adjusting layout, and refining chip styling.
This commit is contained in:
@@ -29,7 +29,6 @@ enum UiChipVariant {
|
|||||||
|
|
||||||
/// A custom chip widget with supports for different sizes, themes, and icons.
|
/// A custom chip widget with supports for different sizes, themes, and icons.
|
||||||
class UiChip extends StatelessWidget {
|
class UiChip extends StatelessWidget {
|
||||||
|
|
||||||
/// Creates a [UiChip].
|
/// Creates a [UiChip].
|
||||||
const UiChip({
|
const UiChip({
|
||||||
super.key,
|
super.key,
|
||||||
@@ -42,6 +41,7 @@ class UiChip extends StatelessWidget {
|
|||||||
this.onTrailingIconTap,
|
this.onTrailingIconTap,
|
||||||
this.isSelected = false,
|
this.isSelected = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
/// The text label to display.
|
/// The text label to display.
|
||||||
final String label;
|
final String label;
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ class UiChip extends StatelessWidget {
|
|||||||
padding: padding,
|
padding: padding,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: backgroundColor,
|
color: backgroundColor,
|
||||||
borderRadius: UiConstants.radiusFull,
|
borderRadius: UiConstants.radiusMd,
|
||||||
border: _getBorder(),
|
border: _getBorder(),
|
||||||
),
|
),
|
||||||
child: content,
|
child: content,
|
||||||
|
|||||||
@@ -140,8 +140,6 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
|
|||||||
children: [
|
children: [
|
||||||
ShiftDetailsHeader(shift: displayShift),
|
ShiftDetailsHeader(shift: displayShift),
|
||||||
const Divider(height: 1, thickness: 0.5),
|
const Divider(height: 1, thickness: 0.5),
|
||||||
ShiftScheduleSummarySection(shift: displayShift),
|
|
||||||
const Divider(height: 1, thickness: 0.5),
|
|
||||||
ShiftStatsRow(
|
ShiftStatsRow(
|
||||||
estimatedTotal: estimatedTotal,
|
estimatedTotal: estimatedTotal,
|
||||||
hourlyRate: displayShift.hourlyRate,
|
hourlyRate: displayShift.hourlyRate,
|
||||||
@@ -160,6 +158,8 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
|
|||||||
clockOutLabel: i18n.end_time,
|
clockOutLabel: i18n.end_time,
|
||||||
),
|
),
|
||||||
const Divider(height: 1, thickness: 0.5),
|
const Divider(height: 1, thickness: 0.5),
|
||||||
|
ShiftScheduleSummarySection(shift: displayShift),
|
||||||
|
const Divider(height: 1, thickness: 0.5),
|
||||||
if (displayShift.breakInfo != null &&
|
if (displayShift.breakInfo != null &&
|
||||||
displayShift.breakInfo!.duration !=
|
displayShift.breakInfo!.duration !=
|
||||||
BreakDuration.none) ...[
|
BreakDuration.none) ...[
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
|
import 'package:core_localization/core_localization.dart';
|
||||||
import 'package:design_system/design_system.dart';
|
import 'package:design_system/design_system.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_modular/flutter_modular.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_core/core.dart';
|
||||||
|
import 'package:krow_domain/krow_domain.dart';
|
||||||
|
|
||||||
/// A bottom action bar containing contextual buttons based on shift status.
|
/// A bottom action bar containing contextual buttons based on shift status.
|
||||||
class ShiftDetailsBottomBar extends StatelessWidget {
|
class ShiftDetailsBottomBar extends StatelessWidget {
|
||||||
/// The current shift.
|
/// The current shift.
|
||||||
final Shift shift;
|
final Shift shift;
|
||||||
|
|
||||||
/// Callback for applying/booking a shift.
|
/// Callback for applying/booking a shift.
|
||||||
final VoidCallback onApply;
|
final VoidCallback onApply;
|
||||||
|
|
||||||
/// Callback for declining a shift.
|
/// Callback for declining a shift.
|
||||||
final VoidCallback onDecline;
|
final VoidCallback onDecline;
|
||||||
|
|
||||||
/// Callback for accepting a shift.
|
/// Callback for accepting a shift.
|
||||||
final VoidCallback onAccept;
|
final VoidCallback onAccept;
|
||||||
|
|
||||||
@@ -57,19 +57,9 @@ class ShiftDetailsBottomBar extends StatelessWidget {
|
|||||||
|
|
||||||
Widget _buildButtons(String status, dynamic i18n, BuildContext context) {
|
Widget _buildButtons(String status, dynamic i18n, BuildContext context) {
|
||||||
if (status == 'confirmed') {
|
if (status == 'confirmed') {
|
||||||
return SizedBox(
|
return Expanded(
|
||||||
width: double.infinity,
|
child: UiButton.primary(
|
||||||
child: ElevatedButton(
|
|
||||||
onPressed: () => Modular.to.toClockIn(),
|
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),
|
child: Text(i18n.clock_in, style: UiTypography.body2b.white),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -79,36 +69,15 @@ class ShiftDetailsBottomBar extends StatelessWidget {
|
|||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: OutlinedButton(
|
child: UiButton.secondary(
|
||||||
onPressed: onDecline,
|
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),
|
child: Text(i18n.decline, style: UiTypography.body2b.textError),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: UiConstants.space4),
|
const SizedBox(width: UiConstants.space4),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ElevatedButton(
|
child: UiButton.primary(
|
||||||
onPressed: onAccept,
|
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),
|
child: Text(i18n.accept_shift, style: UiTypography.body2b.white),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -117,17 +86,9 @@ class ShiftDetailsBottomBar extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (status == 'open' || status == 'available') {
|
if (status == 'open' || status == 'available') {
|
||||||
return ElevatedButton(
|
return UiButton.primary(
|
||||||
onPressed: onApply,
|
onPressed: onApply,
|
||||||
style: ElevatedButton.styleFrom(
|
fullWidth: true,
|
||||||
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.apply_now, style: UiTypography.body2b.white),
|
child: Text(i18n.apply_now, style: UiTypography.body2b.white),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,14 +41,10 @@ class ShiftScheduleSummarySection extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
// Shift Type Title
|
// Shift Type Title
|
||||||
Text(
|
UiChip(label: typeLabel, variant: UiChipVariant.secondary),
|
||||||
typeLabel.toUpperCase(),
|
const SizedBox(height: UiConstants.space2),
|
||||||
style: UiTypography.titleUppercase4b.textSecondary,
|
|
||||||
),
|
|
||||||
|
|
||||||
if (isMultiDay) ...[
|
if (isMultiDay) ...[
|
||||||
const SizedBox(height: UiConstants.space3),
|
|
||||||
|
|
||||||
// Date Range
|
// Date Range
|
||||||
if (shift.startDate != null && shift.endDate != null)
|
if (shift.startDate != null && shift.endDate != null)
|
||||||
Row(
|
Row(
|
||||||
|
|||||||
Reference in New Issue
Block a user