diff --git a/.env.example b/.env.example index 6cb0457..b5debd1 100644 --- a/.env.example +++ b/.env.example @@ -34,5 +34,8 @@ EMAIL_FROM_ADDRESS="mars@noreply.stillwell.cloud" # Vercel auto-sets this on Pro. Used to authenticate cron job requests. CRON_SECRET="" +# ─── Public site URL (used for OG metadata, canonical links) ─ +NEXT_PUBLIC_SITE_URL="https://echoocr.com" + # ─── Environment indicator ──────────────────────────────────── NEXT_PUBLIC_ENV="" diff --git a/public/og-image.png b/public/og-image.png new file mode 100644 index 0000000..37f0e12 Binary files /dev/null and b/public/og-image.png differ diff --git a/src/app/(marketing)/features/ai-ocr/layout.tsx b/src/app/(marketing)/features/ai-ocr/layout.tsx new file mode 100644 index 0000000..42ffa95 --- /dev/null +++ b/src/app/(marketing)/features/ai-ocr/layout.tsx @@ -0,0 +1,17 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "AI-Powered OCR", + description: + "Echo's vision AI reads handwriting, checkboxes, and printed text — extracting 20+ fields per card including names, contact info, prayer requests, and spiritual decisions with over 95% accuracy.", + openGraph: { + title: "AI-Powered OCR | Echo", + description: + "Vision AI that reads handwriting, checkboxes, and printed text — 20+ fields per card with 95%+ accuracy.", + images: ["/og-image.png"], + }, +}; + +export default function AiOcrLayout({ children }: { children: React.ReactNode }) { + return <>{children}; +} diff --git a/src/app/(marketing)/features/analytics/layout.tsx b/src/app/(marketing)/features/analytics/layout.tsx new file mode 100644 index 0000000..764c122 --- /dev/null +++ b/src/app/(marketing)/features/analytics/layout.tsx @@ -0,0 +1,17 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Dashboard & Analytics", + description: + "See first-time guests, salvations, prayer requests, and follow-up status at a glance. Filter, sort, and export your data — powerful card tables with actionable guest insights.", + openGraph: { + title: "Dashboard & Analytics | Echo", + description: + "Real-time stats, powerful filtering, status tracking, and CSV export for your guest services data.", + images: ["/og-image.png"], + }, +}; + +export default function AnalyticsLayout({ children }: { children: React.ReactNode }) { + return <>{children}; +} diff --git a/src/app/(marketing)/features/collection-days/layout.tsx b/src/app/(marketing)/features/collection-days/layout.tsx new file mode 100644 index 0000000..ec5141c --- /dev/null +++ b/src/app/(marketing)/features/collection-days/layout.tsx @@ -0,0 +1,17 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Collection Days & Events", + description: + "Define recurring Sunday services and special events with flexible RFC 5545 scheduling. Echo auto-assigns scanned cards to the right event, keeping everything organized.", + openGraph: { + title: "Collection Days & Events | Echo", + description: + "Recurring services, special events, and automatic card-to-event assignment — keep everything organized.", + images: ["/og-image.png"], + }, +}; + +export default function CollectionDaysLayout({ children }: { children: React.ReactNode }) { + return <>{children}; +} diff --git a/src/app/(marketing)/features/integrations/layout.tsx b/src/app/(marketing)/features/integrations/layout.tsx new file mode 100644 index 0000000..485b00c --- /dev/null +++ b/src/app/(marketing)/features/integrations/layout.tsx @@ -0,0 +1,17 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Integrations", + description: + "Sync scanned card data to Planning Center, Google Sheets, Monday.com, Airtable, or any system via webhooks. Echo fits into the tools your church already uses.", + openGraph: { + title: "Integrations | Echo", + description: + "Planning Center, Google Sheets, Monday.com, Airtable, webhooks, and CSV export — Echo fits into your existing workflow.", + images: ["/og-image.png"], + }, +}; + +export default function IntegrationsLayout({ children }: { children: React.ReactNode }) { + return <>{children}; +} diff --git a/src/app/(marketing)/features/layout.tsx b/src/app/(marketing)/features/layout.tsx new file mode 100644 index 0000000..848e80e --- /dev/null +++ b/src/app/(marketing)/features/layout.tsx @@ -0,0 +1,17 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Features", + description: + "Explore Echo's full feature set — AI-powered OCR, scanner integration, team collaboration, multi-site management, analytics, and integrations with Planning Center, Google Sheets, and more.", + openGraph: { + title: "Features | Echo", + description: + "Everything your guest services team needs — from AI scanning to Planning Center sync.", + images: ["/og-image.png"], + }, +}; + +export default function FeaturesLayout({ children }: { children: React.ReactNode }) { + return <>{children}; +} diff --git a/src/app/(marketing)/features/multi-site/layout.tsx b/src/app/(marketing)/features/multi-site/layout.tsx new file mode 100644 index 0000000..47249cd --- /dev/null +++ b/src/app/(marketing)/features/multi-site/layout.tsx @@ -0,0 +1,17 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Multi-Site Management", + description: + "Manage multiple campuses under one organization. Each location gets its own collection days, scanner setup, and team assignments — with unified reporting across all sites.", + openGraph: { + title: "Multi-Site Management | Echo", + description: + "Independent schedules per campus, unified processing pipeline, and organization-wide reporting.", + images: ["/og-image.png"], + }, +}; + +export default function MultiSiteLayout({ children }: { children: React.ReactNode }) { + return <>{children}; +} diff --git a/src/app/(marketing)/features/scanner-integration/layout.tsx b/src/app/(marketing)/features/scanner-integration/layout.tsx new file mode 100644 index 0000000..6f8dde3 --- /dev/null +++ b/src/app/(marketing)/features/scanner-integration/layout.tsx @@ -0,0 +1,17 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Scanner Integration", + description: + "Connect your office scanner via email or FTP and Echo picks up batches automatically. Or upload photos and PDFs from your phone — supports duplex scanning with front/back pairing.", + openGraph: { + title: "Scanner Integration | Echo", + description: + "Email, FTP, or drag-and-drop — get scanned cards into Echo however works best for your team.", + images: ["/og-image.png"], + }, +}; + +export default function ScannerIntegrationLayout({ children }: { children: React.ReactNode }) { + return <>{children}; +} diff --git a/src/app/(marketing)/features/security/layout.tsx b/src/app/(marketing)/features/security/layout.tsx new file mode 100644 index 0000000..f23242d --- /dev/null +++ b/src/app/(marketing)/features/security/layout.tsx @@ -0,0 +1,17 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Security & Privacy", + description: + "Role-based permissions, encrypted storage, email verification, invitation-only access, SSO support, and enterprise-grade infrastructure protect your congregation's personal data.", + openGraph: { + title: "Security & Privacy | Echo", + description: + "Encryption, RBAC, SSO, audit trails, and invitation-only access — your congregation's data stays safe.", + images: ["/og-image.png"], + }, +}; + +export default function SecurityLayout({ children }: { children: React.ReactNode }) { + return <>{children}; +} diff --git a/src/app/(marketing)/features/team-collaboration/layout.tsx b/src/app/(marketing)/features/team-collaboration/layout.tsx new file mode 100644 index 0000000..55fadc1 --- /dev/null +++ b/src/app/(marketing)/features/team-collaboration/layout.tsx @@ -0,0 +1,17 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Team Collaboration", + description: + "Invite your pastoral care team with five role tiers, assign cards for follow-up, track review status, and keep everyone on the same page with in-app notifications.", + openGraph: { + title: "Team Collaboration | Echo", + description: + "Role-based access, card assignment, review workflows, and notifications for your whole team.", + images: ["/og-image.png"], + }, +}; + +export default function TeamCollaborationLayout({ children }: { children: React.ReactNode }) { + return <>{children}; +} diff --git a/src/app/(marketing)/layout.tsx b/src/app/(marketing)/layout.tsx index 1ef17d1..b1b768d 100644 --- a/src/app/(marketing)/layout.tsx +++ b/src/app/(marketing)/layout.tsx @@ -1,3 +1,11 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { + alternates: { + canonical: "/welcome", + }, +}; + export default function MarketingLayout({ children, }: { diff --git a/src/app/(marketing)/pricing/layout.tsx b/src/app/(marketing)/pricing/layout.tsx new file mode 100644 index 0000000..3fb34a1 --- /dev/null +++ b/src/app/(marketing)/pricing/layout.tsx @@ -0,0 +1,17 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Pricing", + description: + "Simple, transparent pricing for churches of every size. Start free with 50 cards/month, then scale as you grow. All paid plans include a 14-day free trial.", + openGraph: { + title: "Pricing | Echo", + description: + "Start free with 50 cards/month. Upgrade when you're ready — no contract, no commitment.", + images: ["/og-image.png"], + }, +}; + +export default function PricingLayout({ children }: { children: React.ReactNode }) { + return <>{children}; +} diff --git a/src/app/(marketing)/welcome/layout.tsx b/src/app/(marketing)/welcome/layout.tsx new file mode 100644 index 0000000..9f90aa2 --- /dev/null +++ b/src/app/(marketing)/welcome/layout.tsx @@ -0,0 +1,16 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Echo — AI-Powered Response Card Scanning for Churches", + description: + "Stop hand-typing visitor cards. Echo uses AI to scan guest cards, prayer requests, and response forms — then syncs to Planning Center, your CRM, or wherever your team needs it.", + openGraph: { + title: "Echo — AI-Powered Response Card Scanning for Churches", + description: + "Stop hand-typing visitor cards. Scan guest cards with AI and sync to Planning Center in seconds.", + }, +}; + +export default function WelcomeLayout({ children }: { children: React.ReactNode }) { + return <>{children}; +} diff --git a/src/app/layout.tsx b/src/app/layout.tsx index d6065c3..b78d054 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -9,9 +9,54 @@ const quicksand = Quicksand({ weight: ["300", "400", "500", "600", "700"], }); +const siteUrl = process.env.NEXT_PUBLIC_SITE_URL || "https://echoocr.com"; + export const metadata: Metadata = { - title: "Echo OCR", - description: "Response card scanning and management", + title: { + default: "Echo — AI-Powered Response Card Scanning for Churches", + template: "%s | Echo", + }, + description: + "Stop hand-typing visitor cards. Echo uses AI to scan guest cards, prayer requests, and response forms — then syncs to Planning Center, your CRM, or wherever your team needs it.", + metadataBase: new URL(siteUrl), + openGraph: { + type: "website", + siteName: "Echo", + title: "Echo — AI-Powered Response Card Scanning for Churches", + description: + "Stop hand-typing visitor cards. Echo uses AI to scan guest cards, prayer requests, and response forms — then syncs to Planning Center, your CRM, or wherever your team needs it.", + images: [ + { + url: "/og-image.png", + width: 1200, + height: 630, + alt: "Echo — Stop hand-typing visitor cards", + }, + ], + }, + twitter: { + card: "summary_large_image", + title: "Echo — AI-Powered Response Card Scanning for Churches", + description: + "Stop hand-typing visitor cards. Echo uses AI to scan guest cards, prayer requests, and response forms — then syncs to Planning Center, your CRM, or wherever your team needs it.", + images: ["/og-image.png"], + }, + keywords: [ + "church OCR", + "visitor card scanning", + "guest card scanner", + "response card digitization", + "Planning Center integration", + "church management", + "AI OCR", + "prayer request scanning", + "connection card scanner", + "church guest services", + ], + robots: { + index: true, + follow: true, + }, }; export default function RootLayout({