Analyse: Einschalten im WOMS nur mit Datum und Weg der Zustimmung in Textform
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
72f07410fe
commit
52968b3017
4 files changed
+183
-21
No files matched your search
@@ -1,4 +1,5 @@
|
||||
import { account } from './appwrite'
|
||||
import { analyseSetBody } from './analyseView'
|
||||
|
||||
const PROJECT_ADMIN_URL =
|
||||
import.meta.env.VITE_PROJECT_ADMIN_URL || 'https://project.webklar.com'
|
||||
@@ -30,6 +31,6 @@ 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 }) })
|
||||
export function setAnalyse(projectId, fields) {
|
||||
return analyseFetch(base(projectId), { method: 'POST', body: JSON.stringify(analyseSetBody(fields)) })
|
||||
}
|
||||
+65
-3
@@ -15,13 +15,33 @@ function formatBerlinDate(value) {
|
||||
return `${parts.day}.${parts.month}.${parts.year}`
|
||||
}
|
||||
|
||||
// "JJJJ-MM-TT" => "TT.MM.JJJJ"
|
||||
function formatIsoDate(value) {
|
||||
const m = /^(\d{4})-(\d{2})-(\d{2})/.exec(String(value || ''))
|
||||
return m ? `${m[3]}.${m[2]}.${m[1]}` : ''
|
||||
}
|
||||
|
||||
export const CHANNELS = ['chat', 'email']
|
||||
|
||||
export function channelLabel(channel) {
|
||||
if (channel === 'chat') return 'Chat im Kundenportal'
|
||||
if (channel === 'email') return 'E-Mail'
|
||||
return ''
|
||||
}
|
||||
|
||||
// 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 }
|
||||
let text = at ? `An seit ${at}` : 'An'
|
||||
const consent = formatIsoDate(a.avvConsentDate)
|
||||
if (consent) {
|
||||
const way = channelLabel(a.avvConsentChannel)
|
||||
text += ` · Zustimmung in Textform am ${consent}${way ? ` per ${way}` : ''}`
|
||||
}
|
||||
return { text, color: 'green', canEnable: false, canDisable: true }
|
||||
}
|
||||
if (a.state === 'disabled') return { text: 'Gesperrt', hint: 'Vom Team gesperrt', enableLabel: 'Trotz Sperre einschalten', color: 'red', canEnable: Boolean(a.eligible), canDisable: false }
|
||||
if (!a.eligible) {
|
||||
@@ -30,5 +50,47 @@ export function analyseStatus(a) {
|
||||
return { text: 'Aus', color: 'grey', canEnable: true, canDisable: false }
|
||||
}
|
||||
|
||||
export const avvLabel = (version) =>
|
||||
`Der Kunde hat den Auftragsverarbeitungsvertrag (Fassung ${version}) bestätigt`
|
||||
// Kästchentext (banner-portal-mailtexte.md § 3); die beiden Links setzt die Komponente
|
||||
export const textformLabel = (version) => ({
|
||||
before: 'Der Kunde hat dem ',
|
||||
avv: 'AVV Website-Analyse',
|
||||
between: ' und der ',
|
||||
lb: 'Leistungsbeschreibung Website-Analyse',
|
||||
after: ` (Fassung ${version}) in Textform zugestimmt und bestätigt, dass seine Website sich nicht gezielt an Kinder unter 16 Jahren richtet.`,
|
||||
})
|
||||
|
||||
// Alle drei Pflichtangaben; Datum als JJJJ-MM-TT zwischen Fassungsdatum und heute
|
||||
export function canSubmitTextform({ confirmed, date, channel, today, minDate }) {
|
||||
if (confirmed !== true) return false
|
||||
if (!/^\d{4}-\d{2}-\d{2}$/.test(String(date || ''))) return false
|
||||
if (!CHANNELS.includes(channel)) return false
|
||||
if (minDate && date < minDate) return false
|
||||
if (today && date > today) return false
|
||||
return true
|
||||
}
|
||||
|
||||
// Body für POST /api/admin/analyse/:projectId
|
||||
export function analyseSetBody({ on, textformDate, textformChannel, audienceConfirmed }) {
|
||||
if (!on) return { on: false }
|
||||
return { on: true, textformDate, textformChannel, audienceConfirmed }
|
||||
}
|
||||
|
||||
const LEGAL_BASE = 'https://project.webklar.com/rechtliches'
|
||||
export const legalLinks = (version) => ({
|
||||
avv: `${LEGAL_BASE}/avv-website-analyse-${version}.html`,
|
||||
lb: `${LEGAL_BASE}/leistungsbeschreibung-website-analyse-${version}.html`,
|
||||
})
|
||||
|
||||
// Textvorlage für den Chat (banner-portal-mailtexte.md § 3)
|
||||
export function chatTemplate(version) {
|
||||
const l = legalLinks(version)
|
||||
return `Damit wir die Website-Analyse für Dich einschalten können, brauchen wir Deine Zustimmung in Textform. Es gelten der Auftragsverarbeitungsvertrag Website-Analyse und die Leistungsbeschreibung Website-Analyse in der Fassung ${version}: ${l.avv} · ${l.lb}. Bitte antworte hier mit „Ich stimme zu“ und bestätige, dass sich Deine Website nicht gezielt an Kinder unter 16 Jahren richtet.`
|
||||
}
|
||||
|
||||
const MISSING_NAMES = { firma: 'Firma', email: 'E-Mail' }
|
||||
// Hinweis, wenn die Kundendaten für die Datenschutzerklärung fehlen (privacy.ok === false)
|
||||
export function privacyHint(privacy) {
|
||||
if (!privacy || privacy.ok !== false) return ''
|
||||
const names = (privacy.missing || []).map((k) => MISSING_NAMES[k] || k).join(' und ')
|
||||
return `Einschalten nicht möglich: Beim Kunden fehlt${names ? `: ${names}` : ' eine Angabe'} (Pflicht für die Datenschutzerklärung).`
|
||||
}
|
||||
Reference in new issue
Block a user