mirror of
https://github.com/dat515-2025/Group-8.git
synced 2026-03-22 06:57:47 +01:00
feat(backend): added missing untracked files
This commit is contained in:
87
7project/frontend/src/pages/AccountPage.tsx
Normal file
87
7project/frontend/src/pages/AccountPage.tsx
Normal file
@@ -0,0 +1,87 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { deleteMe, getMe, type UpdateMeInput, type User, updateMe } from '../api';
|
||||
|
||||
export default function AccountPage({ onDeleted }: { onDeleted: () => void }) {
|
||||
const [user, setUser] = useState<User | null>(null);
|
||||
const [firstName, setFirstName] = useState('');
|
||||
const [lastName, setLastName] = useState('');
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
try {
|
||||
const u = await getMe();
|
||||
setUser(u);
|
||||
setFirstName(u.first_name || '');
|
||||
setLastName(u.last_name || '');
|
||||
} catch (e: any) {
|
||||
setError(e?.message || 'Failed to load account');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
})();
|
||||
}, []);
|
||||
|
||||
async function handleSave(e: React.FormEvent) {
|
||||
e.preventDefault();
|
||||
setSaving(true);
|
||||
setError(null);
|
||||
try {
|
||||
const payload: UpdateMeInput = { first_name: firstName || null as any, last_name: lastName || null as any };
|
||||
const updated = await updateMe(payload);
|
||||
setUser(updated);
|
||||
} catch (e: any) {
|
||||
setError(e?.message || 'Failed to update');
|
||||
} finally {
|
||||
setSaving(false);
|
||||
}
|
||||
}
|
||||
|
||||
async function handleDelete() {
|
||||
if (!confirm('Are you sure you want to delete your account? This cannot be undone.')) return;
|
||||
try {
|
||||
await deleteMe();
|
||||
onDeleted();
|
||||
} catch (e: any) {
|
||||
alert(e?.message || 'Failed to delete account');
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<section className="card">
|
||||
<h3>Account</h3>
|
||||
{loading ? (
|
||||
<div>Loading…</div>
|
||||
) : error ? (
|
||||
<div style={{ color: 'crimson' }}>{error}</div>
|
||||
) : !user ? (
|
||||
<div>Not signed in</div>
|
||||
) : (
|
||||
<div className="space-y">
|
||||
<div className="muted">Email: <strong>{user.email}</strong></div>
|
||||
<form onSubmit={handleSave} className="space-y">
|
||||
<div className="form-row">
|
||||
<div>
|
||||
<label className="muted">First name</label>
|
||||
<input className="input" value={firstName} onChange={(e) => setFirstName(e.target.value)} />
|
||||
</div>
|
||||
<div>
|
||||
<label className="muted">Last name</label>
|
||||
<input className="input" value={lastName} onChange={(e) => setLastName(e.target.value)} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="actions" style={{ justifyContent: 'flex-end' }}>
|
||||
<button className="btn primary" type="submit" disabled={saving}>{saving ? 'Saving…' : 'Save changes'}</button>
|
||||
</div>
|
||||
</form>
|
||||
<div className="actions" style={{ justifyContent: 'space-between' }}>
|
||||
<div className="muted"></div>
|
||||
<button className="btn" style={{ borderColor: 'crimson', color: 'crimson' }} onClick={handleDelete}>Delete account</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user