feat(scheduling): add frontend types and API client
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
23
src/modules/scheduling/api.ts
Normal file
23
src/modules/scheduling/api.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { fetchJson } from '../../auth/api-client';
|
||||
import type { SchedulingResponse } from './types';
|
||||
|
||||
const BASE = '/api/scheduling';
|
||||
|
||||
export async function fetchSuggestions(targetId?: number): Promise<SchedulingResponse> {
|
||||
const params = new URLSearchParams();
|
||||
if (targetId !== undefined) params.set('targetId', String(targetId));
|
||||
const qs = params.toString();
|
||||
return fetchJson<SchedulingResponse>(`${BASE}/suggestions${qs ? `?${qs}` : ''}`);
|
||||
}
|
||||
|
||||
export async function sendNotify(body: {
|
||||
suggestionId: string;
|
||||
currentPlate: string;
|
||||
candidatePlate: string;
|
||||
}): Promise<{ success: boolean; message: string }> {
|
||||
return fetchJson<{ success: boolean; message: string }>(`${BASE}/notify`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
}
|
||||
58
src/modules/scheduling/types.ts
Normal file
58
src/modules/scheduling/types.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
export interface SchedulingVehicleInfo {
|
||||
plateNumber: string;
|
||||
targetId: number;
|
||||
targetName: string;
|
||||
vehicleType: string;
|
||||
totalMileage: number;
|
||||
completionRate: number;
|
||||
yearTarget: number;
|
||||
region: string;
|
||||
province: string;
|
||||
customer: string | null;
|
||||
customerAvgDaily: number;
|
||||
predictedYearEnd: number;
|
||||
daysLeft: number;
|
||||
}
|
||||
|
||||
export interface CandidateVehicle {
|
||||
plateNumber: string;
|
||||
targetId: number | null;
|
||||
targetName: string | null;
|
||||
vehicleType: string;
|
||||
totalMileage: number;
|
||||
completionRate: number;
|
||||
yearTarget: number | null;
|
||||
region: string;
|
||||
province: string;
|
||||
mileageGap: number;
|
||||
predictedAfterSwap: number;
|
||||
canQualifyAfterSwap: boolean;
|
||||
}
|
||||
|
||||
export interface SchedulingSuggestion {
|
||||
id: string;
|
||||
priority: 'high' | 'medium';
|
||||
type: 'replace_qualified' | 'rescue_hopeless';
|
||||
currentVehicle: SchedulingVehicleInfo;
|
||||
candidates: CandidateVehicle[];
|
||||
reason: string;
|
||||
}
|
||||
|
||||
export interface SchedulingSummary {
|
||||
qualifiedCount: number;
|
||||
hopelessCount: number;
|
||||
suggestionCount: number;
|
||||
estimatedGain: number;
|
||||
}
|
||||
|
||||
export interface SchedulingTargetOption {
|
||||
id: number;
|
||||
name: string;
|
||||
vehicleCount: number;
|
||||
}
|
||||
|
||||
export interface SchedulingResponse {
|
||||
summary: SchedulingSummary;
|
||||
suggestions: SchedulingSuggestion[];
|
||||
targets: SchedulingTargetOption[];
|
||||
}
|
||||
Reference in New Issue
Block a user