diff --git a/app/Http/Controllers/AuthController.php b/app/Http/Controllers/AuthController.php index 9a7bbb1..b6a3016 100644 --- a/app/Http/Controllers/AuthController.php +++ b/app/Http/Controllers/AuthController.php @@ -227,20 +227,38 @@ public function logout(Request $request) } // ================= VERIFY OTP (halaman terpisah jika ada) ================= - public function showVerifyOtp() - { - return view('auth.verify-otp'); + // ================= VERIFY OTP (lupa password) ================= +public function showVerifyOtp() +{ + return view('auth.verify-otp'); +} + +public function verifyOtp(Request $request) +{ + $user = User::find(session('otp_user')); + + if (!$user) { + return back()->with('error', 'Sesi tidak valid, ulangi dari awal.'); } - public function verifyOtp(Request $request) - { - if ((string) $request->otp === (string) session('otp')) { - return redirect()->route('reset.password.form'); - } - - return back()->with('error', 'OTP salah'); + // Cek OTP dari kolom database, bukan session + if ((string)$request->otp !== (string)$user->otp) { + return back()->with('error', 'Kode OTP salah.'); } + if (!$user->otp_expired_at || now()->gt($user->otp_expired_at)) { + return back()->with('error', 'OTP sudah kadaluarsa, kirim ulang.'); + } + + // OTP valid — hapus OTP, redirect ke reset password + $user->update([ + 'otp' => null, + 'otp_expired_at' => null, + ]); + + return redirect()->route('reset.password.form'); +} + // ================= RESET PASSWORD (via OTP lupa password) ================= public function showResetPassword() { @@ -295,4 +313,30 @@ private function redirectByRole($user) default => redirect('/login'), }; } + + // ================= KIRIM OTP LUPA PASSWORD ================= +// ================= KIRIM OTP LUPA PASSWORD ================= +public function sendForgotPasswordOtp(Request $request) +{ + $request->validate([ + 'email' => 'required|email|exists:users,email', + ], [ + 'email.exists' => 'Email tidak terdaftar dalam sistem.', + ]); + + $user = User::where('email', $request->email)->first(); + + // Kirim OTP via email menggunakan OtpService yang sudah ada + app(\App\Services\OtpService::class)->send($user, 'email'); + + // Simpan ke session untuk dipakai saat verifikasi & reset + session([ + 'otp_user' => $user->id, + 'email' => $user->email, + ]); + + // Redirect ke halaman verifikasi OTP + return redirect()->route('verify.otp') + ->with('success', 'OTP telah dikirim ke ' . $user->email); +} } \ No newline at end of file diff --git a/resources/views/admin/dashboard.blade.php b/resources/views/admin/dashboard.blade.php index 03ed3c3..335fde9 100644 --- a/resources/views/admin/dashboard.blade.php +++ b/resources/views/admin/dashboard.blade.php @@ -3,33 +3,34 @@ @section('content')
diff --git a/resources/views/auth/forgot-password.blade.php b/resources/views/auth/forgot-password.blade.php index 79f0e50..913fd3f 100644 --- a/resources/views/auth/forgot-password.blade.php +++ b/resources/views/auth/forgot-password.blade.php @@ -30,7 +30,6 @@ width: 280px; max-width: 100%; margin-bottom: 32px; - filter: drop-shadow(0 8px 24px rgba(79,70,229,.18)); transition: transform .3s; } @@ -129,6 +128,95 @@ text-decoration: none; transition: color .2s; } .back-link:hover { color: #fff; } + +/* ================================================================ + RESPONSIVE MOBILE + Layout: logo + info sekolah di atas, form di bawah + ================================================================ */ +@media (max-width: 768px) { + .page { + flex-direction: column; + height: auto; + min-height: 100vh; + } + + /* LEFT — di atas */ + .left { + width: 100%; + padding: 32px 24px 28px; + order: 1; + } + + /* Garis pembatas horizontal */ + .left::after { + right: unset; + top: unset; + left: 0; + bottom: 0; + width: 100%; + height: 1px; + background: linear-gradient(to right, transparent, #C7D2FE 30%, #C7D2FE 70%, transparent); + } + + .logo { + width: 180px; + margin-bottom: 20px; + } + + .left-title { font-size: 18px; } + .left-sub { font-size: 12px; } + + .left-badge { + margin-top: 20px; + font-size: 11px; + } + + /* RIGHT — form di bawah */ + .right { + order: 2; + padding: 36px 24px 52px; + min-height: auto; + align-items: flex-start; + justify-content: center; + } + + /* Sembunyikan dekorasi lingkaran di mobile */ + .right::before, + .right::after { + display: none; + } + + .form-box { + width: 100%; + max-width: 420px; + } + + .form-title { font-size: 21px; } + + .form-sub { + font-size: 12.5px; + margin-bottom: 22px; + } + + .input-wrap input { + font-size: 16px; /* Cegah auto-zoom di iOS */ + } +} + +/* Extra small phones */ +@media (max-width: 380px) { + .left { + padding: 24px 20px 22px; + } + + .logo { width: 150px; } + + .right { + padding: 28px 20px 44px; + } + + .form-title { font-size: 19px; } +} diff --git a/resources/views/auth/login.blade.php b/resources/views/auth/login.blade.php index 882ba23..bd6beb8 100644 --- a/resources/views/auth/login.blade.php +++ b/resources/views/auth/login.blade.php @@ -341,6 +341,105 @@ flex-shrink: 0; color: #6EE7B7; } + + /* ================================================================ + RESPONSIVE MOBILE + Layout: logo + info sekolah di atas, form login di bawah + ================================================================ */ + @media (max-width: 768px) { + .page { + flex-direction: column; + height: auto; + min-height: 100vh; + } + + /* LEFT — pindah ke atas */ + .left { + width: 100%; + padding: 32px 24px 28px; + order: 1; + } + + /* Garis pembatas horizontal */ + .left::after { + right: unset; + top: unset; + left: 0; + bottom: 0; + width: 100%; + height: 1px; + background: linear-gradient(to right, transparent, #C7D2FE 30%, #C7D2FE 70%, transparent); + } + + .logo { + width: 180px; + margin-bottom: 20px; + } + + .left-title { + font-size: 18px; + } + + .left-sub { + font-size: 12px; + } + + .left-badge { + margin-top: 20px; + font-size: 11px; + } + + /* RIGHT — form login di bawah */ + .right { + order: 2; + padding: 36px 24px 52px; + min-height: auto; + align-items: flex-start; + justify-content: center; + } + + /* Sembunyikan dekorasi lingkaran di mobile */ + .right::before, + .right::after { + display: none; + } + + .form-box { + width: 100%; + max-width: 420px; + } + + .form-title { + font-size: 22px; + } + + .form-sub { + margin-bottom: 20px; + } + + .input-wrap input { + font-size: 16px; /* Cegah auto-zoom di iOS */ + } + } + + /* Extra small phones */ + @media (max-width: 380px) { + .left { + padding: 24px 20px 22px; + } + + .logo { + width: 150px; + } + + .right { + padding: 28px 20px 44px; + } + + .form-title { + font-size: 20px; + } + } diff --git a/resources/views/auth/reset-password.blade.php b/resources/views/auth/reset-password.blade.php index ab649ac..20ee4a0 100644 --- a/resources/views/auth/reset-password.blade.php +++ b/resources/views/auth/reset-password.blade.php @@ -1,173 +1,444 @@ -@extends('layouts.app') + + + + + + Reset Password - Sistem Akademik + + +.btn-submit:hover { transform: translateY(-2px); box-shadow: 0 8px 24px rgba(5,150,105,.4); } -
-
+/* ── ALERTS ── */ +.sw-alert-error { + display: flex; align-items: center; gap: 8px; + background: rgba(239,68,68,.15); border: 1px solid rgba(239,68,68,.3); + border-radius: 10px; padding: 11px 14px; + font-size: 12.5px; color: #FCA5A5; margin-bottom: 18px; +} +.sw-alert-success { + display: flex; align-items: center; gap: 8px; + background: rgba(16,185,129,.15); border: 1px solid rgba(16,185,129,.3); + border-radius: 10px; padding: 11px 14px; + font-size: 12.5px; color: #6EE7B7; margin-bottom: 18px; +} -
-
- +/* ── BACK LINK ── */ +.back-link { + display: flex; align-items: center; justify-content: center; gap: 6px; + margin-top: 20px; + font-size: 12.5px; color: rgba(255,255,255,.6); + text-decoration: none; transition: color .2s; +} +.back-link:hover { color: #fff; } + +/* ================================================================ + RESPONSIVE MOBILE + Layout: logo + info sekolah di atas, form di bawah + ================================================================ */ +@media (max-width: 768px) { + .page { + flex-direction: column; + height: auto; + min-height: 100vh; + } + + .left { + width: 100%; + padding: 32px 24px 28px; + order: 1; + } + + .left::after { + right: unset; top: unset; left: 0; bottom: 0; + width: 100%; height: 1px; + background: linear-gradient(to right, transparent, #C7D2FE 30%, #C7D2FE 70%, transparent); + } + + /* Sembunyikan steps di mobile agar tidak terlalu panjang */ + .steps { display: none; } + + .logo { width: 180px; margin-bottom: 20px; } + .left-title { font-size: 18px; } + .left-sub { font-size: 12px; } + .left-badge { margin-top: 20px; font-size: 11px; } + + .right { + order: 2; + padding: 36px 24px 52px; + min-height: auto; + align-items: flex-start; + justify-content: center; + } + + .right::before, + .right::after { display: none; } + + .form-box { width: 100%; max-width: 420px; } + .form-title { font-size: 21px; } + .form-sub { font-size: 12.5px; margin-bottom: 22px; } + + .input-wrap input { font-size: 16px; } +} + +@media (max-width: 380px) { + .left { padding: 24px 20px 22px; } + .logo { width: 150px; } + .right { padding: 28px 20px 44px; } + .form-title { font-size: 19px; } +} + + + +
+ + +
+ +
SMAN 1
BONDOWOSO
+
Buat password baru untuk
mengamankan akun Anda
+
Sistem Akademik Sekolah
+ + +
+
+
+ +
+
Masukkan Email
+
+
+
+ +
+
Verifikasi OTP
+
+
+
3
+
Reset Password
-

Reset Password

-

Buat password baru untuk akun Anda

+
-
+ +
+
- {{-- ERROR --}} +
+ + + + +
+ +
Reset Password
+
Buat password baru yang kuat
untuk mengamankan akun Anda.
+ + {{-- Alert Error --}} @if(session('error')) -
- +
+ + + {{ session('error') }}
@endif - {{-- SUCCESS --}} + {{-- Alert Success --}} @if(session('success')) -
- +
+ + + {{ session('success') }}
@endif
@csrf - + -
- -
- - -
+ {{-- Password Baru --}} + +
+ + + + + +
-
- -
- - -
+ {{-- Strength bar --}} +
+
+
+
+
+
+
+ + {{-- Konfirmasi Password --}} + +
+ + + + + +
- - + + + + + + Kembali ke Login + +
+
-@endsection \ No newline at end of file + + + + \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index c3431a7..9204489 100644 --- a/routes/web.php +++ b/routes/web.php @@ -95,8 +95,7 @@ return view('auth.forgot-password'); })->name('password.request'); -Route::post('/forgot-password', [AuthController::class, 'sendOtp']) - ->name('password.email'); +Route::post('forgot-password', [AuthController::class, 'sendForgotPasswordOtp'])->name('password.email'); Route::get('/verify-otp', [AuthController::class, 'showVerifyOtp']) ->name('verify.otp.form');