Files
parkerslingshotrentals/contact.php
T
myron 2ecf8f04c4 Add availability calendar, admin portal, and booking backend
- db.php: shared config, PDO, SendGrid, package definitions
- availability.php: GET endpoint returning booked/blocked dates by month
- contact.php: booking handler with DB record, availability check, SendGrid emails
- admin/index.php: full admin portal (login, bookings table, status/notes AJAX, block dates)
- index.html: interactive availability calendar with click-to-select, wires to /contact.php
- .htaccess: block direct access to db.php

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 13:39:20 +00:00

115 lines
6.2 KiB
PHP

<?php
require_once __DIR__ . '/db.php';
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: https://parkerslingshotrentals.com');
header('Access-Control-Allow-Methods: POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type');
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { http_response_code(204); exit; }
if ($_SERVER['REQUEST_METHOD'] !== 'POST') { http_response_code(405); echo json_encode(['success'=>false,'error'=>'Method not allowed']); exit; }
$input = json_decode(file_get_contents('php://input'), true) ?: $_POST;
$name = trim(strip_tags($input['name'] ?? ''));
$email = trim(strip_tags($input['email'] ?? ''));
$phone = trim(strip_tags($input['phone'] ?? ''));
$package = trim(strip_tags($input['package'] ?? ''));
$date = trim(strip_tags($input['date'] ?? ''));
$message = trim(strip_tags($input['message'] ?? ''));
if (!$name || !$email || !$package || !$date) {
http_response_code(400);
echo json_encode(['success'=>false,'error'=>'Name, email, package, and date are required.']); exit;
}
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
http_response_code(400);
echo json_encode(['success'=>false,'error'=>'Invalid email address.']); exit;
}
if (!isset(PACKAGES[$package])) {
http_response_code(400);
echo json_encode(['success'=>false,'error'=>'Invalid package.']); exit;
}
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $date) || strtotime($date) < strtotime('today')) {
http_response_code(400);
echo json_encode(['success'=>false,'error'=>'Invalid or past date.']); exit;
}
$pkg = PACKAGES[$package];
$rentalDate = $date;
$endDate = date('Y-m-d', strtotime($date . ' +' . $pkg['days'] . ' days'));
// Check availability
$conflict = db()->prepare(
"SELECT id FROM bookings
WHERE status IN ('pending','confirmed')
AND rental_date <= ? AND end_date >= ?"
);
$conflict->execute([$endDate, $rentalDate]);
if ($conflict->fetch()) {
echo json_encode(['success'=>false,'error'=>'Sorry, that date is already booked. Please choose another date.']); exit;
}
$blockedCheck = db()->prepare("SELECT id FROM blocked_dates WHERE block_date BETWEEN ? AND ?");
$blockedCheck->execute([$rentalDate, $endDate]);
if ($blockedCheck->fetch()) {
echo json_encode(['success'=>false,'error'=>'That date is unavailable. Please choose another date.']); exit;
}
// Create booking
$ref = generateRef();
$stmt = db()->prepare(
"INSERT INTO bookings (booking_ref, name, email, phone, package, rental_date, end_date, amount, notes)
VALUES (?,?,?,?,?,?,?,?,?)"
);
$stmt->execute([$ref, $name, $email, $phone, $package, $rentalDate, $endDate, $pkg['amount'], $message]);
$dateLabel = date('F j, Y', strtotime($rentalDate));
$pkgLabel = $pkg['label'];
$amountLabel = '$' . number_format($pkg['amount'], 2);
// Admin email
$adminHtml = "<div style='max-width:600px;margin:0 auto;font-family:Arial,sans-serif'>
<div style='background:#f97316;padding:20px;text-align:center'>
<h1 style='color:#fff;margin:0;font-size:20px'>New Booking Request — {$ref}</h1>
</div>
<div style='padding:24px;background:#fff;border:1px solid #e5e7eb'>
<table style='width:100%;font-size:15px'>
<tr><td style='color:#6b7280;padding:8px 0;width:110px'>Ref</td><td style='padding:8px 0;font-weight:700'>{$ref}</td></tr>
<tr><td style='color:#6b7280;padding:8px 0'>Name</td><td style='padding:8px 0'>" . htmlspecialchars($name) . "</td></tr>
<tr><td style='color:#6b7280;padding:8px 0'>Email</td><td style='padding:8px 0'>" . htmlspecialchars($email) . "</td></tr>
<tr><td style='color:#6b7280;padding:8px 0'>Phone</td><td style='padding:8px 0'>" . htmlspecialchars($phone ?: '—') . "</td></tr>
<tr><td style='color:#6b7280;padding:8px 0'>Package</td><td style='padding:8px 0;font-weight:700;color:#f97316'>{$pkgLabel}{$amountLabel}</td></tr>
<tr><td style='color:#6b7280;padding:8px 0'>Date</td><td style='padding:8px 0;font-weight:700'>{$dateLabel}</td></tr>
</table>
" . ($message ? "<div style='margin-top:12px;padding:12px;background:#fff7ed;border-left:4px solid #f97316'>" . nl2br(htmlspecialchars($message)) . "</div>" : "") . "
<p style='margin-top:16px;font-size:13px;color:#9ca3af'>Submitted " . date('F j, Y g:i A') . " CT</p>
</div>
</div>";
// Customer confirmation email
$confirmHtml = "<div style='max-width:600px;margin:0 auto;font-family:Arial,sans-serif'>
<div style='background:#0d0d0d;padding:24px;text-align:center'>
<h1 style='color:#f97316;margin:0;font-size:20px'>Parker County Slingshot Rentals</h1>
</div>
<div style='padding:32px;background:#fff'>
<h2 style='margin-top:0;color:#0d0d0d'>Booking Request Received!</h2>
<p style='color:#374151'>Hey " . htmlspecialchars($name) . ", your request is in. We'll confirm availability and reach out within a few hours.</p>
<div style='background:#fff7ed;border:1px solid #fed7aa;border-radius:10px;padding:20px;margin:20px 0'>
<p style='margin:0 0 6px;font-size:13px;color:#9ca3af;text-transform:uppercase;letter-spacing:1px'>Booking Reference</p>
<p style='margin:0 0 16px;font-size:22px;font-weight:700;color:#f97316'>{$ref}</p>
<p style='margin:4px 0;font-size:14px;color:#374151'><strong>Package:</strong> {$pkgLabel}</p>
<p style='margin:4px 0;font-size:14px;color:#374151'><strong>Requested Date:</strong> {$dateLabel}</p>
<p style='margin:4px 0;font-size:14px;color:#374151'><strong>Total:</strong> {$amountLabel}</p>
</div>
<p style='color:#374151'>Questions? Call or text <strong>(817) 555-0199</strong> or reply to this email.</p>
<p style='color:#374151'>Ride on,<br><strong>The Parker County Slingshot Team</strong></p>
</div>
<div style='background:#f3f4f6;padding:16px;text-align:center'>
<p style='margin:0;font-size:12px;color:#9ca3af'>&copy; " . date('Y') . " Parker County Slingshot Rentals &mdash; Weatherford, TX</p>
</div>
</div>";
sendEmail(ADMIN_EMAIL, 'Parker Slingshot Admin', "New Booking {$ref}: {$name}{$pkgLabel} on {$dateLabel}", $adminHtml);
sendEmail($email, $name, "Booking Request {$ref} — Parker County Slingshot Rentals", $confirmHtml);
echo json_encode(['success'=>true,'ref'=>$ref,'message'=>"Booking request received! Your reference is {$ref}. We'll be in touch shortly."]);