From b358e01b211200cdae9b89c0a897386bc800cd6d Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Tue, 16 Dec 2025 22:27:25 +0000 Subject: [PATCH] versao2 --- assets/css/custom.css | 54 +++++++---- assets/js/main.js | 12 ++- generate.php | 202 +++++++++++++++++++++++++++++++++++++++++- index.php | 14 +-- 4 files changed, 251 insertions(+), 31 deletions(-) diff --git a/assets/css/custom.css b/assets/css/custom.css index 89fedb4..270c03e 100644 --- a/assets/css/custom.css +++ b/assets/css/custom.css @@ -1,47 +1,71 @@ - body { - background-color: #F9FAFB; /* Gray-50 */ - color: #111827; /* Gray-900 */ - font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; + background: linear-gradient(120deg, #fdfbfb 0%, #ebedee 100%); + color: #111827; + font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; } .card { border: none; - border-radius: 0.5rem; - box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); + border-radius: 1rem; + background-color: rgba(255, 255, 255, 0.7); + backdrop-filter: blur(10px) saturate(150%); + -webkit-backdrop-filter: blur(10px) saturate(150%); + box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); + border: 1px solid rgba(255, 255, 255, 0.2); } .form-control, .form-select { border-radius: 0.5rem; padding: 1rem; + background-color: rgba(255, 255, 255, 0.5); border: 1px solid #D1D5DB; /* Gray-300 */ } .form-control:focus, .form-select:focus { - border-color: #6366F1; /* Indigo */ - box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.2); + border-color: #4f46e5; /* Indigo-600 */ + box-shadow: 0 0 0 4px rgba(79, 70, 229, 0.2); + background-color: rgba(255, 255, 255, 0.8); } .btn-primary { - background-image: linear-gradient(to right, #6366F1, #4f46e5); + background-image: linear-gradient(to right, #4f46e5, #818cf8); border: none; border-radius: 0.5rem; padding: 1rem 2rem; - font-weight: 600; + font-weight: 700; color: white; - transition: transform 0.2s; + transition: all 0.3s ease; + box-shadow: 0 4px 6px rgba(79, 70, 229, 0.2); } .btn-primary:hover { - transform: translateY(-2px); - box-shadow: 0 4px 10px rgba(99, 102, 241, 0.3); + transform: translateY(-3px); + box-shadow: 0 10px 20px rgba(79, 70, 229, 0.3); } .logo { - font-weight: 800; - color: #111827; + font-weight: 900; + font-size: 3rem; + color: #1a202c; } .toast-container { z-index: 1090; } + +/* Result Page Styles */ +.result-textarea { + background-color: #0d1117; + color: #c9d1d9; + border: 1px solid #30363d; + font-family: 'Fira Code', monospace; + font-size: 14px; + border-radius: 0.5rem; + padding: 1rem; + box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.2); + height: 60vh; +} + +.result-textarea:focus { + outline: 2px solid #4f46e5; +} diff --git a/assets/js/main.js b/assets/js/main.js index 8181816..a826841 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -6,7 +6,7 @@ document.addEventListener('DOMContentLoaded', function () { form.addEventListener('submit', function (event) { event.preventDefault(); - const url = document.getElementById('url').value; + const url = document.getElementById('page_url').value; if (!url) { alert('Please enter a URL.'); return; @@ -15,12 +15,10 @@ document.addEventListener('DOMContentLoaded', function () { // Show toast notification toast.show(); - // You can add an AJAX call here later to submit the form asynchronously - // For now, it just shows a notification. - console.log('Form submitted with URL:', url); - console.log('Language:', document.getElementById('language').value); + // Submit the form after a brief delay to allow the toast to be seen + setTimeout(() => { + form.submit(); + }, 500); // 0.5-second delay - // Optional: clear the form after submission - // form.reset(); }); }); diff --git a/generate.php b/generate.php index 8a0985e..fd57859 100644 --- a/generate.php +++ b/generate.php @@ -1,5 +1,199 @@ 'success', 'message' => 'Request received. Processing will start soon.']); +ini_set('display_errors', 1); +error_reporting(E_ALL); + +require_once 'ai/LocalAIApi.php'; + +// Helper for debugging +function debug_log($message) { + echo "
DEBUG: " . htmlspecialchars($message) . "
\n"; + flush(); +} + +// Function to fetch URL content using cURL +function fetch_url_content($url) { + if (!filter_var($url, FILTER_VALIDATE_URL)) { + return ['error' => 'Invalid URL provided.']; + } + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($ch, CURLOPT_MAXREDIRS, 10); + curl_setopt($ch, CURLOPT_TIMEOUT, 30); + curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'); + curl_setopt($ch, CURLOPT_HTTPHEADER, [ + 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', + 'Accept-Language: en-US,en;q=0.9', + 'Connection: keep-alive', + ]); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); + + $html = curl_exec($ch); + $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); + $error = curl_error($ch); + curl_close($ch); + + if ($error) { + return ['error' => 'cURL Error: ' . $error]; + } + + if ($http_code >= 400) { + return ['error' => 'The page could not be accessed. HTTP Status Code: ' . $http_code]; + } + + return ['html' => $html]; +} + +// Function to parse HTML and extract key texts +function parse_html_and_extract_texts($doc, $xpath) { + // Remove script and style elements + foreach ($xpath->query('//script | //style') as $node) { + $node->parentNode->removeChild($node); + } + + $texts_map = []; + // More robust XPath to find visible text-containing nodes + $query = '//h1|//h2|//h3|//h4|//h5|//h6|//p|//li|//a|//span|//strong|//em|//b|//i|//button|//div[not(.//div)]'; + $nodes = $xpath->query($query); + + $i = 0; + foreach ($nodes as $node) { + // Find direct text children of the node + foreach($node->childNodes as $child) { + if ($child->nodeType === XML_TEXT_NODE) { + $original_text = trim($child->nodeValue); + if (!empty($original_text) && strlen($original_text) > 2) { // Only process meaningful text + $placeholder = "%%TEXT_{$i}%%"; + $texts_map[$placeholder] = $original_text; + $child->nodeValue = $placeholder; + $i++; + } + } + } + } + + return $texts_map; +} + + +if ($_SERVER['REQUEST_METHOD'] !== 'POST' || !isset($_POST['page_url'])) { + header('Location: /'); + exit; +} + +$page_url = $_POST['page_url']; +$language = $_POST['language'] ?? 'en'; +$error_message = null; +$final_html = ''; + +debug_log("Starting process for URL: {$page_url}"); + +$fetch_result = fetch_url_content($page_url); + +if (isset($fetch_result['error'])) { + $error_message = $fetch_result['error']; + debug_log("Error fetching URL: {$error_message}"); +} else { + $html_content = $fetch_result['html']; + debug_log("URL content fetched successfully (" . strlen($html_content) . " bytes)."); + + if (empty($html_content)) { + $error_message = "The fetched HTML content is empty."; + debug_log($error_message); + } else { + $doc = new DOMDocument(); + @$doc->loadHTML('' . $html_content); + $xpath = new DOMXPath($doc); + + $texts_map = parse_html_and_extract_texts($doc, $xpath); + debug_log("Extracted " . count($texts_map) . " text fragments."); + + if (empty($texts_map)) { + $error_message = "No visible text could be extracted from the HTML provided."; + debug_log($error_message); + $final_html = $doc->saveHTML(); // Save the cleaned HTML even if no text was found + } else { + $prompt_texts = json_encode($texts_map, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); + $system_prompt = "Act as an expert direct response copywriter... your JSON output must be flawless."; // Truncated for brevity + + debug_log("Sending to AI API..."); + $ai_response = LocalAIApi::createResponse([ + 'input' => [ + ['role' => 'system', 'content' => $system_prompt], + ['role' => 'user', 'content' => "Here is the JSON with texts to improve in `{$language}`:\n\n{$prompt_texts}"], + ], + ]); + + $improved_texts_json = LocalAIApi::extractText($ai_response); + debug_log("Received AI response."); + + if (empty($improved_texts_json)) { + $error_message = "AI response was empty."; + debug_log($error_message . " Raw Response: " . json_encode($ai_response)); + $final_html = ''; + } else { + $improved_texts_map = json_decode($improved_texts_json, true); + + if (json_last_error() !== JSON_ERROR_NONE) { + $error_message = "Failed to decode AI response. Error: " . json_last_error_msg(); + debug_log($error_message . " Raw response: " . $improved_texts_json); + $final_html = ''; + } else { + debug_log("AI response decoded. Replacing text nodes..."); + // Reconstruct the HTML by replacing placeholders in the DOM + foreach ($improved_texts_map as $placeholder => $new_text) { + $xpath_query = "//text()[. = '{$placeholder}']"; + $nodes_to_replace = $xpath->query($xpath_query); + foreach ($nodes_to_replace as $node) { + $node->nodeValue = $new_text; + } + } + $final_html = $doc->saveHTML(); + debug_log("HTML reconstruction complete."); + } + } + } + } +} +?> + + + + + + Análise de Conteúdo - PAGEHACK + + + + + + + +
+
+ Flatlogic + + + + + +

Your Improved Page is Ready

+

The copy has been rewritten for higher conversion. Copy the code below and paste it into your website builder.

+ +
+ +
+ + +
+
+ + diff --git a/index.php b/index.php index cb6330d..6da14be 100644 --- a/index.php +++ b/index.php @@ -6,6 +6,10 @@ PAGEHACK — AI Page Conversion + + + + @@ -17,8 +21,8 @@
-

PAGEHACK

-

Clone, rewrite, and translate any sales page for maximum conversion.

+

Page Hacker

+

Paste your website URL, and we'll rewrite the copy to be more persuasive and convert better.

@@ -26,8 +30,8 @@
- - + +
@@ -41,7 +45,7 @@
- +