feat: Add required and filled slots to Shift entity and update ShiftDetailsPage for capacity display
This commit is contained in:
@@ -24,6 +24,8 @@ class Shift extends Equatable {
|
||||
final double? longitude;
|
||||
final String? status;
|
||||
final int? durationDays; // For multi-day shifts
|
||||
final int? requiredSlots;
|
||||
final int? filledSlots;
|
||||
|
||||
const Shift({
|
||||
required this.id,
|
||||
@@ -49,6 +51,8 @@ class Shift extends Equatable {
|
||||
this.longitude,
|
||||
this.status,
|
||||
this.durationDays,
|
||||
this.requiredSlots,
|
||||
this.filledSlots,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -76,6 +80,8 @@ class Shift extends Equatable {
|
||||
longitude,
|
||||
status,
|
||||
durationDays,
|
||||
requiredSlots,
|
||||
filledSlots,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -127,6 +127,8 @@ class ShiftsRepositoryImpl implements ShiftsRepositoryInterface {
|
||||
status: _mapStatus(status),
|
||||
description: shift.description,
|
||||
durationDays: shift.durationDays,
|
||||
requiredSlots: shift.requiredSlots,
|
||||
filledSlots: shift.filledSlots,
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -182,6 +184,8 @@ class ShiftsRepositoryImpl implements ShiftsRepositoryInterface {
|
||||
status: s.status?.stringValue.toLowerCase() ?? 'open',
|
||||
description: s.description,
|
||||
durationDays: s.durationDays,
|
||||
requiredSlots: null, // Basic list doesn't fetch detailed role stats yet
|
||||
filledSlots: null,
|
||||
));
|
||||
}
|
||||
|
||||
@@ -210,6 +214,20 @@ class ShiftsRepositoryImpl implements ShiftsRepositoryInterface {
|
||||
final s = result.data.shift;
|
||||
if (s == null) return null;
|
||||
|
||||
int? required;
|
||||
int? filled;
|
||||
try {
|
||||
final rolesRes = await _dataConnect.listShiftRolesByShiftId(shiftId: shiftId).execute();
|
||||
if (rolesRes.data.shiftRoles.isNotEmpty) {
|
||||
required = 0;
|
||||
filled = 0;
|
||||
for(var r in rolesRes.data.shiftRoles) {
|
||||
required = (required ?? 0) + r.count;
|
||||
filled = (filled ?? 0) + (r.assigned ?? 0);
|
||||
}
|
||||
}
|
||||
} catch (_) {}
|
||||
|
||||
final startDt = _toDateTime(s.startTime);
|
||||
final endDt = _toDateTime(s.endTime);
|
||||
final createdDt = _toDateTime(s.createdAt);
|
||||
@@ -229,6 +247,8 @@ class ShiftsRepositoryImpl implements ShiftsRepositoryInterface {
|
||||
status: s.status?.stringValue ?? 'OPEN',
|
||||
description: s.description,
|
||||
durationDays: s.durationDays,
|
||||
requiredSlots: required,
|
||||
filledSlots: filled,
|
||||
);
|
||||
} catch (e) {
|
||||
return null;
|
||||
|
||||
@@ -3,22 +3,16 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_modular/flutter_modular.dart';
|
||||
import 'package:krow_domain/krow_domain.dart';
|
||||
import 'package:design_system/design_system.dart'; // Re-added for UiIcons/Colors as they are used in expanded logic
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import '../blocs/shift_details/shift_details_bloc.dart';
|
||||
import '../blocs/shift_details/shift_details_event.dart';
|
||||
import '../blocs/shift_details/shift_details_state.dart';
|
||||
import '../styles/shifts_styles.dart';
|
||||
import '../widgets/my_shift_card.dart';
|
||||
|
||||
class ShiftDetailsPage extends StatelessWidget {
|
||||
final String shiftId;
|
||||
final Shift? shift;
|
||||
|
||||
const ShiftDetailsPage({
|
||||
super.key,
|
||||
required this.shiftId,
|
||||
this.shift,
|
||||
});
|
||||
const ShiftDetailsPage({super.key, required this.shiftId, this.shift});
|
||||
|
||||
String _formatTime(String time) {
|
||||
if (time.isEmpty) return '';
|
||||
@@ -33,6 +27,16 @@ class ShiftDetailsPage extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
String _formatDate(String dateStr) {
|
||||
if (dateStr.isEmpty) return '';
|
||||
try {
|
||||
final date = DateTime.parse(dateStr);
|
||||
return DateFormat('EEEE, MMMM d, y').format(date);
|
||||
} catch (e) {
|
||||
return dateStr;
|
||||
}
|
||||
}
|
||||
|
||||
double _calculateDuration(Shift shift) {
|
||||
if (shift.startTime.isEmpty || shift.endTime.isEmpty) {
|
||||
return 0;
|
||||
@@ -70,9 +74,7 @@ class ShiftDetailsPage extends StatelessWidget {
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
value,
|
||||
style: UiTypography.title1m.copyWith(
|
||||
color: UiColors.textPrimary,
|
||||
),
|
||||
style: UiTypography.title1m.copyWith(color: UiColors.textPrimary),
|
||||
),
|
||||
Text(
|
||||
label,
|
||||
@@ -118,9 +120,9 @@ class ShiftDetailsPage extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (_) => Modular.get<ShiftDetailsBloc>()
|
||||
..add(LoadShiftDetailsEvent(shiftId)),
|
||||
return BlocProvider<ShiftDetailsBloc>(
|
||||
create: (_) =>
|
||||
Modular.get<ShiftDetailsBloc>()..add(LoadShiftDetailsEvent(shiftId)),
|
||||
child: BlocListener<ShiftDetailsBloc, ShiftDetailsState>(
|
||||
listener: (context, state) {
|
||||
if (state is ShiftActionSuccess) {
|
||||
@@ -163,213 +165,322 @@ class ShiftDetailsPage extends StatelessWidget {
|
||||
|
||||
final duration = _calculateDuration(displayShift);
|
||||
final estimatedTotal = (displayShift.hourlyRate) * duration;
|
||||
final openSlots =
|
||||
(displayShift.requiredSlots ?? 0) -
|
||||
(displayShift.filledSlots ?? 0);
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: AppColors.krowBackground,
|
||||
appBar: AppBar(
|
||||
title: const Text("Shift Details"),
|
||||
backgroundColor: Colors.white,
|
||||
foregroundColor: AppColors.krowCharcoal,
|
||||
elevation: 0.5,
|
||||
appBar: UiAppBar(
|
||||
title: displayShift.title,
|
||||
showBackButton: true,
|
||||
centerTitle: false,
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(20.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
MyShiftCard(
|
||||
shift: displayShift,
|
||||
// No direct actions on the card, handled by page buttons
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// Stats Row
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: _buildStatCard(
|
||||
UiIcons.dollar,
|
||||
"\$${estimatedTotal.toStringAsFixed(0)}",
|
||||
"Total",
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(20.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Vendor Section
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
"VENDOR",
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: UiColors.textSecondary,
|
||||
letterSpacing: 0.5,
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: _buildStatCard(
|
||||
UiIcons.dollar,
|
||||
"\$${displayShift.hourlyRate.toInt()}",
|
||||
"Hourly Rate",
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: _buildStatCard(
|
||||
UiIcons.clock,
|
||||
"${duration.toInt()}",
|
||||
"Hours",
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// In/Out Time
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: _buildTimeBox(
|
||||
"CLOCK IN TIME",
|
||||
displayShift.startTime,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: _buildTimeBox(
|
||||
"CLOCK OUT TIME",
|
||||
displayShift.endTime,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// Location
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
"LOCATION",
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: UiColors.textSecondary,
|
||||
letterSpacing: 0.5,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
displayShift.location.isEmpty
|
||||
? "TBD"
|
||||
: displayShift.location,
|
||||
style: UiTypography.title1m.copyWith(
|
||||
color: UiColors.textPrimary,
|
||||
),
|
||||
),
|
||||
OutlinedButton.icon(
|
||||
onPressed: () {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(displayShift!.locationAddress),
|
||||
duration: const Duration(seconds: 3),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 24,
|
||||
height: 24,
|
||||
child: displayShift.logoUrl != null
|
||||
? ClipRRect(
|
||||
borderRadius: BorderRadius.circular(
|
||||
6,
|
||||
),
|
||||
child: Image.network(
|
||||
displayShift.logoUrl!,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
)
|
||||
: const Center(
|
||||
child: Icon(
|
||||
UiIcons.briefcase,
|
||||
color: UiColors.primary,
|
||||
size: 20,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
icon: const Icon(UiIcons.navigation, size: 14),
|
||||
label: const Text(
|
||||
"Get direction",
|
||||
style: TextStyle(fontSize: 12),
|
||||
),
|
||||
style: OutlinedButton.styleFrom(
|
||||
foregroundColor: UiColors.textPrimary,
|
||||
side: const BorderSide(color: UiColors.border),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 0),
|
||||
minimumSize: const Size(0, 32),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Container(
|
||||
height: 128,
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey.shade100,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: const Center(
|
||||
child: Icon(
|
||||
UiIcons.mapPin,
|
||||
color: UiColors.iconSecondary,
|
||||
size: 32,
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
displayShift.clientName,
|
||||
style: UiTypography.headline5m.copyWith(
|
||||
color: UiColors.textPrimary,
|
||||
),
|
||||
),
|
||||
// Placeholder for Map
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// Additional Info
|
||||
if (displayShift.description != null) ...[
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
"ADDITIONAL INFO",
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: UiColors.textSecondary,
|
||||
letterSpacing: 0.5,
|
||||
),
|
||||
// Date Section
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
"SHIFT DATE",
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: UiColors.textSecondary,
|
||||
letterSpacing: 0.5,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
children: [
|
||||
const Icon(
|
||||
UiIcons.calendar,
|
||||
size: 20,
|
||||
color: UiColors.primary,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
_formatDate(displayShift.date),
|
||||
style: UiTypography.headline5m.copyWith(
|
||||
color: UiColors.textPrimary,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
displayShift.description!,
|
||||
style: UiTypography.body2m.copyWith(
|
||||
color: UiColors.textPrimary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// Worker Capacity / Open Slots
|
||||
if ((displayShift.requiredSlots ?? 0) > 0)
|
||||
Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF0FDF4), // green-50
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(
|
||||
color: const Color(0xFFBBF7D0),
|
||||
), // green-200
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.people_alt_outlined,
|
||||
size: 20,
|
||||
color: Color(0xFF15803D),
|
||||
), // green-700, using Material Icon as generic fallback
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"$openSlots spots remaining",
|
||||
style: UiTypography.body2b.copyWith(
|
||||
color: const Color(0xFF15803D),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
"${displayShift.filledSlots ?? 0} filled out of ${displayShift.requiredSlots}",
|
||||
style: UiTypography.body3r.copyWith(
|
||||
color: const Color(0xFF166534),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
width: 60,
|
||||
child: LinearProgressIndicator(
|
||||
value: (displayShift.requiredSlots! > 0)
|
||||
? (displayShift.filledSlots ?? 0) /
|
||||
displayShift.requiredSlots!
|
||||
: 0,
|
||||
backgroundColor: Colors.white,
|
||||
color: const Color(0xFF15803D),
|
||||
minHeight: 6,
|
||||
borderRadius: BorderRadius.circular(3),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// Stats Grid
|
||||
GridView.count(
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
crossAxisCount: 3,
|
||||
crossAxisSpacing: 12,
|
||||
childAspectRatio: 0.85,
|
||||
children: [
|
||||
_buildStatCard(
|
||||
UiIcons.dollar,
|
||||
"\$${estimatedTotal.toStringAsFixed(0)}",
|
||||
"Total Pay",
|
||||
),
|
||||
_buildStatCard(
|
||||
UiIcons.dollar,
|
||||
"\$${displayShift.hourlyRate.toInt()}",
|
||||
"Per Hour",
|
||||
),
|
||||
_buildStatCard(
|
||||
UiIcons.clock,
|
||||
"${duration.toInt()}h",
|
||||
"Duration",
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// Shift Timing
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: _buildTimeBox(
|
||||
"START TIME",
|
||||
displayShift.startTime,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: _buildTimeBox(
|
||||
"END TIME",
|
||||
displayShift.endTime,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// Location
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
"LOCATION",
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: UiColors.textSecondary,
|
||||
letterSpacing: 0.5,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
displayShift.location.isEmpty
|
||||
? "TBD"
|
||||
: displayShift.location,
|
||||
style: UiTypography.title1m.copyWith(
|
||||
color: UiColors.textPrimary,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
displayShift.location.isEmpty
|
||||
? "TBD"
|
||||
: displayShift.locationAddress,
|
||||
style: UiTypography.title1m.copyWith(
|
||||
color: UiColors.textPrimary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// Additional Info
|
||||
if (displayShift.description != null) ...[
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
"ADDITIONAL INFO",
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: UiColors.textSecondary,
|
||||
letterSpacing: 0.5,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
displayShift.description!,
|
||||
style: UiTypography.body2m.copyWith(
|
||||
color: UiColors.textPrimary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: OutlinedButton(
|
||||
onPressed: () =>
|
||||
_declineShift(context, displayShift!.id),
|
||||
style: OutlinedButton.styleFrom(
|
||||
foregroundColor: const Color(0xFFEF4444),
|
||||
side: const BorderSide(
|
||||
color: Color(0xFFEF4444),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 16,
|
||||
),
|
||||
),
|
||||
child: const Text("Decline"),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: ElevatedButton(
|
||||
onPressed: () =>
|
||||
_bookShift(context, displayShift!.id),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: const Color(0xFF10B981),
|
||||
foregroundColor: Colors.white,
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 16,
|
||||
),
|
||||
),
|
||||
child: const Text("Book Shift"),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: MediaQuery.of(context).padding.bottom + 10,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: OutlinedButton(
|
||||
onPressed: () => _declineShift(context, displayShift!.id),
|
||||
style: OutlinedButton.styleFrom(
|
||||
foregroundColor: const Color(0xFFEF4444),
|
||||
side: const BorderSide(color: Color(0xFFEF4444)),
|
||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||
),
|
||||
child: const Text("Decline"),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: ElevatedButton(
|
||||
onPressed: () => _bookShift(context, displayShift!.id),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: const Color(0xFF10B981),
|
||||
foregroundColor: Colors.white,
|
||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||
),
|
||||
child: const Text("Book Shift"),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: MediaQuery.of(context).padding.bottom + 10),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
@@ -392,7 +503,9 @@ class ShiftDetailsPage extends StatelessWidget {
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.of(ctx).pop();
|
||||
BlocProvider.of<ShiftDetailsBloc>(context).add(BookShiftDetailsEvent(id));
|
||||
BlocProvider.of<ShiftDetailsBloc>(
|
||||
context,
|
||||
).add(BookShiftDetailsEvent(id));
|
||||
},
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor: const Color(0xFF10B981),
|
||||
@@ -410,7 +523,8 @@ class ShiftDetailsPage extends StatelessWidget {
|
||||
builder: (ctx) => AlertDialog(
|
||||
title: const Text('Decline Shift'),
|
||||
content: const Text(
|
||||
'Are you sure you want to decline this shift? It will be hidden from your available jobs.'),
|
||||
'Are you sure you want to decline this shift? It will be hidden from your available jobs.',
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(ctx).pop(),
|
||||
@@ -419,7 +533,9 @@ class ShiftDetailsPage extends StatelessWidget {
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.of(ctx).pop();
|
||||
BlocProvider.of<ShiftDetailsBloc>(context).add(DeclineShiftDetailsEvent(id));
|
||||
BlocProvider.of<ShiftDetailsBloc>(
|
||||
context,
|
||||
).add(DeclineShiftDetailsEvent(id));
|
||||
},
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor: const Color(0xFFEF4444),
|
||||
|
||||
Reference in New Issue
Block a user