Merge branch 'origin/dev' into feature/session-persistence-new

This commit is contained in:
2026-03-20 12:44:25 +05:30
162 changed files with 6978 additions and 1283 deletions

View File

@@ -17,6 +17,6 @@ class AppConfig {
/// The base URL for the V2 Unified API gateway.
static const String v2ApiBaseUrl = String.fromEnvironment(
'V2_API_BASE_URL',
defaultValue: 'https://krow-api-v2-933560802882.us-central1.run.app',
defaultValue: 'https://krow-api-v2-e3g6witsvq-uc.a.run.app',
);
}

View File

@@ -112,6 +112,13 @@ extension StaffNavigator on IModularNavigator {
safeNavigate(StaffPaths.shiftDetails(shift.id), arguments: shift);
}
/// Navigates to the order details page for a given [AvailableOrder].
///
/// The order is passed as a data argument to the route.
void toOrderDetails(AvailableOrder order) {
safePush(StaffPaths.orderDetailsRoute, arguments: order);
}
/// Navigates to shift details by ID only (no pre-fetched [Shift] object).
///
/// Used when only the shift ID is available (e.g. from dashboard list items).

View File

@@ -107,6 +107,11 @@ class StaffPaths {
/// View detailed information for a specific shift.
static const String shiftDetailsRoute = '/worker-main/shift-details';
/// Order details route.
///
/// View detailed information for an available order and book/apply.
static const String orderDetailsRoute = '/worker-main/order-details';
/// Shift details page (dynamic).
///
/// View detailed information for a specific shift.

View File

@@ -92,7 +92,7 @@ abstract final class ClientEndpoints {
/// View orders.
static const ApiEndpoint ordersView =
ApiEndpoint('/client/orders/view');
ApiEndpoint('/client/shifts/scheduled');
/// Order reorder preview.
static ApiEndpoint orderReorderPreview(String orderId) =>

View File

@@ -14,6 +14,10 @@ abstract final class StaffEndpoints {
static const ApiEndpoint profileCompletion =
ApiEndpoint('/staff/profile-completion');
/// Staff reliability and performance statistics.
static const ApiEndpoint profileStats =
ApiEndpoint('/staff/profile/stats');
/// Staff availability schedule.
static const ApiEndpoint availability = ApiEndpoint('/staff/availability');
@@ -126,6 +130,10 @@ abstract final class StaffEndpoints {
/// FAQs search.
static const ApiEndpoint faqsSearch = ApiEndpoint('/staff/faqs/search');
/// Available orders for the marketplace.
static const ApiEndpoint ordersAvailable =
ApiEndpoint('/staff/orders/available');
// ── Write ─────────────────────────────────────────────────────────────
/// Staff profile setup.
@@ -194,6 +202,10 @@ abstract final class StaffEndpoints {
static const ApiEndpoint locationStreams =
ApiEndpoint('/staff/location-streams');
/// Book an available order.
static ApiEndpoint orderBook(String orderId) =>
ApiEndpoint('/staff/orders/$orderId/book');
/// Register or delete device push token (POST to register, DELETE to remove).
static const ApiEndpoint devicesPushTokens =
ApiEndpoint('/staff/devices/push-tokens');

View File

@@ -32,7 +32,7 @@ class AuthInterceptor extends Interceptor {
if (!skipAuth) {
final User? user = FirebaseAuth.instance.currentUser;
if (user != null) {
final String? token = await user.getIdToken();
final String? token = await user.getIdToken();
if (token != null) {
options.headers['Authorization'] = 'Bearer $token';
}

View File

@@ -4,4 +4,9 @@ class DateTimeUtils {
static DateTime toDeviceTime(DateTime date) {
return date.toLocal();
}
/// Converts a local [DateTime] back to UTC for API payloads.
static String toUtcIso(DateTime local) {
return local.toUtc().toIso8601String();
}
}

View File

@@ -68,3 +68,45 @@ String formatTime(String timeStr) {
}
}
}
/// Converts a local date + local HH:MM time string to a UTC HH:MM string.
///
/// Combines [localDate] with the hours and minutes from [localTime] (e.g.
/// "09:00") to create a full local [DateTime], converts it to UTC, then
/// extracts the HH:MM portion.
///
/// Example: March 19, "21:00" in UTC-5 → "02:00" (next day UTC).
String toUtcTimeHHmm(DateTime localDate, String localTime) {
final List<String> parts = localTime.split(':');
final DateTime localDt = DateTime(
localDate.year,
localDate.month,
localDate.day,
int.parse(parts[0]),
int.parse(parts[1]),
);
final DateTime utcDt = localDt.toUtc();
return '${utcDt.hour.toString().padLeft(2, '0')}:'
'${utcDt.minute.toString().padLeft(2, '0')}';
}
/// Converts a local date + local HH:MM time string to a UTC YYYY-MM-DD string.
///
/// This accounts for date-boundary crossings: a shift at 11 PM on March 19
/// in UTC-5 is actually March 20 in UTC.
///
/// Example: March 19, "23:00" in UTC-5 → "2026-03-20".
String toUtcDateIso(DateTime localDate, String localTime) {
final List<String> parts = localTime.split(':');
final DateTime localDt = DateTime(
localDate.year,
localDate.month,
localDate.day,
int.parse(parts[0]),
int.parse(parts[1]),
);
final DateTime utcDt = localDt.toUtc();
return '${utcDt.year.toString().padLeft(4, '0')}-'
'${utcDt.month.toString().padLeft(2, '0')}-'
'${utcDt.day.toString().padLeft(2, '0')}';
}