207 lines
7.5 KiB
React
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>
|
||
|
|
);
|
||
|
|
}
|