import { useState } from 'react'; import { useAuth } from '../contexts/AuthContext.jsx'; import { useToast } from '../contexts/ToastContext.jsx'; import { api } from '../utils/api.js'; import Avatar from './Avatar.jsx'; export default function ProfileModal({ onClose }) { const { user, updateUser } = useAuth(); const toast = useToast(); const [displayName, setDisplayName] = useState(user?.display_name || ''); const [savedDisplayName, setSavedDisplayName] = useState(user?.display_name || ''); const [displayNameWarning, setDisplayNameWarning] = useState(''); const [aboutMe, setAboutMe] = useState(user?.about_me || ''); const [currentPw, setCurrentPw] = useState(''); const [newPw, setNewPw] = useState(''); const [confirmPw, setConfirmPw] = useState(''); const [loading, setLoading] = useState(false); const [tab, setTab] = useState('profile'); // 'profile' | 'password' | 'notifications' const [pushTesting, setPushTesting] = useState(false); const [pushResult, setPushResult] = useState(null); const [hideAdminTag, setHideAdminTag] = useState(!!user?.hide_admin_tag); const [allowDm, setAllowDm] = useState(user?.allow_dm !== 0); const handleSaveProfile = async () => { if (displayNameWarning) return toast('Display name is already in use', 'error'); setLoading(true); try { const { user: updated } = await api.updateProfile({ displayName, aboutMe, hideAdminTag, allowDm }); updateUser(updated); setSavedDisplayName(displayName); toast('Profile updated', 'success'); } catch (e) { toast(e.message, 'error'); } finally { setLoading(false); } }; const handleAvatarUpload = async (e) => { const file = e.target.files?.[0]; if (!file) return; try { const { avatarUrl } = await api.uploadAvatar(file); updateUser({ avatar: avatarUrl }); toast('Avatar updated', 'success'); } catch (e) { toast(e.message, 'error'); } }; const handleChangePassword = async () => { if (newPw !== confirmPw) return toast('Passwords do not match', 'error'); if (newPw.length < 8) return toast('Password too short (min 8)', 'error'); setLoading(true); try { await api.changePassword({ currentPassword: currentPw, newPassword: newPw }); toast('Password changed', 'success'); setCurrentPw(''); setNewPw(''); setConfirmPw(''); } catch (e) { toast(e.message, 'error'); } finally { setLoading(false); } }; return (
Tap Send Test Notification to trigger a push to this device. The notification will arrive shortly if everything is configured correctly.
If it doesn't arrive, check:
• Notification permission granted (browser prompt)
• Android Settings → Apps → RosterChirp → Notifications → Enabled
• App is backgrounded when the test fires