Cards!
All checks were successful
Build and Deploy Nuxt / build (push) Successful in 2m26s

This commit is contained in:
2026-09-20 03:15:16 +02:00
parent ed187af3dd
commit 770f302bc3
34 changed files with 3302 additions and 677 deletions

View File

@@ -1,6 +1,16 @@
// composables/useApi.js
import { ref } from 'vue'
export const ADMIN_TOKEN_COOKIE = 'admin_token'
export class ApiError extends Error {
status: number
constructor(message: string, status: number) {
super(message)
this.status = status
}
}
function normalizeUrl(url: string): string {
return url.replace(/\/+$/, '')
}
@@ -12,7 +22,7 @@ export default function useApi() {
// Generic GET request
const get = async (endpoint) => {
const res = await fetch(`${baseUrl}${endpoint}`)
if (!res.ok) throw new Error(`API GET ${endpoint} failed`)
if (!res.ok) throw new ApiError(`API GET ${endpoint} failed`, res.status)
return res.json()
}
@@ -23,9 +33,31 @@ export default function useApi() {
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
})
if (!res.ok) throw new Error(`API POST ${endpoint} failed`)
if (!res.ok) throw new ApiError(`API POST ${endpoint} failed`, res.status)
return res.json()
}
return { get, post }
// Authenticated requests (JWT stored in cookie by useAuth)
const authHeaders = (): Record<string, string> => {
const token = useCookie<string | null>(ADMIN_TOKEN_COOKIE).value
return token ? { Authorization: `Bearer ${token}` } : {}
}
const getAuth = async (endpoint) => {
const res = await fetch(`${baseUrl}${endpoint}`, { headers: authHeaders() })
if (!res.ok) throw new ApiError(`API GET ${endpoint} failed`, res.status)
return res.json()
}
const postAuth = async (endpoint, payload) => {
const res = await fetch(`${baseUrl}${endpoint}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json', ...authHeaders() },
body: JSON.stringify(payload)
})
if (!res.ok) throw new ApiError(`API POST ${endpoint} failed`, res.status)
return res.json()
}
return { get, post, getAuth, postAuth }
}