/* global React */ // bookme — Produktseite (Terminbuchung & Einladungen), im 4its-Dark-Theme const BM_ICONS = { calendar: "M8 2v3M16 2v3M3.5 9h17M5 5h14a1.5 1.5 0 0 1 1.5 1.5V19A1.5 1.5 0 0 1 19 20.5H5A1.5 1.5 0 0 1 3.5 19V6.5A1.5 1.5 0 0 1 5 5z", teams: "M8 10h8M8 14h5M21 12a9 9 0 0 1-14 7.6L3 21l1.4-4A9 9 0 1 1 21 12z", check: "M4 8a4 4 0 0 1 4-4h8a4 4 0 0 1 4 4v8a4 4 0 0 1-4 4H8a4 4 0 0 1-4-4zM9 12l2 2 4-4", mail: "M3 6.5h18v11H3zM3.5 7l8.5 6 8.5-6", repeat: "M17 2l3 3-3 3M20 5H9a4 4 0 0 0-4 4v1M7 22l-3-3 3-3M4 19h11a4 4 0 0 0 4-4v-1", lock: "M6 10V8a6 6 0 0 1 12 0v2M5 10h14v10H5zM12 14v3", key: "M14 7a4 4 0 1 0-3.5 3.97L11 11l2 2-1 1 2 2 2-2-2-2 1.5-1.5A4 4 0 0 0 14 7z", shield: "M12 3l7 3v5c0 4.5-3 8-7 9-4-1-7-4.5-7-9V6z", doc: "M7 3h7l4 4v14H7zM14 3v5h4M9 13h6M9 16h6", flag: "M5 21V4M5 4h11l-1.5 3.5L16 11H5", clock: "M12 7v5l3 2M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0z", puzzle: "M10 4a1.5 1.5 0 0 1 3 0c0 .8.7 1.5 1.5 1.5H17v2.5c0 .8.7 1.5 1.5 1.5a1.5 1.5 0 0 1 0 3c-.8 0-1.5.7-1.5 1.5V20h-3a1.5 1.5 0 0 0-1.5-1.5 1.5 1.5 0 0 0-1.5 1.5H6.5v-2.5C6.5 16.7 5.8 16 5 16a1.5 1.5 0 0 1 0-3c.8 0 1.5-.7 1.5-1.5V9H10z", }; const BM_FEATURES = [ { icon: 'calendar', title: 'Selbst-Buchung für Kund:innen', desc: 'Eigener Link je Mitarbeiter:in. Kund:innen wählen selbst einen freien Termin — Schluss mit E-Mail-Ping-Pong.' }, { icon: 'teams', title: 'Automatischer Teams-Link', desc: 'Für jede Buchung wird automatisch eine Microsoft-Teams-Besprechung erstellt und mitgeschickt.' }, { icon: 'check', title: 'Echte Verfügbarkeit', desc: 'Frei/Belegt kommt live aus Exchange oder Microsoft 365 — keine Doppelbuchungen.' }, { icon: 'mail', title: 'Gebrandete Einladungen', desc: 'Professionelle Teams-Einladungs-E-Mails im 4its-Look, zweisprachig, mit Kalender-Datei.' }, { icon: 'repeat', title: 'Erinnerungen & Storno', desc: 'Automatische Erinnerung 24 h vorher; Kund:innen können selbst absagen oder verschieben.' }, { icon: 'lock', title: 'Microsoft-365-Login', desc: 'Anmeldung per SSO mit dem bestehenden 4its-Konto — inklusive MFA, ohne neue Passwörter.' }, ]; const BM_STEPS = [ { n: '01', title: 'Link teilen', desc: 'Jede:r Mitarbeiter:in hat einen persönlichen Buchungslink — auf der Website, in der E-Mail-Signatur oder direkt verschickt.' }, { n: '02', title: 'Termin wählen', desc: 'Kund:innen sehen nur wirklich freie Zeiten und buchen in wenigen Klicks — inklusive eigener Angaben.' }, { n: '03', title: 'Fertig & im Kalender', desc: 'Teams-Termin wird erstellt, Bestätigung mit .ics versendet, alles landet automatisch im Kalender.' }, ]; const BM_SECURITY = [ { icon: 'key', title: 'Single-Sign-on (M365)', desc: 'Anmeldung über Microsoft Entra ID mit euren bestehenden Richtlinien (MFA, Conditional Access).' }, { icon: 'shield', title: 'Verschlüsselt gespeichert', desc: 'Zugangsdaten zur Kalender-Abfrage werden AES-256-verschlüsselt abgelegt.' }, { icon: 'doc', title: 'DSGVO-konform', desc: 'Einwilligung bei der Buchung, Audit-Log und automatische Löschung alter Daten.' }, { icon: 'flag', title: 'In eurer Infrastruktur', desc: 'Selbst gehostet auf eurem Server — die Daten bleiben bei euch.' }, { icon: 'clock', title: 'Rate-Limiting & Spamschutz', desc: 'Schutz der öffentlichen Buchungsseite gegen Missbrauch und Bots.' }, { icon: 'puzzle', title: 'Rollen & Rechte', desc: 'Getrennte Admin- und Benutzerrollen mit zentral verwalteten Standards.' }, ]; // ---- Interactive booking demo ---- const BM_WD = ['So','Mo','Di','Mi','Do','Fr','Sa']; const BM_MON = ['Jan','Feb','Mär','Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Dez']; const BM_SLOTS = ['09:00','09:30','10:30','11:00','13:00','13:30','14:30','15:30']; const BM_TAKEN = { 0:['09:30','13:00','14:30'], 1:['11:00','13:30'], 2:['09:00','15:30'], 3:['10:30'], 4:['11:00'] }; function bmBuildDays() { const out = []; const base = new Date(); base.setHours(0,0,0,0); base.setDate(base.getDate() + 1); let added = 0, cursor = new Date(base); while (added < 5) { const dow = cursor.getDay(); if (dow !== 0 && dow !== 6) { out.push({ idx: added, wd: BM_WD[dow], day: cursor.getDate(), mon: BM_MON[cursor.getMonth()], full: `${BM_WD[dow]}, ${cursor.getDate()}. ${BM_MON[cursor.getMonth()]} ${cursor.getFullYear()}`, }); added++; } cursor.setDate(cursor.getDate() + 1); } return out; } function BookmeDemo() { const days = useRef(bmBuildDays()).current; const [step, setStep] = useState(1); const [dayIdx, setDayIdx] = useState(3); const [slot, setSlot] = useState(null); const [form, setForm] = useState({ name:'', email:'', note:'' }); const [err, setErr] = useState(''); const curDay = days[dayIdx] || days[0]; const taken = BM_TAKEN[dayIdx] || []; const chosenLabel = `${curDay.full} · ${slot || ''} Uhr`; const setF = (k) => (e) => setForm(f => ({ ...f, [k]: e.target.value })); const confirm = () => { if (!form.name.trim() || !/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(form.email.trim())) { setErr('Bitte Name und eine gültige E-Mail angeben.'); return; } setErr(''); setStep(3); }; const reset = () => { setStep(1); setSlot(null); setForm({ name:'', email:'', note:'' }); setErr(''); }; const progressColor = (n) => step >= n ? 'var(--accent)' : 'var(--border)'; return (
Verfügbarkeit kommt live aus dem Kalender.
{chosenLabel}
Eine Bestätigung mit Teams-Link und Kalender-Datei wurde an {form.email || 'deine E-Mail'} gesendet (Demo).
bookme ist das schlanke Buchungs- und Einladungs-Tool für Microsoft 365 & Teams. Kund:innen wählen selbst einen freien Termin — der Teams-Link entsteht automatisch.
Von der Selbstbuchung durch Kund:innen bis zur fertigen Teams-Einladung. bookme verbindet sich direkt mit eurem Microsoft 365.
{f.desc}
{s.desc}
Genau so sehen es eure Kund:innen. Wählt einen Tag, eine Uhrzeit und schließt die Beispiel-Buchung ab.
Neben der Selbstbuchung enthält bookme einen Einladungs-Generator: professionelle, im 4its-Look gestaltete E-Mails mit Agenda, Teams-Link und Kalender-Datei — direkt aus dem Tool versendet.
{s.desc}
Probiert bookme aus oder sprecht mit uns über die Einführung in eurem Team.