add files

This commit is contained in:
luthfihadinugroho79
2026-06-10 19:42:59 +07:00
parent 7bf3c98e59
commit e950468760
3541 changed files with 0 additions and 0 deletions
+436
View File
@@ -0,0 +1,436 @@
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Masuk WebGIS Pontianak</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Sora:wght@300;400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
<style>
:root {
--bg: #080c14;
--surface: #0f1522;
--card: #141b2d;
--border: rgba(99,179,237,0.12);
--accent: #3b82f6;
--accent2: #06b6d4;
--gold: #f59e0b;
--green: #10b981;
--red: #ef4444;
--text: #e2e8f0;
--text2: #7c93b5;
--glow: rgba(59,130,246,0.25);
}
*{box-sizing:border-box;margin:0;padding:0}
body{
font-family:'Sora',sans-serif;
background:var(--bg);
color:var(--text);
min-height:100vh;
display:flex;
align-items:center;
justify-content:center;
overflow:hidden;
position:relative;
}
/* Animated background */
.bg-grid{
position:fixed;inset:0;
background-image:
linear-gradient(rgba(59,130,246,0.04) 1px,transparent 1px),
linear-gradient(90deg,rgba(59,130,246,0.04) 1px,transparent 1px);
background-size:40px 40px;
animation:gridMove 20s linear infinite;
}
@keyframes gridMove{ to{background-position:40px 40px} }
.bg-orb{
position:fixed;
border-radius:50%;
filter:blur(80px);
pointer-events:none;
}
.orb1{width:600px;height:600px;background:rgba(59,130,246,0.08);top:-200px;right:-100px;animation:orbFloat 12s ease-in-out infinite;}
.orb2{width:400px;height:400px;background:rgba(6,182,212,0.06);bottom:-100px;left:-100px;animation:orbFloat 15s ease-in-out infinite reverse;}
.orb3{width:300px;height:300px;background:rgba(245,158,11,0.04);top:50%;left:50%;transform:translate(-50%,-50%);animation:orbFloat 18s ease-in-out infinite 3s;}
@keyframes orbFloat{0%,100%{transform:translate(0,0)}50%{transform:translate(30px,-30px)}}
/* Floating particles */
.particles{position:fixed;inset:0;pointer-events:none}
.particle{
position:absolute;
width:2px;height:2px;
background:var(--accent);
border-radius:50%;
opacity:0;
animation:particleFly 8s ease-in infinite;
}
@keyframes particleFly{
0%{opacity:0;transform:translateY(100vh) scale(0)}
10%{opacity:0.6}
90%{opacity:0.2}
100%{opacity:0;transform:translateY(-20px) scale(1)}
}
/* Main container */
.login-wrap{
position:relative;z-index:10;
display:grid;
grid-template-columns:1fr 1fr;
max-width:900px;width:95%;
min-height:560px;
border-radius:24px;
overflow:hidden;
box-shadow:0 40px 80px rgba(0,0,0,0.6), 0 0 0 1px var(--border);
animation:wrapIn 0.8s cubic-bezier(0.23,1,0.32,1) both;
}
@keyframes wrapIn{from{opacity:0;transform:translateY(30px) scale(0.97)}to{opacity:1;transform:none}}
/* Left panel */
.login-hero{
background:linear-gradient(135deg,#0d1929 0%,#0a1628 50%,#060e1a 100%);
padding:52px 48px;
display:flex;flex-direction:column;justify-content:space-between;
position:relative;overflow:hidden;
}
.hero-map{
position:absolute;inset:0;opacity:0.15;
background-image:radial-gradient(circle at 30% 60%, var(--accent) 0%, transparent 50%);
}
.hero-dots{
position:absolute;inset:0;
background-image:radial-gradient(circle,rgba(59,130,246,0.4) 1px,transparent 1px);
background-size:24px 24px;
opacity:0.3;
}
.brand{position:relative;z-index:2}
.brand-icon{
width:56px;height:56px;
background:linear-gradient(135deg,var(--accent),var(--accent2));
border-radius:16px;
display:flex;align-items:center;justify-content:center;
font-size:26px;
margin-bottom:20px;
box-shadow:0 8px 32px var(--glow);
}
.brand-name{font-size:22px;font-weight:800;letter-spacing:-0.5px;line-height:1.2}
.brand-sub{font-size:12px;color:var(--text2);margin-top:4px;letter-spacing:0.5px}
.hero-stats{
position:relative;z-index:2;
display:flex;flex-direction:column;gap:12px;
}
.hero-stat{
display:flex;align-items:center;gap:12px;
padding:12px 16px;
background:rgba(255,255,255,0.04);
border:1px solid rgba(255,255,255,0.06);
border-radius:12px;
backdrop-filter:blur(8px);
}
.hs-icon{font-size:20px}
.hs-num{font-size:18px;font-weight:700;color:var(--accent)}
.hs-label{font-size:11px;color:var(--text2);margin-top:1px}
.hero-footer{
position:relative;z-index:2;
font-size:11px;color:rgba(124,147,181,0.6);
}
/* Right panel */
.login-form-wrap{
background:var(--card);
padding:52px 48px;
display:flex;flex-direction:column;justify-content:center;
}
.form-title{font-size:26px;font-weight:800;letter-spacing:-0.5px;margin-bottom:4px}
.form-sub{font-size:13px;color:var(--text2);margin-bottom:32px}
/* Role tabs */
.role-tabs{
display:grid;grid-template-columns:1fr 1fr 1fr;
gap:6px;margin-bottom:28px;
background:rgba(255,255,255,0.03);
border:1px solid var(--border);
border-radius:14px;padding:5px;
}
.role-tab{
padding:8px 4px;
border-radius:10px;
border:none;background:transparent;
color:var(--text2);
font-family:'Sora',sans-serif;
font-size:11px;font-weight:600;
cursor:pointer;
transition:all 0.2s;
display:flex;flex-direction:column;align-items:center;gap:3px;
}
.role-tab .tab-icon{font-size:16px}
.role-tab.active{
background:var(--accent);
color:#fff;
box-shadow:0 4px 16px var(--glow);
}
.role-tab:not(.active):hover{background:rgba(255,255,255,0.05);color:var(--text)}
/* Form fields */
.field{margin-bottom:16px}
.field label{display:block;font-size:12px;font-weight:600;color:var(--text2);margin-bottom:6px;letter-spacing:0.3px}
.field-wrap{position:relative}
.field-icon{
position:absolute;left:14px;top:50%;transform:translateY(-50%);
font-size:16px;pointer-events:none;z-index:2;
}
.field input{
width:100%;
background:rgba(255,255,255,0.04);
border:1px solid var(--border);
color:var(--text);
padding:12px 14px 12px 42px;
border-radius:12px;
font-family:'Sora',sans-serif;
font-size:14px;
transition:all 0.2s;
outline:none;
}
.field input:focus{
border-color:var(--accent);
background:rgba(59,130,246,0.06);
box-shadow:0 0 0 3px var(--glow);
}
.field input::placeholder{color:rgba(124,147,181,0.4)}
.toggle-pw{
position:absolute;right:14px;top:50%;transform:translateY(-50%);
background:none;border:none;color:var(--text2);cursor:pointer;
font-size:16px;padding:2px;
}
.error-msg{
background:rgba(239,68,68,0.1);
border:1px solid rgba(239,68,68,0.3);
color:#fca5a5;
padding:10px 14px;border-radius:10px;
font-size:12px;margin-bottom:16px;
display:none;
}
.error-msg.show{display:block}
.btn-login{
width:100%;padding:14px;
background:linear-gradient(135deg,var(--accent),var(--accent2));
border:none;border-radius:12px;
color:#fff;
font-family:'Sora',sans-serif;
font-size:14px;font-weight:700;
cursor:pointer;
transition:all 0.2s;
box-shadow:0 8px 24px var(--glow);
position:relative;overflow:hidden;
}
.btn-login:hover{transform:translateY(-1px);box-shadow:0 12px 32px var(--glow)}
.btn-login:active{transform:translateY(0)}
.btn-login:disabled{opacity:0.6;cursor:not-allowed;transform:none}
.btn-login .spinner{
display:inline-block;width:16px;height:16px;
border:2px solid rgba(255,255,255,0.3);
border-top-color:#fff;
border-radius:50%;
animation:spin 0.7s linear infinite;
vertical-align:middle;margin-right:6px;
}
@keyframes spin{to{transform:rotate(360deg)}}
.form-links{
margin-top:20px;text-align:center;
font-size:12px;color:var(--text2);
}
.form-links a{color:var(--accent);text-decoration:none;font-weight:600}
.form-links a:hover{text-decoration:underline}
.register-hint{
margin-top:12px;
padding:12px;
background:rgba(16,185,129,0.06);
border:1px solid rgba(16,185,129,0.2);
border-radius:10px;
font-size:11px;color:rgba(16,185,129,0.8);
text-align:center;
}
@media(max-width:700px){
.login-wrap{grid-template-columns:1fr}
.login-hero{display:none}
}
</style>
</head>
<body>
<div class="bg-grid"></div>
<div class="bg-orb orb1"></div>
<div class="bg-orb orb2"></div>
<div class="bg-orb orb3"></div>
<div class="particles" id="particles"></div>
<div class="login-wrap">
<!-- Left hero -->
<div class="login-hero">
<div class="hero-map"></div>
<div class="hero-dots"></div>
<div class="brand">
<div class="brand-icon">🗺️</div>
<div class="brand-name">WebGIS Pontianak</div>
<div class="brand-sub">SISTEM PENDUDUK MISKIN TERINTEGRASI</div>
</div>
<div class="hero-stats">
<div class="hero-stat">
<div class="hs-icon">🏘️</div>
<div>
<div class="hs-num" id="h-kk"></div>
<div class="hs-label">Kepala Keluarga Terdaftar</div>
</div>
</div>
<div class="hero-stat">
<div class="hs-icon">🕌</div>
<div>
<div class="hs-num" id="h-ibadah"></div>
<div class="hs-label">Rumah Ibadah Aktif</div>
</div>
</div>
<div class="hero-stat">
<div class="hs-icon">🤝</div>
<div>
<div class="hs-num" id="h-bantuan"></div>
<div class="hs-label">Bantuan Tersalurkan</div>
</div>
</div>
</div>
<div class="hero-footer">© 2025 Pemerintah Kota Pontianak · WebGIS v2.0</div>
</div>
<!-- Right form -->
<div class="login-form-wrap">
<div class="form-title">Selamat datang 👋</div>
<div class="form-sub">Masuk sesuai peran Anda dalam sistem</div>
<div class="role-tabs">
<button class="role-tab active" onclick="setRole('masyarakat',this)" id="tab-mas">
<span class="tab-icon">👤</span>Masyarakat
</button>
<button class="role-tab" onclick="setRole('pengurus_ibadah',this)" id="tab-pen">
<span class="tab-icon">🕌</span>Pengurus
</button>
<button class="role-tab" onclick="setRole('pemerintah',this)" id="tab-pem">
<span class="tab-icon">🏛️</span>Pemerintah
</button>
</div>
<div id="error-box" class="error-msg"></div>
<form id="login-form" onsubmit="doLogin(event)">
<input type="hidden" id="role-input" value="masyarakat">
<div class="field">
<label>USERNAME / NO. HP</label>
<div class="field-wrap">
<span class="field-icon">👤</span>
<input type="text" id="username" placeholder="Masukkan username Anda" autocomplete="username" required>
</div>
</div>
<div class="field">
<label>KATA SANDI</label>
<div class="field-wrap">
<span class="field-icon">🔒</span>
<input type="password" id="password" placeholder="••••••••" autocomplete="current-password" required>
<button type="button" class="toggle-pw" onclick="togglePw()">👁️</button>
</div>
</div>
<button type="submit" class="btn-login" id="btn-login">Masuk ke Sistem</button>
</form>
<div class="form-links">
Belum punya akun? <a href="daftar.php">Daftar sebagai Masyarakat / Pengurus Rumah Ibadah</a>
</div>
<div class="register-hint" id="role-hint">
Masyarakat dapat mendaftar mandiri dan melaporkan kejadian di sekitar mereka.
</div>
</div>
</div>
<script>
// Particles
const pWrap = document.getElementById('particles');
for(let i=0;i<25;i++){
const p=document.createElement('div');
p.className='particle';
p.style.cssText=`left:${Math.random()*100}%;animation-delay:${Math.random()*8}s;animation-duration:${6+Math.random()*6}s;opacity:${Math.random()*0.5}`;
pWrap.appendChild(p);
}
// Load stats
fetch('api/auth.php?action=stats')
.then(r=>r.json()).then(d=>{
document.getElementById('h-kk').textContent=d.kk??'—';
document.getElementById('h-ibadah').textContent=d.ibadah??'—';
document.getElementById('h-bantuan').textContent=d.bantuan??'—';
}).catch(()=>{});
const hints={
masyarakat:'Masyarakat dapat mendaftar mandiri dan melaporkan kejadian di sekitar mereka.',
pengurus_ibadah:'Pengurus rumah ibadah mengelola data bantuan dan laporan warga binaan.',
pemerintah:'Pemerintah mendapat akses read-only untuk memantau semua data dan statistik.'
};
function setRole(role,el){
document.querySelectorAll('.role-tab').forEach(t=>t.classList.remove('active'));
el.classList.add('active');
document.getElementById('role-input').value=role;
document.getElementById('role-hint').textContent=hints[role]||'';
}
function togglePw(){
const i=document.getElementById('password');
i.type=i.type==='password'?'text':'password';
}
async function doLogin(e){
e.preventDefault();
const btn=document.getElementById('btn-login');
const errBox=document.getElementById('error-box');
btn.disabled=true;
btn.innerHTML='<span class="spinner"></span>Memverifikasi...';
errBox.classList.remove('show');
const body={
username:document.getElementById('username').value,
password:document.getElementById('password').value,
role:document.getElementById('role-input').value
};
try{
const res=await fetch('api/auth.php',{
method:'POST',
headers:{'Content-Type':'application/json'},
body:JSON.stringify(body)
});
const data=await res.json();
if(data.success){
btn.innerHTML='✅ Berhasil! Mengalihkan...';
window.location.href=data.redirect||'index.php';
} else {
errBox.textContent=data.error||'Username atau kata sandi salah.';
errBox.classList.add('show');
btn.disabled=false;
btn.innerHTML='Masuk ke Sistem';
}
} catch(err){
errBox.textContent='Terjadi kesalahan. Periksa koneksi Anda.';
errBox.classList.add('show');
btn.disabled=false;
btn.innerHTML='Masuk ke Sistem';
}
}
</script>
</body>
</html>