eSPJ/Views/Login/Index.cshtml

277 lines
12 KiB
Plaintext

@{
ViewData["Title"] = "Login eSPJ";
}
<div class="bg-gradient-to-br from-indigo-50 via-white to-purple-50">
<div class="max-w-sm mx-auto bg-white min-h-screen shadow-xl relative overflow-hidden">
<!-- Background Pattern -->
<div class="absolute inset-0 opacity-5">
<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="grid" width="20" height="20" patternUnits="userSpaceOnUse">
<path d="M 20 0 L 0 0 0 20" fill="none" stroke="#667eea" stroke-width="1"/>
</pattern>
</defs>
<rect width="100%" height="100%" fill="url(#grid)" />
</svg>
</div>
<!-- Splash Screens Container -->
<div id="splashContainer" class="splash-container" style="width: 400%; display: flex;">
<!-- Splash Screen 1 -->
<div class="w-1/4 flex flex-col items-center justify-center h-screen px-6 relative">
<div class="fade-in flex flex-col items-center">
<div class="icon-bg w-24 h-24 rounded-3xl flex items-center justify-center mb-6 shadow-lg">
<svg class="w-12 h-12 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path>
</svg>
</div>
<h2 class="text-2xl font-bold mb-3 text-gray-800 text-center">Selamat Datang di eSPJ</h2>
<p class="text-gray-600 text-center leading-relaxed">Aplikasi pengelolaan Surat Perjalanan Dinas yang modern dan efisien</p>
</div>
</div>
<!-- Splash Screen 2 -->
<div class="w-1/4 flex flex-col items-center justify-center h-screen px-6 relative">
<div class="fade-in flex flex-col items-center">
<div class="icon-bg w-24 h-24 rounded-3xl flex items-center justify-center mb-6 shadow-lg">
<svg class="w-12 h-12 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
</div>
<h2 class="text-2xl font-bold mb-3 text-gray-800 text-center">Mudah & Cepat</h2>
<p class="text-gray-600 text-center leading-relaxed">Proses pengajuan SPJ lebih efisien dan terintegrasi dengan sistem terbaru</p>
</div>
</div>
<!-- Splash Screen 3 -->
<div class="w-1/4 flex flex-col items-center justify-center h-screen px-6 relative">
<div class="fade-in flex flex-col items-center">
<div class="icon-bg w-24 h-24 rounded-3xl flex items-center justify-center mb-6 shadow-lg">
<svg class="w-12 h-12 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"></path>
</svg>
</div>
<h2 class="text-2xl font-bold mb-3 text-gray-800 text-center">Keamanan Data Terjamin</h2>
<p class="text-gray-600 text-center leading-relaxed">Data perjalanan dinas Anda aman dengan enkripsi tingkat enterprise</p>
</div>
</div>
<!-- Login Form -->
<div class="w-1/4 flex flex-col items-center justify-center h-screen px-6 relative">
<div class="w-full max-w-sm slide-up">
<div class="glass-effect rounded-3xl p-8 ">
<div class="text-center mb-8">
<div class="icon-bg w-16 h-16 rounded-2xl flex items-center justify-center mx-auto mb-4 shadow-lg">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"></path>
</svg>
</div>
<h2 class="text-2xl font-bold text-gray-800 mb-2">Masuk ke eSPJ</h2>
<p class="text-gray-600">Silakan masukkan kredensial Anda</p>
</div>
<div class="space-y-4">
<button class="btn-gradient w-full py-3 px-4 rounded-xl text-white font-semibold flex items-center justify-center" type="button" onclick="showSSOModal()">
<i class="w-5 h-5 mr-3" data-lucide="key"></i>
Masuk dengan SSO
</button>
<div class="flex items-center justify-center">
</div>
</div>
</div>
</div>
</div>
</div>
<div id="navigationControls" class="absolute bottom-8 left-0 right-0 px-6">
<!-- Dot Navigation -->
<div class="flex justify-center space-x-2 mb-6">
<div class="dot w-3 h-3 rounded-full transition-all duration-300 dot-active" data-slide="0"></div>
<div class="dot w-3 h-3 rounded-full transition-all duration-300 dot-inactive" data-slide="1"></div>
<div class="dot w-3 h-3 rounded-full transition-all duration-300 dot-inactive" data-slide="2"></div>
<div class="dot w-3 h-3 rounded-full transition-all duration-300 dot-inactive" data-slide="3"></div>
</div>
<!-- Next Button -->
<div class="flex justify-between items-center">
<button id="skipBtn" class="text-gray-500 hover:text-gray-700 transition-colors duration-300">Lewati</button>
<button id="nextBtn" class="btn-gradient px-8 py-3 rounded-xl text-white font-semibold transition-all duration-300">
Selanjutnya
</button>
</div>
</div>
<!-- Modal SSO -->
<div id="ssoModal" style="display:none; position:fixed; z-index:9999; top:0; left:0; width:100vw; height:100vh; background:rgba(0,0,0,0.5);">
<div style="position:relative; width:100%; height:100%;">
<iframe id="ssoIframe" src="" style="width:90vw; max-width:400px; height:70vh; max-height:600px; border-radius:16px; border:none; position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); background:#fff;"></iframe>
<button onclick="closeSSOModal()" style="position:absolute; top:20px; right:20px; z-index:10000;">Tutup</button>
</div>
</div>
</div>
</div>
@section Styles {
<style>
.splash-container {
transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1);
}
.fade-in {
animation: fadeIn 0.8s ease-out;
}
.slide-up {
animation: slideUp 0.6s ease-out;
}
@@keyframes fadeIn {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
@@keyframes slideUp {
from { opacity: 0; transform: translateY(30px); }
to { opacity: 1; transform: translateY(0); }
}
.dot-active {
background: linear-gradient(135deg, #fb923c 0%, #f59e42 100%);
transform: scale(1.2);
}
.dot-inactive {
background: #fde68a;
}
.btn-gradient {
background: linear-gradient(135deg, #fb923c 0%, #f59e42 100%);
box-shadow: 0 4px 15px rgba(251, 146, 60, 0.4);
}
.btn-gradient:hover {
box-shadow: 0 8px 25px rgba(251, 146, 60, 0.6);
transform: translateY(-2px);
}
.glass-effect {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
}
.icon-bg {
background: linear-gradient(135deg, #fb923c 0%, #f59e42 100%);
}
.form-input {
transition: all 0.3s ease;
}
.form-input:focus {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(251, 146, 60, 0.15);
}
</style>
}
@section Scripts {
<script>
let currentSlide = 0;
const totalSlides = 4;
const container = document.getElementById('splashContainer');
const dots = document.querySelectorAll('.dot');
const nextBtn = document.getElementById('nextBtn');
const skipBtn = document.getElementById('skipBtn');
const navigationControls = document.getElementById('navigationControls');
function updateSlide(slideIndex) {
container.style.transform = `translateX(-${slideIndex * 25}%)`;
dots.forEach((dot, index) => {
if (index === slideIndex) {
dot.classList.remove('dot-inactive');
dot.classList.add('dot-active');
} else {
dot.classList.remove('dot-active');
dot.classList.add('dot-inactive');
}
});
if (slideIndex === totalSlides - 1) {
navigationControls.style.display = 'none';
} else {
navigationControls.style.display = 'block';
nextBtn.textContent = slideIndex === totalSlides - 2 ? 'Masuk' : 'Selanjutnya';
}
}
function nextSlide() {
if (currentSlide < totalSlides - 1) {
currentSlide++;
updateSlide(currentSlide);
}
}
function skipToLogin() {
currentSlide = totalSlides - 1;
updateSlide(currentSlide);
}
nextBtn.addEventListener('click', nextSlide);
skipBtn.addEventListener('click', skipToLogin);
dots.forEach((dot, index) => {
dot.addEventListener('click', () => {
currentSlide = index;
updateSlide(currentSlide);
});
});
let startX = 0;
let endX = 0;
container.addEventListener('touchstart', (e) => {
startX = e.touches[0].clientX;
});
container.addEventListener('touchend', (e) => {
endX = e.changedTouches[0].clientX;
handleSwipe();
});
function handleSwipe() {
const swipeThreshold = 50;
const diff = startX - endX;
if (Math.abs(diff) > swipeThreshold) {
if (diff > 0 && currentSlide < totalSlides - 1) {
nextSlide();
} else if (diff < 0 && currentSlide > 0) {
currentSlide--;
updateSlide(currentSlide);
}
}
}
</script>
<script>
function showSSOModal() {
document.getElementById('ssoIframe').src = '@ViewBag.SSOLoginUrl';
document.getElementById('ssoModal').style.display = 'block';
}
function closeSSOModal() {
document.getElementById('ssoModal').style.display = 'none';
document.getElementById('ssoIframe').src = '';
}
// biar bisa nerima pesan dari iframe SSO ( endpoint callback harus mengirim window.parent.postMessage)
window.addEventListener('message', function(event) {
if (event.data === 'sso-success') {
closeSSOModal();
window.location.href = '/';
}
});
</script>
}