mirror of
https://github.com/vercel/commerce.git
synced 2025-05-13 05:07:51 +00:00
feat: support dynamic hero section
Signed-off-by: Chloe <pinkcloudvnn@gmail.com>
This commit is contained in:
parent
d166a2a877
commit
e2ba024761
@ -22,7 +22,9 @@ export async function generateMetadata(): Promise<Metadata> {
|
|||||||
export default async function HomePage() {
|
export default async function HomePage() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<Suspense>
|
||||||
<Hero />
|
<Hero />
|
||||||
|
</Suspense>
|
||||||
<div className="my-3 min-h-96">
|
<div className="my-3 min-h-96">
|
||||||
<Suspense>
|
<Suspense>
|
||||||
<HomePageContent />
|
<HomePageContent />
|
||||||
|
@ -26,4 +26,19 @@ const HomePageFilters = async () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const HomePageFiltersPlaceholder = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<h1 className="text-4xl font-bold tracking-tight text-white lg:text-6xl">
|
||||||
|
Find Your Car Part
|
||||||
|
</h1>
|
||||||
|
<div className="mt-5 flex w-full flex-col items-center gap-3 md:flex-row">
|
||||||
|
<div className="h-9 w-full rounded bg-gray-50 opacity-50" />
|
||||||
|
<div className="h-9 w-full rounded bg-gray-50 opacity-50" />
|
||||||
|
<div className="h-9 w-full rounded bg-gray-50 opacity-50" />
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export default HomePageFilters;
|
export default HomePageFilters;
|
||||||
|
@ -1,33 +1,16 @@
|
|||||||
import {
|
import { getMetaobjects } from 'lib/shopify';
|
||||||
ArrowPathRoundedSquareIcon,
|
|
||||||
CurrencyDollarIcon,
|
|
||||||
StarIcon,
|
|
||||||
TruckIcon
|
|
||||||
} from '@heroicons/react/24/outline';
|
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import { Suspense } from 'react';
|
import { Suspense } from 'react';
|
||||||
import HomePageFilters from './filters/hompage-filters';
|
import HomePageFilters, { HomePageFiltersPlaceholder } from './filters/hompage-filters';
|
||||||
|
import DynamicHeroIcon from './hero-icon';
|
||||||
|
import ImageDisplay from './page/image-display';
|
||||||
|
|
||||||
const offers = [
|
const Hero = async () => {
|
||||||
{
|
const [offers, heroImage] = await Promise.all([
|
||||||
name: 'Flat Rate Shipping (Commercial Address)',
|
getMetaobjects('usp_item'),
|
||||||
icon: TruckIcon
|
getMetaobjects('hero')
|
||||||
},
|
]);
|
||||||
{
|
|
||||||
name: 'Up to 5 Years Unlimited Miles Warranty',
|
|
||||||
icon: ArrowPathRoundedSquareIcon
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Excellent Customer Support',
|
|
||||||
icon: StarIcon
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'No Core Charge for 30 Days',
|
|
||||||
icon: CurrencyDollarIcon
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
const Hero = () => {
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col border-b border-gray-200 lg:border-0">
|
<div className="flex flex-col border-b border-gray-200 lg:border-0">
|
||||||
<nav aria-label="Offers" className="order-last bg-white lg:order-first">
|
<nav aria-label="Offers" className="order-last bg-white lg:order-first">
|
||||||
@ -38,11 +21,14 @@ const Hero = () => {
|
|||||||
>
|
>
|
||||||
{offers.map((offer) => (
|
{offers.map((offer) => (
|
||||||
<li
|
<li
|
||||||
key={offer.name}
|
key={offer.title}
|
||||||
className="flex w-full items-center justify-start px-4 lg:justify-center"
|
className="flex w-full items-center justify-start px-4 lg:justify-center"
|
||||||
>
|
>
|
||||||
<offer.icon className="size-7 flex-shrink-0 text-secondary" />
|
<DynamicHeroIcon
|
||||||
<p className="px-3 py-5 text-sm font-medium text-gray-800">{offer.name}</p>
|
icon={offer.icon_name as string}
|
||||||
|
className="size-7 flex-shrink-0 text-secondary"
|
||||||
|
/>
|
||||||
|
<p className="px-3 py-5 text-sm font-medium text-gray-800">{offer.title}</p>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
@ -53,6 +39,19 @@ const Hero = () => {
|
|||||||
<div className="relative bg-gray-900">
|
<div className="relative bg-gray-900">
|
||||||
{/* Decorative image and overlay */}
|
{/* Decorative image and overlay */}
|
||||||
<div aria-hidden="true" className="absolute inset-0 overflow-hidden">
|
<div aria-hidden="true" className="absolute inset-0 overflow-hidden">
|
||||||
|
{heroImage.length && heroImage[0]?.file ? (
|
||||||
|
<Suspense fallback={<div className="h-[626px] w-full" />}>
|
||||||
|
<ImageDisplay
|
||||||
|
fileId={heroImage[0].file as string}
|
||||||
|
title="Hero Image"
|
||||||
|
priority
|
||||||
|
className="h-full w-full object-cover object-center"
|
||||||
|
sizes="100vw"
|
||||||
|
width={1103}
|
||||||
|
height={626}
|
||||||
|
/>
|
||||||
|
</Suspense>
|
||||||
|
) : (
|
||||||
<Image
|
<Image
|
||||||
src="/hero-image.jpeg"
|
src="/hero-image.jpeg"
|
||||||
alt="Hero Image"
|
alt="Hero Image"
|
||||||
@ -62,11 +61,12 @@ const Hero = () => {
|
|||||||
className="h-full w-full object-cover object-center"
|
className="h-full w-full object-cover object-center"
|
||||||
sizes="100vw"
|
sizes="100vw"
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div aria-hidden="true" className="absolute inset-0 bg-gray-900 opacity-60" />
|
<div aria-hidden="true" className="absolute inset-0 bg-gray-900 opacity-60" />
|
||||||
|
|
||||||
<div className="relative mx-auto flex max-w-4xl flex-col items-center px-6 py-32 text-center sm:py-64 lg:px-0">
|
<div className="relative mx-auto flex max-w-4xl flex-col items-center px-6 py-32 text-center sm:py-64 lg:px-0">
|
||||||
<Suspense>
|
<Suspense fallback={<HomePageFiltersPlaceholder />}>
|
||||||
<HomePageFilters />
|
<HomePageFilters />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user