Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion web/src/features/admin/AdminDashboard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ const AdminDashboard = ({ user, onLogout }) => {
<div className="mb-8 flex justify-between items-end">
<div>
<p className="eyebrow mb-1.5">Panel Administrator</p>
<h1 className="text-3xl md:text-4xl text-display leading-tight">{TITLES[activeTab]}</h1>
<h1 className="text-2xl md:text-3xl text-display leading-tight">{TITLES[activeTab]}</h1>
<p className="text-sm text-ink-muted mt-2">Data operasional Visitor Management System.</p>
</div>
{busy && <Loader2 className="text-[#3C6DB2] animate-spin" size={22} />}
Expand Down
2 changes: 1 addition & 1 deletion web/src/features/admin/DashboardOverviewTab.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ const MetricCard = ({ icon: Icon, label, value, valueClass = 'text-ink' }) => (
</span>
<span className="text-xs font-semibold uppercase tracking-[0.12em] text-ink-muted">{label}</span>
</div>
<div className={`text-5xl text-display ${valueClass}`}>{value}</div>
<div className={`text-4xl text-display ${valueClass}`}>{value}</div>
</div>
);

Expand Down
2 changes: 1 addition & 1 deletion web/src/features/security/SecurityDashboard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ const SecurityDashboard = ({ user, onLogout }) => {

<main className="flex-1 p-4 md:p-8 overflow-y-auto">
<div className="mb-6 md:mb-8 flex items-center justify-between gap-3">
<h1 className="text-3xl md:text-4xl text-display">{TITLES[activeTab]}</h1>
<h1 className="text-2xl md:text-3xl text-display">{TITLES[activeTab]}</h1>
<div className="flex items-center gap-3 shrink-0">
{busy && <Loader2 className="text-[#3C6DB2] animate-spin" size={22} />}
{activeTab === 'paket' && (
Expand Down
57 changes: 14 additions & 43 deletions web/src/screens/LoginScreen.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,44 +86,16 @@ const LoginScreen = ({ onLogin }) => {
};

return (
<div className="min-h-screen lg:grid lg:grid-cols-2 flex flex-col">
{/* Panel brand bergaya editorial mewah (kiri di desktop, atas di mobile). */}
<aside className="relative overflow-hidden bg-ink-gradient text-white px-8 py-12 lg:p-16 flex flex-col justify-between min-h-[34vh] lg:min-h-screen">
<div className="absolute inset-0 opacity-[0.18] pointer-events-none"
style={{ backgroundImage: 'radial-gradient(40rem 40rem at 80% -10%, #3C6DB2, transparent 60%), radial-gradient(30rem 30rem at -10% 110%, #B8924A, transparent 55%)' }} />
<div className="absolute inset-0 pointer-events-none opacity-[0.04]"
style={{ backgroundImage: 'linear-gradient(rgba(255,255,255,.6) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,.6) 1px, transparent 1px)', backgroundSize: '44px 44px' }} />
<div className="relative">
<BrandLogo className="h-10 brightness-0 invert" />
</div>
<div className="relative">
<p className="eyebrow text-gold-soft mb-5">Visitor Management System</p>
<h2 className="text-display text-white text-4xl lg:text-5xl leading-[1.05] mb-5">
Pengalaman kunjungan<br className="hidden lg:block" /> yang aman &amp; berkelas.
</h2>
<p className="text-white/70 max-w-md leading-relaxed">
Registrasi, verifikasi, dan pemantauan tamu dalam satu sistem terintegrasi —
dirancang dengan standar keamanan dan kenyamanan terbaik.
</p>
</div>
<div className="relative hidden lg:flex items-center gap-6 text-xs text-white/50 tracking-wide">
<span>Keamanan Terverifikasi</span>
<span className="h-1 w-1 rounded-full bg-gold-soft/60" />
<span>Sesuai UU PDP</span>
<span className="h-1 w-1 rounded-full bg-gold-soft/60" />
<span>PT Pertamina</span>
</div>
</aside>

{/* Panel autentikasi. */}
<main className="flex-1 flex items-center justify-center p-6 lg:p-12">
<div className="w-full max-w-md surface-raised rounded-[28px] p-8 lg:p-10 flex flex-col items-center text-center">
<p className="eyebrow mb-3">Selamat Datang</p>
<h1 className="text-display text-3xl mb-3">Masuk ke Akun Anda</h1>
<div className="rule-gold w-24 mb-5" />
<p className="text-ink-muted mb-8 text-sm leading-relaxed max-w-sm">
Gunakan akun Google Anda. Sistem akan mengenali peran Anda secara otomatis.
</p>
// Hanya kotak login yang ditampilkan, terpusat & dioptimalkan untuk layar mobile.
<div className="min-h-screen flex items-center justify-center p-4 sm:p-6">
<div className="w-full max-w-sm surface-raised rounded-3xl p-6 sm:p-8 flex flex-col items-center text-center">
<BrandLogo className="h-8 mb-6" />
<p className="eyebrow mb-2">Selamat Datang</p>
<h1 className="text-display text-2xl mb-2">Masuk ke Akun Anda</h1>
<div className="rule-gold w-16 mb-4" />
<p className="text-ink-muted mb-6 text-sm leading-relaxed">
Gunakan akun Google Anda. Sistem akan mengenali peran Anda secara otomatis.
</p>

{error && (
<div role="alert" className="w-full mb-4 px-4 py-3 rounded-2xl bg-[#FBE9EA] border border-[#E9A6AB] text-[#7A1D24] text-sm text-left">
Expand All @@ -133,7 +105,7 @@ const LoginScreen = ({ onLogin }) => {

<Button
variant="outlined"
className={`w-full h-14 text-base bg-white text-ink ${USE_MOCK ? '' : 'hidden'}`}
className={`w-full h-12 text-sm bg-white text-ink ${USE_MOCK ? '' : 'hidden'}`}
disabled={loading}
onClick={handleGoogleMock}
>
Expand All @@ -142,7 +114,7 @@ const LoginScreen = ({ onLogin }) => {
</Button>

{!USE_MOCK && (
<div className={`w-full h-14 flex items-center justify-center ${loading ? 'opacity-60 pointer-events-none' : ''}`}>
<div className={`w-full min-h-[48px] flex items-center justify-center ${loading ? 'opacity-60 pointer-events-none' : ''}`}>
<div ref={googleButtonRef} className="w-full flex justify-center" />
</div>
)}
Expand Down Expand Up @@ -180,11 +152,10 @@ const LoginScreen = ({ onLogin }) => {
</div>
)}

<p className="text-xs text-ink-muted mt-8 max-w-xs leading-relaxed">
<p className="text-[11px] text-ink-muted mt-6 leading-relaxed">
Dengan masuk, Anda menyetujui Kebijakan Privasi serta Syarat &amp; Ketentuan kami (sesuai UU PDP).
</p>
</div>
</main>
</div>
</div>
);
};
Expand Down
8 changes: 4 additions & 4 deletions web/src/screens/VisitorFormScreen.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,13 @@ const VisitorFormScreen = ({ user, onSubmit }) => {
return (
<div className="min-h-screen p-4 md:py-10 flex justify-center">
<div className="w-full max-w-lg surface-raised rounded-[28px] overflow-hidden">
<div className="relative bg-ink-gradient p-8 text-white text-center overflow-hidden">
<div className="relative bg-ink-gradient px-6 py-8 text-white text-center overflow-hidden">
<div className="absolute inset-0 opacity-20 pointer-events-none"
style={{ backgroundImage: 'radial-gradient(28rem 28rem at 80% -30%, #3C6DB2, transparent 60%)' }} />
<div className="relative">
<BrandLogo className="h-8 justify-center brightness-0 invert mb-5" />
<p className="eyebrow text-gold-soft mb-2">Registrasi Kunjungan</p>
<h1 className="text-display text-white text-3xl">Halo, {user.name}</h1>
<BrandLogo className="h-7 justify-center brightness-0 invert mb-4" />
<p className="eyebrow text-gold-soft mb-1.5">Registrasi Kunjungan</p>
<h1 className="text-display text-white text-2xl">Halo, {user.name}</h1>
<p className="text-white/70 text-sm mt-2">
{isReturning ? 'Silakan isi detail kunjungan Anda hari ini.' : 'Lengkapi data diri untuk registrasi tamu.'}
</p>
Expand Down
24 changes: 12 additions & 12 deletions web/src/screens/VisitorStatusScreen.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ const VisitorStatusScreen = ({ statusData, onLogout }) => {

{status === 'PENDING' && (
<>
<div className="w-24 h-24 bg-[#FFEFD6] text-[#5E4200] rounded-full flex items-center justify-center mb-6 ring-8 ring-[#FFEFD6]/40 animate-pulse-soft">
<Clock size={44} />
<div className="w-20 h-20 bg-[#FFEFD6] text-[#5E4200] rounded-full flex items-center justify-center mb-6 ring-8 ring-[#FFEFD6]/40 animate-pulse-soft">
<Clock size={38} />
</div>
<p className="eyebrow mb-2">Status Kunjungan</p>
<h2 className="text-display text-3xl mb-3">Menunggu</h2>
<h2 className="text-display text-2xl mb-3">Menunggu</h2>
<p className="text-ink-muted text-sm mb-6 leading-relaxed">
Mohon tunggu sebentar di lobi. Petugas keamanan sedang memverifikasi data dan tujuan Anda (
<strong>{statusData.tujuan}</strong>).
Expand All @@ -47,11 +47,11 @@ const VisitorStatusScreen = ({ statusData, onLogout }) => {

{status === 'CHECKED_IN' && (
<>
<div className="w-24 h-24 bg-[#E6F893] text-[#192100] rounded-full flex items-center justify-center mb-6 ring-8 ring-[#E6F893]/40">
<CheckCircle size={44} />
<div className="w-20 h-20 bg-[#E6F893] text-[#192100] rounded-full flex items-center justify-center mb-6 ring-8 ring-[#E6F893]/40">
<CheckCircle size={38} />
</div>
<p className="eyebrow mb-2">Status Kunjungan</p>
<h2 className="text-display text-3xl mb-3">Check In</h2>
<h2 className="text-display text-2xl mb-3">Check In</h2>
<p className="text-ink-muted text-sm mb-6 leading-relaxed">
Silakan masuk. Jangan lupa mengenakan kartu visitor Anda selama berada di dalam area.
</p>
Expand All @@ -60,11 +60,11 @@ const VisitorStatusScreen = ({ statusData, onLogout }) => {

{status === 'CHECKED_OUT' && (
<>
<div className="w-24 h-24 bg-[#EFEDF1] text-[#44474E] rounded-full flex items-center justify-center mb-6 ring-8 ring-[#EFEDF1]/50">
<LogOut size={44} />
<div className="w-20 h-20 bg-[#EFEDF1] text-[#44474E] rounded-full flex items-center justify-center mb-6 ring-8 ring-[#EFEDF1]/50">
<LogOut size={38} />
</div>
<p className="eyebrow mb-2">Status Kunjungan</p>
<h2 className="text-display text-3xl mb-3">Check Out</h2>
<h2 className="text-display text-2xl mb-3">Check Out</h2>
<p className="text-ink-muted text-sm mb-6 leading-relaxed">
Terima kasih atas kunjungan Anda. Pastikan kartu visitor telah dikembalikan ke petugas.
</p>
Expand All @@ -73,11 +73,11 @@ const VisitorStatusScreen = ({ statusData, onLogout }) => {

{status === 'REJECTED' && (
<>
<div className="w-24 h-24 bg-[#FFDAD6] text-[#410002] rounded-full flex items-center justify-center mb-6 ring-8 ring-[#FFDAD6]/40">
<X size={44} />
<div className="w-20 h-20 bg-[#FFDAD6] text-[#410002] rounded-full flex items-center justify-center mb-6 ring-8 ring-[#FFDAD6]/40">
<X size={38} />
</div>
<p className="eyebrow mb-2">Status Kunjungan</p>
<h2 className="text-display text-3xl mb-3">Ditolak</h2>
<h2 className="text-display text-2xl mb-3">Ditolak</h2>
<div className="bg-[#FFDAD6]/30 border border-[#FFDAD6] p-4 rounded-2xl text-sm text-[#410002] mb-6 w-full text-left">
<strong>Alasan:</strong> {rejectReason || 'Tujuan tidak dapat ditemui.'}
</div>
Expand Down
3 changes: 2 additions & 1 deletion web/tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ export default {
backgroundImage: {
'brand-gradient': 'linear-gradient(135deg, #3C6DB2 0%, #274875 100%)',
'brand-gradient-soft': 'linear-gradient(135deg, #5587C6 0%, #2F5793 100%)',
'ink-gradient': 'linear-gradient(150deg, #1B2026 0%, #0E1216 100%)',
// Gradien biru korporat yang dalam (BUKAN hitam) untuk header/sidebar gelap.
'ink-gradient': 'linear-gradient(150deg, #2F5793 0%, #16273E 100%)',
'gold-line': 'linear-gradient(90deg, transparent, #D9BE84 50%, transparent)',
},
keyframes: {
Expand Down