Handle no avatar, add delete avatar support

This commit is contained in:
blankhex committed 2026-10-22 23:08:23 +03:00
1 parent 35bff424f1
commit 3864a4c1cc
9 files changed
+110 -11

No files matched your search

+1
View File
@@ -100,6 +100,7 @@ export const api = {
form.append('avatar', file)
return request('PUT', '/api/profile/avatar', form)
},
deleteAvatar: () => request('DELETE', '/api/profile/avatar'),
avatarUrl: () => '/api/profile/avatar',
// sessions
+27 -5
View File
@@ -15,6 +15,7 @@ export default function ProfilePage({ user, onUserChange }) {
const fileRef = useRef(null)
const initials = (user.fullName || user.login || '?').trim().charAt(0).toUpperCase()
const hasAvatar = Boolean(user.hasAvatar) && !avatarError
const saveProfile = async (event) => {
event.preventDefault()
@@ -46,6 +47,8 @@ export default function ProfilePage({ user, onUserChange }) {
setAvatarMsg(null)
try {
await api.uploadAvatar(file)
const profile = await api.getProfile()
onUserChange(profile)
setAvatarVersion(Date.now())
setAvatarError(false)
setAvatarMsg({ type: 'ok', text: 'Avatar updated' })
@@ -56,22 +59,36 @@ export default function ProfilePage({ user, onUserChange }) {
}
}
const removeAvatar = async () => {
if (!confirm('Remove your avatar?')) return
setAvatarMsg(null)
try {
await api.deleteAvatar()
const profile = await api.getProfile()
onUserChange(profile)
setAvatarError(false)
setAvatarMsg({ type: 'ok', text: 'Avatar removed' })
} catch (err) {
setAvatarMsg({ type: 'error', text: err.message })
}
}
return (
<div className="grid">
<section className="card">
<h2>Avatar</h2>
<div className="avatar-row">
{avatarError ? (
<div className="avatar avatar-fallback" aria-label="No avatar">
{initials}
</div>
) : (
{hasAvatar ? (
<img
className="avatar"
src={`${api.avatarUrl()}?v=${avatarVersion}`}
alt="avatar"
onError={() => setAvatarError(true)}
/>
) : (
<div className="avatar avatar-fallback" aria-label="No avatar">
{initials}
</div>
)}
<div>
<input
@@ -81,6 +98,11 @@ export default function ProfilePage({ user, onUserChange }) {
onChange={uploadAvatar}
/>
<p className="hint">PNG or JPEG.</p>
{user.hasAvatar && (
<button className="btn-danger-sm" type="button" onClick={removeAvatar}>
Remove avatar
</button>
)}
</div>
</div>
{avatarMsg && <p className={avatarMsg.type}>{avatarMsg.text}</p>}