diff --git a/.htaccess b/.htaccess index bcb83e73..a32cebe2 100644 --- a/.htaccess +++ b/.htaccess @@ -98,6 +98,9 @@ RewriteRule ^admin_transactions$ src/admin/admin_transactions.php [L] RewriteRule ^admin_trips$ src/admin/admin_trips.php [L] RewriteRule ^manage_events$ src/admin/manage_events.php [L] RewriteRule ^manage_trips$ src/admin/manage_trips.php [L] +RewriteRule ^admin_courses$ /src/admin/admin_courses.php [L,QSA] +RewriteRule ^manage_courses$ /src/admin/manage_courses.php [L,QSA] + # === API/AJAX ENDPOINTS === RewriteRule ^fetch_users$ src/api/fetch_users.php [L] @@ -108,6 +111,8 @@ RewriteRule ^get_tab_total$ src/api/get_tab_total.php [L] RewriteRule ^google_validate_login$ src/api/google_validate_login.php [L] # === PROCESSORS === +RewriteRule ^process_course$ /src/processors/process_course.php [L,QSA] +RewriteRule ^delete_course$ /src/processors/delete_course.php [L,QSA] RewriteRule ^validate_login$ src/processors/validate_login.php [L] RewriteRule ^register_user$ src/processors/register_user.php [L] RewriteRule ^process_application$ src/processors/process_application.php [L] diff --git a/header.php b/header.php index 17930744..d2f04ee0 100644 --- a/header.php +++ b/header.php @@ -286,6 +286,7 @@ if ($headerStyle === 'light') {
  • Manage Blogs
  • Manage Events
  • Manage Trips
  • +
  • Manage Courses
  • Trip Bookings
  • Course Bookings
  • iKhokha Payment History
  • diff --git a/index.php b/index.php index 129dbef9..22e270d6 100644 --- a/index.php +++ b/index.php @@ -90,7 +90,7 @@ if (!empty($bannerImages)) {
    Logo

    - Welcome to
    the 4 Wheel Drive Club
    of Southern Africa + Welcome to
    the Four Wheel Drive Club
    of Southern Africa

    Become a Member diff --git a/src/admin/admin_courses.php b/src/admin/admin_courses.php new file mode 100644 index 00000000..281c7890 --- /dev/null +++ b/src/admin/admin_courses.php @@ -0,0 +1,161 @@ + 'index']]; +require_once($rootPath . '/components/banner.php'); + +// Fetch all courses +$courses_query = " + SELECT + course_id, course_type, date, capacity, booked, cost_members, cost_nonmembers, instructor, instructor_email, code + FROM courses + ORDER BY date DESC +"; + +$result = $conn->query($courses_query); +$courses = []; +if ($result && $result->num_rows > 0) { + while ($row = $result->fetch_assoc()) { + $courses[] = $row; + } +} +?> + + +
    +
    +
    +
    + + + + +
    + + × +
    + + + 0): ?> + +
    + +
    +
    +
    +
    +
    +
    +
    +
    +

    + Instructor: ()
    + Capacity: /   Available:
    + Costs: Members: R | Non-Members: R +

    + +
    +
    + +
    + +
    +

    No courses found. Create one

    +
    + + +
    + +
    +
    +
    + + + + + + diff --git a/src/admin/manage_courses.php b/src/admin/manage_courses.php new file mode 100644 index 00000000..df1f726f --- /dev/null +++ b/src/admin/manage_courses.php @@ -0,0 +1,154 @@ +prepare("SELECT * FROM courses WHERE course_id = ?"); + $stmt->bind_param("i", $course_id); + $stmt->execute(); + $result = $stmt->get_result(); + if ($result->num_rows > 0) { + $course = $result->fetch_assoc(); + } + $stmt->close(); +} +?> + + 'index'], ['Admin' => 'admin_courses'], [$pageTitle => '']]; + require_once($rootPath . '/components/banner.php'); +?> + + +
    +
    +
    +
    +
    +
    + + + + + +
    +

    +
    +
    + +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    + +
    +
    + + +
    +
    +
    +
    + + +
    +
    + +
    +
    + + +
    +
    +
    +
    + + +
    +
    + +
    +
    + + +
    +
    +
    +
    + + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + + + + diff --git a/src/processors/delete_course.php b/src/processors/delete_course.php new file mode 100644 index 00000000..5bf809b6 --- /dev/null +++ b/src/processors/delete_course.php @@ -0,0 +1,49 @@ + 'error', 'message' => 'Unauthorized access']); + exit; +} + +$user_role = getUserRole(); +if (!in_array($user_role, ['admin', 'superadmin'])) { + ob_end_clean(); + echo json_encode(['status' => 'error', 'message' => 'Unauthorized access']); + exit; +} + +try { + $course_id = intval($_POST['course_id'] ?? 0); + + if ($course_id <= 0) { + throw new Exception('Invalid course ID'); + } + + $stmt = $conn->prepare("DELETE FROM courses WHERE course_id = ?"); + $stmt->bind_param("i", $course_id); + + if (!$stmt->execute()) { + throw new Exception('Failed to delete course: ' . $stmt->error); + } + + $stmt->close(); + + ob_end_clean(); + echo json_encode(['status' => 'success', 'message' => 'Course deleted successfully']); + +} catch (Exception $e) { + ob_end_clean(); + echo json_encode(['status' => 'error', 'message' => $e->getMessage()]); +} + +?> diff --git a/src/processors/process_course.php b/src/processors/process_course.php new file mode 100644 index 00000000..5c93080a --- /dev/null +++ b/src/processors/process_course.php @@ -0,0 +1,84 @@ + 'error', 'message' => 'Unauthorized access']); + exit; +} + +$user_role = getUserRole(); +if (!in_array($user_role, ['admin', 'superadmin'])) { + ob_end_clean(); + echo json_encode(['status' => 'error', 'message' => 'Unauthorized access']); + exit; +} + +try { + $course_id = $_POST['course_id'] ?? null; + $course_type = trim($_POST['course_type'] ?? ''); + $code = trim($_POST['code'] ?? ''); + $date = trim($_POST['date'] ?? ''); + $capacity = intval($_POST['capacity'] ?? 0); + $cost_members = floatval($_POST['cost_members'] ?? 0); + $cost_nonmembers = floatval($_POST['cost_nonmembers'] ?? 0); + $instructor = trim($_POST['instructor'] ?? ''); + $instructor_email = trim($_POST['instructor_email'] ?? ''); + + $allowed_types = ['driver_training','bush_mechanics','rescue_recovery','ladies_driver_training']; + + if (!in_array($course_type, $allowed_types)) { + throw new Exception('Invalid course type'); + } + + if (empty($date) || !preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) { + throw new Exception('Invalid date format'); + } + + if ($capacity <= 0) { + throw new Exception('Capacity must be greater than 0'); + } + + if (empty($instructor)) { + throw new Exception('Instructor name is required'); + } + + if ($course_id) { + // Update + $stmt = $conn->prepare("UPDATE courses SET course_type = ?, code = ?, date = ?, capacity = ?, cost_members = ?, cost_nonmembers = ?, instructor = ?, instructor_email = ? WHERE course_id = ?"); + $stmt->bind_param("sssiddssi", $course_type, $code, $date, $capacity, $cost_members, $cost_nonmembers, $instructor, $instructor_email, $course_id); + + if (!$stmt->execute()) { + throw new Exception('Failed to update course: ' . $stmt->error); + } + $stmt->close(); + } else { + // Insert - booked defaults to 0 + $stmt = $conn->prepare("INSERT INTO courses (course_type, code, date, capacity, booked, cost_members, cost_nonmembers, instructor, instructor_email) VALUES (?, ?, ?, ?, 0, ?, ?, ?, ?)"); + $stmt->bind_param("sssiddss", $course_type, $code, $date, $capacity, $cost_members, $cost_nonmembers, $instructor, $instructor_email); + + if (!$stmt->execute()) { + throw new Exception('Failed to create course: ' . $stmt->error); + } + + $course_id = $conn->insert_id; + $stmt->close(); + } + + ob_end_clean(); + echo json_encode(['status' => 'success', 'message' => $course_id ? 'Course saved successfully' : 'Course created successfully', 'course_id' => $course_id]); + +} catch (Exception $e) { + ob_end_clean(); + echo json_encode(['status' => 'error', 'message' => $e->getMessage()]); +} + +?>