Files
fourge-portal/src/pages/Login.jsx
T
Krao Hasanee c91e292066 redesign: Layout2 design-system + dashboard/tasks rework + perf
Design system (Layout2):
- Solid token-driven theme (no animated grid); single-source tokens for bg,
  cards (bg/border/radius), popups, fonts (Inter), and full semantic +
  data-viz color palette. Swept ~168 hardcoded colors to tokens.

Dashboard:
- Reflow: To Do + Calendar row (fixed right rail) over Activity / In-Progress /
  Team Performance; CSS height-match (To Do = Calendar); responsive stacking.
- 'Tasks Not Started' -> 'To Do' card with R#/Assigned columns; compact money fmt.

Tasks page:
- Combined tabs into Tasks + Completed with a Status column.
- Column-header sort + filter (Status, R#/new-vs-revision, Project, Task Type,
  Company) via portaled, scrollable FilterDropdown; removed toolbar filters and
  the projects side panel; headers stay visible when empty; renamed to 'Tasks'.

Perf:
- FK/filter index migration; removed redundant client/external scope waterfall
  (rely on RLS); parallel follow-up queries.

Mobile:
- Responsive grids; mobile topbar = hamburger only, blends with bg, proper offset.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 10:08:40 -04:00

76 lines
2.5 KiB
React

import { useState, useEffect } from 'react';
import { useNavigate, useLocation, Link } from 'react-router-dom';
import { useAuth } from '../context/AuthContext';
export default function Login() {
const { login, currentUser } = useAuth();
const navigate = useNavigate();
const location = useLocation();
const successMessage = location.state?.message || '';
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState('');
const [loading, setLoading] = useState(false);
useEffect(() => {
if (currentUser) {
navigate('/dashboard', { replace: true });
}
}, [currentUser, navigate]);
const handleSuccess = async (e) => {
e.preventDefault();
setLoading(true);
setError('');
const { error: err } = await login(email, password);
if (err) {
setError('Invalid email or password.');
}
setLoading(false);
// Navigation handled by useEffect watching currentUser
};
return (
<div className="auth-page">
<div className="auth-card">
<div className="auth-logo">
<img className="brand-logo brand-logo-auth" src="/fourge-logo.png" alt="Fourge Branding" />
<p>Client & Project Portal</p>
</div>
<form onSubmit={handleSuccess}>
<div className="form-group">
<label>Email Address</label>
<input
type="email"
placeholder="you@example.com"
value={email}
onChange={e => { setEmail(e.target.value); setError(''); }}
required
/>
</div>
<div className="form-group">
<label>Password</label>
<input
type="password"
placeholder="••••••••"
value={password}
onChange={e => { setPassword(e.target.value); setError(''); }}
required
/>
</div>
{successMessage && <p style={{ color: 'var(--success)', fontSize: 13, marginBottom: 12 }}>{successMessage}</p>}
{error && <p style={{ color: 'var(--danger)', fontSize: 13, marginBottom: 12 }}>{error}</p>}
<button type="submit" className="btn btn-primary w-full btn-lg" disabled={loading}>
{loading ? 'Signing in...' : 'Sign In'}
</button>
</form>
<p style={{ textAlign: 'center', marginTop: 20, fontSize: 13, color: 'var(--text-secondary)' }}>
Contact Fourge Branding to get access.
</p>
</div>
</div>
);
}