frontend changes in webpage

This commit is contained in:
sriram
2026-08-18 12:17:57 +05:30
parent 8e219ca277
commit e05d4d6e2b
10 changed files with 632 additions and 2475 deletions

View File

@@ -1,23 +1,27 @@
import React, { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useAuth } from '../context/useAuth';
import { ShieldCheck, UserCheck, Lock, User, ArrowRight, Sparkles } from 'lucide-react';
import { ShieldCheck, Lock, User, ArrowRight, Sparkles } from 'lucide-react';
/*
* There is exactly one interactive account: `admin`.
*
* This screen used to offer an Admin/User tab pair, which was always more
* suggestion than control - the server assigns the role from the account the
* password belongs to (see AuthContext.login), so the tab never affected the
* outcome. With the `user` account switched off in the backend config, the
* tabs would have offered a sign-in that could only ever fail, so they are gone
* and this is a single admin form.
*/
export function LoginPage() {
const navigate = useNavigate();
const { login } = useAuth();
const [selectedRole, setSelectedRole] = useState('admin');
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState('');
const [loading, setLoading] = useState(false);
const handleRoleSelect = (role) => {
setSelectedRole(role);
setError('');
};
const handleFormSubmit = async (e) => {
e.preventDefault();
setError('');
@@ -31,8 +35,8 @@ export function LoginPage() {
try {
const user = await login(username, password);
setLoading(false);
// Route by the role the SERVER assigned, not by the tab that was
// selected. The tab only labels which account you are signing in to.
// Route by the role the SERVER assigned. Only `admin` can sign in now,
// but a token minted for any other role still lands somewhere valid.
if (user.role === 'admin') navigate('/admin');
else navigate('/user');
} catch (err) {
@@ -44,52 +48,30 @@ export function LoginPage() {
};
return (
<div className="min-h-screen w-full bg-slate-950 text-slate-100 flex items-center justify-center p-4 relative overflow-hidden font-sans">
{/* Background Glow Accents */}
<div className="absolute -top-40 -left-40 h-96 w-96 rounded-full bg-amber-500/10 blur-3xl pointer-events-none" />
<div className="absolute -bottom-40 -right-40 h-96 w-96 rounded-full bg-emerald-500/10 blur-3xl pointer-events-none" />
<div className="min-h-screen w-full bg-white text-ink-950 flex items-center justify-center p-4 relative overflow-hidden font-sans">
{/* Background Glow Accents - warmed up to read against a white ground */}
<div className="absolute -top-40 -left-40 h-96 w-96 rounded-full bg-amber-400/25 blur-3xl pointer-events-none" />
<div className="absolute -bottom-40 -right-40 h-96 w-96 rounded-full bg-leaf-500/15 blur-3xl pointer-events-none" />
<div className="w-full max-w-md relative z-10">
{/* Header Branding */}
<div className="text-center mb-8">
<div className="inline-flex items-center gap-2 px-3.5 py-1 rounded-full bg-amber-500/10 border border-amber-500/30 text-amber-400 text-xs font-semibold mb-3">
<Sparkles className="h-3.5 w-3.5" /> Brand Catalog & Store Intelligence
<div className="inline-flex items-center gap-2 px-3.5 py-1 rounded-full bg-amber-500/15 border border-amber-500/40 text-amber-600 text-xs font-semibold mb-3">
<Sparkles className="h-3.5 w-3.5" /> Brand Catalog &amp; Store Intelligence
</div>
<h1 className="text-3xl font-bold tracking-tight text-white font-display">System Authentication</h1>
<p className="text-sm text-slate-400 mt-1">Please enter your username and password to sign in</p>
<h1 className="text-3xl font-bold tracking-tight text-ink-950 font-display">System Authentication</h1>
<p className="text-sm text-slate-500 mt-1">Please enter your username and password to sign in</p>
</div>
{/* Main Card */}
<div className="rounded-2xl border border-slate-800 bg-slate-900/80 p-6 backdrop-blur-xl shadow-2xl">
{/* Role Selection Tabs: Admin and User */}
<div className="grid grid-cols-2 gap-2 p-1.5 rounded-xl bg-slate-950/80 border border-slate-800/80 mb-6">
<button
type="button"
onClick={() => handleRoleSelect('admin')}
className={`flex items-center justify-center gap-2 py-3 px-4 rounded-lg text-xs font-bold transition-all ${
selectedRole === 'admin'
? 'bg-amber-500 text-slate-950 shadow-md scale-[1.02]'
: 'text-slate-400 hover:text-white hover:bg-slate-800/50'
}`}
>
<ShieldCheck className="h-4 w-4" /> Admin Account
</button>
<button
type="button"
onClick={() => handleRoleSelect('user')}
className={`flex items-center justify-center gap-2 py-3 px-4 rounded-lg text-xs font-bold transition-all ${
selectedRole === 'user'
? 'bg-blue-500 text-white shadow-md scale-[1.02]'
: 'text-slate-400 hover:text-white hover:bg-slate-800/50'
}`}
>
<UserCheck className="h-4 w-4" /> User Account
</button>
<div className="rounded-2xl border border-ink-900/10 bg-paper-50 p-6 shadow-lg">
{/* Single account banner - replaces the old Admin/User tab pair */}
<div className="flex items-center justify-center gap-2 py-3 px-4 mb-6 rounded-xl bg-amber-500/10 border border-amber-500/30 text-xs font-bold text-amber-700">
<ShieldCheck className="h-4 w-4" /> Administrator Sign-In
</div>
{error && (
<div className="mb-4 rounded-lg bg-rose-500/10 border border-rose-500/30 p-3 text-xs text-rose-400">
<div className="mb-4 rounded-lg bg-maroon-100 border border-maroon-500/30 p-3 text-xs text-maroon-600">
{error}
</div>
)}
@@ -97,31 +79,31 @@ export function LoginPage() {
{/* Login Form */}
<form onSubmit={handleFormSubmit} className="space-y-4">
<div>
<label className="block text-xs font-medium text-slate-300 mb-1.5">Username</label>
<label className="block text-xs font-medium text-slate-600 mb-1.5">Username</label>
<div className="relative">
<User className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-slate-500" />
<User className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-slate-400" />
<input
type="text"
required
value={username}
onChange={(e) => setUsername(e.target.value)}
placeholder={`Enter ${selectedRole} username`}
className="w-full rounded-xl border border-slate-700 bg-slate-950/80 py-2.5 pl-9 pr-4 text-sm text-white placeholder-slate-500 focus:border-amber-500 focus:outline-none focus:ring-1 focus:ring-amber-500"
placeholder="Enter admin username"
className="w-full rounded-xl border border-ink-900/15 bg-white py-2.5 pl-9 pr-4 text-sm text-ink-950 placeholder-slate-400 focus:border-amber-500 focus:outline-none focus:ring-2 focus:ring-amber-500/25"
/>
</div>
</div>
<div>
<label className="block text-xs font-medium text-slate-300 mb-1.5">Password</label>
<label className="block text-xs font-medium text-slate-600 mb-1.5">Password</label>
<div className="relative">
<Lock className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-slate-500" />
<Lock className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-slate-400" />
<input
type="password"
required
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="Enter password"
className="w-full rounded-xl border border-slate-700 bg-slate-950/80 py-2.5 pl-9 pr-4 text-sm text-white placeholder-slate-500 focus:border-amber-500 focus:outline-none focus:ring-1 focus:ring-amber-500"
className="w-full rounded-xl border border-ink-900/15 bg-white py-2.5 pl-9 pr-4 text-sm text-ink-950 placeholder-slate-400 focus:border-amber-500 focus:outline-none focus:ring-2 focus:ring-amber-500/25"
/>
</div>
</div>
@@ -129,9 +111,9 @@ export function LoginPage() {
<button
type="submit"
disabled={loading}
className="w-full flex items-center justify-center gap-2 rounded-xl bg-gradient-to-r from-amber-500 to-amber-600 hover:from-amber-600 hover:to-amber-700 text-slate-950 py-3 text-sm font-bold shadow-lg shadow-amber-500/20 transition-all duration-200 active:scale-98 disabled:opacity-50"
className="w-full flex items-center justify-center gap-2 rounded-xl bg-gradient-to-r from-amber-500 to-amber-600 hover:from-amber-600 hover:to-amber-700 text-white py-3 text-sm font-bold shadow-md shadow-amber-500/25 transition-all duration-200 active:scale-98 disabled:opacity-50 cursor-pointer"
>
{loading ? 'Authenticating...' : `Sign In as ${selectedRole.toUpperCase()}`}
{loading ? 'Authenticating...' : 'Sign In as ADMIN'}
<ArrowRight className="h-4 w-4" />
</button>
</form>
@@ -139,7 +121,7 @@ export function LoginPage() {
{/* Footer info */}
<p className="text-center text-xs text-slate-500 mt-6">
Powered by pgvector RAG Model & Multi-Store Nutrition Intelligence Engine
Powered by pgvector RAG Model &amp; Multi-Store Nutrition Intelligence Engine
</p>
</div>
</div>