diff --git a/add_template.php b/add_template.php new file mode 100644 index 0000000..e88e0f7 --- /dev/null +++ b/add_template.php @@ -0,0 +1,103 @@ + + + + + + + Add New Template + + + + +
+ + + + +
+

Add New Template

+ + +
+ + +
+ + +
+
+
+
+ + +
+
+ + +
+
+ + +
+ + Cancel +
+
+
+
+
+ + diff --git a/admin.php b/admin.php new file mode 100644 index 0000000..4b575da --- /dev/null +++ b/admin.php @@ -0,0 +1,72 @@ + + + + + + + Admin - Template Management + + + + +
+ + + + +
+
+

Template Management

+ Add New Template +
+ +
+
+ + + + + + + + + '; + echo ''; + echo ''; + echo ''; + } + } else { + echo ''; + } + ?> + +
Template NameActions
' . htmlspecialchars(basename($template)) . ''; + echo 'Edit '; + echo 'Delete'; + echo '
No templates found.
+
+
+
+
+ + \ No newline at end of file diff --git a/admin/config.php b/admin/config.php new file mode 100644 index 0000000..105f79f --- /dev/null +++ b/admin/config.php @@ -0,0 +1,19 @@ + \ No newline at end of file diff --git a/assets/css/admin.css b/assets/css/admin.css new file mode 100644 index 0000000..cf445f3 --- /dev/null +++ b/assets/css/admin.css @@ -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); +} \ No newline at end of file diff --git a/assets/css/custom.css b/assets/css/custom.css new file mode 100644 index 0000000..6a22cc0 --- /dev/null +++ b/assets/css/custom.css @@ -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; +} \ No newline at end of file diff --git a/assets/images/templates/1.jpg b/assets/images/templates/1.jpg new file mode 100644 index 0000000..e343b82 Binary files /dev/null and b/assets/images/templates/1.jpg differ diff --git a/assets/images/templates/2.jpg b/assets/images/templates/2.jpg new file mode 100644 index 0000000..03b7d87 Binary files /dev/null and b/assets/images/templates/2.jpg differ diff --git a/assets/images/templates/3.jpg b/assets/images/templates/3.jpg new file mode 100644 index 0000000..6f680bf Binary files /dev/null and b/assets/images/templates/3.jpg differ diff --git a/assets/js/main.js b/assets/js/main.js new file mode 100644 index 0000000..a054207 --- /dev/null +++ b/assets/js/main.js @@ -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(); +}); diff --git a/delete_template.php b/delete_template.php new file mode 100644 index 0000000..e0fe617 --- /dev/null +++ b/delete_template.php @@ -0,0 +1,30 @@ + \ No newline at end of file diff --git a/edit_template.php b/edit_template.php new file mode 100644 index 0000000..924ad63 --- /dev/null +++ b/edit_template.php @@ -0,0 +1,106 @@ + + + + + + + Edit Template + + + + +
+ + + + +
+

Edit Template:

+ + +
+ + +
+ + +
+
+
+
+ + +
+
+ + +
+ + Cancel +
+
+
+
+
+ + \ No newline at end of file diff --git a/index.php b/index.php index 7205f3d..815b5a8 100644 --- a/index.php +++ b/index.php @@ -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'] ?? ''; + + // 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']) : '
Ebook Cover

' . $title . '

' . $description . '

' . $checkoutHtml . '
'; + $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 = << + + + + + $title + + + + +
+
+
+ $finalPreviewHtml +
+
+
+ + + +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'] ?? ''; ?> - - - New Style - - - - - - - - - - - - - - - - - - - + + + Ebook Lead Magnet Generator + + + + + + + + + + + + + + + + -
-
-

Analyzing your requirements and generating your website…

-
- Loading… -
-

AI is collecting your requirements and applying the first changes.

-

This page will update automatically as the plan is implemented.

-

Runtime: PHP — UTC

-
-
- + +
+
+ + Ebook Page Builder + +
+
+ +
+ +
+
+ +
+
+ +
+
+
+

Customize Your Page

+ ← Back to Gallery +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
This will replace the default button in the preview.
+
+
+ +
+
+
+
+
+ + + +
+ + + + - + \ No newline at end of file diff --git a/login.php b/login.php new file mode 100644 index 0000000..24f6c84 --- /dev/null +++ b/login.php @@ -0,0 +1,52 @@ + + + + + + + Admin Login + + + + +
+
+
+ +
+
+
+ + \ No newline at end of file diff --git a/logout.php b/logout.php new file mode 100644 index 0000000..1779b21 --- /dev/null +++ b/logout.php @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/templates/data.php b/templates/data.php new file mode 100644 index 0000000..63391a9 --- /dev/null +++ b/templates/data.php @@ -0,0 +1,25 @@ + 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', + ], +]; +?> \ No newline at end of file diff --git a/templates/template-1.html b/templates/template-1.html new file mode 100644 index 0000000..f9f6067 --- /dev/null +++ b/templates/template-1.html @@ -0,0 +1,12 @@ +
+
+ Ebook Cover +
+
+

Minimalist Modern Title

+

A compelling description for the minimalist modern template.

+
+ +
+
+
\ No newline at end of file diff --git a/templates/template-2.html b/templates/template-2.html new file mode 100644 index 0000000..06155ee --- /dev/null +++ b/templates/template-2.html @@ -0,0 +1,12 @@ +
+
+ Ebook Cover +
+
+

Bold & Blue Title

+

A vibrant and bold description for the blue-themed template.

+
+ +
+
+
\ No newline at end of file diff --git a/templates/template-3.html b/templates/template-3.html new file mode 100644 index 0000000..30d48a3 --- /dev/null +++ b/templates/template-3.html @@ -0,0 +1,10 @@ +
+
+ Ebook Cover +

Classic Serif Title

+

An elegant and classic description, perfect for a timeless serif-style ebook.

+
+ +
+
+
\ No newline at end of file