fix teacher, parent and admin pages

This commit is contained in:
root
2026-04-25 00:00:10 -04:00
parent 7fe34dde0d
commit 3e77fc92c7
275 changed files with 46412 additions and 3325 deletions
+133 -30
View File
@@ -1,42 +1,145 @@
import { type FormEvent, useEffect, useRef, useState } from 'react'
import { Link } from 'react-router-dom'
import { requestForgotPassword } from '../api/passwordFlow'
/** Mirrors CodeIgniter `Views/user/forgot_password.php` shell; reset flow remains on the Laravel site. */
/** Mirrors CodeIgniter `user/forgot_password.php` + confirmation modal from `password_reset_confirmation.php`. */
export function ForgotPasswordPage() {
const [email, setEmail] = useState('')
const [error, setError] = useState<string | null>(null)
const [loading, setLoading] = useState(false)
const [confirmEmail, setConfirmEmail] = useState<string | null>(null)
const confirmModalRef = useRef<HTMLDivElement | null>(null)
useEffect(() => {
if (!confirmEmail) return
const el = confirmModalRef.current
const B = (
window as unknown as {
bootstrap?: { Modal: { getOrCreateInstance: (n: HTMLElement) => { show: () => void } } }
}
).bootstrap
if (el && B?.Modal?.getOrCreateInstance) {
B.Modal.getOrCreateInstance(el).show()
}
}, [confirmEmail])
async function onSubmit(e: FormEvent) {
e.preventDefault()
setLoading(true)
setError(null)
try {
await requestForgotPassword(email)
setConfirmEmail(email.trim())
} catch (err) {
setError(err instanceof Error ? err.message : 'Request failed.')
} finally {
setLoading(false)
}
}
return (
<div className="ci-auth-bg flex-grow-1 py-4">
<div className="registration-form ci-parity container mt-5 mb-5 text-center">
<div className="text-center mb-4">
<Link to="/">
<img
src="/alrahma_logo.png"
alt=""
style={{ width: 180, height: 120, objectFit: 'contain' }}
onError={(ev) => {
;(ev.target as HTMLImageElement).style.display = 'none'
}}
<div className="registration-form ci-parity container mt-5 mb-5">
<form
className="text-start mx-auto"
style={{ maxWidth: 600 }}
onSubmit={(e) => void onSubmit(e)}
noValidate
>
<div className="text-center mb-4">
<Link to="/">
<img
src="/alrahma_logo.png"
alt=""
style={{ width: 180, height: 120, objectFit: 'contain' }}
onError={(ev) => {
;(ev.target as HTMLImageElement).style.display = 'none'
}}
/>
</Link>
</div>
<h3 className="text-center text-success mb-4" style={{ fontFamily: 'Arial, sans-serif' }}>
Reset Your Password
</h3>
<div className="centered-paragraph mb-4 text-center text-muted">
<p className="mb-1">Please enter the email address you used to register with us.</p>
<p className="mb-0">We&apos;ll send you a link to reset your password.</p>
</div>
{error ? (
<div className="alert alert-danger text-center" role="alert">
{error}
</div>
) : null}
<div className="form-group mb-3">
<label className="form-label visually-hidden" htmlFor="forgot-email">
Email
</label>
<input
type="email"
className="form-control item"
id="forgot-email"
name="email"
maxLength={50}
placeholder="Email Address"
required
value={email}
onChange={(e) => setEmail(e.target.value)}
autoComplete="email"
/>
</Link>
</div>
</div>
<h3 className="text-center text-success mb-4" style={{ fontFamily: 'Arial, sans-serif' }}>
Reset Your Password
</h3>
<div className="d-grid mb-3">
<button type="submit" className="btn btn-success item" disabled={loading}>
{loading ? 'Sending…' : 'Reset Password'}
</button>
</div>
<div className="mx-auto mb-4 text-muted" style={{ maxWidth: 560 }}>
<p>Password reset requests are handled through the school&apos;s main website.</p>
<p className="mb-0">
If this SPA is only the API client, open the legacy site or contact the office for a
reset link.
</p>
</div>
<div className="text-center">
<p className="mb-0">Don&apos;t have an account?</p>
<Link className="d-inline-block mt-1" to="/register">
Register now
</Link>
</div>
</form>
</div>
<div className="d-grid gap-2" style={{ maxWidth: 400, margin: '0 auto' }}>
<Link className="btn btn-success item" to="/login">
Back to Sign in
</Link>
<Link className="btn btn-secondary item" to="/register">
Register now
</Link>
<div
className="modal fade"
id="emailConfirmModal"
tabIndex={-1}
ref={confirmModalRef}
aria-labelledby="emailConfirmLabel"
aria-hidden="true"
>
<div className="modal-dialog modal-dialog-centered modal-lg">
<div className="modal-content rounded-4 shadow border-0" style={{ maxWidth: 600, margin: 'auto' }}>
<div className="modal-body text-center">
<img
src="/alrahma_logo.png"
alt=""
style={{ width: 180, height: 120, objectFit: 'contain' }}
onError={(ev) => {
;(ev.target as HTMLImageElement).style.display = 'none'
}}
/>
<h5 className="modal-title text-success" id="emailConfirmLabel">
Check Your Email
</h5>
<p className="lead mt-3 mb-2">
A link to reset the password has been sent to this email:
<br />
<strong>{confirmEmail ?? ''}</strong>
</p>
<p className="mb-0">Please check your inbox and follow the instructions to reset the password.</p>
<Link className="btn btn-success mt-3" to="/login">
Return to Login
</Link>
</div>
</div>
</div>
</div>
</div>