Initial commit - CMS Gov Bapenda Garut dengan EditorJS
This commit is contained in:
331
app/Views/auth/login.php
Normal file
331
app/Views/auth/login.php
Normal file
@@ -0,0 +1,331 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
|
||||
/>
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
||||
<meta name="csrf-token" content="<?= csrf_hash() ?>" />
|
||||
<meta name="csrf-header" content="<?= csrf_header() ?>" />
|
||||
<title>Sign In - Bapenda Garut</title>
|
||||
<link rel="icon" type="image/png" href="<?= base_url('assets/images/favicon_1762970389090.png') ?>" />
|
||||
<link rel="shortcut icon" type="image/png" href="<?= base_url('assets/images/favicon_1762970389090.png') ?>" />
|
||||
<link rel="stylesheet" href="<?= base_url('assets/css/app.css') ?>">
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
|
||||
</head>
|
||||
<body
|
||||
x-data="{ page: 'comingSoon', 'loaded': true, 'darkMode': false, 'stickyMenu': false, 'sidebarToggle': false, 'scrollTop': false, 'showPassword': false }"
|
||||
x-init="
|
||||
darkMode = JSON.parse(localStorage.getItem('darkMode') || 'false');
|
||||
$watch('darkMode', value => localStorage.setItem('darkMode', JSON.stringify(value)))"
|
||||
:class="{'dark bg-gray-900': darkMode === true}"
|
||||
>
|
||||
<!-- ===== Page Wrapper Start ===== -->
|
||||
<div class="relative p-6 bg-white z-1 dark:bg-gray-900 sm:p-0">
|
||||
<div
|
||||
class="relative flex flex-col justify-center w-full h-screen dark:bg-gray-900 sm:p-0 lg:flex-row"
|
||||
>
|
||||
<!-- Form -->
|
||||
<div class="flex flex-col flex-1 w-full lg:w-1/2">
|
||||
<div class="w-full max-w-md pt-10 mx-auto">
|
||||
<a
|
||||
href="<?= base_url('/') ?>"
|
||||
class="inline-flex items-center text-sm text-gray-500 transition-colors hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300"
|
||||
>
|
||||
<i class="fe fe-arrow-left"></i>
|
||||
<span class="ml-2">Kembali ke Beranda</span>
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
class="flex flex-col justify-center flex-1 w-full max-w-md mx-auto"
|
||||
>
|
||||
<div>
|
||||
<div class="mb-5 sm:mb-8">
|
||||
<h1
|
||||
class="mb-2 font-semibold text-gray-800 text-title-sm dark:text-white/90 sm:text-title-md"
|
||||
>
|
||||
Sign In
|
||||
</h1>
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">
|
||||
Masukkan username dan password anda!
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Flash Messages -->
|
||||
<?php if (session()->getFlashdata('error')): ?>
|
||||
<div class="mb-4 p-4 rounded-lg border border-error-200 bg-error-50 dark:border-error-800 dark:bg-error-900/20 shadow-theme-sm">
|
||||
<div class="flex items-start gap-3">
|
||||
<div class="flex-shrink-0">
|
||||
<div class="flex items-center justify-center w-5 h-5 rounded-full bg-error-100 dark:bg-error-900/40">
|
||||
<i class="fe fe-alert-circle text-error-600 dark:text-error-400 text-sm"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<p class="text-sm font-semibold text-error-800 dark:text-error-200">
|
||||
<?= esc(session()->getFlashdata('error')) ?>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (session()->getFlashdata('success')): ?>
|
||||
<div class="mb-4 p-4 rounded-lg border border-green-200 bg-green-50 dark:border-green-800 dark:bg-green-900/20 shadow-theme-sm">
|
||||
<div class="flex items-start gap-3">
|
||||
<div class="flex-shrink-0">
|
||||
<div class="flex items-center justify-center w-5 h-5 rounded-full bg-green-100 dark:bg-green-900/40">
|
||||
<i class="fe fe-check-circle text-green-600 dark:text-green-400 text-sm"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<p class="text-sm font-semibold text-green-800 dark:text-green-200">
|
||||
<?= esc(session()->getFlashdata('success')) ?>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Validation Errors -->
|
||||
<?php if (isset($validation) && !empty($validation->getErrors())): ?>
|
||||
<?php foreach ($validation->getErrors() as $field => $error): ?>
|
||||
<div class="mb-4 p-4 rounded-lg border border-error-200 bg-error-50 dark:border-error-800 dark:bg-error-900/20 shadow-theme-sm">
|
||||
<div class="flex items-start gap-3">
|
||||
<div class="flex-shrink-0">
|
||||
<div class="flex items-center justify-center w-5 h-5 rounded-full bg-error-100 dark:bg-error-900/40">
|
||||
<i class="fe fe-alert-circle text-error-600 dark:text-error-400 text-sm"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<p class="text-sm font-semibold text-error-800 dark:text-error-200">
|
||||
<?= esc($error) ?>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php
|
||||
$hasValidationErrors = isset($validation) && !empty($validation->getErrors());
|
||||
if (isset($error) && !empty($error) && !$hasValidationErrors):
|
||||
?>
|
||||
<div class="mb-4 p-4 rounded-lg border border-error-200 bg-error-50 dark:border-error-800 dark:bg-error-900/20 shadow-theme-sm">
|
||||
<div class="flex items-start gap-3">
|
||||
<div class="flex-shrink-0">
|
||||
<div class="flex items-center justify-center w-5 h-5 rounded-full bg-error-100 dark:bg-error-900/40">
|
||||
<i class="fe fe-alert-circle text-error-600 dark:text-error-400 text-sm"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<p class="text-sm font-semibold text-error-800 dark:text-error-200">
|
||||
<?= esc($error) ?>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Debug: Always show this to test styling -->
|
||||
<?php if (isset($_GET['debug'])): ?>
|
||||
<div class="mb-4 p-4 rounded-lg border-2 border-error-500 bg-error-50 dark:border-error-500 dark:bg-error-900/30">
|
||||
<p class="text-sm font-medium text-error-800 dark:text-error-300">
|
||||
<i class="fe fe-alert-circle mr-2"></i>
|
||||
DEBUG: Error message styling test - If you see this, styling works!
|
||||
</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Test: Always show error message for debugging (REMOVE AFTER TESTING) -->
|
||||
<!--
|
||||
<div class="mb-4 p-4 rounded-lg border-2 border-error-500 bg-error-50 dark:border-error-500 dark:bg-error-900/30" style="display: block !important; background: #fee2e2 !important; border-color: #ef4444 !important;">
|
||||
<p class="text-sm font-medium text-error-800 dark:text-error-300" style="color: #991b1b !important;">
|
||||
<i class="fe fe-alert-circle mr-2"></i>
|
||||
TEST: Error message test - Jika ini muncul, styling bekerja!
|
||||
</p>
|
||||
</div>
|
||||
-->
|
||||
|
||||
<form action="<?= base_url('auth/login') ?>" method="POST" id="loginForm">
|
||||
<?= csrf_field() ?>
|
||||
<div class="space-y-5">
|
||||
<!-- Username -->
|
||||
<div>
|
||||
<label
|
||||
class="mb-1.5 block text-sm font-medium text-gray-700 dark:text-gray-400"
|
||||
>
|
||||
Username<span class="text-error-500">*</span>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="username"
|
||||
name="username"
|
||||
value="<?= old('username') ?>"
|
||||
placeholder="Masukkan username"
|
||||
class="dark:bg-dark-900 h-11 w-full rounded-lg border border-gray-300 bg-transparent px-4 py-2.5 text-sm text-gray-800 shadow-theme-xs placeholder:text-gray-400 focus:border-brand-300 focus:outline-hidden focus:ring-3 focus:ring-brand-500/10 dark:border-gray-700 dark:bg-gray-900 dark:text-white/90 dark:placeholder:text-white/30 dark:focus:border-brand-800"
|
||||
required
|
||||
autofocus
|
||||
/>
|
||||
<?php if (isset($validation) && $validation->hasError('username')): ?>
|
||||
<p class="mt-1 text-sm text-error-600"><?= esc($validation->getError('username')) ?></p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<!-- Password -->
|
||||
<div>
|
||||
<label
|
||||
class="mb-1.5 block text-sm font-medium text-gray-700 dark:text-gray-400"
|
||||
>
|
||||
Password<span class="text-error-500">*</span>
|
||||
</label>
|
||||
<div x-data="{ showPassword: false }" class="relative">
|
||||
<input
|
||||
:type="showPassword ? 'text' : 'password'"
|
||||
id="password"
|
||||
name="password"
|
||||
placeholder="Masukkan password"
|
||||
class="dark:bg-dark-900 h-11 w-full rounded-lg border border-gray-300 bg-transparent py-2.5 pl-4 pr-11 text-sm text-gray-800 shadow-theme-xs placeholder:text-gray-400 focus:border-brand-300 focus:outline-hidden focus:ring-3 focus:ring-brand-500/10 dark:border-gray-700 dark:bg-gray-900 dark:text-white/90 dark:placeholder:text-white/30 dark:focus:border-brand-800"
|
||||
required
|
||||
/>
|
||||
<span
|
||||
@click="showPassword = !showPassword"
|
||||
class="absolute z-30 text-gray-500 -translate-y-1/2 cursor-pointer right-4 top-1/2 dark:text-gray-400"
|
||||
>
|
||||
<i x-show="!showPassword" class="fe fe-eye text-lg"></i>
|
||||
<i x-show="showPassword" class="fe fe-eye-off text-lg"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Checkbox -->
|
||||
<div class="flex items-center justify-between">
|
||||
<div x-data="{ checkboxToggle: false }">
|
||||
<label
|
||||
for="checkboxLabelOne"
|
||||
class="flex items-center text-sm font-normal text-gray-700 cursor-pointer select-none dark:text-gray-400"
|
||||
>
|
||||
<div class="relative">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="checkboxLabelOne"
|
||||
name="remember"
|
||||
class="sr-only"
|
||||
@change="checkboxToggle = !checkboxToggle"
|
||||
/>
|
||||
<div
|
||||
:class="checkboxToggle ? 'border-brand-500 bg-brand-500' : 'bg-transparent border-gray-300 dark:border-gray-700'"
|
||||
class="mr-3 flex h-5 w-5 items-center justify-center rounded-md border-[1.25px]"
|
||||
>
|
||||
<span :class="checkboxToggle ? '' : 'opacity-0'">
|
||||
<i class="fe fe-check text-white text-xs"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
biarkan tetap masuk
|
||||
</label>
|
||||
</div>
|
||||
<a
|
||||
href="#"
|
||||
class="text-sm text-brand-500 hover:text-brand-600 dark:text-brand-400"
|
||||
>lupa password?</a
|
||||
>
|
||||
</div>
|
||||
<!-- Button -->
|
||||
<div>
|
||||
<button
|
||||
type="submit"
|
||||
class="flex items-center justify-center w-full px-4 py-3 text-sm font-medium text-white transition rounded-lg bg-brand-500 shadow-theme-xs hover:bg-brand-600"
|
||||
>
|
||||
Sign In
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="relative items-center hidden w-full h-full bg-brand-950 dark:bg-white/5 lg:grid lg:w-1/2"
|
||||
>
|
||||
<div class="flex items-center justify-center z-1">
|
||||
<!-- ===== Common Grid Shape Start ===== -->
|
||||
<div class="absolute right-0 top-0 -z-1 w-full max-w-[250px] xl:max-w-[450px]">
|
||||
<img src="<?= base_url('assets/images/shape/grid-01.svg') ?>" alt="grid" />
|
||||
</div>
|
||||
<div
|
||||
class="absolute bottom-0 left-0 -z-1 w-full max-w-[250px] rotate-180 xl:max-w-[450px]"
|
||||
>
|
||||
<img src="<?= base_url('assets/images/shape/grid-01.svg') ?>" alt="grid" />
|
||||
</div>
|
||||
<!-- ===== Common Grid Shape End ===== -->
|
||||
<div class="flex flex-col items-center max-w-xs relative z-10">
|
||||
<div class="flex items-center gap-3 mb-4">
|
||||
<a href="<?= base_url('/') ?>" class="block">
|
||||
<img src="<?= base_url('assets/images/logo/b_logo_1757803697487.png') ?>" alt="Logo Bapenda Garut" class="h-12 w-auto" />
|
||||
</a>
|
||||
<h2 class="text-2xl font-bold text-gray-400 dark:text-white">Bapenda Garut</h2>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Toggler -->
|
||||
<div class="fixed z-50 hidden bottom-6 right-6 sm:block">
|
||||
<button
|
||||
class="inline-flex items-center justify-center text-white transition-colors rounded-full w-14 h-14 bg-brand-500 hover:bg-brand-600"
|
||||
@click.prevent="darkMode = !darkMode"
|
||||
>
|
||||
<i class="fe fe-sun text-lg hidden dark:block"></i>
|
||||
<i class="fe fe-moon text-lg dark:hidden"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ===== Page Wrapper End ===== -->
|
||||
|
||||
<script>
|
||||
// Debug form submission
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const form = document.getElementById('loginForm');
|
||||
if (form) {
|
||||
form.addEventListener('submit', function(e) {
|
||||
console.log('=== FORM SUBMISSION DEBUG ===');
|
||||
console.log('Form action:', this.action);
|
||||
console.log('Form method:', this.method);
|
||||
const formData = new FormData(this);
|
||||
const username = formData.get('username');
|
||||
const password = formData.get('password');
|
||||
console.log('Username:', username || 'EMPTY!');
|
||||
console.log('Password:', password ? '***filled***' : 'EMPTY!');
|
||||
|
||||
// Check CSRF token
|
||||
const csrfToken = formData.get('<?= csrf_token() ?>');
|
||||
console.log('CSRF token:', csrfToken ? 'exists' : 'MISSING!');
|
||||
|
||||
// Prevent submission if empty
|
||||
if (!username || !password) {
|
||||
console.error('ERROR: Username or password is empty!');
|
||||
alert('Username dan password harus diisi!');
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
console.log('Form will be submitted...');
|
||||
console.log('===========================');
|
||||
});
|
||||
} else {
|
||||
console.error('ERROR: Login form not found!');
|
||||
}
|
||||
|
||||
// Check if error message exists
|
||||
const errorDiv = document.querySelector('[class*="error-"]');
|
||||
if (errorDiv) {
|
||||
console.log('Error message div found:', errorDiv.textContent);
|
||||
} else {
|
||||
console.log('No error message div found');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user