Frontend an Backend angebunden mit API-Wrapper und Datenmapping

This commit is contained in:
root
2025-03-13 09:17:22 +01:00
parent b0d8d4f915
commit 9ffa70aad1
5 changed files with 398 additions and 150 deletions

View File

@ -0,0 +1,85 @@
// TypeScript-Definitionen für die Backend-API-Responses
// Steckdosenmodell (entspricht dem Backend socket)
export interface BackendPrinter {
id: string;
name: string;
description: string;
status: number; // 0=available, 1=busy
ipAddress?: string;
connectionStatus?: string;
lastSeen?: string;
uptimeInfo?: {
offline_since?: string;
offline_duration?: number;
offline_duration_formatted?: string;
};
latestJob?: BackendJob | null;
waitingJobs?: BackendJob[];
}
// Druckauftrag (entspricht dem Backend job)
export interface BackendJob {
id: string;
socketId: string; // Backend nennt es socketId statt printerId
userId: string;
startAt: string;
durationInMinutes: number;
comments: string | null;
aborted: boolean;
abortReason: string | null;
waitingApproval?: boolean;
remainingMinutes?: number;
}
// Für die Kartierung zwischen Frontend und Backend
export const mapBackendPrinterToFrontend = (printer: BackendPrinter) => {
return {
id: printer.id,
name: printer.name,
description: printer.description,
status: printer.status,
// Weitere Felder für Frontend-Anpassungen
connectionStatus: printer.connectionStatus || 'unknown',
uptimeInfo: printer.uptimeInfo,
// Transformiere das aktuelle Job-Format
printJobs: printer.latestJob ? [mapBackendJobToFrontend(printer.latestJob)] : [],
// Weitere wartende Jobs
waitingJobs: printer.waitingJobs?.map(mapBackendJobToFrontend) || [],
};
};
export const mapFrontendPrinterToBackend = (printer: any) => {
return {
id: printer.id,
name: printer.name,
description: printer.description,
status: printer.status,
// Frontend hat keine IP-Adresse, diese wird vom Backend verwaltet
};
};
export const mapBackendJobToFrontend = (job: BackendJob) => {
return {
id: job.id,
printerId: job.socketId, // Anpassung des Feldnamens
userId: job.userId,
startAt: new Date(job.startAt),
durationInMinutes: job.durationInMinutes,
comments: job.comments || '',
aborted: job.aborted,
abortReason: job.abortReason || '',
waitingApproval: job.waitingApproval || false,
remainingMinutes: job.remainingMinutes || 0,
};
};
export const mapFrontendJobToBackend = (job: any) => {
return {
printerId: job.printerId, // Im Backend als socketId
userId: job.userId,
durationInMinutes: job.durationInMinutes,
comments: job.comments || '',
// Die restlichen Felder werden vom Backend verwaltet
};
};

View File

@ -1 +1,74 @@
// Konfiguration für das Backend
export const BACKEND_URL = process.env.BACKEND_URL || 'http://localhost:5000';
// Standard Fetcher für SWR
export const fetcher = (url: string) => fetch(url).then((response) => response.json());
// Backend API Client für direkte API-Calls
export const backendFetcher = async (endpoint: string, options?: RequestInit) => {
const url = `${BACKEND_URL}${endpoint}`;
const response = await fetch(url, {
...options,
headers: {
'Content-Type': 'application/json',
...options?.headers,
},
});
if (!response.ok) {
throw new Error(`Backend API error: ${response.status} ${response.statusText}`);
}
return response.json();
};
// Backend API Wrapper mit spezifischen Endpunkten
export const backendApi = {
// Drucker-Endpunkte
printers: {
getAll: () => backendFetcher('/api/printers'),
getById: (id: string) => backendFetcher(`/api/printers/${id}`),
create: (data: any) => backendFetcher('/api/printers', {
method: 'POST',
body: JSON.stringify(data),
}),
update: (id: string, data: any) => backendFetcher(`/api/printers/${id}`, {
method: 'PUT',
body: JSON.stringify(data),
}),
delete: (id: string) => backendFetcher(`/api/printers/${id}`, {
method: 'DELETE',
}),
},
// Druckaufträge-Endpunkte
jobs: {
getAll: () => backendFetcher('/api/jobs'),
getById: (id: string) => backendFetcher(`/api/jobs/${id}`),
create: (data: any) => backendFetcher('/api/jobs', {
method: 'POST',
body: JSON.stringify(data),
}),
abort: (id: string, reason: string) => backendFetcher(`/api/jobs/${id}/abort`, {
method: 'POST',
body: JSON.stringify({ reason }),
}),
finish: (id: string) => backendFetcher(`/api/jobs/${id}/finish`, {
method: 'POST',
}),
extend: (id: string, minutes: number, hours: number) => backendFetcher(`/api/jobs/${id}/extend`, {
method: 'POST',
body: JSON.stringify({ minutes, hours }),
}),
updateComments: (id: string, comments: string) => backendFetcher(`/api/jobs/${id}/comments`, {
method: 'PUT',
body: JSON.stringify({ comments }),
}),
getRemainingTime: (id: string) => backendFetcher(`/api/job/${id}/remaining-time`),
},
// Statistiken-Endpunkt
stats: {
get: () => backendFetcher('/api/stats'),
},
};