- Add register screen with onboarding redirect to address validation - Add waste separation guide screen with 4 categories and offline tips (organicos, reciclables, sanitarios, especiales) plus preventive messaging banner - Add feedback submission screen with 4 types and 1-5 star rating - Add address screen: list colonias, pick one, validate against backend - Switch from pull-to-refresh GPS hack to periodic polling of /tracking/status (30s) — backend now drives the simulation - Filter notifications by logged-in user.id (tunnel-view on client side) - Add register/logout/address actions to profile screen - Hide login/register/feedback/addresses from tab bar (href: null) - Set API_URL to LAN IP for physical phone testing over hotspot
74 lines
1.6 KiB
TypeScript
74 lines
1.6 KiB
TypeScript
import { apiFetch } from "../lib/api";
|
|
|
|
export type NotificationType =
|
|
| "ROUTE_START"
|
|
| "TRUCK_PROXIMITY"
|
|
| "TRUCK_ARRIVED"
|
|
| "ROUTE_COMPLETED"
|
|
| "DELAY"
|
|
| "MECHANICAL_FAILURE";
|
|
|
|
export interface GpsUpdatePayload {
|
|
truckId: string;
|
|
routeId: string;
|
|
lat: number;
|
|
lng: number;
|
|
speed: number;
|
|
status: "EN_RUTA" | "DETENIDO" | "FINALIZADO" | "FALLA";
|
|
positionId?: number;
|
|
timestamp?: string;
|
|
}
|
|
|
|
export interface EtaResult {
|
|
etaMinutes: number;
|
|
arrivalWindow: { from: string; to: string };
|
|
message: string;
|
|
}
|
|
|
|
export interface BackendNotification {
|
|
userId: number;
|
|
type: NotificationType;
|
|
title: string;
|
|
body: string;
|
|
}
|
|
|
|
export interface GpsUpdateResponse {
|
|
message: string;
|
|
truck: { truckId: number; routeId: string; status: string };
|
|
eta: EtaResult;
|
|
notifications: BackendNotification[];
|
|
}
|
|
|
|
export const sendGpsUpdate = (payload: GpsUpdatePayload) =>
|
|
apiFetch<GpsUpdateResponse>("/api/tracking/gps-update", {
|
|
method: "POST",
|
|
body: JSON.stringify(payload),
|
|
});
|
|
|
|
export interface InboxNotification {
|
|
id: string;
|
|
userId: number;
|
|
type: NotificationType;
|
|
title: string;
|
|
body: string;
|
|
createdAt: string;
|
|
}
|
|
|
|
export interface UserStatusResponse {
|
|
user: { id: number; name: string; colonia: string };
|
|
route: {
|
|
routeId: string;
|
|
currentPositionId: number;
|
|
status: string;
|
|
updatedAt: string;
|
|
horarioEstimado: string | null;
|
|
};
|
|
eta: EtaResult | null;
|
|
notifications: InboxNotification[];
|
|
}
|
|
|
|
export const getMyStatus = () =>
|
|
apiFetch<UserStatusResponse>("/api/tracking/status");
|
|
|
|
export const resetDemo = () =>
|
|
apiFetch<{ message: string }>("/api/tracking/reset-demo", { method: "POST" }); |