feat: support dynamic hero section

Signed-off-by: Chloe <pinkcloudvnn@gmail.com>
This commit is contained in:
Chloe 2024-05-28 19:50:10 +07:00
parent d166a2a877
commit e2ba024761
No known key found for this signature in database
GPG Key ID: CFD53CE570D42DF5
3 changed files with 57 additions and 40 deletions

View File

@ -22,7 +22,9 @@ export async function generateMetadata(): Promise<Metadata> {
export default async function HomePage() { export default async function HomePage() {
return ( return (
<> <>
<Hero /> <Suspense>
<Hero />
</Suspense>
<div className="my-3 min-h-96"> <div className="my-3 min-h-96">
<Suspense> <Suspense>
<HomePageContent /> <HomePageContent />

View File

@ -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;

View File

@ -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,20 +39,34 @@ 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">
<Image {heroImage.length && heroImage[0]?.file ? (
src="/hero-image.jpeg" <Suspense fallback={<div className="h-[626px] w-full" />}>
alt="Hero Image" <ImageDisplay
width={1103} fileId={heroImage[0].file as string}
height={626} title="Hero Image"
priority priority
className="h-full w-full object-cover object-center" className="h-full w-full object-cover object-center"
sizes="100vw" sizes="100vw"
/> width={1103}
height={626}
/>
</Suspense>
) : (
<Image
src="/hero-image.jpeg"
alt="Hero Image"
width={1103}
height={626}
priority
className="h-full w-full object-cover object-center"
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>