| Current Path : /home/users/unlimited/www/nigeria.codeskitter.site/ |
| Current File : /home/users/unlimited/www/nigeria.codeskitter.site/register.php |
<?php
include 'includes/config.php';
if(isset($_SESSION['user_id'])) {
header("Location: index.php");
exit();
}
if($_SERVER['REQUEST_METHOD'] == 'POST') {
$name = trim($_POST['name']);
$email = trim($_POST['email']);
$password = $_POST['password'];
$confirm_password = $_POST['confirm_password'];
if($password !== $confirm_password) {
$error = "Passwords do not match!";
} else {
// Check if email exists
$check_sql = "SELECT id FROM users WHERE email = ?";
$stmt = $conn->prepare($check_sql);
$stmt->bind_param("s", $email);
$stmt->execute();
$result = $stmt->get_result();
if($result->num_rows > 0) {
$error = "Email already registered!";
} else {
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
$token = bin2hex(random_bytes(32));
$insert_sql = "INSERT INTO users (name, email, password, role, verification_token, is_verified) VALUES (?, ?, ?, 'student', ?, 0)";
$stmt_insert = $conn->prepare($insert_sql);
$stmt_insert->bind_param("ssss", $name, $email, $hashed_password, $token);
if($stmt_insert->execute()) {
// Send email using PHP mail()
$verifyLink = "https://nigeria.codeskitter.site/verify.php?token=" . urlencode($token);
$subject = "Verify Your Email - Gex Neural Academy";
$message = "
<html>
<head>
<title>Email Verification</title>
</head>
<body>
<h2>Welcome to Gex Neural Academy!</h2>
<p>Click the button below to verify your email:</p>
<p><a href='$verifyLink' style='background:#4e73df;color:white;padding:10px 20px;text-decoration:none;border-radius:5px;'>Verify Email</a></p>
<p>If you did not sign up, ignore this email.</p>
</body>
</html>
";
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";
$headers .= "From: Gex Neural Academy <no-reply@yourdomain.com>" . "\r\n";
if(mail($email, $subject, $message, $headers)) {
$_SESSION['success'] = "Registration successful! Check your email to verify your account.";
header("Location: login.php");
exit();
} else {
$error = "Registration successful, but failed to send verification email.";
}
} else {
$error = "Registration failed! Please try again.";
}
}
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Register - eLearning</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.2/font/bootstrap-icons.css">
<style>
body {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
flex-direction: column;
}
.register-card {
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
overflow: hidden;
border: none;
}
.register-header {
background: linear-gradient(45deg, #4e73df, #224abe);
color: white;
padding: 2rem;
text-align: center;
}
.register-body {
padding: 2.5rem;
background-color: white;
}
.form-control {
border-radius: 8px;
padding: 0.75rem 1rem;
border: 1px solid #e3e6f0;
}
.form-control:focus {
border-color: #4e73df;
box-shadow: 0 0 0 0.2rem rgba(78, 115, 223, 0.25);
}
.btn-register {
background: linear-gradient(45deg, #4e73df, #224abe);
border: none;
border-radius: 8px;
padding: 0.75rem;
font-weight: 600;
transition: all 0.3s;
}
.btn-register:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
}
.password-toggle {
position: absolute;
right: 15px;
top: 50%;
transform: translateY(-50%);
cursor: pointer;
color: #6c757d;
}
.password-container {
position: relative;
}
.form-floating {
margin-bottom: 1.5rem;
}
.brand-logo {
font-size: 2.5rem;
margin-bottom: 1rem;
}
.alert {
border-radius: 8px;
}
.login-link {
color: #4e73df;
font-weight: 500;
text-decoration: none;
}
.login-link:hover {
color: #224abe;
text-decoration: underline;
}
.password-strength {
height: 5px;
border-radius: 5px;
margin-top: 5px;
transition: all 0.3s;
}
.strength-weak {
background-color: #e74a3b;
width: 25%;
}
.strength-medium {
background-color: #f6c23e;
width: 50%;
}
.strength-strong {
background-color: #1cc88a;
width: 100%;
}
.shake {
animation: shake 0.5s;
}
@keyframes shake {
0%, 100% {transform: translateX(0);}
10%, 30%, 50%, 70%, 90% {transform: translateX(-5px);}
20%, 40%, 60%, 80% {transform: translateX(5px);}
}
.requirement-list {
font-size: 0.85rem;
padding-left: 1.5rem;
}
.requirement-item {
margin-bottom: 0.25rem;
}
.requirement-met {
color: #1cc88a;
}
.requirement-unmet {
color: #e74a3b;
}
</style>
</head>
<body>
<?php include 'includes/header.php'; ?>
<div class="container py-5 flex-grow-1">
<div class="row justify-content-center">
<div class="col-md-8 col-lg-6">
<div class="card register-card">
<div class="register-header">
<div class="brand-logo">
<i class="bi bi-book-half"></i>
</div>
<h2 class="fw-bold">Gex Neural Academy</h2>
<p class="mb-0">Create your account</p>
</div>
<div class="card-body register-body">
<?php if(isset($error)): ?>
<div class="alert alert-danger alert-dismissible fade show" role="alert">
<i class="bi bi-exclamation-triangle-fill me-2"></i>
<?php echo $error; ?>
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
<?php endif; ?>
<form method="POST" id="registerForm">
<div class="form-floating">
<input type="text" class="form-control" id="name" name="name" placeholder="John Doe" required>
<label for="name"><i class="bi bi-person me-2"></i>Full Name</label>
<div class="invalid-feedback" id="nameError">
Please provide your full name.
</div>
</div>
<div class="form-floating">
<input type="email" class="form-control" id="email" name="email" placeholder="name@example.com" required>
<label for="email"><i class="bi bi-envelope me-2"></i>Email Address</label>
<div class="invalid-feedback" id="emailError">
Please provide a valid email address.
</div>
</div>
<div class="form-floating password-container">
<input type="password" class="form-control" id="password" name="password" placeholder="Password" required>
<label for="password"><i class="bi bi-lock me-2"></i>Password</label>
<span class="password-toggle" id="togglePassword">
<i class="bi bi-eye"></i>
</span>
<div class="password-strength" id="passwordStrength"></div>
<div class="invalid-feedback" id="passwordError">
Please enter a valid password.
</div>
<div class="mt-2">
<small class="text-muted">Password Requirements:</small>
<ul class="requirement-list mt-1">
<li class="requirement-item" id="reqLength">At least 8 characters</li>
<li class="requirement-item" id="reqUppercase">At least one uppercase letter</li>
<li class="requirement-item" id="reqLowercase">At least one lowercase letter</li>
<li class="requirement-item" id="reqNumber">At least one number</li>
</ul>
</div>
</div>
<div class="form-floating password-container">
<input type="password" class="form-control" id="confirm_password" name="confirm_password" placeholder="Confirm Password" required>
<label for="confirm_password"><i class="bi bi-lock-fill me-2"></i>Confirm Password</label>
<span class="password-toggle" id="toggleConfirmPassword">
<i class="bi bi-eye"></i>
</span>
<div class="invalid-feedback" id="confirmPasswordError">
Passwords do not match.
</div>
</div>
<div class="d-grid mb-3">
<button type="submit" class="btn btn-register btn-lg text-white">
<i class="bi bi-person-plus me-2"></i>Create Account
</button>
</div>
<div class="text-center">
<p class="mb-0">Already have an account? <a href="login.php" class="login-link">Login here</a></p>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<?php include 'includes/footer.php'; ?>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
const form = document.getElementById('registerForm');
const nameInput = document.getElementById('name');
const emailInput = document.getElementById('email');
const passwordInput = document.getElementById('password');
const confirmPasswordInput = document.getElementById('confirm_password');
const passwordStrength = document.getElementById('passwordStrength');
// Password visibility toggles
const togglePassword = document.getElementById('togglePassword');
const toggleConfirmPassword = document.getElementById('toggleConfirmPassword');
togglePassword.addEventListener('click', function() {
const type = passwordInput.getAttribute('type') === 'password' ? 'text' : 'password';
passwordInput.setAttribute('type', type);
this.innerHTML = type === 'password' ? '<i class="bi bi-eye"></i>' : '<i class="bi bi-eye-slash"></i>';
});
toggleConfirmPassword.addEventListener('click', function() {
const type = confirmPasswordInput.getAttribute('type') === 'password' ? 'text' : 'password';
confirmPasswordInput.setAttribute('type', type);
this.innerHTML = type === 'password' ? '<i class="bi bi-eye"></i>' : '<i class="bi bi-eye-slash"></i>';
});
// Name validation
nameInput.addEventListener('blur', function() {
if (!this.value.trim()) {
this.classList.add('is-invalid');
document.getElementById('nameError').textContent = 'Full name is required.';
} else if (this.value.trim().length < 2) {
this.classList.add('is-invalid');
document.getElementById('nameError').textContent = 'Name must be at least 2 characters.';
} else {
this.classList.remove('is-invalid');
this.classList.add('is-valid');
}
});
// Email validation
emailInput.addEventListener('blur', function() {
if (!this.value) {
this.classList.add('is-invalid');
document.getElementById('emailError').textContent = 'Email is required.';
} else if (!isValidEmail(this.value)) {
this.classList.add('is-invalid');
document.getElementById('emailError').textContent = 'Please enter a valid email address.';
} else {
this.classList.remove('is-invalid');
this.classList.add('is-valid');
}
});
// Password validation and strength indicator
passwordInput.addEventListener('input', function() {
validatePassword();
checkPasswordMatch();
});
// Confirm password validation
confirmPasswordInput.addEventListener('input', checkPasswordMatch);
// Form submission
form.addEventListener('submit', function(e) {
let isValid = true;
// Validate name
if (!nameInput.value.trim() || nameInput.value.trim().length < 2) {
nameInput.classList.add('is-invalid');
isValid = false;
}
// Validate email
if (!emailInput.value || !isValidEmail(emailInput.value)) {
emailInput.classList.add('is-invalid');
isValid = false;
}
// Validate password
if (!validatePassword()) {
isValid = false;
}
// Validate password match
if (!checkPasswordMatch()) {
isValid = false;
}
if (!isValid) {
e.preventDefault();
// Add shake animation to invalid fields
const invalidFields = form.querySelectorAll('.is-invalid');
invalidFields.forEach(field => {
field.classList.add('shake');
setTimeout(() => {
field.classList.remove('shake');
}, 500);
});
}
});
// Helper function to validate email
function isValidEmail(email) {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
}
// Function to validate password and show strength
function validatePassword() {
const password = passwordInput.value;
let strength = 0;
let requirements = {
length: false,
uppercase: false,
lowercase: false,
number: false
};
// Check password length
if (password.length >= 8) {
strength++;
requirements.length = true;
document.getElementById('reqLength').classList.add('requirement-met');
document.getElementById('reqLength').classList.remove('requirement-unmet');
} else {
document.getElementById('reqLength').classList.add('requirement-unmet');
document.getElementById('reqLength').classList.remove('requirement-met');
}
// Check for uppercase letters
if (/[A-Z]/.test(password)) {
strength++;
requirements.uppercase = true;
document.getElementById('reqUppercase').classList.add('requirement-met');
document.getElementById('reqUppercase').classList.remove('requirement-unmet');
} else {
document.getElementById('reqUppercase').classList.add('requirement-unmet');
document.getElementById('reqUppercase').classList.remove('requirement-met');
}
// Check for lowercase letters
if (/[a-z]/.test(password)) {
strength++;
requirements.lowercase = true;
document.getElementById('reqLowercase').classList.add('requirement-met');
document.getElementById('reqLowercase').classList.remove('requirement-unmet');
} else {
document.getElementById('reqLowercase').classList.add('requirement-unmet');
document.getElementById('reqLowercase').classList.remove('requirement-met');
}
// Check for numbers
if (/[0-9]/.test(password)) {
strength++;
requirements.number = true;
document.getElementById('reqNumber').classList.add('requirement-met');
document.getElementById('reqNumber').classList.remove('requirement-unmet');
} else {
document.getElementById('reqNumber').classList.add('requirement-unmet');
document.getElementById('reqNumber').classList.remove('requirement-met');
}
// Update strength indicator
passwordStrength.className = 'password-strength';
if (password.length === 0) {
passwordStrength.style.width = '0';
} else if (strength <= 1) {
passwordStrength.classList.add('strength-weak');
} else if (strength <= 3) {
passwordStrength.classList.add('strength-medium');
} else {
passwordStrength.classList.add('strength-strong');
}
// Update password field validation
if (password.length === 0) {
passwordInput.classList.remove('is-valid', 'is-invalid');
return false;
} else if (strength < 4) {
passwordInput.classList.add('is-invalid');
passwordInput.classList.remove('is-valid');
document.getElementById('passwordError').textContent = 'Password does not meet all requirements.';
return false;
} else {
passwordInput.classList.remove('is-invalid');
passwordInput.classList.add('is-valid');
return true;
}
}
// Function to check if passwords match
function checkPasswordMatch() {
const password = passwordInput.value;
const confirmPassword = confirmPasswordInput.value;
if (confirmPassword.length === 0) {
confirmPasswordInput.classList.remove('is-valid', 'is-invalid');
return false;
} else if (password !== confirmPassword) {
confirmPasswordInput.classList.add('is-invalid');
confirmPasswordInput.classList.remove('is-valid');
document.getElementById('confirmPasswordError').textContent = 'Passwords do not match.';
return false;
} else {
confirmPasswordInput.classList.remove('is-invalid');
confirmPasswordInput.classList.add('is-valid');
return true;
}
}
});
</script>
</body>
</html>