feat: Update API endpoint usage in repositories to remove redundant path property

- Refactored multiple repository implementations across client and staff features to directly use endpoint objects without accessing the `path` property.
- Introduced a new `FeatureGate` class for client-side feature gating based on user scopes, allowing for better access control to API endpoints.
- Added `ApiEndpoint` class to represent API endpoints with their paths and required scopes for future feature gating.
This commit is contained in:
Achintha Isuru
2026-03-17 12:01:06 -04:00
parent 57bba8ab4e
commit 376b4e4431
47 changed files with 240 additions and 139 deletions

View File

@@ -20,8 +20,8 @@ export 'src/services/api_service/dio_client.dart';
export 'src/services/api_service/mixins/api_error_handler.dart'; export 'src/services/api_service/mixins/api_error_handler.dart';
export 'src/services/api_service/mixins/session_handler_mixin.dart'; export 'src/services/api_service/mixins/session_handler_mixin.dart';
// API Endpoint classes // Feature Gate & Endpoint classes
export 'src/services/api_service/api_endpoint.dart'; export 'src/services/api_service/feature_gate.dart';
export 'src/services/api_service/endpoints/auth_endpoints.dart'; export 'src/services/api_service/endpoints/auth_endpoints.dart';
export 'src/services/api_service/endpoints/client_endpoints.dart'; export 'src/services/api_service/endpoints/client_endpoints.dart';
export 'src/services/api_service/endpoints/core_endpoints.dart'; export 'src/services/api_service/endpoints/core_endpoints.dart';

View File

@@ -1,10 +1,11 @@
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:krow_domain/krow_domain.dart'; import 'package:krow_domain/krow_domain.dart';
import 'feature_gate.dart';
/// A service that handles HTTP communication using the [Dio] client. /// A service that handles HTTP communication using the [Dio] client.
/// ///
/// This class provides a wrapper around [Dio]'s methods to handle /// Integrates [FeatureGate] to validate endpoint scopes before each request.
/// response parsing and error handling in a consistent way.
class ApiService implements BaseApiService { class ApiService implements BaseApiService {
/// Creates an [ApiService] with the given [Dio] instance. /// Creates an [ApiService] with the given [Dio] instance.
ApiService(this._dio); ApiService(this._dio);
@@ -15,12 +16,13 @@ class ApiService implements BaseApiService {
/// Performs a GET request to the specified [endpoint]. /// Performs a GET request to the specified [endpoint].
@override @override
Future<ApiResponse> get( Future<ApiResponse> get(
String endpoint, { ApiEndpoint endpoint, {
Map<String, dynamic>? params, Map<String, dynamic>? params,
}) async { }) async {
FeatureGate.instance.validateAccess(endpoint);
try { try {
final Response<dynamic> response = await _dio.get<dynamic>( final Response<dynamic> response = await _dio.get<dynamic>(
endpoint, endpoint.path,
queryParameters: params, queryParameters: params,
); );
return _handleResponse(response); return _handleResponse(response);
@@ -32,13 +34,14 @@ class ApiService implements BaseApiService {
/// Performs a POST request to the specified [endpoint]. /// Performs a POST request to the specified [endpoint].
@override @override
Future<ApiResponse> post( Future<ApiResponse> post(
String endpoint, { ApiEndpoint endpoint, {
dynamic data, dynamic data,
Map<String, dynamic>? params, Map<String, dynamic>? params,
}) async { }) async {
FeatureGate.instance.validateAccess(endpoint);
try { try {
final Response<dynamic> response = await _dio.post<dynamic>( final Response<dynamic> response = await _dio.post<dynamic>(
endpoint, endpoint.path,
data: data, data: data,
queryParameters: params, queryParameters: params,
); );
@@ -51,13 +54,14 @@ class ApiService implements BaseApiService {
/// Performs a PUT request to the specified [endpoint]. /// Performs a PUT request to the specified [endpoint].
@override @override
Future<ApiResponse> put( Future<ApiResponse> put(
String endpoint, { ApiEndpoint endpoint, {
dynamic data, dynamic data,
Map<String, dynamic>? params, Map<String, dynamic>? params,
}) async { }) async {
FeatureGate.instance.validateAccess(endpoint);
try { try {
final Response<dynamic> response = await _dio.put<dynamic>( final Response<dynamic> response = await _dio.put<dynamic>(
endpoint, endpoint.path,
data: data, data: data,
queryParameters: params, queryParameters: params,
); );
@@ -70,13 +74,14 @@ class ApiService implements BaseApiService {
/// Performs a PATCH request to the specified [endpoint]. /// Performs a PATCH request to the specified [endpoint].
@override @override
Future<ApiResponse> patch( Future<ApiResponse> patch(
String endpoint, { ApiEndpoint endpoint, {
dynamic data, dynamic data,
Map<String, dynamic>? params, Map<String, dynamic>? params,
}) async { }) async {
FeatureGate.instance.validateAccess(endpoint);
try { try {
final Response<dynamic> response = await _dio.patch<dynamic>( final Response<dynamic> response = await _dio.patch<dynamic>(
endpoint, endpoint.path,
data: data, data: data,
queryParameters: params, queryParameters: params,
); );
@@ -89,13 +94,14 @@ class ApiService implements BaseApiService {
/// Performs a DELETE request to the specified [endpoint]. /// Performs a DELETE request to the specified [endpoint].
@override @override
Future<ApiResponse> delete( Future<ApiResponse> delete(
String endpoint, { ApiEndpoint endpoint, {
dynamic data, dynamic data,
Map<String, dynamic>? params, Map<String, dynamic>? params,
}) async { }) async {
FeatureGate.instance.validateAccess(endpoint);
try { try {
final Response<dynamic> response = await _dio.delete<dynamic>( final Response<dynamic> response = await _dio.delete<dynamic>(
endpoint, endpoint.path,
data: data, data: data,
queryParameters: params, queryParameters: params,
); );
@@ -105,6 +111,10 @@ class ApiService implements BaseApiService {
} }
} }
// ---------------------------------------------------------------------------
// Response handling
// ---------------------------------------------------------------------------
/// Extracts [ApiResponse] from a successful [Response]. /// Extracts [ApiResponse] from a successful [Response].
ApiResponse _handleResponse(Response<dynamic> response) { ApiResponse _handleResponse(Response<dynamic> response) {
return ApiResponse( return ApiResponse(

View File

@@ -26,7 +26,7 @@ class FileUploadService extends BaseCoreService {
if (category != null) 'category': category, if (category != null) 'category': category,
}); });
return api.post(CoreEndpoints.uploadFile.path, data: formData); return api.post(CoreEndpoints.uploadFile, data: formData);
}); });
if (res.code.startsWith('2')) { if (res.code.startsWith('2')) {

View File

@@ -19,7 +19,7 @@ class LlmService extends BaseCoreService {
}) async { }) async {
final ApiResponse res = await action(() async { final ApiResponse res = await action(() async {
return api.post( return api.post(
CoreEndpoints.invokeLlm.path, CoreEndpoints.invokeLlm,
data: <String, dynamic>{ data: <String, dynamic>{
'prompt': prompt, 'prompt': prompt,
if (responseJsonSchema != null) if (responseJsonSchema != null)

View File

@@ -19,7 +19,7 @@ class RapidOrderService extends BaseCoreService {
}) async { }) async {
final ApiResponse res = await action(() async { final ApiResponse res = await action(() async {
return api.post( return api.post(
CoreEndpoints.transcribeRapidOrder.path, CoreEndpoints.transcribeRapidOrder,
data: <String, dynamic>{ data: <String, dynamic>{
'audioFileUri': audioFileUri, 'audioFileUri': audioFileUri,
'locale': locale, 'locale': locale,
@@ -51,7 +51,7 @@ class RapidOrderService extends BaseCoreService {
}) async { }) async {
final ApiResponse res = await action(() async { final ApiResponse res = await action(() async {
return api.post( return api.post(
CoreEndpoints.parseRapidOrder.path, CoreEndpoints.parseRapidOrder,
data: <String, dynamic>{ data: <String, dynamic>{
'text': text, 'text': text,
'locale': locale, 'locale': locale,

View File

@@ -17,7 +17,7 @@ class SignedUrlService extends BaseCoreService {
}) async { }) async {
final ApiResponse res = await action(() async { final ApiResponse res = await action(() async {
return api.post( return api.post(
CoreEndpoints.createSignedUrl.path, CoreEndpoints.createSignedUrl,
data: <String, dynamic>{ data: <String, dynamic>{
'fileUri': fileUri, 'fileUri': fileUri,
'expiresInSeconds': expiresInSeconds, 'expiresInSeconds': expiresInSeconds,

View File

@@ -22,7 +22,7 @@ class VerificationService extends BaseCoreService {
}) async { }) async {
final ApiResponse res = await action(() async { final ApiResponse res = await action(() async {
return api.post( return api.post(
CoreEndpoints.verifications.path, CoreEndpoints.verifications,
data: <String, dynamic>{ data: <String, dynamic>{
'type': type, 'type': type,
'subjectType': subjectType, 'subjectType': subjectType,
@@ -44,7 +44,7 @@ class VerificationService extends BaseCoreService {
/// Polls the status of a specific verification. /// Polls the status of a specific verification.
Future<VerificationResponse> getStatus(String verificationId) async { Future<VerificationResponse> getStatus(String verificationId) async {
final ApiResponse res = await action(() async { final ApiResponse res = await action(() async {
return api.get(CoreEndpoints.verificationStatus(verificationId).path); return api.get(CoreEndpoints.verificationStatus(verificationId));
}); });
if (res.code.startsWith('2')) { if (res.code.startsWith('2')) {
@@ -65,7 +65,7 @@ class VerificationService extends BaseCoreService {
}) async { }) async {
final ApiResponse res = await action(() async { final ApiResponse res = await action(() async {
return api.post( return api.post(
CoreEndpoints.verificationReview(verificationId).path, CoreEndpoints.verificationReview(verificationId),
data: <String, dynamic>{ data: <String, dynamic>{
'decision': decision, 'decision': decision,
if (note != null) 'note': note, if (note != null) 'note': note,
@@ -84,7 +84,7 @@ class VerificationService extends BaseCoreService {
/// Retries a verification job that failed or needs re-processing. /// Retries a verification job that failed or needs re-processing.
Future<VerificationResponse> retryVerification(String verificationId) async { Future<VerificationResponse> retryVerification(String verificationId) async {
final ApiResponse res = await action(() async { final ApiResponse res = await action(() async {
return api.post(CoreEndpoints.verificationRetry(verificationId).path); return api.post(CoreEndpoints.verificationRetry(verificationId));
}); });
if (res.code.startsWith('2')) { if (res.code.startsWith('2')) {

View File

@@ -1,4 +1,4 @@
import 'package:krow_core/src/services/api_service/api_endpoint.dart'; import 'package:krow_domain/krow_domain.dart' show ApiEndpoint;
/// Authentication endpoints for both staff and client apps. /// Authentication endpoints for both staff and client apps.
abstract final class AuthEndpoints { abstract final class AuthEndpoints {

View File

@@ -1,4 +1,4 @@
import 'package:krow_core/src/services/api_service/api_endpoint.dart'; import 'package:krow_domain/krow_domain.dart' show ApiEndpoint;
/// Client-specific API endpoints (read and write). /// Client-specific API endpoints (read and write).
abstract final class ClientEndpoints { abstract final class ClientEndpoints {

View File

@@ -1,4 +1,4 @@
import 'package:krow_core/src/services/api_service/api_endpoint.dart'; import 'package:krow_domain/krow_domain.dart' show ApiEndpoint;
/// Core infrastructure endpoints (upload, signed URLs, LLM, verifications, /// Core infrastructure endpoints (upload, signed URLs, LLM, verifications,
/// rapid orders). /// rapid orders).

View File

@@ -1,4 +1,4 @@
import 'package:krow_core/src/services/api_service/api_endpoint.dart'; import 'package:krow_domain/krow_domain.dart' show ApiEndpoint;
/// Staff-specific API endpoints (read and write). /// Staff-specific API endpoints (read and write).
abstract final class StaffEndpoints { abstract final class StaffEndpoints {

View File

@@ -0,0 +1,69 @@
import 'package:flutter/foundation.dart';
import 'package:krow_domain/krow_domain.dart';
/// Client-side feature gate that checks user scopes against endpoint
/// requirements before allowing an API call.
///
/// Usage:
/// ```dart
/// FeatureGate.instance.validateAccess(StaffEndpoints.dashboard);
/// ```
///
/// When an endpoint's [ApiEndpoint.requiredScopes] is empty, access is always
/// granted. When scopes are defined, the gate verifies that the user has ALL
/// required scopes. Throws [InsufficientScopeException] if any are missing.
class FeatureGate {
FeatureGate._();
/// The global singleton instance.
static final FeatureGate instance = FeatureGate._();
/// The scopes the current user has.
List<String> _userScopes = const <String>[];
/// Updates the user's scopes (call after sign-in or session hydration).
void setUserScopes(List<String> scopes) {
_userScopes = List<String>.unmodifiable(scopes);
debugPrint('[FeatureGate] User scopes updated: $_userScopes');
}
/// Clears the user's scopes (call on sign-out).
void clearScopes() {
_userScopes = const <String>[];
debugPrint('[FeatureGate] User scopes cleared');
}
/// The current user's scopes (read-only).
List<String> get userScopes => _userScopes;
/// Returns `true` if the user has all scopes required by [endpoint].
bool hasAccess(ApiEndpoint endpoint) {
if (endpoint.requiredScopes.isEmpty) return true;
return endpoint.requiredScopes.every(
(String scope) => _userScopes.contains(scope),
);
}
/// Validates that the user can access [endpoint].
///
/// No-op when the endpoint has no required scopes (ungated).
/// Throws [InsufficientScopeException] when scopes are missing.
void validateAccess(ApiEndpoint endpoint) {
if (endpoint.requiredScopes.isEmpty) return;
final List<String> missingScopes = endpoint.requiredScopes
.where((String scope) => !_userScopes.contains(scope))
.toList();
if (missingScopes.isNotEmpty) {
throw InsufficientScopeException(
requiredScopes: endpoint.requiredScopes,
userScopes: _userScopes,
technicalMessage:
'Endpoint "${endpoint.path}" requires scopes '
'${endpoint.requiredScopes} but user has $_userScopes. '
'Missing: $missingScopes',
);
}
}
}

View File

@@ -51,7 +51,7 @@ class V2SessionService with SessionHandlerMixin {
return null; return null;
} }
final ApiResponse response = await api.get(AuthEndpoints.session.path); final ApiResponse response = await api.get(AuthEndpoints.session);
if (response.data is Map<String, dynamic>) { if (response.data is Map<String, dynamic>) {
final Map<String, dynamic> data = final Map<String, dynamic> data =
@@ -99,7 +99,7 @@ class V2SessionService with SessionHandlerMixin {
final BaseApiService? api = _apiService; final BaseApiService? api = _apiService;
if (api != null) { if (api != null) {
try { try {
await api.post(AuthEndpoints.signOut.path); await api.post(AuthEndpoints.signOut);
} catch (e) { } catch (e) {
debugPrint('[V2SessionService] Server sign-out failed: $e'); debugPrint('[V2SessionService] Server sign-out failed: $e');
} }

View File

@@ -23,6 +23,7 @@ export 'src/entities/enums/staff_status.dart';
export 'src/entities/enums/user_role.dart'; export 'src/entities/enums/user_role.dart';
// Core // Core
export 'src/core/services/api_services/api_endpoint.dart';
export 'src/core/services/api_services/api_response.dart'; export 'src/core/services/api_services/api_response.dart';
export 'src/core/services/api_services/base_api_service.dart'; export 'src/core/services/api_services/base_api_service.dart';
export 'src/core/services/api_services/base_core_service.dart'; export 'src/core/services/api_services/base_core_service.dart';

View File

@@ -1,36 +1,38 @@
import 'api_endpoint.dart';
import 'api_response.dart'; import 'api_response.dart';
/// Abstract base class for API services. /// Abstract base class for API services.
/// ///
/// This defines the contract for making HTTP requests. /// Methods accept [ApiEndpoint] which carries the path and required scopes.
/// Implementations should validate scopes via [FeatureGate] before executing.
abstract class BaseApiService { abstract class BaseApiService {
/// Performs a GET request to the specified [endpoint]. /// Performs a GET request to the specified [endpoint].
Future<ApiResponse> get(String endpoint, {Map<String, dynamic>? params}); Future<ApiResponse> get(ApiEndpoint endpoint, {Map<String, dynamic>? params});
/// Performs a POST request to the specified [endpoint]. /// Performs a POST request to the specified [endpoint].
Future<ApiResponse> post( Future<ApiResponse> post(
String endpoint, { ApiEndpoint endpoint, {
dynamic data, dynamic data,
Map<String, dynamic>? params, Map<String, dynamic>? params,
}); });
/// Performs a PUT request to the specified [endpoint]. /// Performs a PUT request to the specified [endpoint].
Future<ApiResponse> put( Future<ApiResponse> put(
String endpoint, { ApiEndpoint endpoint, {
dynamic data, dynamic data,
Map<String, dynamic>? params, Map<String, dynamic>? params,
}); });
/// Performs a PATCH request to the specified [endpoint]. /// Performs a PATCH request to the specified [endpoint].
Future<ApiResponse> patch( Future<ApiResponse> patch(
String endpoint, { ApiEndpoint endpoint, {
dynamic data, dynamic data,
Map<String, dynamic>? params, Map<String, dynamic>? params,
}); });
/// Performs a DELETE request to the specified [endpoint]. /// Performs a DELETE request to the specified [endpoint].
Future<ApiResponse> delete( Future<ApiResponse> delete(
String endpoint, { ApiEndpoint endpoint, {
dynamic data, dynamic data,
Map<String, dynamic>? params, Map<String, dynamic>? params,
}); });

View File

@@ -330,3 +330,22 @@ class NotAuthenticatedException extends AppException {
@override @override
String get messageKey => 'errors.auth.not_authenticated'; String get messageKey => 'errors.auth.not_authenticated';
} }
/// Thrown when the user lacks the required scopes to access an endpoint.
class InsufficientScopeException extends AppException {
/// Creates an [InsufficientScopeException].
const InsufficientScopeException({
required this.requiredScopes,
required this.userScopes,
super.technicalMessage,
}) : super(code: 'SCOPE_001');
/// The scopes required by the endpoint.
final List<String> requiredScopes;
/// The scopes the user currently has.
final List<String> userScopes;
@override
String get messageKey => 'errors.generic.insufficient_scope';
}

View File

@@ -45,7 +45,7 @@ class AuthRepositoryImpl implements AuthRepositoryInterface {
// Step 1: Call V2 sign-in endpoint — server handles Firebase Auth // Step 1: Call V2 sign-in endpoint — server handles Firebase Auth
// via Identity Toolkit and returns a full auth envelope. // via Identity Toolkit and returns a full auth envelope.
final ApiResponse response = await _apiService.post( final ApiResponse response = await _apiService.post(
AuthEndpoints.clientSignIn.path, AuthEndpoints.clientSignIn,
data: <String, dynamic>{ data: <String, dynamic>{
'email': email, 'email': email,
'password': password, 'password': password,
@@ -107,7 +107,7 @@ class AuthRepositoryImpl implements AuthRepositoryInterface {
// - Creates user, tenant, business, memberships in one transaction // - Creates user, tenant, business, memberships in one transaction
// - Returns full auth envelope with session tokens // - Returns full auth envelope with session tokens
final ApiResponse response = await _apiService.post( final ApiResponse response = await _apiService.post(
AuthEndpoints.clientSignUp.path, AuthEndpoints.clientSignUp,
data: <String, dynamic>{ data: <String, dynamic>{
'companyName': companyName, 'companyName': companyName,
'email': email, 'email': email,
@@ -172,7 +172,7 @@ class AuthRepositoryImpl implements AuthRepositoryInterface {
Future<void> signOut() async { Future<void> signOut() async {
try { try {
// Step 1: Call V2 sign-out endpoint for server-side token revocation. // Step 1: Call V2 sign-out endpoint for server-side token revocation.
await _apiService.post(AuthEndpoints.clientSignOut.path); await _apiService.post(AuthEndpoints.clientSignOut);
} catch (e) { } catch (e) {
developer.log( developer.log(
'V2 sign-out request failed: $e', 'V2 sign-out request failed: $e',

View File

@@ -17,7 +17,7 @@ class BillingRepositoryImpl implements BillingRepository {
@override @override
Future<List<BillingAccount>> getBankAccounts() async { Future<List<BillingAccount>> getBankAccounts() async {
final ApiResponse response = final ApiResponse response =
await _apiService.get(ClientEndpoints.billingAccounts.path); await _apiService.get(ClientEndpoints.billingAccounts);
final List<dynamic> items = final List<dynamic> items =
(response.data as Map<String, dynamic>)['items'] as List<dynamic>; (response.data as Map<String, dynamic>)['items'] as List<dynamic>;
return items return items
@@ -29,7 +29,7 @@ class BillingRepositoryImpl implements BillingRepository {
@override @override
Future<List<Invoice>> getPendingInvoices() async { Future<List<Invoice>> getPendingInvoices() async {
final ApiResponse response = final ApiResponse response =
await _apiService.get(ClientEndpoints.billingInvoicesPending.path); await _apiService.get(ClientEndpoints.billingInvoicesPending);
final List<dynamic> items = final List<dynamic> items =
(response.data as Map<String, dynamic>)['items'] as List<dynamic>; (response.data as Map<String, dynamic>)['items'] as List<dynamic>;
return items return items
@@ -41,7 +41,7 @@ class BillingRepositoryImpl implements BillingRepository {
@override @override
Future<List<Invoice>> getInvoiceHistory() async { Future<List<Invoice>> getInvoiceHistory() async {
final ApiResponse response = final ApiResponse response =
await _apiService.get(ClientEndpoints.billingInvoicesHistory.path); await _apiService.get(ClientEndpoints.billingInvoicesHistory);
final List<dynamic> items = final List<dynamic> items =
(response.data as Map<String, dynamic>)['items'] as List<dynamic>; (response.data as Map<String, dynamic>)['items'] as List<dynamic>;
return items return items
@@ -53,7 +53,7 @@ class BillingRepositoryImpl implements BillingRepository {
@override @override
Future<int> getCurrentBillCents() async { Future<int> getCurrentBillCents() async {
final ApiResponse response = final ApiResponse response =
await _apiService.get(ClientEndpoints.billingCurrentBill.path); await _apiService.get(ClientEndpoints.billingCurrentBill);
final Map<String, dynamic> data = final Map<String, dynamic> data =
response.data as Map<String, dynamic>; response.data as Map<String, dynamic>;
return (data['currentBillCents'] as num).toInt(); return (data['currentBillCents'] as num).toInt();
@@ -62,7 +62,7 @@ class BillingRepositoryImpl implements BillingRepository {
@override @override
Future<int> getSavingsCents() async { Future<int> getSavingsCents() async {
final ApiResponse response = final ApiResponse response =
await _apiService.get(ClientEndpoints.billingSavings.path); await _apiService.get(ClientEndpoints.billingSavings);
final Map<String, dynamic> data = final Map<String, dynamic> data =
response.data as Map<String, dynamic>; response.data as Map<String, dynamic>;
return (data['savingsCents'] as num).toInt(); return (data['savingsCents'] as num).toInt();
@@ -74,7 +74,7 @@ class BillingRepositoryImpl implements BillingRepository {
required String endDate, required String endDate,
}) async { }) async {
final ApiResponse response = await _apiService.get( final ApiResponse response = await _apiService.get(
ClientEndpoints.billingSpendBreakdown.path, ClientEndpoints.billingSpendBreakdown,
params: <String, dynamic>{ params: <String, dynamic>{
'startDate': startDate, 'startDate': startDate,
'endDate': endDate, 'endDate': endDate,
@@ -90,13 +90,13 @@ class BillingRepositoryImpl implements BillingRepository {
@override @override
Future<void> approveInvoice(String id) async { Future<void> approveInvoice(String id) async {
await _apiService.post(ClientEndpoints.invoiceApprove(id).path); await _apiService.post(ClientEndpoints.invoiceApprove(id));
} }
@override @override
Future<void> disputeInvoice(String id, String reason) async { Future<void> disputeInvoice(String id, String reason) async {
await _apiService.post( await _apiService.post(
ClientEndpoints.invoiceDispute(id).path, ClientEndpoints.invoiceDispute(id),
data: <String, dynamic>{'reason': reason}, data: <String, dynamic>{'reason': reason},
); );
} }

View File

@@ -20,7 +20,7 @@ class CoverageRepositoryImpl implements CoverageRepository {
final String dateStr = final String dateStr =
'${date.year}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}'; '${date.year}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}';
final ApiResponse response = await _apiService.get( final ApiResponse response = await _apiService.get(
ClientEndpoints.coverage.path, ClientEndpoints.coverage,
params: <String, dynamic>{'date': dateStr}, params: <String, dynamic>{'date': dateStr},
); );
final List<dynamic> items = response.data['items'] as List<dynamic>; final List<dynamic> items = response.data['items'] as List<dynamic>;
@@ -35,7 +35,7 @@ class CoverageRepositoryImpl implements CoverageRepository {
final String dateStr = final String dateStr =
'${date.year}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}'; '${date.year}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}';
final ApiResponse response = await _apiService.get( final ApiResponse response = await _apiService.get(
ClientEndpoints.coverageStats.path, ClientEndpoints.coverageStats,
params: <String, dynamic>{'date': dateStr}, params: <String, dynamic>{'date': dateStr},
); );
return CoverageStats.fromJson(response.data as Map<String, dynamic>); return CoverageStats.fromJson(response.data as Map<String, dynamic>);
@@ -67,7 +67,7 @@ class CoverageRepositoryImpl implements CoverageRepository {
body['markAsFavorite'] = markAsFavorite; body['markAsFavorite'] = markAsFavorite;
} }
await _apiService.post( await _apiService.post(
ClientEndpoints.coverageReviews.path, ClientEndpoints.coverageReviews,
data: body, data: body,
); );
} }
@@ -82,7 +82,7 @@ class CoverageRepositoryImpl implements CoverageRepository {
body['reason'] = reason; body['reason'] = reason;
} }
await _apiService.post( await _apiService.post(
ClientEndpoints.coverageCancelLateWorker(assignmentId).path, ClientEndpoints.coverageCancelLateWorker(assignmentId),
data: body, data: body,
); );
} }

View File

@@ -18,7 +18,7 @@ class HomeRepositoryImpl implements HomeRepositoryInterface {
@override @override
Future<ClientDashboard> getDashboard() async { Future<ClientDashboard> getDashboard() async {
final ApiResponse response = final ApiResponse response =
await _apiService.get(ClientEndpoints.dashboard.path); await _apiService.get(ClientEndpoints.dashboard);
final Map<String, dynamic> data = response.data as Map<String, dynamic>; final Map<String, dynamic> data = response.data as Map<String, dynamic>;
return ClientDashboard.fromJson(data); return ClientDashboard.fromJson(data);
} }
@@ -26,7 +26,7 @@ class HomeRepositoryImpl implements HomeRepositoryInterface {
@override @override
Future<List<RecentOrder>> getRecentReorders() async { Future<List<RecentOrder>> getRecentReorders() async {
final ApiResponse response = final ApiResponse response =
await _apiService.get(ClientEndpoints.reorders.path); await _apiService.get(ClientEndpoints.reorders);
final Map<String, dynamic> body = response.data as Map<String, dynamic>; final Map<String, dynamic> body = response.data as Map<String, dynamic>;
final List<dynamic> items = body['items'] as List<dynamic>; final List<dynamic> items = body['items'] as List<dynamic>;
return items return items

View File

@@ -17,7 +17,7 @@ class HubRepositoryImpl implements HubRepositoryInterface {
@override @override
Future<List<Hub>> getHubs() async { Future<List<Hub>> getHubs() async {
final ApiResponse response = final ApiResponse response =
await _apiService.get(ClientEndpoints.hubs.path); await _apiService.get(ClientEndpoints.hubs);
final List<dynamic> items = final List<dynamic> items =
(response.data as Map<String, dynamic>)['items'] as List<dynamic>; (response.data as Map<String, dynamic>)['items'] as List<dynamic>;
return items return items
@@ -28,7 +28,7 @@ class HubRepositoryImpl implements HubRepositoryInterface {
@override @override
Future<List<CostCenter>> getCostCenters() async { Future<List<CostCenter>> getCostCenters() async {
final ApiResponse response = final ApiResponse response =
await _apiService.get(ClientEndpoints.costCenters.path); await _apiService.get(ClientEndpoints.costCenters);
final List<dynamic> items = final List<dynamic> items =
(response.data as Map<String, dynamic>)['items'] as List<dynamic>; (response.data as Map<String, dynamic>)['items'] as List<dynamic>;
return items return items
@@ -52,7 +52,7 @@ class HubRepositoryImpl implements HubRepositoryInterface {
String? costCenterId, String? costCenterId,
}) async { }) async {
final ApiResponse response = await _apiService.post( final ApiResponse response = await _apiService.post(
ClientEndpoints.hubCreate.path, ClientEndpoints.hubCreate,
data: <String, dynamic>{ data: <String, dynamic>{
'name': name, 'name': name,
'fullAddress': fullAddress, 'fullAddress': fullAddress,
@@ -88,7 +88,7 @@ class HubRepositoryImpl implements HubRepositoryInterface {
String? costCenterId, String? costCenterId,
}) async { }) async {
final ApiResponse response = await _apiService.put( final ApiResponse response = await _apiService.put(
ClientEndpoints.hubUpdate(hubId).path, ClientEndpoints.hubUpdate(hubId),
data: <String, dynamic>{ data: <String, dynamic>{
'hubId': hubId, 'hubId': hubId,
if (name != null) 'name': name, if (name != null) 'name': name,
@@ -111,7 +111,7 @@ class HubRepositoryImpl implements HubRepositoryInterface {
@override @override
Future<void> deleteHub(String hubId) async { Future<void> deleteHub(String hubId) async {
await _apiService.delete(ClientEndpoints.hubDelete(hubId).path); await _apiService.delete(ClientEndpoints.hubDelete(hubId));
} }
@override @override
@@ -120,7 +120,7 @@ class HubRepositoryImpl implements HubRepositoryInterface {
required String nfcTagId, required String nfcTagId,
}) async { }) async {
await _apiService.post( await _apiService.post(
ClientEndpoints.hubAssignNfc(hubId).path, ClientEndpoints.hubAssignNfc(hubId),
data: <String, dynamic>{'nfcTagId': nfcTagId}, data: <String, dynamic>{'nfcTagId': nfcTagId},
); );
} }
@@ -128,7 +128,7 @@ class HubRepositoryImpl implements HubRepositoryInterface {
@override @override
Future<List<HubManager>> getManagers(String hubId) async { Future<List<HubManager>> getManagers(String hubId) async {
final ApiResponse response = final ApiResponse response =
await _apiService.get(ClientEndpoints.hubManagers(hubId).path); await _apiService.get(ClientEndpoints.hubManagers(hubId));
final List<dynamic> items = final List<dynamic> items =
(response.data as Map<String, dynamic>)['items'] as List<dynamic>; (response.data as Map<String, dynamic>)['items'] as List<dynamic>;
return items return items
@@ -143,7 +143,7 @@ class HubRepositoryImpl implements HubRepositoryInterface {
required List<String> businessMembershipIds, required List<String> businessMembershipIds,
}) async { }) async {
await _apiService.post( await _apiService.post(
ClientEndpoints.hubAssignManagers(hubId).path, ClientEndpoints.hubAssignManagers(hubId),
data: <String, dynamic>{ data: <String, dynamic>{
'businessMembershipIds': businessMembershipIds, 'businessMembershipIds': businessMembershipIds,
}, },

View File

@@ -24,17 +24,17 @@ class ClientCreateOrderRepositoryImpl
@override @override
Future<void> createOneTimeOrder(Map<String, dynamic> payload) async { Future<void> createOneTimeOrder(Map<String, dynamic> payload) async {
await _api.post(ClientEndpoints.ordersOneTime.path, data: payload); await _api.post(ClientEndpoints.ordersOneTime, data: payload);
} }
@override @override
Future<void> createRecurringOrder(Map<String, dynamic> payload) async { Future<void> createRecurringOrder(Map<String, dynamic> payload) async {
await _api.post(ClientEndpoints.ordersRecurring.path, data: payload); await _api.post(ClientEndpoints.ordersRecurring, data: payload);
} }
@override @override
Future<void> createPermanentOrder(Map<String, dynamic> payload) async { Future<void> createPermanentOrder(Map<String, dynamic> payload) async {
await _api.post(ClientEndpoints.ordersPermanent.path, data: payload); await _api.post(ClientEndpoints.ordersPermanent, data: payload);
} }
@override @override
@@ -82,7 +82,7 @@ class ClientCreateOrderRepositoryImpl
@override @override
Future<OrderPreview> getOrderDetailsForReorder(String orderId) async { Future<OrderPreview> getOrderDetailsForReorder(String orderId) async {
final ApiResponse response = await _api.get( final ApiResponse response = await _api.get(
ClientEndpoints.orderReorderPreview(orderId).path, ClientEndpoints.orderReorderPreview(orderId),
); );
return OrderPreview.fromJson(response.data as Map<String, dynamic>); return OrderPreview.fromJson(response.data as Map<String, dynamic>);
} }

View File

@@ -19,7 +19,7 @@ class ClientOrderQueryRepositoryImpl
@override @override
Future<List<Vendor>> getVendors() async { Future<List<Vendor>> getVendors() async {
final ApiResponse response = await _api.get(ClientEndpoints.vendors.path); final ApiResponse response = await _api.get(ClientEndpoints.vendors);
final Map<String, dynamic> data = response.data as Map<String, dynamic>; final Map<String, dynamic> data = response.data as Map<String, dynamic>;
final List<dynamic> items = data['items'] as List<dynamic>; final List<dynamic> items = data['items'] as List<dynamic>;
return items return items
@@ -30,7 +30,7 @@ class ClientOrderQueryRepositoryImpl
@override @override
Future<List<OrderRole>> getRolesByVendor(String vendorId) async { Future<List<OrderRole>> getRolesByVendor(String vendorId) async {
final ApiResponse response = final ApiResponse response =
await _api.get(ClientEndpoints.vendorRoles(vendorId).path); await _api.get(ClientEndpoints.vendorRoles(vendorId));
final Map<String, dynamic> data = response.data as Map<String, dynamic>; final Map<String, dynamic> data = response.data as Map<String, dynamic>;
final List<dynamic> items = data['items'] as List<dynamic>; final List<dynamic> items = data['items'] as List<dynamic>;
return items.map((dynamic json) { return items.map((dynamic json) {
@@ -46,7 +46,7 @@ class ClientOrderQueryRepositoryImpl
@override @override
Future<List<OrderHub>> getHubs() async { Future<List<OrderHub>> getHubs() async {
final ApiResponse response = await _api.get(ClientEndpoints.hubs.path); final ApiResponse response = await _api.get(ClientEndpoints.hubs);
final Map<String, dynamic> data = response.data as Map<String, dynamic>; final Map<String, dynamic> data = response.data as Map<String, dynamic>;
final List<dynamic> items = data['items'] as List<dynamic>; final List<dynamic> items = data['items'] as List<dynamic>;
return items.map((dynamic json) { return items.map((dynamic json) {
@@ -71,7 +71,7 @@ class ClientOrderQueryRepositoryImpl
@override @override
Future<List<OrderManager>> getManagersByHub(String hubId) async { Future<List<OrderManager>> getManagersByHub(String hubId) async {
final ApiResponse response = final ApiResponse response =
await _api.get(ClientEndpoints.hubManagers(hubId).path); await _api.get(ClientEndpoints.hubManagers(hubId));
final Map<String, dynamic> data = response.data as Map<String, dynamic>; final Map<String, dynamic> data = response.data as Map<String, dynamic>;
final List<dynamic> items = data['items'] as List<dynamic>; final List<dynamic> items = data['items'] as List<dynamic>;
return items.map((dynamic json) { return items.map((dynamic json) {

View File

@@ -20,7 +20,7 @@ class ViewOrdersRepositoryImpl implements IViewOrdersRepository {
required DateTime end, required DateTime end,
}) async { }) async {
final ApiResponse response = await _api.get( final ApiResponse response = await _api.get(
ClientEndpoints.ordersView.path, ClientEndpoints.ordersView,
params: <String, dynamic>{ params: <String, dynamic>{
'startDate': start.toIso8601String(), 'startDate': start.toIso8601String(),
'endDate': end.toIso8601String(), 'endDate': end.toIso8601String(),
@@ -40,7 +40,7 @@ class ViewOrdersRepositoryImpl implements IViewOrdersRepository {
required Map<String, dynamic> payload, required Map<String, dynamic> payload,
}) async { }) async {
final ApiResponse response = await _api.post( final ApiResponse response = await _api.post(
ClientEndpoints.orderEdit(orderId).path, ClientEndpoints.orderEdit(orderId),
data: payload, data: payload,
); );
final Map<String, dynamic> data = response.data as Map<String, dynamic>; final Map<String, dynamic> data = response.data as Map<String, dynamic>;
@@ -53,7 +53,7 @@ class ViewOrdersRepositoryImpl implements IViewOrdersRepository {
String? reason, String? reason,
}) async { }) async {
await _api.post( await _api.post(
ClientEndpoints.orderCancel(orderId).path, ClientEndpoints.orderCancel(orderId),
data: <String, dynamic>{ data: <String, dynamic>{
if (reason != null) 'reason': reason, if (reason != null) 'reason': reason,
}, },
@@ -62,7 +62,7 @@ class ViewOrdersRepositoryImpl implements IViewOrdersRepository {
@override @override
Future<List<Vendor>> getVendors() async { Future<List<Vendor>> getVendors() async {
final ApiResponse response = await _api.get(ClientEndpoints.vendors.path); final ApiResponse response = await _api.get(ClientEndpoints.vendors);
final Map<String, dynamic> data = response.data as Map<String, dynamic>; final Map<String, dynamic> data = response.data as Map<String, dynamic>;
final List<dynamic> items = data['items'] as List<dynamic>; final List<dynamic> items = data['items'] as List<dynamic>;
return items return items
@@ -73,7 +73,7 @@ class ViewOrdersRepositoryImpl implements IViewOrdersRepository {
@override @override
Future<List<Map<String, dynamic>>> getRolesByVendor(String vendorId) async { Future<List<Map<String, dynamic>>> getRolesByVendor(String vendorId) async {
final ApiResponse response = final ApiResponse response =
await _api.get(ClientEndpoints.vendorRoles(vendorId).path); await _api.get(ClientEndpoints.vendorRoles(vendorId));
final Map<String, dynamic> data = response.data as Map<String, dynamic>; final Map<String, dynamic> data = response.data as Map<String, dynamic>;
final List<dynamic> items = data['items'] as List<dynamic>; final List<dynamic> items = data['items'] as List<dynamic>;
return items.cast<Map<String, dynamic>>(); return items.cast<Map<String, dynamic>>();
@@ -81,7 +81,7 @@ class ViewOrdersRepositoryImpl implements IViewOrdersRepository {
@override @override
Future<List<Map<String, dynamic>>> getHubs() async { Future<List<Map<String, dynamic>>> getHubs() async {
final ApiResponse response = await _api.get(ClientEndpoints.hubs.path); final ApiResponse response = await _api.get(ClientEndpoints.hubs);
final Map<String, dynamic> data = response.data as Map<String, dynamic>; final Map<String, dynamic> data = response.data as Map<String, dynamic>;
final List<dynamic> items = data['items'] as List<dynamic>; final List<dynamic> items = data['items'] as List<dynamic>;
return items.cast<Map<String, dynamic>>(); return items.cast<Map<String, dynamic>>();
@@ -90,7 +90,7 @@ class ViewOrdersRepositoryImpl implements IViewOrdersRepository {
@override @override
Future<List<Map<String, dynamic>>> getManagersByHub(String hubId) async { Future<List<Map<String, dynamic>>> getManagersByHub(String hubId) async {
final ApiResponse response = final ApiResponse response =
await _api.get(ClientEndpoints.hubManagers(hubId).path); await _api.get(ClientEndpoints.hubManagers(hubId));
final Map<String, dynamic> data = response.data as Map<String, dynamic>; final Map<String, dynamic> data = response.data as Map<String, dynamic>;
final List<dynamic> items = data['items'] as List<dynamic>; final List<dynamic> items = data['items'] as List<dynamic>;
return items.cast<Map<String, dynamic>>(); return items.cast<Map<String, dynamic>>();

View File

@@ -32,7 +32,7 @@ class ReportsRepositoryImpl implements ReportsRepository {
required DateTime date, required DateTime date,
}) async { }) async {
final ApiResponse response = await _apiService.get( final ApiResponse response = await _apiService.get(
ClientEndpoints.reportsDailyOps.path, ClientEndpoints.reportsDailyOps,
params: <String, dynamic>{'date': _iso(date)}, params: <String, dynamic>{'date': _iso(date)},
); );
final Map<String, dynamic> data = response.data as Map<String, dynamic>; final Map<String, dynamic> data = response.data as Map<String, dynamic>;
@@ -45,7 +45,7 @@ class ReportsRepositoryImpl implements ReportsRepository {
required DateTime endDate, required DateTime endDate,
}) async { }) async {
final ApiResponse response = await _apiService.get( final ApiResponse response = await _apiService.get(
ClientEndpoints.reportsSpend.path, ClientEndpoints.reportsSpend,
params: _rangeParams(startDate, endDate), params: _rangeParams(startDate, endDate),
); );
final Map<String, dynamic> data = response.data as Map<String, dynamic>; final Map<String, dynamic> data = response.data as Map<String, dynamic>;
@@ -58,7 +58,7 @@ class ReportsRepositoryImpl implements ReportsRepository {
required DateTime endDate, required DateTime endDate,
}) async { }) async {
final ApiResponse response = await _apiService.get( final ApiResponse response = await _apiService.get(
ClientEndpoints.reportsCoverage.path, ClientEndpoints.reportsCoverage,
params: _rangeParams(startDate, endDate), params: _rangeParams(startDate, endDate),
); );
final Map<String, dynamic> data = response.data as Map<String, dynamic>; final Map<String, dynamic> data = response.data as Map<String, dynamic>;
@@ -71,7 +71,7 @@ class ReportsRepositoryImpl implements ReportsRepository {
required DateTime endDate, required DateTime endDate,
}) async { }) async {
final ApiResponse response = await _apiService.get( final ApiResponse response = await _apiService.get(
ClientEndpoints.reportsForecast.path, ClientEndpoints.reportsForecast,
params: _rangeParams(startDate, endDate), params: _rangeParams(startDate, endDate),
); );
final Map<String, dynamic> data = response.data as Map<String, dynamic>; final Map<String, dynamic> data = response.data as Map<String, dynamic>;
@@ -84,7 +84,7 @@ class ReportsRepositoryImpl implements ReportsRepository {
required DateTime endDate, required DateTime endDate,
}) async { }) async {
final ApiResponse response = await _apiService.get( final ApiResponse response = await _apiService.get(
ClientEndpoints.reportsPerformance.path, ClientEndpoints.reportsPerformance,
params: _rangeParams(startDate, endDate), params: _rangeParams(startDate, endDate),
); );
final Map<String, dynamic> data = response.data as Map<String, dynamic>; final Map<String, dynamic> data = response.data as Map<String, dynamic>;
@@ -97,7 +97,7 @@ class ReportsRepositoryImpl implements ReportsRepository {
required DateTime endDate, required DateTime endDate,
}) async { }) async {
final ApiResponse response = await _apiService.get( final ApiResponse response = await _apiService.get(
ClientEndpoints.reportsNoShow.path, ClientEndpoints.reportsNoShow,
params: _rangeParams(startDate, endDate), params: _rangeParams(startDate, endDate),
); );
final Map<String, dynamic> data = response.data as Map<String, dynamic>; final Map<String, dynamic> data = response.data as Map<String, dynamic>;
@@ -110,7 +110,7 @@ class ReportsRepositoryImpl implements ReportsRepository {
required DateTime endDate, required DateTime endDate,
}) async { }) async {
final ApiResponse response = await _apiService.get( final ApiResponse response = await _apiService.get(
ClientEndpoints.reportsSummary.path, ClientEndpoints.reportsSummary,
params: _rangeParams(startDate, endDate), params: _rangeParams(startDate, endDate),
); );
final Map<String, dynamic> data = response.data as Map<String, dynamic>; final Map<String, dynamic> data = response.data as Map<String, dynamic>;

View File

@@ -22,7 +22,7 @@ class SettingsRepositoryImpl implements SettingsRepositoryInterface {
Future<void> signOut() async { Future<void> signOut() async {
try { try {
// Step 1: Call V2 sign-out endpoint for server-side token revocation. // Step 1: Call V2 sign-out endpoint for server-side token revocation.
await _apiService.post(AuthEndpoints.clientSignOut.path); await _apiService.post(AuthEndpoints.clientSignOut);
} catch (e) { } catch (e) {
developer.log( developer.log(
'V2 sign-out request failed: $e', 'V2 sign-out request failed: $e',

View File

@@ -63,7 +63,7 @@ class AuthRepositoryImpl implements AuthRepositoryInterface {
try { try {
final domain.ApiResponse startResponse = await _apiService.post( final domain.ApiResponse startResponse = await _apiService.post(
AuthEndpoints.staffPhoneStart.path, AuthEndpoints.staffPhoneStart,
data: <String, dynamic>{ data: <String, dynamic>{
'phoneNumber': phoneNumber, 'phoneNumber': phoneNumber,
}, },
@@ -182,7 +182,7 @@ class AuthRepositoryImpl implements AuthRepositoryInterface {
// Step 3: Call V2 verify endpoint with the Firebase ID token. // Step 3: Call V2 verify endpoint with the Firebase ID token.
final String v2Mode = mode == AuthMode.signup ? 'sign-up' : 'sign-in'; final String v2Mode = mode == AuthMode.signup ? 'sign-up' : 'sign-in';
final domain.ApiResponse response = await _apiService.post( final domain.ApiResponse response = await _apiService.post(
AuthEndpoints.staffPhoneVerify.path, AuthEndpoints.staffPhoneVerify,
data: <String, dynamic>{ data: <String, dynamic>{
'idToken': idToken, 'idToken': idToken,
'mode': v2Mode, 'mode': v2Mode,
@@ -233,7 +233,7 @@ class AuthRepositoryImpl implements AuthRepositoryInterface {
@override @override
Future<void> signOut() async { Future<void> signOut() async {
try { try {
await _apiService.post(AuthEndpoints.staffSignOut.path); await _apiService.post(AuthEndpoints.staffSignOut);
} catch (_) { } catch (_) {
// Sign-out should not fail even if the API call fails. // Sign-out should not fail even if the API call fails.
// The local sign-out below will clear the session regardless. // The local sign-out below will clear the session regardless.

View File

@@ -27,7 +27,7 @@ class ProfileSetupRepositoryImpl implements ProfileSetupRepository {
required List<String> skills, required List<String> skills,
}) async { }) async {
final ApiResponse response = await _apiService.post( final ApiResponse response = await _apiService.post(
StaffEndpoints.profileSetup.path, StaffEndpoints.profileSetup,
data: <String, dynamic>{ data: <String, dynamic>{
'fullName': fullName, 'fullName': fullName,
if (bio != null && bio.isNotEmpty) 'bio': bio, if (bio != null && bio.isNotEmpty) 'bio': bio,

View File

@@ -25,7 +25,7 @@ class AvailabilityRepositoryImpl implements AvailabilityRepository {
final String endDate = _toIsoDate(end); final String endDate = _toIsoDate(end);
final ApiResponse response = await _apiService.get( final ApiResponse response = await _apiService.get(
StaffEndpoints.availability.path, StaffEndpoints.availability,
params: <String, dynamic>{ params: <String, dynamic>{
'startDate': startDate, 'startDate': startDate,
'endDate': endDate, 'endDate': endDate,
@@ -48,7 +48,7 @@ class AvailabilityRepositoryImpl implements AvailabilityRepository {
required List<TimeSlot> slots, required List<TimeSlot> slots,
}) async { }) async {
final ApiResponse response = await _apiService.put( final ApiResponse response = await _apiService.put(
StaffEndpoints.availability.path, StaffEndpoints.availability,
data: <String, dynamic>{ data: <String, dynamic>{
'dayOfWeek': dayOfWeek, 'dayOfWeek': dayOfWeek,
'availabilityStatus': status.toJson(), 'availabilityStatus': status.toJson(),
@@ -86,7 +86,7 @@ class AvailabilityRepositoryImpl implements AvailabilityRepository {
} }
await _apiService.post( await _apiService.post(
StaffEndpoints.availabilityQuickSet.path, StaffEndpoints.availabilityQuickSet,
data: data, data: data,
); );
} }

View File

@@ -17,7 +17,7 @@ class ClockInRepositoryImpl implements ClockInRepositoryInterface {
@override @override
Future<List<Shift>> getTodaysShifts() async { Future<List<Shift>> getTodaysShifts() async {
final ApiResponse response = await _apiService.get( final ApiResponse response = await _apiService.get(
StaffEndpoints.clockInShiftsToday.path, 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 // TODO: Ask BE to add latitude, longitude, hourlyRate, and clientName
@@ -33,7 +33,7 @@ class ClockInRepositoryImpl implements ClockInRepositoryInterface {
@override @override
Future<AttendanceStatus> getAttendanceStatus() async { Future<AttendanceStatus> getAttendanceStatus() async {
final ApiResponse response = await _apiService.get( final ApiResponse response = await _apiService.get(
StaffEndpoints.clockInStatus.path, StaffEndpoints.clockInStatus,
); );
return AttendanceStatus.fromJson(response.data as Map<String, dynamic>); return AttendanceStatus.fromJson(response.data as Map<String, dynamic>);
} }
@@ -44,7 +44,7 @@ class ClockInRepositoryImpl implements ClockInRepositoryInterface {
String? notes, String? notes,
}) async { }) async {
await _apiService.post( await _apiService.post(
StaffEndpoints.clockIn.path, StaffEndpoints.clockIn,
data: <String, dynamic>{ data: <String, dynamic>{
'shiftId': shiftId, 'shiftId': shiftId,
'sourceType': 'GEO', 'sourceType': 'GEO',
@@ -62,7 +62,7 @@ class ClockInRepositoryImpl implements ClockInRepositoryInterface {
String? shiftId, String? shiftId,
}) async { }) async {
await _apiService.post( await _apiService.post(
StaffEndpoints.clockOut.path, StaffEndpoints.clockOut,
data: <String, dynamic>{ data: <String, dynamic>{
if (shiftId != null) 'shiftId': shiftId, if (shiftId != null) 'shiftId': shiftId,
'sourceType': 'GEO', 'sourceType': 'GEO',

View File

@@ -17,7 +17,7 @@ class HomeRepositoryImpl implements HomeRepository {
@override @override
Future<StaffDashboard> getDashboard() async { Future<StaffDashboard> getDashboard() async {
final ApiResponse response = final ApiResponse response =
await _apiService.get(StaffEndpoints.dashboard.path); await _apiService.get(StaffEndpoints.dashboard);
final Map<String, dynamic> data = response.data as Map<String, dynamic>; final Map<String, dynamic> data = response.data as Map<String, dynamic>;
return StaffDashboard.fromJson(data); return StaffDashboard.fromJson(data);
} }
@@ -25,7 +25,7 @@ class HomeRepositoryImpl implements HomeRepository {
@override @override
Future<bool> getProfileCompletion() async { Future<bool> getProfileCompletion() async {
final ApiResponse response = final ApiResponse response =
await _apiService.get(StaffEndpoints.profileCompletion.path); await _apiService.get(StaffEndpoints.profileCompletion);
final Map<String, dynamic> data = response.data as Map<String, dynamic>; final Map<String, dynamic> data = response.data as Map<String, dynamic>;
final ProfileCompletion completion = ProfileCompletion.fromJson(data); final ProfileCompletion completion = ProfileCompletion.fromJson(data);
return completion.completed; return completion.completed;

View File

@@ -24,7 +24,7 @@ class PaymentsRepositoryImpl implements PaymentsRepository {
if (endDate != null) 'endDate': endDate, if (endDate != null) 'endDate': endDate,
}; };
final ApiResponse response = await _apiService.get( final ApiResponse response = await _apiService.get(
StaffEndpoints.paymentsSummary.path, StaffEndpoints.paymentsSummary,
params: params.isEmpty ? null : params, params: params.isEmpty ? null : params,
); );
return PaymentSummary.fromJson(response.data as Map<String, dynamic>); return PaymentSummary.fromJson(response.data as Map<String, dynamic>);
@@ -40,7 +40,7 @@ class PaymentsRepositoryImpl implements PaymentsRepository {
if (endDate != null) 'endDate': endDate, if (endDate != null) 'endDate': endDate,
}; };
final ApiResponse response = await _apiService.get( final ApiResponse response = await _apiService.get(
StaffEndpoints.paymentsHistory.path, StaffEndpoints.paymentsHistory,
params: params.isEmpty ? null : params, params: params.isEmpty ? null : params,
); );
final Map<String, dynamic> body = response.data as Map<String, dynamic>; final Map<String, dynamic> body = response.data as Map<String, dynamic>;
@@ -63,7 +63,7 @@ class PaymentsRepositoryImpl implements PaymentsRepository {
if (endDate != null) 'endDate': endDate, if (endDate != null) 'endDate': endDate,
}; };
final ApiResponse response = await _apiService.get( final ApiResponse response = await _apiService.get(
StaffEndpoints.paymentsChart.path, StaffEndpoints.paymentsChart,
params: params, params: params,
); );
final Map<String, dynamic> body = response.data as Map<String, dynamic>; final Map<String, dynamic> body = response.data as Map<String, dynamic>;

View File

@@ -14,7 +14,7 @@ class ProfileRepositoryImpl {
/// Fetches the staff profile from the V2 session endpoint. /// Fetches the staff profile from the V2 session endpoint.
Future<Staff> getStaffProfile() async { Future<Staff> getStaffProfile() async {
final ApiResponse response = final ApiResponse response =
await _api.get(StaffEndpoints.session.path); await _api.get(StaffEndpoints.session);
final Map<String, dynamic> json = final Map<String, dynamic> json =
response.data['staff'] as Map<String, dynamic>; response.data['staff'] as Map<String, dynamic>;
return Staff.fromJson(json); return Staff.fromJson(json);
@@ -23,7 +23,7 @@ class ProfileRepositoryImpl {
/// Fetches the profile section completion statuses. /// Fetches the profile section completion statuses.
Future<ProfileSectionStatus> getProfileSections() async { Future<ProfileSectionStatus> getProfileSections() async {
final ApiResponse response = final ApiResponse response =
await _api.get(StaffEndpoints.profileSections.path); await _api.get(StaffEndpoints.profileSections);
final Map<String, dynamic> json = final Map<String, dynamic> json =
response.data as Map<String, dynamic>; response.data as Map<String, dynamic>;
return ProfileSectionStatus.fromJson(json); return ProfileSectionStatus.fromJson(json);
@@ -31,6 +31,6 @@ class ProfileRepositoryImpl {
/// Signs out the current user. /// Signs out the current user.
Future<void> signOut() async { Future<void> signOut() async {
await _api.post(AuthEndpoints.signOut.path); await _api.post(AuthEndpoints.signOut);
} }
} }

View File

@@ -27,7 +27,7 @@ class CertificatesRepositoryImpl implements CertificatesRepository {
@override @override
Future<List<StaffCertificate>> getCertificates() async { Future<List<StaffCertificate>> getCertificates() async {
final ApiResponse response = final ApiResponse response =
await _api.get(StaffEndpoints.certificates.path); await _api.get(StaffEndpoints.certificates);
final List<dynamic> items = final List<dynamic> items =
response.data['certificates'] as List<dynamic>; response.data['certificates'] as List<dynamic>;
return items return items
@@ -73,7 +73,7 @@ class CertificatesRepositoryImpl implements CertificatesRepository {
// 4. Save certificate via V2 API // 4. Save certificate via V2 API
await _api.post( await _api.post(
StaffEndpoints.certificates.path, StaffEndpoints.certificates,
data: <String, dynamic>{ data: <String, dynamic>{
'certificateType': certificateType, 'certificateType': certificateType,
'name': name, 'name': name,
@@ -95,7 +95,7 @@ class CertificatesRepositoryImpl implements CertificatesRepository {
@override @override
Future<void> deleteCertificate({required String certificateId}) async { Future<void> deleteCertificate({required String certificateId}) async {
await _api.delete( await _api.delete(
StaffEndpoints.certificateDelete(certificateId).path, StaffEndpoints.certificateDelete(certificateId),
); );
} }
} }

View File

@@ -27,7 +27,7 @@ class DocumentsRepositoryImpl implements DocumentsRepository {
@override @override
Future<List<ProfileDocument>> getDocuments() async { Future<List<ProfileDocument>> getDocuments() async {
final ApiResponse response = final ApiResponse response =
await _api.get(StaffEndpoints.documents.path); await _api.get(StaffEndpoints.documents);
final List<dynamic> items = response.data['documents'] as List<dynamic>; final List<dynamic> items = response.data['documents'] as List<dynamic>;
return items return items
.map((dynamic json) => .map((dynamic json) =>
@@ -64,7 +64,7 @@ class DocumentsRepositoryImpl implements DocumentsRepository {
// 4. Submit upload result to V2 API // 4. Submit upload result to V2 API
await _api.put( await _api.put(
StaffEndpoints.documentUpload(documentId).path, StaffEndpoints.documentUpload(documentId),
data: <String, dynamic>{ data: <String, dynamic>{
'fileUri': signedUrlRes.signedUrl, 'fileUri': signedUrlRes.signedUrl,
'verificationId': verificationRes.verificationId, 'verificationId': verificationRes.verificationId,

View File

@@ -18,7 +18,7 @@ class TaxFormsRepositoryImpl implements TaxFormsRepository {
@override @override
Future<List<TaxForm>> getTaxForms() async { Future<List<TaxForm>> getTaxForms() async {
final ApiResponse response = final ApiResponse response =
await _api.get(StaffEndpoints.taxForms.path); await _api.get(StaffEndpoints.taxForms);
final List<dynamic> items = response.data['taxForms'] as List<dynamic>; final List<dynamic> items = response.data['taxForms'] as List<dynamic>;
return items return items
.map((dynamic json) => .map((dynamic json) =>
@@ -29,7 +29,7 @@ class TaxFormsRepositoryImpl implements TaxFormsRepository {
@override @override
Future<void> updateTaxForm(TaxForm form) async { Future<void> updateTaxForm(TaxForm form) async {
await _api.put( await _api.put(
StaffEndpoints.taxFormUpdate(form.formType).path, StaffEndpoints.taxFormUpdate(form.formType),
data: form.toJson(), data: form.toJson(),
); );
} }
@@ -37,7 +37,7 @@ class TaxFormsRepositoryImpl implements TaxFormsRepository {
@override @override
Future<void> submitTaxForm(TaxForm form) async { Future<void> submitTaxForm(TaxForm form) async {
await _api.post( await _api.post(
StaffEndpoints.taxFormSubmit(form.formType).path, StaffEndpoints.taxFormSubmit(form.formType),
data: form.toJson(), data: form.toJson(),
); );
} }

View File

@@ -16,7 +16,7 @@ class BankAccountRepositoryImpl implements BankAccountRepository {
@override @override
Future<List<BankAccount>> getAccounts() async { Future<List<BankAccount>> getAccounts() async {
final ApiResponse response = final ApiResponse response =
await _api.get(StaffEndpoints.bankAccounts.path); await _api.get(StaffEndpoints.bankAccounts);
final List<dynamic> items = response.data['accounts'] as List<dynamic>; final List<dynamic> items = response.data['accounts'] as List<dynamic>;
return items return items
.map((dynamic json) => .map((dynamic json) =>
@@ -27,7 +27,7 @@ class BankAccountRepositoryImpl implements BankAccountRepository {
@override @override
Future<void> addAccount(BankAccount account) async { Future<void> addAccount(BankAccount account) async {
await _api.post( await _api.post(
StaffEndpoints.bankAccounts.path, StaffEndpoints.bankAccounts,
data: account.toJson(), data: account.toJson(),
); );
} }

View File

@@ -16,7 +16,7 @@ class TimeCardRepositoryImpl implements TimeCardRepository {
@override @override
Future<List<TimeCardEntry>> getTimeCards(DateTime month) async { Future<List<TimeCardEntry>> getTimeCards(DateTime month) async {
final ApiResponse response = await _api.get( final ApiResponse response = await _api.get(
StaffEndpoints.timeCard.path, StaffEndpoints.timeCard,
params: <String, dynamic>{ params: <String, dynamic>{
'year': month.year, 'year': month.year,
'month': month.month, 'month': month.month,

View File

@@ -27,7 +27,7 @@ class AttireRepositoryImpl implements AttireRepository {
@override @override
Future<List<AttireChecklist>> getAttireOptions() async { Future<List<AttireChecklist>> getAttireOptions() async {
final ApiResponse response = await _api.get(StaffEndpoints.attire.path); final ApiResponse response = await _api.get(StaffEndpoints.attire);
final List<dynamic> items = response.data['items'] as List<dynamic>; final List<dynamic> items = response.data['items'] as List<dynamic>;
return items return items
.map((dynamic json) => .map((dynamic json) =>
@@ -100,7 +100,7 @@ class AttireRepositoryImpl implements AttireRepository {
// 5. Update attire item via V2 API // 5. Update attire item via V2 API
await _api.put( await _api.put(
StaffEndpoints.attireUpload(itemId).path, StaffEndpoints.attireUpload(itemId),
data: <String, dynamic>{ data: <String, dynamic>{
'photoUrl': photoUrl, 'photoUrl': photoUrl,
'verificationId': verifyRes.verificationId, 'verificationId': verifyRes.verificationId,

View File

@@ -17,7 +17,7 @@ class EmergencyContactRepositoryImpl
@override @override
Future<List<EmergencyContact>> getContacts() async { Future<List<EmergencyContact>> getContacts() async {
final ApiResponse response = final ApiResponse response =
await _api.get(StaffEndpoints.emergencyContacts.path); await _api.get(StaffEndpoints.emergencyContacts);
final List<dynamic> items = response.data['contacts'] as List<dynamic>; final List<dynamic> items = response.data['contacts'] as List<dynamic>;
return items return items
.map((dynamic json) => .map((dynamic json) =>
@@ -28,7 +28,7 @@ class EmergencyContactRepositoryImpl
@override @override
Future<void> saveContacts(List<EmergencyContact> contacts) async { Future<void> saveContacts(List<EmergencyContact> contacts) async {
await _api.put( await _api.put(
StaffEndpoints.emergencyContacts.path, StaffEndpoints.emergencyContacts,
data: <String, dynamic>{ data: <String, dynamic>{
'contacts': 'contacts':
contacts.map((EmergencyContact c) => c.toJson()).toList(), contacts.map((EmergencyContact c) => c.toJson()).toList(),

View File

@@ -16,14 +16,14 @@ class ExperienceRepositoryImpl implements ExperienceRepositoryInterface {
@override @override
Future<List<String>> getIndustries() async { Future<List<String>> getIndustries() async {
final ApiResponse response = final ApiResponse response =
await _api.get(StaffEndpoints.industries.path); await _api.get(StaffEndpoints.industries);
final List<dynamic> items = response.data['industries'] as List<dynamic>; final List<dynamic> items = response.data['industries'] as List<dynamic>;
return items.map((dynamic e) => e.toString()).toList(); return items.map((dynamic e) => e.toString()).toList();
} }
@override @override
Future<List<String>> getSkills() async { Future<List<String>> getSkills() async {
final ApiResponse response = await _api.get(StaffEndpoints.skills.path); final ApiResponse response = await _api.get(StaffEndpoints.skills);
final List<dynamic> items = response.data['skills'] as List<dynamic>; final List<dynamic> items = response.data['skills'] as List<dynamic>;
return items.map((dynamic e) => e.toString()).toList(); return items.map((dynamic e) => e.toString()).toList();
} }
@@ -34,7 +34,7 @@ class ExperienceRepositoryImpl implements ExperienceRepositoryInterface {
List<String> skills, List<String> skills,
) async { ) async {
await _api.put( await _api.put(
StaffEndpoints.personalInfo.path, StaffEndpoints.personalInfo,
data: <String, dynamic>{ data: <String, dynamic>{
'industries': industries, 'industries': industries,
'skills': skills, 'skills': skills,

View File

@@ -28,7 +28,7 @@ class PersonalInfoRepositoryImpl implements PersonalInfoRepositoryInterface {
@override @override
Future<StaffPersonalInfo> getStaffProfile() async { Future<StaffPersonalInfo> getStaffProfile() async {
final ApiResponse response = final ApiResponse response =
await _api.get(StaffEndpoints.personalInfo.path); await _api.get(StaffEndpoints.personalInfo);
final Map<String, dynamic> json = final Map<String, dynamic> json =
response.data as Map<String, dynamic>; response.data as Map<String, dynamic>;
return StaffPersonalInfo.fromJson(json); return StaffPersonalInfo.fromJson(json);
@@ -40,7 +40,7 @@ class PersonalInfoRepositoryImpl implements PersonalInfoRepositoryInterface {
required Map<String, dynamic> data, required Map<String, dynamic> data,
}) async { }) async {
final ApiResponse response = await _api.put( final ApiResponse response = await _api.put(
StaffEndpoints.personalInfo.path, StaffEndpoints.personalInfo,
data: data, data: data,
); );
final Map<String, dynamic> json = final Map<String, dynamic> json =
@@ -65,7 +65,7 @@ class PersonalInfoRepositoryImpl implements PersonalInfoRepositoryInterface {
// 3. Submit the photo URL to the V2 API. // 3. Submit the photo URL to the V2 API.
await _api.post( await _api.post(
StaffEndpoints.profilePhoto.path, StaffEndpoints.profilePhoto,
data: <String, dynamic>{ data: <String, dynamic>{
'fileUri': uploadRes.fileUri, 'fileUri': uploadRes.fileUri,
'photoUrl': photoUrl, 'photoUrl': photoUrl,

View File

@@ -18,7 +18,7 @@ class FaqsRepositoryImpl implements FaqsRepositoryInterface {
Future<List<FaqCategory>> getFaqs() async { Future<List<FaqCategory>> getFaqs() async {
try { try {
final ApiResponse response = final ApiResponse response =
await _apiService.get(StaffEndpoints.faqs.path); await _apiService.get(StaffEndpoints.faqs);
return _parseCategories(response); return _parseCategories(response);
} catch (_) { } catch (_) {
return <FaqCategory>[]; return <FaqCategory>[];
@@ -29,7 +29,7 @@ class FaqsRepositoryImpl implements FaqsRepositoryInterface {
Future<List<FaqCategory>> searchFaqs(String query) async { Future<List<FaqCategory>> searchFaqs(String query) async {
try { try {
final ApiResponse response = await _apiService.get( final ApiResponse response = await _apiService.get(
StaffEndpoints.faqsSearch.path, StaffEndpoints.faqsSearch,
params: <String, dynamic>{'q': query}, params: <String, dynamic>{'q': query},
); );
return _parseCategories(response); return _parseCategories(response);

View File

@@ -19,7 +19,7 @@ class PrivacySettingsRepositoryImpl
@override @override
Future<bool> getProfileVisibility() async { Future<bool> getProfileVisibility() async {
final ApiResponse response = final ApiResponse response =
await _api.get(StaffEndpoints.privacy.path); await _api.get(StaffEndpoints.privacy);
final Map<String, dynamic> json = final Map<String, dynamic> json =
response.data as Map<String, dynamic>; response.data as Map<String, dynamic>;
final PrivacySettings settings = PrivacySettings.fromJson(json); final PrivacySettings settings = PrivacySettings.fromJson(json);
@@ -29,7 +29,7 @@ class PrivacySettingsRepositoryImpl
@override @override
Future<bool> updateProfileVisibility(bool isVisible) async { Future<bool> updateProfileVisibility(bool isVisible) async {
await _api.put( await _api.put(
StaffEndpoints.privacy.path, StaffEndpoints.privacy,
data: <String, dynamic>{'profileVisible': isVisible}, data: <String, dynamic>{'profileVisible': isVisible},
); );
return isVisible; return isVisible;

View File

@@ -34,7 +34,7 @@ class ShiftsRepositoryImpl implements ShiftsRepositoryInterface {
required DateTime end, required DateTime end,
}) async { }) async {
final ApiResponse response = await _apiService.get( final ApiResponse response = await _apiService.get(
StaffEndpoints.shiftsAssigned.path, StaffEndpoints.shiftsAssigned,
params: <String, dynamic>{ params: <String, dynamic>{
'startDate': start.toIso8601String(), 'startDate': start.toIso8601String(),
'endDate': end.toIso8601String(), 'endDate': end.toIso8601String(),
@@ -59,7 +59,7 @@ class ShiftsRepositoryImpl implements ShiftsRepositoryInterface {
params['search'] = search; params['search'] = search;
} }
final ApiResponse response = await _apiService.get( final ApiResponse response = await _apiService.get(
StaffEndpoints.shiftsOpen.path, StaffEndpoints.shiftsOpen,
params: params, params: params,
); );
final List<dynamic> items = _extractItems(response.data); final List<dynamic> items = _extractItems(response.data);
@@ -72,7 +72,7 @@ class ShiftsRepositoryImpl implements ShiftsRepositoryInterface {
@override @override
Future<List<PendingAssignment>> getPendingAssignments() async { Future<List<PendingAssignment>> getPendingAssignments() async {
final ApiResponse response = final ApiResponse response =
await _apiService.get(StaffEndpoints.shiftsPending.path); await _apiService.get(StaffEndpoints.shiftsPending);
final List<dynamic> items = _extractItems(response.data); final List<dynamic> items = _extractItems(response.data);
return items return items
.map((dynamic json) => .map((dynamic json) =>
@@ -83,7 +83,7 @@ class ShiftsRepositoryImpl implements ShiftsRepositoryInterface {
@override @override
Future<List<CancelledShift>> getCancelledShifts() async { Future<List<CancelledShift>> getCancelledShifts() async {
final ApiResponse response = final ApiResponse response =
await _apiService.get(StaffEndpoints.shiftsCancelled.path); await _apiService.get(StaffEndpoints.shiftsCancelled);
final List<dynamic> items = _extractItems(response.data); final List<dynamic> items = _extractItems(response.data);
return items return items
.map((dynamic json) => .map((dynamic json) =>
@@ -94,7 +94,7 @@ class ShiftsRepositoryImpl implements ShiftsRepositoryInterface {
@override @override
Future<List<CompletedShift>> getCompletedShifts() async { Future<List<CompletedShift>> getCompletedShifts() async {
final ApiResponse response = final ApiResponse response =
await _apiService.get(StaffEndpoints.shiftsCompleted.path); await _apiService.get(StaffEndpoints.shiftsCompleted);
final List<dynamic> items = _extractItems(response.data); final List<dynamic> items = _extractItems(response.data);
return items return items
.map((dynamic json) => .map((dynamic json) =>
@@ -105,7 +105,7 @@ class ShiftsRepositoryImpl implements ShiftsRepositoryInterface {
@override @override
Future<ShiftDetail?> getShiftDetail(String shiftId) async { Future<ShiftDetail?> getShiftDetail(String shiftId) async {
final ApiResponse response = final ApiResponse response =
await _apiService.get(StaffEndpoints.shiftDetails(shiftId).path); await _apiService.get(StaffEndpoints.shiftDetails(shiftId));
if (response.data == null) { if (response.data == null) {
return null; return null;
} }
@@ -119,7 +119,7 @@ class ShiftsRepositoryImpl implements ShiftsRepositoryInterface {
bool instantBook = false, bool instantBook = false,
}) async { }) async {
await _apiService.post( await _apiService.post(
StaffEndpoints.shiftApply(shiftId).path, StaffEndpoints.shiftApply(shiftId),
data: <String, dynamic>{ data: <String, dynamic>{
if (roleId != null) 'roleId': roleId, if (roleId != null) 'roleId': roleId,
'instantBook': instantBook, 'instantBook': instantBook,
@@ -129,18 +129,18 @@ class ShiftsRepositoryImpl implements ShiftsRepositoryInterface {
@override @override
Future<void> acceptShift(String shiftId) async { Future<void> acceptShift(String shiftId) async {
await _apiService.post(StaffEndpoints.shiftAccept(shiftId).path); await _apiService.post(StaffEndpoints.shiftAccept(shiftId));
} }
@override @override
Future<void> declineShift(String shiftId) async { Future<void> declineShift(String shiftId) async {
await _apiService.post(StaffEndpoints.shiftDecline(shiftId).path); await _apiService.post(StaffEndpoints.shiftDecline(shiftId));
} }
@override @override
Future<void> requestSwap(String shiftId, {String? reason}) async { Future<void> requestSwap(String shiftId, {String? reason}) async {
await _apiService.post( await _apiService.post(
StaffEndpoints.shiftRequestSwap(shiftId).path, StaffEndpoints.shiftRequestSwap(shiftId),
data: <String, dynamic>{ data: <String, dynamic>{
if (reason != null) 'reason': reason, if (reason != null) 'reason': reason,
}, },
@@ -150,7 +150,7 @@ class ShiftsRepositoryImpl implements ShiftsRepositoryInterface {
@override @override
Future<bool> getProfileCompletion() async { Future<bool> getProfileCompletion() async {
final ApiResponse response = final ApiResponse response =
await _apiService.get(StaffEndpoints.profileCompletion.path); await _apiService.get(StaffEndpoints.profileCompletion);
final Map<String, dynamic> data = response.data as Map<String, dynamic>; final Map<String, dynamic> data = response.data as Map<String, dynamic>;
final ProfileCompletion completion = ProfileCompletion.fromJson(data); final ProfileCompletion completion = ProfileCompletion.fromJson(data);
return completion.completed; return completion.completed;

View File

@@ -23,7 +23,7 @@ class StaffMainRepositoryImpl implements StaffMainRepositoryInterface {
Future<bool> getProfileCompletion() async { Future<bool> getProfileCompletion() async {
try { try {
final ApiResponse response = await _apiService.get( final ApiResponse response = await _apiService.get(
StaffEndpoints.profileCompletion.path, StaffEndpoints.profileCompletion,
); );
if (response.data is Map<String, dynamic>) { if (response.data is Map<String, dynamic>) {