diff --git a/.gitignore b/.gitignore index 0aed684..ae1db17 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ downloads/ eggs/ .eggs/ lib/ +!frontend/src/lib/ lib64/ parts/ sdist/ diff --git a/frontend/src/lib/api.ts b/frontend/src/lib/api.ts new file mode 100644 index 0000000..18fd3db --- /dev/null +++ b/frontend/src/lib/api.ts @@ -0,0 +1,106 @@ +const API_BASE = process.env.NEXT_PUBLIC_API_URL || ""; + +interface ApiResponse { + data?: T; + error?: string; +} + +async function fetchApi( + endpoint: string, + options: RequestInit = {} +): Promise> { + const token = + typeof window !== "undefined" ? localStorage.getItem("token") : null; + + const headers: HeadersInit = { + "Content-Type": "application/json", + ...options.headers, + }; + + if (token) { + (headers as Record)["Authorization"] = `Bearer ${token}`; + } + + try { + const response = await fetch(`${API_BASE}${endpoint}`, { + ...options, + headers, + }); + + const data = await response.json(); + + if (!response.ok) { + return { error: data.error || "Ein Fehler ist aufgetreten" }; + } + + return { data }; + } catch (error) { + return { error: "Netzwerkfehler - Server nicht erreichbar" }; + } +} + +export interface LoginResponse { + access_token: string; + token_type: string; + expires_in: number; + user: { + id: number; + username: string; + email: string; + }; +} + +export interface UserResponse { + user: { + id: number; + username: string; + email: string; + created_at: string | null; + }; + container: { + id: string | null; + port: number | null; + status: string; + service_url: string; + }; +} + +export interface ContainerStatusResponse { + container_id: string | null; + status: string; +} + +export interface ContainerRestartResponse { + message: string; + container_id: string; + status: string; +} + +export const api = { + login: (username: string, password: string) => + fetchApi("/api/auth/login", { + method: "POST", + body: JSON.stringify({ username, password }), + }), + + signup: (username: string, email: string, password: string) => + fetchApi("/api/auth/signup", { + method: "POST", + body: JSON.stringify({ username, email, password }), + }), + + logout: () => + fetchApi<{ message: string }>("/api/auth/logout", { + method: "POST", + }), + + getUser: () => fetchApi("/api/user/me"), + + getContainerStatus: () => + fetchApi("/api/container/status"), + + restartContainer: () => + fetchApi("/api/container/restart", { + method: "POST", + }), +}; diff --git a/frontend/src/lib/utils.ts b/frontend/src/lib/utils.ts new file mode 100644 index 0000000..a5ef193 --- /dev/null +++ b/frontend/src/lib/utils.ts @@ -0,0 +1,6 @@ +import { clsx, type ClassValue } from "clsx"; +import { twMerge } from "tailwind-merge"; + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)); +}