Compare commits
No commits in common. "ai-dev" and "master" have entirely different histories.
65
apply.php
65
apply.php
@ -1,65 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require_once 'db/config.php';
|
|
||||||
require_once 'mail/MailService.php';
|
|
||||||
|
|
||||||
// 1. Validation
|
|
||||||
$name = trim($_POST['name'] ?? '');
|
|
||||||
$company = trim($_POST['company'] ?? '');
|
|
||||||
$email = trim($_POST['email'] ?? '');
|
|
||||||
$role = trim($_POST['role'] ?? '');
|
|
||||||
$error = '';
|
|
||||||
|
|
||||||
if (empty($name) || empty($company) || empty($email) || empty($role)) {
|
|
||||||
$error = 'All fields are required.';
|
|
||||||
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
|
||||||
$error = 'Please enter a valid email address.';
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($error) {
|
|
||||||
header('Location: index.php?error=' . urlencode($error) . '#apply');
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Database Insert
|
|
||||||
try {
|
|
||||||
$pdo = db();
|
|
||||||
$stmt = $pdo->prepare(
|
|
||||||
'INSERT INTO applications (name, company, email, role) VALUES (?, ?, ?, ?)'
|
|
||||||
);
|
|
||||||
$stmt->execute([$name, $company, $email, $role]);
|
|
||||||
} catch (PDOException $e) {
|
|
||||||
// In a real app, log this error. For now, redirect with a generic error.
|
|
||||||
error_log('DB Error: ' . $e->getMessage());
|
|
||||||
header('Location: index.php?error=' . urlencode('A database error occurred.') . '#apply');
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Email Notification
|
|
||||||
$to = getenv('MAIL_TO') ?: null; // Use admin email from .env
|
|
||||||
$subject = 'New FinMox Founding Access Application';
|
|
||||||
$htmlBody = "
|
|
||||||
<h1>New Application Received</h1>
|
|
||||||
<p>A new application has been submitted for FinMox founding access:</p>
|
|
||||||
<ul>
|
|
||||||
<li><strong>Name:</strong> " . htmlspecialchars($name) . "</li>
|
|
||||||
<li><strong>Company:</strong> " . htmlspecialchars($company) . "</li>
|
|
||||||
<li><strong>Email:</strong> " . htmlspecialchars($email) . "</li>
|
|
||||||
<li><strong>Role:</strong> " . htmlspecialchars($role) . "</li>
|
|
||||||
</ul>
|
|
||||||
";
|
|
||||||
$textBody = "New Application:\nName: $name\nCompany: $company\nEmail: $email\nRole: $role";
|
|
||||||
|
|
||||||
// Use MailService, but don't block the user if it fails
|
|
||||||
try {
|
|
||||||
MailService::sendMail($to, $subject, $htmlBody, $textBody);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
// Log email error but don't prevent user from seeing success
|
|
||||||
error_log('MailService Error: ' . $e->getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 4. Redirect to Success
|
|
||||||
header('Location: index.php?status=applied#apply');
|
|
||||||
exit;
|
|
||||||
|
|
||||||
@ -1,53 +0,0 @@
|
|||||||
:root{
|
|
||||||
--ink:#0b0b0c;
|
|
||||||
--paper:#fbfaf7;
|
|
||||||
--warm:#f2efe7;
|
|
||||||
--warm2:#ebe6da;
|
|
||||||
--line: rgba(11,11,12,.08);
|
|
||||||
--shadow: 0 18px 48px rgba(11,11,12,.10);
|
|
||||||
--shadow2: 0 10px 26px rgba(11,11,12,.10);
|
|
||||||
--radius: 28px;
|
|
||||||
}
|
|
||||||
|
|
||||||
html, body { height: 100%; }
|
|
||||||
body { font-family: 'Inter', sans-serif; background: var(--paper); color: var(--ink); }
|
|
||||||
|
|
||||||
/* page routing */
|
|
||||||
.page.hidden { display: none; }
|
|
||||||
|
|
||||||
/* warm glass cards */
|
|
||||||
.panel { border: 1px solid var(--line); border-radius: var(--radius); background: rgba(255,255,255,.70); box-shadow: var(--shadow2); backdrop-filter: blur(10px); }
|
|
||||||
.panel-strong { border: 1px solid var(--line); border-radius: var(--radius); background: rgba(255,255,255,.92); box-shadow: var(--shadow); }
|
|
||||||
.chip { border: 1px solid var(--line); border-radius: 999px; background: rgba(255,255,255,.75); }
|
|
||||||
.softline { border-color: var(--line); }
|
|
||||||
|
|
||||||
/* hero background */
|
|
||||||
.bg-warm {
|
|
||||||
background:
|
|
||||||
radial-gradient(1200px 520px at 20% 15%, rgba(243,236,223,.95), rgba(251,250,247,0) 60%),
|
|
||||||
radial-gradient(900px 520px at 85% 20%, rgba(236,232,219,.9), rgba(251,250,247,0) 55%),
|
|
||||||
radial-gradient(900px 520px at 55% 90%, rgba(241,238,230,.9), rgba(251,250,247,0) 60%),
|
|
||||||
var(--paper);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* subtle motion */
|
|
||||||
.fade { transition: opacity .18s ease, transform .18s ease; }
|
|
||||||
.hoverlift { transition: transform .18s ease, box-shadow .18s ease; }
|
|
||||||
.hoverlift:hover { transform: translateY(-2px); box-shadow: var(--shadow); }
|
|
||||||
|
|
||||||
/* nav active state */
|
|
||||||
.navlink.active { font-weight: 700; }
|
|
||||||
|
|
||||||
/* mobile menu */
|
|
||||||
.drawer.hidden { display:none; }
|
|
||||||
|
|
||||||
/* details */
|
|
||||||
details[open] summary { font-weight: 700; }
|
|
||||||
summary { cursor: pointer; }
|
|
||||||
summary::-webkit-details-marker { display:none; }
|
|
||||||
|
|
||||||
/* input focus */
|
|
||||||
.chip:focus-within {
|
|
||||||
outline: 2px solid var(--ink);
|
|
||||||
outline-offset: 2px;
|
|
||||||
}
|
|
||||||
@ -1,121 +0,0 @@
|
|||||||
const pages = ['home','problem','why','how','roi','pricing','who','trust','roadmap','faq','signin','apply'];
|
|
||||||
|
|
||||||
|
|
||||||
function openPage(pageId) {
|
|
||||||
if (!pages.includes(pageId)) {
|
|
||||||
console.warn(`Attempted to navigate to a non-existent page: ${pageId}`);
|
|
||||||
return; // Do not proceed if the page is not in the allowed list
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hide all pages
|
|
||||||
document.querySelectorAll('.page').forEach(p => {
|
|
||||||
p.classList.add('hidden');
|
|
||||||
});
|
|
||||||
|
|
||||||
// Show the active page
|
|
||||||
const activePage = document.getElementById('page-' + pageId);
|
|
||||||
if (activePage) {
|
|
||||||
activePage.classList.remove('hidden');
|
|
||||||
} else {
|
|
||||||
// If no specific page content, default to home
|
|
||||||
document.getElementById('page-home').classList.remove('hidden');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update active link styling
|
|
||||||
document.querySelectorAll('.navlink').forEach(link => {
|
|
||||||
if (link.dataset.page === pageId) {
|
|
||||||
link.classList.add('active');
|
|
||||||
} else {
|
|
||||||
link.classList.remove('active');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Smooth scroll to top
|
|
||||||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
|
||||||
const navLinksContainer = document.getElementById('nav-links');
|
|
||||||
const mobileMenuContainer = document.getElementById('mobile-menu');
|
|
||||||
const footerLinksContainer = document.getElementById('footer-links');
|
|
||||||
const menuButton = document.getElementById('menu-button');
|
|
||||||
|
|
||||||
// Generate navigation links
|
|
||||||
let navHTML = '';
|
|
||||||
pages.forEach(page => {
|
|
||||||
let link = `#${page}`;
|
|
||||||
if (page === 'faq' || page === 'trust') {
|
|
||||||
link = `#${page}`;
|
|
||||||
}
|
|
||||||
navHTML += `<a href="${link}" class="navlink px-3 py-2 rounded-full hover:bg-gray-100" data-page="${page}">${page.charAt(0).toUpperCase() + page.slice(1)}</a>`;
|
|
||||||
});
|
|
||||||
navLinksContainer.innerHTML = navHTML;
|
|
||||||
mobileMenuContainer.innerHTML = navHTML.replace(/class="/g, 'class="block w-full text-left ');
|
|
||||||
|
|
||||||
// Generate footer links
|
|
||||||
if (footerLinksContainer) {
|
|
||||||
let footerHTML = '';
|
|
||||||
const footerPages = ['apply', 'signin', 'trust', 'faq'];
|
|
||||||
footerPages.forEach((page, index) => {
|
|
||||||
let link = `#${page}`;
|
|
||||||
if (page === 'faq' || page === 'trust') {
|
|
||||||
link = `#${page}`;
|
|
||||||
}
|
|
||||||
footerHTML += `<a href="${link}" class="underline navlink" data-page="${page}">${page.charAt(0).toUpperCase() + page.slice(1)}</a>`;
|
|
||||||
if (index < footerPages.length - 1) {
|
|
||||||
footerHTML += `<span class="opacity-50">·</span>`;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
footerLinksContainer.innerHTML = footerHTML;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Toggle mobile menu
|
|
||||||
menuButton.addEventListener('click', () => {
|
|
||||||
mobileMenuContainer.classList.toggle('hidden');
|
|
||||||
});
|
|
||||||
|
|
||||||
if (document.getElementById('page-home')) {
|
|
||||||
// Handle navigation clicks for SPA
|
|
||||||
document.querySelectorAll('.navlink').forEach(link => {
|
|
||||||
link.addEventListener('click', (e) => {
|
|
||||||
const page = link.dataset.page;
|
|
||||||
e.preventDefault();
|
|
||||||
openPage(link.dataset.page);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Open page based on hash or default to 'home'
|
|
||||||
const initialPage = window.location.hash.substring(1) || 'home';
|
|
||||||
openPage(initialPage);
|
|
||||||
|
|
||||||
// Tab functionality for 'Why FinMox' page
|
|
||||||
const whyTabs = document.querySelectorAll('.why-tab');
|
|
||||||
const whyContents = document.querySelectorAll('.why-content');
|
|
||||||
|
|
||||||
whyTabs.forEach(tab => {
|
|
||||||
tab.addEventListener('click', () => {
|
|
||||||
const tabId = tab.dataset.tab;
|
|
||||||
|
|
||||||
// Update tab styles
|
|
||||||
whyTabs.forEach(t => {
|
|
||||||
if (t.dataset.tab === tabId) {
|
|
||||||
t.classList.add('bg-white', 'text-gray-900');
|
|
||||||
t.classList.remove('bg-gray-200', 'text-gray-500');
|
|
||||||
} else {
|
|
||||||
t.classList.remove('bg-white', 'text-gray-900');
|
|
||||||
t.classList.add('bg-gray-200', 'text-gray-500');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update content visibility
|
|
||||||
whyContents.forEach(c => {
|
|
||||||
if (c.dataset.content === tabId) {
|
|
||||||
c.classList.remove('hidden');
|
|
||||||
} else {
|
|
||||||
c.classList.add('hidden');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@ -1 +0,0 @@
|
|||||||
ran
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
CREATE TABLE IF NOT EXISTS `applications` (
|
|
||||||
`id` INT AUTO_INCREMENT PRIMARY KEY,
|
|
||||||
`name` VARCHAR(255) NOT NULL,
|
|
||||||
`company` VARCHAR(255) NOT NULL,
|
|
||||||
`email` VARCHAR(255) NOT NULL,
|
|
||||||
`role` VARCHAR(255) NOT NULL,
|
|
||||||
`applied_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
||||||
);
|
|
||||||
Loading…
x
Reference in New Issue
Block a user