steelforesight/src/pages/Auth/LoginPage.tsx

113 lines
4.4 KiB
TypeScript

import React, { useState } from 'react'
import { useNavigate, Link } from 'react-router-dom'
import { useAuth } from '@/context/AuthContext'
import { useLang } from '@/context/LangContext'
const GOLD = '#CD9E53'
const NAVY = '#032340'
export default function LoginPage() {
const { lang } = useLang()
const { login } = useAuth()
const navigate = useNavigate()
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const [error, setError] = useState('')
const [loading, setLoading] = useState(false)
const T = {
title: lang === 'fa' ? 'ورود به حساب' : 'Sign In',
email: lang === 'fa' ? 'ایمیل' : 'Email',
pass: lang === 'fa' ? 'رمز عبور' : 'Password',
submit: lang === 'fa' ? 'ورود' : 'Login',
noAcc: lang === 'fa' ? 'حساب ندارید؟' : "Don't have an account?",
register: lang === 'fa' ? 'ثبت‌نام کنید' : 'Register',
}
async function handleSubmit(e: React.FormEvent) {
e.preventDefault()
setError('')
setLoading(true)
try {
await login(email, password)
navigate('/profile')
} catch (err: unknown) {
setError(err instanceof Error ? err.message : 'خطا در ورود')
} finally {
setLoading(false)
}
}
return (
<div style={{
minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center',
background: 'var(--paper)', padding: '2rem',
}}>
<div style={{
width: '100%', maxWidth: 420,
background: 'var(--paper-2)', borderRadius: 16,
padding: '2.5rem 2rem', boxShadow: '0 4px 40px rgba(0,0,0,0.08)',
border: `1px solid var(--rule-thin)`,
}}>
<div style={{ textAlign: 'center', marginBottom: '2rem' }}>
<div style={{ width: 48, height: 48, borderRadius: '50%', background: GOLD, margin: '0 auto 1rem', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke={NAVY} strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/>
</svg>
</div>
<h1 style={{ color: 'var(--ink)', fontSize: '1.5rem', fontWeight: 700, margin: 0 }}>{T.title}</h1>
</div>
<form onSubmit={handleSubmit} dir={lang === 'fa' ? 'rtl' : 'ltr'} style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
<div>
<label style={{ display: 'block', color: 'var(--ink-3)', fontSize: '0.85rem', marginBottom: 6 }}>{T.email}</label>
<input
type="email" required value={email}
onChange={e => setEmail(e.target.value)}
style={inputStyle}
placeholder="example@email.com"
dir="ltr"
/>
</div>
<div>
<label style={{ display: 'block', color: 'var(--ink-3)', fontSize: '0.85rem', marginBottom: 6 }}>{T.pass}</label>
<input
type="password" required value={password}
onChange={e => setPassword(e.target.value)}
style={inputStyle}
dir="ltr"
/>
</div>
{error && (
<p style={{ color: 'var(--red)', fontSize: '0.85rem', margin: 0, textAlign: 'center' }}>{error}</p>
)}
<button type="submit" disabled={loading} style={btnStyle(loading)}>
{loading ? '...' : T.submit}
</button>
</form>
<p style={{ textAlign: 'center', marginTop: '1.5rem', color: 'var(--ink-3)', fontSize: '0.875rem' }}>
{T.noAcc}{' '}
<Link to="/register" style={{ color: GOLD, fontWeight: 600, textDecoration: 'none' }}>{T.register}</Link>
</p>
</div>
</div>
)
}
const inputStyle: React.CSSProperties = {
width: '100%', padding: '0.75rem 1rem', borderRadius: 8,
border: '1px solid var(--rule-thin)', background: 'var(--paper)',
color: 'var(--ink)', fontSize: '0.95rem', outline: 'none', boxSizing: 'border-box',
}
const btnStyle = (loading: boolean): React.CSSProperties => ({
width: '100%', padding: '0.85rem', borderRadius: 8,
background: loading ? 'var(--ink-5)' : GOLD,
color: NAVY, fontWeight: 700, fontSize: '1rem',
border: 'none', cursor: loading ? 'not-allowed' : 'pointer',
transition: 'opacity 0.2s',
})