import { useState } from "react"; import { INK, RED, BLUE, PAPER, SKY, MUTE, FONT_MONO } from "../../theme"; import { GENDER_LABEL, genderLabel, PASSWORD_MIN, PASSWORD_MAX, NAME_MAX } from "../../constants"; import DateFields from "../../components/DateFields"; /* * Account (AVG art. 16, rectificatie): naam, e-mail, geboortedatum, gender/trans en wachtwoord * wijzigen — bij Mijn profiel. Ingeklapt tot je op 'wijzigen' klikt. Alleen gewijzigde velden gaan * mee; het huidige wachtwoord is altijd verplicht. onSave(changes) → Promise. */ /* Date (lokaal) → 'YYYY-MM-DD' */ const toIso = (d) => `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`; export default function AccountSection({ me, onSave, onLogoutOthers }) { const [open, setOpen] = useState(false); const [name, setName] = useState(me.name); const [email, setEmail] = useState(me.email); const [birthdate, setBirthdate] = useState(toIso(me.birth)); // null zolang de datumvelden geen echte datum vormen const [gender, setGender] = useState(me.gender); const [trans, setTrans] = useState(me.trans); const [newPassword, setNewPassword] = useState(""); const [currentPassword, setCurrentPassword] = useState(""); const [state, setState] = useState({ busy: false, saved: false, error: null }); /* De knop 'overal elders uitloggen' heeft een eigen uitkomst: null = nog niet gedaan */ const [elders, setElders] = useState({ busy: false, done: null }); /* Wat is er anders dan wat de server heeft? Alleen dat sturen we */ const changes = { ...(name.trim() !== me.name && { name: name.trim() }), ...(email.trim().toLowerCase() !== me.email && { email: email.trim() }), ...(birthdate && birthdate !== toIso(me.birth) && { birthdate }), ...(gender !== me.gender && { gender }), ...(trans !== me.trans && { trans }), ...(newPassword && { newPassword }), }; const dirty = Object.keys(changes).length > 0; const valid = name.trim() && name.trim().length <= NAME_MAX && email.trim() && birthdate && (!newPassword || newPassword.length >= PASSWORD_MIN); const canSave = dirty && valid && currentPassword && !state.busy; const save = async (e) => { e.preventDefault(); if (!canSave) return; setState({ busy: true, saved: false, error: null }); try { await onSave({ ...changes, currentPassword }); setNewPassword(""); setCurrentPassword(""); setState({ busy: false, saved: true, error: null }); setTimeout(() => setState((s) => ({ ...s, saved: false })), 2500); } catch (err) { setState({ busy: false, saved: false, error: err.message }); } }; /* * Overal elders uitloggen. Gebruikt hetzelfde 'huidig wachtwoord' als het formulier eromheen — * daarom staat het hier en niet als losse knop met een eigen wachtwoordveld. */ const logoutOthers = async () => { if (!currentPassword || elders.busy || !onLogoutOthers) return; setElders({ busy: true, done: null }); setState((s) => ({ ...s, error: null })); try { const { loggedOut } = await onLogoutOthers(currentPassword); setElders({ busy: false, done: loggedOut }); } catch (err) { setElders({ busy: false, done: null }); setState((s) => ({ ...s, error: err.message })); } }; const input = { width: "100%", padding: "10px 12px", fontSize: 15, border: `2px solid ${INK}`, background: PAPER, borderRadius: 0, marginTop: 6 }; const label = { display: "block", fontWeight: 700, fontSize: 14, marginBottom: 14 }; const chip = (active) => ({ padding: "8px 14px", border: `2px solid ${INK}`, fontWeight: 600, fontSize: 14, background: active ? INK : "#fff", color: active ? "#fff" : INK, }); const link = { background: "none", border: "none", color: BLUE, fontWeight: 700, fontSize: 13, padding: 0, textDecoration: "underline" }; return (

Account

{me.name} · {genderLabel(me)} · {me.age} jaar · {me.email}

{!open ? ( ) : (

Ik ben

{Object.entries(GENDER_LABEL).map(([g, text]) => ( ))}

je staat als: {genderLabel({ gender, trans })} {(gender !== me.gender || trans !== me.trans) && <> · let op: dit verandert wie jou ziet en wie jij ziet}

Geboortedatum
{newPassword && (

Na het wijzigen zijn je andere toestellen uitgelogd; dit toestel blijft ingelogd.

)} {onLogoutOthers && (

Staat er nog ergens anders een toestel ingelogd?{" "} {elders.done !== null && ( <> — {elders.done === 0 ? "er stond er geen een." : `${elders.done} ${elders.done === 1 ? "toestel is" : "toestellen zijn"} uitgelogd.`} )}

)} {state.error && (

fout: {state.error}

)}
)}
); }