v.1
This commit is contained in:
parent
552395fb3c
commit
e87822db43
103
add_template.php
Normal file
103
add_template.php
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'admin/config.php';
|
||||||
|
require_login();
|
||||||
|
|
||||||
|
$error = '';
|
||||||
|
$success = '';
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
$template_name = isset($_POST['template_name']) ? trim($_POST['template_name']) : '';
|
||||||
|
$template_content = isset($_POST['template_content']) ? trim($_POST['template_content']) : '';
|
||||||
|
|
||||||
|
if (empty($template_name) || empty($template_content)) {
|
||||||
|
$error = 'Template name and content are required.';
|
||||||
|
} elseif (preg_match('/[^a-zA-Z0-9_-]/', $template_name)) {
|
||||||
|
$error = 'Template name can only contain letters, numbers, underscores, and dashes.';
|
||||||
|
} else {
|
||||||
|
$template_path = 'templates/' . $template_name . '.html';
|
||||||
|
if (file_exists($template_path)) {
|
||||||
|
$error = 'A template with this name already exists.';
|
||||||
|
} else {
|
||||||
|
if (file_put_contents($template_path, $template_content)) {
|
||||||
|
$success = 'Template created successfully.';
|
||||||
|
|
||||||
|
if (isset($_FILES['template_image']) && $_FILES['template_image']['error'] === UPLOAD_ERR_OK) {
|
||||||
|
$image_dir = 'assets/images/templates/';
|
||||||
|
$image_name = basename($_FILES['template_image']['name']);
|
||||||
|
$image_path = $image_dir . $image_name;
|
||||||
|
if (move_uploaded_file($_FILES['template_image']['tmp_name'], $image_path)) {
|
||||||
|
$success .= ' Image uploaded successfully.';
|
||||||
|
} else {
|
||||||
|
$error .= ' Failed to upload image.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
header('Location: admin.php');
|
||||||
|
} else {
|
||||||
|
$error = 'Failed to create template file.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Add New Template</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="assets/css/admin.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="wrapper">
|
||||||
|
<!-- Sidebar -->
|
||||||
|
<nav id="sidebar">
|
||||||
|
<div class="sidebar-header">
|
||||||
|
<h3>Admin Panel</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul class="list-unstyled components">
|
||||||
|
<li>
|
||||||
|
<a href="admin.php">Templates</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="logout.php">Logout</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<!-- Page Content -->
|
||||||
|
<div id="content">
|
||||||
|
<h1 class="page-title">Add New Template</h1>
|
||||||
|
|
||||||
|
<?php if ($error): ?>
|
||||||
|
<div class="alert alert-danger"><?php echo $error; ?></div>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php if ($success): ?>
|
||||||
|
<div class="alert alert-success"><?php echo $success; ?></div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<form method="POST" enctype="multipart/form-data">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="template_name" class="form-label">Template Name (without .html extension)</label>
|
||||||
|
<input type="text" class="form-control" id="template_name" name="template_name" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="template_content" class="form-label">Template Content (HTML)</label>
|
||||||
|
<textarea class="form-control" id="template_content" name="template_content" rows="10" required></textarea>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="template_image" class="form-label">Featured Image</label>
|
||||||
|
<input class="form-control" type="file" id="template_image" name="template_image">
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary">Create Template</button>
|
||||||
|
<a href="admin.php" class="btn btn-secondary">Cancel</a>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
72
admin.php
Normal file
72
admin.php
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'admin/config.php';
|
||||||
|
require_login();
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Admin - Template Management</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="assets/css/admin.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="wrapper">
|
||||||
|
<!-- Sidebar -->
|
||||||
|
<nav id="sidebar">
|
||||||
|
<div class="sidebar-header">
|
||||||
|
<h3>Admin Panel</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul class="list-unstyled components">
|
||||||
|
<li class="active">
|
||||||
|
<a href="admin.php">Templates</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="logout.php">Logout</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<!-- Page Content -->
|
||||||
|
<div id="content">
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||||
|
<h1 class="page-title">Template Management</h1>
|
||||||
|
<a href="add_template.php" class="btn btn-primary btn-lg">Add New Template</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<table class="table table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Template Name</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php
|
||||||
|
$templates = glob('templates/*.html');
|
||||||
|
if (!empty($templates)) {
|
||||||
|
foreach ($templates as $template) {
|
||||||
|
echo '<tr>';
|
||||||
|
echo '<td>' . htmlspecialchars(basename($template)) . '</td>';
|
||||||
|
echo '<td>';
|
||||||
|
echo '<a href="edit_template.php?template=' . urlencode(basename($template)) . '" class="btn btn-sm btn-outline-primary">Edit</a> ';
|
||||||
|
echo '<a href="delete_template.php?template=' . urlencode(basename($template)) . '" class="btn btn-sm btn-outline-danger" onclick="return confirm(\'Are you sure you want to delete this template?\')">Delete</a>';
|
||||||
|
echo '</td>';
|
||||||
|
echo '</tr>';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
echo '<tr><td colspan="2">No templates found.</td></tr>';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
19
admin/config.php
Normal file
19
admin/config.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
// Simple password protection for the admin area.
|
||||||
|
// IMPORTANT: For a real application, use a proper authentication system.
|
||||||
|
define('ADMIN_USERNAME', 'admin');
|
||||||
|
define('ADMIN_PASSWORD', 'password');
|
||||||
|
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
function is_logged_in() {
|
||||||
|
return isset($_SESSION['is_logged_in']) && $_SESSION['is_logged_in'] === true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function require_login() {
|
||||||
|
if (!is_logged_in()) {
|
||||||
|
header('Location: login.php');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
144
assets/css/admin.css
Normal file
144
assets/css/admin.css
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
/* assets/css/admin.css */
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--primary-color: #007bff;
|
||||||
|
--primary-hover: #0056b3;
|
||||||
|
--background-color: #f4f7fc;
|
||||||
|
--sidebar-bg: #ffffff;
|
||||||
|
--text-color: #333;
|
||||||
|
--text-light: #777;
|
||||||
|
--border-color: #eef2f7;
|
||||||
|
--shadow: 0 10px 30px rgba(0, 0, 0, 0.07);
|
||||||
|
--border-radius: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Poppins', sans-serif;
|
||||||
|
background-color: var(--background-color);
|
||||||
|
color: var(--text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Login Page Styles */
|
||||||
|
.login-page {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-card {
|
||||||
|
border: none;
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
box-shadow: var(--shadow);
|
||||||
|
padding: 2rem;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 420px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-card .card-title {
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
background-color: var(--primary-color);
|
||||||
|
border-color: var(--primary-color);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover {
|
||||||
|
background-color: var(--primary-hover);
|
||||||
|
border-color: var(--primary-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control {
|
||||||
|
border-radius: 8px;
|
||||||
|
border-color: var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control:focus {
|
||||||
|
box-shadow: 0 0 0 0.25rem rgba(0, 123, 255, 0.15);
|
||||||
|
border-color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Admin Layout Styles */
|
||||||
|
.wrapper {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar {
|
||||||
|
width: 250px;
|
||||||
|
background: var(--sidebar-bg);
|
||||||
|
box-shadow: 0 0 20px rgba(0,0,0,0.05);
|
||||||
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar .sidebar-header {
|
||||||
|
padding: 20px;
|
||||||
|
background: #fff;
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
text-align: center;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar ul.components {
|
||||||
|
padding: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar ul li a {
|
||||||
|
padding: 15px 20px;
|
||||||
|
font-size: 1rem;
|
||||||
|
display: block;
|
||||||
|
color: var(--text-light);
|
||||||
|
border-left: 3px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar ul li a:hover {
|
||||||
|
color: var(--primary-color);
|
||||||
|
background: #f7f7f7;
|
||||||
|
border-left-color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar ul li.active > a, a[aria-expanded="true"] {
|
||||||
|
color: var(--primary-color);
|
||||||
|
background: #f0f0f0;
|
||||||
|
border-left-color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
#content {
|
||||||
|
width: calc(100% - 250px);
|
||||||
|
padding: 40px;
|
||||||
|
min-height: 100vh;
|
||||||
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-title {
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
box-shadow: var(--shadow);
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table thead th {
|
||||||
|
border-top: none;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-light);
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table td, .table th {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-striped > tbody > tr:nth-of-type(odd) > * {
|
||||||
|
background-color: rgba(0,0,0,0.02);
|
||||||
|
}
|
||||||
130
assets/css/custom.css
Normal file
130
assets/css/custom.css
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
/* assets/css/custom.css */
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--primary-color: #007bff; /* A vibrant blue */
|
||||||
|
--primary-hover: #0056b3;
|
||||||
|
--background-color: #fdfdfd; /* A very light, almost white grey */
|
||||||
|
--card-bg-color: #ffffff;
|
||||||
|
--text-color: #333;
|
||||||
|
--text-light: #666;
|
||||||
|
--border-color: #eef2f7;
|
||||||
|
--shadow: 0 10px 30px rgba(0, 0, 0, 0.07);
|
||||||
|
--border-radius: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Poppins', sans-serif;
|
||||||
|
background-color: var(--background-color);
|
||||||
|
color: var(--text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
color: var(--primary-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
background-color: var(--primary-color);
|
||||||
|
border-color: var(--primary-color);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover {
|
||||||
|
background-color: var(--primary-hover);
|
||||||
|
border-color: var(--primary-hover);
|
||||||
|
transform: translateY(-2px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-success {
|
||||||
|
background-color: #28a745;
|
||||||
|
border-color: #28a745;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-success:hover {
|
||||||
|
background-color: #218838;
|
||||||
|
border-color: #1e7e34;
|
||||||
|
}
|
||||||
|
|
||||||
|
header.bg-white {
|
||||||
|
background-color: var(--card-bg-color) !important;
|
||||||
|
border-bottom-color: var(--border-color) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
header .fs-4 {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gallery-section .display-5 {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gallery-section .card {
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
box-shadow: none;
|
||||||
|
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gallery-section .card:hover {
|
||||||
|
transform: translateY(-5px);
|
||||||
|
box-shadow: var(--shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
#gallery-section .card-img-top {
|
||||||
|
border-top-left-radius: var(--border-radius);
|
||||||
|
border-top-right-radius: var(--border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
#gallery-section .card-title {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gallery-section .card-footer {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
#preview-section {
|
||||||
|
padding-top: 4rem;
|
||||||
|
padding-bottom: 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-container {
|
||||||
|
max-width: 960px;
|
||||||
|
margin: auto;
|
||||||
|
background: var(--card-bg-color);
|
||||||
|
padding: 3rem;
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
box-shadow: var(--shadow);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-container img {
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
#editor-section {
|
||||||
|
background-color: #f8f9fa; /* A slightly darker grey for contrast */
|
||||||
|
}
|
||||||
|
|
||||||
|
#editor-section h2 {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control, .form-select {
|
||||||
|
border-radius: 8px;
|
||||||
|
border-color: var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control:focus {
|
||||||
|
box-shadow: 0 0 0 0.25rem rgba(0, 123, 255, 0.15);
|
||||||
|
border-color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
footer.bg-light {
|
||||||
|
background-color: var(--card-bg-color) !important;
|
||||||
|
border-top-color: var(--border-color) !important;
|
||||||
|
}
|
||||||
BIN
assets/images/templates/1.jpg
Normal file
BIN
assets/images/templates/1.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 92 KiB |
BIN
assets/images/templates/2.jpg
Normal file
BIN
assets/images/templates/2.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 300 KiB |
BIN
assets/images/templates/3.jpg
Normal file
BIN
assets/images/templates/3.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 206 KiB |
65
assets/js/main.js
Normal file
65
assets/js/main.js
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const editorSection = document.getElementById('editor-section');
|
||||||
|
|
||||||
|
// Only run the script if the editor section exists
|
||||||
|
if (!editorSection) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const titleInput = document.getElementById('titleInput');
|
||||||
|
const descriptionInput = document.getElementById('descriptionInput');
|
||||||
|
const imageUrlInput = document.getElementById('imageUrlInput');
|
||||||
|
const ctaInput = document.getElementById('ctaInput');
|
||||||
|
const checkoutHtmlInput = document.getElementById('checkoutHtmlInput');
|
||||||
|
|
||||||
|
const previewTitle = document.getElementById('previewTitle');
|
||||||
|
const previewDescription = document.getElementById('previewDescription');
|
||||||
|
const previewImage = document.getElementById('previewImage');
|
||||||
|
const previewCtaContainer = document.getElementById('previewCtaContainer');
|
||||||
|
|
||||||
|
// --- Initialize Form from Preview ---
|
||||||
|
const initEditor = () => {
|
||||||
|
if (previewTitle) titleInput.value = previewTitle.textContent.trim();
|
||||||
|
if (previewDescription) descriptionInput.value = previewDescription.textContent.trim();
|
||||||
|
if (previewImage) imageUrlInput.value = previewImage.src;
|
||||||
|
|
||||||
|
const ctaButton = document.getElementById('previewCta');
|
||||||
|
if (ctaButton) ctaInput.value = ctaButton.textContent.trim();
|
||||||
|
};
|
||||||
|
|
||||||
|
// --- Event Listeners for Live Preview ---
|
||||||
|
titleInput.addEventListener('input', () => {
|
||||||
|
if (previewTitle) previewTitle.textContent = titleInput.value || 'Your Awesome Ebook Title';
|
||||||
|
});
|
||||||
|
|
||||||
|
descriptionInput.addEventListener('input', () => {
|
||||||
|
if (previewDescription) previewDescription.textContent = descriptionInput.value || 'A compelling description...';
|
||||||
|
});
|
||||||
|
|
||||||
|
imageUrlInput.addEventListener('input', () => {
|
||||||
|
if (previewImage) previewImage.src = imageUrlInput.value || 'https://images.pexels.com/photos/1907785/pexels-photo-1907785.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1';
|
||||||
|
});
|
||||||
|
|
||||||
|
const updateCtaView = () => {
|
||||||
|
if (!previewCtaContainer) return;
|
||||||
|
|
||||||
|
const checkoutValue = checkoutHtmlInput.value.trim();
|
||||||
|
if (checkoutValue !== '') {
|
||||||
|
previewCtaContainer.innerHTML = checkoutValue;
|
||||||
|
} else {
|
||||||
|
const ctaButton = document.createElement('button');
|
||||||
|
ctaButton.id = 'previewCta';
|
||||||
|
ctaButton.className = 'btn btn-primary btn-lg mt-3';
|
||||||
|
ctaButton.textContent = ctaInput.value.trim() || 'Download Now';
|
||||||
|
previewCtaContainer.innerHTML = '';
|
||||||
|
previewCtaContainer.appendChild(ctaButton);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
checkoutHtmlInput.addEventListener('input', updateCtaView);
|
||||||
|
ctaInput.addEventListener('input', updateCtaView);
|
||||||
|
|
||||||
|
// --- Initial Run ---
|
||||||
|
initEditor();
|
||||||
|
updateCtaView();
|
||||||
|
});
|
||||||
30
delete_template.php
Normal file
30
delete_template.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'admin/config.php';
|
||||||
|
require_login();
|
||||||
|
|
||||||
|
$template_name = isset($_GET['template']) ? basename($_GET['template']) : '';
|
||||||
|
|
||||||
|
if (empty($template_name)) {
|
||||||
|
header('Location: admin.php');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$template_path = 'templates/' . $template_name;
|
||||||
|
|
||||||
|
if (file_exists($template_path)) {
|
||||||
|
if (unlink($template_path)) {
|
||||||
|
// Optionally, you might want to delete the associated image as well.
|
||||||
|
// This part is left commented out as it requires more logic to find the correct image.
|
||||||
|
/*
|
||||||
|
$image_name = pathinfo($template_name, PATHINFO_FILENAME) . '.jpg'; // or png, etc.
|
||||||
|
$image_path = 'assets/images/templates/' . $image_name;
|
||||||
|
if (file_exists($image_path)) {
|
||||||
|
unlink($image_path);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
header('Location: admin.php');
|
||||||
|
exit;
|
||||||
|
?>
|
||||||
106
edit_template.php
Normal file
106
edit_template.php
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'admin/config.php';
|
||||||
|
require_login();
|
||||||
|
|
||||||
|
$error = '';
|
||||||
|
$success = '';
|
||||||
|
|
||||||
|
$template_name = isset($_GET['template']) ? basename($_GET['template']) : '';
|
||||||
|
|
||||||
|
if (empty($template_name)) {
|
||||||
|
header('Location: admin.php');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$template_path = 'templates/' . $template_name;
|
||||||
|
|
||||||
|
if (!file_exists($template_path)) {
|
||||||
|
die('Template not found.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
$template_content = isset($_POST['template_content']) ? trim($_POST['template_content']) : '';
|
||||||
|
|
||||||
|
if (empty($template_content)) {
|
||||||
|
$error = 'Template content is required.';
|
||||||
|
} else {
|
||||||
|
if (file_put_contents($template_path, $template_content)) {
|
||||||
|
$success = 'Template updated successfully.';
|
||||||
|
|
||||||
|
if (isset($_FILES['template_image']) && $_FILES['template_image']['error'] === UPLOAD_ERR_OK) {
|
||||||
|
$image_dir = 'assets/images/templates/';
|
||||||
|
$image_name = basename($_FILES['template_image']['name']);
|
||||||
|
$image_path = $image_dir . $image_name;
|
||||||
|
if (move_uploaded_file($_FILES['template_image']['tmp_name'], $image_path)) {
|
||||||
|
$success .= ' Image uploaded successfully.';
|
||||||
|
} else {
|
||||||
|
$error .= ' Failed to upload image.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
header('Location: admin.php');
|
||||||
|
} else {
|
||||||
|
$error = 'Failed to update template file.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$template_content = file_get_contents($template_path);
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Edit Template</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="assets/css/admin.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="wrapper">
|
||||||
|
<!-- Sidebar -->
|
||||||
|
<nav id="sidebar">
|
||||||
|
<div class="sidebar-header">
|
||||||
|
<h3>Admin Panel</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul class="list-unstyled components">
|
||||||
|
<li>
|
||||||
|
<a href="admin.php">Templates</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="logout.php">Logout</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<!-- Page Content -->
|
||||||
|
<div id="content">
|
||||||
|
<h1 class="page-title">Edit Template: <?php echo htmlspecialchars($template_name); ?></h1>
|
||||||
|
|
||||||
|
<?php if ($error): ?>
|
||||||
|
<div class="alert alert-danger"><?php echo $error; ?></div>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php if ($success): ?>
|
||||||
|
<div class="alert alert-success"><?php echo $success; ?></div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<form method="POST" enctype="multipart/form-data">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="template_content" class="form-label">Template Content (HTML)</label>
|
||||||
|
<textarea class="form-control" id="template_content" name="template_content" rows="10" required><?php echo htmlspecialchars($template_content); ?></textarea>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="template_image" class="form-label">Featured Image (optional, will replace existing)</label>
|
||||||
|
<input class="form-control" type="file" id="template_image" name="template_image">
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary">Update Template</button>
|
||||||
|
<a href="admin.php" class="btn btn-secondary">Cancel</a>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
382
index.php
382
index.php
@ -4,147 +4,257 @@ declare(strict_types=1);
|
|||||||
@error_reporting(E_ALL);
|
@error_reporting(E_ALL);
|
||||||
@date_default_timezone_set('UTC');
|
@date_default_timezone_set('UTC');
|
||||||
|
|
||||||
$phpVersion = PHP_VERSION;
|
require_once 'templates/data.php';
|
||||||
$now = date('Y-m-d H:i:s');
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'download') {
|
||||||
|
// (The download logic remains the same)
|
||||||
|
// Sanitize and retrieve POST data
|
||||||
|
$title = htmlspecialchars($_POST['title'] ?? 'Your Awesome Ebook Title');
|
||||||
|
$description = htmlspecialchars($_POST['description'] ?? 'A compelling description...');
|
||||||
|
$imageUrl = filter_var($_POST['imageUrl'] ?? '', FILTER_VALIDATE_URL) ?: 'https://images.pexels.com/photos/1907785/pexels-photo-1907785.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1';
|
||||||
|
$ctaText = htmlspecialchars($_POST['ctaText'] ?? 'Download Now');
|
||||||
|
$checkoutHtml = $_POST['checkoutHtml'] ?? '<!-- Paste your checkout/buy button code here -->';
|
||||||
|
|
||||||
|
// Fetch CSS for inlining
|
||||||
|
$cssContent = file_get_contents('assets/css/custom.css');
|
||||||
|
|
||||||
|
// Prepare image for ZIP
|
||||||
|
$imageContent = @file_get_contents($imageUrl);
|
||||||
|
$imageFilename = basename(parse_url($imageUrl, PHP_URL_PATH));
|
||||||
|
if (empty($imageFilename)) {
|
||||||
|
$imageFilename = 'featured-image.jpg';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate the final HTML content from the selected template structure
|
||||||
|
$templateId = (int)($_POST['template_id'] ?? 1);
|
||||||
|
$selectedTemplate = null;
|
||||||
|
foreach ($templates as $t) {
|
||||||
|
if ($t['id'] === $templateId) {
|
||||||
|
$selectedTemplate = $t;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$templateHtml = $selectedTemplate ? file_get_contents($selectedTemplate['file']) : '<div class="row align-items-center"><div class="col-md-6"><img id="previewImage" src="' . $imageUrl . '" class="img-fluid rounded shadow-sm" alt="Ebook Cover"></div><div class="col-md-6"><h1 id="previewTitle" class="display-5 fw-bold mt-4 mt-md-0">' . $title . '</h1><p id="previewDescription" class="lead fs-4">' . $description . '</p><div id="previewCtaContainer">' . $checkoutHtml . '</div></div></div>';
|
||||||
|
$templateDom = new DOMDocument();
|
||||||
|
@$templateDom->loadHTML($templateHtml, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
|
||||||
|
|
||||||
|
$imgTag = $templateDom->getElementById('previewImage');
|
||||||
|
if ($imgTag) $imgTag->setAttribute('src', $imageFilename);
|
||||||
|
|
||||||
|
$titleTag = $templateDom->getElementById('previewTitle');
|
||||||
|
if ($titleTag) $titleTag->nodeValue = $title;
|
||||||
|
|
||||||
|
$descTag = $templateDom->getElementById('previewDescription');
|
||||||
|
if ($descTag) $descTag->nodeValue = $description;
|
||||||
|
|
||||||
|
$ctaContainer = $templateDom->getElementById('previewCtaContainer');
|
||||||
|
if ($ctaContainer) {
|
||||||
|
// Clear existing content
|
||||||
|
while ($ctaContainer->hasChildNodes()) {
|
||||||
|
$ctaContainer->removeChild($ctaContainer->firstChild);
|
||||||
|
}
|
||||||
|
if (!empty(trim($checkoutHtml))) {
|
||||||
|
$fragment = $templateDom->createDocumentFragment();
|
||||||
|
@$fragment->appendXML($checkoutHtml);
|
||||||
|
$ctaContainer->appendChild($fragment);
|
||||||
|
} else {
|
||||||
|
$ctaContainer->nodeValue = $ctaText; // Fallback to simple text if no HTML
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$finalPreviewHtml = $templateDom->saveHTML();
|
||||||
|
|
||||||
|
|
||||||
|
$htmlContent = <<<HTML
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<title>$title</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||||
|
background-color: #F8F9FA;
|
||||||
|
color: #212529;
|
||||||
|
}
|
||||||
|
.preview-container { max-width: 960px; }
|
||||||
|
$cssContent
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main>
|
||||||
|
<section class="py-5">
|
||||||
|
<div class="container preview-container">
|
||||||
|
$finalPreviewHtml
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
<footer class="text-center py-3 bg-light">
|
||||||
|
<p class="mb-0">© 2025 The Contentrepreneur</p>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
HTML;
|
||||||
|
|
||||||
|
// Create a Zip archive
|
||||||
|
$zip = new ZipArchive();
|
||||||
|
$zipFileName = tempnam(sys_get_temp_dir(), 'ebook') . '.zip';
|
||||||
|
if ($zip->open($zipFileName, ZipArchive::CREATE) === TRUE) {
|
||||||
|
$zip->addFromString('index.html', $htmlContent);
|
||||||
|
if ($imageContent) {
|
||||||
|
$zip->addFromString($imageFilename, $imageContent);
|
||||||
|
}
|
||||||
|
$zip->close();
|
||||||
|
|
||||||
|
// Force download
|
||||||
|
header('Content-Type: application/zip');
|
||||||
|
header('Content-Disposition: attachment; filename="ebook_page.zip"');
|
||||||
|
header('Content-Length: ' . filesize($zipFileName));
|
||||||
|
readfile($zipFileName);
|
||||||
|
unlink($zipFileName);
|
||||||
|
exit;
|
||||||
|
} else {
|
||||||
|
error_log('Failed to create the ZIP file.');
|
||||||
|
exit('Could not create ZIP file.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$template_id = isset($_GET['template_id']) ? (int)$_GET['template_id'] : null;
|
||||||
|
$selectedTemplate = null;
|
||||||
|
$templateContent = '';
|
||||||
|
|
||||||
|
if ($template_id) {
|
||||||
|
foreach ($templates as $t) {
|
||||||
|
if ($t['id'] === $template_id) {
|
||||||
|
$selectedTemplate = $t;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($selectedTemplate && file_exists($selectedTemplate['file'])) {
|
||||||
|
$templateContent = file_get_contents($selectedTemplate['file']);
|
||||||
|
} else {
|
||||||
|
$template_id = null; // Reset if template not found
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read project preview data from environment
|
||||||
|
$projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Create and customize your own ebook landing page.';
|
||||||
|
$projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
|
||||||
?>
|
?>
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<title>New Style</title>
|
<title>Ebook Lead Magnet Generator</title>
|
||||||
<?php
|
|
||||||
// Read project preview data from environment
|
<?php if ($projectDescription): ?>
|
||||||
$projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? '';
|
<meta name="description" content="<?= htmlspecialchars($projectDescription) ?>" />
|
||||||
$projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
|
<meta property="og:description" content="<?= htmlspecialchars($projectDescription) ?>" />
|
||||||
?>
|
<meta property="twitter:description" content="<?= htmlspecialchars($projectDescription) ?>" />
|
||||||
<?php if ($projectDescription): ?>
|
<?php endif; ?>
|
||||||
<!-- Meta description -->
|
<?php if ($projectImageUrl): ?>
|
||||||
<meta name="description" content='<?= htmlspecialchars($projectDescription) ?>' />
|
<meta property="og:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
|
||||||
<!-- Open Graph meta tags -->
|
<meta property="twitter:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
|
||||||
<meta property="og:description" content="<?= htmlspecialchars($projectDescription) ?>" />
|
<?php endif; ?>
|
||||||
<!-- Twitter meta tags -->
|
|
||||||
<meta property="twitter:description" content="<?= htmlspecialchars($projectDescription) ?>" />
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
<?php endif; ?>
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
<?php if ($projectImageUrl): ?>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
<!-- Open Graph image -->
|
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||||
<meta property="og:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
|
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
|
||||||
<!-- Twitter image -->
|
|
||||||
<meta property="twitter:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
|
|
||||||
<?php endif; ?>
|
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet">
|
|
||||||
<style>
|
|
||||||
:root {
|
|
||||||
--bg-color-start: #6a11cb;
|
|
||||||
--bg-color-end: #2575fc;
|
|
||||||
--text-color: #ffffff;
|
|
||||||
--card-bg-color: rgba(255, 255, 255, 0.01);
|
|
||||||
--card-border-color: rgba(255, 255, 255, 0.1);
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
font-family: 'Inter', sans-serif;
|
|
||||||
background: linear-gradient(45deg, var(--bg-color-start), var(--bg-color-end));
|
|
||||||
color: var(--text-color);
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
min-height: 100vh;
|
|
||||||
text-align: center;
|
|
||||||
overflow: hidden;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
body::before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><path d="M-10 10L110 10M10 -10L10 110" stroke-width="1" stroke="rgba(255,255,255,0.05)"/></svg>');
|
|
||||||
animation: bg-pan 20s linear infinite;
|
|
||||||
z-index: -1;
|
|
||||||
}
|
|
||||||
@keyframes bg-pan {
|
|
||||||
0% { background-position: 0% 0%; }
|
|
||||||
100% { background-position: 100% 100%; }
|
|
||||||
}
|
|
||||||
main {
|
|
||||||
padding: 2rem;
|
|
||||||
}
|
|
||||||
.card {
|
|
||||||
background: var(--card-bg-color);
|
|
||||||
border: 1px solid var(--card-border-color);
|
|
||||||
border-radius: 16px;
|
|
||||||
padding: 2rem;
|
|
||||||
backdrop-filter: blur(20px);
|
|
||||||
-webkit-backdrop-filter: blur(20px);
|
|
||||||
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
.loader {
|
|
||||||
margin: 1.25rem auto 1.25rem;
|
|
||||||
width: 48px;
|
|
||||||
height: 48px;
|
|
||||||
border: 3px solid rgba(255, 255, 255, 0.25);
|
|
||||||
border-top-color: #fff;
|
|
||||||
border-radius: 50%;
|
|
||||||
animation: spin 1s linear infinite;
|
|
||||||
}
|
|
||||||
@keyframes spin {
|
|
||||||
from { transform: rotate(0deg); }
|
|
||||||
to { transform: rotate(360deg); }
|
|
||||||
}
|
|
||||||
.hint {
|
|
||||||
opacity: 0.9;
|
|
||||||
}
|
|
||||||
.sr-only {
|
|
||||||
position: absolute;
|
|
||||||
width: 1px; height: 1px;
|
|
||||||
padding: 0; margin: -1px;
|
|
||||||
overflow: hidden;
|
|
||||||
clip: rect(0, 0, 0, 0);
|
|
||||||
white-space: nowrap; border: 0;
|
|
||||||
}
|
|
||||||
h1 {
|
|
||||||
font-size: 3rem;
|
|
||||||
font-weight: 700;
|
|
||||||
margin: 0 0 1rem;
|
|
||||||
letter-spacing: -1px;
|
|
||||||
}
|
|
||||||
p {
|
|
||||||
margin: 0.5rem 0;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
}
|
|
||||||
code {
|
|
||||||
background: rgba(0,0,0,0.2);
|
|
||||||
padding: 2px 6px;
|
|
||||||
border-radius: 4px;
|
|
||||||
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
||||||
}
|
|
||||||
footer {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 1rem;
|
|
||||||
font-size: 0.8rem;
|
|
||||||
opacity: 0.7;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main>
|
|
||||||
<div class="card">
|
<header class="py-3 mb-4 border-bottom bg-white">
|
||||||
<h1>Analyzing your requirements and generating your website…</h1>
|
<div class="container d-flex flex-wrap justify-content-center">
|
||||||
<div class="loader" role="status" aria-live="polite" aria-label="Applying initial changes">
|
<a href="/" class="d-flex align-items-center mb-3 mb-md-0 me-md-auto text-dark text-decoration-none">
|
||||||
<span class="sr-only">Loading…</span>
|
<span class="fs-4">Ebook Page Builder</span>
|
||||||
</div>
|
</a>
|
||||||
<p class="hint"><?= ($_SERVER['HTTP_HOST'] ?? '') === 'appwizzy.com' ? 'AppWizzy' : 'Flatlogic' ?> AI is collecting your requirements and applying the first changes.</p>
|
</div>
|
||||||
<p class="hint">This page will update automatically as the plan is implemented.</p>
|
</header>
|
||||||
<p>Runtime: PHP <code><?= htmlspecialchars($phpVersion) ?></code> — UTC <code><?= htmlspecialchars($now) ?></code></p>
|
|
||||||
</div>
|
<main>
|
||||||
</main>
|
<?php if ($template_id): ?>
|
||||||
<footer>
|
<section id="preview-section" class="py-5">
|
||||||
Page updated: <?= htmlspecialchars($now) ?> (UTC)
|
<div class="container preview-container">
|
||||||
</footer>
|
<?= $templateContent ?>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="editor-section" class="bg-light-subtle py-5 border-top">
|
||||||
|
<div class="container">
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||||
|
<h2 class="m-0">Customize Your Page</h2>
|
||||||
|
<a href="/" class="btn btn-outline-secondary">← Back to Gallery</a>
|
||||||
|
</div>
|
||||||
|
<form method="POST">
|
||||||
|
<input type="hidden" name="action" value="download">
|
||||||
|
<input type="hidden" name="template_id" value="<?= $template_id ?>">
|
||||||
|
<div class="row g-4">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label for="titleInput" class="form-label">Title</label>
|
||||||
|
<input type="text" class="form-control" id="titleInput" name="title" placeholder="Enter ebook title">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label for="ctaInput" class="form-label">Call to Action Button Text</label>
|
||||||
|
<input type="text" class="form-control" id="ctaInput" name="ctaText" placeholder="e.g., Get Your Free Copy">
|
||||||
|
</div>
|
||||||
|
<div class="col-12">
|
||||||
|
<label for="descriptionInput" class="form-label">Description</label>
|
||||||
|
<textarea class="form-control" id="descriptionInput" name="description" rows="3" placeholder="Describe your ebook"></textarea>
|
||||||
|
</div>
|
||||||
|
<div class="col-12">
|
||||||
|
<label for="imageUrlInput" class="form-label">Featured Image URL</label>
|
||||||
|
<input type="url" class="form-control" id="imageUrlInput" name="imageUrl" placeholder="https://example.com/image.jpg">
|
||||||
|
</div>
|
||||||
|
<div class="col-12">
|
||||||
|
<label for="checkoutHtmlInput" class="form-label">Checkout/Buy Button HTML</label>
|
||||||
|
<textarea class="form-control" id="checkoutHtmlInput" name="checkoutHtml" rows="4" placeholder="Paste your HTML embed code here (e.g., from Stripe, PayPal, Gumroad)"></textarea>
|
||||||
|
<div class="form-text">This will replace the default button in the preview.</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 text-center mt-4">
|
||||||
|
<button type="submit" class="btn btn-success btn-lg">Generate and Download ZIP</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<?php else: ?>
|
||||||
|
<section id="gallery-section" class="py-5">
|
||||||
|
<div class="container">
|
||||||
|
<div class="text-center mb-5">
|
||||||
|
<h1 class="display-5 fw-bold">Start with a Beautiful Design</h1>
|
||||||
|
<p class="lead fs-4 text-muted">Select a professionally designed template to begin.</p>
|
||||||
|
</div>
|
||||||
|
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 g-4">
|
||||||
|
<?php foreach ($templates as $template): ?>
|
||||||
|
<div class="col">
|
||||||
|
<div class="card h-100 shadow-sm">
|
||||||
|
<img src="<?= htmlspecialchars($template['preview_image']) ?>" class="card-img-top" alt="<?= htmlspecialchars($template['name']) ?>">
|
||||||
|
<div class="card-body">
|
||||||
|
<h5 class="card-title"><?= htmlspecialchars($template['name']) ?></h5>
|
||||||
|
<p class="card-text"><?= htmlspecialchars($template['description']) ?></p>
|
||||||
|
</div>
|
||||||
|
<div class="card-footer bg-white border-0">
|
||||||
|
<a href="?template_id=<?= $template['id'] ?>" class="btn btn-primary w-100">Customize this template</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<?php endif; ?>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer class="text-center py-3 mt-5 bg-light border-top">
|
||||||
|
<p class="mb-0">© <?= date('Y') ?> The Contentrepreneur</p>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<script src="assets/js/main.js?v=<?php echo time(); ?>"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
52
login.php
Normal file
52
login.php
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'admin/config.php';
|
||||||
|
|
||||||
|
$error = '';
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
if (isset($_POST['username']) && isset($_POST['password'])) {
|
||||||
|
if ($_POST['username'] === ADMIN_USERNAME && $_POST['password'] === ADMIN_PASSWORD) {
|
||||||
|
$_SESSION['is_logged_in'] = true;
|
||||||
|
header('Location: admin.php');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$error = 'Invalid username or password.';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Admin Login</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="assets/css/admin.css">
|
||||||
|
</head>
|
||||||
|
<body class="login-page">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-md-5">
|
||||||
|
<div class="card login-card">
|
||||||
|
<div class="card-body">
|
||||||
|
<h1 class="card-title text-center">Admin Login</h1>
|
||||||
|
<?php if ($error): ?>
|
||||||
|
<div class="alert alert-danger"><?php echo $error; ?></div>
|
||||||
|
<?php endif; ?>
|
||||||
|
<form method="POST">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="username" class="form-label">Username</label>
|
||||||
|
<input type="text" class="form-control" id="username" name="username" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="password" class="form-label">Password</label>
|
||||||
|
<input type="password" class="form-control" id="password" name="password" required>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary w-100">Login</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
7
logout.php
Normal file
7
logout.php
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'admin/config.php';
|
||||||
|
$_SESSION['is_logged_in'] = false;
|
||||||
|
session_destroy();
|
||||||
|
header('Location: login.php');
|
||||||
|
exit;
|
||||||
|
?>
|
||||||
25
templates/data.php
Normal file
25
templates/data.php
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
$templates = [
|
||||||
|
[
|
||||||
|
'id' => 1,
|
||||||
|
'name' => 'Minimalist Modern',
|
||||||
|
'description' => 'A clean, modern design with a large feature image.',
|
||||||
|
'preview_image' => 'assets/images/templates/1.jpg',
|
||||||
|
'file' => 'templates/template-1.html',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'id' => 2,
|
||||||
|
'name' => 'Bold & Blue',
|
||||||
|
'description' => 'A vibrant design with a prominent blue call-to-action.',
|
||||||
|
'preview_image' => 'assets/images/templates/2.jpg',
|
||||||
|
'file' => 'templates/template-2.html',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'id' => 3,
|
||||||
|
'name' => 'Classic Serif',
|
||||||
|
'description' => 'An elegant, text-focused design for a classic feel.',
|
||||||
|
'preview_image' => 'assets/images/templates/3.jpg',
|
||||||
|
'file' => 'templates/template-3.html',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
?>
|
||||||
12
templates/template-1.html
Normal file
12
templates/template-1.html
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<div class="row align-items-center">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<img id="previewImage" src="https://images.pexels.com/photos/1907785/pexels-photo-1907785.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1" class="img-fluid rounded shadow-sm" alt="Ebook Cover">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<h1 id="previewTitle" class="display-5 fw-bold mt-4 mt-md-0">Minimalist Modern Title</h1>
|
||||||
|
<p id="previewDescription" class="lead fs-4">A compelling description for the minimalist modern template.</p>
|
||||||
|
<div id="previewCtaContainer">
|
||||||
|
<button id="previewCta" class="btn btn-primary btn-lg mt-3">Download Now</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
12
templates/template-2.html
Normal file
12
templates/template-2.html
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<div class="row align-items-center">
|
||||||
|
<div class="col-md-6 order-md-2">
|
||||||
|
<img id="previewImage" src="https://images.pexels.com/photos/2088205/pexels-photo-2088205.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1" class="img-fluid rounded shadow-sm" alt="Ebook Cover">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 order-md-1">
|
||||||
|
<h1 id="previewTitle" class="display-5 fw-bold mt-4 mt-md-0">Bold & Blue Title</h1>
|
||||||
|
<p id="previewDescription" class="lead fs-4">A vibrant and bold description for the blue-themed template.</p>
|
||||||
|
<div id="previewCtaContainer">
|
||||||
|
<button id="previewCta" class="btn btn-primary btn-lg mt-3">Get It Now!</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
10
templates/template-3.html
Normal file
10
templates/template-3.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<div class="row justify-content-center text-center">
|
||||||
|
<div class="col-lg-8">
|
||||||
|
<img id="previewImage" src="https://images.pexels.com/photos/1181298/pexels-photo-1181298.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1" class="img-fluid rounded shadow-sm mb-4" alt="Ebook Cover">
|
||||||
|
<h1 id="previewTitle" class="display-4 fw-bold">Classic Serif Title</h1>
|
||||||
|
<p id="previewDescription" class="lead fs-3 mx-auto">An elegant and classic description, perfect for a timeless serif-style ebook.</p>
|
||||||
|
<div id="previewCtaContainer">
|
||||||
|
<button id="previewCta" class="btn btn-outline-dark btn-lg mt-3">Read More</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
Loading…
x
Reference in New Issue
Block a user