MIF_E31221105/resources/views/reset_password.blade.php

380 lines
14 KiB
PHP

<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Reset Password</title>
<!-- Bootstrap CSS -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/css/bootstrap.min.css" rel="stylesheet">
<!-- Font Awesome -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
<style>
body {
background-color: #f8f9fa;
padding-top: 40px;
padding-bottom: 40px;
min-height: 100vh;
display: flex;
align-items: center;
}
.reset-password-container {
max-width: 500px;
margin: 0 auto;
padding: 30px;
background-color: white;
border-radius: 10px;
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
}
.header {
text-align: center;
margin-bottom: 30px;
}
.header h3 {
color: #344767;
font-weight: 600;
}
.header .icon {
font-size: 50px;
color: #198754;
margin-bottom: 15px;
}
.form-group {
margin-bottom: 20px;
}
.form-label {
font-weight: 500;
color: #344767;
}
.btn-submit {
background-color: #198754;
color: white;
padding: 12px 20px;
border-radius: 5px;
font-weight: 500;
width: 100%;
margin-top: 15px;
}
.btn-submit:hover {
background-color: #157347;
}
.cancel-link {
text-align: center;
margin-top: 20px;
}
.alert {
border-radius: 5px;
padding: 15px;
margin-bottom: 20px;
}
.alert-danger {
background-color: #f8d7da;
border-color: #f5c2c7;
color: #842029;
}
.input-group-text {
background-color: transparent;
}
.password-strength {
height: 5px;
margin-top: 10px;
border-radius: 5px;
transition: all 0.3s ease;
}
.strength-weak {
width: 30%;
background-color: #dc3545;
}
.strength-medium {
width: 60%;
background-color: #ffc107;
}
.strength-strong {
width: 100%;
background-color: #198754;
}
.strength-text {
font-size: 14px;
margin-top: 5px;
}
.divider {
display: flex;
align-items: center;
text-align: center;
margin: 20px 0;
}
.divider::before, .divider::after {
content: '';
flex: 1;
border-bottom: 1px solid #dee2e6;
}
.divider span {
padding: 0 10px;
color: #6c757d;
font-size: 14px;
}
.helper-text {
font-size: 14px;
color: #6c757d;
margin-top: 5px;
}
.password-requirements {
background-color: #f8f9fa;
padding: 15px;
border-radius: 5px;
margin-top: 20px;
margin-bottom: 20px;
}
.password-requirements ul {
margin-bottom: 0;
padding-left: 20px;
}
.password-requirements li {
font-size: 14px;
margin-bottom: 5px;
color: #6c757d;
}
.requirement-met {
color: #198754;
}
.requirement-not-met {
color: #6c757d;
}
</style>
</head>
<body>
<div class="container">
<div class="reset-password-container">
<div class="header">
<div class="icon">
<i class="fas fa-key"></i>
</div>
<h3>Reset Password Baru</h3>
<p class="text-muted">Buat password baru yang kuat untuk akun Anda</p>
</div>
@if(session('error'))
<div class="alert alert-danger" role="alert">
<i class="fas fa-exclamation-circle me-2"></i>{{ session('error') }}
</div>
@endif
@if($errors->any())
<div class="alert alert-danger">
<ul class="mb-0">
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form action="{{ route('password.reset') }}" method="POST" class="needs-validation" novalidate>
@csrf
<input type="hidden" name="token" value="{{ request()->route('token') }}">
<input type="hidden" name="email" value="{{ request()->get('email') }}">
<div class="form-group">
<label for="password" class="form-label">Password Baru</label>
<div class="input-group">
<span class="input-group-text"><i class="fas fa-lock"></i></span>
<input type="password" name="password" id="password" class="form-control @error('password') is-invalid @enderror" required>
<button class="btn btn-outline-secondary" type="button" id="togglePassword">
<i class="fas fa-eye"></i>
</button>
@error('password')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<div class="password-strength" id="passwordStrength"></div>
<div class="strength-text" id="strengthText"></div>
</div>
<div class="form-group">
<label for="password_confirmation" class="form-label">Konfirmasi Password</label>
<div class="input-group">
<span class="input-group-text"><i class="fas fa-lock"></i></span>
<input type="password" name="password_confirmation" id="password_confirmation" class="form-control" required>
<button class="btn btn-outline-secondary" type="button" id="toggleConfirmPassword">
<i class="fas fa-eye"></i>
</button>
</div>
<div class="helper-text" id="passwordMatch"></div>
</div>
<div class="password-requirements">
<p class="mb-2"><strong>Password harus memenuhi kriteria berikut:</strong></p>
<ul>
<li id="length-req"><i class="fas fa-circle me-2 requirement-not-met"></i>Minimal 8 karakter</li>
<li id="uppercase-req"><i class="fas fa-circle me-2 requirement-not-met"></i>Minimal 1 huruf besar</li>
<li id="lowercase-req"><i class="fas fa-circle me-2 requirement-not-met"></i>Minimal 1 huruf kecil</li>
<li id="number-req"><i class="fas fa-circle me-2 requirement-not-met"></i>Minimal 1 angka</li>
<li id="special-req"><i class="fas fa-circle me-2 requirement-not-met"></i>Minimal 1 karakter khusus (!@#$%^&*)</li>
</ul>
</div>
<div class="divider">
<span>SELESAIKAN RESET PASSWORD</span>
</div>
<button type="submit" class="btn btn-submit" id="submitBtn">
<i class="fas fa-save me-2"></i>Simpan Password Baru
</button>
<div class="cancel-link">
<a href="{{ route('login') }}" class="text-decoration-none">
<i class="fas fa-arrow-left me-1"></i>Kembali ke halaman login
</a>
</div>
</form>
</div>
</div>
<!-- Bootstrap & jQuery JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/js/bootstrap.bundle.min.js"></script>
<script>
// Form validation
(function() {
'use strict';
window.addEventListener('load', function() {
const forms = document.getElementsByClassName('needs-validation');
Array.prototype.filter.call(forms, function(form) {
form.addEventListener('submit', function(event) {
if (form.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add('was-validated');
}, false);
});
}, false);
})();
// Toggle password visibility
document.getElementById('togglePassword').addEventListener('click', function() {
const passwordInput = document.getElementById('password');
const icon = this.querySelector('i');
if (passwordInput.type === 'password') {
passwordInput.type = 'text';
icon.classList.remove('fa-eye');
icon.classList.add('fa-eye-slash');
} else {
passwordInput.type = 'password';
icon.classList.remove('fa-eye-slash');
icon.classList.add('fa-eye');
}
});
// Toggle confirm password visibility
document.getElementById('toggleConfirmPassword').addEventListener('click', function() {
const confirmPasswordInput = document.getElementById('password_confirmation');
const icon = this.querySelector('i');
if (confirmPasswordInput.type === 'password') {
confirmPasswordInput.type = 'text';
icon.classList.remove('fa-eye');
icon.classList.add('fa-eye-slash');
} else {
confirmPasswordInput.type = 'password';
icon.classList.remove('fa-eye-slash');
icon.classList.add('fa-eye');
}
});
// Password strength checker
const passwordInput = document.getElementById('password');
const strengthBar = document.getElementById('passwordStrength');
const strengthText = document.getElementById('strengthText');
// Password requirements
const lengthReq = document.getElementById('length-req');
const uppercaseReq = document.getElementById('uppercase-req');
const lowercaseReq = document.getElementById('lowercase-req');
const numberReq = document.getElementById('number-req');
const specialReq = document.getElementById('special-req');
passwordInput.addEventListener('input', function() {
const val = passwordInput.value;
let strength = 0;
// Check requirements
const hasLength = val.length >= 8;
const hasUppercase = /[A-Z]/.test(val);
const hasLowercase = /[a-z]/.test(val);
const hasNumber = /[0-9]/.test(val);
const hasSpecial = /[!@#$%^&*]/.test(val);
// Update requirement indicators
updateRequirement(lengthReq, hasLength);
updateRequirement(uppercaseReq, hasUppercase);
updateRequirement(lowercaseReq, hasLowercase);
updateRequirement(numberReq, hasNumber);
updateRequirement(specialReq, hasSpecial);
// Calculate strength
if (hasLength) strength += 1;
if (hasUppercase) strength += 1;
if (hasLowercase) strength += 1;
if (hasNumber) strength += 1;
if (hasSpecial) strength += 1;
// Update strength bar and text
if (val.length === 0) {
strengthBar.style.width = '0';
strengthBar.className = 'password-strength';
strengthText.textContent = '';
} else if (strength <= 2) {
strengthBar.className = 'password-strength strength-weak';
strengthText.textContent = 'Lemah';
strengthText.style.color = '#dc3545';
} else if (strength <= 4) {
strengthBar.className = 'password-strength strength-medium';
strengthText.textContent = 'Sedang';
strengthText.style.color = '#ffc107';
} else {
strengthBar.className = 'password-strength strength-strong';
strengthText.textContent = 'Kuat';
strengthText.style.color = '#198754';
}
});
function updateRequirement(element, isMet) {
const icon = element.querySelector('i');
if (isMet) {
icon.className = 'fas fa-check-circle me-2 requirement-met';
element.style.color = '#198754';
} else {
icon.className = 'fas fa-circle me-2 requirement-not-met';
element.style.color = '#6c757d';
}
}
// Check if passwords match
const confirmPasswordInput = document.getElementById('password_confirmation');
const passwordMatch = document.getElementById('passwordMatch');
const submitBtn = document.getElementById('submitBtn');
confirmPasswordInput.addEventListener('input', function() {
if (passwordInput.value && confirmPasswordInput.value) {
if (passwordInput.value === confirmPasswordInput.value) {
passwordMatch.textContent = 'Password cocok';
passwordMatch.style.color = '#198754';
} else {
passwordMatch.textContent = 'Password tidak cocok';
passwordMatch.style.color = '#dc3545';
}
} else {
passwordMatch.textContent = '';
}
});
// Auto-hide alerts after 5 seconds
window.setTimeout(function() {
$(".alert").fadeTo(500, 0).slideUp(500, function(){
$(this).remove();
});
}, 5000);
</script>
</body>
</html>