114 lines
3.6 KiB
TypeScript
114 lines
3.6 KiB
TypeScript
// services/trip.service.ts
|
|
// All API calls for the Trip module.
|
|
// Endpoints extracted from: trip_api_reference.html → /api/v1/trips/...
|
|
// Follows the exact same pattern as services/driver.service.ts.
|
|
|
|
import { get, post, patch, del } from "./api";
|
|
import type {
|
|
Trip,
|
|
TripListResponse,
|
|
TripDetailResponse,
|
|
TripReportResponse,
|
|
CreateTripPayload,
|
|
UpdateTripPayload,
|
|
TripListParams,
|
|
} from "@/types/trip";
|
|
|
|
/** Build a query string for list endpoints */
|
|
function buildQuery(
|
|
params: Record<string, string | number | undefined>,
|
|
): string {
|
|
const entries = Object.entries(params).filter(
|
|
([, v]) => v !== undefined && v !== "",
|
|
);
|
|
if (!entries.length) return "";
|
|
return (
|
|
"?" +
|
|
entries
|
|
.map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`)
|
|
.join("&")
|
|
);
|
|
}
|
|
|
|
export const tripService = {
|
|
/**
|
|
* GET /trips
|
|
* Fetch paginated + filterable + searchable trip list.
|
|
* Requires: "read-trip" permission
|
|
*/
|
|
getAll: (params: TripListParams = {}, token: string | null) =>
|
|
get<TripListResponse>(`trips${buildQuery({ ...params })}`, token),
|
|
|
|
/**
|
|
* GET /trips/archived
|
|
* Fetch soft-deleted (archived) trips. Same filters as getAll.
|
|
* Requires: "read-deleted-trip" permission
|
|
*/
|
|
getArchived: (params: TripListParams = {}, token: string | null) =>
|
|
get<TripListResponse>(`trips/archived${buildQuery({ ...params })}`, token),
|
|
|
|
/**
|
|
* GET /trips/archived/:id
|
|
* Fetch a single archived trip with full details.
|
|
* Requires: "read-deleted-trip" permission
|
|
*/
|
|
getArchivedById: (id: string, token: string | null) =>
|
|
get<TripDetailResponse>(`trips/archived/${id}`, token),
|
|
|
|
/**
|
|
* GET /trips/:id
|
|
* Fetch a single trip with full driver/car details.
|
|
* Requires: "read-trip" permission
|
|
*/
|
|
getById: (id: string, token: string | null) =>
|
|
get<TripDetailResponse>(`trips/${id}`, token),
|
|
|
|
/**
|
|
* POST /trips
|
|
* Create a new trip.
|
|
* Side effect: driver & car flip to status "InTrip" automatically.
|
|
* Requires: "create-trip" permission
|
|
*/
|
|
create: (payload: CreateTripPayload, token: string | null) =>
|
|
post<{ data: Trip }>("trips", payload, token),
|
|
|
|
/**
|
|
* PATCH /trips/:id
|
|
* Update trip data / status / reassign driver or car.
|
|
* Side effects:
|
|
* - changing driverId: old driver -> Active, new driver -> InTrip
|
|
* - changing carId: same logic for cars
|
|
* - status Completed/Cancelled: driver & car both -> Active
|
|
* Requires: "update-trip" permission
|
|
*/
|
|
update: (id: string, payload: UpdateTripPayload, token: string | null) =>
|
|
patch<{ data: Trip }>(`trips/${id}`, payload, token),
|
|
|
|
/**
|
|
* DELETE /trips/:id
|
|
* Soft-delete a trip (isDeleted=true, deletedAt=now()). 204 No Content.
|
|
* Requires: "delete-trip" permission
|
|
*/
|
|
delete: (id: string, token: string | null) =>
|
|
del<void>(`trips/${id}`, token),
|
|
|
|
// ── Reports ───────────────────────────────────────────────────────────────
|
|
|
|
/**
|
|
* GET /trips/:id/reports
|
|
* Generate the Trip Manifest report (HTML, saved server-side).
|
|
* Returns { reportUrl }
|
|
* Requires: "generate-trip-report" permission
|
|
*/
|
|
getReport: (id: string, token: string | null) =>
|
|
get<TripReportResponse>(`trips/${id}/reports`, token),
|
|
|
|
/**
|
|
* GET /trips/:id/reports/client/:clientId
|
|
* Generate a client-filtered version of the trip report.
|
|
* Returns { reportUrl }
|
|
* Requires: "generate-trip-report" permission
|
|
*/
|
|
getClientReport: (id: string, clientId: string, token: string | null) =>
|
|
get<TripReportResponse>(`trips/${id}/reports/client/${clientId}`, token),
|
|
}; |