107 lines
5.4 KiB
Plaintext
107 lines
5.4 KiB
Plaintext
<#import "template.ftl" as layout>
|
|
<@layout.registrationLayout displayMessage=!messagesPerField.existsError('username','password') displayInfo=realm.password && realm.registrationAllowed && !registrationDisabled??; section>
|
|
<#if section = "header">
|
|
${msg("loginAccountTitle")}
|
|
<#elseif section = "form">
|
|
<div id="kc-form">
|
|
<div id="kc-form-wrapper">
|
|
|
|
<div class="login-container">
|
|
<div class="login-card">
|
|
<!-- Logo -->
|
|
<div class="logo-section">
|
|
<img src="${url.resourcesPath}/img/rssa-logo.webp" alt="RSSA Logo" class="login-logo" />
|
|
</div>
|
|
|
|
<!-- Title -->
|
|
<h1 class="login-heading">RSSA Login</h1>
|
|
<p class="login-subtitle">Masukkan akses Anda untuk melanjutkan</p>
|
|
|
|
<!-- Alert Messages -->
|
|
<#if message?has_content && (message.type != 'warning' || !isAppInitiatedAction??)>
|
|
<div class="alert alert-${message.type}">
|
|
<#if message.type = 'success'><span class="pficon pficon-ok"></span></#if>
|
|
<#if message.type = 'warning'><span class="pficon pficon-warning-triangle-o"></span></#if>
|
|
<#if message.type = 'error'></span></#if>
|
|
<#if message.type = 'info'><span class="pficon pficon-info"></span></#if>
|
|
<span class="kc-feedback-text">${kcSanitize(message.summary)?no_esc}</span>
|
|
</div>
|
|
</#if>
|
|
|
|
<!-- Login Form -->
|
|
<form id="kc-form-login" onsubmit="login.disabled = true; return true;" action="${url.loginAction}" method="post">
|
|
|
|
<!-- Username Field -->
|
|
<div class="form-group">
|
|
<input tabindex="1"
|
|
id="username"
|
|
class="form-control"
|
|
name="username"
|
|
value="${(login.username!'')}"
|
|
type="text"
|
|
autofocus
|
|
autocomplete="off"
|
|
aria-invalid="<#if messagesPerField.existsError('username','password')>true</#if>"
|
|
placeholder="Username atau alamat email"
|
|
/>
|
|
</div>
|
|
|
|
<!-- Password Field -->
|
|
<div class="form-group">
|
|
<div class="password-wrapper">
|
|
<input tabindex="2"
|
|
id="password"
|
|
class="form-control"
|
|
name="password"
|
|
type="password"
|
|
autocomplete="off"
|
|
aria-invalid="<#if messagesPerField.existsError('username','password')>true</#if>"
|
|
placeholder="Kata sandi"
|
|
/>
|
|
<button type="button" class="password-toggle" onclick="togglePassword()" aria-label="Toggle password visibility">
|
|
<svg class="eye-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
|
|
<circle cx="12" cy="12" r="3"></circle>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Forgot Password -->
|
|
<#if realm.resetPasswordAllowed>
|
|
<div class="forgot-password">
|
|
<a tabindex="5" href="${url.loginResetCredentialsUrl}">Lupa Kata sandi</a>
|
|
</div>
|
|
</#if>
|
|
|
|
<!-- Login Button -->
|
|
<div class="form-actions">
|
|
<input type="hidden" id="id-hidden-input" name="credentialId" <#if auth.selectedCredential?has_content>value="${auth.selectedCredential}"</#if>/>
|
|
<button tabindex="4" class="btn-login" name="login" id="kc-login" type="submit">
|
|
Login
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
function togglePassword() {
|
|
var passwordInput = document.getElementById('password');
|
|
var eyeIcon = document.querySelector('.eye-icon');
|
|
if (passwordInput.type === 'password') {
|
|
passwordInput.type = 'text';
|
|
eyeIcon.innerHTML = '<path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"></path><line x1="1" y1="1" x2="23" y2="23"></line>';
|
|
} else {
|
|
passwordInput.type = 'password';
|
|
eyeIcon.innerHTML = '<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path><circle cx="12" cy="12" r="3"></circle>';
|
|
}
|
|
}
|
|
</script>
|
|
|
|
</#if>
|
|
</@layout.registrationLayout>
|