Initial commit: MSPE website - full site with admin panel, API, and public pages
This commit is contained in:
Executable
+147
@@ -0,0 +1,147 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="robots" content="noindex, nofollow, noarchive">
|
||||
<title>Reset Password - MSPE Admin</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" integrity="sha384-t1nt8BQoYMLFN5p42tRAtuAAFQaCQODekUVeKKZrEnEyp4H2R0RHFz0KWpmj7i8g" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="/admin/css/admin.css">
|
||||
</head>
|
||||
<body class="login-page">
|
||||
<div class="login-container">
|
||||
<div class="login-card" style="max-width: 520px;">
|
||||
<div class="login-header">
|
||||
<div class="login-logo">
|
||||
<i class="fas fa-key"></i>
|
||||
<span>MSPE</span>
|
||||
</div>
|
||||
<h1 id="page-title">Reset Password</h1>
|
||||
<p id="page-subtitle">Request a secure password reset link.</p>
|
||||
</div>
|
||||
|
||||
<form id="request-form" class="login-form">
|
||||
<div class="form-group">
|
||||
<label for="identity">Email or Username</label>
|
||||
<div class="input-icon">
|
||||
<i class="fas fa-user"></i>
|
||||
<input type="text" id="identity" required placeholder="admin@company.com or username">
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary btn-block">
|
||||
<span>Send Reset Link</span>
|
||||
<i class="fas fa-paper-plane"></i>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<form id="reset-form" class="login-form" style="display:none;">
|
||||
<div class="form-group">
|
||||
<label for="new-password">New Password</label>
|
||||
<div class="input-icon">
|
||||
<i class="fas fa-lock"></i>
|
||||
<input type="password" id="new-password" required minlength="8" placeholder="Minimum 8 characters">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="confirm-password">Confirm New Password</label>
|
||||
<div class="input-icon">
|
||||
<i class="fas fa-lock"></i>
|
||||
<input type="password" id="confirm-password" required minlength="8" placeholder="Repeat password">
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary btn-block">
|
||||
<span>Update Password</span>
|
||||
<i class="fas fa-check"></i>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div class="login-message" id="reset-message" style="display:none;"></div>
|
||||
|
||||
<div class="login-footer">
|
||||
<p><a href="/admin/index.html">Back to login</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const token = params.get('token');
|
||||
|
||||
const requestForm = document.getElementById('request-form');
|
||||
const resetForm = document.getElementById('reset-form');
|
||||
const message = document.getElementById('reset-message');
|
||||
|
||||
if (token) {
|
||||
document.getElementById('page-title').textContent = 'Set New Password';
|
||||
document.getElementById('page-subtitle').textContent = 'Enter your new password below.';
|
||||
requestForm.style.display = 'none';
|
||||
resetForm.style.display = 'block';
|
||||
}
|
||||
|
||||
function showMessage(text, type = 'success') {
|
||||
message.className = 'login-message ' + type;
|
||||
message.innerHTML = `<i class="fas fa-${type === 'success' ? 'check-circle' : 'exclamation-circle'}"></i> ${text}`;
|
||||
message.style.display = 'block';
|
||||
}
|
||||
|
||||
requestForm.addEventListener('submit', async function(e) {
|
||||
e.preventDefault();
|
||||
const identity = document.getElementById('identity').value.trim();
|
||||
|
||||
try {
|
||||
const res = await fetch('/api/auth.php', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ action: 'request_password_reset', identity })
|
||||
});
|
||||
const data = await res.json();
|
||||
if (data.success) {
|
||||
showMessage('If the account exists, a reset email has been sent.', 'success');
|
||||
} else {
|
||||
showMessage(data.message || 'Failed to request reset.', 'error');
|
||||
}
|
||||
} catch (err) {
|
||||
showMessage('Network error. Please try again.', 'error');
|
||||
}
|
||||
});
|
||||
|
||||
resetForm.addEventListener('submit', async function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const newPassword = document.getElementById('new-password').value;
|
||||
const confirmPassword = document.getElementById('confirm-password').value;
|
||||
|
||||
if (newPassword !== confirmPassword) {
|
||||
showMessage('Passwords do not match.', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await fetch('/api/auth.php', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
action: 'reset_password',
|
||||
token,
|
||||
new_password: newPassword
|
||||
})
|
||||
});
|
||||
const data = await res.json();
|
||||
|
||||
if (data.success) {
|
||||
showMessage('Password updated. Redirecting to login...', 'success');
|
||||
setTimeout(() => {
|
||||
window.location.href = '/admin/index.html';
|
||||
}, 1200);
|
||||
} else {
|
||||
showMessage(data.message || 'Could not reset password.', 'error');
|
||||
}
|
||||
} catch (err) {
|
||||
showMessage('Network error. Please try again.', 'error');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user