diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 0000000..e4704a8
Binary files /dev/null and b/.DS_Store differ
diff --git a/Assets/css/style.css b/Assets/css/style.css
new file mode 100644
index 0000000..5ce57a6
--- /dev/null
+++ b/Assets/css/style.css
@@ -0,0 +1,581 @@
+
+ * {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ }
+
+ body {
+ background: #0e2f47;
+ font-family: "Segoe UI", Arial, sans-serif;
+ padding: 0;
+ min-height: 100vh;
+ }
+
+ .toggle-label {
+ color: #fff;
+ font-size: 13px;
+ font-weight: 600;
+ letter-spacing: 0.3px;
+ }
+
+ .toggle-switch {
+ position: relative;
+ width: 50px;
+ height: 26px;
+ background: rgba(255, 255, 255, 0.3);
+ border-radius: 13px;
+ cursor: pointer;
+ transition: background 0.3s ease;
+ }
+
+ .toggle-switch.active {
+ background: #67b7c8;
+ }
+
+ .toggle-slider {
+ position: absolute;
+ top: 3px;
+ left: 3px;
+ width: 20px;
+ height: 20px;
+ background: #fff;
+ border-radius: 50%;
+ transition: left 0.3s ease;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
+ }
+
+ .toggle-switch.active .toggle-slider {
+ left: 27px;
+ }
+
+ .device-icon {
+ font-size: 18px;
+ display: flex;
+ align-items: center;
+ }
+
+ .section-header {
+ text-align: center;
+ color: #fff;
+ padding: 60px 20px 40px;
+ }
+
+ .section-header h1 {
+ font-size: 42px;
+ font-weight: 500;
+ margin-bottom: 12px;
+ letter-spacing: -0.5px;
+ }
+
+ .section-header p {
+ color: #cfd8df;
+ font-size: 16px;
+ line-height: 1.6;
+ }
+
+ .main-container {
+ padding: 0 20px 60px;
+ }
+
+ .desktop-view {
+ display: none;
+ }
+
+ .desktop-view.active {
+ display: block;
+ }
+
+ .feature-wrapper {
+ background: #fff;
+ border-radius: 8px;
+ overflow: hidden;
+ max-width: 1200px;
+ margin: auto;
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
+ }
+
+ .desktop-row {
+ display: grid;
+ grid-template-columns: 1fr 1.2fr 1.5fr;
+ gap: 0;
+ min-height: 400px;
+ }
+ .feature-tabs {
+ background: #f6f6f6;
+ padding: 40px 30px;
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+ border-right: 1px solid #e9ecef;
+ }
+
+ .feature-tab {
+ background: #fff;
+ border-radius: 6px;
+ padding: 18px 20px;
+ display: flex;
+ align-items: center;
+ gap: 14px;
+ cursor: pointer;
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
+ position: relative;
+ transition: all 0.3s ease;
+ border-left: 4px solid transparent;
+ }
+
+ .feature-tab:hover {
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
+ transform: translateX(4px);
+ }
+
+ .feature-tab.active {
+ box-shadow: 0 4px 12px rgba(103, 183, 200, 0.2);
+ border-left: 4px solid #67b7c8;
+ }
+
+ .feature-tab.active::after {
+ content: "";
+ position: absolute;
+ right: -15px;
+ top: 50%;
+ transform: translateY(-50%);
+ width: 0;
+ height: 0;
+ border-style: solid;
+ border-width: 12px 0 12px 12px;
+ border-color: transparent transparent transparent #fff;
+ }
+
+ .feature-tab span {
+ font-weight: 600;
+ color: #1c2b36;
+ font-size: 15px;
+ }
+
+ .feature-tab-icon {
+ font-size: 24px;
+ min-width: 28px;
+ }
+
+ .feature-slider {
+ background: #67b7c8;
+ color: #fff;
+ padding: 50px 40px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ position: relative;
+ overflow: hidden;
+ }
+
+ .feature-slider::before {
+ content: "";
+ position: absolute;
+ top: -50%;
+ right: -50%;
+ width: 300px;
+ height: 300px;
+ background: rgba(255, 255, 255, 0.05);
+ border-radius: 50%;
+ animation: float 6s ease-in-out infinite;
+ }
+
+ @keyframes float {
+ 0%, 100% { transform: translateY(0px); }
+ 50% { transform: translateY(20px); }
+ }
+
+ .slider-content {
+ position: relative;
+ z-index: 1;
+ }
+
+ .feature-slider small {
+ background: rgba(0, 0, 0, 0.15);
+ padding: 8px 14px;
+ border-radius: 4px;
+ font-size: 11px;
+ letter-spacing: 0.6px;
+ font-weight: 600;
+ display: inline-block;
+ width: fit-content;
+ }
+
+ .feature-slider h2 {
+ font-size: 32px;
+ font-weight: 600;
+ margin: 24px 0 28px;
+ line-height: 1.3;
+ }
+
+ .feature-slider p {
+ font-size: 14px;
+ line-height: 1.6;
+ margin-bottom: 24px;
+ opacity: 0.95;
+ }
+
+ .learn-more {
+ color: #fff;
+ font-weight: 600;
+ text-decoration: none;
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ transition: gap 0.3s ease;
+ width: fit-content;
+ }
+
+ .learn-more:hover {
+ gap: 12px;
+ }
+
+ .slider-dots {
+ position: absolute;
+ bottom: 30px;
+ left: 40px;
+ display: flex;
+ gap: 10px;
+ }
+
+ .slider-dots span {
+ width: 10px;
+ height: 10px;
+ border-radius: 50%;
+ background: rgba(255, 255, 255, 0.5);
+ cursor: pointer;
+ transition: all 0.3s ease;
+ }
+
+ .slider-dots span.active {
+ background: #fff;
+ width: 28px;
+ border-radius: 5px;
+ }
+
+ .feature-image {
+ background-size: cover;
+ background-position: center;
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ color: rgba(255, 255, 255, 0.6);
+ font-size: 14px;
+ background: linear-gradient(135deg, #1a3a4a 0%, #0e2f47 100%);
+ overflow: hidden;
+ gap: 20px;
+ }
+
+ .feature-image img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ position: absolute;
+ inset: 0;
+ }
+
+ .image-overlay {
+ position: absolute;
+ inset: 0;
+ background: radial-gradient(circle at 60% 40%, rgba(103, 183, 200, 0.1) 0%, transparent 70%);
+ z-index: 1;
+ }
+
+ .insurance-toggle-section {
+ position: relative;
+ z-index: 2;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 12px;
+ }
+
+ .insurance-label {
+ font-size: 14px;
+ font-weight: 600;
+ letter-spacing: 0.3px;
+ color: #fff;
+ }
+
+ .insurance-toggle {
+ position: relative;
+ width: 60px;
+ height: 32px;
+ background: rgba(255, 255, 255, 0.2);
+ border-radius: 16px;
+ cursor: pointer;
+ transition: background 0.3s ease;
+ border: 2px solid rgba(255, 255, 255, 0.4);
+ }
+
+ .insurance-toggle.active {
+ background: rgba(255, 255, 255, 0.9);
+ }
+
+ .insurance-toggle-slider {
+ position: absolute;
+ top: 2px;
+ left: 2px;
+ width: 26px;
+ height: 26px;
+ background: #67b7c8;
+ border-radius: 50%;
+ transition: left 0.3s ease;
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
+ }
+
+ .insurance-toggle.active .insurance-toggle-slider {
+ left: 30px;
+ background: #67b7c8;
+ }
+
+ .mobile-view {
+ display: block;
+ }
+
+ .mobile-view.hidden {
+ display: none;
+ }
+
+ .accordion-wrapper {
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+ }
+
+ .accordion-item-custom {
+ background: #fff;
+ border-radius: 8px;
+ overflow: hidden;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
+ transition: all 0.3s ease;
+ }
+
+ .accordion-header-custom {
+ padding: 20px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ cursor: pointer;
+ background: #fff;
+ border: none;
+ width: 100%;
+ font-size: 16px;
+ font-weight: 600;
+ color: #1c2b36;
+ transition: background 0.3s ease;
+ text-align: left;
+ }
+
+ .accordion-header-custom:hover {
+ background: #f9f9f9;
+ }
+
+ .header-content {
+ display: flex;
+ align-items: center;
+ gap: 16px;
+ flex: 1;
+ }
+
+ .header-icon {
+ font-size: 28px;
+ min-width: 40px;
+ text-align: center;
+ }
+
+ .header-text {
+ flex: 1;
+ }
+
+ .toggle-icon {
+ width: 24px;
+ height: 24px;
+ min-width: 24px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: transform 0.3s ease;
+ }
+
+ .toggle-icon img {
+ width: 16px;
+ height: 16px;
+ object-fit: contain;
+ }
+
+ .accordion-body-custom {
+ max-height: 0;
+ overflow: hidden;
+ transition: max-height 0.4s ease, padding 0.4s ease;
+ background: #f8f9fa;
+ }
+
+ .accordion-item-custom.expanded .accordion-body-custom {
+ max-height: 800px;
+ padding: 24px 20px;
+ border-top: 1px solid #e9ecef;
+ }
+
+ .body-content {
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+ }
+
+ .tag {
+ background: #67b7c8;
+ color: #fff;
+ padding: 8px 14px;
+ border-radius: 4px;
+ font-size: 11px;
+ letter-spacing: 0.6px;
+ font-weight: 600;
+ display: inline-block;
+ width: fit-content;
+ }
+
+ .body-content h3 {
+ font-size: 18px;
+ font-weight: 600;
+ color: #1c2b36;
+ line-height: 1.4;
+ margin: 8px 0;
+ }
+
+ .body-content p {
+ font-size: 14px;
+ color: #555;
+ line-height: 1.6;
+ margin: 0;
+ }
+
+ .learn-more-link {
+ color: #67b7c8;
+ font-weight: 600;
+ text-decoration: none;
+ font-size: 14px;
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ margin-top: 8px;
+ transition: color 0.3s ease;
+ width: fit-content;
+ }
+
+ .learn-more-link:hover {
+ color: #4a98a8;
+ }
+
+ .image-placeholder {
+ width: 100%;
+ height: 200px;
+ background: linear-gradient(135deg, #67b7c8 0%, #4a98a8 100%);
+ border-radius: 6px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: rgba(255, 255, 255, 0.7);
+ font-size: 14px;
+ margin-top: 12px;
+ overflow: hidden;
+ }
+
+ .image-placeholder img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ }
+
+ @media (min-width: 992px) {
+ .section-header {
+ padding: 80px 40px 60px;
+ }
+
+ .section-header h1 {
+ font-size: 48px;
+ margin-bottom: 16px;
+ }
+
+ .section-header p {
+ font-size: 16px;
+ max-width: 600px;
+ margin: 0 auto;
+ }
+
+ .main-container {
+ padding: 0 40px 100px;
+ }
+
+ .mobile-view {
+ display: none;
+ }
+
+ .desktop-view {
+ display: block;
+ }
+
+ .desktop-view.active {
+ display: block;
+ }
+ }
+
+ @media (max-width: 991px) {
+ .device-toggle-container {
+ top: 15px;
+ right: 15px;
+ }
+
+ .section-header {
+ padding: 40px 20px 30px;
+ }
+
+ .section-header h1 {
+ font-size: 28px;
+ margin-bottom: 12px;
+ }
+
+ .section-header p {
+ font-size: 14px;
+ }
+
+ .main-container {
+ padding: 0 16px 40px;
+ }
+
+ .accordion-header-custom {
+ padding: 16px;
+ font-size: 15px;
+ }
+
+ .header-icon {
+ font-size: 24px;
+ }
+
+ .body-content h3 {
+ font-size: 16px;
+ }
+
+ .body-content p {
+ font-size: 13px;
+ }
+ }
+
+ @media (max-width: 480px) {
+ .device-toggle-container {
+ gap: 8px;
+ padding: 10px 14px;
+ font-size: 12px;
+ }
+
+ .toggle-label {
+ font-size: 11px;
+ }
+
+ .device-icon {
+ font-size: 16px;
+ }
+ }
diff --git a/Assets/images/DL-Communication.jpg b/Assets/images/DL-Communication.jpg
new file mode 100644
index 0000000..51b3b5b
Binary files /dev/null and b/Assets/images/DL-Communication.jpg differ
diff --git a/Assets/images/DL-Learning-1.jpg b/Assets/images/DL-Learning-1.jpg
new file mode 100644
index 0000000..755171f
Binary files /dev/null and b/Assets/images/DL-Learning-1.jpg differ
diff --git a/Assets/images/DL-Technology.jpg b/Assets/images/DL-Technology.jpg
new file mode 100644
index 0000000..a8d4354
Binary files /dev/null and b/Assets/images/DL-Technology.jpg differ
diff --git a/Assets/images/DL-learning.svg b/Assets/images/DL-learning.svg
new file mode 100644
index 0000000..bfeb0b5
--- /dev/null
+++ b/Assets/images/DL-learning.svg
@@ -0,0 +1,50 @@
+
+
+
+
diff --git a/Assets/images/DL-technology.svg b/Assets/images/DL-technology.svg
new file mode 100644
index 0000000..59f2ea5
--- /dev/null
+++ b/Assets/images/DL-technology.svg
@@ -0,0 +1,48 @@
+
+
+
+
diff --git a/Assets/images/arrow-right.svg b/Assets/images/arrow-right.svg
new file mode 100644
index 0000000..37d307b
--- /dev/null
+++ b/Assets/images/arrow-right.svg
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/Assets/images/cat_20251218202136_7112.jpg b/Assets/images/cat_20251218202136_7112.jpg
new file mode 100644
index 0000000..a8d4354
Binary files /dev/null and b/Assets/images/cat_20251218202136_7112.jpg differ
diff --git a/Assets/images/cat_20251218202503_9878.svg b/Assets/images/cat_20251218202503_9878.svg
new file mode 100644
index 0000000..bfeb0b5
--- /dev/null
+++ b/Assets/images/cat_20251218202503_9878.svg
@@ -0,0 +1,50 @@
+
+
+
+
diff --git a/Assets/images/minus-01.svg b/Assets/images/minus-01.svg
new file mode 100644
index 0000000..a0639ca
--- /dev/null
+++ b/Assets/images/minus-01.svg
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/Assets/images/plus-01.svg b/Assets/images/plus-01.svg
new file mode 100644
index 0000000..d80a766
--- /dev/null
+++ b/Assets/images/plus-01.svg
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/Assets/images/thumbnail.png b/Assets/images/thumbnail.png
new file mode 100644
index 0000000..b79a1c0
Binary files /dev/null and b/Assets/images/thumbnail.png differ
diff --git a/Assets/js/script.js b/Assets/js/script.js
new file mode 100644
index 0000000..17e13a6
--- /dev/null
+++ b/Assets/js/script.js
@@ -0,0 +1,128 @@
+
+
+ const deviceToggle = document.getElementById('deviceToggle');
+ const mobileView = document.getElementById('mobileView');
+ const desktopView = document.getElementById('desktopView');
+ let isDesktopMode = window.innerWidth >= 992;
+
+ // Initialize based on screen size
+ function initializeView() {
+ if (window.innerWidth >= 992) {
+ isDesktopMode = true;
+ deviceToggle.classList.add('active');
+ mobileView.classList.add('hidden');
+ desktopView.classList.add('active');
+ } else {
+ isDesktopMode = false;
+ deviceToggle.classList.remove('active');
+ mobileView.classList.remove('hidden');
+ desktopView.classList.remove('active');
+ }
+ }
+
+ // Toggle device view
+ deviceToggle.addEventListener('click', () => {
+ isDesktopMode = !isDesktopMode;
+ deviceToggle.classList.toggle('active');
+
+ if (isDesktopMode) {
+ mobileView.classList.add('hidden');
+ desktopView.classList.add('active');
+ } else {
+ mobileView.classList.remove('hidden');
+ desktopView.classList.remove('active');
+ }
+ });
+
+ // Mobile accordion functionality
+ const accordionItems = document.querySelectorAll('.accordion-item-custom');
+
+ function updateIconForItem(item) {
+ const toggleIcon = item.querySelector('.toggle-icon img');
+ const isExpanded = item.classList.contains('expanded');
+
+ if (isExpanded) {
+ toggleIcon.src = 'Assets/images/minus-01.svg';
+ toggleIcon.alt = 'Minus Icon';
+ } else {
+ toggleIcon.src = 'Assets/images/plus-01.svg';
+ toggleIcon.alt = 'Plus Icon';
+ }
+ }
+
+ accordionItems.forEach(item => {
+ const header = item.querySelector('.accordion-header-custom');
+ header.addEventListener('click', () => {
+ accordionItems.forEach(otherItem => {
+ if (otherItem !== item && otherItem.classList.contains('expanded')) {
+ otherItem.classList.remove('expanded');
+ updateIconForItem(otherItem);
+ }
+ });
+ item.classList.toggle('expanded');
+ updateIconForItem(item);
+ });
+ });
+
+ // Desktop tab and slider functionality
+ const tabs = document.querySelectorAll('.feature-tab');
+ const dots = document.querySelectorAll('.slider-dots span');
+ const sliderContent = document.querySelector('.slider-content');
+
+ const contentData = [
+ {
+ tag: 'DIGITAL LEARNING INFRASTRUCTURE',
+ title: 'Usability enhancement and Training for Transaction Portal for Customers',
+ desc: 'Our comprehensive training program ensures seamless adoption of the transaction portal with enhanced usability features.'
+ },
+ {
+ tag: 'TECHNOLOGY INFRASTRUCTURE',
+ title: 'Advanced Technology Solutions for Modern Business',
+ desc: 'Leverage cutting-edge technology infrastructure to streamline operations, enhance security, and drive innovation.'
+ },
+ {
+ tag: 'COMMUNICATION FRAMEWORK',
+ title: 'Seamless Communication Channels for Better Engagement',
+ desc: 'Connect with customers through multiple channels with our integrated communication framework for engagement.'
+ }
+ ];
+
+ function updateSlider(index) {
+ tabs.forEach((tab, i) => {
+ tab.classList.toggle('active', i === index);
+ });
+
+ dots.forEach((dot, i) => {
+ dot.classList.toggle('active', i === index);
+ });
+
+ const data = contentData[index];
+ sliderContent.innerHTML = `
+ ${data.tag}
+
${data.title}
+ ${data.desc}
+ Learn More →
+ `;
+ }
+
+ tabs.forEach((tab, index) => {
+ tab.addEventListener('click', () => updateSlider(index));
+ });
+
+ dots.forEach((dot, index) => {
+ dot.addEventListener('click', () => updateSlider(index));
+ });
+
+ // Insurance toggle functionality
+ const insuranceToggle = document.getElementById('insuranceToggle');
+ if (insuranceToggle) {
+ insuranceToggle.addEventListener('click', () => {
+ insuranceToggle.classList.toggle('active');
+ });
+ }
+
+ // Handle window resize
+ window.addEventListener('resize', initializeView);
+
+ // Initialize
+ initializeView();
diff --git a/admin/api/CategoryController.php b/admin/api/CategoryController.php
new file mode 100644
index 0000000..a3505e5
--- /dev/null
+++ b/admin/api/CategoryController.php
@@ -0,0 +1,95 @@
+ false, 'message' => 'Category name required'];
+ }
+
+ $iconUrl = null;
+
+ if (isset($_FILES['icon']) && $_FILES['icon']['error'] === UPLOAD_ERR_OK) {
+ if ($_FILES['icon']['size'] > 2 * 1024 * 1024) {
+ return ['success' => false, 'message' => 'Icon size must be under 2MB'];
+ }
+
+ $allowedMime = [
+ 'image/jpeg' => 'jpg',
+ 'image/png' => 'png',
+ 'image/webp' => 'webp',
+ 'image/svg+xml' => 'svg'
+];
+
+ $mimeType = mime_content_type($_FILES['icon']['tmp_name']);
+ if (!isset($allowedMime[$mimeType])) {
+ return ['success' => false, 'message' => 'Invalid image format'];
+ }
+
+ $uploadDir = __DIR__ . '/../../Assets/images/';
+ if (!is_dir($uploadDir)) {
+ mkdir($uploadDir, 0777, true);
+ }
+
+ $fileName = sprintf(
+ 'cat_%s_%s.%s',
+ date('YmdHis'),
+ random_int(1000, 9999),
+ $allowedMime[$mimeType]
+ );
+
+ $target = $uploadDir . $fileName;
+
+ if (!move_uploaded_file($_FILES['icon']['tmp_name'], $target)) {
+ return ['success' => false, 'message' => 'Icon upload failed'];
+ }
+
+ $iconUrl = 'Assets/images/' . $fileName;
+ }
+
+ /* ========= BASE PAYLOAD ========= */
+ $payload = [
+ 'name' => trim($data['name']),
+ 'description' => trim($data['description'] ?? ''),
+ 'display_order' => (int)($data['display_order'] ?? 1),
+ 'is_active' => !empty($data['is_active']) ? 1 : 0
+ ];
+
+ if ($iconUrl !== null) {
+ $payload['icon_url'] = $iconUrl;
+ }
+ if (!empty($data['id'])) {
+ $id = (int)$data['id'];
+
+ if ($iconUrl) {
+ $old = $db->fetch(
+ 'SELECT icon_url FROM categories WHERE id = :id',
+ ['id' => $id]
+ );
+
+ if (!empty($old['icon_url'])) {
+ $oldFile = __DIR__ . '/../../' . $old['icon_url'];
+ if (is_file($oldFile)) {
+ unlink($oldFile);
+ }
+ }
+ }
+
+ $db->update('categories', $payload, 'id = :id', ['id' => $id]);
+
+ return ['success' => true, 'message' => 'Category updated'];
+ }
+
+ $db->insert('categories', $payload);
+
+ return ['success' => true, 'message' => 'Category created'];
+}
+
+function deleteCategory(DatabaseUtility $db, int $id): array
+{
+ if ($id <= 0) {
+ return ['success' => false, 'message' => 'Invalid ID'];
+ }
+
+ $db->delete('categories', 'id = :id', ['id' => $id]);
+ return ['success' => true, 'message' => 'Category deleted'];
+}
diff --git a/admin/api/SettingsController.php b/admin/api/SettingsController.php
new file mode 100644
index 0000000..e5953a9
--- /dev/null
+++ b/admin/api/SettingsController.php
@@ -0,0 +1,107 @@
+ false, 'message' => 'Page title is required'];
+ }
+
+ $db->begin();
+
+ try {
+ $db->update(
+ 'settings',
+ ['setting_value' => $title],
+ 'setting_key = :key',
+ ['key' => 'site_title']
+ );
+
+ $db->update(
+ 'settings',
+ ['setting_value' => $description],
+ 'setting_key = :key',
+ ['key' => 'site_description']
+ );
+
+ $db->commit();
+
+ return ['success' => true, 'message' => 'Header updated successfully'];
+
+ } catch (Throwable $e) {
+ $db->rollback();
+ throw $e;
+ }
+}
+
+function getHeader(DatabaseUtility $db): array
+{
+ return [
+ 'site_title' => $db->getSetting('site_title'),
+ 'site_description' => $db->getSetting('site_description')
+ ];
+}
+
+function getSettings(DatabaseUtility $db): array
+{
+ return $db->fetch(
+ "SELECT *
+ FROM settings
+ WHERE id = 1"
+ ) ?? [
+ 'insurance_enabled' => 0,
+ 'max_topics_per_category' => 10,
+ 'slider_dots_count' => 3,
+ 'site_title' => '',
+ 'site_description' => ''
+ ];
+}
+function saveSettings(DatabaseUtility $db, array $data): array
+{
+ $payload = [
+ 'insurance_enabled' => !empty($data['insurance_enabled']) ? 1 : 0,
+ 'max_topics_per_category' => (int) ($data['max_topics_per_category'] ?? 10),
+ 'slider_dots_count' => (int) ($data['slider_dots_count'] ?? 3)
+ ];
+
+ try {
+ $db->begin();
+
+ $exists = $db->fetch(
+ "SELECT id FROM settings WHERE id = 1"
+ );
+
+ if ($exists) {
+ $db->update(
+ 'settings',
+ $payload,
+ 'id = :id',
+ ['id' => 1]
+ );
+ } else {
+ $db->insert(
+ 'settings',
+ array_merge(['id' => 1], $payload)
+ );
+ }
+
+ $db->commit();
+
+ return [
+ 'success' => true,
+ 'message' => 'Settings saved successfully'
+ ];
+
+ } catch (Throwable $e) {
+ $db->rollback();
+
+ return [
+ 'success' => false,
+ 'message' => 'Failed to save settings'
+ ];
+ }
+}
diff --git a/admin/api/TopicController.php b/admin/api/TopicController.php
new file mode 100644
index 0000000..c6c8f4c
--- /dev/null
+++ b/admin/api/TopicController.php
@@ -0,0 +1,103 @@
+fetchAll(
+ "SELECT *
+ FROM topics
+ ORDER BY display_order ASC, id ASC"
+ );
+}
+
+function saveTopic(DatabaseUtility $db, array $data): array
+{
+ if (empty(trim($data['title'] ?? ''))) {
+ return ['success' => false, 'message' => 'Topic title is required'];
+ }
+
+ if (empty($data['category_id'])) {
+ return ['success' => false, 'message' => 'Category is required'];
+ }
+
+ $slug = strtolower(trim($data['slug'] ?? ''));
+ if ($slug === '') {
+ $slug = preg_replace('/[^a-z0-9]+/i', '-', $data['title']);
+ $slug = trim($slug, '-');
+ }
+
+ $payload = [
+ 'category_id' => (int) $data['category_id'],
+ 'title' => trim($data['title']),
+ 'slug' => $slug,
+ 'description' => trim($data['description'] ?? ''),
+ 'content' => trim($data['content'] ?? ''),
+ 'image_url' => trim($data['image_url'] ?? ''),
+ 'display_order' => (int) ($data['display_order'] ?? 1),
+ 'is_active' => !empty($data['is_active']) ? 1 : 0
+ ];
+
+ try {
+ $db->begin();
+
+ if (!empty($data['id'])) {
+ $db->update('topics', $payload, 'id = :id', [
+ 'id' => (int) $data['id']
+ ]);
+ } else {
+ $db->insert('topics', $payload);
+ }
+
+ $db->commit();
+
+ return ['success' => true, 'message' => 'Topic saved successfully'];
+
+ } catch (Throwable $e) {
+ $db->rollback();
+
+ error_log($e->getMessage());
+
+ return [
+ 'success' => false,
+ 'message' => 'Database error: ' . $e->getMessage()
+ ];
+ }
+}
+
+function deleteTopic(DatabaseUtility $db, int $id): array
+{
+ if ($id <= 0) {
+ return [
+ 'success' => false,
+ 'message' => 'Invalid topic ID'
+ ];
+ }
+
+ try {
+ $db->begin();
+
+
+
+ $db->delete(
+ 'topics',
+ 'id = :id',
+ ['id' => $id]
+ );
+
+ $db->commit();
+
+ return [
+ 'success' => true,
+ 'message' => 'Topic and related data deleted successfully'
+ ];
+
+ } catch (Throwable $e) {
+ $db->rollback();
+
+ return [
+ 'success' => false,
+ 'message' => 'Failed to delete topic'
+ ];
+ }
+}
diff --git a/admin/api/index.php b/admin/api/index.php
new file mode 100644
index 0000000..efd64eb
--- /dev/null
+++ b/admin/api/index.php
@@ -0,0 +1,81 @@
+ true,
+ 'data' => getHeader($db)
+ ]);
+ break;
+
+ case 'header.save':
+ require 'SettingsController.php';
+ echo json_encode(saveHeader($db, $_POST));
+ break;
+
+ /* ===== Categories ===== */
+ case 'category.list':
+ echo json_encode([
+ 'success' => true,
+ 'data' => $db->getllCategories()
+ ]);
+ break;
+
+ case 'category.save':
+ require 'CategoryController.php';
+ echo json_encode(saveCategory($db, $_POST));
+ break;
+
+ case 'category.delete':
+ require 'CategoryController.php';
+ echo json_encode(deleteCategory($db, (int)$_POST['id']));
+ break;
+
+ /* ===== Topics ===== */
+ case 'topic.list':
+ require 'TopicController.php';
+ echo json_encode([
+ 'success' => true,
+ 'data' => getTopics($db)
+ ]);
+ break;
+
+ case 'topic.save':
+ require 'TopicController.php';
+ echo json_encode(saveTopic($db, $_POST));
+ break;
+
+ case 'topic.delete':
+ require 'TopicController.php';
+ echo json_encode(deleteTopic($db, (int)$_POST['id']));
+ break;
+
+ default:
+ http_response_code(400);
+ echo json_encode(['success' => false, 'message' => 'Invalid action']);
+ }
+
+} catch (Throwable $e) {
+ http_response_code(500);
+ echo json_encode([
+ 'success' => false,
+ 'message' => 'Server error',
+ 'debug' => $e->getMessage()
+ ]);
+}
+
diff --git a/admin/css/style.css b/admin/css/style.css
new file mode 100644
index 0000000..993c860
--- /dev/null
+++ b/admin/css/style.css
@@ -0,0 +1,548 @@
+
+ * {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ }
+
+ body {
+ background: #f5f7fa;
+ font-family: "Segoe UI", Arial, sans-serif;
+ min-height: 100vh;
+ }
+
+ /* ===== Sidebar ===== */
+ .sidebar {
+ background: linear-gradient(135deg, #0e2f47 0%, #1a4a5f 100%);
+ min-height: 100vh;
+ padding: 30px 20px;
+ color: #fff;
+ position: fixed;
+ left: 0;
+ top: 0;
+ width: 280px;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+ overflow-y: auto;
+ z-index: 100;
+ }
+
+ .sidebar-logo {
+ font-size: 22px;
+ font-weight: 700;
+ margin-bottom: 40px;
+ color: #67b7c8;
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ }
+
+ .sidebar-menu {
+ list-style: none;
+ }
+
+ .sidebar-menu li {
+ margin-bottom: 8px;
+ }
+
+ .sidebar-menu a {
+ color: #cfd8df;
+ text-decoration: none;
+ padding: 12px 16px;
+ border-radius: 6px;
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ transition: all 0.3s ease;
+ cursor: pointer;
+ border-left: 3px solid transparent;
+ }
+
+ .sidebar-menu a:hover {
+ background: rgba(103, 183, 200, 0.15);
+ color: #fff;
+ transform: translateX(4px);
+ }
+
+ .sidebar-menu a.active {
+ background: rgba(103, 183, 200, 0.25);
+ color: #67b7c8;
+ border-left: 3px solid #67b7c8;
+ font-weight: 600;
+ }
+
+ /* ===== Main Content ===== */
+ .main-content {
+ margin-left: 280px;
+ padding: 30px;
+ }
+
+ .header-section {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 30px;
+ background: #fff;
+ padding: 24px 28px;
+ border-radius: 8px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+ position: sticky;
+ top: 0;
+ z-index: 50;
+ }
+
+ .header-section h1 {
+ font-size: 28px;
+ font-weight: 700;
+ color: #1c2b36;
+ margin: 0;
+ }
+
+ .btn-primary-custom {
+ background: #67b7c8;
+ border: none;
+ color: #fff;
+ padding: 10px 24px;
+ border-radius: 6px;
+ cursor: pointer;
+ font-weight: 600;
+ transition: all 0.3s ease;
+ font-size: 14px;
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ }
+
+ .btn-primary-custom:hover {
+ background: #4a98a8;
+ transform: translateY(-2px);
+ box-shadow: 0 4px 12px rgba(103, 183, 200, 0.3);
+ }
+
+ /* ===== Content Sections ===== */
+ .content-section {
+ background: #fff;
+ border-radius: 8px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+ margin-bottom: 24px;
+ overflow: hidden;
+ border: 1px solid #e9ecef;
+ }
+
+ .section-header {
+ background: linear-gradient(135deg, #f8f9fa 0%, #f1f3f5 100%);
+ padding: 20px 24px;
+ border-bottom: 1px solid #e9ecef;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ cursor: pointer;
+ user-select: none;
+ transition: all 0.3s ease;
+ }
+
+ .section-header:hover {
+ background: linear-gradient(135deg, #f1f3f5 0%, #e9ecef 100%);
+ }
+
+ .section-header h2 {
+ font-size: 18px;
+ font-weight: 600;
+ color: #1c2b36;
+ margin: 0;
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ }
+
+ .section-header .toggle-icon {
+ color: #67b7c8;
+ transition: transform 0.3s ease;
+ }
+
+ .section-header.collapsed .toggle-icon {
+ transform: rotate(-90deg);
+ }
+
+ .section-body {
+ padding: 24px;
+ max-height: 2000px;
+ overflow: hidden;
+ transition: all 0.4s ease;
+ }
+
+ .section-body.collapsed {
+ max-height: 0;
+ padding: 0 24px;
+ opacity: 0;
+ }
+
+ /* ===== Form Styles ===== */
+ .form-group {
+ margin-bottom: 20px;
+ }
+
+ .form-group label {
+ display: block;
+ font-weight: 600;
+ color: #1c2b36;
+ margin-bottom: 8px;
+ font-size: 14px;
+ }
+
+ .form-group input,
+ .form-group textarea,
+ .form-group select {
+ width: 100%;
+ padding: 12px 14px;
+ border: 1px solid #ddd;
+ border-radius: 6px;
+ font-family: "Segoe UI", Arial, sans-serif;
+ font-size: 14px;
+ transition: all 0.3s ease;
+ }
+
+ .form-group input:focus,
+ .form-group textarea:focus,
+ .form-group select:focus {
+ outline: none;
+ border-color: #67b7c8;
+ box-shadow: 0 0 0 3px rgba(103, 183, 200, 0.1);
+ }
+
+ .form-group textarea {
+ resize: vertical;
+ min-height: 100px;
+ }
+
+ .form-row {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 20px;
+ }
+
+ .form-row.full {
+ grid-template-columns: 1fr;
+ }
+
+ /* ===== Table Styles ===== */
+ .table-container {
+ overflow-x: auto;
+ }
+
+ table {
+ width: 100%;
+ border-collapse: collapse;
+ }
+
+ thead {
+ background: #f6f6f6;
+ border-top: 1px solid #e9ecef;
+ border-bottom: 2px solid #e9ecef;
+ }
+
+ th {
+ padding: 14px 16px;
+ text-align: left;
+ font-weight: 700;
+ color: #1c2b36;
+ font-size: 13px;
+ letter-spacing: 0.5px;
+ text-transform: uppercase;
+ }
+
+ td {
+ padding: 14px 16px;
+ border-bottom: 1px solid #f0f0f0;
+ font-size: 14px;
+ color: #555;
+ }
+
+ tbody tr {
+ transition: all 0.2s ease;
+ }
+
+ tbody tr:hover {
+ background: #f9f9f9;
+ }
+
+ .status-badge {
+ display: inline-block;
+ padding: 4px 12px;
+ border-radius: 20px;
+ font-size: 12px;
+ font-weight: 600;
+ }
+
+ .status-active {
+ background: rgba(103, 183, 200, 0.15);
+ color: #0e7490;
+ }
+
+ .status-inactive {
+ background: rgba(220, 53, 69, 0.15);
+ color: #dc3545;
+ }
+
+ .action-buttons {
+ display: flex;
+ gap: 8px;
+ }
+
+ .btn-edit, .btn-delete {
+ padding: 6px 12px;
+ border: none;
+ border-radius: 4px;
+ cursor: pointer;
+ font-size: 12px;
+ font-weight: 600;
+ transition: all 0.3s ease;
+ }
+
+ .btn-edit {
+ background: #67b7c8;
+ color: #fff;
+ }
+
+ .btn-edit:hover {
+ background: #4a98a8;
+ transform: translateY(-2px);
+ }
+
+ .btn-delete {
+ background: #dc3545;
+ color: #fff;
+ }
+
+ .btn-delete:hover {
+ background: #c82333;
+ transform: translateY(-2px);
+ }
+
+ /* ===== Modal ===== */
+ .modal-backdrop {
+ display: none;
+ position: fixed;
+ inset: 0;
+ background: rgba(0, 0, 0, 0.5);
+ z-index: 999;
+ animation: fadeIn 0.3s ease;
+ }
+
+ .modal-backdrop.active {
+ display: block;
+ }
+
+ .modal {
+ display: none;
+ position: fixed;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ background: #fff;
+ border-radius: 8px;
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
+ z-index: 1000;
+ max-width: 600px;
+ width: 90%;
+ max-height: 90vh;
+ overflow-y: auto;
+ animation: slideUp 0.3s ease;
+ }
+
+ .modal.active {
+ display: block;
+ }
+
+ @keyframes slideUp {
+ from {
+ transform: translate(-50%, -40%);
+ opacity: 0;
+ }
+ to {
+ transform: translate(-50%, -50%);
+ opacity: 1;
+ }
+ }
+
+ @keyframes fadeIn {
+ from { opacity: 0; }
+ to { opacity: 1; }
+ }
+
+ .modal-header {
+ background: linear-gradient(135deg, #67b7c8 0%, #4a98a8 100%);
+ padding: 20px 24px;
+ border-bottom: none;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ color: #fff;
+ border-radius: 8px 8px 0 0;
+ }
+
+ .modal-header h3 {
+ font-size: 18px;
+ font-weight: 700;
+ color: #fff;
+ margin: 0;
+ }
+
+ .modal-close {
+ background: none;
+ border: none;
+ font-size: 28px;
+ color: rgba(255, 255, 255, 0.8);
+ cursor: pointer;
+ transition: color 0.3s ease;
+ }
+
+ .modal-close:hover {
+ color: #fff;
+ }
+
+ .modal-body {
+ padding: 24px;
+ }
+
+ .modal-footer {
+ padding: 16px 24px;
+ border-top: 1px solid #e9ecef;
+ display: flex;
+ gap: 12px;
+ justify-content: flex-end;
+ }
+
+ .btn-cancel {
+ padding: 10px 24px;
+ background: #e9ecef;
+ border: none;
+ border-radius: 6px;
+ cursor: pointer;
+ font-weight: 600;
+ color: #1c2b36;
+ transition: all 0.3s ease;
+ }
+
+ .btn-cancel:hover {
+ background: #dee2e6;
+ }
+
+ .btn-submit {
+ padding: 10px 24px;
+ background: #67b7c8;
+ border: none;
+ border-radius: 6px;
+ cursor: pointer;
+ font-weight: 600;
+ color: #fff;
+ transition: all 0.3s ease;
+ }
+
+ .btn-submit:hover {
+ background: #4a98a8;
+ }
+
+ .empty-state {
+ text-align: center;
+ padding: 40px 20px;
+ color: #999;
+ }
+
+ .empty-state i {
+ font-size: 48px;
+ margin-bottom: 16px;
+ opacity: 0.5;
+ }
+
+ /* ===== Responsive ===== */
+ @media (max-width: 768px) {
+ .sidebar {
+ width: 250px;
+ }
+
+ .main-content {
+ margin-left: 250px;
+ padding: 20px;
+ }
+
+ .form-row {
+ grid-template-columns: 1fr;
+ }
+
+ .header-section {
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 16px;
+ }
+ }
+
+ @media (max-width: 576px) {
+ .sidebar {
+ width: 200px;
+ padding: 20px 12px;
+ }
+
+ .main-content {
+ margin-left: 200px;
+ padding: 16px;
+ }
+
+ .sidebar-logo {
+ font-size: 18px;
+ margin-bottom: 30px;
+ }
+
+ .modal {
+ width: 95%;
+ }
+
+ .header-section h1 {
+ font-size: 22px;
+ }
+ }
+ #toast-container {
+ position: fixed;
+ top: 20px;
+ right: 20px;
+ z-index: 9999;
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+}
+
+.toast {
+ min-width: 280px;
+ padding: 14px 16px;
+ border-radius: 8px;
+ font-size: 14px;
+ color: #fff;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ box-shadow: 0 8px 24px rgba(0,0,0,0.15);
+ animation: slideIn 0.3s ease;
+}
+
+.toast.success {
+ background: linear-gradient(135deg, #2ecc71, #27ae60);
+}
+
+.toast.error {
+ background: linear-gradient(135deg, #e74c3c, #c0392b);
+}
+
+.toast.info {
+ background: linear-gradient(135deg, #3498db, #2980b9);
+}
+
+.toast .close {
+ cursor: pointer;
+ margin-left: 12px;
+ font-weight: bold;
+ opacity: 0.8;
+}
+
+@keyframes slideIn {
+ from { opacity: 0; transform: translateX(20px); }
+ to { opacity: 1; transform: translateX(0); }
+}
diff --git a/admin/index.php b/admin/index.php
new file mode 100644
index 0000000..f919bc8
--- /dev/null
+++ b/admin/index.php
@@ -0,0 +1,552 @@
+
+
+
+
+
+
+ DelphianLogic - Admin Panel
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ | Name |
+ Description |
+ Status |
+ Order |
+ Actions |
+
+
+
+ | Loading... |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ | Title |
+ Category |
+ Status |
+ Actions |
+
+
+
+ | Loading... |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/admin/js/script.js b/admin/js/script.js
new file mode 100644
index 0000000..5d9f58c
--- /dev/null
+++ b/admin/js/script.js
@@ -0,0 +1,25 @@
+const API_URL = 'api/index.php';
+const CSRF_TOKEN = document.querySelector('meta[name="csrf"]').content;
+
+async function api(action, payload = {}) {
+ const form = new FormData();
+ form.append('action', action);
+
+ Object.keys(payload).forEach(key => {
+ form.append(key, payload[key]);
+ });
+
+ const res = await fetch(API_URL, {
+ method: 'POST',
+ headers: {
+ 'X-CSRF-TOKEN': CSRF_TOKEN
+ },
+ body: form
+ });
+
+ return res.json();
+}
+
+
+
+
diff --git a/config/DatabaseUtility.php b/config/DatabaseUtility.php
new file mode 100644
index 0000000..69af691
--- /dev/null
+++ b/config/DatabaseUtility.php
@@ -0,0 +1,191 @@
+host};dbname={$this->db};charset={$this->charset}";
+
+ $options = [
+ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
+ PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
+ PDO::ATTR_EMULATE_PREPARES => false,
+ ];
+
+ try {
+ $this->conn = new PDO($dsn, $this->user, $this->pass, $options);
+ } catch (PDOException $e) {
+ $this->logError($e->getMessage());
+ die('Database connection failed');
+ }
+ }
+
+
+ public static function getInstance(): DatabaseUtility
+ {
+ if (self::$instance === null) {
+ self::$instance = new self();
+ }
+ return self::$instance;
+ }
+
+
+ public function getConnection(): PDO
+ {
+ return $this->conn;
+ }
+
+ /**
+ * Execute Prepared Query
+ */
+ public function query(string $sql, array $params = []): PDOStatement
+ {
+ $stmt = $this->conn->prepare($sql);
+ $stmt->execute($params);
+ return $stmt;
+ }
+
+ /**
+ * Fetch All Rows
+ */
+ public function fetchAll(string $sql, array $params = []): array
+ {
+ return $this->query($sql, $params)->fetchAll();
+ }
+
+ /**
+ * Fetch Single Row
+ */
+ public function fetch(string $sql, array $params = []): ?array
+ {
+ $result = $this->query($sql, $params)->fetch();
+ return $result ?: null;
+ }
+
+ /**
+ * Insert Record
+ */
+ public function insert(string $table, array $data): int
+ {
+ $fields = array_keys($data);
+ $placeholders = array_map(fn ($f) => ':' . $f, $fields);
+
+ $sql = "INSERT INTO {$table} (" . implode(',', $fields) . ") VALUES (" . implode(',', $placeholders) . ")";
+ $this->query($sql, $data);
+
+ return (int) $this->conn->lastInsertId();
+ }
+
+ /**
+ * Update Record
+ */
+ public function update(string $table, array $data, string $where, array $whereParams): int
+ {
+ $set = [];
+ foreach ($data as $key => $value) {
+ $set[] = "$key = :$key";
+ }
+
+ $sql = "UPDATE {$table} SET " . implode(', ', $set) . " WHERE {$where}";
+ $stmt = $this->conn->prepare($sql);
+ $stmt->execute(array_merge($data, $whereParams));
+
+ return $stmt->rowCount();
+ }
+
+ /**
+ * Delete Record
+ */
+ public function delete(string $table, string $where, array $params): int
+ {
+ $sql = "DELETE FROM {$table} WHERE {$where}";
+ return $this->query($sql, $params)->rowCount();
+ }
+
+ /**
+ * Transactions
+ */
+ public function begin(): void
+ {
+ $this->conn->beginTransaction();
+ }
+
+ public function commit(): void
+ {
+ $this->conn->commit();
+ }
+
+ public function rollback(): void
+ {
+ $this->conn->rollBack();
+ }
+
+ public function getActiveCategories(): array
+ {
+ return $this->fetchAll(
+ "SELECT * FROM categories WHERE is_active = 1 ORDER BY display_order"
+ );
+ }
+
+ public function getllCategories(): array
+ {
+ return $this->fetchAll(
+ "SELECT * FROM categories ORDER BY display_order"
+ );
+ }
+
+ /**
+ * Get Topics by Category (Active Only)
+ */
+ public function getTopicsByCategory(int $categoryId): array
+ {
+ return $this->fetchAll(
+ "SELECT * FROM topics WHERE category_id = :cid AND is_active = 1 ORDER BY display_order",
+ ['cid' => $categoryId]
+ );
+ }
+
+
+
+ /**
+ * Get Setting with Auto Type Casting
+ */
+public function getSetting(string $key): mixed
+{
+ $row = $this->fetch(
+ "SELECT setting_value, data_type
+ FROM settings
+ WHERE setting_key = :key
+ LIMIT 1",
+ ['key' => $key]
+ );
+
+ if (!$row) {
+ return null;
+ }
+
+ return match ($row['data_type']) {
+ 'boolean' => filter_var($row['setting_value'], FILTER_VALIDATE_BOOLEAN),
+ 'integer' => (int)$row['setting_value'],
+ default => $row['setting_value'],
+ };
+}
+}
\ No newline at end of file
diff --git a/config/csrf.php b/config/csrf.php
new file mode 100644
index 0000000..f085b70
--- /dev/null
+++ b/config/csrf.php
@@ -0,0 +1,22 @@
+ false, 'message' => 'Invalid CSRF token']);
+ exit;
+ }
+}
diff --git a/delphian_logic.sql b/delphian_logic.sql
new file mode 100644
index 0000000..17ad93d
--- /dev/null
+++ b/delphian_logic.sql
@@ -0,0 +1,166 @@
+-- phpMyAdmin SQL Dump
+-- version 5.2.1
+-- https://www.phpmyadmin.net/
+--
+-- Host: 127.0.0.1
+-- Generation Time: Dec 18, 2025 at 08:26 PM
+-- Server version: 10.4.32-MariaDB
+-- PHP Version: 8.1.25
+
+SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
+START TRANSACTION;
+SET time_zone = "+00:00";
+
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8mb4 */;
+
+--
+-- Database: `delphian_logic`
+--
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `categories`
+--
+
+CREATE TABLE `categories` (
+ `id` int(11) NOT NULL,
+ `name` varchar(100) NOT NULL,
+ `description` text DEFAULT NULL,
+ `icon_url` varchar(255) DEFAULT NULL,
+ `display_order` int(11) DEFAULT 0,
+ `is_active` tinyint(1) DEFAULT 1,
+ `created_at` timestamp NOT NULL DEFAULT current_timestamp(),
+ `updated_at` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp()
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
+
+--
+-- Dumping data for table `categories`
+--
+
+INSERT INTO `categories` (`id`, `name`, `description`, `icon_url`, `display_order`, `is_active`, `created_at`, `updated_at`) VALUES
+(6, 'Learningd', 'Digital Learning Infrastructure', 'Assets/images/DL-learning.svg', 2, 1, '2025-12-18 17:37:12', '2025-12-18 18:57:03'),
+(7, 'Technology', 'Technology Infrastructure', 'Assets/images/cat_20251218202503_9878.svg', 1, 1, '2025-12-18 17:54:26', '2025-12-18 19:25:03'),
+(8, 'Communication', 'Communication Framework', 'Assets/images/cat_20251218202136_7112.jpg', 2, 1, '2025-12-18 18:17:30', '2025-12-18 19:21:36');
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `settings`
+--
+
+CREATE TABLE `settings` (
+ `id` int(11) NOT NULL,
+ `setting_key` varchar(100) NOT NULL,
+ `setting_value` varchar(255) DEFAULT NULL,
+ `description` text DEFAULT NULL,
+ `data_type` varchar(50) DEFAULT 'string',
+ `updated_at` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp()
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
+
+--
+-- Dumping data for table `settings`
+--
+
+INSERT INTO `settings` (`id`, `setting_key`, `setting_value`, `description`, `data_type`, `updated_at`) VALUES
+(2, 'site_title', 'DelphianLogic in Actions', 'Main site title', 'string', '2025-12-18 10:15:43'),
+(3, 'site_description', 'Lorem ipsum dolor sit amet consectetur adipisicing elit. A consequuntur similique quibusdam quos, voluptas accusamus, quis delectus totam ipsam mollitia nostrum veritatis officia.', 'Site description', 'string', '2025-12-18 19:01:11'),
+(5, 'slider_dots_count', '3', 'Number of slider dots to display', 'integer', '2025-12-18 08:14:42');
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `topics`
+--
+
+CREATE TABLE `topics` (
+ `id` int(11) NOT NULL,
+ `category_id` int(11) NOT NULL,
+ `title` varchar(255) NOT NULL,
+ `slug` varchar(255) NOT NULL,
+ `description` text DEFAULT NULL,
+ `content` text DEFAULT NULL,
+ `short_content` varchar(500) DEFAULT NULL,
+ `image_url` varchar(255) DEFAULT NULL,
+ `display_order` int(11) DEFAULT 0,
+ `is_active` tinyint(1) DEFAULT 1,
+ `created_at` timestamp NOT NULL DEFAULT current_timestamp(),
+ `updated_at` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp()
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
+
+--
+-- Dumping data for table `topics`
+--
+
+INSERT INTO `topics` (`id`, `category_id`, `title`, `slug`, `description`, `content`, `short_content`, `image_url`, `display_order`, `is_active`, `created_at`, `updated_at`) VALUES
+(5, 6, 'Usability enhancement and Training for Transaction Portal for Customers', 'Usability-enhancement-and-Training-for-Transaction-Portal-for-Customers', 'Enhanced training portal;', '', NULL, '', 1, 1, '2025-12-18 17:40:40', '2025-12-18 18:15:47'),
+(6, 7, 'Advanced Technology Solutions for Modern Business', 'Advanced-Technology-Solutions-for-Modern-Business', 'Leverage cutting-edge technology infrastructure to streamline operations, enhance security, and drive innovation.', '', NULL, '', 1, 1, '2025-12-18 18:15:39', '2025-12-18 18:16:14');
+
+--
+-- Indexes for dumped tables
+--
+
+--
+-- Indexes for table `categories`
+--
+ALTER TABLE `categories`
+ ADD PRIMARY KEY (`id`),
+ ADD UNIQUE KEY `name` (`name`);
+
+--
+-- Indexes for table `settings`
+--
+ALTER TABLE `settings`
+ ADD PRIMARY KEY (`id`),
+ ADD UNIQUE KEY `setting_key` (`setting_key`);
+
+--
+-- Indexes for table `topics`
+--
+ALTER TABLE `topics`
+ ADD PRIMARY KEY (`id`),
+ ADD UNIQUE KEY `unique_slug_per_category` (`category_id`,`slug`),
+ ADD KEY `idx_category` (`category_id`),
+ ADD KEY `idx_active` (`is_active`),
+ ADD KEY `idx_topics_category_active` (`category_id`,`is_active`);
+
+--
+-- AUTO_INCREMENT for dumped tables
+--
+
+--
+-- AUTO_INCREMENT for table `categories`
+--
+ALTER TABLE `categories`
+ MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=9;
+
+--
+-- AUTO_INCREMENT for table `settings`
+--
+ALTER TABLE `settings`
+ MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=6;
+
+--
+-- AUTO_INCREMENT for table `topics`
+--
+ALTER TABLE `topics`
+ MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=7;
+
+--
+-- Constraints for dumped tables
+--
+
+--
+-- Constraints for table `topics`
+--
+ALTER TABLE `topics`
+ ADD CONSTRAINT `topics_ibfk_1` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`) ON DELETE CASCADE;
+COMMIT;
+
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
diff --git a/files/.DS_Store b/files/.DS_Store
new file mode 100644
index 0000000..ea997e6
Binary files /dev/null and b/files/.DS_Store differ
diff --git a/index.php b/index.php
new file mode 100644
index 0000000..f617993
--- /dev/null
+++ b/index.php
@@ -0,0 +1,139 @@
+getSetting('site_title') ?? 'DelphianLogic in Action';
+$siteDescription = $db->getSetting('site_description') ?? '';
+$sliderDotsCount = $db->getSetting('slider_dots_count') ?? 3;
+
+$categories = $db->getActiveCategories();
+?>
+
+
+
+
+
+ = htmlspecialchars($siteTitle) ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $category):
+ $topics = $db->getTopicsByCategory((int)$category['id']);
+ $topic = $topics[0] ?? null;
+?>
+
+
+
+
+
+
+
= strtoupper($category['description']) ?>
+
= htmlspecialchars($topic['title']) ?>
+
= htmlspecialchars($topic['short_content'] ?? '') ?>
+
+
 ?>)
+
+
Learn More →
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $category): ?>
+
+
+
 ?>)
+
+
= htmlspecialchars($category['name']) ?>
+
+
+
+
+ getTopicsByCategory((int)$firstCategory['id'])[0] ?? null) : null;
+ ?>
+
+
+
+
+
= strtoupper($firstCategory['description']) ?>
+
= htmlspecialchars($firstTopic['title']) ?>
+
= htmlspecialchars($firstTopic['short_content'] ?? '') ?>
+
Learn More →
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+