DSP Project first push, date: 29/01/2026

This commit is contained in:
Sok Ponlork
2026-01-29 14:31:48 +07:00
parent 951262afb3
commit 644b624d2d
1857 changed files with 163516 additions and 0 deletions

562
index.php Normal file
View File

@@ -0,0 +1,562 @@
<?php
// index.php
// This file will serve as the main entry point for your application.
// It includes common elements like header, footer, and conditionally displays content.
session_start(); // Start the session at the very beginning
// Include necessary configuration and helper files
require_once 'config.php';
require_once 'includes/auth.php'; // Handles session checks and user roles
require_once 'classes/User.php';
require_once 'classes/Announcement.php';
require_once 'classes/Classifications.php'; // For data types and categories
require_once 'classes/Aboutus.php'; // For About Us content
require_once 'classes/Contactus.php'; // For Contact Us (Feedback)
require_once 'classes/Faq.php'; // For FAQ content
require_once 'classes/Slide.php'; // NEW: For carousel slides
require_once 'classes/DataSource.php'; // Still needed for actual data source browsing/permissions
// Instantiate classes
$user_manager = new User($pdo);
$announcement_manager = new Announcement($pdo);
$classification_manager = new Classifications($pdo);
$about_us_manager = new Aboutus($pdo);
$contact_us_manager = new Contactus($pdo);
$faq_manager = new Faq($pdo);
$slide_manager = new Slide($pdo); // NEW: Instantiate Slide class
$data_source_manager = new DataSource($pdo); // Keep DataSource for browsing actual data sources
// Determine which content to display based on URL or session
$page = $_GET['page'] ?? 'home'; // Default to home page
$is_logged_in = isset($_SESSION['user_id']);
$user_role = $_SESSION['user_status'] ?? 'Guest';
// Fetch data for the homepage (e.g., slides, announcements, classifications)
$slides = $slide_manager->getAllSlides(); // NEW: Get slides from database
// If no slides from DB, use placeholders
if (empty($slides)) {
$slides = [
['dspsslide_title_en' => 'Welcome to NIPH DSPS', 'dspsslide_description' => 'Your gateway to public health data and insights.', 'dspsslide_photoname' => 'https://placehold.co/1200x400/007bff/ffffff?text=Slide+1+-+Welcome'],
['dspsslide_title_en' => 'Discover Research Data', 'dspsslide_description' => 'Access a wide range of datasets for your studies.', 'dspsslide_photoname' => 'https://placehold.co/1200x400/28a745/ffffff?text=Slide+2+-+Data+Insights'],
['dspsslide_title_en' => 'Stay Informed', 'dspsslide_description' => 'Read the latest announcements and updates from NIPH.', 'dspsslide_photoname' => 'https://placehold.co/1200x400/ffc107/ffffff?text=Slide+3+-+Announcements'],
];
} else {
// Adjust photo path for display if coming from DB
foreach ($slides as &$slide) {
$slide['dspsslide_photoname'] = 'uploads/slides/' . $slide['dspsslide_photoname'];
}
unset($slide); // Unset reference
}
$announcements = $announcement_manager->getAllAnnouncements('Published', 3); // Get 3 latest published announcements
// If no announcements from DB, use placeholders
if (empty($announcements)) {
$announcements = [
['dspsann_title' => 'Important Update on Data Policy', 'dspsann_description' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.', 'dspsann_photopath' => 'https://placehold.co/400x250/6c757d/ffffff?text=Announcement+1'],
['dspsann_title' => 'New Data Sources Available', 'dspsann_description' => 'Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.', 'dspsann_photopath' => 'https://placehold.co/400x250/6c757d/ffffff?text=Announcement+2'],
['dspsann_title' => 'Upcoming Maintenance Schedule', 'dspsann_description' => 'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.', 'dspsann_photopath' => 'https://placehold.co/400x250/6c757d/ffffff?text=Announcement+3'],
];
} else {
// Adjust photo path for display if coming from DB
foreach ($announcements as &$ann) {
if (!empty($ann['dspsann_photopath'])) {
$ann['dspsann_photopath'] = 'uploads/announcements/' . $ann['dspsann_photopath'];
} else {
$ann['dspsann_photopath'] = 'https://placehold.co/400x250/6c757d/ffffff?text=No+Image';
}
}
unset($ann); // Unset reference
}
// Fetch data types for classifications section
$data_types = $classification_manager->getAllDataTypes(); // Use Classifications manager
if (empty($data_types)) {
$data_types = [
['dspstds_name_en' => 'CSV Data', 'icon' => 'fas fa-file-csv', 'color' => 'text-primary', 'description' => 'Explore tabular data in CSV format.'],
['dspstds_name_en' => 'JSON Data', 'icon' => 'fas fa-file-code', 'color' => 'text-success', 'description' => 'Access structured data in JSON format.'],
['dspstds_name_en' => 'API Endpoints', 'icon' => 'fas fa-code-branch', 'color' => 'text-warning', 'description' => 'Integrate with data via API interfaces.'],
['dspstds_name_en' => 'PDF Documents', 'icon' => 'fas fa-file-pdf', 'color' => 'text-danger', 'description' => 'View reports and documents in PDF.'],
];
} else {
// Map DB data to include placeholder icons/colors if not stored in DB
foreach ($data_types as &$type) {
switch ($type['dspstds_name_en']) {
case 'CSV': $type['icon'] = 'fas fa-file-csv'; $type['color'] = 'text-primary'; break;
case 'JSON': $type['icon'] = 'fas fa-file-code'; $type['color'] = 'text-success'; break;
case 'API': $type['icon'] = 'fas fa-code-branch'; $type['color'] = 'text-warning'; break;
case 'PDF': $type['icon'] = 'fas fa-file-pdf'; $type['color'] = 'text-danger'; break;
default: $type['icon'] = 'fas fa-file'; $type['color'] = 'text-secondary'; break;
}
$type['description'] = "Explore data of type " . htmlspecialchars($type['dspstds_name_en']) . ".";
}
unset($type); // Unset reference
}
// Fetch all categories for the filter dropdown
$all_categories = $classification_manager->getAllCategories();
/**
* Sanitises rich text content by allowing a limited subset of HTML tags.
*
* @param string|null $value
* @return string
*/
function dsp_render_rich_text(?string $value): string {
if ($value === null) {
return '';
}
$allowed = '<p><br><br/><strong><em><u><ol><ul><li><a><blockquote><table><thead><tbody><tr><td><th><span><div><h1><h2><h3><h4><h5><h6>';
return strip_tags($value, $allowed);
}
/**
* Converts rich text into a plain-text excerpt capped at the provided length.
*
* @param string|null $value
* @param int $limit
* @return string
*/
function dsp_plain_text_excerpt(?string $value, int $limit = 150): string {
$text = trim(strip_tags((string) $value));
if ($text === '') {
return '';
}
if (mb_strlen($text) > $limit) {
return mb_substr($text, 0, $limit) . '...';
}
return $text;
}
?>
<!DOCTYPE html>
<html lang="en">
<!-- Header -->
<?php
include_once("includes/header_public.php");
?>
<body>
<!-- Header (Sticky Navbar) -->
<?php
include_once("includes/nav_public.php");
?>
<!-- Login Modal -->
<div class="modal fade" id="loginModal" tabindex="-1" aria-labelledby="loginModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content rounded shadow-lg">
<div class="modal-header text-white rounded-top" style="background-color: #28a745;">
<h5 class="modal-title" id="loginModalLabel">Login to Your Account</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body p-4">
<form action="process_login.php" method="POST">
<div class="mb-3">
<label for="loginUsername" class="form-label">Username</label>
<input type="text" class="form-control rounded" id="loginUsername" name="username" required>
</div>
<div class="mb-3">
<label for="loginPassword" class="form-label">Password</label>
<input type="password" class="form-control rounded" id="loginPassword" name="password" required>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-primary rounded">Login</button>
</div>
</form>
</div>
<div class="modal-footer justify-content-center border-0">
<p class="text-muted mb-0">Don't have an account? <a href="#" data-bs-toggle="modal" data-bs-target="#registerModal" data-bs-dismiss="modal">Register here</a></p>
</div>
</div>
</div>
</div>
<!-- Register Modal -->
<div class="modal fade" id="registerModal" tabindex="-1" aria-labelledby="registerModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content rounded shadow-lg">
<div class="modal-header text-white rounded-top" style="background-color: #28a745;">
<h5 class="modal-title" id="registerModalLabel">Create New Account</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body p-4">
<form action="process_register.php" method="POST">
<div class="mb-3">
</div>
<div class="mb-3">
<label for="regFirstName" class="form-label">First Name (EN)</label>
<input type="text" class="form-control rounded" id="regFirstName" name="first_name_en" required>
</div>
<div class="mb-3">
<label for="regLastName" class="form-label">Last Name (EN)</label>
<input type="text" class="form-control rounded" id="regLastName" name="last_name_en" required>
</div>
<div class="mb-3">
<label for="regSex" class="form-label">Sex</label>
<select class="form-select rounded" id="regSex" name="sex" required>
<option value="">Select...</option>
<option value="Male">Male</option>
<option value="Female">Female</option>
<option value="Other">Other</option>
</select>
</div>
<div class="mb-3">
<label for="regDob" class="form-label">Date of Birth</label>
<input type="date" class="form-control rounded" id="regDob" name="dob" required>
</div>
<div class="mb-3">
<label for="regPhoneNumber" class="form-label">Phone Number</label>
<input type="tel" class="form-control rounded" id="regPhoneNumber" name="phone_number">
</div>
<div class="mb-3">
<label for="regEmail" class="form-label">Email address</label>
<input type="email" class="form-control rounded" id="regEmail" name="email">
</div>
<div class="mb-3">
<label for="regUsername" class="form-label">Username</label>
<input type="text" class="form-control rounded" id="regUsername" name="username" required>
</div>
<div class="mb-3">
<label for="regPassword" class="form-label">Password</label>
<input type="password" class="form-control rounded" id="regPassword" name="password" required>
</div>
<div class="mb-3">
<label for="regConfirmPassword" class="form-label">Confirm Password</label>
<input type="password" class="form-control rounded" id="regConfirmPassword" name="confirm_password" required>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-primary rounded">Register</button>
</div>
</form>
</div>
<div class="modal-footer justify-content-center border-0">
<p class="text-muted mb-0">Already have an account? <a href="#" data-bs-toggle="modal" data-bs-target="#loginModal" data-bs-dismiss="modal">Login here</a></p>
</div>
</div>
</div>
</div>
<!-- Main Content Area -->
<main class="container mt-4">
<?php if (isset($_SESSION['message'])): ?>
<div class="alert alert-<?= $_SESSION['message_type'] ?> alert-dismissible fade show rounded" role="alert">
<?= $_SESSION['message'] ?>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php
unset($_SESSION['message']);
unset($_SESSION['message_type']);
?>
<?php endif; ?>
<?php
// Display content based on the 'page' parameter
switch ($page) {
case 'home':
// Home Page - Carousel Slide
echo '<section id="home-carousel" class="mb-5">';
echo '<div id="carouselExampleCaptions" class="carousel slide rounded shadow-sm" data-bs-ride="carousel">';
echo '<div class="carousel-indicators">';
foreach ($slides as $index => $slide) {
echo '<button type="button" data-bs-target="#carouselExampleCaptions" data-bs-slide-to="' . $index . '" class="' . ($index == 0 ? 'active' : '') . '" aria-current="' . ($index == 0 ? 'true' : 'false') . '" aria-label="Slide ' . ($index + 1) . '"></button>';
}
echo '</div>';
echo '<div class="carousel-inner rounded">';
foreach ($slides as $index => $slide) {
// Use dspsslide_photoname directly as it's already adjusted with 'uploads/slides/'
echo '<div class="carousel-item ' . ($index == 0 ? 'active' : '') . '">';
echo '<img src="' . htmlspecialchars($slide['dspsslide_photoname']) . '" class="d-block w-100 rounded" alt="' . htmlspecialchars($slide['dspsslide_title_en']) . '">';
echo '<div class="carousel-caption d-none d-md-block bg-dark bg-opacity-50 rounded p-2">';
echo '<h5>' . htmlspecialchars($slide['dspsslide_title_en']) . '</h5>';
echo '<p>' . dsp_render_rich_text($slide['dspsslide_description']) . '</p>';
echo '</div>';
echo '</div>';
}
echo '</div>';
echo '<button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleCaptions" data-bs-slide="prev">';
echo '<span class="carousel-control-prev-icon" aria-hidden="true"></span>';
echo '<span class="visually-hidden">Previous</span>';
echo '</button>';
echo '<button class="carousel-control-next" type="button" data-bs-target="#carouselExampleCaptions" data-bs-slide="next">';
echo '<span class="carousel-control-next-icon" aria-hidden="true"></span>';
echo '<span class="visually-hidden">Next</span>';
echo '</button>';
echo '</div>';
echo '</section>';
// Latest Announcements Section
echo '<section class="my-5">';
echo '<h2 class="text-center mb-4">Latest Announcements</h2>';
echo '<div class="row row-cols-1 row-cols-md-3 g-4">';
foreach ($announcements as $announcement) {
echo '<div class="col">';
echo '<div class="card h-100 shadow-sm rounded">';
echo '<img src="' . htmlspecialchars($announcement['dspsann_photopath']) . '" class="card-img-top rounded-top" alt="' . htmlspecialchars($announcement['dspsann_title']) . '">';
echo '<div class="card-body">';
echo '<h5 class="card-title">' . htmlspecialchars($announcement['dspsann_title']) . '</h5>';
echo '<p class="card-text">' . htmlspecialchars(dsp_plain_text_excerpt($announcement['dspsann_description'], 150)) . '</p>';
echo '<a href="index.php?page=announcements&id=' . ($announcement['pkdspsann_id'] ?? '') . '" class="btn btn-primary rounded-pill">Read More</a>';
echo '</div>';
echo '</div>';
echo '</div>';
}
echo '</div>';
// Call-to-action cards under announcements
echo '<div class="row g-4 mt-2">';
echo ' <div class="col-12 col-md-6">';
echo ' <div class="card h-100 shadow-sm rounded border-success">';
echo ' <div class="card-body">';
echo ' <p class="text-uppercase text-muted small mb-1"><i class="fas fa-user-plus me-1"></i> New here?</p>';
echo ' <h5 class="card-title">Register a New Account</h5>';
echo ' <p class="card-text">Create your DSP profile to request datasets, run analytics in JupyterHub, and stay informed about the latest releases.</p>';
echo ' <a href="#" class="btn btn-success rounded-pill" data-bs-toggle="modal" data-bs-target="#registerModal">Start Registration</a>';
echo ' </div>';
echo ' </div>';
echo ' </div>';
$policyFile = 'uploads/policy/policy.pdf';
$policyExists = is_file($policyFile);
$policyLink = $policyExists ? $policyFile : '#';
$policyAttrs = $policyExists ? 'target="_blank" rel="noopener"' : 'aria-disabled="true"';
$policyBtnClass = $policyExists ? 'btn-primary' : 'btn-secondary disabled';
echo ' <div class="col-12 col-md-6">';
echo ' <div class="card h-100 shadow-sm rounded border-primary">';
echo ' <div class="card-body">';
echo ' <p class="text-uppercase text-muted small mb-1"><i class="fas fa-file-alt me-1"></i> Policy &amp; Governance</p>';
echo ' <h5 class="card-title">Review the DSP Data Access Policy</h5>';
echo ' <p class="card-text">Understand the legal, privacy, and usage conditions before requesting or sharing datasets on the platform.</p>';
echo " <a href='" . htmlspecialchars($policyLink, ENT_QUOTES, 'UTF-8') . "' class='btn " . $policyBtnClass . " rounded-pill' $policyAttrs><i class='fas fa-file-pdf me-2'></i>Download Policy</a>";
echo ' </div>';
echo ' </div>';
echo ' </div>';
echo '</div>';
echo '</section>';
break;
case 'announcements':
// Announcements Page (List all or show single)
echo '<h2 class="text-center mb-4">All Announcements</h2>';
if (isset($_GET['id'])) {
$announcement_id = filter_var($_GET['id'], FILTER_SANITIZE_NUMBER_INT);
$single_announcement = $announcement_manager->getAnnouncementById($announcement_id);
if ($single_announcement) {
// Adjust photo path for display
$photo_path = !empty($single_announcement['dspsann_photopath']) ? 'uploads/announcements/' . $single_announcement['dspsann_photopath'] : 'https://placehold.co/800x400/6c757d/ffffff?text=No+Image';
echo '<div class="card shadow-sm rounded mb-4">';
echo '<img src="' . htmlspecialchars($photo_path) . '" class="card-img-top rounded-top" alt="' . htmlspecialchars($single_announcement['dspsann_title']) . '">';
echo '<div class="card-body">';
echo '<h1 class="card-title">' . htmlspecialchars($single_announcement['dspsann_title']) . '</h1>';
echo '<p class="card-text text-muted">Published: ' . date('F j, Y', strtotime($single_announcement['dspsann_reg_datetime'])) . '</p>';
echo '<div class="card-text">' . dsp_render_rich_text($single_announcement['dspsann_description']) . '</div>';
echo '<a href="index.php?page=announcements" class="btn btn-secondary mt-3 rounded-pill"><i class="fas fa-arrow-left me-2"></i>Back to Announcements</a>';
echo '</div>';
echo '</div>';
} else {
echo '<div class="alert alert-warning rounded">Announcement not found.</div>';
}
} else {
$all_announcements = $announcement_manager->getAllAnnouncements('Published');
if (!empty($all_announcements)) {
echo '<div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 g-4">';
foreach ($all_announcements as $announcement) {
// Adjust photo path for display
$photo_path = !empty($announcement['dspsann_photopath']) ? 'uploads/announcements/' . $announcement['dspsann_photopath'] : 'https://placehold.co/400x250/6c757d/ffffff?text=No+Image';
echo '<div class="col">';
echo '<div class="card h-100 shadow-sm rounded">';
echo '<img src="' . htmlspecialchars($photo_path) . '" class="card-img-top rounded-top" alt="' . htmlspecialchars($announcement['dspsann_title']) . '">';
echo '<div class="card-body">';
echo '<h5 class="card-title">' . htmlspecialchars($announcement['dspsann_title']) . '</h5>';
echo '<p class="card-text text-muted small">Published: ' . date('M d, Y', strtotime($announcement['dspsann_reg_datetime'])) . '</p>';
echo '<p class="card-text">' . htmlspecialchars(dsp_plain_text_excerpt($announcement['dspsann_description'], 100)) . '</p>';
echo '<a href="index.php?page=announcements&id=' . htmlspecialchars($announcement['pkdspsann_id']) . '" class="btn btn-primary rounded-pill">Read More</a>';
echo '</div>';
echo '</div>';
echo '</div>';
}
echo '</div>';
} else {
echo '<div class="alert alert-info rounded text-center">No announcements available at the moment.</div>';
}
}
break;
case 'classifications':
echo '<h2 class="text-center mb-4">Data Classifications</h2>';
echo '<p class="text-center lead">Explore data categorized by type and subject matter.</p>';
// Filter to browse data sources by category and search query
echo '<div class="card shadow-sm rounded mb-4 p-3">';
echo '<div class="card-body">';
echo '<form action="index.php" method="GET" class="row g-3 align-items-end">';
echo '<input type="hidden" name="page" value="browse_datasources">';
// Category filter dropdown
echo '<div class="col-md-4">';
echo '<label for="categoryFilter" class="form-label">Filter by Category:</label>';
echo '<select class="form-select rounded" id="categoryFilter" name="category_id">';
echo '<option value="">All Categories</option>';
foreach ($all_categories as $category) {
echo '<option value="' . htmlspecialchars($category['pkdspscate_id']) . '">';
echo htmlspecialchars($category['dspscate_title_en']);
echo '</option>';
}
echo '</select>';
echo '</div>';
// Search query input
echo '<div class="col-md-5">';
echo '<label for="searchQuery" class="form-label">Search by Title/Description:</label>';
echo '<input type="text" class="form-control rounded" id="searchQuery" name="search" placeholder="Enter keywords...">';
echo '</div>';
// Search button
echo '<div class="col-md-3 d-grid">';
echo '<button type="submit" class="btn btn-primary rounded"><i class="fas fa-search me-2"></i> Search Data</button>';
echo '</div>';
echo '</form>';
echo '</div>';
echo '</div>';
// Existing: List of Category cards
echo '<h3 class="text-center mt-5 mb-4">Data Categories</h3>';
echo '<div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 g-4 mt-4">';
$categories = $classification_manager->getAllCategories(); // Use Classifications manager
if (!empty($categories)) {
foreach ($categories as $category) {
echo '<div class="col">';
echo '<div class="card h-100 shadow-sm rounded p-3">';
echo '<div class="card-body text-center">';
echo '<i class="fas fa-folder fa-3x text-info mb-3"></i>'; // Generic icon for category
echo '<h5 class="card-title">' . htmlspecialchars($category['dspscate_title_en']) . '</h5>';
echo '<p class="card-text">' . htmlspecialchars($category['dspscate_details'] ?? 'No details provided.') . '</p>';
echo '<a href="index.php?page=browse_datasources&category_id=' . htmlspecialchars($category['pkdspscate_id']) . '" class="btn btn-outline-info rounded-pill mt-2">View Data Sources</a>';
echo '</div>';
echo '</div>';
echo '</div>';
}
} else {
echo '<div class="col-12"><div class="alert alert-info rounded text-center">No data categories defined yet.</div></div>';
}
echo '</div>';
/*
echo '<h3 class="text-center mt-5 mb-4">Data Source Types</h3>';
echo '<div class="row row-cols-1 row-cols-md-2 row-cols-lg-4 g-4 text-center">';
foreach ($data_types as $type) {
echo '<div class="col">';
echo '<div class="card h-100 shadow-sm rounded p-3">';
echo '<div class="card-body">';
echo '<i class="' . htmlspecialchars($type['icon']) . ' fa-3x ' . htmlspecialchars($type['color']) . ' mb-3"></i>';
echo '<h5 class="card-title">' . htmlspecialchars($type['dspstds_name_en']) . '</h5>';
echo '<p class="card-text">' . htmlspecialchars($type['description']) . '</p>';
echo '</div>';
echo '</div>';
echo '</div>';
}
echo '</div>';
*/
break;
case 'about':
echo '<h2 class="text-center mb-4">About Us</h2>';
$about_entries = $about_us_manager->getAllAboutUs();
if (!empty($about_entries)) {
foreach ($about_entries as $entry) {
echo '<div class="card shadow-sm rounded mb-3">';
echo '<div class="card-body">';
echo '<h3 class="card-title">' . htmlspecialchars($entry['dspsabout_title_en']) . '</h3>';
echo '<p class="card-text">' . dsp_render_rich_text($entry['dspsabout_description']) . '</p>';
echo '</div>';
echo '</div>';
}
} else {
echo '<div class="alert alert-info rounded text-center">No "About Us" content available yet.</div>';
}
break;
case 'contact':
echo '<h2 class="text-center mb-4">Contact Us</h2>';
?>
<div class="row">
<div class="accordion">
<div class="card shadow-sm rounded p-4">
<h4 class="mb-3">Send us a message</h4>
<form action="process_contact.php" method="POST">
<div class="mb-3">
<label for="contactName" class="form-label">Your Name</label>
<input type="text" class="form-control rounded" id="contactName" name="name" required>
</div>
<div class="mb-3">
<label for="contactEmail" class="form-label">Your Email (Optional)</label>
<input type="email" class="form-control rounded" id="contactEmail" name="email">
</div>
<div class="mb-3">
<label for="contactMessage" class="form-label">Message</label>
<textarea class="form-control rounded-3" id="contactMessage" name="message" rows="5" required></textarea>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-primary rounded">Send Message</button>
</div>
</form>
<hr class="my-4">
<h4 class="mb-3">Our Contact Information</h4>
<ul class="list-unstyled">
<li><i class="fas fa-map-marker-alt me-2"></i> St.(289), Phnom Penh, Cambodia</li>
<li><i class="fas fa-phone me-2"></i> +855 12 345 678</li>
<li><i class="fas fa-envelope me-2"></i> dac@niph.org.kh</li>
</ul>
</div>
</div>
</div>
<?php
break;
case 'faq':
echo '<h2 class="text-center mb-4">Frequently Asked Questions</h2>';
$faq_entries = $faq_manager->getAllFaqs();
if (!empty($faq_entries)) {
echo '<div class="accordion" id="faqAccordion">';
foreach ($faq_entries as $index => $entry) {
echo '<div class="accordion-item rounded shadow-sm mb-3">';
echo '<h2 class="accordion-header" id="heading' . $index . '">';
echo '<button class="accordion-button ' . ($index == 0 ? '' : 'collapsed') . ' rounded-top" type="button" data-bs-toggle="collapse" data-bs-target="#collapse' . $index . '" aria-expanded="' . ($index == 0 ? 'true' : 'false') . '" aria-controls="collapse' . $index . '">';
echo htmlspecialchars($entry['dspsfaq_title_en']);
echo '</button>';
echo '</h2>';
echo '<div id="collapse' . $index . '" class="accordion-collapse collapse ' . ($index == 0 ? 'show' : '') . '" aria-labelledby="heading' . $index . '" data-bs-parent="#faqAccordion">';
echo '<div class="accordion-body">';
echo dsp_render_rich_text($entry['dspsfaq_description']);
echo '</div>';
echo '</div>';
echo '</div>';
}
echo '</div>';
} else {
echo '<div class="alert alert-info rounded text-center">No FAQ entries available yet.</div>';
}
break;
case 'browse_datasources':
// This will be a public page for browsing data sources
include 'browse_datasources.php'; // Include the content from the data_user folder
break;
default:
// Fallback to home if page is not recognized
header("Location: index.php?page=home");
exit();
}
?>
</main>
<!-- Footer -->
<?php
include_once("includes/footer_public.php");
?>
</body>
</html>