refactor(storefront): replace supabase shim in storefront pages
The legacy lib/supabase.ts shim returns { data: null } for every query,
which silently broke the tuxedo and indian-river-direct storefronts:
they displayed 'No stops on the calendar just yet' regardless of the
real data in Postgres.
Added src/actions/storefront.ts as a new "use server" module with
typed actions that hit the shared pg pool directly:
- getStorefrontData(slug) — brand + stops + products in one call
- getStorefrontStopBySlug(slug) — single stop + its products
- getStorefrontWholesaleSettings(slug) — public invoice/business info
Updated to use these actions instead of the shim:
- src/app/tuxedo/page.tsx
- src/app/tuxedo/stops/[slug]/page.tsx
- src/app/tuxedo/contact/ContactClientPage.tsx
- src/app/indian-river-direct/page.tsx
- src/app/indian-river-direct/stops/[slug]/page.tsx
The shim file itself is still imported by other pages and API routes
that will be migrated in follow-up steps.
This commit is contained in:
@@ -8,8 +8,8 @@ import StorefrontHeader from "@/components/storefront/StorefrontHeader";
|
||||
import StorefrontFooter from "@/components/storefront/StorefrontFooter";
|
||||
import LayoutContainer from "@/components/layout/LayoutContainer";
|
||||
import WhyIndianRiverDirect from "@/components/storefront/WhyIndianRiverDirect";
|
||||
import { supabase } from "@/lib/supabase";
|
||||
import { getBrandSettingsPublic } from "@/actions/brand-settings";
|
||||
import { getStorefrontData } from "@/actions/storefront";
|
||||
|
||||
type Brand = { id: string; name: string; slug: string };
|
||||
type Stop = { id: string; city: string; state: string; date: string; time: string; location: string; slug: string; brand_id: string };
|
||||
@@ -85,12 +85,12 @@ export default function IndianRiverDirectPage() {
|
||||
useEffect(() => {
|
||||
async function load() {
|
||||
const slug = "indian-river-direct";
|
||||
const [brandResult, settingsResult] = await Promise.all([
|
||||
supabase.from("brands").select("*").eq("slug", slug).single(),
|
||||
const [storefront, settingsResult] = await Promise.all([
|
||||
getStorefrontData(slug),
|
||||
getBrandSettingsPublic(slug),
|
||||
]);
|
||||
|
||||
const brandData = brandResult.data as Brand | null;
|
||||
const brandData = storefront.brand as Brand | null;
|
||||
setBrand(brandData);
|
||||
|
||||
if (settingsResult.success && settingsResult.settings) {
|
||||
@@ -110,12 +110,8 @@ export default function IndianRiverDirectPage() {
|
||||
} catch { /* not logged in */ }
|
||||
|
||||
if (brandData?.id) {
|
||||
const [{ data: stopsData }, { data: productsData }] = await Promise.all([
|
||||
supabase.from("stops").select("*").eq("brand_id", brandData.id).eq("active", true) as unknown as { data: Stop[] | null },
|
||||
supabase.from("products").select("*").eq("brand_id", brandData.id).eq("active", true) as unknown as { data: Product[] | null },
|
||||
]);
|
||||
setStops(stopsData ?? []);
|
||||
setProducts(productsData ?? []);
|
||||
setStops(storefront.stops as unknown as Stop[]);
|
||||
setProducts(storefront.products as unknown as Product[]);
|
||||
}
|
||||
}
|
||||
load();
|
||||
|
||||
@@ -9,7 +9,7 @@ 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 { getStorefrontStopBySlug } from "@/actions/storefront";
|
||||
import { formatDate } from "@/lib/format-date";
|
||||
|
||||
type Product = {
|
||||
@@ -53,26 +53,14 @@ export default function StopPage() {
|
||||
|
||||
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 };
|
||||
const result = await getStorefrontStopBySlug(slug);
|
||||
if (!result) return;
|
||||
|
||||
if (!stopData) return;
|
||||
|
||||
setStop(stopData);
|
||||
setStop(result.stop as unknown as Stop);
|
||||
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 ?? []);
|
||||
setProducts(result.products as unknown as Product[]);
|
||||
}
|
||||
load();
|
||||
}, [slug]);
|
||||
|
||||
@@ -5,7 +5,7 @@ import Link from "next/link";
|
||||
import StorefrontHeader from "@/components/storefront/StorefrontHeader";
|
||||
import StorefrontFooter from "@/components/storefront/StorefrontFooter";
|
||||
import LayoutContainer from "@/components/layout/LayoutContainer";
|
||||
import { supabase } from "@/lib/supabase";
|
||||
import { getStorefrontWholesaleSettings } from "@/actions/storefront";
|
||||
|
||||
type BrandSettings = {
|
||||
invoice_business_name: string | null;
|
||||
@@ -29,13 +29,8 @@ export default function TuxedoContactPage() {
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const TUXEDO_BRAND_ID = "64294306-5f42-463d-a5e8-2ad6c81a96de";
|
||||
supabase
|
||||
.from("wholesale_settings")
|
||||
.select("invoice_business_name, invoice_business_address, invoice_business_phone, invoice_business_email, invoice_business_website")
|
||||
.eq("brand_id", TUXEDO_BRAND_ID)
|
||||
.single()
|
||||
.then(({ data }) => setBrandSettings((data as unknown as BrandSettings) ?? null));
|
||||
getStorefrontWholesaleSettings("tuxedo")
|
||||
.then((data) => setBrandSettings(data as BrandSettings | null));
|
||||
}, []);
|
||||
|
||||
function handleSubmit(e: React.FormEvent) {
|
||||
|
||||
+6
-10
@@ -12,8 +12,8 @@ import StorefrontHeader from "@/components/storefront/StorefrontHeader";
|
||||
import StorefrontFooter from "@/components/storefront/StorefrontFooter";
|
||||
import BrandStylesProvider from "@/components/storefront/BrandStylesProvider";
|
||||
import { ScrollReveal, ParallaxLayer, FadeOnScroll } from "@/components/ui/ScrollAnimations";
|
||||
import { supabase } from "@/lib/supabase";
|
||||
import { getBrandSettingsPublic } from "@/actions/brand-settings";
|
||||
import { getStorefrontData } from "@/actions/storefront";
|
||||
import { gsap } from "gsap";
|
||||
import { ScrollTrigger } from "gsap/ScrollTrigger";
|
||||
|
||||
@@ -448,12 +448,12 @@ export default function TuxedoPage() {
|
||||
async function load() {
|
||||
const slug = "tuxedo";
|
||||
|
||||
const [brandResult, settingsResult] = await Promise.all([
|
||||
supabase.from("brands").select("*").eq("slug", slug).single(),
|
||||
const [storefront, settingsResult] = await Promise.all([
|
||||
getStorefrontData(slug),
|
||||
getBrandSettingsPublic(slug),
|
||||
]);
|
||||
|
||||
const brandData = brandResult.data as Brand | null;
|
||||
const brandData = storefront.brand as Brand | null;
|
||||
setBrand(brandData);
|
||||
|
||||
if (settingsResult.success && settingsResult.settings) {
|
||||
@@ -484,12 +484,8 @@ export default function TuxedoPage() {
|
||||
}
|
||||
|
||||
if (brandData?.id) {
|
||||
const [{ data: stopsData }, { data: productsData }] = await Promise.all([
|
||||
supabase.from("stops").select("*").eq("brand_id", brandData.id).eq("active", true) as unknown as { data: Stop[] | null },
|
||||
supabase.from("products").select("*").eq("brand_id", brandData.id).eq("active", true) as unknown as { data: Product[] | null },
|
||||
]);
|
||||
setStops(stopsData ?? []);
|
||||
setProducts(productsData ?? []);
|
||||
setStops(storefront.stops as unknown as Stop[]);
|
||||
setProducts(storefront.products as unknown as Product[]);
|
||||
}
|
||||
}
|
||||
load();
|
||||
|
||||
@@ -8,7 +8,7 @@ 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 { getStorefrontStopBySlug } from "@/actions/storefront";
|
||||
import { formatDate } from "@/lib/format-date";
|
||||
|
||||
type Product = {
|
||||
@@ -52,26 +52,14 @@ export default function StopPage() {
|
||||
|
||||
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 };
|
||||
const result = await getStorefrontStopBySlug(slug);
|
||||
if (!result) return;
|
||||
|
||||
if (!stopData) return;
|
||||
|
||||
setStop(stopData);
|
||||
setStop(result.stop as unknown as Stop);
|
||||
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 ?? []);
|
||||
setProducts(result.products as unknown as Product[]);
|
||||
}
|
||||
load();
|
||||
}, [slug]);
|
||||
|
||||
Reference in New Issue
Block a user