Compare commits
No commits in common. "ai-dev" and "master" have entirely different histories.
27
admin.php
27
admin.php
@ -1,27 +0,0 @@
|
|||||||
<?php
|
|
||||||
require_once 'templates/header.php';
|
|
||||||
|
|
||||||
// Protect this page
|
|
||||||
if (!isset($_SESSION['user_id'])) {
|
|
||||||
header("Location: login.php");
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
<main class="container my-5">
|
|
||||||
|
|
||||||
<section class="py-5">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-lg-8">
|
|
||||||
<div class="feature-card p-4">
|
|
||||||
<h2 class="text-center mb-4">Admin Panel</h2>
|
|
||||||
<p class="text-center">Welcome, <?php echo htmlspecialchars($_SESSION['username']); ?>!</p>
|
|
||||||
<p class="text-center">This is your admin dashboard. You can add content and manage your site from here.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
</main>
|
|
||||||
<?php require_once 'templates/footer.php'; ?>
|
|
||||||
@ -1,88 +0,0 @@
|
|||||||
:root {
|
|
||||||
--primary-color: #0D6EFD;
|
|
||||||
--secondary-color: #6C757D;
|
|
||||||
--background-color: #F8F9FA;
|
|
||||||
--surface-color: #FFFFFF;
|
|
||||||
--primary-font: 'Poppins', sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
font-family: var(--primary-font);
|
|
||||||
background: linear-gradient(270deg, #a1c4fd, #c2e9fb);
|
|
||||||
background-size: 400% 400%;
|
|
||||||
animation: moveGradient 15s ease infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes moveGradient {
|
|
||||||
0%{background-position:0% 50%}
|
|
||||||
50%{background-position:100% 50%}
|
|
||||||
100%{background-position:0% 50%}
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero-section {
|
|
||||||
background: linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), url('https://picsum.photos/seed/nimbus-hero/1600/900');
|
|
||||||
background-size: cover;
|
|
||||||
background-position: center;
|
|
||||||
color: white;
|
|
||||||
padding: 10rem 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar.scrolled {
|
|
||||||
background-color: rgba(255, 255, 255, 0.9);
|
|
||||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-control:focus {
|
|
||||||
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
|
|
||||||
border-color: #86b7fe;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary {
|
|
||||||
background-color: var(--primary-color);
|
|
||||||
border-color: var(--primary-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-icon {
|
|
||||||
font-size: 2.5rem;
|
|
||||||
color: var(--primary-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature-card {
|
|
||||||
background: rgba(255, 255, 255, 0.1);
|
|
||||||
backdrop-filter: blur(10px);
|
|
||||||
-webkit-backdrop-filter: blur(10px); /* For Safari */
|
|
||||||
border-radius: 15px;
|
|
||||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
||||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
|
||||||
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature-card:hover {
|
|
||||||
transform: translateY(-5px);
|
|
||||||
box-shadow: 0 8px 12px rgba(0, 0, 0, 0.15);
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero-section .btn-primary {
|
|
||||||
background-color: var(--primary-color);
|
|
||||||
border-color: var(--primary-color);
|
|
||||||
padding: 12px 30px;
|
|
||||||
font-weight: 600;
|
|
||||||
transition: background-color 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero-section .btn-primary:hover {
|
|
||||||
background-color: #0b5ed7;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero-section .btn-outline-secondary {
|
|
||||||
color: white;
|
|
||||||
border-color: white;
|
|
||||||
padding: 12px 30px;
|
|
||||||
font-weight: 600;
|
|
||||||
transition: background-color 0.3s ease, color 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero-section .btn-outline-secondary:hover {
|
|
||||||
background-color: white;
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
document.addEventListener('DOMContentLoaded', function () {
|
|
||||||
// Navbar shrink on scroll
|
|
||||||
const navbar = document.querySelector('.navbar');
|
|
||||||
if (navbar) {
|
|
||||||
window.addEventListener('scroll', () => {
|
|
||||||
if (window.scrollY > 50) {
|
|
||||||
navbar.classList.add('scrolled');
|
|
||||||
} else {
|
|
||||||
navbar.classList.remove('scrolled');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Smooth scroll for anchor links
|
|
||||||
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
|
||||||
anchor.addEventListener('click', function (e) {
|
|
||||||
e.preventDefault();
|
|
||||||
const target = document.querySelector(this.getAttribute('href'));
|
|
||||||
if (target) {
|
|
||||||
target.scrollIntoView({
|
|
||||||
behavior: 'smooth'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Pricing toggle
|
|
||||||
const priceToggle = document.getElementById('priceToggle');
|
|
||||||
if (priceToggle) {
|
|
||||||
priceToggle.addEventListener('change', function() {
|
|
||||||
const isYearly = this.checked;
|
|
||||||
document.querySelectorAll('[data-monthly]').forEach(priceEl => {
|
|
||||||
const monthly = priceEl.getAttribute('data-monthly');
|
|
||||||
const yearly = priceEl.getAttribute('data-yearly');
|
|
||||||
priceEl.textContent = isYearly ? yearly : monthly;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
<?php
|
|
||||||
// Simple migration runner
|
|
||||||
require_once __DIR__ . '/config.php';
|
|
||||||
|
|
||||||
try {
|
|
||||||
$pdo = db();
|
|
||||||
$migrationsDir = __DIR__ . '/migrations';
|
|
||||||
$files = glob($migrationsDir . '/*.sql');
|
|
||||||
|
|
||||||
if (empty($files)) {
|
|
||||||
echo "No migration files found.\n";
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
sort($files);
|
|
||||||
|
|
||||||
foreach ($files as $file) {
|
|
||||||
echo "Running migration: " . basename($file) . "...\n";
|
|
||||||
$sql = file_get_contents($file);
|
|
||||||
$pdo->exec($sql);
|
|
||||||
echo "Success.\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "\nAll migrations completed successfully.\n";
|
|
||||||
|
|
||||||
} catch (PDOException $e) {
|
|
||||||
die("Database error: " . $e->getMessage() . "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
CREATE TABLE IF NOT EXISTS `users` (
|
|
||||||
`id` INT AUTO_INCREMENT PRIMARY KEY,
|
|
||||||
`username` VARCHAR(50) NOT NULL UNIQUE,
|
|
||||||
`email` VARCHAR(100) NOT NULL UNIQUE,
|
|
||||||
`password_hash` VARCHAR(255) NOT NULL,
|
|
||||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
|
||||||
413
index.php
413
index.php
@ -1,288 +1,131 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
declare(strict_types=1);
|
||||||
$message_sent = null;
|
@ini_set('display_errors', '1');
|
||||||
|
@error_reporting(E_ALL);
|
||||||
|
@date_default_timezone_set('UTC');
|
||||||
|
|
||||||
if ($_SERVER["REQUEST_METHOD"] == "POST" && isset($_POST['form_submitted'])) {
|
$phpVersion = PHP_VERSION;
|
||||||
require_once __DIR__ . '/mail/MailService.php';
|
$now = date('Y-m-d H:i:s');
|
||||||
|
|
||||||
$name = filter_var(trim($_POST['name']), FILTER_SANITIZE_STRING);
|
|
||||||
$email = filter_var(trim($_POST['email']), FILTER_SANITIZE_EMAIL);
|
|
||||||
$message_text = filter_var(trim($_POST['message']), FILTER_SANITIZE_STRING);
|
|
||||||
|
|
||||||
if (filter_var($email, FILTER_VALIDATE_EMAIL) && !empty($name) && !empty($message_text)) {
|
|
||||||
$to = getenv('MAIL_TO') ?: 'support@yourdomain.com'; // Fallback recipient
|
|
||||||
$subject = 'New Lead from Nimbus Landing Page';
|
|
||||||
|
|
||||||
$res = MailService::sendContactMessage($name, $email, $message_text, $to, $subject);
|
|
||||||
|
|
||||||
if (!empty($res['success'])) {
|
|
||||||
$_SESSION['message_sent'] = 'success';
|
|
||||||
} else {
|
|
||||||
$_SESSION['message_sent'] = 'error';
|
|
||||||
// Log the detailed error
|
|
||||||
$log_message = date('[Y-m-d H:i:s]') . ' Mailer Error: ' . ($res['error'] ?? 'Unknown error') . PHP_EOL;
|
|
||||||
file_put_contents('mail_log.txt', $log_message, FILE_APPEND);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$_SESSION['message_sent'] = 'validation_error';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Redirect to avoid form resubmission
|
|
||||||
header("Location: " . $_SERVER['PHP_SELF'] . "#contact");
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_SESSION['message_sent'])) {
|
|
||||||
$message_sent = $_SESSION['message_sent'];
|
|
||||||
unset($_SESSION['message_sent']);
|
|
||||||
}
|
|
||||||
?>
|
?>
|
||||||
<?php require_once 'templates/header.php'; ?>
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
<!-- Hero -->
|
<head>
|
||||||
<section class="hero-section text-center py-5">
|
<meta charset="utf-8" />
|
||||||
<div class="container py-5">
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<h1 class="display-3 fw-bold">Your Cloud, Simplified</h1>
|
<title>New Style</title>
|
||||||
<p class="lead mb-5">Nimbus is the single pane of glass for your entire cloud infrastructure. Monitor, optimize, and automate with ease.</p>
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
<a href="#contact" class="btn btn-primary btn-lg">Start Your Free Trial</a>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
<a href="#features" class="btn btn-outline-secondary btn-lg">Explore Features</a>
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet">
|
||||||
</div>
|
<style>
|
||||||
</section>
|
:root {
|
||||||
|
--bg-color-start: #6a11cb;
|
||||||
<!-- Social Proof -->
|
--bg-color-end: #2575fc;
|
||||||
<section class="py-5">
|
--text-color: #ffffff;
|
||||||
<div class="container text-center">
|
--card-bg-color: rgba(255, 255, 255, 0.01);
|
||||||
<h6 class="text-muted mb-4">TRUSTED BY LEADING COMPANIES WORLDWIDE</h6>
|
--card-border-color: rgba(255, 255, 255, 0.1);
|
||||||
<div class="d-flex flex-wrap justify-content-center align-items-center">
|
}
|
||||||
<i class="bi bi-cloud-haze2 fs-1 text-muted mx-4"></i>
|
body {
|
||||||
<i class="bi bi-bar-chart-line fs-1 text-muted mx-4"></i>
|
margin: 0;
|
||||||
<i class="bi bi-shield-lock fs-1 text-muted mx-4"></i>
|
font-family: 'Inter', sans-serif;
|
||||||
<i class="bi bi-hdd-stack fs-1 text-muted mx-4"></i>
|
background: linear-gradient(45deg, var(--bg-color-start), var(--bg-color-end));
|
||||||
<i class="bi bi-globe2 fs-1 text-muted mx-4"></i>
|
color: var(--text-color);
|
||||||
</div>
|
display: flex;
|
||||||
</div>
|
justify-content: center;
|
||||||
</section>
|
align-items: center;
|
||||||
|
min-height: 100vh;
|
||||||
<!-- Features -->
|
text-align: center;
|
||||||
<section id="features" class="py-5">
|
overflow: hidden;
|
||||||
<div class="container">
|
position: relative;
|
||||||
<div class="text-center mb-5">
|
}
|
||||||
<h2>Core Features</h2>
|
body::before {
|
||||||
<p class="lead">Everything you need in one platform.</p>
|
content: '';
|
||||||
</div>
|
position: absolute;
|
||||||
<div class="row">
|
top: 0;
|
||||||
<div class="col-md-4 mb-4">
|
left: 0;
|
||||||
<div class="feature-card text-center p-4 h-100">
|
width: 100%;
|
||||||
<i class="bi bi-graph-up-arrow section-icon mb-3"></i>
|
height: 100%;
|
||||||
<h4>Unified Monitoring</h4>
|
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>');
|
||||||
<p>Get a bird's-eye view of your entire infrastructure in one place.</p>
|
animation: bg-pan 20s linear infinite;
|
||||||
</div>
|
z-index: -1;
|
||||||
</div>
|
}
|
||||||
<div class="col-md-4 mb-4">
|
@keyframes bg-pan {
|
||||||
<div class="feature-card text-center p-4 h-100">
|
0% { background-position: 0% 0%; }
|
||||||
<i class="bi bi-piggy-bank section-icon mb-3"></i>
|
100% { background-position: 100% 100%; }
|
||||||
<h4>Cost Optimization</h4>
|
}
|
||||||
<p>Identify and eliminate wasted cloud spend with smart recommendations.</p>
|
main {
|
||||||
</div>
|
padding: 2rem;
|
||||||
</div>
|
}
|
||||||
<div class="col-md-4 mb-4">
|
.card {
|
||||||
<div class="feature-card text-center p-4 h-100">
|
background: var(--card-bg-color);
|
||||||
<i class="bi bi-shield-check section-icon mb-3"></i>
|
border: 1px solid var(--card-border-color);
|
||||||
<h4>Automated Security</h4>
|
border-radius: 16px;
|
||||||
<p>Proactively secure your cloud environment against threats.</p>
|
padding: 2rem;
|
||||||
</div>
|
backdrop-filter: blur(20px);
|
||||||
</div>
|
-webkit-backdrop-filter: blur(20px);
|
||||||
</div>
|
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.1);
|
||||||
</div>
|
}
|
||||||
</section>
|
.loader {
|
||||||
|
margin: 1.25rem auto 1.25rem;
|
||||||
<!-- Product Screenshot -->
|
width: 48px;
|
||||||
<section class="py-5">
|
height: 48px;
|
||||||
<div class="container">
|
border: 3px solid rgba(255, 255, 255, 0.25);
|
||||||
<div class="text-center mb-5">
|
border-top-color: #fff;
|
||||||
<h2>See Nimbus in Action</h2>
|
border-radius: 50%;
|
||||||
</div>
|
animation: spin 1s linear infinite;
|
||||||
<img src="https://picsum.photos/seed/nimbus-dashboard/1200/800" class="img-fluid rounded shadow" alt="A mock screenshot of the Nimbus dashboard showing key performance metrics.">
|
}
|
||||||
</div>
|
@keyframes spin {
|
||||||
</section>
|
from { transform: rotate(0deg); }
|
||||||
|
to { transform: rotate(360deg); }
|
||||||
<!-- Testimonials -->
|
}
|
||||||
<section id="testimonials" class="py-5">
|
.hint {
|
||||||
<div class="container">
|
opacity: 0.9;
|
||||||
<div class="text-center mb-5">
|
}
|
||||||
<h2>What Our Customers Say</h2>
|
.sr-only {
|
||||||
</div>
|
position: absolute;
|
||||||
<div class="row">
|
width: 1px; height: 1px;
|
||||||
<div class="col-md-4 mb-4">
|
padding: 0; margin: -1px;
|
||||||
<div class="feature-card p-4 h-100">
|
overflow: hidden;
|
||||||
<p class="fst-italic">"Nimbus has been a game-changer for us. We've saved over 30% on our cloud bills."</p>
|
clip: rect(0, 0, 0, 0);
|
||||||
<div class="d-flex align-items-center mt-4">
|
white-space: nowrap; border: 0;
|
||||||
<img src="https://picsum.photos/seed/avatar1/96/96" class="rounded-circle me-3" alt="Avatar of a satisfied Nimbus customer.">
|
}
|
||||||
<div>
|
h1 {
|
||||||
<h6 class="m-0">Jane Doe</h6>
|
font-size: 3rem;
|
||||||
<small class="text-muted">CTO, TechCorp</small>
|
font-weight: 700;
|
||||||
</div>
|
margin: 0 0 1rem;
|
||||||
</div>
|
letter-spacing: -1px;
|
||||||
</div>
|
}
|
||||||
</div>
|
p {
|
||||||
<div class="col-md-4 mb-4">
|
margin: 0.5rem 0;
|
||||||
<div class="feature-card p-4 h-100">
|
font-size: 1.1rem;
|
||||||
<p class="fst-italic">"The unified dashboard is incredibly intuitive. Our team was up and running in minutes."</p>
|
}
|
||||||
<div class="d-flex align-items-center mt-4">
|
code {
|
||||||
<img src="https://picsum.photos/seed/avatar2/96/96" class="rounded-circle me-3" alt="Avatar of a satisfied Nimbus customer.">
|
background: rgba(0,0,0,0.2);
|
||||||
<div>
|
padding: 2px 6px;
|
||||||
<h6 class="m-0">John Smith</h6>
|
border-radius: 4px;
|
||||||
<small class="text-muted">CEO, Innovate LLC</small>
|
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
||||||
</div>
|
}
|
||||||
</div>
|
footer {
|
||||||
</div>
|
position: absolute;
|
||||||
</div>
|
bottom: 1rem;
|
||||||
<div class="col-md-4 mb-4">
|
font-size: 0.8rem;
|
||||||
<div class="feature-card p-4 h-100">
|
opacity: 0.7;
|
||||||
<p class="fst-italic">"I can't imagine managing our infrastructure without Nimbus. It's essential."</p>
|
}
|
||||||
<div class="d-flex align-items-center mt-4">
|
</style>
|
||||||
<img src="https://picsum.photos/seed/avatar3/96/96" class="rounded-circle me-3" alt="Avatar of a satisfied Nimbus customer.">
|
</head>
|
||||||
<div>
|
<body>
|
||||||
<h6 class="m-0">Sam Wilson</h6>
|
<main>
|
||||||
<small class="text-muted">DevOps Lead, Future Solutions</small>
|
<div class="card">
|
||||||
</div>
|
<h1>Analyzing your requirements and generating your website…</h1>
|
||||||
</div>
|
<div class="loader" role="status" aria-live="polite" aria-label="Applying initial changes">
|
||||||
</div>
|
<span class="sr-only">Loading…</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<p class="hint">Flatlogic AI is collecting your requirements and applying the first changes.</p>
|
||||||
</div>
|
<p class="hint">This page will update automatically as the plan is implemented.</p>
|
||||||
</section>
|
<p>Runtime: PHP <code><?= htmlspecialchars($phpVersion) ?></code> — UTC <code><?= htmlspecialchars($now) ?></code></p>
|
||||||
|
</div>
|
||||||
<!-- Pricing -->
|
</main>
|
||||||
<section id="pricing" class="py-5">
|
<footer>
|
||||||
<div class="container">
|
Page updated: <?= htmlspecialchars($now) ?> (UTC)
|
||||||
<div class="text-center mb-5">
|
</footer>
|
||||||
<h2>Simple, Transparent Pricing</h2>
|
</body>
|
||||||
<div class="form-check form-switch d-inline-block">
|
</html>
|
||||||
<input class="form-check-input" type="checkbox" id="priceToggle">
|
|
||||||
<label class="form-check-label" for="priceToggle">Yearly (Save 20%)</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<!-- Pricing Tier 1 -->
|
|
||||||
<div class="col-lg-4 mb-4">
|
|
||||||
<div class="feature-card text-center p-4 h-100">
|
|
||||||
<h4>Starter</h4>
|
|
||||||
<h5 class="card-title my-4">
|
|
||||||
<span data-monthly="$49" data-yearly="$39">$49</span>/mo
|
|
||||||
</h5>
|
|
||||||
<ul class="list-unstyled my-4">
|
|
||||||
<li>10 Projects</li>
|
|
||||||
<li>Basic Analytics</li>
|
|
||||||
<li>Email Support</li>
|
|
||||||
</ul>
|
|
||||||
<button class="btn btn-outline-light">Choose Plan</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- Pricing Tier 2 -->
|
|
||||||
<div class="col-lg-4 mb-4">
|
|
||||||
<div class="feature-card text-center p-4 h-100">
|
|
||||||
<h4>Pro</h4>
|
|
||||||
<h5 class="card-title my-4">
|
|
||||||
<span data-monthly="$99" data-yearly="$79">$99</span>/mo
|
|
||||||
</h5>
|
|
||||||
<ul class="list-unstyled my-4">
|
|
||||||
<li>Unlimited Projects</li>
|
|
||||||
<li>Advanced Analytics</li>
|
|
||||||
<li>Priority Support</li>
|
|
||||||
</ul>
|
|
||||||
<button class="btn btn-light">Choose Plan</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- Pricing Tier 3 -->
|
|
||||||
<div class="col-lg-4 mb-4">
|
|
||||||
<div class="feature-card text-center p-4 h-100">
|
|
||||||
<h4>Enterprise</h4>
|
|
||||||
<h5 class="card-title my-4">Contact Us</h5>
|
|
||||||
<ul class="list-unstyled my-4">
|
|
||||||
<li>Dedicated Infrastructure</li>
|
|
||||||
<li>Custom Integrations</li>
|
|
||||||
<li>24/7 Support</li>
|
|
||||||
</ul>
|
|
||||||
<button class="btn btn-outline-light">Contact Sales</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<!-- FAQ -->
|
|
||||||
<section id="faq" class="py-5">
|
|
||||||
<div class="container">
|
|
||||||
<div class="text-center mb-5">
|
|
||||||
<h2>Frequently Asked Questions</h2>
|
|
||||||
</div>
|
|
||||||
<div class="accordion" id="faqAccordion">
|
|
||||||
<div class="accordion-item">
|
|
||||||
<h2 class="accordion-header"><button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#faq1">What is Nimbus?</button></h2>
|
|
||||||
<div id="faq1" class="accordion-collapse collapse show" data-bs-parent="#faqAccordion">
|
|
||||||
<div class="accordion-body">Nimbus is a B2B SaaS platform that helps businesses manage their cloud infrastructure.</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="accordion-item">
|
|
||||||
<h2 class="accordion-header"><button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#faq2">What cloud providers do you support?</button></h2>
|
|
||||||
<div id="faq2" class="accordion-collapse collapse" data-bs-parent="#faqAccordion">
|
|
||||||
<div class="accordion-body">We support AWS, Google Cloud, and Azure.</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="accordion-item">
|
|
||||||
<h2 class="accordion-header"><button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#faq3">Can I cancel my subscription?</button></h2>
|
|
||||||
<div id="faq3" class="accordion-collapse collapse" data-bs-parent="#faqAccordion">
|
|
||||||
<div class="accordion-body">Yes, you can cancel your subscription at any time.</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<!-- Contact Form -->
|
|
||||||
<section id="contact" class="py-5">
|
|
||||||
<div class="container">
|
|
||||||
<div class="text-center mb-5">
|
|
||||||
<h2>Get in Touch</h2>
|
|
||||||
<p class="lead">We'd love to hear from you.</p>
|
|
||||||
</div>
|
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-lg-6">
|
|
||||||
<?php if ($message_sent === 'success'): ?>
|
|
||||||
<div class="alert alert-success" role="alert">
|
|
||||||
<strong>Thank you!</strong> Your message has been sent successfully.
|
|
||||||
</div>
|
|
||||||
<?php elseif ($message_sent === 'error'): ?>
|
|
||||||
<div class="alert alert-danger" role="alert">
|
|
||||||
<strong>Error!</strong> There was a problem sending your message. Please try again later.
|
|
||||||
</div>
|
|
||||||
<?php elseif ($message_sent === 'validation_error'): ?>
|
|
||||||
<div class="alert alert-warning" role="alert">
|
|
||||||
<strong>Oops!</strong> Please fill out all fields correctly.
|
|
||||||
</div>
|
|
||||||
<?php endif; ?>
|
|
||||||
|
|
||||||
<form id="leadForm" method="POST" action="#contact" novalidate>
|
|
||||||
<input type="hidden" name="form_submitted" value="1">
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="name" class="form-label">Name</label>
|
|
||||||
<input type="text" class="form-control" id="name" name="name" required>
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="email" class="form-label">Email</label>
|
|
||||||
<input type="email" class="form-control" id="email" name="email" required>
|
|
||||||
<div class="invalid-feedback">Please provide a valid email.</div>
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="message" class="form-label">Message</label>
|
|
||||||
<textarea class="form-control" id="message" name="message" rows="4" required></textarea>
|
|
||||||
</div>
|
|
||||||
<button type="submit" class="btn btn-primary">Send Message</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<?php require_once 'templates/footer.php'; ?>
|
|
||||||
|
|||||||
86
login.php
86
login.php
@ -1,86 +0,0 @@
|
|||||||
<?php
|
|
||||||
require_once 'db/config.php';
|
|
||||||
require_once 'templates/header.php';
|
|
||||||
|
|
||||||
$errors = [];
|
|
||||||
$email = '';
|
|
||||||
|
|
||||||
if (isset($_SESSION['user_id'])) {
|
|
||||||
header("Location: admin.php");
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($_SERVER["REQUEST_METHOD"] == "POST") {
|
|
||||||
$email = trim($_POST['email']);
|
|
||||||
$password = $_POST['password'];
|
|
||||||
|
|
||||||
if (empty($email)) {
|
|
||||||
$errors[] = 'Email is required';
|
|
||||||
}
|
|
||||||
if (empty($password)) {
|
|
||||||
$errors[] = 'Password is required';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (empty($errors)) {
|
|
||||||
$stmt = db()->prepare("SELECT id, username, password_hash FROM users WHERE email = ?");
|
|
||||||
$stmt->execute([$email]);
|
|
||||||
$user = $stmt->fetch();
|
|
||||||
|
|
||||||
if ($user && password_verify($password, $user['password_hash'])) {
|
|
||||||
$_SESSION['user_id'] = $user['id'];
|
|
||||||
$_SESSION['username'] = $user['username'];
|
|
||||||
header("Location: admin.php");
|
|
||||||
exit();
|
|
||||||
} else {
|
|
||||||
$errors[] = 'Invalid email or password';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
<main class="container my-5">
|
|
||||||
|
|
||||||
<section class="py-5">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-lg-6">
|
|
||||||
<div class="feature-card p-4">
|
|
||||||
<h2 class="text-center mb-4">Login</h2>
|
|
||||||
|
|
||||||
<?php if (isset($_GET['registration']) && $_GET['registration'] === 'success'): ?>
|
|
||||||
<div class="alert alert-success">
|
|
||||||
Registration successful! You can now log in.
|
|
||||||
</div>
|
|
||||||
<?php endif; ?>
|
|
||||||
|
|
||||||
<?php if (!empty($errors)): ?>
|
|
||||||
<div class="alert alert-danger">
|
|
||||||
<?php foreach ($errors as $error): ?>
|
|
||||||
<p class="m-0"><?php echo $error; ?></p>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</div>
|
|
||||||
<?php endif; ?>
|
|
||||||
|
|
||||||
<form method="POST" action="login.php">
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="email" class="form-label">Email</label>
|
|
||||||
<input type="email" class="form-control" id="email" name="email" value="<?php echo htmlspecialchars($email); ?>" 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>
|
|
||||||
<div class="d-grid">
|
|
||||||
<button type="submit" class="btn btn-primary">Login</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<p class="text-center mt-3">
|
|
||||||
Don't have an account? <a href="register.php">Register here</a>.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
</main>
|
|
||||||
<?php require_once 'templates/footer.php'; ?>
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
<?php
|
|
||||||
session_start();
|
|
||||||
session_unset();
|
|
||||||
session_destroy();
|
|
||||||
header("Location: login.php");
|
|
||||||
exit();
|
|
||||||
?>
|
|
||||||
@ -75,9 +75,7 @@ class MailService
|
|||||||
foreach ($toList as $addr) {
|
foreach ($toList as $addr) {
|
||||||
if (filter_var($addr, FILTER_VALIDATE_EMAIL)) { $mail->addAddress($addr); $added++; }
|
if (filter_var($addr, FILTER_VALIDATE_EMAIL)) { $mail->addAddress($addr); $added++; }
|
||||||
}
|
}
|
||||||
if ($added === 0) {
|
if ($added === 0) { $mail->addAddress($fromEmail, $fromName); }
|
||||||
return [ 'success' => false, 'error' => 'No recipients defined (set MAIL_TO or pass $to)' ];
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ((array)($opts['cc'] ?? []) as $cc) { if (filter_var($cc, FILTER_VALIDATE_EMAIL)) $mail->addCC($cc); }
|
foreach ((array)($opts['cc'] ?? []) as $cc) { if (filter_var($cc, FILTER_VALIDATE_EMAIL)) $mail->addCC($cc); }
|
||||||
foreach ((array)($opts['bcc'] ?? []) as $bcc){ if (filter_var($bcc, FILTER_VALIDATE_EMAIL)) $mail->addBCC($bcc); }
|
foreach ((array)($opts['bcc'] ?? []) as $bcc){ if (filter_var($bcc, FILTER_VALIDATE_EMAIL)) $mail->addBCC($bcc); }
|
||||||
@ -158,6 +156,8 @@ class MailService
|
|||||||
{
|
{
|
||||||
$mail = new PHPMailer\PHPMailer\PHPMailer(true);
|
$mail = new PHPMailer\PHPMailer\PHPMailer(true);
|
||||||
try {
|
try {
|
||||||
|
// Enable verbose debug output
|
||||||
|
$mail->SMTPDebug = 0;
|
||||||
$mail->isSMTP();
|
$mail->isSMTP();
|
||||||
$mail->Host = $cfg['smtp_host'] ?? '';
|
$mail->Host = $cfg['smtp_host'] ?? '';
|
||||||
$mail->Port = (int)($cfg['smtp_port'] ?? 587);
|
$mail->Port = (int)($cfg['smtp_port'] ?? 587);
|
||||||
@ -181,7 +181,7 @@ class MailService
|
|||||||
$mail->addReplyTo($cfg['reply_to']);
|
$mail->addReplyTo($cfg['reply_to']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destination: prefer dynamic recipients ($to), fallback to MAIL_TO; no silent FROM fallback
|
// Destination: prefer dynamic recipients ($to), fallback to MAIL_TO, then MAIL_FROM
|
||||||
$toList = [];
|
$toList = [];
|
||||||
if ($to) {
|
if ($to) {
|
||||||
if (is_string($to)) {
|
if (is_string($to)) {
|
||||||
@ -201,7 +201,8 @@ class MailService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($added === 0) {
|
if ($added === 0) {
|
||||||
return [ 'success' => false, 'error' => 'No recipients defined (set MAIL_TO or pass $to)' ];
|
// Final fallback: send to FROM address
|
||||||
|
$mail->addAddress($fromEmail, $fromName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// DKIM (optional)
|
// DKIM (optional)
|
||||||
|
|||||||
@ -35,8 +35,7 @@ function load_dotenv_if_needed(array $keys): void {
|
|||||||
|
|
||||||
load_dotenv_if_needed([
|
load_dotenv_if_needed([
|
||||||
'MAIL_TRANSPORT','SMTP_HOST','SMTP_PORT','SMTP_SECURE','SMTP_USER','SMTP_PASS',
|
'MAIL_TRANSPORT','SMTP_HOST','SMTP_PORT','SMTP_SECURE','SMTP_USER','SMTP_PASS',
|
||||||
'MAIL_FROM','MAIL_FROM_NAME','MAIL_REPLY_TO','MAIL_TO',
|
'MAIL_FROM','MAIL_FROM_NAME','MAIL_REPLY_TO','DKIM_DOMAIN','DKIM_SELECTOR','DKIM_PRIVATE_KEY_PATH'
|
||||||
'DKIM_DOMAIN','DKIM_SELECTOR','DKIM_PRIVATE_KEY_PATH'
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$transport = env_val('MAIL_TRANSPORT', 'smtp');
|
$transport = env_val('MAIL_TRANSPORT', 'smtp');
|
||||||
|
|||||||
224
mail_log.txt
224
mail_log.txt
@ -1,224 +0,0 @@
|
|||||||
SERVER -> CLIENT: 220 email-smtp.amazonaws.com ESMTP SimpleEmailService-d-UJAP95IYE gQZPHeokgr2tbwK3Dh8W
|
|
||||||
|
|
||||||
CLIENT -> SERVER: EHLO vm-30855.dev.flatlogic.app
|
|
||||||
|
|
||||||
SERVER -> CLIENT: 250-email-smtp.amazonaws.com
|
|
||||||
250-8BITMIME
|
|
||||||
250-STARTTLS
|
|
||||||
250-AUTH PLAIN LOGIN
|
|
||||||
250 Ok
|
|
||||||
|
|
||||||
CLIENT -> SERVER: STARTTLS
|
|
||||||
|
|
||||||
SERVER -> CLIENT: 220 Ready to start TLS
|
|
||||||
|
|
||||||
CLIENT -> SERVER: EHLO vm-30855.dev.flatlogic.app
|
|
||||||
|
|
||||||
SERVER -> CLIENT: 250-email-smtp.amazonaws.com
|
|
||||||
250-8BITMIME
|
|
||||||
250-STARTTLS
|
|
||||||
250-AUTH PLAIN LOGIN
|
|
||||||
250 Ok
|
|
||||||
|
|
||||||
CLIENT -> SERVER: AUTH LOGIN
|
|
||||||
|
|
||||||
SERVER -> CLIENT: 334 VXNlcm5hbWU6
|
|
||||||
|
|
||||||
CLIENT -> SERVER: [credentials hidden]
|
|
||||||
SERVER -> CLIENT: 334 UGFzc3dvcmQ6
|
|
||||||
|
|
||||||
CLIENT -> SERVER: [credentials hidden]
|
|
||||||
SERVER -> CLIENT: 235 Authentication successful.
|
|
||||||
|
|
||||||
CLIENT -> SERVER: MAIL FROM:<app@flatlogic.app>
|
|
||||||
|
|
||||||
SERVER -> CLIENT: 250 Ok
|
|
||||||
|
|
||||||
CLIENT -> SERVER: RCPT TO:<support@yourdomain.com>
|
|
||||||
|
|
||||||
SERVER -> CLIENT: 250 Ok
|
|
||||||
|
|
||||||
CLIENT -> SERVER: DATA
|
|
||||||
|
|
||||||
SERVER -> CLIENT: 354 End data with <CR><LF>.<CR><LF>
|
|
||||||
|
|
||||||
CLIENT -> SERVER: Date: Wed, 10 Sep 2025 13:14:43 +0000
|
|
||||||
|
|
||||||
CLIENT -> SERVER: To: support@yourdomain.com
|
|
||||||
|
|
||||||
CLIENT -> SERVER: From: 10 <app@flatlogic.app>
|
|
||||||
|
|
||||||
CLIENT -> SERVER: Reply-To: Administrator <Blarior@gmail.com>, app@flatlogic.app
|
|
||||||
|
|
||||||
CLIENT -> SERVER: Subject: New Lead from Nimbus Landing Page
|
|
||||||
|
|
||||||
CLIENT -> SERVER: Message-ID: <RGGz281O0f5ZTbjFzdr3xDUogbl4E1VbKQwy0wGzlc@vm-30855.dev.flatlogic.app>
|
|
||||||
|
|
||||||
CLIENT -> SERVER: X-Mailer: PHPMailer 6.6.3 (https://github.com/PHPMailer/PHPMailer)
|
|
||||||
|
|
||||||
CLIENT -> SERVER: MIME-Version: 1.0
|
|
||||||
|
|
||||||
CLIENT -> SERVER: Content-Type: multipart/alternative;
|
|
||||||
|
|
||||||
CLIENT -> SERVER: boundary="b1_RGGz281O0f5ZTbjFzdr3xDUogbl4E1VbKQwy0wGzlc"
|
|
||||||
|
|
||||||
CLIENT -> SERVER: Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
CLIENT -> SERVER:
|
|
||||||
|
|
||||||
CLIENT -> SERVER: This is a multi-part message in MIME format.
|
|
||||||
|
|
||||||
CLIENT -> SERVER:
|
|
||||||
|
|
||||||
CLIENT -> SERVER: --b1_RGGz281O0f5ZTbjFzdr3xDUogbl4E1VbKQwy0wGzlc
|
|
||||||
|
|
||||||
CLIENT -> SERVER: Content-Type: text/plain; charset=us-ascii
|
|
||||||
|
|
||||||
CLIENT -> SERVER:
|
|
||||||
|
|
||||||
CLIENT -> SERVER: Name: Administrator
|
|
||||||
|
|
||||||
CLIENT -> SERVER: Email: Blarior@gmail.com
|
|
||||||
|
|
||||||
CLIENT -> SERVER:
|
|
||||||
|
|
||||||
CLIENT -> SERVER: 123123
|
|
||||||
|
|
||||||
CLIENT -> SERVER:
|
|
||||||
|
|
||||||
CLIENT -> SERVER: --b1_RGGz281O0f5ZTbjFzdr3xDUogbl4E1VbKQwy0wGzlc
|
|
||||||
|
|
||||||
CLIENT -> SERVER: Content-Type: text/html; charset=us-ascii
|
|
||||||
|
|
||||||
CLIENT -> SERVER:
|
|
||||||
|
|
||||||
CLIENT -> SERVER: <p><strong>Name:</strong> Administrator</p><p><strong>Email:</strong> Blarior@gmail.com</p><hr>123123
|
|
||||||
|
|
||||||
CLIENT -> SERVER:
|
|
||||||
|
|
||||||
CLIENT -> SERVER:
|
|
||||||
|
|
||||||
CLIENT -> SERVER: --b1_RGGz281O0f5ZTbjFzdr3xDUogbl4E1VbKQwy0wGzlc--
|
|
||||||
|
|
||||||
CLIENT -> SERVER:
|
|
||||||
|
|
||||||
CLIENT -> SERVER: .
|
|
||||||
|
|
||||||
SERVER -> CLIENT: 250 Ok 0100019933c3a725-dee3f92c-89a8-43b8-b180-c9a6a6fc68db-000000
|
|
||||||
|
|
||||||
CLIENT -> SERVER: QUIT
|
|
||||||
|
|
||||||
SERVER -> CLIENT: 221 Bye
|
|
||||||
|
|
||||||
SERVER -> CLIENT: 220 email-smtp.amazonaws.com ESMTP SimpleEmailService-d-UJAP95IYE 6w6jayOyd9KI2UxK7oOd
|
|
||||||
|
|
||||||
CLIENT -> SERVER: EHLO vm-30855.dev.flatlogic.app
|
|
||||||
|
|
||||||
SERVER -> CLIENT: 250-email-smtp.amazonaws.com
|
|
||||||
250-8BITMIME
|
|
||||||
250-STARTTLS
|
|
||||||
250-AUTH PLAIN LOGIN
|
|
||||||
250 Ok
|
|
||||||
|
|
||||||
CLIENT -> SERVER: STARTTLS
|
|
||||||
|
|
||||||
SERVER -> CLIENT: 220 Ready to start TLS
|
|
||||||
|
|
||||||
CLIENT -> SERVER: EHLO vm-30855.dev.flatlogic.app
|
|
||||||
|
|
||||||
SERVER -> CLIENT: 250-email-smtp.amazonaws.com
|
|
||||||
250-8BITMIME
|
|
||||||
250-STARTTLS
|
|
||||||
250-AUTH PLAIN LOGIN
|
|
||||||
250 Ok
|
|
||||||
|
|
||||||
CLIENT -> SERVER: AUTH LOGIN
|
|
||||||
|
|
||||||
SERVER -> CLIENT: 334 VXNlcm5hbWU6
|
|
||||||
|
|
||||||
CLIENT -> SERVER: [credentials hidden]
|
|
||||||
SERVER -> CLIENT: 334 UGFzc3dvcmQ6
|
|
||||||
|
|
||||||
CLIENT -> SERVER: [credentials hidden]
|
|
||||||
SERVER -> CLIENT: 235 Authentication successful.
|
|
||||||
|
|
||||||
CLIENT -> SERVER: MAIL FROM:<app@flatlogic.app>
|
|
||||||
|
|
||||||
SERVER -> CLIENT: 250 Ok
|
|
||||||
|
|
||||||
CLIENT -> SERVER: RCPT TO:<support@yourdomain.com>
|
|
||||||
|
|
||||||
SERVER -> CLIENT: 250 Ok
|
|
||||||
|
|
||||||
CLIENT -> SERVER: DATA
|
|
||||||
|
|
||||||
SERVER -> CLIENT: 354 End data with <CR><LF>.<CR><LF>
|
|
||||||
|
|
||||||
CLIENT -> SERVER: Date: Wed, 10 Sep 2025 13:14:44 +0000
|
|
||||||
|
|
||||||
CLIENT -> SERVER: To: support@yourdomain.com
|
|
||||||
|
|
||||||
CLIENT -> SERVER: From: 10 <app@flatlogic.app>
|
|
||||||
|
|
||||||
CLIENT -> SERVER: Reply-To: Administrator <Blarior@gmail.com>, app@flatlogic.app
|
|
||||||
|
|
||||||
CLIENT -> SERVER: Subject: New Lead from Nimbus Landing Page
|
|
||||||
|
|
||||||
CLIENT -> SERVER: Message-ID: <cFHV6zdk7XiFa9a6KOQI4Pr2H941RS0y1Dmc5CeJU@vm-30855.dev.flatlogic.app>
|
|
||||||
|
|
||||||
CLIENT -> SERVER: X-Mailer: PHPMailer 6.6.3 (https://github.com/PHPMailer/PHPMailer)
|
|
||||||
|
|
||||||
CLIENT -> SERVER: MIME-Version: 1.0
|
|
||||||
|
|
||||||
CLIENT -> SERVER: Content-Type: multipart/alternative;
|
|
||||||
|
|
||||||
CLIENT -> SERVER: boundary="b1_cFHV6zdk7XiFa9a6KOQI4Pr2H941RS0y1Dmc5CeJU"
|
|
||||||
|
|
||||||
CLIENT -> SERVER: Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
CLIENT -> SERVER:
|
|
||||||
|
|
||||||
CLIENT -> SERVER: This is a multi-part message in MIME format.
|
|
||||||
|
|
||||||
CLIENT -> SERVER:
|
|
||||||
|
|
||||||
CLIENT -> SERVER: --b1_cFHV6zdk7XiFa9a6KOQI4Pr2H941RS0y1Dmc5CeJU
|
|
||||||
|
|
||||||
CLIENT -> SERVER: Content-Type: text/plain; charset=us-ascii
|
|
||||||
|
|
||||||
CLIENT -> SERVER:
|
|
||||||
|
|
||||||
CLIENT -> SERVER: Name: Administrator
|
|
||||||
|
|
||||||
CLIENT -> SERVER: Email: Blarior@gmail.com
|
|
||||||
|
|
||||||
CLIENT -> SERVER:
|
|
||||||
|
|
||||||
CLIENT -> SERVER: 123123
|
|
||||||
|
|
||||||
CLIENT -> SERVER:
|
|
||||||
|
|
||||||
CLIENT -> SERVER: --b1_cFHV6zdk7XiFa9a6KOQI4Pr2H941RS0y1Dmc5CeJU
|
|
||||||
|
|
||||||
CLIENT -> SERVER: Content-Type: text/html; charset=us-ascii
|
|
||||||
|
|
||||||
CLIENT -> SERVER:
|
|
||||||
|
|
||||||
CLIENT -> SERVER: <p><strong>Name:</strong> Administrator</p><p><strong>Email:</strong> Blarior@gmail.com</p><hr>123123
|
|
||||||
|
|
||||||
CLIENT -> SERVER:
|
|
||||||
|
|
||||||
CLIENT -> SERVER:
|
|
||||||
|
|
||||||
CLIENT -> SERVER: --b1_cFHV6zdk7XiFa9a6KOQI4Pr2H941RS0y1Dmc5CeJU--
|
|
||||||
|
|
||||||
CLIENT -> SERVER:
|
|
||||||
|
|
||||||
CLIENT -> SERVER: .
|
|
||||||
|
|
||||||
SERVER -> CLIENT: 250 Ok 0100019933c3aa2d-e6f1f09d-c150-43d9-9c5a-d8f926c41ff2-000000
|
|
||||||
|
|
||||||
CLIENT -> SERVER: QUIT
|
|
||||||
|
|
||||||
SERVER -> CLIENT: 221 Bye
|
|
||||||
|
|
||||||
102
register.php
102
register.php
@ -1,102 +0,0 @@
|
|||||||
<?php
|
|
||||||
require_once 'db/config.php';
|
|
||||||
require_once 'templates/header.php';
|
|
||||||
|
|
||||||
$errors = [];
|
|
||||||
$username = '';
|
|
||||||
$email = '';
|
|
||||||
|
|
||||||
if ($_SERVER["REQUEST_METHOD"] == "POST") {
|
|
||||||
$username = trim($_POST['username']);
|
|
||||||
$email = trim($_POST['email']);
|
|
||||||
$password = $_POST['password'];
|
|
||||||
$password_confirm = $_POST['password_confirm'];
|
|
||||||
|
|
||||||
// Validation
|
|
||||||
if (empty($username)) {
|
|
||||||
$errors[] = 'Username is required';
|
|
||||||
}
|
|
||||||
if (empty($email)) {
|
|
||||||
$errors[] = 'Email is required';
|
|
||||||
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
|
||||||
$errors[] = 'Invalid email format';
|
|
||||||
}
|
|
||||||
if (empty($password)) {
|
|
||||||
$errors[] = 'Password is required';
|
|
||||||
}
|
|
||||||
if ($password !== $password_confirm) {
|
|
||||||
$errors[] = 'Passwords do not match';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if user already exists
|
|
||||||
if (empty($errors)) {
|
|
||||||
$stmt = db()->prepare("SELECT id FROM users WHERE username = ? OR email = ?");
|
|
||||||
$stmt->execute([$username, $email]);
|
|
||||||
if ($stmt->fetch()) {
|
|
||||||
$errors[] = 'Username or email already taken';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert user if no errors
|
|
||||||
if (empty($errors)) {
|
|
||||||
$password_hash = password_hash($password, PASSWORD_DEFAULT);
|
|
||||||
$stmt = db()->prepare("INSERT INTO users (username, email, password_hash) VALUES (?, ?, ?)");
|
|
||||||
if ($stmt->execute([$username, $email, $password_hash])) {
|
|
||||||
// Redirect to login page
|
|
||||||
header("Location: login.php?registration=success");
|
|
||||||
exit();
|
|
||||||
} else {
|
|
||||||
$errors[] = 'Something went wrong. Please try again.';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
<main class="container my-5">
|
|
||||||
|
|
||||||
<section class="py-5">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-lg-6">
|
|
||||||
<div class="feature-card p-4">
|
|
||||||
<h2 class="text-center mb-4">Create an Account</h2>
|
|
||||||
|
|
||||||
<?php if (!empty($errors)): ?>
|
|
||||||
<div class="alert alert-danger">
|
|
||||||
<?php foreach ($errors as $error): ?>
|
|
||||||
<p class="m-0"><?php echo $error; ?></p>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</div>
|
|
||||||
<?php endif; ?>
|
|
||||||
|
|
||||||
<form method="POST" action="register.php">
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="username" class="form-label">Username</label>
|
|
||||||
<input type="text" class="form-control" id="username" name="username" value="<?php echo htmlspecialchars($username); ?>" required>
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="email" class="form-label">Email</label>
|
|
||||||
<input type="email" class="form-control" id="email" name="email" value="<?php echo htmlspecialchars($email); ?>" 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>
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="password_confirm" class="form-label">Confirm Password</label>
|
|
||||||
<input type="password" class="form-control" id="password_confirm" name="password_confirm" required>
|
|
||||||
</div>
|
|
||||||
<div class="d-grid">
|
|
||||||
<button type="submit" class="btn btn-primary">Register</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<p class="text-center mt-3">
|
|
||||||
Already have an account? <a href="login.php">Login here</a>.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
</main>
|
|
||||||
<?php require_once 'templates/footer.php'; ?>
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
<!-- Footer -->
|
|
||||||
<footer class="py-4 bg-dark text-white text-center">
|
|
||||||
<div class="container">
|
|
||||||
<p class="m-0">© <?php echo date("Y"); ?> Nimbus. All Rights Reserved.</p>
|
|
||||||
<p class="m-0"><a href="#" class="text-white">Privacy Policy</a> · <a href="#" class="text-white">Terms of Service</a></p>
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
|
||||||
<script src="assets/js/main.js?v=<?php echo time(); ?>"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
<?php if (session_status() === PHP_SESSION_NONE) { session_start(); } ?>
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>Nimbus - Effortless Cloud Management</title>
|
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
|
||||||
<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@400;600;700&display=swap" rel="stylesheet">
|
|
||||||
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<!-- Navbar -->
|
|
||||||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark sticky-top">
|
|
||||||
<div class="container">
|
|
||||||
<a class="navbar-brand fw-bold" href="index.php">Nimbus</a>
|
|
||||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
|
|
||||||
<span class="navbar-toggler-icon"></span>
|
|
||||||
</button>
|
|
||||||
<div class="collapse navbar-collapse" id="navbarNav">
|
|
||||||
<ul class="navbar-nav ms-auto">
|
|
||||||
<li class="nav-item"><a class="nav-link" href="index.php#features">Features</a></li>
|
|
||||||
<li class="nav-item"><a class="nav-link" href="index.php#testimonials">Testimonials</a></li>
|
|
||||||
<li class="nav-item"><a class="nav-link" href="index.php#pricing">Pricing</a></li>
|
|
||||||
<li class="nav-item"><a class="nav-link" href="index.php#faq">FAQ</a></li>
|
|
||||||
<?php if (isset($_SESSION['user_id'])): ?>
|
|
||||||
<li class="nav-item"><a class="nav-link" href="admin.php">Admin</a></li>
|
|
||||||
<li class="nav-item"><a class="btn btn-primary ms-lg-2" href="logout.php">Logout</a></li>
|
|
||||||
<?php else: ?>
|
|
||||||
<li class="nav-item"><a class="nav-link" href="login.php">Login</a></li>
|
|
||||||
<li class="nav-item"><a class="btn btn-primary ms-lg-2" href="register.php">Register</a></li>
|
|
||||||
<?php endif; ?>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
Loading…
x
Reference in New Issue
Block a user