MIF_E31232094/resources/views/auth/otp-verivy.blade.php

158 lines
5.2 KiB
PHP

{{-- resources/views/auth/otp-verify.blade.php --}}
@extends('layouts.auth')
@section('title', 'Verifikasi OTP')
@section('content')
{{-- Steps indicator --}}
<div class="steps">
<div class="step done"><div class="step-dot"></div> Email</div>
<div class="step-line done"></div>
<div class="step active"><div class="step-dot">2</div> Kode OTP</div>
<div class="step-line"></div>
<div class="step"><div class="step-dot">3</div> Password Baru</div>
</div>
<div class="page-title">Masukkan Kode OTP</div>
<p class="page-sub">
Kode 6 digit telah dikirim ke email kamu. Berlaku selama
<strong id="timerDisplay">05:00</strong>.
</p>
{{-- Alert success --}}
@if (session('success'))
<div class="alert alert-success">{{ session('success') }}</div>
@endif
{{-- Alert error --}}
@if ($errors->any())
<div class="alert alert-error">{{ $errors->first() }}</div>
@endif
<div class="info-box">
<span>📧</span>
<span>Cek folder <strong>Spam</strong> jika kode tidak muncul dalam 1 menit.</span>
</div>
{{-- Form verifikasi OTP --}}
<form method="POST" action="{{ route('password.otp.verify') }}" id="otpForm">
@csrf
<div class="form-group">
<label>Kode Verifikasi</label>
<div class="otp-group" id="otpGroup">
@for ($i = 0; $i < 6; $i++)
<input
type="text"
maxlength="1"
class="otp-input"
inputmode="numeric"
pattern="[0-9]"
autocomplete="off"
/>
@endfor
</div>
{{-- Hidden input yang akan dikirim --}}
<input type="hidden" name="otp" id="otpHidden" />
@error('otp')
<span class="invalid-feedback" style="display:block; margin-top:8px;">{{ $message }}</span>
@enderror
</div>
<button type="submit" class="btn btn-primary" id="verifyBtn" disabled>
Verifikasi Kode
</button>
</form>
{{-- Kirim ulang OTP --}}
<div class="resend">
Tidak menerima kode?
<form method="POST" action="{{ route('password.otp.resend') }}" style="display:inline;">
@csrf
<button type="submit" id="resendBtn" disabled>
Kirim Ulang (<span id="resendTimer">60</span>s)
</button>
</form>
</div>
<a href="{{ route('password.email') }}" class="btn btn-ghost" style="display:block; text-align:center; margin-top:12px; text-decoration:none;">
Ganti Email
</a>
@endsection
@push('scripts')
<script>
// ── OTP Timer (5 menit) ──
let timerInterval;
(function startOTPTimer() {
let seconds = 300;
const display = document.getElementById('timerDisplay');
const tick = () => {
const m = String(Math.floor(seconds / 60)).padStart(2, '0');
const s = String(seconds % 60).padStart(2, '0');
display.textContent = m + ':' + s;
if (seconds-- <= 0) {
clearInterval(timerInterval);
display.textContent = 'Kedaluwarsa';
display.style.color = '#e74c3c';
}
};
tick();
timerInterval = setInterval(tick, 1000);
})();
// ── Resend countdown (60 detik) ──
(function startResendTimer() {
const btn = document.getElementById('resendBtn');
const span = document.getElementById('resendTimer');
btn.disabled = true;
let t = 60;
const interval = setInterval(() => {
span.textContent = --t;
if (t <= 0) {
clearInterval(interval);
btn.disabled = false;
btn.innerHTML = 'Kirim Ulang';
}
}, 1000);
})();
// ── OTP Input UX ──
const inputs = document.querySelectorAll('.otp-input');
const hidden = document.getElementById('otpHidden');
const verBtn = document.getElementById('verifyBtn');
function syncHidden() {
hidden.value = [...inputs].map(i => i.value).join('');
verBtn.disabled = hidden.value.length !== 6;
}
inputs.forEach((inp, idx) => {
inp.addEventListener('input', () => {
inp.value = inp.value.replace(/\D/g, '').slice(-1);
if (inp.value && idx < inputs.length - 1) inputs[idx + 1].focus();
syncHidden();
});
inp.addEventListener('keydown', e => {
if (e.key === 'Backspace' && !inp.value && idx > 0) {
inputs[idx - 1].focus();
}
});
inp.addEventListener('paste', e => {
e.preventDefault();
const pasted = (e.clipboardData || window.clipboardData)
.getData('text').replace(/\D/g, '').slice(0, 6);
pasted.split('').forEach((ch, i) => { if (inputs[i]) inputs[i].value = ch; });
syncHidden();
inputs[Math.min(pasted.length, inputs.length - 1)].focus();
});
});
// Auto-focus input pertama
inputs[0].focus();
</script>
@endpush