BREATHE / frontend /src /pages /AuthPage.jsx
tannuiscoding's picture
added app.py
5a264f5
import { useState } from 'react'
import { useNavigate, useSearchParams } from 'react-router-dom'
import { useAuth } from '../context/AuthContext'
export default function AuthPage() {
const [searchParams] = useSearchParams()
const [tab, setTab] = useState(searchParams.get('tab') === 'signup' ? 'signup' : 'login')
const [error, setError] = useState('')
const [loading, setLoading] = useState(false)
// Login fields
const [identity, setIdentity] = useState('')
const [loginPw, setLoginPw] = useState('')
// Signup fields
const [uname, setUname] = useState('')
const [email, setEmail] = useState('')
const [signupPw, setSignupPw] = useState('')
const { login, signup } = useAuth()
const navigate = useNavigate()
async function handleLogin(e) {
e.preventDefault()
setError(''); setLoading(true)
try {
await login(identity, loginPw)
navigate('/app/dashboard')
} catch (err) { setError(err.message) }
finally { setLoading(false) }
}
async function handleSignup(e) {
e.preventDefault()
setError(''); setLoading(true)
try {
await signup(uname, email, signupPw)
navigate('/app/dashboard')
} catch (err) { setError(err.message) }
finally { setLoading(false) }
}
return (
<div className="auth-screen">
{/* Breathing rings */}
<div className="breath-rings">
{[1,2,3,4].map(i => <div key={i} className={`ring ring-${i}`} />)}
</div>
<div className="auth-card">
{/* Brand */}
<div className="auth-brand">
<img src="/logo.svg" alt="BREATHE" className="auth-logo" />
<p className="auth-subtitle">Stress Intelligence Platform</p>
</div>
{/* Tabs */}
<div className="auth-tabs">
<button className={`auth-tab ${tab==='login' ? 'auth-tab--active' : ''}`} onClick={() => { setTab('login'); setError('') }}>Log In</button>
<button className={`auth-tab ${tab==='signup' ? 'auth-tab--active' : ''}`} onClick={() => { setTab('signup'); setError('') }}>Sign Up</button>
</div>
{error && <div className="form-error">{error}</div>}
{/* Login form */}
{tab === 'login' && (
<form className="auth-form" onSubmit={handleLogin}>
<div className="field">
<label>Email or Username</label>
<input type="text" placeholder="you@example.com" value={identity}
onChange={e => setIdentity(e.target.value)} autoComplete="username" required />
</div>
<div className="field">
<label>Password</label>
<input type="password" placeholder="••••••••" value={loginPw}
onChange={e => setLoginPw(e.target.value)} autoComplete="current-password" required />
</div>
<button type="submit" className="btn-primary btn--full" disabled={loading}>
{loading ? <span className="btn-spinner" /> : 'Log In →'}
</button>
</form>
)}
{/* Signup form */}
{tab === 'signup' && (
<form className="auth-form" onSubmit={handleSignup}>
<div className="field">
<label>Username</label>
<input type="text" placeholder="breatheuser" value={uname}
onChange={e => setUname(e.target.value)} autoComplete="username" required />
</div>
<div className="field">
<label>Email</label>
<input type="email" placeholder="you@example.com" value={email}
onChange={e => setEmail(e.target.value)} autoComplete="email" required />
</div>
<div className="field">
<label>Password <small>(min 8 characters)</small></label>
<input type="password" placeholder="••••••••" value={signupPw}
onChange={e => setSignupPw(e.target.value)} autoComplete="new-password" required />
</div>
<button type="submit" className="btn-primary btn--full" disabled={loading}>
{loading ? <span className="btn-spinner" /> : 'Create Account →'}
</button>
</form>
)}
</div>
</div>
)
}