12/28/25 V.18
This commit is contained in:
parent
7f34b50ab8
commit
f87d8bee23
106
apply.php
Normal file
106
apply.php
Normal file
@ -0,0 +1,106 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/db/config.php';
|
||||
require_once __DIR__ . '/mail/MailService.php';
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
$response = ['success' => false, 'message' => 'An unknown error occurred.'];
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
$response['message'] = 'Invalid request method.';
|
||||
echo json_encode($response);
|
||||
exit;
|
||||
}
|
||||
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
|
||||
if (empty($data)) {
|
||||
$response['message'] = 'No data received.';
|
||||
echo json_encode($response);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Sanitize and validate data
|
||||
$companyName = htmlspecialchars($data['companyName'] ?? '');
|
||||
$yourName = htmlspecialchars($data['yourName'] ?? '');
|
||||
$workEmail = filter_var($data['workEmail'] ?? '', FILTER_SANITIZE_EMAIL);
|
||||
$role = htmlspecialchars($data['role'] ?? '');
|
||||
$employees = filter_var($data['employees'] ?? '', FILTER_SANITIZE_NUMBER_INT);
|
||||
$rolesPerMonth = filter_var($data['rolesPerMonth'] ?? '', FILTER_SANITIZE_NUMBER_INT);
|
||||
$candidatesPerRole = filter_var($data['candidatesPerRole'] ?? '', FILTER_SANITIZE_NUMBER_INT);
|
||||
$ats = htmlspecialchars($data['ats'] ?? '');
|
||||
$scheduling = htmlspecialchars($data['scheduling'] ?? '');
|
||||
$painPoints = htmlspecialchars($data['painPoints'] ?? '');
|
||||
$successMetrics = htmlspecialchars($data['successMetrics'] ?? '');
|
||||
$hiringFocus = htmlspecialchars($data['hiringFocus'] ?? '');
|
||||
|
||||
if (!filter_var($workEmail, FILTER_VALIDATE_EMAIL)) {
|
||||
$response['message'] = 'Invalid email address.';
|
||||
echo json_encode($response);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (empty($companyName) || empty($yourName)) {
|
||||
$response['message'] = 'Please fill out all required fields.';
|
||||
echo json_encode($response);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Insert into database
|
||||
$pdo = db();
|
||||
$stmt = $pdo->prepare("
|
||||
INSERT INTO applications (name, company, email, role, employees, roles_per_month, candidates_per_role, ats, scheduling, pain_points, success_metrics, hiring_focus)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
");
|
||||
|
||||
try {
|
||||
$stmt->execute([
|
||||
$yourName,
|
||||
$companyName,
|
||||
$workEmail,
|
||||
$role,
|
||||
$employees,
|
||||
$rolesPerMonth,
|
||||
$candidatesPerRole,
|
||||
$ats,
|
||||
$scheduling,
|
||||
$painPoints,
|
||||
$successMetrics,
|
||||
$hiringFocus
|
||||
]);
|
||||
} catch (PDOException $e) {
|
||||
error_log('Database Error: ' . $e->getMessage());
|
||||
$response['message'] = 'There was an error saving your application. Please try again later.';
|
||||
echo json_encode($response);
|
||||
exit;
|
||||
}
|
||||
|
||||
$to = getenv('MAIL_TO') ?: 'default-recipient@example.com'; // Fallback recipient
|
||||
$subject = 'New FinMox Beta Application';
|
||||
|
||||
$htmlBody = ""
|
||||
. "<h1>New FinMox Beta Application</h1>"
|
||||
. "<p><strong>Company Name:</strong> {$companyName}</p>"
|
||||
. "<p><strong>Name:</strong> {$yourName}</p>"
|
||||
. "<p><strong>Email:</strong> {$workEmail}</p>"
|
||||
. "<p><strong>Role:</strong> {$role}</p>"
|
||||
. "<p><strong>Employees:</strong> {$employees}</p>"
|
||||
. "<p><strong>Roles Per Month:</strong> {$rolesPerMonth}</p>"
|
||||
. "<p><strong>Candidates Per Role:</strong> {$candidatesPerRole}</p>"
|
||||
. "<p><strong>ATS:</strong> {$ats}</p>"
|
||||
. "<p><strong>Scheduling:</strong> {$scheduling}</p>"
|
||||
. "<p><strong>Pain Points:</strong> {$painPoints}</p>"
|
||||
. "<p><strong>Success Metrics:</strong> {$successMetrics}</p>"
|
||||
. "<p><strong>Hiring Focus:</strong> {$hiringFocus}</p>";
|
||||
|
||||
$res = MailService::sendMail($to, $subject, $htmlBody);
|
||||
|
||||
if (!empty($res['success'])) {
|
||||
$response['success'] = true;
|
||||
$response['message'] = 'Application submitted successfully!';
|
||||
} else {
|
||||
error_log('MailService Error: ' . ($res['error'] ?? 'Unknown error'));
|
||||
$response['message'] = 'There was an error submitting your application. Please try again later.';
|
||||
}
|
||||
|
||||
echo json_encode($response);
|
||||
@ -118,4 +118,116 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const applyNowBtn = document.getElementById('applyNowBtn');
|
||||
if (applyNowBtn) {
|
||||
applyNowBtn.addEventListener('click', applyForBeta);
|
||||
}
|
||||
});
|
||||
|
||||
function signIn(event) {
|
||||
event.preventDefault();
|
||||
const emailEl = document.getElementById('signinEmail');
|
||||
const passwordEl = document.getElementById('signinPassword');
|
||||
const msgEl = document.getElementById('signinMsg');
|
||||
|
||||
if (!emailEl || !passwordEl || !msgEl) {
|
||||
return;
|
||||
}
|
||||
|
||||
const email = emailEl.value.trim();
|
||||
const password = passwordEl.value.trim();
|
||||
|
||||
msgEl.classList.add('hidden');
|
||||
msgEl.textContent = '';
|
||||
|
||||
if (!email || !password) {
|
||||
msgEl.textContent = 'Please enter both email and password.';
|
||||
msgEl.classList.remove('hidden');
|
||||
return;
|
||||
}
|
||||
|
||||
fetch('login.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
credentials: 'same-origin',
|
||||
body: JSON.stringify({ email, password }),
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
window.location.href = 'dashboard.php';
|
||||
} else {
|
||||
msgEl.textContent = data.message || 'An unknown error occurred.';
|
||||
msgEl.classList.remove('hidden');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
msgEl.textContent = 'A network error occurred. Please try again.';
|
||||
msgEl.classList.remove('hidden');
|
||||
});
|
||||
}
|
||||
|
||||
function applyForBeta(event) {
|
||||
event.preventDefault();
|
||||
|
||||
const form = document.getElementById('applyForm');
|
||||
const msgEl = document.getElementById('applyMsg');
|
||||
|
||||
if (!form || !msgEl) {
|
||||
return;
|
||||
}
|
||||
|
||||
const data = {
|
||||
companyName: document.getElementById('companyName').value,
|
||||
yourName: document.getElementById('yourName').value,
|
||||
workEmail: document.getElementById('workEmail').value,
|
||||
role: document.getElementById('role').value,
|
||||
employees: document.getElementById('employees').value,
|
||||
rolesPerMonth: document.getElementById('rolesPerMonth').value,
|
||||
candidatesPerRole: document.getElementById('candidatesPerRole').value,
|
||||
ats: document.getElementById('ats').value,
|
||||
scheduling: document.getElementById('scheduling').value,
|
||||
painPoints: document.getElementById('painPoints').value,
|
||||
successMetrics: document.getElementById('successMetrics').value,
|
||||
hiringFocus: document.getElementById('hiringFocus').value,
|
||||
};
|
||||
|
||||
msgEl.classList.add('hidden');
|
||||
msgEl.textContent = '';
|
||||
|
||||
// Basic validation
|
||||
if (!data.workEmail || !data.companyName || !data.yourName) {
|
||||
msgEl.textContent = 'Please fill out all required fields.';
|
||||
msgEl.classList.remove('hidden');
|
||||
return;
|
||||
}
|
||||
|
||||
fetch('apply.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
credentials: 'same-origin',
|
||||
body: JSON.stringify(data),
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(result => {
|
||||
if (result.success) {
|
||||
msgEl.textContent = 'Thank you for your application! We will be in touch shortly.';
|
||||
msgEl.classList.remove('hidden');
|
||||
msgEl.classList.remove('text-red-600');
|
||||
msgEl.classList.add('text-green-600');
|
||||
form.reset();
|
||||
} else {
|
||||
msgEl.textContent = result.message || 'An unknown error occurred.';
|
||||
msgEl.classList.remove('hidden');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
msgEl.textContent = 'A network error occurred. Please try again.';
|
||||
msgEl.classList.remove('hidden');
|
||||
});
|
||||
}
|
||||
BIN
assets/pasted-20251228-074747-5baef672.png
Normal file
BIN
assets/pasted-20251228-074747-5baef672.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.0 MiB |
7
check_auth.php
Normal file
7
check_auth.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
if (!isset($_SESSION['user'])) {
|
||||
header('Location: index.php#signin');
|
||||
exit();
|
||||
}
|
||||
2
dashboard.php
Normal file
2
dashboard.php
Normal file
File diff suppressed because one or more lines are too long
31
db/migrate.php
Normal file
31
db/migrate.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/config.php';
|
||||
|
||||
function run_migrations() {
|
||||
$pdo = db();
|
||||
$pdo->exec("CREATE TABLE IF NOT EXISTS `migrations` ( `id` INT AUTO_INCREMENT PRIMARY KEY, `migration` VARCHAR(255) NOT NULL, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP );");
|
||||
|
||||
$ran_migrations = $pdo->query("SELECT migration FROM migrations")->fetchAll(PDO::FETCH_COLUMN);
|
||||
|
||||
$migration_files = glob(__DIR__ . '/migrations/*.sql');
|
||||
sort($migration_files);
|
||||
|
||||
foreach ($migration_files as $file) {
|
||||
$migration_name = basename($file);
|
||||
|
||||
if (!in_array($migration_name, $ran_migrations)) {
|
||||
$sql = file_get_contents($file);
|
||||
$pdo->exec($sql);
|
||||
|
||||
$stmt = $pdo->prepare("INSERT INTO migrations (migration) VALUES (?)");
|
||||
$stmt->execute([$migration_name]);
|
||||
|
||||
echo "Migration run: " . $migration_name . "\n";
|
||||
} else {
|
||||
echo "Migration already run: " . $migration_name . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
run_migrations();
|
||||
|
||||
5
db/migrations/00_create_migrations_table.sql
Normal file
5
db/migrations/00_create_migrations_table.sql
Normal file
@ -0,0 +1,5 @@
|
||||
CREATE TABLE IF NOT EXISTS `migrations` (
|
||||
`id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||
`migration` VARCHAR(255) NOT NULL,
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
9
db/migrations/02_alter_applications_table.sql
Normal file
9
db/migrations/02_alter_applications_table.sql
Normal file
@ -0,0 +1,9 @@
|
||||
ALTER TABLE `applications`
|
||||
ADD COLUMN `employees` INT NULL,
|
||||
ADD COLUMN `roles_per_month` INT NULL,
|
||||
ADD COLUMN `candidates_per_role` INT NULL,
|
||||
ADD COLUMN `ats` VARCHAR(255) NULL,
|
||||
ADD COLUMN `scheduling` VARCHAR(255) NULL,
|
||||
ADD COLUMN `pain_points` TEXT NULL,
|
||||
ADD COLUMN `success_metrics` TEXT NULL,
|
||||
ADD COLUMN `hiring_focus` VARCHAR(255) NULL;
|
||||
39
index.php
39
index.php
@ -1,3 +1,4 @@
|
||||
<?php session_start(); ?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
@ -635,7 +636,14 @@
|
||||
<section class="max-w-7xl mx-auto px-6 py-24 text-center"> <h2 class="text-3xl font-semibold mb-4"> Still have questions? </h2> <p class="text-gray-600 mb-8"> We’d rather answer them directly than hide behind marketing. </p> <div class="flex justify-center gap-4"> <a href="/apply.php" class="bg-black text-white px-8 py-4 rounded-xl"> Apply for access </a> <a href="/trust.php" class="border px-8 py-4 rounded-xl"> Security & Trust → </a> </div> </section>
|
||||
</section>
|
||||
|
||||
<!-- SIGNIN PAGE (PART 1/2) --> <section id="page-signin" class="page fade hidden"> <section class="panel-strong p-8 lg:p-10"> <div class="grid lg:grid-cols-12 gap-10 items-start"> <!-- Left: Trust / context --> <div class="lg:col-span-5"> <div class="chip inline-flex px-3 py-1 text-xs">Account</div> <h1 class="mt-5 text-4xl font-extrabold tracking-tight"> Sign in to FinMox </h1> <p class="mt-5 text-gray-700"> Access your workspace to review hiring execution, decision trails, and audit-ready outputs. </p> <div class="mt-7 panel p-6"> <div class="text-sm font-semibold">What you can do inside</div> <ul class="mt-3 text-sm text-gray-700 space-y-2"> <li>✔ Review ranked candidates + structured scoring</li> <li>✔ See interview summaries + recommendations</li> <li>✔ Track movement + SLA nudges</li> <li>✔ Export decision logs for audits</li> </ul> <div class="mt-4 flex flex-wrap gap-2"> <span class="chip px-3 py-1 text-xs">Role-based access</span> <span class="chip px-3 py-1 text-xs">Least privilege</span> <span class="chip px-3 py-1 text-xs">Audit trail</span> </div> </div> <div class="mt-7 panel p-6"> <div class="text-sm font-semibold">Need access?</div> <p class="mt-2 text-sm text-gray-700"> FinMox is onboarding teams through private beta. Apply and we’ll confirm fit. </p> <div class="mt-4 flex flex-wrap gap-3"> <a href="#apply" onclick="openPage('apply'); return false;" class="bg-black text-white px-6 py-3 rounded-2xl text-sm hoverlift"> Apply for Access </a> <a href="#trust" onclick="openPage('trust'); return false;" class="chip px-6 py-3 rounded-2xl text-sm hoverlift"> Security & Trust → </a> </div> </div> </div><!-- SIGNIN PAGE (PART 2/2) --> <!-- Right: Sign in card --> <div class="lg:col-span-7"> <div class="panel p-7"> <div class="flex items-center justify-between gap-4"> <div> <div class="text-sm font-semibold">Welcome back</div> <div class="text-sm text-gray-600 mt-1">Sign in to continue.</div> </div> <span class="chip px-3 py-1 text-xs">Private beta</span> </div> <form class="mt-6 grid gap-3" onsubmit="return false;"> <div class="grid md:grid-cols-2 gap-3"> <input type="email" placeholder="Work email" class="panel-strong px-4 py-3 rounded-2xl" autocomplete="email" /> <input type="password" placeholder="Password" class="panel-strong px-4 py-3 rounded-2xl" autocomplete="current-password" /> </div> <div class="flex items-center justify-between gap-4 text-sm"> <label class="flex items-center gap-2 text-gray-700"> <input type="checkbox" class="accent-black" /> Remember me </label> <a href="#forgot" onclick="openPage('forgot'); return false;" class="underline text-sm text-gray-700"> Forgot access? </a> </div> <button type="button" class="bg-black text-white py-3 rounded-2xl hoverlift" > Sign In </button> <div class="text-xs text-gray-600"> Demo placeholder. Wire this to your auth later (AppWizzy auth, Supabase, Clerk, etc.). </div> </form> <div class="mt-6 grid md:grid-cols-3 gap-3"> <div class="panel-strong p-5"> <div class="text-xs text-gray-500">Access control</div> <div class="mt-2 text-sm text-gray-700">Role-based permissions supported.</div> </div> <div class="panel-strong p-5"> <div class="text-xs text-gray-500">Session security</div> <div class="mt-2 text-sm text-gray-700">Least-privilege by default.</div> </div> <div class="panel-strong p-5"> <div class="text-xs text-gray-500">Auditability</div> <div class="mt-2 text-sm text-gray-700">Actions map to decision trail.</div> </div> </div> <div class="mt-6 panel-strong p-6"> <div class="text-sm font-semibold">New here?</div> <div class="mt-2 text-sm text-gray-700"> Apply for beta access and we’ll onboard your team with a short process.</div></div></div></div></section></section>
|
||||
<!-- SIGNIN PAGE (PART 1/2) --> <section id="page-signin" class="page fade hidden"> <section class="panel-strong p-8 lg:p-10"> <div class="grid lg:grid-cols-12 gap-10 items-start"> <!-- Left: Trust / context --> <div class="lg:col-span-5"> <div class="chip inline-flex px-3 py-1 text-xs">Account</div> <h1 class="mt-5 text-4xl font-extrabold tracking-tight"> Sign in to FinMox </h1> <p class="mt-5 text-gray-700"> Access your workspace to review hiring execution, decision trails, and audit-ready outputs. </p> <div class="mt-7 panel p-6"> <div class="text-sm font-semibold">What you can do inside</div> <ul class="mt-3 text-sm text-gray-700 space-y-2"> <li>✔ Review ranked candidates + structured scoring</li> <li>✔ See interview summaries + recommendations</li> <li>✔ Track movement + SLA nudges</li> <li>✔ Export decision logs for audits</li> </ul> <div class="mt-4 flex flex-wrap gap-2"> <span class="chip px-3 py-1 text-xs">Role-based access</span> <span class="chip px-3 py-1 text-xs">Least privilege</span> <span class="chip px-3 py-1 text-xs">Audit trail</span> </div> </div> <div class="mt-7 panel p-6"> <div class="text-sm font-semibold">Need access?</div> <p class="mt-2 text-sm text-gray-700"> FinMox is onboarding teams through private beta. Apply and we’ll confirm fit. </p> <div class="mt-4 flex flex-wrap gap-3"> <a href="#apply" onclick="openPage('apply'); return false;" class="bg-black text-white px-6 py-3 rounded-2xl text-sm hoverlift"> Apply for Access </a> <a href="#trust" onclick="openPage('trust'); return false;" class="chip px-6 py-3 rounded-2xl text-sm hoverlift"> Security & Trust → </a> </div> </div> </div><!-- SIGNIN PAGE (PART 2/2) --> <!-- Right: Sign in card --> <div class="lg:col-span-7"> <div class="panel p-7"> <div class="flex items-center justify-between gap-4"> <div> <div class="text-sm font-semibold">Welcome back</div> <div class="text-sm text-gray-600 mt-1">Sign in to continue.</div> </div> <span class="chip px-3 py-1 text-xs">Private beta</span> </div> <form class="mt-6 grid gap-3">
|
||||
<input type="email" id="signinEmail" placeholder="Work email" class="panel-strong px-4 py-3 rounded-2xl" />
|
||||
<input type="password" id="signinPassword" placeholder="Password" class="panel-strong px-4 py-3 rounded-2xl" />
|
||||
<button type="button" onclick="signIn(event)" class="bg-black text-white py-3 rounded-2xl hoverlift">
|
||||
Sign in
|
||||
</button>
|
||||
<div id="signinMsg" class="hidden text-sm text-red-600"></div>
|
||||
</form> <div class="mt-6 grid md:grid-cols-3 gap-3"> <div class="panel-strong p-5"> <div class="text-xs text-gray-500">Access control</div> <div class="mt-2 text-sm text-gray-700">Role-based permissions supported.</div> </div> <div class="panel-strong p-5"> <div class="text-xs text-gray-500">Session security</div> <div class="mt-2 text-sm text-gray-700">Least-privilege by default.</div> </div> <div class="panel-strong p-5"> <div class="text-xs text-gray-500">Auditability</div> <div class="mt-2 text-sm text-gray-700">Actions map to decision trail.</div> </div> </div> <div class="mt-6 panel-strong p-6"> <div class="text-sm font-semibold">New here?</div> <div class="mt-2 text-sm text-gray-700"> Apply for beta access and we’ll onboard your team with a short process.</div></div></div></div></section></section>
|
||||
|
||||
<!-- APPLY PAGE (PART 1/3) -->
|
||||
<section id="page-apply" class="page fade hidden">
|
||||
@ -692,35 +700,36 @@
|
||||
</div>
|
||||
<span class="chip px-3 py-1 text-xs">Pilot-first</span>
|
||||
</div>
|
||||
<form class="mt-6 grid gap-3" onsubmit="return false;">
|
||||
<form id="applyForm" class="mt-6 grid gap-3" onsubmit="return false;">
|
||||
<div class="grid md:grid-cols-2 gap-3">
|
||||
<input type="text" placeholder="Company name" class="panel-strong px-4 py-3 rounded-2xl" />
|
||||
<input type="text" placeholder="Your name" class="panel-strong px-4 py-3 rounded-2xl" />
|
||||
<input id="companyName" type="text" placeholder="Company name" class="panel-strong px-4 py-3 rounded-2xl" />
|
||||
<input id="yourName" type="text" placeholder="Your name" class="panel-strong px-4 py-3 rounded-2xl" />
|
||||
</div>
|
||||
<div class="grid md:grid-cols-2 gap-3">
|
||||
<input type="email" placeholder="Work email" class="panel-strong px-4 py-3 rounded-2xl" />
|
||||
<input type="text" placeholder="Role / title" class="panel-strong px-4 py-3 rounded-2xl" />
|
||||
<input id="workEmail" type="email" placeholder="Work email" class="panel-strong px-4 py-3 rounded-2xl" />
|
||||
<input id="role" type="text" placeholder="Role / title" class="panel-strong px-4 py-3 rounded-2xl" />
|
||||
</div>
|
||||
<div class="grid md:grid-cols-3 gap-3">
|
||||
<input type="number" placeholder="Employees" class="panel-strong px-4 py-3 rounded-2xl" />
|
||||
<input type="number" placeholder="Roles per month" class="panel-strong px-4 py-3 rounded-2xl" />
|
||||
<input type="number" placeholder="Candidates per role" class="panel-strong px-4 py-3 rounded-2xl" />
|
||||
<input id="employees" type="number" placeholder="Employees" class="panel-strong px-4 py-3 rounded-2xl" />
|
||||
<input id="rolesPerMonth" type="number" placeholder="Roles per month" class="panel-strong px-4 py-3 rounded-2xl" />
|
||||
<input id="candidatesPerRole" type="number" placeholder="Candidates per role" class="panel-strong px-4 py-3 rounded-2xl" />
|
||||
</div>
|
||||
<div class="grid md:grid-cols-2 gap-3">
|
||||
<input type="text" placeholder="ATS (Greenhouse, Lever, etc.)" class="panel-strong px-4 py-3 rounded-2xl" />
|
||||
<input type="text" placeholder="Scheduling (Calendly, Google, etc.)" class="panel-strong px-4 py-3 rounded-2xl" />
|
||||
<input id="ats" type="text" placeholder="ATS (Greenhouse, Lever, etc.)" class="panel-strong px-4 py-3 rounded-2xl" />
|
||||
<input id="scheduling" type="text" placeholder="Scheduling (Calendly, Google, etc.)" class="panel-strong px-4 py-3 rounded-2xl" />
|
||||
</div>
|
||||
<textarea rows="4" placeholder="Where does hiring execution break today? (drift, delays, inconsistency, documentation)" class="panel-strong px-4 py-3 rounded-2xl"></textarea>
|
||||
<textarea rows="3" placeholder="What does success look like in 30 days? (faster decisions, less chasing, audit trail, etc.)" class="panel-strong px-4 py-3 rounded-2xl"></textarea>
|
||||
<textarea id="painPoints" rows="4" placeholder="Where does hiring execution break today? (drift, delays, inconsistency, documentation)" class="panel-strong px-4 py-3 rounded-2xl"></textarea>
|
||||
<textarea id="successMetrics" rows="3" placeholder="What does success look like in 30 days? (faster decisions, less chasing, audit trail, etc.)" class="panel-strong px-4 py-3 rounded-2xl"></textarea>
|
||||
<div id="applyMsg" class="hidden text-sm text-red-600"></div>
|
||||
<div class="grid md:grid-cols-2 gap-3">
|
||||
<select class="panel-strong px-4 py-3 rounded-2xl">
|
||||
<select id="hiringFocus" class="panel-strong px-4 py-3 rounded-2xl">
|
||||
<option>Primary hiring focus</option>
|
||||
<option>Engineering</option>
|
||||
<option>Sales</option>
|
||||
<option>Marketing</option>
|
||||
<option>Other</option>
|
||||
</select>
|
||||
<button type="button" class="bg-black text-white py-3 rounded-2xl hoverlift" > Apply Now </button>
|
||||
<button type="button" id="applyNowBtn" class="bg-black text-white py-3 rounded-2xl hoverlift" > Apply Now </button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
29
login.php
Normal file
29
login.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
// Hardcoded credentials for demonstration.
|
||||
// In a real application, you should fetch user from a database and verify the password hash.
|
||||
$valid_email = 'test@example.com';
|
||||
$valid_password = 'password';
|
||||
|
||||
$response = ['success' => false, 'message' => ''];
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
$email = $data['email'] ?? null;
|
||||
$password = $data['password'] ?? null;
|
||||
|
||||
if (empty($email) || empty($password)) {
|
||||
$response['message'] = 'Please enter both email and password.';
|
||||
} elseif ($email === $valid_email && $password === $valid_password) {
|
||||
$_SESSION['user'] = ['email' => $email];
|
||||
$response['success'] = true;
|
||||
} else {
|
||||
$response['message'] = 'Invalid credentials.';
|
||||
}
|
||||
} else {
|
||||
$response['message'] = 'Invalid request method.';
|
||||
}
|
||||
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode($response);
|
||||
Loading…
x
Reference in New Issue
Block a user