Feat: reset password ui with OTP
This commit is contained in:
parent
2ccee78660
commit
d51df1583e
|
|
@ -1,5 +1,5 @@
|
|||
<x-app-layout>
|
||||
@section('page-title', 'Dashboard Admin')
|
||||
@section('page-title', 'Beranda')
|
||||
|
||||
{{-- Welcome card Section --}}
|
||||
<div class="card border-0 shadow-sm rounded-4 my-4 p-4 position-relative" style="background-color: #CEDEFF;">
|
||||
|
|
|
|||
|
|
@ -9,17 +9,18 @@
|
|||
<div class="card shadow mb-5">
|
||||
<div class="card-header py-3 d-flex justify-content-between align-items-center flex-wrap gap-2">
|
||||
<h6 class="m-0 font-weight-bold text-primary">Daftar Pengguna Aktif</h6>
|
||||
|
||||
|
||||
<div class="d-flex align-items-center">
|
||||
<form action="{{ route('admin.pengguna.index') }}" method="GET" class="me-2 mb-0">
|
||||
<select name="role" class="form-select form-select-sm" onchange="this.form.submit()">
|
||||
<option value="">Semua Kategori</option>
|
||||
<option value="siswa" {{ request('role') == 'siswa' ? 'selected' : '' }}>Siswa</option>
|
||||
<option value="guru" {{ request('role') == 'guru' ? 'selected' : '' }}>Guru</option>
|
||||
<option value="penjaga perpus" {{ request('role') == 'penjaga perpus' ? 'selected' : '' }}>Petugas</option>
|
||||
<option value="siswa" {{ request('role')=='siswa' ? 'selected' : '' }}>Siswa</option>
|
||||
<option value="guru" {{ request('role')=='guru' ? 'selected' : '' }}>Guru</option>
|
||||
<option value="penjaga perpus" {{ request('role')=='penjaga perpus' ? 'selected' : '' }}>
|
||||
Petugas</option>
|
||||
</select>
|
||||
</form>
|
||||
|
||||
|
||||
<a href="{{ route('admin.pengguna.create') }}" class="btn btn-sm btn-primary">
|
||||
<i class="bi bi-plus-circle-fill me-1"></i>Tambah Pengguna
|
||||
</a>
|
||||
|
|
@ -41,47 +42,58 @@
|
|||
</thead>
|
||||
<tbody>
|
||||
@forelse($users as $index => $user)
|
||||
<tr>
|
||||
<td>{{ $users->firstItem() + $index }}</td>
|
||||
<td class="fw-bold">{{ $user->name }}</td>
|
||||
<td>
|
||||
<div>{{ $user->email }}</div>
|
||||
<div class="small text-muted"><i class="bi bi-telephone me-1"></i>{{ $user->no_hp ?? '-' }}</div>
|
||||
</td>
|
||||
<td>
|
||||
@if($user->role == 'guru')
|
||||
<span class="badge bg-info text-dark">Guru</span>
|
||||
@elseif($user->role == 'siswa')
|
||||
<span class="badge bg-primary">Siswa</span>
|
||||
@else
|
||||
<span class="badge bg-secondary">Petugas</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="font-monospace text-primary">
|
||||
{{ $user->nisn ?? ($user->nip ?? '-') }}
|
||||
</td>
|
||||
<td>
|
||||
@if($user->role == 'siswa')
|
||||
<span class="badge bg-light text-black border">Kelas: {{ $user->kelas ?? '-' }} / {{ $user->golongan ?? '-' }}</span>
|
||||
@else
|
||||
-
|
||||
@endif
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a href="{{ route('admin.pengguna.edit', $user->id) }}" class="btn btn-sm btn-warning">
|
||||
<i class="bi bi-pencil"></i> Edit
|
||||
</a>
|
||||
<form action="{{ route('admin.pengguna.destroy', $user->id) }}" method="POST" class="d-inline form-delete-user" data-nama="{{ $user->name }}">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="button" class="btn btn-sm btn-danger btn-hapus"><i class="bi bi-trash"></i></button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ $users->firstItem() + $index }}</td>
|
||||
<td class="fw-bold">{{ $user->name }}</td>
|
||||
<td>
|
||||
<div>{{ $user->email }}</div>
|
||||
<div class="small text-muted"><i class="bi bi-telephone me-1"></i>{{ $user->no_hp ??
|
||||
'-' }}</div>
|
||||
</td>
|
||||
<td>
|
||||
@if($user->role == 'guru')
|
||||
<span class="badge bg-info text-dark">Guru</span>
|
||||
@elseif($user->role == 'siswa')
|
||||
<span class="badge bg-primary">Siswa</span>
|
||||
@else
|
||||
<span class="badge bg-secondary">Petugas</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="font-monospace text-primary">
|
||||
{{ $user->nisn ?? ($user->nip ?? '-') }}
|
||||
</td>
|
||||
<td>
|
||||
@if($user->role == 'siswa')
|
||||
<span class="badge bg-light text-black border">Kelas: {{ $user->kelas ?? '-' }} / {{
|
||||
$user->golongan ?? '-' }}</span>
|
||||
@else
|
||||
-
|
||||
@endif
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a href="{{ route('admin.pengguna.edit', $user->id) }}"
|
||||
class="btn btn-sm btn-warning">
|
||||
<i class="bi bi-pencil"></i> Edit
|
||||
</a>
|
||||
|
||||
<button type="button" class="btn btn-sm btn-secondary btn-reset-password"
|
||||
data-nama="{{ $user->name }}" title="Reset Password (OTP)">
|
||||
<i class="bi bi-key-fill"></i>
|
||||
</button>
|
||||
|
||||
<form action="{{ route('admin.pengguna.destroy', $user->id) }}" method="POST"
|
||||
class="d-inline form-delete-user" data-nama="{{ $user->name }}">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="button" class="btn btn-sm btn-danger btn-hapus"><i
|
||||
class="bi bi-trash"></i></button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="7" class="text-center py-4 text-muted">Belum ada pengguna terdaftar.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="7" class="text-center py-4 text-muted">Belum ada pengguna terdaftar.</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -97,7 +109,8 @@
|
|||
{{-- BAGIAN DATA INDUK (WHITELIST) --}}
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<div>
|
||||
<h4 class="fw-bold text-success mb-1"><i class="bi bi-database-lock me-2"></i>Data Induk (Whitelist)</h4>
|
||||
<h4 class="fw-bold text-success mb-1"><i class="bi bi-database-lock me-2"></i>Data Induk (Whitelist)
|
||||
</h4>
|
||||
<p class="text-muted mb-0">Daftar NIP/NISN yang <b>diizinkan</b> untuk mendaftar.</p>
|
||||
</div>
|
||||
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#modalMasterInduk">
|
||||
|
|
@ -121,43 +134,48 @@
|
|||
</thead>
|
||||
<tbody>
|
||||
@forelse($whitelists as $index => $item)
|
||||
<tr>
|
||||
<td>{{ $index + 1 }}</td>
|
||||
<td class="fw-bold font-monospace">{{ $item->nomor_induk }}</td>
|
||||
<td>{{ $item->nama_pemilik }}</td>
|
||||
<td>
|
||||
@if($item->role == 'guru')
|
||||
<span class="badge bg-info text-dark">Guru</span>
|
||||
@elseif($item->role == 'siswa')
|
||||
<span class="badge bg-primary">Siswa</span>
|
||||
@else
|
||||
<span class="badge bg-secondary">Petugas</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="text-center">
|
||||
@php
|
||||
$isRegistered = \App\Models\User::where('nisn', $item->nomor_induk)->orWhere('nip', $item->nomor_induk)->exists();
|
||||
@endphp
|
||||
@if ($isRegistered)
|
||||
<span class="badge bg-success text-white"><i class="bi bi-check-circle-fill me-1"></i>Terdaftar</span>
|
||||
@else
|
||||
<span class="badge bg-warning text-dark"><i class="bi bi-hourglass-split me-1"></i>Belum Daftar</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<form action="{{ route('admin.master-induk.destroy', $item->id) }}" method="POST" class="d-inline form-delete-whitelist" data-induk="{{ $item->nomor_induk }}">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="button" class="btn btn-sm btn-outline-danger btn-hapus-whitelist">
|
||||
<i class="bi bi-trash"></i> Hapus
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ $index + 1 }}</td>
|
||||
<td class="fw-bold font-monospace">{{ $item->nomor_induk }}</td>
|
||||
<td>{{ $item->nama_pemilik }}</td>
|
||||
<td>
|
||||
@if($item->role == 'guru')
|
||||
<span class="badge bg-info text-dark">Guru</span>
|
||||
@elseif($item->role == 'siswa')
|
||||
<span class="badge bg-primary">Siswa</span>
|
||||
@else
|
||||
<span class="badge bg-secondary">Petugas</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="text-center">
|
||||
@php
|
||||
$isRegistered = \App\Models\User::where('nisn', $item->nomor_induk)->orWhere('nip',
|
||||
$item->nomor_induk)->exists();
|
||||
@endphp
|
||||
@if ($isRegistered)
|
||||
<span class="badge bg-success text-white"><i
|
||||
class="bi bi-check-circle-fill me-1"></i>Terdaftar</span>
|
||||
@else
|
||||
<span class="badge bg-warning text-dark"><i
|
||||
class="bi bi-hourglass-split me-1"></i>Belum Daftar</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<form action="{{ route('admin.master-induk.destroy', $item->id) }}" method="POST"
|
||||
class="d-inline form-delete-whitelist" data-induk="{{ $item->nomor_induk }}">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="button" class="btn btn-sm btn-outline-danger btn-hapus-whitelist">
|
||||
<i class="bi bi-trash"></i> Hapus
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="6" class="text-center py-4 text-muted">Belum ada data whitelist. Silakan tambah data.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="6" class="text-center py-4 text-muted">Belum ada data whitelist. Silakan
|
||||
tambah data.</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -192,11 +210,13 @@
|
|||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">NIP / NISN</label>
|
||||
<input type="number" name="nomor_induk" class="form-control" placeholder="Contoh: 1234567890" required>
|
||||
<input type="number" name="nomor_induk" class="form-control"
|
||||
placeholder="Contoh: 1234567890" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Nama Pemilik</label>
|
||||
<input type="text" name="nama_pemilik" class="form-control" placeholder="Nama Siswa/Guru..." required>
|
||||
<input type="text" name="nama_pemilik" class="form-control" placeholder="Nama Siswa/Guru..."
|
||||
required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
|
@ -257,6 +277,48 @@
|
|||
Toast.fire({ icon: 'success', title: 'Berhasil', text: '{{ session("success") }}' });
|
||||
});
|
||||
@endif
|
||||
|
||||
// GENERATE OTP & LINK RESET
|
||||
$(document).on('click', '.btn-reset-password', function() {
|
||||
const nama = $(this).data('nama');
|
||||
const otpCode = "678901";
|
||||
const linkReset = "{{ route('reset.password-request') }}";
|
||||
|
||||
modernSwal.fire({
|
||||
title: 'Generate OTP Reset?',
|
||||
html: `Anda akan membuat Token Reset Password untuk <b>${nama}</b>.`,
|
||||
icon: 'question',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'Ya, Generate',
|
||||
cancelButtonText: 'Batal',
|
||||
confirmButtonColor: '#0d6efd'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
modernSwal.fire({
|
||||
title: 'Generating...', timer: 1000, didOpen: () => Swal.showLoading()
|
||||
}).then(() => {
|
||||
modernSwal.fire({
|
||||
title: 'OTP Berhasil Dibuat!',
|
||||
html: `
|
||||
<div class="text-start bg-light p-3 rounded border">
|
||||
<p class="mb-1 small text-muted">Kode OTP:</p>
|
||||
<h3 class="text-primary fw-bold letter-spacing-1 mb-3">${otpCode}</h3>
|
||||
<p class="mb-1 small text-muted">Link Reset:</p>
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control form-control-sm" value="${linkReset}" readonly>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-3 small text-muted">
|
||||
Silakan salin Kode OTP & Link di atas lalu kirim ke WhatsApp user.
|
||||
</div>
|
||||
`,
|
||||
icon: 'success',
|
||||
confirmButtonText: 'Selesai'
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
</x-app-layout>
|
||||
|
|
@ -1,69 +1,117 @@
|
|||
<x-guest-layout>
|
||||
@if ($errors->has('forbidden'))
|
||||
<div class="alert alert-danger d-flex align-items-center" role="alert">
|
||||
<i class="bi bi-exclamation-triangle-fill me-2"></i>
|
||||
<div>{{ $errors->first('forbidden') }}</div>
|
||||
</div>
|
||||
<div class="alert alert-danger border-0 d-flex align-items-center mb-4 shadow-sm" role="alert">
|
||||
<i class="bi bi-exclamation-triangle-fill me-2 fs-5"></i>
|
||||
<div>{{ $errors->first('forbidden') }}</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form method="POST" action="{{ route('login') }}">
|
||||
@csrf
|
||||
<input type="hidden" name="role" value="{{ $role }}">
|
||||
|
||||
{{-- HEADER LOGIN --}}
|
||||
<div class="text-center mb-4">
|
||||
{{-- Judul dinamis --}}
|
||||
<h3 class="fw-bold text-primary">Login {{ Str::title($role) }}</h3>
|
||||
<p class="text-muted">
|
||||
<div class="bg-primary bg-opacity-10 text-primary rounded-circle d-inline-flex align-items-center justify-content-center mb-3"
|
||||
style="width: 70px; height: 70px;">
|
||||
<i class="bi bi-shield-lock-fill fs-1"></i>
|
||||
</div>
|
||||
<h3 class="fw-bold text-dark">Login {{ Str::title($role) }}</h3>
|
||||
<p class="text-muted small">
|
||||
@if ($role == 'siswa')
|
||||
Masukan NISN dan kata sandi Anda.
|
||||
Silakan masukkan <b>NISN</b> dan kata sandi.
|
||||
@else
|
||||
Masukan NIP/NIK dan kata sandi Anda.
|
||||
Silakan masukkan <b>NIP/NIK</b> dan kata sandi.
|
||||
@endif
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{{-- Form dinamis --}}
|
||||
@if ($role == 'siswa')
|
||||
<div class="mb-3">
|
||||
<label for="nisn" class="form-label">Nomor Induk Siswa Nasional (NISN)</label>
|
||||
<input id="nisn" class="form-control" type="text" name="nisn" required autofocus />
|
||||
<x-input-error :messages="$errors->get('nisn')" class="mt-2" />
|
||||
</div>
|
||||
@else
|
||||
<div class="mb-3">
|
||||
<label for="nip" class="form-label">NIP/NIK</label>
|
||||
<input id="nip" class="form-control" type="text" name="nip" required autofocus />
|
||||
<x-input-error :messages="$errors->get('nip')" class="mt-2" />
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- INPUT USERNAME (NISN/NIP) --}}
|
||||
<div class="mb-3">
|
||||
<label for="password" class="form-label">Kata Sandi</label>
|
||||
<label for="{{ $role == 'siswa' ? 'nisn' : 'nip' }}" class="form-label fw-semibold small">
|
||||
{{ $role == 'siswa' ? 'Nomor Induk Siswa Nasional (NISN)' : 'NIP / NIK' }}
|
||||
</label>
|
||||
<div class="input-group">
|
||||
<input id="password" class="form-control" type="password" name="password" required />
|
||||
<button class="btn btn-outline-secondary" type="button" id="togglePassword">
|
||||
<span class="input-group-text bg-light text-muted border-end-0">
|
||||
<i class="bi bi-person-fill"></i>
|
||||
</span>
|
||||
@if ($role == 'siswa')
|
||||
<input id="nisn" class="form-control border-start-0 ps-0 bg-light" type="text" name="nisn"
|
||||
placeholder="Contoh: 0012345678" required autofocus />
|
||||
@else
|
||||
<input id="nip" class="form-control border-start-0 ps-0 bg-light" type="text" name="nip"
|
||||
placeholder="Contoh: 19800101..." required autofocus />
|
||||
@endif
|
||||
</div>
|
||||
{{-- Error Message --}}
|
||||
@if ($role == 'siswa')
|
||||
<x-input-error :messages="$errors->get('nisn')" class="mt-1 small text-danger" />
|
||||
@else
|
||||
<x-input-error :messages="$errors->get('nip')" class="mt-1 small text-danger" />
|
||||
@endif
|
||||
</div>
|
||||
|
||||
{{-- INPUT PASSWORD --}}
|
||||
<div class="mb-4">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<label for="password" class="form-label fw-semibold small">Kata Sandi</label>
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text bg-light text-muted border-end-0">
|
||||
<i class="bi bi-lock-fill"></i>
|
||||
</span>
|
||||
<input id="password" class="form-control border-start-0 border-end-0 ps-0 bg-light" type="password"
|
||||
name="password" placeholder="Masukan kata sandi" required />
|
||||
<button class="btn btn-light border border-start-0 text-muted" type="button" id="togglePassword">
|
||||
<i class="bi bi-eye-slash-fill"></i>
|
||||
</button>
|
||||
</div>
|
||||
<x-input-error :messages="$errors->get('password')" class="mt-1 small text-danger" />
|
||||
</div>
|
||||
|
||||
<div class="d-grid mt-4">
|
||||
<button type="submit" class="btn btn-primary">Masuk</button>
|
||||
{{-- TOMBOL LOGIN --}}
|
||||
<div class="d-grid mb-4">
|
||||
<button type="submit" class="btn btn-primary py-2 fw-bold shadow-sm">
|
||||
Masuk Sekarang <i class="bi bi-arrow-right ms-2"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{{-- Link href untuk ke Register --}}
|
||||
{{-- <p class="mt-4 text-center text-muted small">
|
||||
@if ($role == 'siswa')
|
||||
Belum punya akun?
|
||||
<a href="{{ route('register', ['role' => 'siswa']) }}" class="fw-semibold text-decoration-none">Daftar sebagai Siswa</a>
|
||||
@else
|
||||
Belum punya akun?
|
||||
<a href="{{ route('register', ['role' => 'guru']) }}" class="fw-semibold text-decoration-none">Daftar sebagai Guru</a>
|
||||
@endif
|
||||
</p> --}}
|
||||
{{-- BANTUAN / LUPA PASSWORD --}}
|
||||
<div class="bg-light p-3 rounded-3 text-center border border-dashed">
|
||||
<p class="text-muted small mb-1">Mengalami kendala login?</p>
|
||||
<a href="https://wa.me/6281234567890?text=Halo%20Admin,%20saya%20lupa%20kata%20sandi%20akun%20saya."
|
||||
target="_blank" class="text-decoration-none fw-bold text-success d-inline-flex align-items-center">
|
||||
<i class="bi bi-whatsapp me-1"></i> Hubungi Petugas via WA
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<p class="mt-3 text-center text-muted small">
|
||||
Kembali ke <a href="/" class="fw-semibold text-decoration-none">halaman utama</a>.
|
||||
</p>
|
||||
<div class="text-center mt-4">
|
||||
<a href="/" class="text-decoration-none text-muted small hover-text-primary">
|
||||
<i class="bi bi-arrow-left me-1"></i>Kembali ke Halaman Utama
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const togglePassword = document.querySelector('#togglePassword');
|
||||
const password = document.querySelector('#password');
|
||||
const icon = togglePassword.querySelector('i');
|
||||
|
||||
if (togglePassword && password) {
|
||||
togglePassword.addEventListener('click', function(e) {
|
||||
const type = password.getAttribute('type') === 'password' ? 'text' : 'password';
|
||||
password.setAttribute('type', type);
|
||||
|
||||
if (type === 'password') {
|
||||
icon.classList.remove('bi-eye-fill');
|
||||
icon.classList.add('bi-eye-slash-fill');
|
||||
} else {
|
||||
icon.classList.remove('bi-eye-slash-fill');
|
||||
icon.classList.add('bi-eye-fill');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</x-guest-layout>
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
<x-guest-layout>
|
||||
{{-- VERIFIKASI OTP --}}
|
||||
<div id="step-otp">
|
||||
<div class="mb-4 text-center">
|
||||
<h4 class="fw-bold text-dark">Verifikasi Kode OTP</h4>
|
||||
<p class="text-muted small">Masukkan 6 digit kode yang diberikan Admin via WhatsApp.</p>
|
||||
</div>
|
||||
|
||||
<form id="formVerifyOtp" onsubmit="verifikasiOTP(event)">
|
||||
<div class="mb-4">
|
||||
<label class="form-label fw-bold">Kode OTP</label>
|
||||
<input class="form-control text-center fs-3 letter-spacing-2 py-2" type="text" id="inputOtp"
|
||||
placeholder="000000" maxlength="6" required autofocus autocomplete="off">
|
||||
</div>
|
||||
|
||||
<div class="d-grid">
|
||||
<button type="submit" class="btn btn-primary py-2 fw-bold">
|
||||
Verifikasi Kode
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="text-center mt-3">
|
||||
<a href="/login" class="text-decoration-none small text-muted">
|
||||
<i class="bi bi-arrow-left me-1"></i>Kembali ke Login
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{{-- PASSWORD BARU --}}
|
||||
<div id="step-password" class="d-none">
|
||||
<div class="mb-4 text-center">
|
||||
<h4 class="fw-bold text-dark">Buat Kata Sandi Baru</h4>
|
||||
<p class="text-muted small">OTP Valid! Silakan buat kata sandi baru Anda.</p>
|
||||
</div>
|
||||
|
||||
<form id="formResetPassword" onsubmit="simpanPassword(event)">
|
||||
{{-- Password Utama --}}
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Kata Sandi Baru</label>
|
||||
<div class="input-group">
|
||||
<input id="password" class="form-control" type="password" name="password" required placeholder="Minimal 8 karakter"/>
|
||||
<button class="btn btn-outline-secondary" type="button" onclick="lihatPassword('password', this)">
|
||||
<i class="bi bi-eye-slash-fill"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Konfirmasi Password --}}
|
||||
<div class="mb-4">
|
||||
<label class="form-label">Konfirmasi Kata Sandi</label>
|
||||
<div class="input-group">
|
||||
<input id="password_confirmation" class="form-control" type="password" name="password_confirmation" required placeholder="Ulangi kata sandi"/>
|
||||
<button class="btn btn-outline-secondary" type="button" onclick="lihatPassword('password_confirmation', this)">
|
||||
<i class="bi bi-eye-slash-fill"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-grid">
|
||||
<button type="submit" class="btn btn-primary py-2 fw-bold">
|
||||
Simpan Kata Sandi
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||
<script>
|
||||
// Fungsi Toggle Lihat Password
|
||||
function lihatPassword(targetId, btn) {
|
||||
const input = document.getElementById(targetId);
|
||||
const icon = btn.querySelector('i');
|
||||
|
||||
if (input.type === 'password') {
|
||||
input.type = 'text';
|
||||
icon.classList.remove('bi-eye-slash-fill');
|
||||
icon.classList.add('bi-eye-fill');
|
||||
} else {
|
||||
input.type = 'password';
|
||||
icon.classList.remove('bi-eye-fill');
|
||||
icon.classList.add('bi-eye-slash-fill');
|
||||
}
|
||||
}
|
||||
|
||||
// Fungsi Verifikasi OTP
|
||||
function verifikasiOTP(e) {
|
||||
e.preventDefault();
|
||||
const inputOtp = document.getElementById('inputOtp').value;
|
||||
|
||||
if(inputOtp !== '678901') {
|
||||
Swal.fire({ icon: 'error', title: 'Gagal', text: 'Kode OTP salah! Coba cek lagi WA Admin.' });
|
||||
return;
|
||||
}
|
||||
|
||||
Swal.fire({ title: 'Memverifikasi...', timer: 800, didOpen: () => Swal.showLoading() }).then(() => {
|
||||
document.getElementById('step-otp').classList.add('d-none');
|
||||
document.getElementById('step-password').classList.remove('d-none');
|
||||
document.getElementById('password').focus();
|
||||
|
||||
const Toast = Swal.mixin({ toast: true, position: 'top-end', showConfirmButton: false, timer: 3000 });
|
||||
Toast.fire({ icon: 'success', title: 'Kode OTP Valid' });
|
||||
});
|
||||
}
|
||||
|
||||
// Fungsi Simpan Password
|
||||
function simpanPassword(e) {
|
||||
e.preventDefault();
|
||||
const pass = document.getElementById('password').value;
|
||||
const conf = document.getElementById('password_confirmation').value;
|
||||
|
||||
if(pass.length < 8) {
|
||||
Swal.fire({ icon: 'warning', text: 'Kata sandi minimal 8 karakter!' }); return;
|
||||
}
|
||||
if(pass !== conf) {
|
||||
Swal.fire({ icon: 'warning', text: 'Konfirmasi kata sandi tidak cocok!' }); return;
|
||||
}
|
||||
|
||||
Swal.fire({ title: 'Menyimpan...', timer: 1500, didOpen: () => Swal.showLoading() }).then(() => {
|
||||
Swal.fire({
|
||||
icon: 'success', title: 'Berhasil!', text: 'Kata sandi Anda telah diperbarui. Silakan login.',
|
||||
confirmButtonText: 'Ke Halaman Login', allowOutsideClick: false
|
||||
}).then(() => { window.location.href = "/login"; });
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.letter-spacing-2 {
|
||||
letter-spacing: 0.5em;
|
||||
font-weight: bold;
|
||||
color: #0d6efd;
|
||||
}
|
||||
</style>
|
||||
</x-guest-layout>
|
||||
|
|
@ -1,11 +1,6 @@
|
|||
@section('page-title', 'Beranda')
|
||||
<x-app-layout>
|
||||
|
||||
{{-- <button type="button" class="btn btn-sm btn-primary end-0">
|
||||
<i class="bi bi-plus-circle me-1"></i>
|
||||
Pinjam Buku Baru
|
||||
</button> --}}
|
||||
|
||||
{{-- CEK STATUS BANNED --}}
|
||||
@if (Auth::user()->is_banned)
|
||||
<div class="alert alert-danger border-0 shadow-sm d-flex align-items-center mb-4" role="alert">
|
||||
|
|
@ -28,6 +23,7 @@
|
|||
</div>
|
||||
@endif
|
||||
|
||||
{{-- HERO SECTION --}}
|
||||
<div class="card border-0 shadow-sm rounded-4 my-4 p-4 position-relative" style="background-color: #CEDEFF;">
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-8 p-4 p-md-5" style="z-index: 2;">
|
||||
|
|
@ -38,7 +34,7 @@
|
|||
|
||||
<div class="position-absolute d-none d-md-block"
|
||||
style="top: -35px; right: 40px; width: 30%; max-width: 300px; z-index: 1;">
|
||||
<img src="{{ asset('images/assets/vector-dashboard.svg') }}" alt="Ilustrasi Dashboard" class="img-fluid">
|
||||
<img src="{{ asset('images/assets/vector-dashboard.svg') }}" alt="Ilustrasi Beranda" class="img-fluid">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -214,11 +210,17 @@ class="badge bg-{{ $item['type'] }}-soft text-{{ $item['type'] }} rounded-pill p
|
|||
@forelse($bukuPinjamOffline as $buku)
|
||||
<div class="col-xl-4 col-md-6" x-show="expanded || {{ $loop->index }} < 3" x-transition>
|
||||
<x-book-card :buku="$buku">
|
||||
<div
|
||||
class="d-flex align-items-center text-danger bg-white bg-opacity-75 rounded-2 px-2 py-1">
|
||||
<i class="bi bi-clock-fill me-2 shadow-md"></i>
|
||||
<span class="fw-bold small">Sisa: {{ $buku['sisa_hari'] }} hari</span>
|
||||
</div>
|
||||
@if($buku['sisa_hari'] < 0)
|
||||
<div class="d-flex align-items-center text-danger bg-danger-subtle rounded-2 px-2 py-1">
|
||||
<i class="bi bi-exclamation-circle-fill me-2 shadow-md"></i>
|
||||
<span class="fw-bold small">Terlambat: {{ abs($buku['sisa_hari']) }} hari</span>
|
||||
</div>
|
||||
@else
|
||||
<div class="d-flex align-items-center text-primary bg-primary-subtle rounded-2 px-2 py-1">
|
||||
<i class="bi bi-clock-fill me-2 shadow-md"></i>
|
||||
<span class="fw-bold small">Sisa: {{ $buku['sisa_hari'] }} hari</span>
|
||||
</div>
|
||||
@endif
|
||||
</x-book-card>
|
||||
</div>
|
||||
@empty
|
||||
|
|
@ -312,7 +314,6 @@ class="d-flex gap-3 text-decoration-none text-dark mb-3">
|
|||
</div>
|
||||
@endif
|
||||
|
||||
<!-- Modals untuk Pengumuman-->
|
||||
<div class="modal fade" id="pengumumanModal" tabindex="-1" aria-labelledby="pengumumanModalLabel"
|
||||
aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-scrollable modal-lg">
|
||||
|
|
@ -345,7 +346,6 @@ class="d-flex gap-3 text-decoration-none text-dark mb-3">
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modals untuk Pemberitahuan-->
|
||||
<div class="modal fade" id="pemberitahuanModal" tabindex="-1" aria-labelledby="pemberitahuanModalLabel"
|
||||
aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-scrollable modal-lg">
|
||||
|
|
@ -386,7 +386,6 @@ class="badge bg-{{ $item['type'] }}-soft text-{{ $item['type'] }} rounded-pill p
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modals untuk Rekomendasi Pembelajaran-->
|
||||
<div class="modal fade" id="rekomendasiModal" tabindex="-1" aria-labelledby="rekomendasiModalLabel"
|
||||
aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-scrollable modal-lg">
|
||||
|
|
@ -429,4 +428,4 @@ class="badge fw-normal text-primary border me-1">{{ $item['kategori'] }}</span>
|
|||
</script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<script src="{{ asset('js/dashboard-charts.js') }}"></script>
|
||||
</x-app-layout>
|
||||
</x-app-layout>
|
||||
|
|
@ -63,7 +63,6 @@
|
|||
const password = document.querySelector('#password');
|
||||
|
||||
if (togglePassword && password) {
|
||||
// Tambahkan ikon awal jika belum ada
|
||||
const initialIcon = togglePassword.querySelector('i');
|
||||
if (!initialIcon.classList.contains('bi-eye-fill') && !initialIcon.classList.contains('bi-eye-slash-fill')) {
|
||||
initialIcon.classList.add('bi-eye-slash-fill');
|
||||
|
|
|
|||
|
|
@ -121,4 +121,9 @@
|
|||
Route::post('/admin/login', [AdminLoginController::class, 'store'])->name('admin.login.store');
|
||||
});
|
||||
|
||||
// -- RUTE RESET PASSWORD --
|
||||
Route::get('/reset-password', function () {
|
||||
return view('auth.reset-password-request');
|
||||
})->name('reset.password-request');
|
||||
|
||||
require __DIR__ . '/auth.php';
|
||||
Loading…
Reference in New Issue