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',
|
timezone: json['timezone'] as String? ?? 'UTC',
|
||||||
locationName: json['locationName'] as String?,
|
locationName: json['locationName'] as String?,
|
||||||
locationAddress: json['locationAddress'] as String?,
|
locationAddress: json['locationAddress'] as String?,
|
||||||
latitude: _parseDouble(json['latitude']),
|
latitude: parseDouble(json['latitude']),
|
||||||
longitude: _parseDouble(json['longitude']),
|
longitude: parseDouble(json['longitude']),
|
||||||
geofenceRadiusMeters: json['geofenceRadiusMeters'] as int?,
|
geofenceRadiusMeters: json['geofenceRadiusMeters'] as int?,
|
||||||
requiredWorkers: json['requiredWorkers'] as int? ?? 1,
|
requiredWorkers: json['requiredWorkers'] as int? ?? 1,
|
||||||
assignedWorkers: json['assignedWorkers'] as int? ?? 0,
|
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 == null) return null;
|
||||||
if (value is double) return value;
|
if (value is double) return value;
|
||||||
if (value is int) return value.toDouble();
|
if (value is int) return value.toDouble();
|
||||||
|
|||||||
@@ -20,8 +20,6 @@ class ClockInRepositoryImpl implements ClockInRepositoryInterface {
|
|||||||
StaffEndpoints.clockInShiftsToday,
|
StaffEndpoints.clockInShiftsToday,
|
||||||
);
|
);
|
||||||
final List<dynamic> items = response.data['items'] as List<dynamic>;
|
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
|
return items
|
||||||
.map(
|
.map(
|
||||||
(dynamic json) =>
|
(dynamic json) =>
|
||||||
@@ -75,23 +73,17 @@ class ClockInRepositoryImpl implements ClockInRepositoryInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Maps a V2 `listTodayShifts` JSON item to the domain [Shift] entity.
|
/// 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) {
|
static Shift _mapTodayShiftJsonToShift(Map<String, dynamic> json) {
|
||||||
return Shift(
|
return Shift(
|
||||||
id: json['shiftId'] as String,
|
id: json['shiftId'] as String,
|
||||||
orderId: '',
|
orderId: json['orderId'] as String? ?? '',
|
||||||
title: json['roleName'] as String? ?? '',
|
title: json['clientName'] as String? ?? json['roleName'] as String? ?? '',
|
||||||
status: ShiftStatus.fromJson(json['attendanceStatus'] as String?),
|
status: ShiftStatus.fromJson(json['attendanceStatus'] as String?),
|
||||||
startsAt: DateTime.parse(json['startTime'] as String),
|
startsAt: DateTime.parse(json['startTime'] as String),
|
||||||
endsAt: DateTime.parse(json['endTime'] as String),
|
endsAt: DateTime.parse(json['endTime'] as String),
|
||||||
locationName: json['location'] as String?,
|
locationName: json['location'] as String?,
|
||||||
|
latitude: Shift.parseDouble(json['latitude']),
|
||||||
|
longitude: Shift.parseDouble(json['longitude']),
|
||||||
requiredWorkers: 0,
|
requiredWorkers: 0,
|
||||||
assignedWorkers: 0,
|
assignedWorkers: 0,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -79,13 +79,6 @@ class _ShiftDetails extends StatelessWidget {
|
|||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: <Widget>[
|
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),
|
Text(shift.title, style: UiTypography.body2b),
|
||||||
// TODO: Ask BE to add clientName to the listTodayShifts response.
|
// TODO: Ask BE to add clientName to the listTodayShifts response.
|
||||||
// Currently showing locationName as subtitle fallback.
|
// Currently showing locationName as subtitle fallback.
|
||||||
|
|||||||
Reference in New Issue
Block a user