add admin pages

This commit is contained in:
root
2026-04-23 15:28:56 -04:00
parent 94700d4f0f
commit 7fe34dde0d
9 changed files with 6513 additions and 99 deletions
+25 -26
View File
@@ -8,22 +8,19 @@ export function RoleSelectPage() {
const { user, roles, selectedRole, setSelectedRole } = useAuth()
const navigate = useNavigate()
const location = useLocation()
const [pickedRole, setPickedRole] = useState<string | null>(selectedRole)
const [busyRole, setBusyRole] = useState<string | null>(null)
const [busy, setBusy] = useState(false)
const [error, setError] = useState<string | null>(null)
const from = (location.state as { from?: string } | null)?.from ?? '/app/home'
async function continueLogin() {
if (!pickedRole) {
setError('Please select a role to continue.')
return
}
async function continueLogin(nextRole: string) {
setBusy(true)
setBusyRole(nextRole)
setError(null)
setSelectedRole(pickedRole)
setSelectedRole(nextRole)
let target = from.startsWith('/app') ? from : '/app/home'
if (pickedRole.toLowerCase() === 'parent' && target === '/app/home') {
if (nextRole.toLowerCase() === 'parent' && target === '/app/home') {
target = '/app/parent/home'
}
try {
@@ -39,41 +36,43 @@ export function RoleSelectPage() {
}
return (
<div className="container py-4">
<div className="card border-0 shadow-sm mx-auto" style={{ maxWidth: 640 }}>
<div className="card-body p-4">
<h2 className="h4 mb-2">Select role</h2>
<p className="text-muted mb-3">
{user?.name ? `Signed in as ${user.name}.` : 'Signed in successfully.'} Choose a role
to continue.
<div className="container mt-5">
<div className="card shadow-sm border-0 mx-auto" style={{ maxWidth: 720 }}>
<div className="card-header bg-primary text-white">
<h4 className="mb-0">Select Account Type</h4>
</div>
<div className="card-body">
<p className="mb-4">
{user?.name ? `${user.name}, y` : 'Y'}ou have multiple roles. Please select the account
you&apos;d like to log into:
</p>
<div className="list-group mb-3">
<div className="d-flex flex-wrap gap-3">
{roles.map((role) => (
<button
key={role}
type="button"
className={`list-group-item list-group-item-action text-start ${
pickedRole === role ? 'active' : ''
className={`btn ${
selectedRole === role ? 'btn-primary' : 'btn-outline-primary'
}`}
onClick={() => setPickedRole(role)}
onClick={() => {
void continueLogin(role)
}}
disabled={busy}
>
{role}
{busy && busyRole === role
? 'Opening...'
: role.replace(/_/g, ' ').replace(/\b\w/g, (letter) => letter.toUpperCase())}
</button>
))}
</div>
{error ? (
<div className="alert alert-danger py-2" role="alert">
<div className="alert alert-danger py-2 mt-3" role="alert">
{error}
</div>
) : null}
<div className="d-grid">
<button type="button" className="btn btn-success" onClick={continueLogin} disabled={busy}>
{busy ? 'Continuing…' : 'Continue'}
</button>
</div>
</div>
</div>
</div>