Files
mechanic-pwa/mechanic-pwa/frontend/src/api/auth.ts
T
tremble7681andclaude-flow 537548d716 feat(mechanic-pwa): Login + Home + VehicleCard pages with TanStack Query + OAuth2 login
- api/auth.ts: OAuth2 password flow via form-urlencoded POST /api/auth/login (not mechanic prefix)
- api/me.ts: GET /api/v1/mechanic/me with Me interface
- api/vehicles.ts: listVehicles (unwraps {items:[]}), getVehicle with VehicleDetail + InspectionSummary
- api/inspections.ts: createInspection returning full InspectionDetail; 9-value InspectionType union
- Login.tsx: full form with Логин/Пароль labels, useMutation, toast feedback, navigate on success
- Home.tsx: vehicle list with search, /me header with user name, logout, TanStack Query
- VehicleCard.tsx: vehicle info card, all 9 inspection type buttons (ru labels), history list

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-05-17 10:44:39 +10:00

33 lines
815 B
TypeScript

import { useAuth } from "@/store/auth";
export interface LoginInput {
username: string;
password: string;
}
export interface LoginOutput {
access_token: string;
token_type: string;
}
export async function login(input: LoginInput): Promise<LoginOutput> {
// OAuth2 password flow — form-urlencoded, NOT JSON, NOT under /api/v1/mechanic/
const body = new URLSearchParams();
body.set("username", input.username);
body.set("password", input.password);
const res = await fetch("/api/auth/login", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body,
});
if (!res.ok) {
throw new Error(`Login failed: ${res.status}`);
}
return res.json() as Promise<LoginOutput>;
}
export function logout(): void {
useAuth.getState().setToken(null);
}