294 lines
12 KiB
HTML
294 lines
12 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="id">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Login — Smart Donation Box</title>
|
|
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css">
|
|
<style>
|
|
:root {
|
|
--primary-green: hsl(160, 84%, 39%);
|
|
--primary-green-light: #D1FAE5;
|
|
--card-bg: #FFFFFF;
|
|
--text-main: #1E293B;
|
|
--text-muted: #64748B;
|
|
--border-color: #E2E8F0;
|
|
--danger-red: #EF4444;
|
|
--bg-color: #F0F4F0;
|
|
--input-bg: #F8F9FB;
|
|
--nav-bg: #FFFFFF;
|
|
}
|
|
|
|
/* ── Dark mode variables ── */
|
|
body.dark-mode {
|
|
--bg-color: #000000;
|
|
--card-bg: #0a111c;
|
|
--text-main: #F8FAFC;
|
|
--text-muted: #94A3B8;
|
|
--border-color: #334155;
|
|
--primary-green-light: rgba(16, 185, 129, 0.2);
|
|
--input-bg: #111827;
|
|
--nav-bg: #0a111c;
|
|
}
|
|
|
|
* { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Poppins', sans-serif; }
|
|
|
|
body {
|
|
background: var(--bg-color);
|
|
min-height: 100vh;
|
|
display: flex;
|
|
flex-direction: column;
|
|
transition: background-color 0.3s ease, color 0.3s ease;
|
|
color: var(--text-main);
|
|
}
|
|
|
|
/* ── Top Nav ── */
|
|
.top-nav {
|
|
background: var(--nav-bg);
|
|
border-bottom: 1px solid var(--border-color);
|
|
padding: 14px 32px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
transition: background-color 0.3s ease;
|
|
}
|
|
.top-nav-logo { display: flex; align-items: center; gap: 10px; color: var(--primary-green); }
|
|
.top-nav-logo i { font-size: 22px; }
|
|
.top-nav-logo span { font-size: 15px; font-weight: 600; color: var(--text-main); }
|
|
|
|
/* Theme toggle di nav */
|
|
.btn-theme-nav {
|
|
background: none;
|
|
border: 1px solid var(--border-color);
|
|
width: 36px; height: 36px;
|
|
border-radius: 50%;
|
|
display: flex; align-items: center; justify-content: center;
|
|
cursor: pointer;
|
|
color: var(--text-main);
|
|
font-size: 14px;
|
|
transition: all 0.3s ease;
|
|
}
|
|
.btn-theme-nav:hover { background: var(--primary-green-light); color: var(--primary-green); border-color: var(--primary-green); }
|
|
body.dark-mode .btn-theme-nav { color: #FFD700; }
|
|
|
|
/* ── Login wrapper ── */
|
|
.login-wrapper { flex: 1; display: flex; align-items: center; justify-content: center; padding: 40px 20px; }
|
|
|
|
.login-card {
|
|
background: var(--card-bg);
|
|
border-radius: 16px;
|
|
border: 1px solid var(--border-color);
|
|
box-shadow: 0 4px 24px rgba(0,0,0,0.06);
|
|
width: 100%;
|
|
max-width: 420px;
|
|
padding: 40px 36px 32px;
|
|
animation: slideUp 0.4s ease;
|
|
transition: background-color 0.3s ease, border-color 0.3s ease;
|
|
}
|
|
body.dark-mode .login-card { box-shadow: 0 4px 32px rgba(0,0,0,0.4); }
|
|
|
|
@keyframes slideUp {
|
|
from { opacity: 0; transform: translateY(20px); }
|
|
to { opacity: 1; transform: translateY(0); }
|
|
}
|
|
|
|
.login-icon-wrap { display: flex; align-items: center; justify-content: center; margin-bottom: 20px; }
|
|
.icon-circle {
|
|
width: 68px; height: 68px; border-radius: 50%;
|
|
background: var(--primary-green-light);
|
|
display: flex; align-items: center; justify-content: center;
|
|
color: var(--primary-green); font-size: 28px;
|
|
transition: background-color 0.3s ease;
|
|
}
|
|
|
|
.login-title { text-align: center; margin-bottom: 28px; }
|
|
.login-title h2 { font-size: 20px; font-weight: 700; color: var(--text-main); line-height: 1.3; margin-bottom: 6px; transition: color 0.3s; }
|
|
.login-title p { font-size: 13px; color: var(--text-muted); }
|
|
|
|
/* ── Form ── */
|
|
.form-group { margin-bottom: 18px; }
|
|
.form-group label { display: block; font-size: 13px; font-weight: 500; color: var(--text-muted); margin-bottom: 8px; }
|
|
|
|
.input-wrapper { position: relative; }
|
|
.input-wrapper .icon-left { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); color: #94A3B8; font-size: 14px; }
|
|
.input-wrapper input {
|
|
width: 100%;
|
|
padding: 12px 44px 12px 40px;
|
|
border: 1px solid var(--border-color);
|
|
border-radius: 8px;
|
|
font-size: 14px;
|
|
font-family: 'Poppins', sans-serif;
|
|
color: var(--text-main);
|
|
background: var(--input-bg);
|
|
outline: none;
|
|
transition: border-color 0.2s, box-shadow 0.2s, background-color 0.3s, color 0.3s;
|
|
}
|
|
.input-wrapper input:focus { border-color: var(--primary-green); box-shadow: 0 0 0 3px rgba(16,185,129,0.12); }
|
|
.input-wrapper input::placeholder { color: #CBD5E1; }
|
|
body.dark-mode .input-wrapper input::placeholder { color: #475569; }
|
|
|
|
/* Toggle mata */
|
|
.btn-toggle-pass {
|
|
position: absolute; right: 12px; top: 50%; transform: translateY(-50%);
|
|
background: none; border: none; cursor: pointer;
|
|
color: #94A3B8; font-size: 15px; padding: 4px;
|
|
display: flex; align-items: center;
|
|
transition: color 0.2s;
|
|
}
|
|
.btn-toggle-pass:hover { color: var(--primary-green); }
|
|
|
|
.btn-login {
|
|
width: 100%; padding: 13px;
|
|
background: var(--primary-green); color: #fff; border: none;
|
|
border-radius: 8px; font-size: 15px; font-weight: 600;
|
|
font-family: 'Poppins', sans-serif; cursor: pointer;
|
|
display: flex; align-items: center; justify-content: center; gap: 8px;
|
|
margin-top: 8px; transition: background 0.2s, transform 0.1s;
|
|
}
|
|
.btn-login:hover { background: #059669; }
|
|
.btn-login:active { transform: scale(0.98); }
|
|
.btn-login:disabled { opacity: 0.7; cursor: not-allowed; }
|
|
|
|
.msg-error { text-align: center; margin-top: 14px; font-size: 13px; min-height: 18px; color: var(--danger-red); }
|
|
|
|
.login-note {
|
|
text-align: center; margin-top: 24px; padding-top: 20px;
|
|
border-top: 1px solid var(--border-color);
|
|
font-size: 12px; color: var(--text-muted); line-height: 1.7;
|
|
transition: border-color 0.3s;
|
|
}
|
|
|
|
.login-footer { text-align: center; padding: 20px; font-size: 12px; color: var(--text-muted); }
|
|
.login-footer .footer-brand { color: var(--primary-green); display: flex; align-items: center; justify-content: center; gap: 6px; margin-bottom: 4px; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<nav class="top-nav">
|
|
<div class="top-nav-logo">
|
|
<i class="fa-solid fa-mosque"></i>
|
|
<span>Smart Donation Box</span>
|
|
</div>
|
|
<!-- Tombol dark mode sama seperti di dalam dashboard -->
|
|
<button class="btn-theme-nav" id="btn-theme-login" title="Toggle dark mode">
|
|
<i class="fas fa-moon" id="login-theme-icon"></i>
|
|
</button>
|
|
</nav>
|
|
|
|
<div class="login-wrapper">
|
|
<div class="login-card">
|
|
<div class="login-icon-wrap">
|
|
<div class="icon-circle"><i class="fa-solid fa-mosque"></i></div>
|
|
</div>
|
|
<div class="login-title">
|
|
<h2>Smart Donation Box<br>Monitoring System</h2>
|
|
<p>Monitoring Donasi Kotak Amal Berbasis IoT</p>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>Username</label>
|
|
<div class="input-wrapper">
|
|
<i class="fa-regular fa-user icon-left"></i>
|
|
<input type="text" id="user" placeholder="Enter your username" autocomplete="username">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>Password</label>
|
|
<div class="input-wrapper">
|
|
<i class="fa-solid fa-lock icon-left"></i>
|
|
<input type="password" id="pass" placeholder="Enter your password" autocomplete="current-password">
|
|
<button class="btn-toggle-pass" id="btn-toggle-pass" type="button" title="Lihat/sembunyikan password">
|
|
<i class="fa-regular fa-eye" id="pass-eye-icon"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<button class="btn-login" id="btn-login">
|
|
Login <i class="fa-solid fa-arrow-right-to-bracket"></i>
|
|
</button>
|
|
<p class="msg-error" id="msg"></p>
|
|
|
|
<div class="login-note">
|
|
This project is developed for final year undergraduate requirements.<br>
|
|
Ensuring transparency in community donations.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<footer class="login-footer">
|
|
<div class="footer-brand">
|
|
<i class="fa-solid fa-mosque"></i>
|
|
Transparansi Donasi Terjamin dengan Sistem IoT
|
|
</div>
|
|
© 2026 Proyek Akhir Smart Donation Box
|
|
</footer>
|
|
|
|
<script type="module">
|
|
import { db } from './firebase-config.js';
|
|
import { ref, get } from "https://www.gstatic.com/firebasejs/12.10.0/firebase-database.js";
|
|
|
|
// ── Sinkronisasi dark mode dengan dashboard ──
|
|
const themeIcon = document.getElementById('login-theme-icon');
|
|
function applyTheme(dark) {
|
|
document.body.classList.toggle('dark-mode', dark);
|
|
themeIcon.className = dark ? 'fas fa-sun' : 'fas fa-moon';
|
|
}
|
|
// Load state tersimpan dari localStorage (sama dengan dashboard)
|
|
applyTheme(localStorage.getItem('theme') === 'dark');
|
|
|
|
document.getElementById('btn-theme-login').addEventListener('click', () => {
|
|
const isDark = !document.body.classList.contains('dark-mode');
|
|
applyTheme(isDark);
|
|
localStorage.setItem('theme', isDark ? 'dark' : 'light');
|
|
});
|
|
|
|
// ── Toggle lihat/sembunyikan password ──
|
|
const passInput = document.getElementById('pass');
|
|
const eyeIcon = document.getElementById('pass-eye-icon');
|
|
|
|
document.getElementById('btn-toggle-pass').addEventListener('click', () => {
|
|
const isHidden = passInput.type === 'password';
|
|
passInput.type = isHidden ? 'text' : 'password';
|
|
eyeIcon.className = isHidden ? 'fa-regular fa-eye-slash' : 'fa-regular fa-eye';
|
|
});
|
|
|
|
// Enter key support
|
|
passInput.addEventListener('keydown', (e) => { if (e.key === 'Enter') btn.click(); });
|
|
|
|
// ── Login logic ──
|
|
const btn = document.getElementById('btn-login');
|
|
const msg = document.getElementById('msg');
|
|
|
|
btn.addEventListener('click', async () => {
|
|
const userIn = document.getElementById('user').value.trim();
|
|
const passIn = passInput.value;
|
|
msg.innerText = '';
|
|
|
|
if (!userIn || !passIn) { msg.innerText = '⚠️ Username dan Password wajib diisi!'; return; }
|
|
|
|
btn.disabled = true;
|
|
btn.innerHTML = '<i class="fa-solid fa-spinner fa-spin"></i> Masuk...';
|
|
|
|
try {
|
|
const snap = await get(ref(db, 'smart_donation_box/users/admin'));
|
|
const data = snap.val();
|
|
|
|
if (data && data.username === userIn && data.password === passIn) {
|
|
localStorage.setItem('isLoggedIn', 'true');
|
|
window.location.href = 'index.html';
|
|
} else {
|
|
msg.innerText = '⚠️ Username atau Password salah!';
|
|
btn.disabled = false;
|
|
btn.innerHTML = 'Login <i class="fa-solid fa-arrow-right-to-bracket"></i>';
|
|
}
|
|
} catch (err) {
|
|
msg.innerText = '❌ Gagal terhubung ke server. Coba lagi.';
|
|
btn.disabled = false;
|
|
btn.innerHTML = 'Login <i class="fa-solid fa-arrow-right-to-bracket"></i>';
|
|
}
|
|
});
|
|
</script>
|
|
</body>
|
|
</html> |