diff --git a/frontend/src/admin/AccountView.jsx b/frontend/src/admin/AccountView.jsx new file mode 100644 index 0000000..62fc567 --- /dev/null +++ b/frontend/src/admin/AccountView.jsx @@ -0,0 +1,39 @@ +import { useState } from 'react' +import { adminApi } from './api' +import styles from './Admin.module.css' + +export default function AccountView({ instructor }) { + const [oldPassword, setOldPassword] = useState('') + const [newPassword, setNewPassword] = useState('') + const [error, setError] = useState(null) + const [notice, setNotice] = useState(null) + const [busy, setBusy] = useState(false) + + const submit = async (e) => { + e.preventDefault() + setBusy(true); setError(null); setNotice(null) + try { + await adminApi.changePassword(oldPassword, newPassword) + setOldPassword(''); setNewPassword('') + setNotice('Password changed. Any other sessions you had open elsewhere were signed out.') + } catch (e) { setError(e.message) } finally { setBusy(false) } + } + + return ( +
{instructor.display_name} · {instructor.email} · role: {instructor.role}
+ +{notice}
} +Instructor sign-in. Not connected to student accounts.
{error &&Most recent 200 security/admin events.
+ {error &&Loading…
: ( +| When | Actor | Action | Resource | Result |
|---|---|---|---|---|
| {new Date(e.created_at).toLocaleString()} | +{e.actor_type}{e.actor_id ? ` · ${e.actor_id.slice(0, 8)}` : ''} | +{e.action} | +{e.resource_type ? `${e.resource_type}${e.resource_id ? ` (${e.resource_id})` : ''}` : '—'} | +{e.result} | +
Loading…
: cohorts.length === 0 ?None yet.
: ( @@ -79,7 +82,7 @@ function CreateCohortForm({ onCreated }) { ) } -function CohortDetail({ cohortId, onBack }) { +function CohortDetail({ cohortId, canManage, onBack }) { const [students, setStudents] = useState(null) const [progress, setProgress] = useState(null) const [prepResults, setPrepResults] = useState(null) @@ -136,10 +139,12 @@ function CohortDetail({ cohortId, onBack }) {| Name | Status | Last active |
|---|
| Name | Role | Status | Last login | ||
|---|---|---|---|---|---|
| {i.display_name} | +{i.email} | +{i.role} | +{i.status} | +{i.last_login_at ? new Date(i.last_login_at).toLocaleString() : 'never'} | +
Loading…
+ + return ( + <> +{notice}
} + +This is your own account — the platform refuses to remove the last active owner, whichever account that is.
} +Last login: {instructor.last_login_at ? new Date(instructor.last_login_at).toLocaleString() : 'never'}
+ {instructor.sessions?.length ? ( +| Created | Last active | Expires | Status |
|---|---|---|---|
| {new Date(s.created_at).toLocaleString()} | +{new Date(s.last_seen_at).toLocaleString()} | +{new Date(s.expires_at).toLocaleString()} | +{s.revoked_at ? revoked : active} | +
No sessions on record.
} +