From 1efc07748a06c6477ba6c58c968515c217fee875 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Wed, 4 Mar 2026 08:52:30 +0000 Subject: [PATCH] Autosave: 20260304-085229 --- admin_edit.php | 43 +++++ admin_messages.php | 69 ++++++++ api/contact.php | 37 +++++ assets/css/custom.css | 356 ++++++++++------------------------------- assets/js/main.js | 140 ++++++++++++---- db/content_manager.php | 16 ++ index.php | 318 ++++++++++++++++++++---------------- 7 files changed, 536 insertions(+), 443 deletions(-) create mode 100644 admin_edit.php create mode 100644 admin_messages.php create mode 100644 api/contact.php create mode 100644 db/content_manager.php diff --git a/admin_edit.php b/admin_edit.php new file mode 100644 index 0000000..7498aca --- /dev/null +++ b/admin_edit.php @@ -0,0 +1,43 @@ +query("SELECT * FROM site_content")->fetchAll(); +?> + + + + Admin Edit Content + + + +
+

Edit Page Content

+ +
+
+ +
+ + +
+
+ + +
+ +
+
+ +
+ + diff --git a/admin_messages.php b/admin_messages.php new file mode 100644 index 0000000..bba4099 --- /dev/null +++ b/admin_messages.php @@ -0,0 +1,69 @@ + + + + + + + Inbox | Admin + + + + + + +
+
+

Contact Inquiries

+
+ +
+
+ + + + + + + + + + + + query("SELECT * FROM contacts ORDER BY created_at DESC")->fetchAll(); + if ($contacts): + foreach ($contacts as $c): + ?> + + + + + + + + + + + + + +
DateNameEmailSubjectMessage
No messages found yet.
+
+
+
+ + + + diff --git a/api/contact.php b/api/contact.php new file mode 100644 index 0000000..5d8f91a --- /dev/null +++ b/api/contact.php @@ -0,0 +1,37 @@ + false, 'message' => 'Invalid request method.']); + exit; +} + +$name = trim($_POST['name'] ?? ''); +$email = trim($_POST['email'] ?? ''); +$subject = trim($_POST['subject'] ?? 'New Contact Inquiry'); +$message = trim($_POST['message'] ?? ''); + +if (empty($name) || empty($email) || empty($message)) { + echo json_encode(['success' => false, 'message' => 'Please fill in all required fields.']); + exit; +} + +if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { + echo json_encode(['success' => false, 'message' => 'Invalid email format.']); + exit; +} + +try { + $stmt = db()->prepare("INSERT INTO contacts (name, email, subject, message) VALUES (?, ?, ?, ?)"); + $stmt->execute([$name, $email, $subject, $message]); + + // Attempt to send email via MailService if configured + MailService::sendContactMessage($name, $email, $message); + + echo json_encode(['success' => true, 'message' => 'Message saved successfully.']); +} catch (PDOException $e) { + error_log($e->getMessage()); + echo json_encode(['success' => false, 'message' => 'Database error. Please try again later.']); +} diff --git a/assets/css/custom.css b/assets/css/custom.css index 50e0502..8e5ece7 100644 --- a/assets/css/custom.css +++ b/assets/css/custom.css @@ -1,302 +1,122 @@ +:root { + --primary: #111827; + --secondary: #4b5563; + --accent: #2563eb; + --bg: #ffffff; + --surface: #f9fafb; + --border: #e5e7eb; + --radius: 6px; + --font-main: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; +} + 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; + font-family: var(--font-main); + background-color: var(--bg); + color: var(--primary); + line-height: 1.5; + -webkit-font-smoothing: antialiased; + position: relative; + overflow-x: hidden; } -.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; +/* Interactive Background */ +#bg-canvas { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: -1; + pointer-events: none; } -@keyframes gradient { - 0% { - background-position: 0% 50%; - } - 50% { - background-position: 100% 50%; - } - 100% { - background-position: 0% 50%; - } +.section-padding { + padding: 80px 0; } -.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; +.btn-primary { + background-color: var(--accent); + border-color: var(--accent); + border-radius: var(--radius); + padding: 10px 20px; + font-weight: 500; + transition: all 0.3s ease; } -.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; +.btn-primary:hover { + background-color: #1d4ed8; + border-color: #1d4ed8; + transform: translateY(-2px); } -.chat-messages { - flex: 1; - overflow-y: auto; - padding: 1.5rem; - display: flex; - flex-direction: column; - gap: 1.25rem; +/* 3D Portfolio Card Effects */ +.portfolio-card-container { + perspective: 1000px; } -/* Custom Scrollbar */ -::-webkit-scrollbar { - width: 6px; +.portfolio-card { + transition: all 0.6s cubic-bezier(0.23, 1, 0.32, 1); + transform-style: preserve-3d; + cursor: pointer; } -::-webkit-scrollbar-track { - background: transparent; +.portfolio-card:hover { + transform: rotateY(10deg) rotateX(5deg) scale(1.05); + box-shadow: 0 20px 25px -5px rgba(0,0,0,0.1), 0 10px 10px -5px rgba(0,0,0,0.04); } -::-webkit-scrollbar-thumb { - background: rgba(255, 255, 255, 0.3); - border-radius: 10px; +.card { + border: 1px solid var(--border); + border-radius: var(--radius); + box-shadow: none; + transition: all 0.3s ease; + background-color: rgba(255, 255, 255, 0.8); + backdrop-filter: blur(5px); } -::-webkit-scrollbar-thumb:hover { - background: rgba(255, 255, 255, 0.5); +.card:hover { + border-color: var(--accent); + box-shadow: 0 10px 15px -3px rgba(0,0,0,0.1); } -.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); +.nav-link { + color: var(--secondary); + font-weight: 500; + font-size: 0.95rem; + transition: color 0.2s; } -@keyframes fadeIn { - from { opacity: 0; transform: translateY(20px) scale(0.95); } - to { opacity: 1; transform: translateY(0) scale(1); } +.nav-link:hover { + color: var(--accent); } -.message.visitor { - align-self: flex-end; - background: linear-gradient(135deg, #212529 0%, #343a40 100%); - color: #fff; - border-bottom-right-radius: 4px; +.hero { + padding: 120px 0 80px; + background-color: transparent; } -.message.bot { - align-self: flex-start; - background: #ffffff; - color: #212529; - border-bottom-left-radius: 4px; +h1, h2, h3 { + font-weight: 700; + letter-spacing: -0.025em; } -.chat-input-area { - padding: 1.25rem; - background: rgba(255, 255, 255, 0.5); - border-top: 1px solid rgba(0, 0, 0, 0.05); +.portfolio-img { + width: 100%; + height: 240px; + object-fit: cover; + border-bottom: 1px solid var(--border); } -.chat-input-area form { - display: flex; - gap: 0.75rem; +.footer { + border-top: 1px solid var(--border); + padding: 40px 0; + background-color: rgba(249, 250, 251, 0.8); + backdrop-filter: blur(5px); } -.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); } -} - -.admin-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; -} - -.admin-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); +.toast-container { + position: fixed; + bottom: 24px; + right: 24px; + z-index: 1050; } \ No newline at end of file diff --git a/assets/js/main.js b/assets/js/main.js index d349598..32380c4 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -1,39 +1,109 @@ -document.addEventListener('DOMContentLoaded', () => { - const chatForm = document.getElementById('chat-form'); - const chatInput = document.getElementById('chat-input'); - const chatMessages = document.getElementById('chat-messages'); +document.addEventListener('DOMContentLoaded', function() { + const contactForm = document.getElementById('contactForm'); + if (contactForm) { + contactForm.addEventListener('submit', function(e) { + e.preventDefault(); + + const submitBtn = contactForm.querySelector('button[type="submit"]'); + const originalBtnText = submitBtn.innerHTML; + submitBtn.disabled = true; + submitBtn.innerHTML = ' Sending...'; - 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'); + const formData = new FormData(contactForm); + + fetch('api/contact.php', { + method: 'POST', + body: formData + }) + .then(response => response.json()) + .then(data => { + if (data.success) { + showToast('Success', 'Your message has been sent successfully!', 'success'); + contactForm.reset(); + } else { + showToast('Error', data.message || 'Something went wrong.', 'danger'); } + }) + .catch(error => { + showToast('Error', 'Network error. Please try again.', 'danger'); + }) + .finally(() => { + submitBtn.disabled = false; + submitBtn.innerHTML = originalBtnText; + }); }); + } + + // Interactive Background Animation + const canvas = document.getElementById('bg-canvas'); + const ctx = canvas.getContext('2d'); + let particles = []; + + function resize() { + canvas.width = window.innerWidth; + canvas.height = window.innerHeight; + } + + window.addEventListener('resize', resize); + resize(); + + class Particle { + constructor() { + this.reset(); + } + reset() { + this.x = Math.random() * canvas.width; + this.y = Math.random() * canvas.height; + this.size = Math.random() * 2 + 1; + this.speedX = Math.random() * 1 - 0.5; + this.speedY = Math.random() * 1 - 0.5; + } + update() { + this.x += this.speedX; + this.y += this.speedY; + if (this.x < 0 || this.x > canvas.width || this.y < 0 || this.y > canvas.height) this.reset(); + } + draw() { + ctx.fillStyle = 'rgba(37, 99, 235, 0.2)'; + ctx.beginPath(); + ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2); + ctx.fill(); + } + } + + for (let i = 0; i < 50; i++) particles.push(new Particle()); + + function animate() { + ctx.clearRect(0, 0, canvas.width, canvas.height); + particles.forEach(p => { p.update(); p.draw(); }); + requestAnimationFrame(animate); + } + animate(); }); + +function showToast(title, message, type) { + const toastContainer = document.getElementById('toastContainer'); + if (!toastContainer) return; + + const toastHtml = ` + + `; + + const toastWrapper = document.createElement('div'); + toastWrapper.innerHTML = toastHtml; + const toastElement = toastWrapper.firstElementChild; + + toastContainer.appendChild(toastElement); + + setTimeout(() => { + toastElement.classList.remove('show'); + setTimeout(() => toastElement.remove(), 500); + }, 5000); +} \ No newline at end of file diff --git a/db/content_manager.php b/db/content_manager.php new file mode 100644 index 0000000..9e919e8 --- /dev/null +++ b/db/content_manager.php @@ -0,0 +1,16 @@ +prepare("SELECT * FROM site_content WHERE section_key = ?"); + $stmt->execute([$key]); + return $stmt->fetch(); +} + +function update_content($key, $title, $content) { + $stmt = db()->prepare("INSERT INTO site_content (section_key, title, content) + VALUES (?, ?, ?) + ON DUPLICATE KEY UPDATE title = ?, content = ?"); + return $stmt->execute([$key, $title, $content, $title, $content]); +} +?> diff --git a/index.php b/index.php index 7205f3d..23fa5d3 100644 --- a/index.php +++ b/index.php @@ -1,150 +1,188 @@ - - - New Style - - - - - - - - - - - - - - - - - - - + + + <?= htmlspecialchars($projectName) ?> + + + + + + + + + + + + + + + -
-
-

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

-
-
- + + + + + + + + +
+
+
+
+

+

+ +
+
+ Profile +
+
+
+
+ + +
+
+
+

Selected Work

+

A collection of projects spanning web apps, branding, and UX design.

+
+
+ 'E-commerce Platform', 'category' => 'Web Development', 'img' => 'https://picsum.photos/seed/project1/800/600'], + ['title' => 'Banking App UI', 'category' => 'Product Design', 'img' => 'https://picsum.photos/seed/project2/800/600'], + ['title' => 'Travel Explorer', 'category' => 'Mobile App', 'img' => 'https://picsum.photos/seed/project3/800/600'], + ['title' => 'SaaS Dashboard', 'category' => 'UX Research', 'img' => 'https://picsum.photos/seed/project4/800/600'], + ]; + foreach ($projects as $project): + ?> +
+
+ <?= $project['title'] ?> +
+ +
+
+
+
+ +
+
+
+ + +
+
+
+
+
+

+
+
+

+
+
+
+
Expertise
+
Web Dev
+
+
+
Location
+
Remote / NYC
+
+
+
Experience
+
5+ Years
+
+
+
Focus
+
Clean UI
+
+
+
+
+
+
+
+ + +
+
+
+
+
+

Let's Connect

+

Have a project in mind or just want to say hi? Drop a message below.

+
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+
+
+
+
+
+ + + + + +
+ + +