Files
ds-chat/frontend/src/pages/ForgotPasswordPage.tsx
T
ksmithandClaude Sonnet 5 14dc340174 Rename project from KeepItTalking to DS Chat
Renames the app's display name everywhere (page titles, PWA manifest,
TopBar, email subject lines, HMAC signature header) and its internal
technical slug from chatapp to ds-chat/ds_chat: the Python package name
and console script, the systemd unit and its user/group/paths, the deploy
scripts, the Docker container names, and the Postgres database name.

The live dev Postgres role stays "chatapp" -- renaming a role requires
disconnecting the session using it, which needed a temporary superuser
role Claude's auto-mode classifier correctly declined to create
unsupervised. Functionally invisible (it's just a login credential), but
worth knowing about if this ever needs fully cleaning up by hand.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-15 21:11:41 -06:00

71 lines
2.1 KiB
TypeScript

import { useState, type FormEvent } from 'react'
import { Link, Navigate } from 'react-router-dom'
import { requestPasswordReset } from '../api/auth'
import { useAuth } from '../context/AuthContext'
import logo from '../assets/logo.png'
import './LoginPage.css'
export function ForgotPasswordPage() {
const { user } = useAuth()
const [email, setEmail] = useState('')
const [submitting, setSubmitting] = useState(false)
const [sent, setSent] = useState(false)
if (user) return <Navigate to="/rooms" replace />
async function handleSubmit(e: FormEvent) {
e.preventDefault()
setSubmitting(true)
try {
await requestPasswordReset(email)
} catch {
// Fall through to the generic message regardless -- the request
// itself never reveals whether the email is registered.
} finally {
setSubmitting(false)
setSent(true)
}
}
return (
<div className="login-screen">
<div className="login-card">
<div className="login-brand">
<img src={logo} alt="" />
<span>DS Chat</span>
</div>
{sent ? (
<p className="login-copy">
If an account exists for that email, a password reset link is on its way. The link
expires in 15 minutes.
</p>
) : (
<>
<p className="login-copy">Enter your account email and we'll send a reset link.</p>
<form className="login-form" onSubmit={handleSubmit}>
<label>
Email
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
autoFocus
/>
</label>
<button type="submit" className="btn-primary" disabled={submitting}>
{submitting ? 'Sending' : 'Send reset link'}
</button>
</form>
</>
)}
<Link to="/login" className="login-link">
Back to log in
</Link>
</div>
</div>
)
}