Merge branch 'origin/dev' into feature/session-persistence-new
This commit is contained in:
@@ -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',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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) =>
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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';
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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')}';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user