This commit is contained in:
Flatlogic Bot 2025-12-01 02:19:38 +00:00
parent 552395fb3c
commit e87822db43
18 changed files with 1034 additions and 137 deletions

103
add_template.php Normal file
View 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
View 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
View 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
View 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
View 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;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

65
assets/js/main.js Normal file
View 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
View 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
View 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>

384
index.php
View File

@ -4,147 +4,257 @@ declare(strict_types=1);
@error_reporting(E_ALL);
@date_default_timezone_set('UTC');
$phpVersion = PHP_VERSION;
$now = date('Y-m-d H:i:s');
require_once 'templates/data.php';
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">&copy; 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>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>New Style</title>
<?php
// Read project preview data from environment
$projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? '';
$projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
?>
<?php if ($projectDescription): ?>
<!-- Meta description -->
<meta name="description" content='<?= htmlspecialchars($projectDescription) ?>' />
<!-- Open Graph meta tags -->
<meta property="og:description" content="<?= htmlspecialchars($projectDescription) ?>" />
<!-- Twitter meta tags -->
<meta property="twitter:description" content="<?= htmlspecialchars($projectDescription) ?>" />
<?php endif; ?>
<?php if ($projectImageUrl): ?>
<!-- Open Graph image -->
<meta property="og:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
<!-- 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>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Ebook Lead Magnet Generator</title>
<?php if ($projectDescription): ?>
<meta name="description" content="<?= htmlspecialchars($projectDescription) ?>" />
<meta property="og:description" content="<?= htmlspecialchars($projectDescription) ?>" />
<meta property="twitter:description" content="<?= htmlspecialchars($projectDescription) ?>" />
<?php endif; ?>
<?php if ($projectImageUrl): ?>
<meta property="og:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
<meta property="twitter:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
<?php endif; ?>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<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=Poppins:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head>
<body>
<main>
<div class="card">
<h1>Analyzing your requirements and generating your website…</h1>
<div class="loader" role="status" aria-live="polite" aria-label="Applying initial changes">
<span class="sr-only">Loading…</span>
</div>
<p class="hint"><?= ($_SERVER['HTTP_HOST'] ?? '') === 'appwizzy.com' ? 'AppWizzy' : 'Flatlogic' ?> AI is collecting your requirements and applying the first changes.</p>
<p class="hint">This page will update automatically as the plan is implemented.</p>
<p>Runtime: PHP <code><?= htmlspecialchars($phpVersion) ?></code> — UTC <code><?= htmlspecialchars($now) ?></code></p>
</div>
</main>
<footer>
Page updated: <?= htmlspecialchars($now) ?> (UTC)
</footer>
<header class="py-3 mb-4 border-bottom bg-white">
<div class="container d-flex flex-wrap justify-content-center">
<a href="/" class="d-flex align-items-center mb-3 mb-md-0 me-md-auto text-dark text-decoration-none">
<span class="fs-4">Ebook Page Builder</span>
</a>
</div>
</header>
<main>
<?php if ($template_id): ?>
<section id="preview-section" class="py-5">
<div class="container preview-container">
<?= $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">&larr; 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">&copy; <?= date('Y') ?> The Contentrepreneur</p>
</footer>
<script src="assets/js/main.js?v=<?php echo time(); ?>"></script>
</body>
</html>
</html>

52
login.php Normal file
View 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
View 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
View 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
View 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
View 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
View 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>