0% found this document useful (0 votes)
7 views44 pages

SQL Database Schema for Planning App

The document outlines the SQL database schema for a planning application, including tables for admins, news, events, media, downloads, and contact messages. It also includes PHP scripts for handling admin login/logout, managing news and events, uploading media and downloads, and processing public messages. The document provides a comprehensive structure for both database and API interactions for the application.

Uploaded by

Bedilu Asnake
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views44 pages

SQL Database Schema for Planning App

The document outlines the SQL database schema for a planning application, including tables for admins, news, events, media, downloads, and contact messages. It also includes PHP scripts for handling admin login/logout, managing news and events, uploading media and downloads, and processing public messages. The document provides a comprehensive structure for both database and API interactions for the application.

Uploaded by

Bedilu Asnake
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

-- SQL Database Schema

-- Create database

CREATE DATABASE IF NOT EXISTS planning_db CHARACTER SET utf8mb4 COLLATE


utf8mb4_unicode_ci;

USE planning_db;

-- Table for Admin (simple, hashed password)

CREATE TABLE admins (

id INT AUTO_INCREMENT PRIMARY KEY,

username VARCHAR(50) UNIQUE NOT NULL,

password VARCHAR(255) NOT NULL,

created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP

);

-- Insert default admin (username: admin, password: admin123 hashed with password_hash)

INSERT INTO admins (username, password) VALUES ('admin',


'$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/[Link]/igi'); -- Hashed 'admin123'

-- Table for News

CREATE TABLE news (

id INT AUTO_INCREMENT PRIMARY KEY,

title VARCHAR(255) NOT NULL,

content TEXT NOT NULL,

created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP

);

-- Table for Events


CREATE TABLE events (

id INT AUTO_INCREMENT PRIMARY KEY,

title VARCHAR(255) NOT NULL,

content TEXT NOT NULL,

event_date DATE NOT NULL,

created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP

);

-- Table for Media (Gallery and Carousel)

CREATE TABLE media (

id INT AUTO_INCREMENT PRIMARY KEY,

name VARCHAR(255) NOT NULL,

path VARCHAR(500) NOT NULL, -- Relative path to uploaded file

description VARCHAR(255),

type ENUM('gallery', 'carousel') NOT NULL,

uploaded_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP

);

-- Table for Downloads

CREATE TABLE downloads (

id INT AUTO_INCREMENT PRIMARY KEY,

name VARCHAR(255) NOT NULL,

path VARCHAR(500) NOT NULL,

description VARCHAR(255) NOT NULL,

uploaded_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP

);
-- Table for Contact Messages

CREATE TABLE messages (

id INT AUTO_INCREMENT PRIMARY KEY,

name VARCHAR(255) NOT NULL,

email VARCHAR(255) NOT NULL,

message TEXT NOT NULL,

created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP

);

-- Indexes for performance

CREATE INDEX idx_news_date ON news(created_at);

CREATE INDEX idx_events_date ON events(event_date, created_at);

CREATE INDEX idx_media_type ON media(type);

CREATE INDEX idx_messages_date ON messages(created_at);

php

<?php

// [Link] - Database Configuration

$host = 'localhost';

$dbname = 'planning_db';

$username = 'your_db_user'; // Replace with your DB username

$password = 'your_db_password'; // Replace with your DB password

try {

$pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8mb4", $username,


$password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

} catch (PDOException $e) {

die("Connection failed: " . $e->getMessage());

?>

php

<?php

// api/[Link] - Admin Login

session_start();

require_once '../[Link]';

header('Content-Type: application/json');

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {

http_response_code(405);

echo json_encode(['error' => 'Method not allowed']);

exit;

$input = json_decode(file_get_contents('php://input'), true);

$username = $input['username'] ?? '';

$password = $input['password'] ?? '';

if (empty($username) || empty($password)) {

echo json_encode(['error' => 'Missing credentials']);

exit;
}

$stmt = $pdo->prepare("SELECT id, password FROM admins WHERE username = ?");

$stmt->execute([$username]);

$admin = $stmt->fetch(PDO::FETCH_ASSOC);

if ($admin && password_verify($password, $admin['password'])) {

$_SESSION['admin_id'] = $admin['id'];

echo json_encode(['success' => true]);

} else {

echo json_encode(['error' => 'Invalid credentials']);

?>

php

<?php

// api/[Link] - Admin Logout

session_start();

session_destroy();

header('Content-Type: application/json');

echo json_encode(['success' => true]);

?>

php

<?php

// api/[Link] - Get and Post News (Admin only for post)

session_start();

require_once '../[Link]';
header('Content-Type: application/json');

$method = $_SERVER['REQUEST_METHOD'];

if ($method === 'GET') {

// Get all news

$stmt = $pdo->query("SELECT id, title, content, created_at FROM news ORDER BY created_at
DESC");

$news = $stmt->fetchAll(PDO::FETCH_ASSOC);

echo json_encode($news);

} elseif ($method === 'POST') {

// Check admin session

if (!isset($_SESSION['admin_id'])) {

http_response_code(401);

echo json_encode(['error' => 'Unauthorized']);

exit;

$input = json_decode(file_get_contents('php://input'), true);

$title = $input['title'] ?? '';

$content = $input['content'] ?? '';

if (empty($title) || empty($content)) {

echo json_encode(['error' => 'Missing fields']);

exit;
}

$stmt = $pdo->prepare("INSERT INTO news (title, content) VALUES (?, ?)");

$stmt->execute([$title, $content]);

echo json_encode(['success' => true, 'id' => $pdo->lastInsertId()]);

} else {

http_response_code(405);

echo json_encode(['error' => 'Method not allowed']);

?>

php

<?php

// api/[Link] - Get and Post Events (Admin only for post)

session_start();

require_once '../[Link]';

header('Content-Type: application/json');

$method = $_SERVER['REQUEST_METHOD'];

if ($method === 'GET') {

// Get all events

$stmt = $pdo->query("SELECT id, title, content, event_date, created_at FROM events ORDER
BY event_date ASC");

$events = $stmt->fetchAll(PDO::FETCH_ASSOC);

echo json_encode($events);
} elseif ($method === 'POST') {

// Check admin session

if (!isset($_SESSION['admin_id'])) {

http_response_code(401);

echo json_encode(['error' => 'Unauthorized']);

exit;

$input = json_decode(file_get_contents('php://input'), true);

$title = $input['title'] ?? '';

$content = $input['content'] ?? '';

$event_date = $input['event_date'] ?? '';

if (empty($title) || empty($content) || empty($event_date)) {

echo json_encode(['error' => 'Missing fields']);

exit;

$stmt = $pdo->prepare("INSERT INTO events (title, content, event_date) VALUES (?, ?, ?)");

$stmt->execute([$title, $content, $event_date]);

echo json_encode(['success' => true, 'id' => $pdo->lastInsertId()]);

} else {

http_response_code(405);

echo json_encode(['error' => 'Method not allowed']);

?>
php

<?php

// api/[Link] - Get and Post Media (Admin only for post, handles file upload)

session_start();

require_once '../[Link]';

header('Content-Type: application/json');

$method = $_SERVER['REQUEST_METHOD'];

$upload_dir = '../uploads/media/'; // Create this directory with 755 permissions

if (!is_dir($upload_dir)) {

mkdir($upload_dir, 0755, true);

if ($method === 'GET') {

$type = $_GET['type'] ?? null;

if ($type) {

$stmt = $pdo->prepare("SELECT id, name, path, description, type, uploaded_at FROM


media WHERE type = ? ORDER BY uploaded_at DESC");

$stmt->execute([$type]);

} else {

$stmt = $pdo->query("SELECT id, name, path, description, type, uploaded_at FROM media
ORDER BY uploaded_at DESC");

$media = $stmt->fetchAll(PDO::FETCH_ASSOC);

echo json_encode($media);

} elseif ($method === 'POST') {


// Check admin session

if (!isset($_SESSION['admin_id'])) {

http_response_code(401);

echo json_encode(['error' => 'Unauthorized']);

exit;

if (isset($_FILES['files']) && $_FILES['files']['error'] === UPLOAD_ERR_OK) {

$description = $_POST['description'] ?? '';

$type = $_POST['type'] ?? 'gallery';

$allowed_types = ['image/jpeg', 'image/png', 'image/gif', 'video/mp4', 'video/avi',


'video/mov'];

$max_size = 50 * 1024 * 1024; // 50MB

foreach ($_FILES['files']['tmp_name'] as $key => $tmp_name) {

if ($_FILES['files']['error'][$key] === UPLOAD_ERR_OK) {

$file_name = basename($_FILES['files']['name'][$key]);

$file_size = $_FILES['files']['size'][$key];

$file_type = $_FILES['files']['type'][$key];

$file_ext = strtolower(pathinfo($file_name, PATHINFO_EXTENSION));

if (!in_array($file_type, $allowed_types) || $file_size > $max_size) {

continue; // Skip invalid files

$new_name = uniqid() . '_' . $file_name;


$target_path = $upload_dir . $new_name;

if (move_uploaded_file($tmp_name, $target_path)) {

$stmt = $pdo->prepare("INSERT INTO media (name, path, description, type) VALUES


(?, ?, ?, ?)");

$stmt->execute([$file_name, $target_path, $description, $type]);

echo json_encode(['success' => true]);

} else {

echo json_encode(['error' => 'No file uploaded']);

} else {

http_response_code(405);

echo json_encode(['error' => 'Method not allowed']);

?>

php

<?php

// api/[Link] - Get and Post Downloads (Admin only for post, handles file upload)

session_start();

require_once '../[Link]';

header('Content-Type: application/json');

$method = $_SERVER['REQUEST_METHOD'];
$upload_dir = '../uploads/downloads/'; // Create this directory with 755 permissions

if (!is_dir($upload_dir)) {

mkdir($upload_dir, 0755, true);

if ($method === 'GET') {

// Get all downloads

$stmt = $pdo->query("SELECT id, name, path, description, uploaded_at FROM downloads


ORDER BY uploaded_at DESC");

$downloads = $stmt->fetchAll(PDO::FETCH_ASSOC);

echo json_encode($downloads);

} elseif ($method === 'POST') {

// Check admin session

if (!isset($_SESSION['admin_id'])) {

http_response_code(401);

echo json_encode(['error' => 'Unauthorized']);

exit;

if (isset($_FILES['file']) && $_FILES['file']['error'] === UPLOAD_ERR_OK) {

$description = $_POST['description'] ?? '';

$allowed_exts = ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'jpg', 'png', 'gif'];

$file_ext = strtolower(pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION));

$max_size = 50 * 1024 * 1024; // 50MB

if (!in_array($file_ext, $allowed_exts) || $_FILES['file']['size'] > $max_size) {


echo json_encode(['error' => 'Invalid file type or size']);

exit;

$file_name = basename($_FILES['file']['name']);

$new_name = uniqid() . '_' . $file_name;

$target_path = $upload_dir . $new_name;

if (move_uploaded_file($_FILES['file']['tmp_name'], $target_path)) {

$stmt = $pdo->prepare("INSERT INTO downloads (name, path, description) VALUES


(?, ?, ?)");

$stmt->execute([$file_name, $target_path, $description]);

echo json_encode(['success' => true, 'id' => $pdo->lastInsertId()]);

} else {

echo json_encode(['error' => 'Upload failed']);

} else {

echo json_encode(['error' => 'No file uploaded']);

} else {

http_response_code(405);

echo json_encode(['error' => 'Method not allowed']);

?>

php

<?php
// api/[Link] - Get and Post Messages (Public post, Admin get)

session_start();

require_once '../[Link]';

header('Content-Type: application/json');

$method = $_SERVER['REQUEST_METHOD'];

if ($method === 'GET') {

// Check admin session for get

if (!isset($_SESSION['admin_id'])) {

http_response_code(401);

echo json_encode(['error' => 'Unauthorized']);

exit;

// Get all messages

$stmt = $pdo->query("SELECT id, name, email, message, created_at FROM messages ORDER
BY created_at DESC");

$messages = $stmt->fetchAll(PDO::FETCH_ASSOC);

echo json_encode($messages);

} elseif ($method === 'POST') {

// Public post

$input = json_decode(file_get_contents('php://input'), true);

$name = $input['name'] ?? '';

$email = $input['email'] ?? '';

$message = $input['message'] ?? '';


if (empty($name) || empty($email) || empty($message)) {

echo json_encode(['error' => 'Missing fields']);

exit;

$stmt = $pdo->prepare("INSERT INTO messages (name, email, message) VALUES (?, ?, ?)");

$stmt->execute([$name, $email, $message]);

echo json_encode(['success' => true]);

} else {

http_response_code(405);

echo json_encode(['error' => 'Method not allowed']);

?>

php

<?php

// [Link] - Serve file downloads (protect with .htaccess if needed)

require_once '[Link]'; // Adjust path

$id = $_GET['id'] ?? 0;

if ($id) {

$stmt = $pdo->prepare("SELECT path, name FROM downloads WHERE id = ?");

$stmt->execute([$id]);

$download = $stmt->fetch(PDO::FETCH_ASSOC);

if ($download) {
header('Content-Type: application/octet-stream');

header('Content-Disposition: attachment; filename="' . $download['name'] . '"');

header('Content-Length: ' . filesize($download['path']));

readfile($download['path']);

exit;

http_response_code(404);

?>

html

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Planning and Development Bureau</title>

<style>

body {

font-family: Arial, sans-serif;

margin: 0;

padding: 0;

background-color: #f4f4f4;

header {

background-color: #333;

color: white;
padding: 10px;

display: flex;

justify-content: space-between;

align-items: center;

.logo {

font-size: 24px;

font-weight: bold;

nav ul {

list-style: none;

display: flex;

gap: 20px;

nav a {

color: white;

text-decoration: none;

padding: 10px;

nav a:hover {

background-color: #555;

#carousel {

position: relative;

max-width: 800px;

margin: 20px auto;


overflow: hidden;

border-radius: 10px;

height: 400px;

.slide {

position: absolute;

top: 0;

left: 0;

width: 100%;

height: 100%;

object-fit: cover;

transform: translateX(100%);

transition: transform 0.5s ease-in-out;

.[Link] {

transform: translateX(0%);

.prev, .next {

position: absolute;

top: 50%;

transform: translateY(-50%);

background-color: rgba(0,0,0,0.5);

color: white;

border: none;

padding: 10px;

cursor: pointer;
z-index: 10;

.prev {

left: 10px;

.next {

right: 10px;

main {

padding: 20px;

max-width: 1200px;

margin: 0 auto;

section {

margin-bottom: 40px;

#news, #events, #gallery, #downloads, #contacts, #departments {

background: white;

padding: 20px;

border-radius: 5px;

box-shadow: 0 2px 5px rgba(0,0,0,0.1);

form {

display: flex;

flex-direction: column;

gap: 10px;
max-width: 400px;

input, textarea, button, select {

padding: 10px;

border: 1px solid #ddd;

border-radius: 4px;

button {

background-color: #333;

color: white;

cursor: pointer;

button:hover {

background-color: #555;

.news-item, .event-item, .download-item, .message-item, .media-item {

border-bottom: 1px solid #ddd;

padding: 10px 0;

.media-item img, .media-item video {

max-width: 200px;

height: auto;

margin: 10px 0;

.admin-only {

display: none;
}

.admin-visible {

display: block;

#admin-login {

max-width: 300px;

margin: 0 auto;

.hidden {

display: none;

.division {

margin-bottom: 30px;

padding: 15px;

border: 1px solid #ddd;

border-radius: 5px;

.division h3 {

color: #333;

border-bottom: 2px solid #333;

padding-bottom: 5px;

.directorate-list {

list-style-type: disc;

padding-left: 20px;

}
footer {

background-color: #333;

color: white;

text-align: center;

padding: 10px;

position: fixed;

bottom: 0;

width: 100%;

</style>

</head>

<body>

<header>

<div class="logo">

<img src="[Link]" alt="Logo" width="50" height="50" style="margin-right: 10px;"> <!--


Replace with actual logo -->

Planning and Development Bureau

</div>

<nav>

<ul>

<li><a href="#" onclick="showPage('home')">Home</a></li>

<li><a href="#" onclick="showPage('departments')">Departments</a></li>

<li><a href="#" onclick="showPage('news')">News</a></li>

<li><a href="#" onclick="showPage('events')">Events</a></li>

<li><a href="#" onclick="showPage('gallery')">Gallery</a></li>


<li><a href="#" onclick="showPage('contacts')">Contacts</a></li>

<li><a href="#" onclick="showPage('downloads')">Downloads</a></li>

<li><a href="#" onclick="showPage('about')">About Us</a></li>

<li><a href="#" onclick="showPage('admin')">Admin</a></li>

</ul>

</nav>

</header>

<main>

<!-- Home Page -->

<div id="home" class="page">

<section id="carousel">

<!-- Slides loaded dynamically -->

<button class="prev" onclick="changeSlide(-1)">&#10094;</button>

<button class="next" onclick="changeSlide(1)">&#10095;</button>

</section>

</div>

<!-- Departments Page -->

<div id="departments" class="page hidden">

<h2>Departments</h2>

<div class="division">

<h3>Strategic Planning Division</h3>

<ul class="directorate-list">

<li>Directorate of Policy Analysis</li>

<li>Directorate of Research and Development</li>


<li>Directorate of Monitoring and Evaluation</li>

<li>Directorate of Data Management and Statistics</li>

</ul>

<p>This division focuses on long-term planning, policy formulation, and performance


tracking.</p>

</div>

<div class="division">

<h3>Infrastructure Development Division</h3>

<ul class="directorate-list">

<li>Directorate of Roads and Transportation</li>

<li>Directorate of Water Resources and Sanitation</li>

<li>Directorate of Energy and Power</li>

<li>Directorate of Urban and Rural Planning</li>

</ul>

<p>Responsible for developing and maintaining essential infrastructure across the


region.</p>

</div>

<div class="division">

<h3>Economic Development Division</h3>

<ul class="directorate-list">

<li>Directorate of Agriculture and Food Security</li>

<li>Directorate of Industry and Manufacturing</li>

<li>Directorate of Trade and Commerce</li>

<li>Directorate of Tourism and Cultural Affairs</li>

</ul>

<p>Aims to foster economic growth, job creation, and sustainable business


practices.</p>
</div>

<div class="division">

<h3>Human Resources and Administration Division</h3>

<ul class="directorate-list">

<li>Directorate of Personnel Management</li>

<li>Directorate of Finance and Budget</li>

<li>Directorate of Information Technology</li>

<li>Directorate of Legal and Compliance</li>

</ul>

<p>Manages internal operations, staff welfare, and administrative support.</p>

</div>

</div>

<!-- News Page -->

<div id="news" class="page hidden">

<h2>News</h2>

<div id="news-list">

<!-- News items loaded dynamically -->

</div>

</div>

<!-- Events Page -->

<div id="events" class="page hidden">

<h2>Events</h2>

<div id="events-list">

<!-- Event items loaded dynamically -->


</div>

</div>

<!-- Gallery Page -->

<div id="gallery" class="page hidden">

<h2>Gallery</h2>

<div id="gallery-list">

<!-- Media items loaded dynamically -->

</div>

</div>

<!-- Contacts Page -->

<div id="contacts" class="page hidden">

<h2>Contacts</h2>

<p>Contact us via the form below:</p>

<form id="contact-form">

<input type="text" id="contact-name" placeholder="Your Name" required>

<input type="email" id="contact-email" placeholder="Your Email" required>

<textarea id="contact-message" placeholder="Your Message" required></textarea>

<button type="button" onclick="sendMessage()">Send Message</button>

</form>

<p>Or email us at: info@[Link]</p>

</div>

<!-- Downloads Page -->

<div id="downloads" class="page hidden">


<h2>Downloads</h2>

<div id="download-list">

<!-- Download items loaded dynamically -->

</div>

</div>

<!-- About Us Page -->

<div id="about" class="page hidden">

<h2>About Us</h2>

<p>The Planning and Development Bureau is dedicated to fostering sustainable growth and
development through strategic planning, infrastructure enhancement, economic initiatives, and
efficient administration. Established to serve the community, we collaborate with stakeholders
to implement policies that drive progress and improve quality of life.</p>

<!-- Expanded static content to cover missing description points -->

</div>

<!-- Admin Page -->

<div id="admin" class="page hidden">

<h2>Admin Panel</h2>

<div id="admin-login">

<input type="text" id="admin-username" placeholder="Username">

<input type="password" id="admin-password" placeholder="Password">

<button onclick="loginAdmin()">Login</button>

</div>

<div id="admin-content" class="admin-only">

<button onclick="logoutAdmin()">Logout</button>

<h3>Manage Content</h3>
<!-- News Upload -->

<section>

<h4>Publish News</h4>

<form id="news-form">

<input type="text" id="news-title" placeholder="News Title" required>

<textarea id="news-content" placeholder="News Content" required></textarea>

<button type="button" onclick="publishNews()">Publish</button>

</form>

</section>

<!-- Events Upload -->

<section>

<h4>Publish Event</h4>

<form id="event-form">

<input type="text" id="event-title" placeholder="Event Title" required>

<textarea id="event-content" placeholder="Event Details" required></textarea>

<input type="date" id="event-date" required>

<button type="button" onclick="publishEvent()">Publish</button>

</form>

</section>

<!-- Media Upload -->

<section>

<h4>Upload Media</h4>

<form id="media-form" enctype="multipart/form-data">


<input type="file" id="media-upload" name="files" accept="image/*,video/*"
multiple required>

<input type="text" id="media-description" name="description" placeholder="Media


Description">

<select id="media-type" name="type">

<option value="gallery">Gallery</option>

<option value="carousel">Home Carousel</option>

</select>

<button type="button" onclick="uploadMedia()">Upload</button>

</form>

</section>

<!-- Documents Upload -->

<section>

<h4>Upload Document</h4>

<form id="upload-form" enctype="multipart/form-data">

<input type="file" id="file-upload" name="file"


accept=".pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.jpg,.png,.gif" required>

<input type="text" id="file-description" name="description" placeholder="File


Description" required>

<button type="button" onclick="uploadFile()">Upload</button>

</form>

</section>

<!-- Manage Messages -->

<section>

<h4>Manage User Messages</h4>


<div id="messages-list">

<!-- Messages loaded dynamically -->

</div>

</section>

</div>

</div>

</main>

<footer>

<p>Developed by: Your Name | Links: <a href="#" style="color: #ccc;">Privacy Policy</a> | <a
href="#" style="color: #ccc;">Terms of Service</a> | &copy; 2025 Planning and Development
Bureau</p>

</footer>

<script>

let currentSlide = 0;

let totalSlides = 0;

let slides = [];

let isAdmin = false;

const API_BASE = 'api/'; // Adjust if needed

// Utility function for API calls

async function apiCall(endpoint, options = {}) {

const response = await fetch(API_BASE + endpoint, options);

if (![Link]) {

throw new Error(`HTTP ${[Link]}`);

}
return await [Link]();

// Carousel functions

function initCarousel() {

slides = [Link]('.slide');

totalSlides = [Link];

if (totalSlides > 0) {

[Link]((slide, index) => {

[Link] = index === 0 ? 'translateX(0%)' : 'translateX(100%)';

if (index === 0) [Link]('active');

else [Link]('active');

});

currentSlide = 0;

function changeSlide(n) {

if (totalSlides <= 1) return;

let oldIndex = currentSlide;

currentSlide = (currentSlide + n + totalSlides) % totalSlides;

let newIndex = currentSlide;

let outTranslate = n > 0 ? '-100%' : '100%';

slides[oldIndex].[Link] = `translateX(${outTranslate})`;

slides[oldIndex].[Link]('active');
let inStart = n > 0 ? '100%' : '-100%';

slides[newIndex].[Link] = `translateX(${inStart})`;

slides[newIndex].offsetHeight;

slides[newIndex].[Link]('active');

slides[newIndex].[Link] = 'translateX(0%)';

setInterval(() => {

if (![Link]('home').[Link]('hidden') && totalSlides > 1) {

changeSlide(1);

}, 3000);

// Page navigation

function showPage(pageId) {

[Link]('.page').forEach(page => [Link]('hidden'));

[Link](pageId).[Link]('hidden');

if (pageId === 'home') loadCarouselMedia();

if (pageId === 'news') loadNews();

if (pageId === 'events') loadEvents();

if (pageId === 'gallery') loadGallery();

if (pageId === 'downloads') loadDownloads();

if (pageId === 'admin' && isAdmin) {

[Link]('admin-login').[Link]('hidden');

[Link]('admin-content').[Link]('admin-only');
loadMessages();

// Admin Login

async function loginAdmin() {

const username = [Link]('admin-username').value;

const password = [Link]('admin-password').value;

try {

const result = await apiCall('[Link]', {

method: 'POST',

headers: { 'Content-Type': 'application/json' },

body: [Link]({ username, password })

});

if ([Link]) {

isAdmin = true;

[Link]('admin-login').[Link]('hidden');

[Link]('admin-content').[Link]('admin-only');

loadMessages();

} else {

alert('Login failed');

} catch (err) {

alert('Error: ' + [Link]);

}
async function logoutAdmin() {

await apiCall('[Link]', { method: 'POST' });

isAdmin = false;

[Link]('admin-login').[Link]('hidden');

[Link]('admin-content').[Link]('admin-only');

// News

async function publishNews() {

const title = [Link]('news-title').value;

const content = [Link]('news-content').value;

try {

await apiCall('[Link]', {

method: 'POST',

headers: { 'Content-Type': 'application/json' },

body: [Link]({ title, content })

});

[Link]('news-form').reset();

loadNews();

} catch (err) {

alert('Error publishing news');

async function loadNews() {


try {

const news = await apiCall('[Link]');

const list = [Link]('news-list');

[Link] = '';

[Link](item => {

const div = [Link]('div');

[Link]('news-item');

[Link] = `<h3>${[Link]}</h3><p>${[Link]}</p><small>${new
Date(item.created_at).toLocaleDateString()}</small>`;

[Link](div);

});

} catch (err) {

[Link]('Error loading news');

// Events (similar)

async function publishEvent() {

const title = [Link]('event-title').value;

const content = [Link]('event-content').value;

const event_date = [Link]('event-date').value;

try {

await apiCall('[Link]', {

method: 'POST',

headers: { 'Content-Type': 'application/json' },

body: [Link]({ title, content, event_date })


});

[Link]('event-form').reset();

loadEvents();

} catch (err) {

alert('Error publishing event');

async function loadEvents() {

try {

const events = await apiCall('[Link]');

const list = [Link]('events-list');

[Link] = '';

[Link](item => {

const div = [Link]('div');

[Link]('event-item');

[Link] = `<h3>${[Link]}</h3><p>${[Link]}</p><small>Date: $
{item.event_date} | Posted: ${new Date(item.created_at).toLocaleDateString()}</small>`;

[Link](div);

});

} catch (err) {

[Link]('Error loading events');

// Media
async function uploadMedia() {

const formData = new FormData();

const files = [Link]('media-upload').files;

const description = [Link]('media-description').value;

const type = [Link]('media-type').value;

for (let file of files) {

[Link]('files[]', file);

[Link]('description', description);

[Link]('type', type);

try {

await apiCall('[Link]', { method: 'POST', body: formData });

[Link]('media-form').reset();

loadGallery();

if (type === 'carousel') loadCarouselMedia();

} catch (err) {

alert('Error uploading media');

async function loadGallery() {

try {

const media = await apiCall('[Link]?type=gallery');

const list = [Link]('gallery-list');


[Link] = '';

[Link](item => {

const div = [Link]('div');

[Link]('media-item');

if ([Link](/\.(mp4|avi|mov)$/i)) {

[Link] = `<video controls><source src="${[Link]}"


type="video/mp4"></video><p>${[Link]}</p>`;

} else {

[Link] = `<img src="${[Link]}" alt="${[Link]}"><p>$


{[Link]}</p>`;

[Link](div);

});

} catch (err) {

[Link]('Error loading gallery');

async function loadCarouselMedia() {

try {

const media = await apiCall('[Link]?type=carousel');

const carousel = [Link]('carousel');

const existingSlides = [Link]('.slide');

[Link](slide => [Link]());

[Link](0, 10).forEach(item => { // Limit to 10

if ([Link](/\.(jpg|jpeg|png|gif)$/i)) {
const img = [Link]('img');

[Link] = [Link];

[Link] = [Link];

[Link]('slide');

[Link](img);

});

initCarousel();

} catch (err) {

[Link]('Error loading carousel');

// Downloads

async function uploadFile() {

const formData = new FormData();

const file = [Link]('file-upload').files[0];

const description = [Link]('file-description').value;

[Link]('file', file);

[Link]('description', description);

try {

await apiCall('[Link]', { method: 'POST', body: formData });

[Link]('upload-form').reset();

loadDownloads();
} catch (err) {

alert('Error uploading file');

async function loadDownloads() {

try {

const downloads = await apiCall('[Link]');

const list = [Link]('download-list');

[Link] = '';

[Link](item => {

const div = [Link]('div');

[Link]('download-item');

[Link] = `<p><strong>${[Link]}</strong> - <a href="[Link]?


id=${[Link]}" download="${[Link]}">Download ${[Link]}</a></p><small>Uploaded: $
{new Date(item.uploaded_at).toLocaleDateString()}</small>`;

[Link](div);

});

} catch (err) {

[Link]('Error loading downloads');

// Messages

async function sendMessage() {

const name = [Link]('contact-name').value;

const email = [Link]('contact-email').value;


const message = [Link]('contact-message').value;

try {

await apiCall('[Link]', {

method: 'POST',

headers: { 'Content-Type': 'application/json' },

body: [Link]({ name, email, message })

});

alert('Message sent successfully!');

[Link]('contact-form').reset();

} catch (err) {

alert('Error sending message');

async function loadMessages() {

try {

const messages = await apiCall('[Link]');

const list = [Link]('messages-list');

[Link] = '';

[Link](item => {

const div = [Link]('div');

[Link]('message-item');

[Link] = `<h4>From: ${[Link]} (${[Link]})</h4><p>$


{[Link]}</p><small>${new Date(item.created_at).toLocaleDateString()}</small><hr>`;

[Link](div);

});
} catch (err) {

[Link]('Error loading messages');

// Initialize

[Link] = function() {

showPage('home');

loadNews();

loadEvents();

loadGallery();

loadDownloads();

loadCarouselMedia();

};

</script>

</body>

</html>

Additional Points Addressed from Original Description

 File Formats: Upload handler in [Link] and [Link] explicitly checks for PDF,
DOC/DOCX, XLS/XLSX, PPT/PPTX, and images (JPG/PNG/GIF). Videos (MP4/AVI/MOV)
added for gallery as per updates.

 Security: Admin login uses PHP sessions and password_verify. File uploads validate
types/sizes. Use HTTPS in production. Add CAPTCHA to contact form if needed.

 Events Happening/Happened: Events table stores event_date; query sorts by it. Display
past/future based on current date (e.g., filter in JS if desired).

 Interactive Website: Retained single-page app feel with AJAX/fetch for dynamic loads.
Carousel flips sides as updated.
 Missing Static Content: Expanded About Us with a brief description. Footer links to
Privacy/Terms (static placeholders; add pages if needed).

 Admin Management: Full CRUD simulation (post/get); extend with delete/edit via
additional endpoints if required.

Deployment Steps

1. Prepare Server Environment:

o Choose a hosting provider (e.g., shared hosting like Bluehost, or VPS like
DigitalOcean) with PHP 8.0+, MySQL 5.7+, and Apache/Nginx.

o Ensure mod_rewrite (for .htaccess) and file upload limits


(upload_max_filesize=50M in [Link]).

2. Set Up Database:

o Log into cPanel/phpMyAdmin (or MySQL Workbench for VPS).

o Create database planning_db.

o Run the SQL schema above to create tables and insert default admin (username:
admin, password: admin123).

3. Upload Files:

o Create directories: /uploads/media/ and /uploads/downloads/ with 755


permissions (chmod via FTP/cPanel).

o Upload all PHP files ([Link], api/*.php, [Link], [Link] renamed


to [Link]) to root directory via FTP (e.g., FileZilla).

o Update [Link] with your DB credentials.

o Add [Link] and initial photos to root (optional; carousel loads from DB).

4. Configure Server:

o In cPanel: Set document root to public_html.

o For security: Add .htaccess to deny access to api/ (or use folder permissions).
Example .htaccess in root:

text

<Files "[Link]">

Order allow,deny
Deny from all

</Files>

o Test locally with XAMPP/WAMP if possible.

5. Domain Configuration:

o Register domain (e.g., via GoDaddy) if not already.

o In hosting control panel: Add domain, point nameservers to host (e.g.,


[Link]).

o Update DNS: Add A record for domain to server IP (propagates in 1-48 hours).

o For subdomain (e.g., www): Add CNAME to @.

o SSL: Enable free Let's Encrypt via cPanel for HTTPS.

6. Test and Go Live:

o Access via IP first, then domain.

o Test: Login as admin, upload files, submit contact, view pages.

o Monitor errors in server logs (cPanel > Errors).

o Backup: Schedule DB backups in cPanel.

For production, consider adding error logging, input sanitization (already PDO-prepared), and
email integration (e.g., PHPMailer for real contact emails). If issues, check PHP error logs.

You might also like