feat(breaks): Implement break functionality with Break entity and adapter
This commit is contained in:
@@ -141,6 +141,10 @@ class ShiftsRepositoryImpl
|
||||
requiredSlots: app.shiftRole.count,
|
||||
filledSlots: app.shiftRole.assigned ?? 0,
|
||||
hasApplied: true,
|
||||
breakInfo: BreakAdapter.fromData(
|
||||
isPaid: app.shiftRole.isBreakPaid ?? false,
|
||||
breakTime: app.shiftRole.breakType?.stringValue,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -208,6 +212,10 @@ class ShiftsRepositoryImpl
|
||||
requiredSlots: app.shiftRole.count,
|
||||
filledSlots: app.shiftRole.assigned ?? 0,
|
||||
hasApplied: true,
|
||||
breakInfo: BreakAdapter.fromData(
|
||||
isPaid: app.shiftRole.isBreakPaid ?? false,
|
||||
breakTime: app.shiftRole.breakType?.stringValue,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -277,6 +285,10 @@ class ShiftsRepositoryImpl
|
||||
durationDays: sr.shift.durationDays,
|
||||
requiredSlots: sr.count,
|
||||
filledSlots: sr.assigned ?? 0,
|
||||
breakInfo: BreakAdapter.fromData(
|
||||
isPaid: sr.isBreakPaid ?? false,
|
||||
breakTime: sr.breakType?.stringValue,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -350,6 +362,10 @@ class ShiftsRepositoryImpl
|
||||
filledSlots: sr.assigned ?? 0,
|
||||
hasApplied: hasApplied,
|
||||
totalValue: sr.totalValue,
|
||||
breakInfo: BreakAdapter.fromData(
|
||||
isPaid: sr.isBreakPaid ?? false,
|
||||
breakTime: sr.breakType?.stringValue,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -360,6 +376,7 @@ class ShiftsRepositoryImpl
|
||||
|
||||
int? required;
|
||||
int? filled;
|
||||
Break? breakInfo;
|
||||
try {
|
||||
final rolesRes = await executeProtected(() =>
|
||||
_dataConnect.listShiftRolesByShiftId(shiftId: shiftId).execute());
|
||||
@@ -370,6 +387,12 @@ class ShiftsRepositoryImpl
|
||||
required = (required ?? 0) + r.count;
|
||||
filled = (filled ?? 0) + (r.assigned ?? 0);
|
||||
}
|
||||
// Use the first role's break info as a representative
|
||||
final firstRole = rolesRes.data.shiftRoles.first;
|
||||
breakInfo = BreakAdapter.fromData(
|
||||
isPaid: firstRole.isBreakPaid ?? false,
|
||||
breakTime: firstRole.breakType?.stringValue,
|
||||
);
|
||||
}
|
||||
} catch (_) {}
|
||||
|
||||
@@ -394,6 +417,7 @@ class ShiftsRepositoryImpl
|
||||
durationDays: s.durationDays,
|
||||
requiredSlots: required,
|
||||
filledSlots: filled,
|
||||
breakInfo: breakInfo,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -132,7 +132,7 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
|
||||
return BlocProvider<ShiftDetailsBloc>(
|
||||
create: (_) => Modular.get<ShiftDetailsBloc>()
|
||||
..add(
|
||||
LoadShiftDetailsEvent(widget.shiftId, roleId: widget.shift?.roleId),
|
||||
LoadShiftDetailsEvent(widget.shiftId, roleId: widget.shift.roleId),
|
||||
),
|
||||
child: BlocListener<ShiftDetailsBloc, ShiftDetailsState>(
|
||||
listener: (context, state) {
|
||||
@@ -148,7 +148,7 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
|
||||
);
|
||||
Modular.to.toShifts(selectedDate: state.shiftDate);
|
||||
} else if (state is ShiftDetailsError) {
|
||||
if (_isApplying || widget.shift == null) {
|
||||
if (_isApplying) {
|
||||
UiSnackbar.show(
|
||||
context,
|
||||
message: translateErrorKey(state.message),
|
||||
@@ -240,7 +240,7 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
|
||||
|
||||
const Divider(height: 1, thickness: 0.5),
|
||||
|
||||
// Date Section
|
||||
// Date & Time Section
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(UiConstants.space5),
|
||||
child: Column(
|
||||
@@ -248,8 +248,7 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
|
||||
children: [
|
||||
Text(
|
||||
i18n.shift_date,
|
||||
style: UiTypography
|
||||
.titleUppercase4b
|
||||
style: UiTypography.titleUppercase4b
|
||||
.textSecondary,
|
||||
),
|
||||
const SizedBox(height: UiConstants.space2),
|
||||
@@ -268,6 +267,24 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: UiConstants.space4),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: _buildTimeBox(
|
||||
"CLOCK IN TIME",
|
||||
displayShift.startTime,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: UiConstants.space4),
|
||||
Expanded(
|
||||
child: _buildTimeBox(
|
||||
"CLOCK OUT TIME",
|
||||
displayShift.endTime,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -308,30 +325,6 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
|
||||
|
||||
const Divider(height: 1, thickness: 0.5),
|
||||
|
||||
// Time Section (New)
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(UiConstants.space5),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: _buildTimeBox(
|
||||
"CLOCK IN TIME",
|
||||
displayShift.startTime,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: UiConstants.space4),
|
||||
Expanded(
|
||||
child: _buildTimeBox(
|
||||
"CLOCK OUT TIME",
|
||||
displayShift.endTime,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
const Divider(height: 1, thickness: 0.5),
|
||||
|
||||
// Location Section (New with Map)
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(UiConstants.space5),
|
||||
@@ -344,7 +337,6 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
|
||||
.titleUppercase4b
|
||||
.textSecondary,
|
||||
),
|
||||
const SizedBox(height: UiConstants.space3),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
@@ -366,12 +358,10 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
|
||||
).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
displayShift!
|
||||
.locationAddress
|
||||
displayShift.locationAddress
|
||||
.isNotEmpty
|
||||
? displayShift!
|
||||
.locationAddress
|
||||
: displayShift!.location,
|
||||
? displayShift.locationAddress
|
||||
: displayShift.location,
|
||||
),
|
||||
duration: const Duration(
|
||||
seconds: 3,
|
||||
@@ -509,36 +499,6 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
|
||||
);
|
||||
}
|
||||
|
||||
void _declineShift(BuildContext context, String id) {
|
||||
final i18n = Translations.of(
|
||||
context,
|
||||
).staff_shifts.shift_details.decline_dialog;
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (ctx) => AlertDialog(
|
||||
title: Text(i18n.title),
|
||||
content: Text(i18n.message),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Modular.to.pop(),
|
||||
child: Text(Translations.of(context).common.cancel),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
BlocProvider.of<ShiftDetailsBloc>(
|
||||
context,
|
||||
).add(DeclineShiftDetailsEvent(id));
|
||||
},
|
||||
style: TextButton.styleFrom(foregroundColor: UiColors.destructive),
|
||||
child: Text(
|
||||
Translations.of(context).staff_shifts.shift_details.decline,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _showApplyingDialog(BuildContext context, Shift shift) {
|
||||
if (_actionDialogOpen) return;
|
||||
_actionDialogOpen = true;
|
||||
|
||||
Reference in New Issue
Block a user