Merge remote-tracking branch 'origin/fix_staff_app_bugs' into 312-feature-integrate-google-maps-places-autocomplete-for-hub-address-validation

This commit is contained in:
Achintha Isuru
2026-02-01 16:35:32 -05:00
19 changed files with 19313 additions and 18268 deletions

View File

@@ -1,16 +1,16 @@
# Basic Usage
```dart
ExampleConnector.instance.createBusiness(createBusinessVariables).execute();
ExampleConnector.instance.updateBusiness(updateBusinessVariables).execute();
ExampleConnector.instance.deleteBusiness(deleteBusinessVariables).execute();
ExampleConnector.instance.createRecentPayment(createRecentPaymentVariables).execute();
ExampleConnector.instance.updateRecentPayment(updateRecentPaymentVariables).execute();
ExampleConnector.instance.deleteRecentPayment(deleteRecentPaymentVariables).execute();
ExampleConnector.instance.createStaffAvailability(createStaffAvailabilityVariables).execute();
ExampleConnector.instance.updateStaffAvailability(updateStaffAvailabilityVariables).execute();
ExampleConnector.instance.deleteStaffAvailability(deleteStaffAvailabilityVariables).execute();
ExampleConnector.instance.listTeamHudDepartments(listTeamHudDepartmentsVariables).execute();
ExampleConnector.instance.createApplication(createApplicationVariables).execute();
ExampleConnector.instance.updateApplicationStatus(updateApplicationStatusVariables).execute();
ExampleConnector.instance.deleteApplication(deleteApplicationVariables).execute();
ExampleConnector.instance.createStaffRole(createStaffRoleVariables).execute();
ExampleConnector.instance.deleteStaffRole(deleteStaffRoleVariables).execute();
ExampleConnector.instance.CreateUser(createUserVariables).execute();
ExampleConnector.instance.UpdateUser(updateUserVariables).execute();
ExampleConnector.instance.DeleteUser(deleteUserVariables).execute();
ExampleConnector.instance.createUserConversation(createUserConversationVariables).execute();
ExampleConnector.instance.updateUserConversation(updateUserConversationVariables).execute();
```
@@ -23,8 +23,8 @@ Optional fields can be discovered based on classes that have `Optional` object t
This is an example of a mutation with an optional field:
```dart
await ExampleConnector.instance.updateApplicationStatus({ ... })
.shiftId(...)
await ExampleConnector.instance.filterUsers({ ... })
.id(...)
.execute();
```

View File

@@ -0,0 +1,645 @@
part of 'generated.dart';
class GetApplicationByStaffShiftAndRoleVariablesBuilder {
String staffId;
String shiftId;
String roleId;
Optional<int> _offset = Optional.optional(nativeFromJson, nativeToJson);
Optional<int> _limit = Optional.optional(nativeFromJson, nativeToJson);
final FirebaseDataConnect _dataConnect; GetApplicationByStaffShiftAndRoleVariablesBuilder offset(int? t) {
_offset.value = t;
return this;
}
GetApplicationByStaffShiftAndRoleVariablesBuilder limit(int? t) {
_limit.value = t;
return this;
}
GetApplicationByStaffShiftAndRoleVariablesBuilder(this._dataConnect, {required this.staffId,required this.shiftId,required this.roleId,});
Deserializer<GetApplicationByStaffShiftAndRoleData> dataDeserializer = (dynamic json) => GetApplicationByStaffShiftAndRoleData.fromJson(jsonDecode(json));
Serializer<GetApplicationByStaffShiftAndRoleVariables> varsSerializer = (GetApplicationByStaffShiftAndRoleVariables vars) => jsonEncode(vars.toJson());
Future<QueryResult<GetApplicationByStaffShiftAndRoleData, GetApplicationByStaffShiftAndRoleVariables>> execute() {
return ref().execute();
}
QueryRef<GetApplicationByStaffShiftAndRoleData, GetApplicationByStaffShiftAndRoleVariables> ref() {
GetApplicationByStaffShiftAndRoleVariables vars= GetApplicationByStaffShiftAndRoleVariables(staffId: staffId,shiftId: shiftId,roleId: roleId,offset: _offset,limit: _limit,);
return _dataConnect.query("getApplicationByStaffShiftAndRole", dataDeserializer, varsSerializer, vars);
}
}
@immutable
class GetApplicationByStaffShiftAndRoleApplications {
final String id;
final String shiftId;
final String staffId;
final EnumValue<ApplicationStatus> status;
final Timestamp? appliedAt;
final Timestamp? checkInTime;
final Timestamp? checkOutTime;
final EnumValue<ApplicationOrigin> origin;
final Timestamp? createdAt;
final GetApplicationByStaffShiftAndRoleApplicationsShift shift;
final GetApplicationByStaffShiftAndRoleApplicationsShiftRole shiftRole;
GetApplicationByStaffShiftAndRoleApplications.fromJson(dynamic json):
id = nativeFromJson<String>(json['id']),
shiftId = nativeFromJson<String>(json['shiftId']),
staffId = nativeFromJson<String>(json['staffId']),
status = applicationStatusDeserializer(json['status']),
appliedAt = json['appliedAt'] == null ? null : Timestamp.fromJson(json['appliedAt']),
checkInTime = json['checkInTime'] == null ? null : Timestamp.fromJson(json['checkInTime']),
checkOutTime = json['checkOutTime'] == null ? null : Timestamp.fromJson(json['checkOutTime']),
origin = applicationOriginDeserializer(json['origin']),
createdAt = json['createdAt'] == null ? null : Timestamp.fromJson(json['createdAt']),
shift = GetApplicationByStaffShiftAndRoleApplicationsShift.fromJson(json['shift']),
shiftRole = GetApplicationByStaffShiftAndRoleApplicationsShiftRole.fromJson(json['shiftRole']);
@override
bool operator ==(Object other) {
if(identical(this, other)) {
return true;
}
if(other.runtimeType != runtimeType) {
return false;
}
final GetApplicationByStaffShiftAndRoleApplications otherTyped = other as GetApplicationByStaffShiftAndRoleApplications;
return id == otherTyped.id &&
shiftId == otherTyped.shiftId &&
staffId == otherTyped.staffId &&
status == otherTyped.status &&
appliedAt == otherTyped.appliedAt &&
checkInTime == otherTyped.checkInTime &&
checkOutTime == otherTyped.checkOutTime &&
origin == otherTyped.origin &&
createdAt == otherTyped.createdAt &&
shift == otherTyped.shift &&
shiftRole == otherTyped.shiftRole;
}
@override
int get hashCode => Object.hashAll([id.hashCode, shiftId.hashCode, staffId.hashCode, status.hashCode, appliedAt.hashCode, checkInTime.hashCode, checkOutTime.hashCode, origin.hashCode, createdAt.hashCode, shift.hashCode, shiftRole.hashCode]);
Map<String, dynamic> toJson() {
Map<String, dynamic> json = {};
json['id'] = nativeToJson<String>(id);
json['shiftId'] = nativeToJson<String>(shiftId);
json['staffId'] = nativeToJson<String>(staffId);
json['status'] =
applicationStatusSerializer(status)
;
if (appliedAt != null) {
json['appliedAt'] = appliedAt!.toJson();
}
if (checkInTime != null) {
json['checkInTime'] = checkInTime!.toJson();
}
if (checkOutTime != null) {
json['checkOutTime'] = checkOutTime!.toJson();
}
json['origin'] =
applicationOriginSerializer(origin)
;
if (createdAt != null) {
json['createdAt'] = createdAt!.toJson();
}
json['shift'] = shift.toJson();
json['shiftRole'] = shiftRole.toJson();
return json;
}
GetApplicationByStaffShiftAndRoleApplications({
required this.id,
required this.shiftId,
required this.staffId,
required this.status,
this.appliedAt,
this.checkInTime,
this.checkOutTime,
required this.origin,
this.createdAt,
required this.shift,
required this.shiftRole,
});
}
@immutable
class GetApplicationByStaffShiftAndRoleApplicationsShift {
final String id;
final String title;
final Timestamp? date;
final Timestamp? startTime;
final Timestamp? endTime;
final String? location;
final EnumValue<ShiftStatus>? status;
final GetApplicationByStaffShiftAndRoleApplicationsShiftOrder order;
GetApplicationByStaffShiftAndRoleApplicationsShift.fromJson(dynamic json):
id = nativeFromJson<String>(json['id']),
title = nativeFromJson<String>(json['title']),
date = json['date'] == null ? null : Timestamp.fromJson(json['date']),
startTime = json['startTime'] == null ? null : Timestamp.fromJson(json['startTime']),
endTime = json['endTime'] == null ? null : Timestamp.fromJson(json['endTime']),
location = json['location'] == null ? null : nativeFromJson<String>(json['location']),
status = json['status'] == null ? null : shiftStatusDeserializer(json['status']),
order = GetApplicationByStaffShiftAndRoleApplicationsShiftOrder.fromJson(json['order']);
@override
bool operator ==(Object other) {
if(identical(this, other)) {
return true;
}
if(other.runtimeType != runtimeType) {
return false;
}
final GetApplicationByStaffShiftAndRoleApplicationsShift otherTyped = other as GetApplicationByStaffShiftAndRoleApplicationsShift;
return id == otherTyped.id &&
title == otherTyped.title &&
date == otherTyped.date &&
startTime == otherTyped.startTime &&
endTime == otherTyped.endTime &&
location == otherTyped.location &&
status == otherTyped.status &&
order == otherTyped.order;
}
@override
int get hashCode => Object.hashAll([id.hashCode, title.hashCode, date.hashCode, startTime.hashCode, endTime.hashCode, location.hashCode, status.hashCode, order.hashCode]);
Map<String, dynamic> toJson() {
Map<String, dynamic> json = {};
json['id'] = nativeToJson<String>(id);
json['title'] = nativeToJson<String>(title);
if (date != null) {
json['date'] = date!.toJson();
}
if (startTime != null) {
json['startTime'] = startTime!.toJson();
}
if (endTime != null) {
json['endTime'] = endTime!.toJson();
}
if (location != null) {
json['location'] = nativeToJson<String?>(location);
}
if (status != null) {
json['status'] =
shiftStatusSerializer(status!)
;
}
json['order'] = order.toJson();
return json;
}
GetApplicationByStaffShiftAndRoleApplicationsShift({
required this.id,
required this.title,
this.date,
this.startTime,
this.endTime,
this.location,
this.status,
required this.order,
});
}
@immutable
class GetApplicationByStaffShiftAndRoleApplicationsShiftOrder {
final String id;
final String? eventName;
final GetApplicationByStaffShiftAndRoleApplicationsShiftOrderTeamHub teamHub;
final GetApplicationByStaffShiftAndRoleApplicationsShiftOrderBusiness business;
final GetApplicationByStaffShiftAndRoleApplicationsShiftOrderVendor? vendor;
GetApplicationByStaffShiftAndRoleApplicationsShiftOrder.fromJson(dynamic json):
id = nativeFromJson<String>(json['id']),
eventName = json['eventName'] == null ? null : nativeFromJson<String>(json['eventName']),
teamHub = GetApplicationByStaffShiftAndRoleApplicationsShiftOrderTeamHub.fromJson(json['teamHub']),
business = GetApplicationByStaffShiftAndRoleApplicationsShiftOrderBusiness.fromJson(json['business']),
vendor = json['vendor'] == null ? null : GetApplicationByStaffShiftAndRoleApplicationsShiftOrderVendor.fromJson(json['vendor']);
@override
bool operator ==(Object other) {
if(identical(this, other)) {
return true;
}
if(other.runtimeType != runtimeType) {
return false;
}
final GetApplicationByStaffShiftAndRoleApplicationsShiftOrder otherTyped = other as GetApplicationByStaffShiftAndRoleApplicationsShiftOrder;
return id == otherTyped.id &&
eventName == otherTyped.eventName &&
teamHub == otherTyped.teamHub &&
business == otherTyped.business &&
vendor == otherTyped.vendor;
}
@override
int get hashCode => Object.hashAll([id.hashCode, eventName.hashCode, teamHub.hashCode, business.hashCode, vendor.hashCode]);
Map<String, dynamic> toJson() {
Map<String, dynamic> json = {};
json['id'] = nativeToJson<String>(id);
if (eventName != null) {
json['eventName'] = nativeToJson<String?>(eventName);
}
json['teamHub'] = teamHub.toJson();
json['business'] = business.toJson();
if (vendor != null) {
json['vendor'] = vendor!.toJson();
}
return json;
}
GetApplicationByStaffShiftAndRoleApplicationsShiftOrder({
required this.id,
this.eventName,
required this.teamHub,
required this.business,
this.vendor,
});
}
@immutable
class GetApplicationByStaffShiftAndRoleApplicationsShiftOrderTeamHub {
final String address;
final String? placeId;
final String hubName;
GetApplicationByStaffShiftAndRoleApplicationsShiftOrderTeamHub.fromJson(dynamic json):
address = nativeFromJson<String>(json['address']),
placeId = json['placeId'] == null ? null : nativeFromJson<String>(json['placeId']),
hubName = nativeFromJson<String>(json['hubName']);
@override
bool operator ==(Object other) {
if(identical(this, other)) {
return true;
}
if(other.runtimeType != runtimeType) {
return false;
}
final GetApplicationByStaffShiftAndRoleApplicationsShiftOrderTeamHub otherTyped = other as GetApplicationByStaffShiftAndRoleApplicationsShiftOrderTeamHub;
return address == otherTyped.address &&
placeId == otherTyped.placeId &&
hubName == otherTyped.hubName;
}
@override
int get hashCode => Object.hashAll([address.hashCode, placeId.hashCode, hubName.hashCode]);
Map<String, dynamic> toJson() {
Map<String, dynamic> json = {};
json['address'] = nativeToJson<String>(address);
if (placeId != null) {
json['placeId'] = nativeToJson<String?>(placeId);
}
json['hubName'] = nativeToJson<String>(hubName);
return json;
}
GetApplicationByStaffShiftAndRoleApplicationsShiftOrderTeamHub({
required this.address,
this.placeId,
required this.hubName,
});
}
@immutable
class GetApplicationByStaffShiftAndRoleApplicationsShiftOrderBusiness {
final String id;
final String businessName;
final String? email;
final String? contactName;
final String? companyLogoUrl;
GetApplicationByStaffShiftAndRoleApplicationsShiftOrderBusiness.fromJson(dynamic json):
id = nativeFromJson<String>(json['id']),
businessName = nativeFromJson<String>(json['businessName']),
email = json['email'] == null ? null : nativeFromJson<String>(json['email']),
contactName = json['contactName'] == null ? null : nativeFromJson<String>(json['contactName']),
companyLogoUrl = json['companyLogoUrl'] == null ? null : nativeFromJson<String>(json['companyLogoUrl']);
@override
bool operator ==(Object other) {
if(identical(this, other)) {
return true;
}
if(other.runtimeType != runtimeType) {
return false;
}
final GetApplicationByStaffShiftAndRoleApplicationsShiftOrderBusiness otherTyped = other as GetApplicationByStaffShiftAndRoleApplicationsShiftOrderBusiness;
return id == otherTyped.id &&
businessName == otherTyped.businessName &&
email == otherTyped.email &&
contactName == otherTyped.contactName &&
companyLogoUrl == otherTyped.companyLogoUrl;
}
@override
int get hashCode => Object.hashAll([id.hashCode, businessName.hashCode, email.hashCode, contactName.hashCode, companyLogoUrl.hashCode]);
Map<String, dynamic> toJson() {
Map<String, dynamic> json = {};
json['id'] = nativeToJson<String>(id);
json['businessName'] = nativeToJson<String>(businessName);
if (email != null) {
json['email'] = nativeToJson<String?>(email);
}
if (contactName != null) {
json['contactName'] = nativeToJson<String?>(contactName);
}
if (companyLogoUrl != null) {
json['companyLogoUrl'] = nativeToJson<String?>(companyLogoUrl);
}
return json;
}
GetApplicationByStaffShiftAndRoleApplicationsShiftOrderBusiness({
required this.id,
required this.businessName,
this.email,
this.contactName,
this.companyLogoUrl,
});
}
@immutable
class GetApplicationByStaffShiftAndRoleApplicationsShiftOrderVendor {
final String id;
final String companyName;
GetApplicationByStaffShiftAndRoleApplicationsShiftOrderVendor.fromJson(dynamic json):
id = nativeFromJson<String>(json['id']),
companyName = nativeFromJson<String>(json['companyName']);
@override
bool operator ==(Object other) {
if(identical(this, other)) {
return true;
}
if(other.runtimeType != runtimeType) {
return false;
}
final GetApplicationByStaffShiftAndRoleApplicationsShiftOrderVendor otherTyped = other as GetApplicationByStaffShiftAndRoleApplicationsShiftOrderVendor;
return id == otherTyped.id &&
companyName == otherTyped.companyName;
}
@override
int get hashCode => Object.hashAll([id.hashCode, companyName.hashCode]);
Map<String, dynamic> toJson() {
Map<String, dynamic> json = {};
json['id'] = nativeToJson<String>(id);
json['companyName'] = nativeToJson<String>(companyName);
return json;
}
GetApplicationByStaffShiftAndRoleApplicationsShiftOrderVendor({
required this.id,
required this.companyName,
});
}
@immutable
class GetApplicationByStaffShiftAndRoleApplicationsShiftRole {
final String id;
final String roleId;
final int count;
final int? assigned;
final Timestamp? startTime;
final Timestamp? endTime;
final double? hours;
final double? totalValue;
final GetApplicationByStaffShiftAndRoleApplicationsShiftRoleRole role;
GetApplicationByStaffShiftAndRoleApplicationsShiftRole.fromJson(dynamic json):
id = nativeFromJson<String>(json['id']),
roleId = nativeFromJson<String>(json['roleId']),
count = nativeFromJson<int>(json['count']),
assigned = json['assigned'] == null ? null : nativeFromJson<int>(json['assigned']),
startTime = json['startTime'] == null ? null : Timestamp.fromJson(json['startTime']),
endTime = json['endTime'] == null ? null : Timestamp.fromJson(json['endTime']),
hours = json['hours'] == null ? null : nativeFromJson<double>(json['hours']),
totalValue = json['totalValue'] == null ? null : nativeFromJson<double>(json['totalValue']),
role = GetApplicationByStaffShiftAndRoleApplicationsShiftRoleRole.fromJson(json['role']);
@override
bool operator ==(Object other) {
if(identical(this, other)) {
return true;
}
if(other.runtimeType != runtimeType) {
return false;
}
final GetApplicationByStaffShiftAndRoleApplicationsShiftRole otherTyped = other as GetApplicationByStaffShiftAndRoleApplicationsShiftRole;
return id == otherTyped.id &&
roleId == otherTyped.roleId &&
count == otherTyped.count &&
assigned == otherTyped.assigned &&
startTime == otherTyped.startTime &&
endTime == otherTyped.endTime &&
hours == otherTyped.hours &&
totalValue == otherTyped.totalValue &&
role == otherTyped.role;
}
@override
int get hashCode => Object.hashAll([id.hashCode, roleId.hashCode, count.hashCode, assigned.hashCode, startTime.hashCode, endTime.hashCode, hours.hashCode, totalValue.hashCode, role.hashCode]);
Map<String, dynamic> toJson() {
Map<String, dynamic> json = {};
json['id'] = nativeToJson<String>(id);
json['roleId'] = nativeToJson<String>(roleId);
json['count'] = nativeToJson<int>(count);
if (assigned != null) {
json['assigned'] = nativeToJson<int?>(assigned);
}
if (startTime != null) {
json['startTime'] = startTime!.toJson();
}
if (endTime != null) {
json['endTime'] = endTime!.toJson();
}
if (hours != null) {
json['hours'] = nativeToJson<double?>(hours);
}
if (totalValue != null) {
json['totalValue'] = nativeToJson<double?>(totalValue);
}
json['role'] = role.toJson();
return json;
}
GetApplicationByStaffShiftAndRoleApplicationsShiftRole({
required this.id,
required this.roleId,
required this.count,
this.assigned,
this.startTime,
this.endTime,
this.hours,
this.totalValue,
required this.role,
});
}
@immutable
class GetApplicationByStaffShiftAndRoleApplicationsShiftRoleRole {
final String id;
final String name;
final double costPerHour;
GetApplicationByStaffShiftAndRoleApplicationsShiftRoleRole.fromJson(dynamic json):
id = nativeFromJson<String>(json['id']),
name = nativeFromJson<String>(json['name']),
costPerHour = nativeFromJson<double>(json['costPerHour']);
@override
bool operator ==(Object other) {
if(identical(this, other)) {
return true;
}
if(other.runtimeType != runtimeType) {
return false;
}
final GetApplicationByStaffShiftAndRoleApplicationsShiftRoleRole otherTyped = other as GetApplicationByStaffShiftAndRoleApplicationsShiftRoleRole;
return id == otherTyped.id &&
name == otherTyped.name &&
costPerHour == otherTyped.costPerHour;
}
@override
int get hashCode => Object.hashAll([id.hashCode, name.hashCode, costPerHour.hashCode]);
Map<String, dynamic> toJson() {
Map<String, dynamic> json = {};
json['id'] = nativeToJson<String>(id);
json['name'] = nativeToJson<String>(name);
json['costPerHour'] = nativeToJson<double>(costPerHour);
return json;
}
GetApplicationByStaffShiftAndRoleApplicationsShiftRoleRole({
required this.id,
required this.name,
required this.costPerHour,
});
}
@immutable
class GetApplicationByStaffShiftAndRoleData {
final List<GetApplicationByStaffShiftAndRoleApplications> applications;
GetApplicationByStaffShiftAndRoleData.fromJson(dynamic json):
applications = (json['applications'] as List<dynamic>)
.map((e) => GetApplicationByStaffShiftAndRoleApplications.fromJson(e))
.toList();
@override
bool operator ==(Object other) {
if(identical(this, other)) {
return true;
}
if(other.runtimeType != runtimeType) {
return false;
}
final GetApplicationByStaffShiftAndRoleData otherTyped = other as GetApplicationByStaffShiftAndRoleData;
return applications == otherTyped.applications;
}
@override
int get hashCode => applications.hashCode;
Map<String, dynamic> toJson() {
Map<String, dynamic> json = {};
json['applications'] = applications.map((e) => e.toJson()).toList();
return json;
}
GetApplicationByStaffShiftAndRoleData({
required this.applications,
});
}
@immutable
class GetApplicationByStaffShiftAndRoleVariables {
final String staffId;
final String shiftId;
final String roleId;
late final Optional<int>offset;
late final Optional<int>limit;
@Deprecated('fromJson is deprecated for Variable classes as they are no longer required for deserialization.')
GetApplicationByStaffShiftAndRoleVariables.fromJson(Map<String, dynamic> json):
staffId = nativeFromJson<String>(json['staffId']),
shiftId = nativeFromJson<String>(json['shiftId']),
roleId = nativeFromJson<String>(json['roleId']) {
offset = Optional.optional(nativeFromJson, nativeToJson);
offset.value = json['offset'] == null ? null : nativeFromJson<int>(json['offset']);
limit = Optional.optional(nativeFromJson, nativeToJson);
limit.value = json['limit'] == null ? null : nativeFromJson<int>(json['limit']);
}
@override
bool operator ==(Object other) {
if(identical(this, other)) {
return true;
}
if(other.runtimeType != runtimeType) {
return false;
}
final GetApplicationByStaffShiftAndRoleVariables otherTyped = other as GetApplicationByStaffShiftAndRoleVariables;
return staffId == otherTyped.staffId &&
shiftId == otherTyped.shiftId &&
roleId == otherTyped.roleId &&
offset == otherTyped.offset &&
limit == otherTyped.limit;
}
@override
int get hashCode => Object.hashAll([staffId.hashCode, shiftId.hashCode, roleId.hashCode, offset.hashCode, limit.hashCode]);
Map<String, dynamic> toJson() {
Map<String, dynamic> json = {};
json['staffId'] = nativeToJson<String>(staffId);
json['shiftId'] = nativeToJson<String>(shiftId);
json['roleId'] = nativeToJson<String>(roleId);
if(offset.state == OptionalState.set) {
json['offset'] = offset.toJson();
}
if(limit.state == OptionalState.set) {
json['limit'] = limit.toJson();
}
return json;
}
GetApplicationByStaffShiftAndRoleVariables({
required this.staffId,
required this.shiftId,
required this.roleId,
required this.offset,
required this.limit,
});
}

View File

@@ -4,6 +4,8 @@ class GetApplicationsByStaffIdVariablesBuilder {
String staffId;
Optional<int> _offset = Optional.optional(nativeFromJson, nativeToJson);
Optional<int> _limit = Optional.optional(nativeFromJson, nativeToJson);
Optional<Timestamp> _dayStart = Optional.optional((json) => json['dayStart'] = Timestamp.fromJson(json['dayStart']), defaultSerializer);
Optional<Timestamp> _dayEnd = Optional.optional((json) => json['dayEnd'] = Timestamp.fromJson(json['dayEnd']), defaultSerializer);
final FirebaseDataConnect _dataConnect; GetApplicationsByStaffIdVariablesBuilder offset(int? t) {
_offset.value = t;
@@ -13,6 +15,14 @@ class GetApplicationsByStaffIdVariablesBuilder {
_limit.value = t;
return this;
}
GetApplicationsByStaffIdVariablesBuilder dayStart(Timestamp? t) {
_dayStart.value = t;
return this;
}
GetApplicationsByStaffIdVariablesBuilder dayEnd(Timestamp? t) {
_dayEnd.value = t;
return this;
}
GetApplicationsByStaffIdVariablesBuilder(this._dataConnect, {required this.staffId,});
Deserializer<GetApplicationsByStaffIdData> dataDeserializer = (dynamic json) => GetApplicationsByStaffIdData.fromJson(jsonDecode(json));
@@ -22,7 +32,7 @@ class GetApplicationsByStaffIdVariablesBuilder {
}
QueryRef<GetApplicationsByStaffIdData, GetApplicationsByStaffIdVariables> ref() {
GetApplicationsByStaffIdVariables vars= GetApplicationsByStaffIdVariables(staffId: staffId,offset: _offset,limit: _limit,);
GetApplicationsByStaffIdVariables vars= GetApplicationsByStaffIdVariables(staffId: staffId,offset: _offset,limit: _limit,dayStart: _dayStart,dayEnd: _dayEnd,);
return _dataConnect.query("getApplicationsByStaffId", dataDeserializer, varsSerializer, vars);
}
}
@@ -132,6 +142,8 @@ class GetApplicationsByStaffIdApplicationsShift {
final Timestamp? endTime;
final String? location;
final EnumValue<ShiftStatus>? status;
final int? durationDays;
final String? description;
final GetApplicationsByStaffIdApplicationsShiftOrder order;
GetApplicationsByStaffIdApplicationsShift.fromJson(dynamic json):
@@ -142,6 +154,8 @@ class GetApplicationsByStaffIdApplicationsShift {
endTime = json['endTime'] == null ? null : Timestamp.fromJson(json['endTime']),
location = json['location'] == null ? null : nativeFromJson<String>(json['location']),
status = json['status'] == null ? null : shiftStatusDeserializer(json['status']),
durationDays = json['durationDays'] == null ? null : nativeFromJson<int>(json['durationDays']),
description = json['description'] == null ? null : nativeFromJson<String>(json['description']),
order = GetApplicationsByStaffIdApplicationsShiftOrder.fromJson(json['order']);
@override
bool operator ==(Object other) {
@@ -160,11 +174,13 @@ class GetApplicationsByStaffIdApplicationsShift {
endTime == otherTyped.endTime &&
location == otherTyped.location &&
status == otherTyped.status &&
durationDays == otherTyped.durationDays &&
description == otherTyped.description &&
order == otherTyped.order;
}
@override
int get hashCode => Object.hashAll([id.hashCode, title.hashCode, date.hashCode, startTime.hashCode, endTime.hashCode, location.hashCode, status.hashCode, order.hashCode]);
int get hashCode => Object.hashAll([id.hashCode, title.hashCode, date.hashCode, startTime.hashCode, endTime.hashCode, location.hashCode, status.hashCode, durationDays.hashCode, description.hashCode, order.hashCode]);
Map<String, dynamic> toJson() {
@@ -188,6 +204,12 @@ class GetApplicationsByStaffIdApplicationsShift {
shiftStatusSerializer(status!)
;
}
if (durationDays != null) {
json['durationDays'] = nativeToJson<int?>(durationDays);
}
if (description != null) {
json['description'] = nativeToJson<String?>(description);
}
json['order'] = order.toJson();
return json;
}
@@ -200,6 +222,8 @@ class GetApplicationsByStaffIdApplicationsShift {
this.endTime,
this.location,
this.status,
this.durationDays,
this.description,
required this.order,
});
}
@@ -314,12 +338,14 @@ class GetApplicationsByStaffIdApplicationsShiftOrderBusiness {
final String businessName;
final String? email;
final String? contactName;
final String? companyLogoUrl;
GetApplicationsByStaffIdApplicationsShiftOrderBusiness.fromJson(dynamic json):
id = nativeFromJson<String>(json['id']),
businessName = nativeFromJson<String>(json['businessName']),
email = json['email'] == null ? null : nativeFromJson<String>(json['email']),
contactName = json['contactName'] == null ? null : nativeFromJson<String>(json['contactName']);
contactName = json['contactName'] == null ? null : nativeFromJson<String>(json['contactName']),
companyLogoUrl = json['companyLogoUrl'] == null ? null : nativeFromJson<String>(json['companyLogoUrl']);
@override
bool operator ==(Object other) {
if(identical(this, other)) {
@@ -333,11 +359,12 @@ class GetApplicationsByStaffIdApplicationsShiftOrderBusiness {
return id == otherTyped.id &&
businessName == otherTyped.businessName &&
email == otherTyped.email &&
contactName == otherTyped.contactName;
contactName == otherTyped.contactName &&
companyLogoUrl == otherTyped.companyLogoUrl;
}
@override
int get hashCode => Object.hashAll([id.hashCode, businessName.hashCode, email.hashCode, contactName.hashCode]);
int get hashCode => Object.hashAll([id.hashCode, businessName.hashCode, email.hashCode, contactName.hashCode, companyLogoUrl.hashCode]);
Map<String, dynamic> toJson() {
@@ -350,6 +377,9 @@ class GetApplicationsByStaffIdApplicationsShiftOrderBusiness {
if (contactName != null) {
json['contactName'] = nativeToJson<String?>(contactName);
}
if (companyLogoUrl != null) {
json['companyLogoUrl'] = nativeToJson<String?>(companyLogoUrl);
}
return json;
}
@@ -358,6 +388,7 @@ class GetApplicationsByStaffIdApplicationsShiftOrderBusiness {
required this.businessName,
this.email,
this.contactName,
this.companyLogoUrl,
});
}
@@ -569,6 +600,8 @@ class GetApplicationsByStaffIdVariables {
final String staffId;
late final Optional<int>offset;
late final Optional<int>limit;
late final Optional<Timestamp>dayStart;
late final Optional<Timestamp>dayEnd;
@Deprecated('fromJson is deprecated for Variable classes as they are no longer required for deserialization.')
GetApplicationsByStaffIdVariables.fromJson(Map<String, dynamic> json):
@@ -583,6 +616,14 @@ class GetApplicationsByStaffIdVariables {
limit = Optional.optional(nativeFromJson, nativeToJson);
limit.value = json['limit'] == null ? null : nativeFromJson<int>(json['limit']);
dayStart = Optional.optional((json) => json['dayStart'] = Timestamp.fromJson(json['dayStart']), defaultSerializer);
dayStart.value = json['dayStart'] == null ? null : Timestamp.fromJson(json['dayStart']);
dayEnd = Optional.optional((json) => json['dayEnd'] = Timestamp.fromJson(json['dayEnd']), defaultSerializer);
dayEnd.value = json['dayEnd'] == null ? null : Timestamp.fromJson(json['dayEnd']);
}
@override
bool operator ==(Object other) {
@@ -596,11 +637,13 @@ class GetApplicationsByStaffIdVariables {
final GetApplicationsByStaffIdVariables otherTyped = other as GetApplicationsByStaffIdVariables;
return staffId == otherTyped.staffId &&
offset == otherTyped.offset &&
limit == otherTyped.limit;
limit == otherTyped.limit &&
dayStart == otherTyped.dayStart &&
dayEnd == otherTyped.dayEnd;
}
@override
int get hashCode => Object.hashAll([staffId.hashCode, offset.hashCode, limit.hashCode]);
int get hashCode => Object.hashAll([staffId.hashCode, offset.hashCode, limit.hashCode, dayStart.hashCode, dayEnd.hashCode]);
Map<String, dynamic> toJson() {
@@ -612,6 +655,12 @@ class GetApplicationsByStaffIdVariables {
if(limit.state == OptionalState.set) {
json['limit'] = limit.toJson();
}
if(dayStart.state == OptionalState.set) {
json['dayStart'] = dayStart.toJson();
}
if(dayEnd.state == OptionalState.set) {
json['dayEnd'] = dayEnd.toJson();
}
return json;
}
@@ -619,6 +668,8 @@ class GetApplicationsByStaffIdVariables {
required this.staffId,
required this.offset,
required this.limit,
required this.dayStart,
required this.dayEnd,
});
}

View File

@@ -65,7 +65,7 @@ class ClockInRepositoryImpl implements ClockInRepositoryInterface {
/// Helper to create Timestamp from DateTime
Timestamp _fromDateTime(DateTime d) {
// Assuming Timestamp.fromJson takes an ISO string
return Timestamp.fromJson(d.toIso8601String());
return Timestamp.fromJson(d.toUtc().toIso8601String());
}
/// Helper to find today's active application

View File

@@ -2,6 +2,7 @@ import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_data_connect/firebase_data_connect.dart';
import 'package:krow_data_connect/krow_data_connect.dart';
import 'package:krow_domain/krow_domain.dart' as domain;
import 'package:krow_core/core.dart';
import '../../domain/repositories/certificates_repository.dart';
@@ -63,7 +64,9 @@ class CertificatesRepositoryImpl implements CertificatesRepository {
description: null, // Description not available in this query response
status: _mapStatus(doc.status),
documentUrl: doc.documentUrl,
expiryDate: doc.expiryDate?.toDateTime(),
expiryDate: doc.expiryDate == null
? null
: DateTimeUtils.toDeviceTime(doc.expiryDate!.toDateTime()),
);
}

View File

@@ -2,6 +2,7 @@ import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_data_connect/firebase_data_connect.dart';
import 'package:krow_data_connect/krow_data_connect.dart';
import 'package:krow_domain/krow_domain.dart' as domain;
import 'package:krow_core/core.dart';
import '../../domain/repositories/documents_repository.dart';
@@ -75,7 +76,9 @@ class DocumentsRepositoryImpl implements DocumentsRepository {
description: null, // Description not available in data source
status: _mapStatus(doc.status),
documentUrl: doc.documentUrl,
expiryDate: doc.expiryDate?.toDateTime(),
expiryDate: doc.expiryDate == null
? null
: DateTimeUtils.toDeviceTime(doc.expiryDate!.toDateTime()),
);
}

View File

@@ -1,4 +1,5 @@
import 'package:firebase_data_connect/firebase_data_connect.dart';
import 'package:krow_core/core.dart';
import 'package:krow_data_connect/krow_data_connect.dart' as dc;
import 'package:krow_domain/krow_domain.dart';
@@ -62,14 +63,17 @@ class TaxFormMapper {
status: form.status.stringValue,
staffId: form.staffId,
formData: formData,
updatedAt: form.updatedAt?.toDateTime(),
updatedAt: form.updatedAt == null
? null
: DateTimeUtils.toDeviceTime(form.updatedAt!.toDateTime()),
);
}
static String? _formatDate(Timestamp? timestamp) {
if (timestamp == null) return null;
final DateTime date = timestamp.toDateTime();
final DateTime date =
DateTimeUtils.toDeviceTime(timestamp.toDateTime());
return '${date.month.toString().padLeft(2, '0')}/${date.day.toString().padLeft(2, '0')}/${date.year}';
}

View File

@@ -5,6 +5,7 @@ import 'package:krow_data_connect/krow_data_connect.dart' as dc;
import 'package:krow_domain/krow_domain.dart';
// ignore: implementation_imports
import 'package:krow_domain/src/adapters/financial/time_card_adapter.dart';
import 'package:krow_core/core.dart';
import '../../domain/repositories/time_card_repository.dart';
/// Implementation of [TimeCardRepository] using Firebase Data Connect.
@@ -40,12 +41,15 @@ class TimeCardRepositoryImpl implements TimeCardRepository {
return result.data.applications
.where((dc.GetApplicationsByStaffIdApplications app) {
final DateTime? shiftDate = app.shift.date?.toDateTime();
final DateTime? shiftDate = app.shift.date == null
? null
: DateTimeUtils.toDeviceTime(app.shift.date!.toDateTime());
if (shiftDate == null) return false;
return shiftDate.year == month.year && shiftDate.month == month.month;
})
.map((dc.GetApplicationsByStaffIdApplications app) {
final DateTime shiftDate = app.shift.date!.toDateTime();
final DateTime shiftDate =
DateTimeUtils.toDeviceTime(app.shift.date!.toDateTime());
final String startTime = _formatTime(app.checkInTime) ?? _formatTime(app.shift.startTime) ?? '';
final String endTime = _formatTime(app.checkOutTime) ?? _formatTime(app.shift.endTime) ?? '';
@@ -73,6 +77,7 @@ class TimeCardRepositoryImpl implements TimeCardRepository {
String? _formatTime(fdc.Timestamp? timestamp) {
if (timestamp == null) return null;
return DateFormat('HH:mm').format(timestamp.toDateTime());
return DateFormat('HH:mm')
.format(DateTimeUtils.toDeviceTime(timestamp.toDateTime()));
}
}

View File

@@ -78,8 +78,15 @@ class ShiftsRepositoryImpl implements ShiftsRepositoryInterface {
}
@override
Future<List<Shift>> getMyShifts() async {
return _fetchApplications(dc.ApplicationStatus.ACCEPTED);
Future<List<Shift>> getMyShifts({
required DateTime start,
required DateTime end,
}) async {
return _fetchApplications(
dc.ApplicationStatus.ACCEPTED,
start: start,
end: end,
);
}
@override
@@ -97,12 +104,20 @@ class ShiftsRepositoryImpl implements ShiftsRepositoryInterface {
return _fetchApplications(dc.ApplicationStatus.CHECKED_OUT);
}
Future<List<Shift>> _fetchApplications(dc.ApplicationStatus status) async {
Future<List<Shift>> _fetchApplications(
dc.ApplicationStatus status, {
DateTime? start,
DateTime? end,
}) async {
try {
final staffId = await _getStaffId();
final response = await _dataConnect
.getApplicationsByStaffId(staffId: staffId)
.execute();
var query = _dataConnect.getApplicationsByStaffId(staffId: staffId);
if (start != null && end != null) {
query = query
.dayStart(_toTimestamp(start))
.dayEnd(_toTimestamp(end));
}
final response = await query.execute();
final apps = response.data.applications.where(
(app) => app.status.stringValue == status.name,
@@ -113,30 +128,40 @@ class ShiftsRepositoryImpl implements ShiftsRepositoryInterface {
_shiftToAppIdMap[app.shift.id] = app.id;
_appToRoleIdMap[app.id] = app.shiftRole.id;
final shift = await _getShiftDetails(app.shift.id);
if (shift != null) {
// Override status to reflect the application state (e.g., CHECKED_OUT, ACCEPTED)
shifts.add(
Shift(
id: shift.id,
title: shift.title,
clientName: shift.clientName,
logoUrl: shift.logoUrl,
hourlyRate: shift.hourlyRate,
location: shift.location,
locationAddress: shift.locationAddress,
date: shift.date,
startTime: shift.startTime,
endTime: shift.endTime,
createdDate: shift.createdDate,
status: _mapStatus(status),
description: shift.description,
durationDays: shift.durationDays,
requiredSlots: shift.requiredSlots,
filledSlots: shift.filledSlots,
),
);
}
final String roleName = app.shiftRole.role.name;
final String orderName =
(app.shift.order.eventName ?? '').trim().isNotEmpty
? app.shift.order.eventName!
: app.shift.order.business.businessName;
final String title = '$roleName - $orderName';
final DateTime? shiftDate = _toDateTime(app.shift.date);
final DateTime? startDt = _toDateTime(app.shiftRole.startTime);
final DateTime? endDt = _toDateTime(app.shiftRole.endTime);
final DateTime? createdDt = _toDateTime(app.createdAt);
// Override status to reflect the application state (e.g., CHECKED_OUT, ACCEPTED)
shifts.add(
Shift(
id: app.shift.id,
roleId: app.shiftRole.roleId,
title: title,
clientName: app.shift.order.business.businessName,
logoUrl: app.shift.order.business.companyLogoUrl,
hourlyRate: app.shiftRole.role.costPerHour,
location: app.shift.location ?? '',
locationAddress: app.shift.order.teamHub.hubName,
date: shiftDate?.toIso8601String() ?? '',
startTime: startDt != null ? DateFormat('HH:mm').format(startDt) : '',
endTime: endDt != null ? DateFormat('HH:mm').format(endDt) : '',
createdDate: createdDt?.toIso8601String() ?? '',
status: _mapStatus(status),
description: app.shift.description,
durationDays: app.shift.durationDays,
requiredSlots: app.shiftRole.count,
filledSlots: app.shiftRole.assigned ?? 0,
hasApplied: true,
),
);
}
return shifts;
} catch (e) {
@@ -144,6 +169,13 @@ class ShiftsRepositoryImpl implements ShiftsRepositoryInterface {
}
}
Timestamp _toTimestamp(DateTime dateTime) {
final DateTime utc = dateTime.toUtc();
final int seconds = utc.millisecondsSinceEpoch ~/ 1000;
final int nanoseconds = (utc.microsecondsSinceEpoch % 1000000) * 1000;
return Timestamp(nanoseconds, seconds);
}
String _mapStatus(dc.ApplicationStatus status) {
switch (status) {
case dc.ApplicationStatus.ACCEPTED:
@@ -359,6 +391,16 @@ class ShiftsRepositoryImpl implements ShiftsRepositoryInterface {
if (role == null) {
throw Exception('Shift role not found');
}
final existingApplicationResult = await _dataConnect
.getApplicationByStaffShiftAndRole(
staffId: staffId,
shiftId: shiftId,
roleId: targetRoleId,
)
.execute();
if (existingApplicationResult.data.applications.isNotEmpty) {
throw Exception('Application already exists.');
}
final int assigned = role.assigned ?? 0;
if (assigned >= role.count) {
throw Exception('This shift is full.');

View File

@@ -0,0 +1,11 @@
import 'package:krow_core/core.dart';
class GetMyShiftsArguments extends UseCaseArgument {
final DateTime start;
final DateTime end;
const GetMyShiftsArguments({
required this.start,
required this.end,
});
}

View File

@@ -6,7 +6,10 @@ import 'package:krow_domain/krow_domain.dart';
/// Implementations of this interface should reside in the data layer.
abstract interface class ShiftsRepositoryInterface {
/// Retrieves the list of shifts assigned to the current user.
Future<List<Shift>> getMyShifts();
Future<List<Shift>> getMyShifts({
required DateTime start,
required DateTime end,
});
/// Retrieves available shifts matching the given [query] and [type].
Future<List<Shift>> getAvailableShifts(String query, String type);

View File

@@ -1,18 +1,21 @@
import 'package:krow_core/core.dart';
import 'package:krow_domain/krow_domain.dart';
import '../arguments/get_my_shifts_arguments.dart';
import '../repositories/shifts_repository_interface.dart';
/// Use case for retrieving the user's assigned shifts.
///
/// This use case delegates to [ShiftsRepositoryInterface].
class GetMyShiftsUseCase extends NoInputUseCase<List<Shift>> {
class GetMyShiftsUseCase extends UseCase<GetMyShiftsArguments, List<Shift>> {
final ShiftsRepositoryInterface repository;
GetMyShiftsUseCase(this.repository);
@override
Future<List<Shift>> call() async {
return repository.getMyShifts();
Future<List<Shift>> call(GetMyShiftsArguments arguments) async {
return repository.getMyShifts(
start: arguments.start,
end: arguments.end,
);
}
}

View File

@@ -4,6 +4,7 @@ import 'package:krow_domain/krow_domain.dart';
import 'package:meta/meta.dart';
import '../../../domain/arguments/get_available_shifts_arguments.dart';
import '../../../domain/arguments/get_my_shifts_arguments.dart';
import '../../../domain/usecases/get_available_shifts_usecase.dart';
import '../../../domain/usecases/get_cancelled_shifts_usecase.dart';
import '../../../domain/usecases/get_history_shifts_usecase.dart';
@@ -28,6 +29,7 @@ class ShiftsBloc extends Bloc<ShiftsEvent, ShiftsState> {
required this.getHistoryShifts,
}) : super(ShiftsInitial()) {
on<LoadShiftsEvent>(_onLoadShifts);
on<LoadShiftsForRangeEvent>(_onLoadShiftsForRange);
on<FilterAvailableShiftsEvent>(_onFilterAvailableShifts);
}
@@ -43,7 +45,10 @@ class ShiftsBloc extends Bloc<ShiftsEvent, ShiftsState> {
// Or load all for simplicity as per prototype logic which had them all in memory.
try {
final myShiftsResult = await getMyShifts();
final List<DateTime> days = _getCalendarDaysForOffset(0);
final myShiftsResult = await getMyShifts(
GetMyShiftsArguments(start: days.first, end: days.last),
);
final pendingResult = await getPendingAssignments();
final cancelledResult = await getCancelledShifts();
final historyResult = await getHistoryShifts();
@@ -65,6 +70,41 @@ class ShiftsBloc extends Bloc<ShiftsEvent, ShiftsState> {
}
}
Future<void> _onLoadShiftsForRange(
LoadShiftsForRangeEvent event,
Emitter<ShiftsState> emit,
) async {
try {
final myShiftsResult = await getMyShifts(
GetMyShiftsArguments(start: event.start, end: event.end),
);
if (state is ShiftsLoaded) {
final currentState = state as ShiftsLoaded;
emit(currentState.copyWith(myShifts: myShiftsResult));
return;
}
final pendingResult = await getPendingAssignments();
final cancelledResult = await getCancelledShifts();
final historyResult = await getHistoryShifts();
final availableResult =
await getAvailableShifts(const GetAvailableShiftsArguments());
emit(ShiftsLoaded(
myShifts: myShiftsResult,
pendingShifts: pendingResult,
cancelledShifts: cancelledResult,
availableShifts: _filterPastShifts(availableResult),
historyShifts: historyResult,
searchQuery: '',
jobType: 'all',
));
} catch (_) {
emit(const ShiftsError('Failed to load shifts'));
}
}
Future<void> _onFilterAvailableShifts(
FilterAvailableShiftsEvent event,
Emitter<ShiftsState> emit,
@@ -91,6 +131,17 @@ class ShiftsBloc extends Bloc<ShiftsEvent, ShiftsState> {
}
}
List<DateTime> _getCalendarDaysForOffset(int weekOffset) {
final now = DateTime.now();
final int reactDayIndex = now.weekday == 7 ? 0 : now.weekday;
final int daysSinceFriday = (reactDayIndex + 2) % 7;
final start = now
.subtract(Duration(days: daysSinceFriday))
.add(Duration(days: weekOffset * 7));
final startDate = DateTime(start.year, start.month, start.day);
return List.generate(7, (index) => startDate.add(Duration(days: index)));
}
List<Shift> _filterPastShifts(List<Shift> shifts) {
final now = DateTime.now();
return shifts.where((shift) {

View File

@@ -10,6 +10,19 @@ sealed class ShiftsEvent extends Equatable {
class LoadShiftsEvent extends ShiftsEvent {}
class LoadShiftsForRangeEvent extends ShiftsEvent {
final DateTime start;
final DateTime end;
const LoadShiftsForRangeEvent({
required this.start,
required this.end,
});
@override
List<Object?> get props => [start, end];
}
class FilterAvailableShiftsEvent extends ShiftsEvent {
final String? query;
final String? jobType;

View File

@@ -444,11 +444,11 @@ class ShiftDetailsPage extends StatelessWidget {
],
const SizedBox(height: 20),
if (displayShift!.status != 'confirmed' &&
(displayShift!.hasApplied == true ||
(displayShift!.requiredSlots == null ||
displayShift!.filledSlots == null ||
displayShift!.filledSlots! <
displayShift!.requiredSlots!)))
displayShift!.hasApplied != true &&
(displayShift!.requiredSlots == null ||
displayShift!.filledSlots == null ||
displayShift!.filledSlots! <
displayShift!.requiredSlots!))
Row(
children: [
Expanded(
@@ -470,31 +470,26 @@ class ShiftDetailsPage extends StatelessWidget {
),
),
const SizedBox(width: 16),
if ((displayShift!.hasApplied != true) &&
(displayShift!.requiredSlots == null ||
displayShift!.filledSlots == null ||
displayShift!.filledSlots! <
displayShift!.requiredSlots!))
Expanded(
child: ElevatedButton(
onPressed: () => _bookShift(
context,
displayShift!.id,
displayShift!.roleId,
DateTime.tryParse(displayShift!.date),
),
style: ElevatedButton.styleFrom(
backgroundColor: const Color(
0xFF10B981,
),
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(
vertical: 16,
),
),
child: const Text("Book Shift"),
Expanded(
child: ElevatedButton(
onPressed: () => _bookShift(
context,
displayShift!.id,
displayShift!.roleId,
DateTime.tryParse(displayShift!.date),
),
style: ElevatedButton.styleFrom(
backgroundColor: const Color(
0xFF10B981,
),
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(
vertical: 16,
),
),
child: const Text("Book Shift"),
),
),
],
),
SizedBox(

View File

@@ -38,6 +38,9 @@ class _MyShiftsTabState extends State<MyShiftsTab> {
if (widget.initialDate != null) {
_applyInitialDate(widget.initialDate!);
}
WidgetsBinding.instance.addPostFrameCallback((_) {
_loadShiftsForCurrentWeek();
});
}
@override
@@ -69,6 +72,9 @@ class _MyShiftsTabState extends State<MyShiftsTab> {
setState(() {
_weekOffset = (diff / 7).floor();
});
WidgetsBinding.instance.addPostFrameCallback((_) {
_loadShiftsForCurrentWeek();
});
}
List<DateTime> _getCalendarDays() {
@@ -82,6 +88,16 @@ class _MyShiftsTabState extends State<MyShiftsTab> {
return List.generate(7, (index) => startDate.add(Duration(days: index)));
}
void _loadShiftsForCurrentWeek() {
final List<DateTime> calendarDays = _getCalendarDays();
context.read<ShiftsBloc>().add(
LoadShiftsForRangeEvent(
start: calendarDays.first,
end: calendarDays.last,
),
);
}
bool _isSameDay(DateTime a, DateTime b) {
return a.year == b.year && a.month == b.month && a.day == b.day;
}
@@ -211,7 +227,11 @@ class _MyShiftsTabState extends State<MyShiftsTab> {
size: 20,
color: AppColors.krowCharcoal,
),
onPressed: () => setState(() => _weekOffset--),
onPressed: () => setState(() {
_weekOffset--;
_selectedDate = _getCalendarDays().first;
_loadShiftsForCurrentWeek();
}),
constraints: const BoxConstraints(),
padding: EdgeInsets.zero,
),
@@ -229,7 +249,11 @@ class _MyShiftsTabState extends State<MyShiftsTab> {
size: 20,
color: AppColors.krowCharcoal,
),
onPressed: () => setState(() => _weekOffset++),
onPressed: () => setState(() {
_weekOffset++;
_selectedDate = _getCalendarDays().first;
_loadShiftsForCurrentWeek();
}),
constraints: const BoxConstraints(),
padding: EdgeInsets.zero,
),