fix: homepage revamp
Signed-off-by: Chloe <pinkcloudvnn@gmail.com>
BIN
app/favicon.ico
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
@ -2,7 +2,7 @@ import Banner from 'components/banner';
|
||||
import Navbar from 'components/layout/navbar';
|
||||
import { GeistSans } from 'geist/font/sans';
|
||||
import { ensureStartsWith } from 'lib/utils';
|
||||
import { League_Spartan } from 'next/font/google';
|
||||
import Script from 'next/script';
|
||||
import { ReactNode, Suspense } from 'react';
|
||||
import './globals.css';
|
||||
|
||||
@ -13,12 +13,6 @@ const baseUrl = process.env.NEXT_PUBLIC_VERCEL_URL
|
||||
const twitterCreator = TWITTER_CREATOR ? ensureStartsWith(TWITTER_CREATOR, '@') : undefined;
|
||||
const twitterSite = TWITTER_SITE ? ensureStartsWith(TWITTER_SITE, 'https://') : undefined;
|
||||
|
||||
const league_spartan = League_Spartan({
|
||||
subsets: ['latin'],
|
||||
variable: '--font-league-spartan',
|
||||
display: 'swap'
|
||||
});
|
||||
|
||||
export const metadata = {
|
||||
metadataBase: new URL(baseUrl),
|
||||
title: {
|
||||
@ -41,8 +35,13 @@ export const metadata = {
|
||||
|
||||
export default async function RootLayout({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
<html lang="en" className={`${GeistSans.variable} ${league_spartan.variable}`}>
|
||||
<html lang="en" className={GeistSans.variable}>
|
||||
<body className="bg-neutral-50 text-black selection:bg-teal-300 dark:bg-neutral-900 dark:text-white dark:selection:bg-pink-500 dark:selection:text-white">
|
||||
<Script
|
||||
src="//widget.trustpilot.com/bootstrap/v5/tp.widget.bootstrap.min.js"
|
||||
async
|
||||
type="text/javascript"
|
||||
/>
|
||||
<header>
|
||||
<Banner />
|
||||
<Navbar />
|
||||
|
@ -1,5 +1,5 @@
|
||||
import Hero from 'components/hero';
|
||||
import HomePageContent from 'components/home-page-content';
|
||||
import About from 'components/home-page/about';
|
||||
import Footer from 'components/layout/footer';
|
||||
import { getPage } from 'lib/shopify';
|
||||
import { Metadata } from 'next';
|
||||
@ -25,10 +25,8 @@ export default async function HomePage() {
|
||||
<Suspense>
|
||||
<Hero />
|
||||
</Suspense>
|
||||
<div className="my-3 min-h-96">
|
||||
<Suspense>
|
||||
<HomePageContent />
|
||||
</Suspense>
|
||||
<div className="mx-auto flex min-h-96 max-w-7xl flex-col space-y-16 px-6 py-12 lg:px-8">
|
||||
<About />
|
||||
</div>
|
||||
<Suspense>
|
||||
<Footer />
|
||||
|
@ -3,7 +3,7 @@ import Tooltip from './tooltip';
|
||||
|
||||
function Banner() {
|
||||
return (
|
||||
<div className="flex min-h-10 w-full flex-col items-center justify-center gap-x-8 bg-primary p-2 text-sm font-medium text-dark md:flex-row md:p-0">
|
||||
<div className="flex min-h-10 w-full flex-col items-center justify-center gap-x-8 bg-primary p-2 text-sm font-medium text-white md:flex-row md:p-0">
|
||||
<span>
|
||||
Speak to a Specialist Now:{' '}
|
||||
<a href={`tel:${8882422605}`} className="ml-1">
|
||||
|
@ -4,6 +4,7 @@ import { Suspense } from 'react';
|
||||
import HomePageFilters, { HomePageFiltersPlaceholder } from './filters/hompage-filters';
|
||||
import DynamicHeroIcon from './hero-icon';
|
||||
import ImageDisplay from './page/image-display';
|
||||
import TrustPilot from './trust-pilot';
|
||||
|
||||
const Hero = async () => {
|
||||
const [offers, heroImage] = await Promise.all([
|
||||
@ -63,9 +64,21 @@ const Hero = async () => {
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<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 aria-hidden="true" className="absolute inset-0 bg-dark opacity-80" />
|
||||
<div className="flex flex-col gap-10 px-6 py-32 text-center sm:py-64 lg:px-0">
|
||||
<div className="mx-auto hidden max-w-[800px] items-center justify-between gap-10 md:flex">
|
||||
<div className="relative flex items-center">
|
||||
<Image src="/best-price.svg" alt="Best Price" width={100} height={90} />
|
||||
<div className="ml-4 text-left text-white">
|
||||
<p className="tracking-wide">Best Price Guarantee</p>
|
||||
<p className="max-w-[200px] text-sm tracking-wide">
|
||||
We will match or beat any competitor's pricing.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<TrustPilot />
|
||||
</div>
|
||||
<div className="relative mx-auto flex max-w-4xl flex-col items-center ">
|
||||
<Suspense fallback={<HomePageFiltersPlaceholder />}>
|
||||
<HomePageFilters />
|
||||
</Suspense>
|
||||
@ -73,6 +86,7 @@ const Hero = async () => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
42
components/home-page/about.tsx
Normal file
@ -0,0 +1,42 @@
|
||||
import Image from 'next/image';
|
||||
import ButtonLink from './button-link';
|
||||
import Tag from './tag';
|
||||
|
||||
const About = () => {
|
||||
return (
|
||||
<div className="grid grid-cols-1 items-start gap-x-0 gap-y-10 lg:grid-cols-2 lg:gap-x-10">
|
||||
<div className="col-span-1">
|
||||
<Image
|
||||
src="/about.png"
|
||||
alt="About Us"
|
||||
sizes="(min-width: 1920px) 588px, (min-width: 770px) 50vw, 100vw"
|
||||
width={588}
|
||||
height={405}
|
||||
className="w-full object-contain"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex h-full flex-col justify-between pb-2">
|
||||
<div className="mb-3 flex flex-col gap-3">
|
||||
<Tag text="About Us" />
|
||||
<h3 className="text-3xl font-semibold lg:text-4xl">Engine & Transmission Experts</h3>
|
||||
<p className="leading-6 text-slate-500">
|
||||
{`Car Part Planet is your ultimate destination for all your drivetrain replacement needs.
|
||||
Whether you're searching for a used engine, a remanufactured engine, a used
|
||||
transmission, a remanufactured transmission, or seeking expert drivetrain fitment
|
||||
guidance for your DIY replacement project, we've got you covered.`}
|
||||
</p>
|
||||
<p className="leading-6 text-slate-500">
|
||||
Our dedicated team is committed to sourcing top-quality parts at affordable prices for a
|
||||
wide range of gasoline and diesel vehicles, including those from American, Japanese, and
|
||||
various other manufacturers. Our extensive inventory includes popular engines and
|
||||
transmissions for GM, Chevrolet, Dodge, Ford, Chrysler, Jeep, Nissan, Toyota, Honda, and
|
||||
many other manufacturers.
|
||||
</p>
|
||||
</div>
|
||||
<ButtonLink link={{ text: 'Learn More', url: '/about' }} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default About;
|
18
components/home-page/button-link.tsx
Normal file
@ -0,0 +1,18 @@
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
|
||||
const ButtonLink = ({ link }: { link: { text: string; url: string } }) => {
|
||||
return (
|
||||
<Link href={link.url} className="relative w-fit px-5 py-2 text-white">
|
||||
<Image
|
||||
src="background.svg"
|
||||
alt="button background"
|
||||
className="absolute inset-0 -z-10 h-full w-full rounded object-cover"
|
||||
fill
|
||||
/>
|
||||
<div className="text-sm font-medium leading-5 tracking-wide">{link.text}</div>
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
||||
export default ButtonLink;
|
7
components/home-page/tag.tsx
Normal file
@ -0,0 +1,7 @@
|
||||
const Tag = ({ text }: { text: string }) => {
|
||||
return (
|
||||
<div className="w-fit border-l-4 border-l-primary bg-gray-100 px-2 py-0.5 text-sm">{text}</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Tag;
|
@ -20,16 +20,13 @@ export default async function Footer() {
|
||||
<div className="mx-auto flex w-full max-w-7xl flex-row flex-wrap items-start gap-6 px-6 py-12 text-sm md:gap-12 md:px-4 min-[1320px]:px-0">
|
||||
<div className="flex flex-col gap-1">
|
||||
<Link className="flex items-center text-white md:pt-1" href="/">
|
||||
<LogoSquare sm />
|
||||
<span className="font-league-spartan text-xl leading-tight tracking-tight">
|
||||
{SITE_NAME}
|
||||
</span>
|
||||
<LogoSquare dark />
|
||||
</Link>
|
||||
<a href={`tel:${8882422605}`} className="ml-4 text-white">
|
||||
<a href={`tel:${8882422605}`} className="ml-16 text-white">
|
||||
(888) 242-2605
|
||||
</a>
|
||||
<p className="ml-4">Monday - Friday 9:00am - 8:00pm EST</p>
|
||||
<p className="ml-4">Saturday 11:00am - 4:00pm EST</p>
|
||||
<p className="ml-16">Monday - Friday 9:00am - 8:00pm EST</p>
|
||||
<p className="ml-16">Saturday 11:00am - 4:00pm EST</p>
|
||||
</div>
|
||||
<Suspense
|
||||
fallback={
|
||||
|
@ -9,7 +9,6 @@ import { Suspense } from 'react';
|
||||
import MainMenu from './main-menu';
|
||||
import MobileMenu from './mobile-menu';
|
||||
import Search, { SearchSkeleton } from './search';
|
||||
const { SITE_NAME } = process.env;
|
||||
|
||||
export default async function Navbar() {
|
||||
const menu = await getMenu('main-menu');
|
||||
@ -26,12 +25,9 @@ export default async function Navbar() {
|
||||
<div className="flex w-full md:w-1/3">
|
||||
<Link
|
||||
href="/"
|
||||
className="mr-2 flex w-full items-center justify-center md:w-auto lg:mr-6"
|
||||
className="flex w-full items-center justify-center pl-3 sm:pl-0 md:w-auto lg:mr-6"
|
||||
>
|
||||
<LogoSquare />
|
||||
<div className="flex-none font-league-spartan text-xl font-semibold tracking-tight text-dark dark:text-white md:hidden md:text-2xl lg:block lg:text-3xl lg:leading-tight">
|
||||
{SITE_NAME}
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="hidden justify-center md:flex md:w-1/3">
|
||||
|
@ -1,15 +1,13 @@
|
||||
import clsx from 'clsx';
|
||||
import LogoIcon from './icons/logo';
|
||||
import Image from 'next/image';
|
||||
|
||||
export default function LogoSquare({ sm }: { sm?: boolean }) {
|
||||
export default function LogoSquare({ dark = false }: { dark?: boolean }) {
|
||||
return (
|
||||
<div className={clsx('flex h-[40px] w-[40px] flex-none items-center justify-center')}>
|
||||
<LogoIcon
|
||||
className={clsx('h-[20px] w-[20px]', {
|
||||
'lg:h-[26px] lg:w-[26px]': !sm,
|
||||
'lg:h-[20px]lg:w-[20px]': sm
|
||||
})}
|
||||
/>
|
||||
<div className="h-12 md:h-[55px]">
|
||||
{dark ? (
|
||||
<Image src="/dark-logo.svg" alt="Logo" width={327} height={61} className="h-full w-full" />
|
||||
) : (
|
||||
<Image src="/logo.svg" alt="Logo" width={327} height={61} className="h-full w-full" />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
34
components/trust-pilot.tsx
Normal file
@ -0,0 +1,34 @@
|
||||
'use client';
|
||||
|
||||
import { useEffect, useRef } from 'react';
|
||||
|
||||
const TrustPilot = () => {
|
||||
const ref = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
// @ts-ignore
|
||||
if (window.Trustpilot) {
|
||||
// @ts-ignore
|
||||
window.Trustpilot.loadFromElement(ref.current);
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
data-locale="en-US"
|
||||
data-template-id="53aa8807dec7e10d38f59f32"
|
||||
data-businessunit-id="58af38df0000ff00059d3de2"
|
||||
data-style-height="120px"
|
||||
data-style-width="100%"
|
||||
data-style-font-size="10px"
|
||||
data-theme="dark"
|
||||
>
|
||||
<a href="https://www.trustpilot.com/review/carpartplanet.com" target="_blank" rel="noopener">
|
||||
Trustpilot
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default TrustPilot;
|
5
lib/styles.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export const colors = {
|
||||
primary: '#EF6C02',
|
||||
dark: '#091242',
|
||||
secondary: '#EF6C02'
|
||||
};
|
BIN
public/about.png
Normal file
After Width: | Height: | Size: 457 KiB |
11
public/background.svg
Normal file
@ -0,0 +1,11 @@
|
||||
<svg width="194" height="61" viewBox="0 0 194 61" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="Background">
|
||||
<path id="Background_2" d="M0 4.83398C0 2.3487 2.01472 0.333984 4.5 0.333984H189.5C191.985 0.333984 194 2.3487 194 4.83398V55.834C194 58.3193 191.985 60.334 189.5 60.334H4.5C2.01472 60.334 0 58.3193 0 55.834V4.83398Z" fill="#091242"/>
|
||||
<mask id="mask0_13_1494" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="194" height="61">
|
||||
<path id="Background_3" d="M0 4.83398C0 2.3487 2.01472 0.333984 4.5 0.333984H189.5C191.985 0.333984 194 2.3487 194 4.83398V55.834C194 58.3193 191.985 60.334 189.5 60.334H4.5C2.01472 60.334 0 58.3193 0 55.834V4.83398Z" fill="#FFB629"/>
|
||||
</mask>
|
||||
<g mask="url(#mask0_13_1494)">
|
||||
<circle id="Pattern" cx="185" cy="62.334" r="26" fill="#1F2A69"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 823 B |
9
public/best-price.svg
Normal file
After Width: | Height: | Size: 55 KiB |
7
public/dark-logo.svg
Normal file
After Width: | Height: | Size: 19 KiB |
8
public/logo.svg
Normal file
After Width: | Height: | Size: 32 KiB |
@ -1,4 +1,5 @@
|
||||
const plugin = require('tailwindcss/plugin');
|
||||
import { colors } from './lib/styles.ts';
|
||||
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
@ -6,14 +7,9 @@ module.exports = {
|
||||
content: ['./app/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}'],
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: '#17E4BB',
|
||||
dark: '#08312B',
|
||||
secondary: '#12baa9'
|
||||
},
|
||||
colors,
|
||||
fontFamily: {
|
||||
sans: ['var(--font-geist-sans)'],
|
||||
'league-spartan': ['var(--font-league-spartan)']
|
||||
sans: ['var(--font-geist-sans)']
|
||||
},
|
||||
keyframes: {
|
||||
fadeIn: {
|
||||
|