Next.js 15 App Router mit öffentlicher Übersicht und geschütztem Admin-Bereich zur Pflege von Datenschutzerklärungen nach Art. 12ff. DSGVO. - Oberfläche auf Basis von shadcn/ui, Inter lokal eingebunden - Prisma/SQLite, Auth.js mit Credentials-Provider und Rollen - Massenimport der Merkblätter des Amtes Leezen aus PDF - Docker-Image (standalone) und Gitea-Workflow zur Veröffentlichung Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
67 lines
1.8 KiB
TypeScript
67 lines
1.8 KiB
TypeScript
import { PrivacyPolicy } from '@/types/privacy-policy'
|
|
|
|
const API_BASE_URL = '/api'
|
|
|
|
/** Fehler einer API-Antwort inkl. der Feld-Validierungsmeldungen des Servers. */
|
|
export class ApiError extends Error {
|
|
details: string[]
|
|
|
|
constructor(message: string, details: string[] = []) {
|
|
super(message)
|
|
this.name = 'ApiError'
|
|
this.details = details
|
|
}
|
|
}
|
|
|
|
export class ApiClient {
|
|
private async request(endpoint: string, options?: RequestInit) {
|
|
const response = await fetch(`${API_BASE_URL}${endpoint}`, {
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
...options?.headers,
|
|
},
|
|
...options,
|
|
})
|
|
|
|
if (!response.ok) {
|
|
const error = await response.json().catch(() => ({ error: 'Netzwerkfehler' }))
|
|
throw new ApiError(
|
|
error.error || 'Die Anfrage ist fehlgeschlagen',
|
|
Array.isArray(error.details) ? error.details : []
|
|
)
|
|
}
|
|
|
|
return response.json()
|
|
}
|
|
|
|
async getAllPolicies(admin = false): Promise<PrivacyPolicy[]> {
|
|
const query = admin ? '?admin=true' : ''
|
|
return this.request(`/privacy-policies${query}`)
|
|
}
|
|
|
|
async getPolicy(id: number): Promise<PrivacyPolicy> {
|
|
return this.request(`/privacy-policies/${id}`)
|
|
}
|
|
|
|
async createPolicy(data: Omit<PrivacyPolicy, 'id' | 'createdAt' | 'updatedAt'>): Promise<PrivacyPolicy> {
|
|
return this.request('/privacy-policies', {
|
|
method: 'POST',
|
|
body: JSON.stringify(data),
|
|
})
|
|
}
|
|
|
|
async updatePolicy(id: number, data: Omit<PrivacyPolicy, 'id' | 'createdAt' | 'updatedAt'>): Promise<PrivacyPolicy> {
|
|
return this.request(`/privacy-policies/${id}`, {
|
|
method: 'PUT',
|
|
body: JSON.stringify(data),
|
|
})
|
|
}
|
|
|
|
async deletePolicy(id: number): Promise<{ message: string }> {
|
|
return this.request(`/privacy-policies/${id}`, {
|
|
method: 'DELETE',
|
|
})
|
|
}
|
|
}
|
|
|
|
export const apiClient = new ApiClient() |