Analyse: Schalter im WOMS

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Sonnet 5.5 committed 2026-10-01 10:38:11 +00:00
1 parent 447b7e733e
commit 0cec45d3da
8 files changed
+211 -1

No files matched your search

+35
View File
@@ -0,0 +1,35 @@
import { account } from './appwrite'
const PROJECT_ADMIN_URL =
import.meta.env.VITE_PROJECT_ADMIN_URL || 'https://project.webklar.com'
// Wie previewFetch in previewApi.js: der Fehler trägt .status und .data
async function analyseFetch(path, options = {}) {
const jwt = await account.createJWT()
const response = await fetch(`${PROJECT_ADMIN_URL}${path}`, {
...options,
headers: {
Authorization: `Bearer ${jwt.jwt}`,
'Content-Type': 'application/json',
...options.headers,
},
})
const data = await response.json().catch(() => ({}))
if (!response.ok) {
const error = new Error(data.error || `API-Fehler ${response.status}`)
error.status = response.status
error.data = data
throw error
}
return data
}
const base = (projectId) => `/api/admin/analyse/${encodeURIComponent(projectId)}`
export function fetchAnalyse(projectId) {
return analyseFetch(base(projectId))
}
export function setAnalyse(projectId, { on, avvConfirmedVerbally = false }) {
return analyseFetch(base(projectId), { method: 'POST', body: JSON.stringify({ on, avvConfirmedVerbally }) })
}
+34
View File
@@ -0,0 +1,34 @@
// Anzeige-Logik für die Zeile "Website-Analyse" (Schalter im WOMS)
const dateFormat = new Intl.DateTimeFormat('de-DE', {
timeZone: 'Europe/Berlin',
day: '2-digit',
month: '2-digit',
year: 'numeric',
})
// "TT.MM.JJJJ" in Europe/Berlin
function formatBerlinDate(value) {
const d = new Date(value)
if (!value || Number.isNaN(d.getTime())) return ''
const parts = Object.fromEntries(dateFormat.formatToParts(d).map((p) => [p.type, p.value]))
return `${parts.day}.${parts.month}.${parts.year}`
}
// Antwort von GET /api/admin/analyse/:projectId => Statustext und erlaubte Aktionen
export function analyseStatus(a) {
if (!a) return { text: '', color: 'grey', canEnable: false, canDisable: false }
if (!a.enabled) return { text: 'Noch nicht freigeschaltet', color: 'grey', canEnable: false, canDisable: false }
if (a.state === 'active') {
const at = formatBerlinDate(a.activatedAt)
return { text: at ? `An seit ${at}` : 'An', color: 'green', canEnable: false, canDisable: true }
}
if (a.state === 'disabled') return { text: 'Gesperrt', color: 'red', canEnable: Boolean(a.eligible), canDisable: false }
if (!a.eligible) {
return { text: `Nicht verfügbar${a.reasonText ? `: ${a.reasonText}` : ''}`, color: 'grey', canEnable: false, canDisable: false }
}
return { text: 'Aus', color: 'grey', canEnable: true, canDisable: false }
}
export const avvLabel = (version) =>
`Der Kunde hat den Auftragsverarbeitungsvertrag (Fassung ${version}) bestätigt`
+1 -1
View File
@@ -1,5 +1,5 @@
// Aufbereitung der /api/admin/services-Antwort für die Seite "Services"
const STATUS_LABELS = { in_development: 'In Entwicklung' }
const STATUS_LABELS = { in_development: 'In Entwicklung', available: 'Verfügbar' }
export function servicesCards(api) {
if (!api) return []