Expose parseDouble; fix shift mapping and UI
Rename and expose numeric parser (from _parseDouble to parseDouble) with a doc comment so other modules can reuse it. Update ClockIn repository mapping to populate orderId and prefer clientName for the shift title, and map latitude/longitude using Shift.parseDouble. Remove outdated TODOs and remove the selected/today badge text from the shift card UI. These changes consolidate parsing logic, improve today-shift mapping fidelity, and simplify the shift card display.
This commit is contained in:
@@ -39,8 +39,8 @@ class Shift extends Equatable {
|
||||
timezone: json['timezone'] as String? ?? 'UTC',
|
||||
locationName: json['locationName'] as String?,
|
||||
locationAddress: json['locationAddress'] as String?,
|
||||
latitude: _parseDouble(json['latitude']),
|
||||
longitude: _parseDouble(json['longitude']),
|
||||
latitude: parseDouble(json['latitude']),
|
||||
longitude: parseDouble(json['longitude']),
|
||||
geofenceRadiusMeters: json['geofenceRadiusMeters'] as int?,
|
||||
requiredWorkers: json['requiredWorkers'] as int? ?? 1,
|
||||
assignedWorkers: json['assignedWorkers'] as int? ?? 0,
|
||||
@@ -114,7 +114,8 @@ class Shift extends Equatable {
|
||||
};
|
||||
}
|
||||
|
||||
static double? _parseDouble(dynamic value) {
|
||||
/// Safely parses a numeric value to double.
|
||||
static double? parseDouble(dynamic value) {
|
||||
if (value == null) return null;
|
||||
if (value is double) return value;
|
||||
if (value is int) return value.toDouble();
|
||||
|
||||
@@ -20,8 +20,6 @@ class ClockInRepositoryImpl implements ClockInRepositoryInterface {
|
||||
StaffEndpoints.clockInShiftsToday,
|
||||
);
|
||||
final List<dynamic> items = response.data['items'] as List<dynamic>;
|
||||
// TODO: Ask BE to add latitude, longitude, hourlyRate, and clientName
|
||||
// to the listTodayShifts query to avoid mapping gaps and extra API calls.
|
||||
return items
|
||||
.map(
|
||||
(dynamic json) =>
|
||||
@@ -75,23 +73,17 @@ class ClockInRepositoryImpl implements ClockInRepositoryInterface {
|
||||
}
|
||||
|
||||
/// Maps a V2 `listTodayShifts` JSON item to the domain [Shift] entity.
|
||||
///
|
||||
/// The today-shifts endpoint returns a lightweight shape that lacks some
|
||||
/// [Shift] fields. Missing fields are defaulted:
|
||||
/// - `orderId` defaults to empty string
|
||||
/// - `latitude` / `longitude` default to null (disables geofence)
|
||||
/// - `requiredWorkers` / `assignedWorkers` default to 0
|
||||
// TODO: Ask BE to add latitude/longitude to the listTodayShifts query
|
||||
// to avoid losing geofence validation.
|
||||
static Shift _mapTodayShiftJsonToShift(Map<String, dynamic> json) {
|
||||
return Shift(
|
||||
id: json['shiftId'] as String,
|
||||
orderId: '',
|
||||
title: json['roleName'] as String? ?? '',
|
||||
orderId: json['orderId'] as String? ?? '',
|
||||
title: json['clientName'] as String? ?? json['roleName'] as String? ?? '',
|
||||
status: ShiftStatus.fromJson(json['attendanceStatus'] as String?),
|
||||
startsAt: DateTime.parse(json['startTime'] as String),
|
||||
endsAt: DateTime.parse(json['endTime'] as String),
|
||||
locationName: json['location'] as String?,
|
||||
latitude: Shift.parseDouble(json['latitude']),
|
||||
longitude: Shift.parseDouble(json['longitude']),
|
||||
requiredWorkers: 0,
|
||||
assignedWorkers: 0,
|
||||
);
|
||||
|
||||
@@ -79,13 +79,6 @@ class _ShiftDetails extends StatelessWidget {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
isSelected ? i18n.selected_shift_badge : i18n.today_shift_badge,
|
||||
style: UiTypography.titleUppercase4b.copyWith(
|
||||
color: isSelected ? UiColors.primary : UiColors.textSecondary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(shift.title, style: UiTypography.body2b),
|
||||
// TODO: Ask BE to add clientName to the listTodayShifts response.
|
||||
// Currently showing locationName as subtitle fallback.
|
||||
|
||||
Reference in New Issue
Block a user