diff --git a/packages/reservation-platform/src/app/api/printers/route.ts b/packages/reservation-platform/src/app/api/printers/route.ts index d9e06fb..f4ba797 100755 --- a/packages/reservation-platform/src/app/api/printers/route.ts +++ b/packages/reservation-platform/src/app/api/printers/route.ts @@ -1,9 +1,22 @@ -import { getPrinters } from "@/server/actions/printers"; +import { backendApi } from "@/utils/fetch"; +import { mapBackendPrinterToFrontend } from "@/utils/backend-types"; export const dynamic = "force-dynamic"; export async function GET() { - const printers = await getPrinters(); + try { + // Hole Drucker vom Backend statt aus der lokalen Datenbank + const backendPrinters = await backendApi.printers.getAll(); + + // Transformiere die Backend-Daten ins Frontend-Format + const printers = backendPrinters.map(mapBackendPrinterToFrontend); - return Response.json(printers); + return Response.json(printers); + } catch (error) { + console.error("Fehler beim Abrufen der Drucker vom Backend:", error); + return Response.json( + { error: "Fehler beim Abrufen der Drucker vom Backend" }, + { status: 500 } + ); + } } diff --git a/packages/reservation-platform/src/server/actions/printJobs.ts b/packages/reservation-platform/src/server/actions/printJobs.ts index 89e05e5..fd44869 100755 --- a/packages/reservation-platform/src/server/actions/printJobs.ts +++ b/packages/reservation-platform/src/server/actions/printJobs.ts @@ -30,14 +30,47 @@ export async function createPrintJob(printJob: InferInsertModel) { const { user } = await validateRequest(); @@ -35,8 +37,16 @@ export async function createPrinter(printer: InferInsertModel) } try { + // Transformiere die Daten ins Backend-Format + const backendPrinter = mapFrontendPrinterToBackend(printer); + + // Rufe das Backend API auf + await backendApi.printers.create(backendPrinter); + + // Lokale Datenbank bleibt synchronisiert (optional, wenn du weiterhin lokale Daten brauchst) await db.insert(printers).values(printer); } catch (error) { + console.error("Fehler beim Erstellen des Druckers:", error); return { error: "Drucker konnte nicht hinzugefügt werden.", }; @@ -72,10 +82,18 @@ export async function updatePrinter(id: string, data: InferInsertModel [desc(printJobs.startAt)], + try { + // Rufe die Drucker vom Backend ab + const backendPrinters = await backendApi.printers.getAll(); + + // Transformiere die Backend-Daten ins Frontend-Format + return backendPrinters.map(mapBackendPrinterToFrontend); + } catch (error) { + console.error("Fehler beim Abrufen der Drucker:", error); + + // Fallback zur lokalen Datenbank, falls das Backend nicht erreichbar ist + return await db.query.printers.findMany({ + with: { + printJobs: { + limit: 1, + orderBy: (printJobs, { desc }) => [desc(printJobs.startAt)], + }, }, - }, - }); + }); + } } diff --git a/packages/reservation-platform/src/utils/backend-types.ts b/packages/reservation-platform/src/utils/backend-types.ts new file mode 100644 index 0000000..c72b351 --- /dev/null +++ b/packages/reservation-platform/src/utils/backend-types.ts @@ -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 + }; +}; \ No newline at end of file diff --git a/packages/reservation-platform/src/utils/fetch.ts b/packages/reservation-platform/src/utils/fetch.ts index 4945184..669e2cd 100755 --- a/packages/reservation-platform/src/utils/fetch.ts +++ b/packages/reservation-platform/src/utils/fetch.ts @@ -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'), + }, +};