Production readiness hardening and ops tooling

This commit is contained in:
2026-05-29 10:10:12 +07:00
parent e0b8f9af9a
commit 648e77cee9
68 changed files with 12222 additions and 848 deletions

View File

@ -139,12 +139,12 @@
<p class="font-body-lg text-body-lg text-on-surface-variant">Selamat datang kembali. Silakan masuk untuk mengelola transaksi Anda.</p>
</div>
<!-- Login Form -->
<form class="space-y-6" onsubmit="event.preventDefault();">
<form id="merchant-login-form" class="space-y-6">
<div>
<label class="block font-label-md text-label-md text-on-surface-variant mb-2 ml-1" for="email">Email Bisnis</label>
<label class="block font-label-md text-label-md text-on-surface-variant mb-2 ml-1" for="email">Merchant ID / Code</label>
<div class="relative group">
<span class="material-symbols-outlined absolute left-4 top-1/2 -translate-y-1/2 text-outline group-focus-within:text-primary transition-colors">mail</span>
<input class="w-full pl-12 pr-4 py-3.5 bg-surface-container-lowest border border-slate-200 rounded-xl focus:ring-2 focus:ring-primary focus:border-transparent outline-none transition-all placeholder:text-slate-500 font-body-md text-on-surface" id="email" name="email" placeholder="nama@bisnisanda.com" type="email"/>
<span class="material-symbols-outlined absolute left-4 top-1/2 -translate-y-1/2 text-outline group-focus-within:text-primary transition-colors">storefront</span>
<input class="w-full pl-12 pr-4 py-3.5 bg-surface-container-lowest border border-slate-200 rounded-xl focus:ring-2 focus:ring-primary focus:border-transparent outline-none transition-all placeholder:text-slate-500 font-body-md text-on-surface" id="email" name="email" placeholder="merchant id atau m_xxxxxx" type="text" required/>
</div>
</div>
<div>
@ -154,7 +154,7 @@
</div>
<div class="relative group">
<span class="material-symbols-outlined absolute left-4 top-1/2 -translate-y-1/2 text-outline group-focus-within:text-primary transition-colors">lock</span>
<input class="w-full pl-12 pr-12 py-3.5 bg-surface-container-lowest border border-slate-200 rounded-xl focus:ring-2 focus:ring-primary focus:border-transparent outline-none transition-all placeholder:text-slate-500 font-body-md text-on-surface" id="password" name="password" placeholder="••••••••" type="password"/>
<input class="w-full pl-12 pr-12 py-3.5 bg-surface-container-lowest border border-slate-200 rounded-xl focus:ring-2 focus:ring-primary focus:border-transparent outline-none transition-all placeholder:text-slate-500 font-body-md text-on-surface" id="password" name="password" placeholder="••••••••" type="password" required/>
<button class="absolute right-4 top-1/2 -translate-y-1/2 text-outline hover:text-on-surface transition-colors" type="button">
<span class="material-symbols-outlined">visibility</span>
</button>
@ -164,6 +164,7 @@
<input class="w-4 h-4 text-primary bg-surface-container-lowest border-slate-200 rounded focus:ring-primary" id="remember" type="checkbox"/>
<label class="ml-2 font-body-md text-body-md text-on-surface-variant" for="remember">Ingat saya selama 30 hari</label>
</div>
<p id="merchant-login-feedback" class="text-danger text-sm hidden"></p>
<button class="w-full py-4 bg-primary hover:bg-surface-tint text-on-primary font-headline-md text-headline-md rounded-xl shadow-lg shadow-primary/20 active:scale-[0.98] transition-all flex justify-center items-center gap-2" type="submit">
<span>Merchant Sign In</span>
<span class="material-symbols-outlined">login</span>
@ -254,6 +255,7 @@
<a class="font-label-md text-label-md text-primary" href="#">Syarat Layanan</a>
</div>
</footer>
<script src="/ui/shared/merchant-api.js"></script>
<script>
// Simple micro-interactions
document.querySelectorAll('input').forEach(input => {
@ -273,6 +275,23 @@
passInput.setAttribute('type', type);
toggleBtn.querySelector('span').innerText = type === 'password' ? 'visibility' : 'visibility_off';
});
const form = document.getElementById('merchant-login-form');
const feedback = document.getElementById('merchant-login-feedback');
form.addEventListener('submit', async (event) => {
event.preventDefault();
feedback.classList.add('hidden');
try {
await MerchantUIAPI.login({
username: document.getElementById('email').value.trim(),
password: document.getElementById('password').value
});
window.location.href = '/ui/merchant-settlement-history';
} catch (error) {
feedback.textContent = error.message || 'Unable to sign in';
feedback.classList.remove('hidden');
}
});
</script>
<!-- ui-nav -->
<div id="__sb_nav" style="position:fixed;left:16px;bottom:16px;z-index:9999;background:#fff;border:1px solid #e2e8f0;padding:8px 10px;border-radius:8px;box-shadow:0 6px 24px rgba(15,23,42,0.12);font-family:Inter,Arial,sans-serif;font-size:12px;line-height:1.4">
@ -283,4 +302,4 @@
<a href="/ui/admin-dashboard-overview" style="margin-right:0;color:#2563eb;text-decoration:none;font-weight:600">Dashboard</a>
</div>
'
</body></html>
</body></html>