<?php
session_start();
require_once '../config/database.php';
// Check if user is logged in and is admin
if (!isset($_SESSION['user_id']) || ($_SESSION['role'] !== 'admin' && $_SESSION['role'] !== 'director')) {
header('Location: login.php');
exit();
}
// Include header
include_once 'includes/header.php';
?>
<!-- Breadcrumb -->
<nav aria-label="breadcrumb" class="mb-4">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="index.php">Dashboard</a></li>
<li class="breadcrumb-item"><a href="#settingsSubmenu" data-bs-toggle="collapse">Settings</a></li>
<li class="breadcrumb-item active">Live Website Editor</li>
</ol>
</nav>
<!-- Page Title and Action Buttons -->
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="h3 mb-0 text-gray-800">Live Website Editor</h1>
<div>
<a href="../index.php" target="_blank" class="btn btn-outline-primary me-2">
<i class="fas fa-external-link-alt me-1"></i> Open Website
</a>
<button type="button" class="btn btn-primary" id="enterEditModeBtn">
<i class="fas fa-edit me-1"></i> Enter Edit Mode
</button>
</div>
</div>
<!-- Main Content -->
<div class="row">
<!-- Page Selection -->
<div class="col-lg-4 mb-4">
<div class="card shadow-sm h-100">
<div class="card-header">
<h5 class="mb-0">Select Page to Edit</h5>
</div>
<div class="card-body">
<div class="input-group mb-3">
<span class="input-group-text"><i class="fas fa-search"></i></span>
<input type="text" class="form-control" placeholder="Search pages..." id="pageSearchInput">
</div>
<div class="list-group page-list">
<a href="#" class="list-group-item list-group-item-action active" data-page="index.php">
<i class="fas fa-home me-2"></i> Homepage
</a>
<a href="#" class="list-group-item list-group-item-action" data-page="courses.php">
<i class="fas fa-book me-2"></i> Courses Page
</a>
<a href="#" class="list-group-item list-group-item-action" data-page="about.php">
<i class="fas fa-info-circle me-2"></i> About Us
</a>
<a href="#" class="list-group-item list-group-item-action" data-page="contact.php">
<i class="fas fa-envelope me-2"></i> Contact Page
</a>
</div>
</div>
</div>
</div>
<!-- Preview and Editor -->
<div class="col-lg-8 mb-4">
<div class="card shadow-sm h-100">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0">Page Preview</h5>
<div class="btn-group">
<button type="button" class="btn btn-sm btn-outline-secondary active" data-device="desktop">
<i class="fas fa-desktop"></i>
</button>
<button type="button" class="btn btn-sm btn-outline-secondary" data-device="tablet">
<i class="fas fa-tablet-alt"></i>
</button>
<button type="button" class="btn btn-sm btn-outline-secondary" data-device="mobile">
<i class="fas fa-mobile-alt"></i>
</button>
</div>
</div>
<div class="card-body p-0">
<div class="preview-container">
<iframe src="../index.php" id="previewFrame" class="preview-frame device-desktop"></iframe>
<!-- Editing Overlay (Appears when in edit mode) -->
<div class="editing-overlay d-none">
<div class="editing-toolbar bg-dark text-white p-2">
<div class="d-flex justify-content-between align-items-center">
<div>
<span class="badge bg-primary me-2">Edit Mode</span>
<span class="element-path">No element selected</span>
</div>
<div class="btn-group">
<button class="btn btn-sm btn-outline-light" id="saveChangesBtn" disabled>
<i class="fas fa-save me-1"></i> Save
</button>
<button class="btn btn-sm btn-outline-light" id="cancelEditBtn">
<i class="fas fa-times me-1"></i> Cancel
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Element Editor Panel -->
<div class="element-editor-panel shadow-lg">
<div class="editor-header">
<h5><i class="fas fa-sliders-h me-2"></i> Element Properties</h5>
<button type="button" class="btn-close" id="closeEditorBtn"></button>
</div>
<div class="editor-body">
<div class="element-info mb-3">
<span class="badge bg-secondary element-type">div</span>
<span class="element-id">No element selected</span>
</div>
<ul class="nav nav-tabs mb-3" id="propertyTabs" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="content-tab" data-bs-toggle="tab" data-bs-target="#content" type="button" role="tab">Content</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="style-tab" data-bs-toggle="tab" data-bs-target="#style" type="button" role="tab">Style</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="advanced-tab" data-bs-toggle="tab" data-bs-target="#advanced" type="button" role="tab">Advanced</button>
</li>
</ul>
<div class="tab-content" id="propertyTabsContent">
<!-- Content Tab -->
<div class="tab-pane fade show active" id="content" role="tabpanel">
<div class="mb-3">
<label class="form-label">Text Content</label>
<textarea class="form-control" id="elementText" rows="4"></textarea>
</div>
<div class="mb-3">
<label class="form-label">Image (if applicable)</label>
<div class="input-group">
<input type="text" class="form-control" id="elementImage">
<button class="btn btn-outline-secondary" type="button">Browse</button>
</div>
</div>
</div>
<!-- Style Tab -->
<div class="tab-pane fade" id="style" role="tabpanel">
<div class="row g-2">
<div class="col-md-6">
<label class="form-label">Font Size</label>
<div class="input-group mb-3">
<input type="number" class="form-control" id="fontSize" min="8" max="72">
<span class="input-group-text">px</span>
</div>
</div>
<div class="col-md-6">
<label class="form-label">Font Weight</label>
<select class="form-select" id="fontWeight">
<option value="normal">Normal</option>
<option value="bold">Bold</option>
<option value="lighter">Lighter</option>
<option value="bolder">Bolder</option>
</select>
</div>
</div>
<div class="mb-3">
<label class="form-label">Text Color</label>
<input type="color" class="form-control form-control-color" id="textColor" value="#000000">
</div>
<div class="mb-3">
<label class="form-label">Background Color</label>
<input type="color" class="form-control form-control-color" id="bgColor" value="#ffffff">
</div>
<div class="row g-2">
<div class="col-6">
<label class="form-label">Padding</label>
<div class="input-group mb-3">
<input type="number" class="form-control" id="padding" min="0" max="100">
<span class="input-group-text">px</span>
</div>
</div>
<div class="col-6">
<label class="form-label">Margin</label>
<div class="input-group mb-3">
<input type="number" class="form-control" id="margin" min="0" max="100">
<span class="input-group-text">px</span>
</div>
</div>
</div>
</div>
<!-- Advanced Tab -->
<div class="tab-pane fade" id="advanced" role="tabpanel">
<div class="mb-3">
<label class="form-label">CSS Classes</label>
<input type="text" class="form-control" id="cssClasses">
</div>
<div class="mb-3">
<label class="form-label">Custom CSS</label>
<textarea class="form-control" id="customCss" rows="5"></textarea>
</div>
</div>
</div>
</div>
<div class="editor-footer">
<button type="button" class="btn btn-primary" id="applyChangesBtn">Apply Changes</button>
<button type="button" class="btn btn-outline-danger ms-auto" id="deleteElementBtn">Delete Element</button>
</div>
</div>
<!-- Live Editor Tutorial Modal -->
<div class="modal fade" id="editorTutorialModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">How to Use the Live Editor</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="row mb-4">
<div class="col-md-6">
<div class="card h-100">
<div class="card-body">
<h5><i class="fas fa-mouse-pointer text-primary me-2"></i> Step 1: Click to Select</h5>
<p>Click on any element on the page to select it. The element will be highlighted with a blue border.</p>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card h-100">
<div class="card-body">
<h5><i class="fas fa-edit text-primary me-2"></i> Step 2: Edit Properties</h5>
<p>Use the element properties panel to modify text, style, and advanced settings.</p>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="card h-100">
<div class="card-body">
<h5><i class="fas fa-check-circle text-primary me-2"></i> Step 3: Apply Changes</h5>
<p>Click "Apply Changes" to preview your modifications in real-time.</p>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card h-100">
<div class="card-body">
<h5><i class="fas fa-save text-primary me-2"></i> Step 4: Save Changes</h5>
<p>When you're satisfied with all your changes, click "Save" in the editing toolbar.</p>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="dontShowAgainCheck">
<label class="form-check-label" for="dontShowAgainCheck">Don't show this again</label>
</div>
<button type="button" class="btn btn-primary" data-bs-dismiss="modal">Got it!</button>
</div>
</div>
</div>
</div>
<style>
/* Live Editor Styles */
.preview-container {
position: relative;
height: 600px;
background-color: #f0f2f5;
overflow: hidden;
}
.preview-frame {
width: 100%;
height: 100%;
border: none;
transition: all 0.3s ease;
}
.device-desktop {
width: 100%;
}
.device-tablet {
width: 768px;
height: 1024px;
margin: 0 auto;
display: block;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
border: 10px solid #333;
border-radius: 10px;
}
.device-mobile {
width: 375px;
height: 667px;
margin: 0 auto;
display: block;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
border: 10px solid #333;
border-radius: 20px;
}
.editing-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
pointer-events: none;
}
.editing-toolbar {
position: absolute;
top: 0;
left: 0;
right: 0;
z-index: 100;
pointer-events: auto;
}
.element-path {
font-size: 0.85rem;
opacity: 0.8;
}
.element-editor-panel {
position: fixed;
right: -350px;
top: 0;
width: 350px;
height: 100vh;
background: white;
z-index: 1050;
transition: right 0.3s ease;
display: flex;
flex-direction: column;
}
.element-editor-panel.open {
right: 0;
}
.editor-header {
padding: 15px;
background: #f8f9fc;
border-bottom: 1px solid #e3e6f0;
display: flex;
justify-content: space-between;
align-items: center;
}
.editor-body {
padding: 15px;
flex-grow: 1;
overflow-y: auto;
}
.editor-footer {
padding: 15px;
background: #f8f9fc;
border-top: 1px solid #e3e6f0;
display: flex;
}
.element-info {
display: flex;
align-items: center;
gap: 10px;
}
.element-type {
text-transform: uppercase;
}
.element-id {
font-size: 0.9rem;
color: #6c757d;
}
/* Page List Styles */
.page-list {
max-height: 500px;
overflow-y: auto;
}
.page-list .list-group-item {
padding: 10px 15px;
border-left: 3px solid transparent;
transition: all 0.2s ease;
}
.page-list .list-group-item:hover {
background-color: #f8f9fc;
border-left-color: #4e73df;
}
.page-list .list-group-item.active {
background-color: #4e73df;
border-color: #4e73df;
border-left-width: 3px;
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Page preview device switcher
const deviceButtons = document.querySelectorAll('[data-device]');
const previewFrame = document.getElementById('previewFrame');
deviceButtons.forEach(button => {
button.addEventListener('click', function() {
const device = this.getAttribute('data-device');
// Update active button
deviceButtons.forEach(btn => btn.classList.remove('active'));
this.classList.add('active');
// Update iframe class
previewFrame.className = `preview-frame device-${device}`;
});
});
// Page selection
const pageLinks = document.querySelectorAll('.page-list a');
pageLinks.forEach(link => {
link.addEventListener('click', function(e) {
e.preventDefault();
// Update active link
pageLinks.forEach(pageLink => pageLink.classList.remove('active'));
this.classList.add('active');
// Load the selected page in the iframe
const page = this.getAttribute('data-page');
previewFrame.src = `../${page}`;
});
});
// Page search functionality
const pageSearchInput = document.getElementById('pageSearchInput');
if (pageSearchInput) {
pageSearchInput.addEventListener('input', function() {
const searchTerm = this.value.toLowerCase();
pageLinks.forEach(link => {
const pageName = link.textContent.toLowerCase();
if (pageName.includes(searchTerm)) {
link.style.display = 'block';
} else {
link.style.display = 'none';
}
});
});
}
// Enter edit mode button
const enterEditModeBtn = document.getElementById('enterEditModeBtn');
const editingOverlay = document.querySelector('.editing-overlay');
const editorPanel = document.querySelector('.element-editor-panel');
if (enterEditModeBtn && editingOverlay) {
enterEditModeBtn.addEventListener('click', function() {
editingOverlay.classList.remove('d-none');
this.disabled = true;
// Show tutorial modal on first use
if (!localStorage.getItem('editorTutorialShown')) {
const tutorialModal = new bootstrap.Modal(document.getElementById('editorTutorialModal'));
tutorialModal.show();
}
// Initialize edit mode in the iframe
previewFrame.contentWindow.postMessage({
action: 'initEditMode'
}, '*');
});
}
// Cancel edit button
const cancelEditBtn = document.getElementById('cancelEditBtn');
if (cancelEditBtn) {
cancelEditBtn.addEventListener('click', function() {
editingOverlay.classList.add('d-none');
enterEditModeBtn.disabled = false;
if (editorPanel.classList.contains('open')) {
editorPanel.classList.remove('open');
}
// Disable edit mode in the iframe
previewFrame.contentWindow.postMessage({
action: 'exitEditMode'
}, '*');
});
}
// Close editor panel button
const closeEditorBtn = document.getElementById('closeEditorBtn');
if (closeEditorBtn && editorPanel) {
closeEditorBtn.addEventListener('click', function() {
editorPanel.classList.remove('open');
});
}
// Listen for messages from the iframe
window.addEventListener('message', function(event) {
if (event.data.action === 'elementSelected') {
// Show the editor panel
editorPanel.classList.add('open');
// Update element info
document.querySelector('.element-type').textContent = event.data.elementType;
document.querySelector('.element-id').textContent = event.data.elementId || 'No ID';
document.querySelector('.element-path').textContent = event.data.elementPath || 'Unknown path';
// Update form fields
document.getElementById('elementText').value = event.data.elementText || '';
document.getElementById('elementImage').value = event.data.elementImage || '';
// Enable save button
document.getElementById('saveChangesBtn').disabled = false;
}
});
// Apply changes button
const applyChangesBtn = document.getElementById('applyChangesBtn');
if (applyChangesBtn) {
applyChangesBtn.addEventListener('click', function() {
// Get values from form fields
const text = document.getElementById('elementText').value;
const fontSize = document.getElementById('fontSize').value;
const fontWeight = document.getElementById('fontWeight').value;
const textColor = document.getElementById('textColor').value;
const bgColor = document.getElementById('bgColor').value;
// Send update message to iframe
previewFrame.contentWindow.postMessage({
action: 'updateElement',
updates: {
text,
style: {
fontSize: fontSize ? `${fontSize}px` : '',
fontWeight,
color: textColor,
backgroundColor: bgColor
}
}
}, '*');
});
}
// Tutorial modal don't show again checkbox
const dontShowAgainCheck = document.getElementById('dontShowAgainCheck');
if (dontShowAgainCheck) {
dontShowAgainCheck.addEventListener('change', function() {
if (this.checked) {
localStorage.setItem('editorTutorialShown', 'true');
} else {
localStorage.removeItem('editorTutorialShown');
}
});
}
});
</script>
<?php include_once 'includes/footer.php'; ?>