mirror of
https://github.com/myronblair/tomsjavajive
synced 2026-06-30 09:40:24 -05:00
Google Merchant Center trust signal improvements
- Add contact.php (was 404, linked from footer and returns page) - Add shippingDetails and hasMerchantReturnPolicy to product schema - Add priceValidUntil to product Offer schema - Improve merchant feed descriptions (use DB description when present) - Add handling/transit times and return_policy_label to feed Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+169
@@ -0,0 +1,169 @@
|
||||
<?php
|
||||
$pageTitle = "Contact Us - Tom's Java Jive";
|
||||
$metaDescription = "Get in touch with Tom's Java Jive. We're here to help with orders, questions, and anything coffee-related.";
|
||||
$canonicalUrl = 'https://tomsjavajive.com/contact.php';
|
||||
$breadcrumbs = [
|
||||
['name' => 'Home', 'url' => 'https://tomsjavajive.com'],
|
||||
['name' => 'Contact', 'url' => 'https://tomsjavajive.com/contact.php']
|
||||
];
|
||||
require_once __DIR__ . '/includes/functions.php';
|
||||
|
||||
$sent = false;
|
||||
$errors = [];
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$name = trim($_POST['name'] ?? '');
|
||||
$email = trim($_POST['email'] ?? '');
|
||||
$subject = trim($_POST['subject'] ?? '');
|
||||
$message = trim($_POST['message'] ?? '');
|
||||
|
||||
if (empty($name)) $errors['name'] = 'Name is required.';
|
||||
if (empty($email) || !filter_var($email, FILTER_VALIDATE_EMAIL))
|
||||
$errors['email'] = 'A valid email address is required.';
|
||||
if (empty($subject)) $errors['subject'] = 'Please choose a subject.';
|
||||
if (empty($message)) $errors['message'] = 'Message cannot be empty.';
|
||||
|
||||
if (empty($errors)) {
|
||||
$body = "Name: {$name}\nEmail: {$email}\nSubject: {$subject}\n\n{$message}";
|
||||
cybermailSend('hello@tomsjavajive.com', "Contact Form: {$subject}", $body, $name, $email);
|
||||
$sent = true;
|
||||
}
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/includes/header.php';
|
||||
?>
|
||||
|
||||
<section class="section" style="padding-top: 2rem; padding-bottom: 4rem;">
|
||||
<div class="container" style="max-width: 900px;">
|
||||
|
||||
<div style="text-align: center; margin-bottom: 3rem;">
|
||||
<h1 style="font-size: 2.5rem; margin-bottom: 0.75rem;">Contact Us</h1>
|
||||
<p class="text-muted" style="font-size: 1.1rem;">Questions about your order or just want to talk coffee? We'd love to hear from you.</p>
|
||||
</div>
|
||||
|
||||
<div style="display: grid; grid-template-columns: 1fr 1.6fr; gap: 2.5rem; align-items: start;">
|
||||
|
||||
<!-- Contact Info -->
|
||||
<div>
|
||||
<div class="card" style="margin-bottom: 1.5rem;">
|
||||
<div class="card-body">
|
||||
<h3 style="margin-bottom: 1.25rem; font-size: 1.1rem;">Get in Touch</h3>
|
||||
|
||||
<div style="display: flex; align-items: flex-start; gap: 0.85rem; margin-bottom: 1.25rem;">
|
||||
<div style="width: 38px; height: 38px; background: rgba(255,94,26,0.1); border-radius: 50%; display: flex; align-items: center; justify-content: center; flex-shrink: 0; color: var(--color-primary);">
|
||||
<i class="fas fa-envelope"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div style="font-weight: 600; margin-bottom: 0.2rem;">Email</div>
|
||||
<a href="mailto:hello@tomsjavajive.com">hello@tomsjavajive.com</a>
|
||||
<div class="text-muted" style="font-size: 0.85rem; margin-top: 0.15rem;">We reply within 1 business day</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display: flex; align-items: flex-start; gap: 0.85rem; margin-bottom: 1.25rem;">
|
||||
<div style="width: 38px; height: 38px; background: rgba(255,94,26,0.1); border-radius: 50%; display: flex; align-items: center; justify-content: center; flex-shrink: 0; color: var(--color-primary);">
|
||||
<i class="fas fa-phone"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div style="font-weight: 600; margin-bottom: 0.2rem;">Phone</div>
|
||||
<a href="tel:+18175550120">(817) 555-0120</a>
|
||||
<div class="text-muted" style="font-size: 0.85rem; margin-top: 0.15rem;">Mon–Fri, 9am–5pm CT</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display: flex; align-items: flex-start; gap: 0.85rem;">
|
||||
<div style="width: 38px; height: 38px; background: rgba(255,94,26,0.1); border-radius: 50%; display: flex; align-items: center; justify-content: center; flex-shrink: 0; color: var(--color-primary);">
|
||||
<i class="fas fa-map-marker-alt"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div style="font-weight: 600; margin-bottom: 0.2rem;">Location</div>
|
||||
<div>Weatherford, TX 76086</div>
|
||||
<div class="text-muted" style="font-size: 0.85rem; margin-top: 0.15rem;">United States</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h3 style="margin-bottom: 0.75rem; font-size: 1rem;">Quick Links</h3>
|
||||
<ul class="footer-links" style="list-style: none; padding: 0; margin: 0;">
|
||||
<li style="margin-bottom: 0.4rem;"><a href="/track-order.php"><i class="fas fa-search" style="width: 16px;"></i> Track Your Order</a></li>
|
||||
<li style="margin-bottom: 0.4rem;"><a href="/returns.php"><i class="fas fa-undo" style="width: 16px;"></i> Returns & Refunds</a></li>
|
||||
<li style="margin-bottom: 0.4rem;"><a href="/shipping.php"><i class="fas fa-truck" style="width: 16px;"></i> Shipping Info</a></li>
|
||||
<li><a href="/faq.php"><i class="fas fa-question-circle" style="width: 16px;"></i> FAQ</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Contact Form -->
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<?php if ($sent): ?>
|
||||
<div style="text-align: center; padding: 2rem 0;">
|
||||
<div style="font-size: 3rem; margin-bottom: 1rem;">☕</div>
|
||||
<h3 style="margin-bottom: 0.5rem;">Message Sent!</h3>
|
||||
<p class="text-muted">Thanks for reaching out. We'll get back to you within one business day.</p>
|
||||
<a href="/shop.php" class="btn btn-primary mt-2">Browse Our Coffee</a>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<h3 style="margin-bottom: 1.5rem; font-size: 1.1rem;">Send a Message</h3>
|
||||
<form method="POST" action="">
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem;">
|
||||
<div class="form-group">
|
||||
<label class="form-label">Your Name *</label>
|
||||
<input type="text" name="name" class="form-input <?= isset($errors['name']) ? 'is-invalid' : '' ?>"
|
||||
value="<?= htmlspecialchars($_POST['name'] ?? '') ?>" required>
|
||||
<?php if (isset($errors['name'])): ?>
|
||||
<span class="form-error"><?= $errors['name'] ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Email Address *</label>
|
||||
<input type="email" name="email" class="form-input <?= isset($errors['email']) ? 'is-invalid' : '' ?>"
|
||||
value="<?= htmlspecialchars($_POST['email'] ?? '') ?>" required>
|
||||
<?php if (isset($errors['email'])): ?>
|
||||
<span class="form-error"><?= $errors['email'] ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label">Subject *</label>
|
||||
<select name="subject" class="form-input <?= isset($errors['subject']) ? 'is-invalid' : '' ?>" required>
|
||||
<option value="">— Select a subject —</option>
|
||||
<option value="Order Question" <?= ($_POST['subject'] ?? '') === 'Order Question' ? 'selected' : '' ?>>Order Question</option>
|
||||
<option value="Shipping & Delivery" <?= ($_POST['subject'] ?? '') === 'Shipping & Delivery' ? 'selected' : '' ?>>Shipping & Delivery</option>
|
||||
<option value="Returns & Refunds" <?= ($_POST['subject'] ?? '') === 'Returns & Refunds' ? 'selected' : '' ?>>Returns & Refunds</option>
|
||||
<option value="Product Question" <?= ($_POST['subject'] ?? '') === 'Product Question' ? 'selected' : '' ?>>Product Question</option>
|
||||
<option value="Wholesale Inquiry" <?= ($_POST['subject'] ?? '') === 'Wholesale Inquiry' ? 'selected' : '' ?>>Wholesale Inquiry</option>
|
||||
<option value="Other" <?= ($_POST['subject'] ?? '') === 'Other' ? 'selected' : '' ?>>Other</option>
|
||||
</select>
|
||||
<?php if (isset($errors['subject'])): ?>
|
||||
<span class="form-error"><?= $errors['subject'] ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label">Message *</label>
|
||||
<textarea name="message" class="form-textarea <?= isset($errors['message']) ? 'is-invalid' : '' ?>"
|
||||
rows="5" placeholder="How can we help?" required><?= htmlspecialchars($_POST['message'] ?? '') ?></textarea>
|
||||
<?php if (isset($errors['message'])): ?>
|
||||
<span class="form-error"><?= $errors['message'] ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="fas fa-paper-plane"></i> Send Message
|
||||
</button>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|
||||
+21
-5
@@ -31,12 +31,22 @@ foreach ($products as $p) {
|
||||
$imageUrl = !empty($images) ? $base . $images[0] : $base . '/assets/images/placeholder-product.svg';
|
||||
|
||||
$categoryLabel = $p['category'] === 'Bean' ? 'Whole Bean' : 'Ground';
|
||||
$grindNote = $p['category'] === 'Bean'
|
||||
? 'Available as whole bean so you can grind fresh for maximum flavor.'
|
||||
: 'Pre-ground to a versatile medium grind, ready to brew right out of the bag.';
|
||||
$title = htmlspecialchars($p['name'] . ' ' . $categoryLabel . ' Coffee');
|
||||
$desc = htmlspecialchars(
|
||||
$p['name'] . ' flavored artisan coffee — ' . strtolower($categoryLabel) . '. ' .
|
||||
'All natural flavoring. ' .
|
||||
'12 oz bag.'
|
||||
);
|
||||
$rawDesc = $p['description'] ?? '';
|
||||
if (!empty($rawDesc)) {
|
||||
$desc = htmlspecialchars(
|
||||
strip_tags($rawDesc) . ' ' . $grindNote . ' 12 oz bag. Ships from Weatherford, TX.'
|
||||
);
|
||||
} else {
|
||||
$desc = htmlspecialchars(
|
||||
"Tom's Java Jive {$p['name']} flavored artisan coffee, freshly roasted in small batches in Weatherford, Texas. " .
|
||||
"All-natural flavoring with no artificial additives. {$grindNote} " .
|
||||
"12 oz bag. Free shipping on orders over \$50."
|
||||
);
|
||||
}
|
||||
$link = htmlspecialchars($base . '/product.php?id=' . $p['product_id']);
|
||||
$imageLink = htmlspecialchars($imageUrl);
|
||||
$price = number_format((float)($p['sale_price'] ?? $p['price']), 2, '.', '');
|
||||
@@ -66,11 +76,17 @@ foreach ($products as $p) {
|
||||
echo " <g:google_product_category>{$gCategory}</g:google_product_category>\n";
|
||||
echo " <g:product_type>Coffee > Flavored Coffee > {$categoryLabel}</g:product_type>\n";
|
||||
echo " <g:identifier_exists>false</g:identifier_exists>\n";
|
||||
echo " <g:custom_label_0>{$categoryLabel}</g:custom_label_0>\n";
|
||||
echo " <g:shipping>\n";
|
||||
echo " <g:country>US</g:country>\n";
|
||||
echo " <g:service>Standard</g:service>\n";
|
||||
echo " <g:price>5.99 USD</g:price>\n";
|
||||
echo " <g:min_handling_time>1</g:min_handling_time>\n";
|
||||
echo " <g:max_handling_time>2</g:max_handling_time>\n";
|
||||
echo " <g:min_transit_time>3</g:min_transit_time>\n";
|
||||
echo " <g:max_transit_time>7</g:max_transit_time>\n";
|
||||
echo " </g:shipping>\n";
|
||||
echo " <g:return_policy_label>default</g:return_policy_label>\n";
|
||||
echo " </item>\n";
|
||||
}
|
||||
|
||||
|
||||
+26
-6
@@ -69,12 +69,32 @@ $productSchemaData = [
|
||||
'description' => $metaDescription,
|
||||
'brand' => ['@type' => 'Brand', 'name' => "Tom's Java Jive"],
|
||||
'offers' => [
|
||||
'@type' => 'Offer',
|
||||
'priceCurrency' => 'USD',
|
||||
'price' => number_format((float) $displayPrice, 2, '.', ''),
|
||||
'availability' => $inStock ? 'https://schema.org/InStock' : 'https://schema.org/OutOfStock',
|
||||
'url' => $canonicalUrl,
|
||||
'seller' => ['@type' => 'Organization', 'name' => "Tom's Java Jive"],
|
||||
'@type' => 'Offer',
|
||||
'priceCurrency' => 'USD',
|
||||
'price' => number_format((float) $displayPrice, 2, '.', ''),
|
||||
'priceValidUntil' => date('Y-12-31', strtotime('+1 year')),
|
||||
'availability' => $inStock ? 'https://schema.org/InStock' : 'https://schema.org/OutOfStock',
|
||||
'url' => $canonicalUrl,
|
||||
'seller' => ['@type' => 'Organization', 'name' => "Tom's Java Jive"],
|
||||
'shippingDetails' => [
|
||||
'@type' => 'OfferShippingDetails',
|
||||
'shippingRate' => ['@type' => 'MonetaryAmount', 'value' => '5.99', 'currency' => 'USD'],
|
||||
'shippingDestination'=> ['@type' => 'DefinedRegion', 'addressCountry' => 'US'],
|
||||
'deliveryTime' => [
|
||||
'@type' => 'ShippingDeliveryTime',
|
||||
'handlingTime' => ['@type' => 'QuantitativeValue', 'minValue' => 1, 'maxValue' => 2, 'unitCode' => 'DAY'],
|
||||
'transitTime' => ['@type' => 'QuantitativeValue', 'minValue' => 3, 'maxValue' => 7, 'unitCode' => 'DAY'],
|
||||
],
|
||||
],
|
||||
'hasMerchantReturnPolicy' => [
|
||||
'@type' => 'MerchantReturnPolicy',
|
||||
'applicableCountry' => 'US',
|
||||
'returnPolicyCategory' => 'https://schema.org/MerchantReturnFiniteReturnWindow',
|
||||
'merchantReturnDays' => 30,
|
||||
'returnMethod' => 'https://schema.org/ReturnByMail',
|
||||
'returnFees' => 'https://schema.org/FreeReturn',
|
||||
'returnPolicyLink' => 'https://tomsjavajive.com/returns.php',
|
||||
],
|
||||
],
|
||||
];
|
||||
if ($reviewCount > 0) {
|
||||
|
||||
Reference in New Issue
Block a user