diff --git a/admin/dashboard.php b/admin/dashboard.php new file mode 100644 index 0000000..aa17f69 --- /dev/null +++ b/admin/dashboard.php @@ -0,0 +1,30 @@ +query("SELECT c.*, u.username FROM campaigns c JOIN users u ON c.user_id = u.id")->fetchAll(); +?> + + +Admin Dashboard + +

Admin Dashboard

+ Logout +

Manage Campaigns

+ + + + + + + + + +
UserSlugActions
Edit
+ + diff --git a/api/chat.php b/api/chat.php deleted file mode 100644 index dbe026c..0000000 --- a/api/chat.php +++ /dev/null @@ -1,64 +0,0 @@ - "I didn't catch that. Could you repeat?"]); - exit; -} - -try { - // 1. Fetch Knowledge Base (FAQs) - $stmt = db()->query("SELECT keywords, answer FROM faqs"); - $faqs = $stmt->fetchAll(PDO::FETCH_ASSOC); - - $knowledgeBase = "Here is the knowledge base for this website:\n\n"; - foreach ($faqs as $faq) { - $knowledgeBase .= "Q: " . $faq['keywords'] . "\nA: " . $faq['answer'] . "\n---\n"; - } - - // 2. Construct Prompt for AI - $systemPrompt = "You are a helpful, friendly AI assistant for this website. " . - "Use the provided Knowledge Base to answer user questions accurately. " . - "If the answer is found in the Knowledge Base, rephrase it naturally. " . - "If the answer is NOT in the Knowledge Base, use your general knowledge to help, " . - "but politely mention that you don't have specific information about that if it seems like a site-specific question. " . - "Keep answers concise and professional.\n\n" . - $knowledgeBase; - - // 3. Call AI API - $response = LocalAIApi::createResponse([ - 'model' => 'gpt-4o-mini', - 'input' => [ - ['role' => 'system', 'content' => $systemPrompt], - ['role' => 'user', 'content' => $message], - ] - ]); - - if (!empty($response['success'])) { - $aiReply = LocalAIApi::extractText($response); - - // 4. Save to Database - try { - $stmt = db()->prepare("INSERT INTO messages (user_message, ai_response) VALUES (?, ?)"); - $stmt->execute([$message, $aiReply]); - } catch (Exception $e) { - error_log("DB Save Error: " . $e->getMessage()); - // Continue even if save fails, so the user still gets a reply - } - - echo json_encode(['reply' => $aiReply]); - } else { - // Fallback if AI fails - error_log("AI Error: " . ($response['error'] ?? 'Unknown')); - echo json_encode(['reply' => "I'm having trouble connecting to my brain right now. Please try again later."]); - } - -} catch (Exception $e) { - error_log("Chat Error: " . $e->getMessage()); - echo json_encode(['reply' => "An internal error occurred."]); -} diff --git a/api/telegram_webhook.php b/api/telegram_webhook.php deleted file mode 100644 index fa4899c..0000000 --- a/api/telegram_webhook.php +++ /dev/null @@ -1,91 +0,0 @@ -query("SELECT setting_value FROM settings WHERE setting_key = 'telegram_token'"); -$token = $stmt->fetchColumn(); - -if (!$token) { - error_log("Telegram Error: No bot token found in settings."); - exit; -} - -function sendTelegramMessage($chatId, $text, $token) { - $url = "https://api.telegram.org/bot$token/sendMessage"; - $data = [ - 'chat_id' => $chatId, - 'text' => $text, - 'parse_mode' => 'Markdown' - ]; - - $options = [ - 'http' => [ - 'header' => "Content-type: application/x-www-form-urlencoded\r\n", - 'method' => 'POST', - 'content' => http_build_query($data), - ], - ]; - $context = stream_context_create($options); - return file_get_contents($url, false, $context); -} - -// Process with AI (Similar logic to api/chat.php) -try { - // 1. Fetch Knowledge Base - $stmt = db()->query("SELECT keywords, answer FROM faqs"); - $faqs = $stmt->fetchAll(PDO::FETCH_ASSOC); - - $knowledgeBase = "Here is the knowledge base for this website:\n\n"; - foreach ($faqs as $faq) { - $knowledgeBase .= "Q: " . $faq['keywords'] . "\nA: " . $faq['answer'] . "\n---\n"; - } - - $systemPrompt = "You are a helpful AI assistant integrated with Telegram. " . - "Use the provided Knowledge Base to answer user questions. " . - "Keep answers concise for mobile reading. Use Markdown for formatting.\n\n" . - $knowledgeBase; - - // 2. Call AI - $response = LocalAIApi::createResponse([ - 'model' => 'gpt-4o-mini', - 'input' => [ - ['role' => 'system', 'content' => $systemPrompt], - ['role' => 'user', 'content' => $text], - ] - ]); - - if (!empty($response['success'])) { - $aiReply = LocalAIApi::extractText($response); - - // 3. Save History - try { - $stmt = db()->prepare("INSERT INTO messages (user_message, ai_response) VALUES (?, ?)"); - $stmt->execute(["[Telegram] " . $text, $aiReply]); - } catch (Exception $e) {} - - // 4. Send back to Telegram - sendTelegramMessage($chatId, $aiReply, $token); - } else { - sendTelegramMessage($chatId, "I'm sorry, I encountered an error processing your request.", $token); - } - -} catch (Exception $e) { - error_log("Telegram Webhook Error: " . $e->getMessage()); -} diff --git a/assets/css/custom.css b/assets/css/custom.css deleted file mode 100644 index 789132e..0000000 --- a/assets/css/custom.css +++ /dev/null @@ -1,403 +0,0 @@ -body { - background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab); - background-size: 400% 400%; - animation: gradient 15s ease infinite; - color: #212529; - font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; - font-size: 14px; - margin: 0; - min-height: 100vh; -} - -.main-wrapper { - display: flex; - align-items: center; - justify-content: center; - min-height: 100vh; - width: 100%; - padding: 20px; - box-sizing: border-box; - position: relative; - z-index: 1; -} - -@keyframes gradient { - 0% { - background-position: 0% 50%; - } - 50% { - background-position: 100% 50%; - } - 100% { - background-position: 0% 50%; - } -} - -.chat-container { - width: 100%; - max-width: 600px; - background: rgba(255, 255, 255, 0.85); - border: 1px solid rgba(255, 255, 255, 0.3); - border-radius: 20px; - display: flex; - flex-direction: column; - height: 85vh; - box-shadow: 0 20px 40px rgba(0,0,0,0.2); - backdrop-filter: blur(15px); - -webkit-backdrop-filter: blur(15px); - overflow: hidden; -} - -.chat-header { - padding: 1.5rem; - border-bottom: 1px solid rgba(0, 0, 0, 0.05); - background: rgba(255, 255, 255, 0.5); - font-weight: 700; - font-size: 1.1rem; - display: flex; - justify-content: space-between; - align-items: center; -} - -.chat-messages { - flex: 1; - overflow-y: auto; - padding: 1.5rem; - display: flex; - flex-direction: column; - gap: 1.25rem; -} - -/* Custom Scrollbar */ -::-webkit-scrollbar { - width: 6px; -} - -::-webkit-scrollbar-track { - background: transparent; -} - -::-webkit-scrollbar-thumb { - background: rgba(255, 255, 255, 0.3); - border-radius: 10px; -} - -::-webkit-scrollbar-thumb:hover { - background: rgba(255, 255, 255, 0.5); -} - -.message { - max-width: 85%; - padding: 0.85rem 1.1rem; - border-radius: 16px; - line-height: 1.5; - font-size: 0.95rem; - box-shadow: 0 4px 15px rgba(0,0,0,0.05); - animation: fadeIn 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275); -} - -@keyframes fadeIn { - from { opacity: 0; transform: translateY(20px) scale(0.95); } - to { opacity: 1; transform: translateY(0) scale(1); } -} - -.message.visitor { - align-self: flex-end; - background: linear-gradient(135deg, #212529 0%, #343a40 100%); - color: #fff; - border-bottom-right-radius: 4px; -} - -.message.bot { - align-self: flex-start; - background: #ffffff; - color: #212529; - border-bottom-left-radius: 4px; -} - -.chat-input-area { - padding: 1.25rem; - background: rgba(255, 255, 255, 0.5); - border-top: 1px solid rgba(0, 0, 0, 0.05); -} - -.chat-input-area form { - display: flex; - gap: 0.75rem; -} - -.chat-input-area input { - flex: 1; - border: 1px solid rgba(0, 0, 0, 0.1); - border-radius: 12px; - padding: 0.75rem 1rem; - outline: none; - background: rgba(255, 255, 255, 0.9); - transition: all 0.3s ease; -} - -.chat-input-area input:focus { - border-color: #23a6d5; - box-shadow: 0 0 0 3px rgba(35, 166, 213, 0.2); -} - -.chat-input-area button { - background: #212529; - color: #fff; - border: none; - padding: 0.75rem 1.5rem; - border-radius: 12px; - cursor: pointer; - font-weight: 600; - transition: all 0.3s ease; -} - -.chat-input-area button:hover { - background: #000; - transform: translateY(-2px); - box-shadow: 0 5px 15px rgba(0,0,0,0.2); -} - -/* Background Animations */ -.bg-animations { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: 0; - overflow: hidden; - pointer-events: none; -} - -.blob { - position: absolute; - width: 500px; - height: 500px; - background: rgba(255, 255, 255, 0.2); - border-radius: 50%; - filter: blur(80px); - animation: move 20s infinite alternate cubic-bezier(0.45, 0, 0.55, 1); -} - -.blob-1 { - top: -10%; - left: -10%; - background: rgba(238, 119, 82, 0.4); -} - -.blob-2 { - bottom: -10%; - right: -10%; - background: rgba(35, 166, 213, 0.4); - animation-delay: -7s; - width: 600px; - height: 600px; -} - -.blob-3 { - top: 40%; - left: 30%; - background: rgba(231, 60, 126, 0.3); - animation-delay: -14s; - width: 450px; - height: 450px; -} - -@keyframes move { - 0% { transform: translate(0, 0) rotate(0deg) scale(1); } - 33% { transform: translate(150px, 100px) rotate(120deg) scale(1.1); } - 66% { transform: translate(-50px, 200px) rotate(240deg) scale(0.9); } - 100% { transform: translate(0, 0) rotate(360deg) scale(1); } -} - -.header-link { - font-size: 14px; - color: #fff; - text-decoration: none; - background: rgba(0, 0, 0, 0.2); - padding: 0.5rem 1rem; - border-radius: 8px; - transition: all 0.3s ease; -} - -.header-link:hover { - background: rgba(0, 0, 0, 0.4); - text-decoration: none; -} - -/* Admin Styles */ -.admin-container { - max-width: 900px; - margin: 3rem auto; - padding: 2.5rem; - background: rgba(255, 255, 255, 0.85); - backdrop-filter: blur(20px); - -webkit-backdrop-filter: blur(20px); - border-radius: 24px; - box-shadow: 0 20px 50px rgba(0,0,0,0.15); - border: 1px solid rgba(255, 255, 255, 0.4); - position: relative; - z-index: 1; -} - -.admin-container h1 { - margin-top: 0; - color: #212529; - font-weight: 800; -} - -.table { - width: 100%; - border-collapse: separate; - border-spacing: 0 8px; - margin-top: 1.5rem; -} - -.table th { - background: transparent; - border: none; - padding: 1rem; - color: #6c757d; - font-weight: 600; - text-transform: uppercase; - font-size: 0.75rem; - letter-spacing: 1px; -} - -.table td { - background: #fff; - padding: 1rem; - border: none; -} - -.table tr td:first-child { border-radius: 12px 0 0 12px; } -.table tr td:last-child { border-radius: 0 12px 12px 0; } - -.form-group { - margin-bottom: 1.25rem; -} - -.form-group label { - display: block; - margin-bottom: 0.5rem; - font-weight: 600; - font-size: 0.9rem; -} - -.form-control { - width: 100%; - padding: 0.75rem 1rem; - border: 1px solid rgba(0, 0, 0, 0.1); - border-radius: 12px; - background: #fff; - transition: all 0.3s ease; - box-sizing: border-box; -} - -.form-control:focus { - outline: none; - border-color: #23a6d5; - box-shadow: 0 0 0 3px rgba(35, 166, 213, 0.1); -} - -.header-container { - display: flex; - justify-content: space-between; - align-items: center; -} - -.header-links { - display: flex; - gap: 1rem; -} - -.admin-card { - background: rgba(255, 255, 255, 0.6); - padding: 2rem; - border-radius: 20px; - border: 1px solid rgba(255, 255, 255, 0.5); - margin-bottom: 2.5rem; - box-shadow: 0 10px 30px rgba(0,0,0,0.05); -} - -.admin-card h3 { - margin-top: 0; - margin-bottom: 1.5rem; - font-weight: 700; -} - -.btn-delete { - background: #dc3545; - color: white; - border: none; - padding: 0.25rem 0.5rem; - border-radius: 4px; - cursor: pointer; -} - -.btn-add { - background: #212529; - color: white; - border: none; - padding: 0.5rem 1rem; - border-radius: 4px; - cursor: pointer; - margin-top: 1rem; -} - -.btn-save { - background: #0088cc; - color: white; - border: none; - padding: 0.8rem 1.5rem; - border-radius: 12px; - cursor: pointer; - font-weight: 600; - width: 100%; - transition: all 0.3s ease; -} - -.webhook-url { - font-size: 0.85em; - color: #555; - margin-top: 0.5rem; -} - -.history-table-container { - overflow-x: auto; - background: rgba(255, 255, 255, 0.4); - padding: 1rem; - border-radius: 12px; - border: 1px solid rgba(255, 255, 255, 0.3); -} - -.history-table { - width: 100%; -} - -.history-table-time { - width: 15%; - white-space: nowrap; - font-size: 0.85em; - color: #555; -} - -.history-table-user { - width: 35%; - background: rgba(255, 255, 255, 0.3); - border-radius: 8px; - padding: 8px; -} - -.history-table-ai { - width: 50%; - background: rgba(255, 255, 255, 0.5); - border-radius: 8px; - padding: 8px; -} - -.no-messages { - text-align: center; - color: #777; -} \ No newline at end of file diff --git a/assets/js/main.js b/assets/js/main.js deleted file mode 100644 index d349598..0000000 --- a/assets/js/main.js +++ /dev/null @@ -1,39 +0,0 @@ -document.addEventListener('DOMContentLoaded', () => { - const chatForm = document.getElementById('chat-form'); - const chatInput = document.getElementById('chat-input'); - const chatMessages = document.getElementById('chat-messages'); - - const appendMessage = (text, sender) => { - const msgDiv = document.createElement('div'); - msgDiv.classList.add('message', sender); - msgDiv.textContent = text; - chatMessages.appendChild(msgDiv); - chatMessages.scrollTop = chatMessages.scrollHeight; - }; - - chatForm.addEventListener('submit', async (e) => { - e.preventDefault(); - const message = chatInput.value.trim(); - if (!message) return; - - appendMessage(message, 'visitor'); - chatInput.value = ''; - - try { - const response = await fetch('api/chat.php', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ message }) - }); - const data = await response.json(); - - // Artificial delay for realism - setTimeout(() => { - appendMessage(data.reply, 'bot'); - }, 500); - } catch (error) { - console.error('Error:', error); - appendMessage("Sorry, something went wrong. Please try again.", 'bot'); - } - }); -}); diff --git a/assets/pasted-20260314-014551-772d9ad4.jpg b/assets/pasted-20260314-014551-772d9ad4.jpg new file mode 100644 index 0000000..2a76fad Binary files /dev/null and b/assets/pasted-20260314-014551-772d9ad4.jpg differ diff --git a/db/migrations/01_init_schema.php b/db/migrations/01_init_schema.php new file mode 100644 index 0000000..e31d9d3 --- /dev/null +++ b/db/migrations/01_init_schema.php @@ -0,0 +1,40 @@ +exec($sqlUsers); + +// Create Campaigns Table +$sqlCampaigns = "CREATE TABLE IF NOT EXISTS campaigns ( + id INT AUTO_INCREMENT PRIMARY KEY, + user_id INT NOT NULL, + slug VARCHAR(100) NOT NULL UNIQUE, + video_url VARCHAR(255), + offer_url VARCHAR(255), + is_active BOOLEAN DEFAULT TRUE, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (user_id) REFERENCES users(id) +)"; +$pdo->exec($sqlCampaigns); + +// Create Stats Table +$sqlStats = "CREATE TABLE IF NOT EXISTS stats ( + id INT AUTO_INCREMENT PRIMARY KEY, + campaign_id INT NOT NULL, + type ENUM('view', 'click') NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (campaign_id) REFERENCES campaigns(id) +)"; +$pdo->exec($sqlStats); + +echo "Database tables created successfully."; +?> diff --git a/index.php b/index.php deleted file mode 100644 index 7205f3d..0000000 --- a/index.php +++ /dev/null @@ -1,150 +0,0 @@ - - - - - - - New Style - - - - - - - - - - - - - - - - - - - - - -
-
-

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

-
-
- - - diff --git a/login.php b/login.php new file mode 100644 index 0000000..26a8cdb --- /dev/null +++ b/login.php @@ -0,0 +1,36 @@ +prepare("SELECT id, password, role FROM users WHERE username = ?"); + $stmt->execute([$username]); + $user = $stmt->fetch(); + + if ($user && password_verify($password, $user['password'])) { + $_SESSION['user_id'] = $user['id']; + $_SESSION['role'] = $user['role']; + header('Location: ' . ($user['role'] == 'admin' ? 'admin/dashboard.php' : 'member/dashboard.php')); + exit; + } else { + $error = "Invalid username or password."; + } +} +?> + + +Login + +

Login

+ $error

"; ?> +
+ Username:
+ Password:
+ +
+ + diff --git a/member/campaign_create.php b/member/campaign_create.php new file mode 100644 index 0000000..e8d0c23 --- /dev/null +++ b/member/campaign_create.php @@ -0,0 +1,33 @@ +prepare("INSERT INTO campaigns (user_id, slug, offer_url) VALUES (?, ?, ?)"); + $stmt->execute([$user_id, $slug, $offer_url]); + + header('Location: dashboard.php'); + exit; +} +?> + + +Create Campaign + +

Create Campaign

+
+ Slug (URL path):
+ Offer URL:
+ +
+ + diff --git a/member/dashboard.php b/member/dashboard.php new file mode 100644 index 0000000..8bded0d --- /dev/null +++ b/member/dashboard.php @@ -0,0 +1,34 @@ +prepare("SELECT * FROM campaigns WHERE user_id = ?"); +$campaigns->execute([$user_id]); +$campaigns = $campaigns->fetchAll(); +?> + + +Member Dashboard + +

Member Dashboard

+ Logout +

Your Campaigns

+ Create New Campaign + + + + + + + + + +
SlugURLActions
Edit
+ + diff --git a/setup_admin.php b/setup_admin.php new file mode 100644 index 0000000..3ff5dae --- /dev/null +++ b/setup_admin.php @@ -0,0 +1,15 @@ +query("SELECT id FROM users WHERE role = 'admin'"); +if (!$stmt->fetch()) { + $password = password_hash('admin123', PASSWORD_BCRYPT); + $stmt = $pdo->prepare("INSERT INTO users (username, email, password, role) VALUES (?, ?, ?, 'admin')"); + $stmt->execute(['admin', 'admin@verigate.local', $password]); + echo "Default admin user created: admin / admin123"; +} else { + echo "Admin user already exists."; +} +?> \ No newline at end of file diff --git a/verify.php b/verify.php new file mode 100644 index 0000000..8b2832b --- /dev/null +++ b/verify.php @@ -0,0 +1,34 @@ +prepare("SELECT * FROM campaigns WHERE slug = ? AND is_active = TRUE"); +$stmt->execute([$slug]); +$campaign = $stmt->fetch(); + +if (!$campaign) { + die("Campaign not found or inactive."); +} + +// Log view +$stmt = $pdo->prepare("INSERT INTO stats (campaign_id, type) VALUES (?, 'view')"); +$stmt->execute([$campaign['id']]); + +?> + + +Verify Age + +
+

Please Verify Your Age

+

This content is for adults only.

+ +
+ + diff --git a/verify_action.php b/verify_action.php new file mode 100644 index 0000000..b5273db --- /dev/null +++ b/verify_action.php @@ -0,0 +1,21 @@ +prepare("SELECT * FROM campaigns WHERE slug = ?"); +$stmt->execute([$slug]); +$campaign = $stmt->fetch(); + +if ($campaign) { + // Log click + $stmt = $pdo->prepare("INSERT INTO stats (campaign_id, type) VALUES (?, 'click')"); + $stmt->execute([$campaign['id']]); + header("Location: " . $campaign['offer_url']); + exit; +} else { + die("Error."); +} +?>