refactor shopify storefront

This commit is contained in:
Rami Bitar
2026-05-05 13:42:40 -04:00
parent ba8826030c
commit 62fbdead87
156 changed files with 1688 additions and 8293 deletions

View File

@@ -0,0 +1,139 @@
import { useState } from "react";
import { cn } from "@/lib/utils";
import { Typography } from "@/components/Typography";
export type NewsletterCtaProps = {
tagline: string;
heading: string;
subheading: string;
buttonLabel: string;
endpoint: string;
imageUrl: string;
layout: "split" | "stacked";
};
export function NewsletterCta({
tagline,
heading,
subheading,
buttonLabel,
endpoint,
imageUrl,
layout,
}: NewsletterCtaProps) {
const [email, setEmail] = useState("");
const [submitted, setSubmitted] = useState(false);
const [submitting, setSubmitting] = useState(false);
const submit = async (e: React.FormEvent) => {
e.preventDefault();
if (!email) return;
setSubmitting(true);
try {
if (endpoint) {
await fetch(endpoint, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email }),
});
}
setSubmitted(true);
} catch {
setSubmitted(true);
} finally {
setSubmitting(false);
}
};
const Form = (
<form
onSubmit={submit}
className="flex w-full max-w-md items-center border-b border-foreground/30 focus-within:border-foreground"
>
<input
type="email"
required
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="you@example.com"
className="flex-1 bg-transparent py-3 text-sm placeholder:text-muted-foreground focus:outline-none"
/>
<button
type="submit"
disabled={submitting}
className="ml-3 text-sm font-medium tracking-wide hover:opacity-70 disabled:opacity-40"
>
{submitting ? "…" : buttonLabel}
</button>
</form>
);
if (layout === "split") {
return (
<section className="bg-background">
<div className="container mx-auto max-w-7xl px-6 py-16 md:py-24">
<div className="grid grid-cols-1 items-center gap-12 md:grid-cols-2">
<div>
{imageUrl ? (
<img
src={imageUrl}
alt=""
className="aspect-[5/4] w-full rounded-md object-cover"
/>
) : null}
</div>
<div className="flex flex-col items-start">
{tagline ? (
<p className="mb-3 text-xs uppercase tracking-[0.2em] text-muted-foreground">
{tagline}
</p>
) : null}
<Typography variant="h2">{heading}</Typography>
{subheading ? (
<Typography variant="subtitle1" className="mt-3 max-w-md">
{subheading}
</Typography>
) : null}
<div className="mt-8 w-full">
{submitted ? (
<p className="text-sm text-muted-foreground">
Thanks we'll be in touch.
</p>
) : (
Form
)}
</div>
</div>
</div>
</div>
</section>
);
}
return (
<section className="bg-muted/40 py-20 md:py-28">
<div className="container mx-auto max-w-2xl px-6 text-center">
{tagline ? (
<p className="mb-3 text-xs uppercase tracking-[0.2em] text-muted-foreground">
{tagline}
</p>
) : null}
<Typography variant="h2">{heading}</Typography>
{subheading ? (
<Typography variant="subtitle1" className="mt-3">
{subheading}
</Typography>
) : null}
<div className={cn("mx-auto mt-10 flex w-full max-w-md justify-center")}>
{submitted ? (
<p className="text-sm text-muted-foreground">
Thanks — we'll be in touch.
</p>
) : (
Form
)}
</div>
</div>
</section>
);
}