minor bug fixes

This commit is contained in:
2026-04-02 15:22:38 -04:00
parent 97b308e9f0
commit 18e4a92241
4 changed files with 79 additions and 29 deletions

View File

@@ -36,8 +36,10 @@ export default function ProfileModal({ onClose }) {
const [hideAdminTag, setHideAdminTag] = useState(!!user?.hide_admin_tag);
const [allowDm, setAllowDm] = useState(user?.allow_dm !== 0);
// Minor age protection — DOB/phone display only
// Minor age protection — DOB/phone display + mixed_age forced-DOB gate
const [loginType, setLoginType] = useState('all_ages');
// True when mixed_age mode and the user still has no DOB on record
const needsDob = loginType === 'mixed_age' && !user?.date_of_birth;
const savedScale = parseFloat(localStorage.getItem(LS_FONT_KEY));
const [fontScale, setFontScale] = useState(
@@ -105,6 +107,55 @@ export default function ProfileModal({ onClose }) {
}
};
// ── Forced DOB gate for mixed_age users ───────────────────────────────────
if (needsDob) {
return (
<div className="modal-overlay">
<div className="modal" style={{ maxWidth: 380 }}>
<h2 className="modal-title" style={{ marginBottom: 8 }}>Date of Birth Required</h2>
<p className="text-sm" style={{ color: 'var(--text-secondary)', marginBottom: 16, lineHeight: 1.5 }}>
Your organisation requires a date of birth on file. Please enter yours to continue.
</p>
<div className="flex-col gap-1" style={{ marginBottom: 16 }}>
<label className="text-sm font-medium" style={{ color: 'var(--text-secondary)' }}>
Date of Birth <span style={{ color: 'var(--error)' }}>*</span>
</label>
<input
className="input"
type="text"
placeholder="YYYY-MM-DD"
value={dob}
onChange={e => setDob(e.target.value)}
autoComplete="off"
style={{ borderColor: dob ? undefined : 'var(--error)' }}
/>
</div>
<button
className="btn btn-primary"
style={{ width: '100%' }}
disabled={loading || !dob.trim()}
onClick={async () => {
if (!dob.trim()) return;
setLoading(true);
try {
const { user: updated } = await api.updateProfile({ displayName, aboutMe, hideAdminTag, allowDm, dateOfBirth: dob.trim(), phone: phone || null });
updateUser(updated);
toast('Profile updated', 'success');
// needsDob will re-evaluate to false now that user.date_of_birth is set
} catch (e) {
toast(e.message, 'error');
} finally {
setLoading(false);
}
}}
>
{loading ? 'Saving…' : 'Save & Continue'}
</button>
</div>
</div>
);
}
return (
<div className="modal-overlay" onClick={e => e.target === e.currentTarget && onClose()}>
<div className="modal">

View File

@@ -162,7 +162,7 @@ function TeamManagementTab() {
const LOGIN_TYPE_OPTIONS = [
{
id: 'all_ages',
label: 'All Ages',
label: 'Unrestricted',
desc: 'No age restrictions. All users interact normally. Default behaviour.',
},
{
@@ -172,7 +172,7 @@ const LOGIN_TYPE_OPTIONS = [
},
{
id: 'mixed_age',
label: 'Mixed Age',
label: 'Restricted',
desc: "Parents, or user managers, add the minor's user account to their guardian profile. Minor aged users cannot login until a manager approves the guardian link.",
},
];