diff --git a/next.config.ts b/next.config.ts
index f8c2c9e..cd27f06 100644
--- a/next.config.ts
+++ b/next.config.ts
@@ -159,6 +159,15 @@ const nextConfig: NextConfig = {
fullUrl: process.env.NODE_ENV === "development",
},
},
+
+ // Allow cross-origin requests to dev resources (HMR, dev manifest, etc.)
+ // from non-localhost hosts (e.g. LAN IPs, dev tunnels). Read from
+ // `NEXT_ALLOWED_DEV_ORIGINS` as a comma-separated list. Empty in production.
+ allowedDevOrigins: process.env.NEXT_ALLOWED_DEV_ORIGINS
+ ? process.env.NEXT_ALLOWED_DEV_ORIGINS.split(",")
+ .map((s) => s.trim())
+ .filter(Boolean)
+ : [],
};
export default nextConfig;
\ No newline at end of file
diff --git a/src/app/indian-river-direct/stops/[slug]/error.tsx b/src/app/indian-river-direct/stops/[slug]/error.tsx
deleted file mode 100644
index 5114744..0000000
--- a/src/app/indian-river-direct/stops/[slug]/error.tsx
+++ /dev/null
@@ -1,66 +0,0 @@
-"use client";
-
-import Link from "next/link";
-import { m as motion } from "framer-motion";
-
-export default function ErrorPage({
- error,
- reset,
-}: {
- error: Error & { digest?: string };
- reset: () => void;
-}) {
- return (
-
-
-
-
-
-
-
-
- Stop Not Available
-
- We couldn't load this stop. Please try again.
-
-
- {process.env.NODE_ENV === "development" && (
-
-
Error Details
-
{error.message}
-
- )}
-
-
-
-
- Back to Homepage
-
-
-
-
- );
-}
\ No newline at end of file
diff --git a/src/app/indian-river-direct/stops/[slug]/loading.tsx b/src/app/indian-river-direct/stops/[slug]/loading.tsx
deleted file mode 100644
index 11609c9..0000000
--- a/src/app/indian-river-direct/stops/[slug]/loading.tsx
+++ /dev/null
@@ -1,6 +0,0 @@
-import { LoadingFade } from "@/components/transitions/LoadingFade";
-
-/** Subtle navigation indicator — see LoadingFade for rationale. */
-export default function Loading() {
- return ;
-}
diff --git a/src/app/indian-river-direct/stops/[slug]/page.tsx b/src/app/indian-river-direct/stops/[slug]/page.tsx
deleted file mode 100644
index 78276e3..0000000
--- a/src/app/indian-river-direct/stops/[slug]/page.tsx
+++ /dev/null
@@ -1,276 +0,0 @@
-"use client";
-
-import { useEffect, useState } from "react";
-import { useParams } from "next/navigation";
-import Link from "next/link";
-import { m as motion } from "framer-motion";
-import ProductCard from "@/components/storefront/ProductCard";
-import StopSetEffect from "@/components/storefront/StopSetEffect";
-import StorefrontHeader from "@/components/storefront/StorefrontHeader";
-import StorefrontFooter from "@/components/storefront/StorefrontFooter";
-import LayoutContainer from "@/components/layout/LayoutContainer";
-import { supabase } from "@/lib/supabase";
-import { formatDate } from "@/lib/format-date";
-
-type Product = {
- id: string;
- name: string;
- description: string | null;
- price: number;
- type: string;
- image_url: string | null;
- brand_id: string;
- is_taxable?: boolean;
- pickup_type?: "scheduled_stop" | "shed";
-};
-
-type Stop = {
- id: string;
- city: string;
- state: string;
- date: string;
- time: string;
- location: string;
- brand_id: string;
-};
-
-export default function StopPage() {
- const params = useParams();
- const slug = params.slug as string;
-
- const [stop, setStop] = useState<{
- id: string;
- city: string;
- state: string;
- date: string;
- time: string;
- location: string;
- brand_id: string;
- } | null>(null);
- const [products, setProducts] = useState([]);
- const [brandSlug, setBrandSlug] = useState("indian-river-direct");
- const [brandAccent, setBrandAccent] = useState<"green" | "orange" | "blue">("blue");
-
- useEffect(() => {
- async function load() {
- const { data: stopData } = await supabase
- .from("stops")
- .select("*")
- .eq("slug", slug)
- .eq("active", true)
- .single() as unknown as { data: Stop | null };
-
- if (!stopData) return;
-
- setStop(stopData);
- const isIndian = slug.includes("indian");
- setBrandSlug(isIndian ? "indian-river-direct" : "tuxedo");
- setBrandAccent(isIndian ? "blue" : "green");
-
- const { data: productsData } = await supabase
- .from("products")
- .select("*")
- .eq("brand_id", stopData.brand_id)
- .eq("active", true) as unknown as { data: Product[] | null };
- setProducts(productsData ?? []);
- }
- load();
- }, [slug]);
-
- if (!stop) {
- return (
-
- );
- }
-
- const isBlue = brandAccent === "blue";
- const brandLabel = isBlue ? "Indian River Direct" : "Tuxedo Corn";
-
- return (
-
-
-
-
-
-
-
- {/* Back navigation */}
-
-
-
- All Stops
-
- /
- {stop.city}, {stop.state}
-
-
- {/* Stop header with animation */}
-
-
- {isBlue ? "Indian River Direct" : "Tuxedo Corn"}
-
-
- {stop.city},
{stop.state}
-
-
- {isBlue
- ? "Order fresh Florida citrus for pickup at this stop."
- : "Order fresh Olathe Sweet™ sweet corn for pickup at this stop."}
-
-
-
-
- {/* Stop info */}
-
-
- {/* Date */}
-
-
-
-
Date
-
{formatDate(stop.date)}
-
-
- {/* Time */}
-
-
-
-
- {/* Location */}
-
-
-
-
Location
-
{stop.location}
-
-
-
-
-
- {/* Available Products — editorial header */}
-
-
-
Farm-Direct
-
- Available Products
-
-
-
- Preorder for pickup — add items below and we will have them ready at the stop.
-
-
- {products.length === 0 ? (
-
-
No products available for this stop.
-
- ) : (
-
- {products.map((product) => (
-
- ))}
-
- )}
-
-
-
-
-
-
-
- );
-}
\ No newline at end of file
diff --git a/src/app/tuxedo/stops/[slug]/error.tsx b/src/app/tuxedo/stops/[slug]/error.tsx
deleted file mode 100644
index 635ffda..0000000
--- a/src/app/tuxedo/stops/[slug]/error.tsx
+++ /dev/null
@@ -1,61 +0,0 @@
-"use client";
-
-import Link from "next/link";
-import { m as motion } from "framer-motion";
-
-export default function ErrorPage({
- error,
- reset,
-}: {
- error: Error & { digest?: string };
- reset: () => void;
-}) {
- return (
-
-
-
-
-
-
- Stop Not Available
-
- We couldn't load this stop. Please try again.
-
-
- {process.env.NODE_ENV === "development" && (
-
-
Error Details
-
{error.message}
-
- )}
-
-
-
-
- Back to Homepage
-
-
-
-
- );
-}
\ No newline at end of file
diff --git a/src/app/tuxedo/stops/[slug]/loading.tsx b/src/app/tuxedo/stops/[slug]/loading.tsx
deleted file mode 100644
index 11609c9..0000000
--- a/src/app/tuxedo/stops/[slug]/loading.tsx
+++ /dev/null
@@ -1,6 +0,0 @@
-import { LoadingFade } from "@/components/transitions/LoadingFade";
-
-/** Subtle navigation indicator — see LoadingFade for rationale. */
-export default function Loading() {
- return ;
-}
diff --git a/src/app/tuxedo/stops/[slug]/page.tsx b/src/app/tuxedo/stops/[slug]/page.tsx
deleted file mode 100644
index d3fbdb9..0000000
--- a/src/app/tuxedo/stops/[slug]/page.tsx
+++ /dev/null
@@ -1,235 +0,0 @@
-"use client";
-
-import { useEffect, useState } from "react";
-import { useParams } from "next/navigation";
-import Link from "next/link";
-import ProductCard from "@/components/storefront/ProductCard";
-import StopSetEffect from "@/components/storefront/StopSetEffect";
-import StorefrontHeader from "@/components/storefront/StorefrontHeader";
-import StorefrontFooter from "@/components/storefront/StorefrontFooter";
-import LayoutContainer from "@/components/layout/LayoutContainer";
-import { supabase } from "@/lib/supabase";
-import { formatDate } from "@/lib/format-date";
-
-type Product = {
- id: string;
- name: string;
- description: string | null;
- price: number;
- type: string;
- image_url: string | null;
- brand_id: string;
- is_taxable?: boolean;
- pickup_type?: "scheduled_stop" | "shed";
-};
-
-type Stop = {
- id: string;
- city: string;
- state: string;
- date: string;
- time: string;
- location: string;
- brand_id: string;
-};
-
-export default function StopPage() {
- const params = useParams();
- const slug = params.slug as string;
-
- const [stop, setStop] = useState<{
- id: string;
- city: string;
- state: string;
- date: string;
- time: string;
- location: string;
- brand_id: string;
- } | null>(null);
- const [products, setProducts] = useState([]);
- const [brandSlug, setBrandSlug] = useState("tuxedo");
- const [brandAccent, setBrandAccent] = useState<"green" | "orange" | "blue">("green");
-
- useEffect(() => {
- async function load() {
- const { data: stopData } = await supabase
- .from("stops")
- .select("*")
- .eq("slug", slug)
- .eq("active", true)
- .single() as unknown as { data: Stop | null };
-
- if (!stopData) return;
-
- setStop(stopData);
- const isIndian = slug.includes("indian");
- setBrandSlug(isIndian ? "indian-river-direct" : "tuxedo");
- setBrandAccent(isIndian ? "blue" : "green");
-
- const { data: productsData } = await supabase
- .from("products")
- .select("*")
- .eq("brand_id", stopData.brand_id)
- .eq("active", true) as unknown as { data: Product[] | null };
- setProducts(productsData ?? []);
- }
- load();
- }, [slug]);
-
- if (!stop) {
- return (
-
-
-
-
-
-
Stop Not Found
-
-
-
-
- );
- }
-
- const isBlue = brandAccent === "blue";
- const brandLabel = isBlue ? "Indian River Direct" : "Tuxedo Corn";
-
- return (
-
-
-
-
-
-
-
- {/* Back navigation */}
-
-
-
- All Stops
-
-
/
-
{stop.city}, {stop.state}
-
-
- {/* Stop header */}
-
-
- {brandLabel}
-
-
- {stop.city},
{stop.state}
-
-
- {isBlue
- ? "Order fresh Florida citrus for pickup at this stop."
- : "Order fresh Olathe Sweet™ sweet corn for pickup at this stop."}
-
-
-
-
- {/* Stop info */}
-
-
-
-
-
-
Date
-
{formatDate(stop.date)}
-
-
-
-
-
-
-
Location
-
{stop.location}
-
-
-
-
-
- {/* Available Products — editorial header */}
-
-
-
Farm-Direct
-
- Available Products
-
-
-
- Preorder for pickup — add items below and we will have them ready at the stop.
-
-
- {products.length === 0 ? (
-
-
No products available for this stop.
-
- ) : (
-
- {products.map((product) => (
-
- ))}
-
- )}
-
-
-
-
-
-
-
- );
-}
\ No newline at end of file