Files
merica/frontend/src/components/LoginModal.jsx
T

207 lines
7.5 KiB
React

import React, { useState } from 'react';
import { Layers, ShieldCheck, UserCheck, Eye, Lock, ArrowRight, CheckCircle } from 'lucide-react';
export default function LoginModal({ isOpen, onLogin }) {
const [email, setEmail] = useState('admin@dlh.go.id');
const [password, setPassword] = useState('admin123');
const [selectedRole, setSelectedRole] = useState('admin');
if (!isOpen) return null;
const handleQuickFill = (role) => {
setSelectedRole(role);
if (role === 'admin') {
setEmail('admin@dlh.go.id');
setPassword('admin123');
} else {
setEmail('viewer@dlh.go.id');
setPassword('viewer123');
}
};
const handleSubmit = (e) => {
e.preventDefault();
onLogin({
email,
role: selectedRole,
name: selectedRole === 'admin' ? 'Administrator (DLH Lead)' : 'Guest Inspector (Viewer)',
});
};
return (
<div
style={{
position: 'fixed',
inset: 0,
background: 'rgba(8, 9, 13, 0.85)',
backdropFilter: 'blur(12px)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
zIndex: 1000,
padding: '20px',
}}
>
<div
style={{
width: '100%',
maxWidth: '480px',
background: 'var(--color-surface, #0E1016)',
border: '1px solid var(--color-border-strong, rgba(255,255,255,0.14))',
borderRadius: 'var(--radius-2xl, 24px)',
boxShadow: '0 25px 70px rgba(0,0,0,0.5)',
padding: '32px',
color: 'var(--color-text-primary, #F5F7FA)',
display: 'flex',
flexDirection: 'column',
gap: '24px',
}}
>
{/* BRAND HEADER */}
<div style={{ textAlign: 'center' }}>
<div
style={{
width: '52px',
height: '52px',
borderRadius: '16px',
background: 'linear-gradient(135deg, #8B7CFF 0%, #6377FF 100%)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
margin: '0 auto 14px auto',
boxShadow: '0 8px 24px rgba(139, 124, 255, 0.35)',
}}
>
<Layers size={28} color="#ffffff" />
</div>
<h2 style={{ fontSize: '20px', fontWeight: '700', margin: '0 0 6px 0', letterSpacing: '-0.3px' }}>
DLH Low-Code Studio Access
</h2>
<p style={{ fontSize: '13px', color: 'var(--color-text-muted, #707686)', margin: 0 }}>
Select user role or quick-autofill credentials to sign in
</p>
</div>
{/* QUICK AUTOFILL ROLE SELECTOR BUTTONS */}
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '10px' }}>
<button
type="button"
onClick={() => handleQuickFill('admin')}
style={{
padding: '12px',
borderRadius: '12px',
border: selectedRole === 'admin' ? '2px solid #8B7CFF' : '1px solid var(--color-border-subtle, rgba(255,255,255,0.06))',
background: selectedRole === 'admin' ? 'rgba(139, 124, 255, 0.12)' : 'var(--color-surface-raised, #12141B)',
color: selectedRole === 'admin' ? '#ffffff' : 'var(--color-text-muted, #707686)',
cursor: 'pointer',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
gap: '6px',
transition: 'all 0.2s ease',
}}
>
<UserCheck size={20} color={selectedRole === 'admin' ? '#8B7CFF' : '#707686'} />
<span style={{ fontSize: '12px', fontWeight: '700' }}>👑 Admin Role</span>
<span style={{ fontSize: '10px', opacity: 0.8 }}>Full Edit & Deploy</span>
</button>
<button
type="button"
onClick={() => handleQuickFill('viewer')}
style={{
padding: '12px',
borderRadius: '12px',
border: selectedRole === 'viewer' ? '2px solid #38bdf8' : '1px solid var(--color-border-subtle, rgba(255,255,255,0.06))',
background: selectedRole === 'viewer' ? 'rgba(56, 189, 248, 0.12)' : 'var(--color-surface-raised, #12141B)',
color: selectedRole === 'viewer' ? '#ffffff' : 'var(--color-text-muted, #707686)',
cursor: 'pointer',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
gap: '6px',
transition: 'all 0.2s ease',
}}
>
<Eye size={20} color={selectedRole === 'viewer' ? '#38bdf8' : '#707686'} />
<span style={{ fontSize: '12px', fontWeight: '700' }}>👁️ Viewer Role</span>
<span style={{ fontSize: '10px', opacity: 0.8 }}>Read-Only Canvas</span>
</button>
</div>
{/* LOGIN FORM */}
<form onSubmit={handleSubmit} style={{ display: 'flex', flexDirection: 'column', gap: '14px' }}>
<div>
<label style={{ fontSize: '12px', fontWeight: '600', color: 'var(--color-text-secondary, #A5AAB8)', display: 'block', marginBottom: '6px' }}>
User Email Address
</label>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
style={{
width: '100%',
padding: '10px 14px',
borderRadius: '8px',
background: 'var(--color-surface-raised, #12141B)',
border: '1px solid var(--color-border-default, rgba(255,255,255,0.09))',
color: 'var(--color-text-primary, #F5F7FA)',
fontSize: '13px',
outline: 'none',
}}
/>
</div>
<div>
<label style={{ fontSize: '12px', fontWeight: '600', color: 'var(--color-text-secondary, #A5AAB8)', display: 'block', marginBottom: '6px' }}>
Password
</label>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
required
style={{
width: '100%',
padding: '10px 14px',
borderRadius: '8px',
background: 'var(--color-surface-raised, #12141B)',
border: '1px solid var(--color-border-default, rgba(255,255,255,0.09))',
color: 'var(--color-text-primary, #F5F7FA)',
fontSize: '13px',
outline: 'none',
}}
/>
</div>
<button
type="submit"
style={{
width: '100%',
padding: '12px',
borderRadius: '10px',
background: selectedRole === 'admin'
? 'linear-gradient(135deg, #8B7CFF 0%, #6377FF 100%)'
: 'linear-gradient(135deg, #0EA5E9 0%, #0284C7 100%)',
color: '#ffffff',
border: 'none',
fontSize: '14px',
fontWeight: '700',
cursor: 'pointer',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
gap: '8px',
marginTop: '6px',
boxShadow: '0 4px 16px rgba(139, 124, 255, 0.3)',
}}
>
Enter Studio Workspace as {selectedRole.toUpperCase()} <ArrowRight size={16} />
</button>
</form>
</div>
</div>
);
}