Files
route-commerce/src/app/tuxedo/faq/layout.tsx
T
Nora c71354d2ae
Deploy to route.crispygoat.com / deploy (push) Successful in 4m25s
tuxedo: align storefront subpages with Field Almanac editorial voice
Reskin /tuxedo/contact, /tuxedo/faq, /tuxedo/stops, and
/tuxedo/stops/[id] so they match the homepage's editorial
magazine language (Fraunces display serif, stone-50/stone-950
alternation, amber rims, hairline rules, tabular numerals).

- About page rewritten as inlined editorial sections sharing
  one WP_IMAGES library with the homepage; the four lazy-loaded
  Tuxedo about components are removed (Indian River has its own
  variants).
- Contact page now uses a dark hero with heroField half-bleed,
  a hairline-ruled info strip (address/phone/email), a two-column
  form section with bottom-border editorial inputs, and a closing
  Fraunces italic quote. /tuxedo/contact was 404ing in prod because
  page.tsx was missing — created and removed the duplicated render
  from layout.tsx.
- FAQ page uses a cream hero with Fraunces headline, an editorial
  bottom-border search, hairline-ruled accordion rows (no card
  wrappers), and a dark closing CTA with Contact pill.
- Stops list uses a dark hero with heroField bleed and a cream
  hairline-ruled sidebar list: tabular date numerals on the left,
  city/location middle, mono time + cutoff right, chevron for
  upcoming rows.
- Stop detail uses a dark hero pairing the city/state headline
  with a giant tabular day stamp, a cream hairline-ruled 4-col
  info strip (Date/Time/Location/Order by), and the editorial
  products header. Removed the dual-brand isBlue branching now
  that Indian River has its own page.
- Extracted TUXEDO_IMAGES to src/components/storefront/tuxedo-images.ts
  so the homepage, about, contact, and stops list share one
  brand-specific asset library.
- /tuxedo/faq/layout.tsx no longer double-renders the page
  component (was rendering <FAQClientPage /> alongside children).

Verified: tsc --noEmit clean, eslint clean (only pre-existing
homepage warnings), npm run build produces all Tuxedo routes
including the now-existing /tuxedo/contact.
2026-07-06 14:40:18 -06:00

149 lines
4.5 KiB
TypeScript

import type { Metadata } from "next";
import { serializeJsonForScript } from "@/lib/safe-json";
const BASE_URL = process.env.NEXT_PUBLIC_SITE_URL ?? "https://routecommerce.com";
export const metadata: Metadata = {
title: "FAQ — Frequently Asked Questions",
description: "Find answers to common questions about ordering corn, pickup stops, shipping, and wholesale accounts for Tuxedo Corn.",
keywords: ["Tuxedo Corn FAQ", "Olathe Sweet corn questions", "corn pickup FAQ", "wholesale corn accounts", "corn shipping"],
openGraph: {
title: "FAQ — Tuxedo Corn Frequently Asked Questions",
description: "Find answers to common questions about ordering corn, pickup stops, shipping, and wholesale accounts.",
url: `${BASE_URL}/tuxedo/faq`,
siteName: "Tuxedo Corn",
locale: "en_US",
type: "website",
images: [
{
url: "/og-tuxedo.jpg",
width: 1200,
height: 630,
alt: "Tuxedo Corn FAQ",
},
],
},
twitter: {
card: "summary_large_image",
title: "FAQ — Tuxedo Corn",
description: "Find answers to common questions about ordering corn, pickup stops, shipping, and wholesale accounts.",
site: "@TuxedoCorn",
images: ["/og-tuxedo.jpg"],
},
alternates: {
canonical: `${BASE_URL}/tuxedo/faq`,
},
robots: {
index: true,
follow: true,
},
};
const faqJsonLd = {
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "How do I place a preorder for corn?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Find a stop near you on our homepage and click 'Shop This Stop' to add corn to your cart and select your pickup location. Preordering helps us bring the right amount of corn to each stop."
}
},
{
"@type": "Question",
"name": "Can I order without selecting a pickup stop?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes. Choose 'Shipping' at checkout and we will mail cooler boxes directly to your home. Shipping is available for orders of 4 or more dozen and is fulfilled after the season ends."
}
},
{
"@type": "Question",
"name": "Do you ship corn?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes. We ship Olathe Sweet Sweet Corn nationwide. Orders ship as cooler boxes after our field season ends in late summer. A minimum of 4 dozen is required for shipping."
}
},
{
"@type": "Question",
"name": "How do I set up a wholesale account?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Visit /wholesale/register to apply. We review applications and respond within 1-2 business days. Wholesale accounts are available to retailers, restaurants, and farm stands."
}
},
{
"@type": "Question",
"name": "What makes Olathe Sweet different?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Olathe Sweet Sweet Corn is grown in the Uncompahgre Valley of Colorado, where high-altitude days and cool nights produce exceptionally sweet, tender corn. We have been growing this variety for over 40 years."
}
}
]
};
const breadcrumbJsonLd = {
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "Home",
"item": BASE_URL
},
{
"@type": "ListItem",
"position": 2,
"name": "Tuxedo Corn",
"item": `${BASE_URL}/tuxedo`
},
{
"@type": "ListItem",
"position": 3,
"name": "FAQ",
"item": `${BASE_URL}/tuxedo/faq`
}
]
};
const organizationJsonLd = {
"@context": "https://schema.org",
"@type": "Organization",
name: "Tuxedo Corn",
url: `${BASE_URL}/tuxedo`,
logo: {
"@type": "ImageObject",
url: `${BASE_URL}/logo-tuxedo.png`
},
contactPoint: {
"@type": "ContactPoint",
telephone: "+1-970-323-6874",
contactType: "customer service",
availableLanguage: "English"
}
};
export default function TuxedoFAQLayout({ children }: { children: React.ReactNode }) {
return (
<>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: serializeJsonForScript(faqJsonLd) }}
/>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: serializeJsonForScript(breadcrumbJsonLd) }}
/>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: serializeJsonForScript(organizationJsonLd) }}
/>
{children}
</>
);
}