frontend: Owner management

This commit is contained in:
Frank Agerholm 2026-01-25 17:00:59 +01:00
commit 994ba0bc01
No known key found for this signature in database
8 changed files with 293 additions and 27 deletions

View file

@ -0,0 +1,59 @@
export function useApi() {
const config = useRuntimeConfig()
const { token, logout } = useAuth()
async function apiFetch<T>(url: string, options: any = {}) {
try {
return await $fetch<T>(url, {
baseURL: config.public.apiBase,
headers: {
...(options.headers || {}),
...(token.value ? { Authorization: `Bearer ${token.value}` } : {})
},
...options
})
} catch (error: any) {
// Netzwerkfehler oder Server nicht erreichbar
if (!error.response) {
console.error("API unreachable:", error)
throw new Error("Der Server ist nicht erreichbar.")
}
const status = error.response.status
const data = error.response._data
// 401 → Token ungültig oder abgelaufen
if (status === 401) {
console.warn("API returned 401 — logging out")
logout()
throw new Error("Deine Sitzung ist abgelaufen. Bitte erneut einloggen.")
}
// 403 → keine Berechtigung
if (status === 403) {
throw new Error("Du hast keine Berechtigung für diese Aktion.")
}
// 400 → Validierungsfehler
if (status === 400) {
throw new Error(data?.detail || "Ungültige Eingabe.")
}
// 404 → nicht gefunden
if (status === 404) {
throw new Error("Die angeforderte Ressource wurde nicht gefunden.")
}
// 500 → Serverfehler
if (status >= 500) {
console.error("Server error:", data)
throw new Error("Interner Serverfehler. Bitte später erneut versuchen.")
}
// Fallback
throw new Error(data?.detail || "Unbekannter Fehler.")
}
}
return { apiFetch }
}

View file

@ -1,15 +1,46 @@
function decodeJwt(token: string) {
try {
const payload = token.split(".")[1]
const decoded = JSON.parse(atob(payload))
return decoded
} catch {
return null
}
}
export function useAuth() {
const token = useState("token", () => null)
const token = useState<string | null>("token", () => null)
function setToken(t: string) {
token.value = t
localStorage.setItem("token", t)
if (typeof window !== "undefined") {
localStorage.setItem("token", t)
}
}
function loadToken() {
token.value = localStorage.getItem("token")
if (typeof window !== "undefined") {
const stored = localStorage.getItem("token")
if (!stored) return
const payload = decodeJwt(stored)
if( !payload || !payload.exp || payload.exp * 1000 < Date.now()) {
console.info("Token expired - removing it from storage")
localStorage.removeItem("token")
token.value = null
}
token.value = stored
}
}
return { token, setToken, loadToken }
}
function logout() {
token.value = null
if (typeof window !== "undefined") {
localStorage.removeItem("token")
}
}
return { token, setToken, loadToken, logout }
}