Skip to content

Commit

Permalink
Image card (#61)
Browse files Browse the repository at this point in the history
* initial image card

* image card component

* Fixed styles and optimized

* image first

* use ui components

* refactor

* refactor

* add sm
  • Loading branch information
nickbristow authored Nov 27, 2024
1 parent dce1fb7 commit 158c002
Show file tree
Hide file tree
Showing 7 changed files with 221 additions and 78 deletions.
Binary file added public/images/homepage-1.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 24 additions & 0 deletions src/app/_ui/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
interface TextProps {
children: React.ReactNode;
className?: string;
}

export function Heading({ children, className = '' }: TextProps) {
return (
<h2
className={`text-[1.5rem] font-bold text-[#224a58] xl:text-[2rem] ${className}`}
>
{children}
</h2>
);
}

export function Paragraph({ children, className = '' }: TextProps) {
return (
<p
className={`text-base font-normal leading-relaxed text-[#224a58] ${className}`}
>
{children}
</p>
);
}
32 changes: 32 additions & 0 deletions src/app/components/ImageCard/ImageCard.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
.imageCard {
background: var(--card-background);
@media (min-width: 1280px) {
border-radius: 2.5rem 0rem 2.5rem 0rem;
}
box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.1);

.imageContainer {
@media (min-width: 1280px) {
border-radius: 2.5rem 0rem 0rem 0rem;
img {
border-radius: 2.5rem 0rem 0rem 0rem;
}
}
@media (max-width: 1279px) {
margin-top: 2rem;
}
}

.textBox {
padding: 2.5rem;
}

.imageContainerReverse {
@media (min-width: 1280px) {
border-radius: 0rem 0rem 2.5rem 0rem;
img {
border-radius: 0rem 0rem 2.5rem 0rem;
}
}
}
}
34 changes: 34 additions & 0 deletions src/app/components/ImageCard/ImageCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import Image from 'next/image';
import { type CSSProperties } from 'react';
import { Container, ImageContainer, TextContainer } from './_ui';

interface ImageCardProps {
imageUrl: string;
imageAlt: string;
children: React.ReactNode;
imageFirst?: boolean;
imageStyle?: CSSProperties;
}

export const ImageCard = ({
imageUrl,
imageAlt,
children,
imageFirst = true,
imageStyle = {},
}: ImageCardProps) => (
<Container imageFirst={imageFirst}>
<ImageContainer imageFirst={imageFirst}>
<Image
className="h-full w-full object-cover"
src={imageUrl}
width={0}
height={0}
alt={imageAlt}
style={imageStyle}
priority={true}
/>
</ImageContainer>
<TextContainer imageFirst={imageFirst}>{children}</TextContainer>
</Container>
);
53 changes: 53 additions & 0 deletions src/app/components/ImageCard/_ui/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import classNames from 'classnames';
import styles from '../ImageCard.module.scss';

interface ContainerProps {
children: React.ReactNode;
imageFirst?: boolean;
}

export const Container = ({ children, imageFirst = true }: ContainerProps) => {
const imageFirstClass = imageFirst
? 'xl:grid-cols-[1fr_2fr]'
: 'xl:grid-cols-[2fr_1fr]';

return (
<div
className={classNames(
'grid grid-cols-1 justify-items-center gap-4 xl:justify-items-start xl:gap-14',
imageFirstClass,
styles.imageCard,
)}
>
{children}
</div>
);
};

interface ChildrenProps {
children: React.ReactNode;
imageFirst: boolean;
}

export const ImageContainer = ({ children, imageFirst }: ChildrenProps) => (
<div
className={classNames(
imageFirst ? styles.imageContainer : styles['image-box-reverse'],
'image-box h-full overflow-hidden sm:w-[30rem]',
imageFirst ? 'order-1' : 'order-1 xl:order-2',
)}
>
{children}
</div>
);

export const TextContainer = ({ children, imageFirst }: ChildrenProps) => (
<div
className={classNames(
'text-box order-2 flex flex-col gap-5 pb-10 pt-10',
imageFirst ? '' : 'xl:order-1 xl:pl-10',
)}
>
{children}
</div>
);
8 changes: 6 additions & 2 deletions src/app/custom-styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
text-wrap: balance;
}
}

/* --xl-breakpoint: 1280px; */
:root {
--background: #e7f2f580;
--background: #e7f2f5;
--card-background: #fbfbfb;
--foreground: #171717;
--header-teal: #224a58;
--background-light-blue: #dcecf3;
Expand All @@ -23,6 +24,9 @@ body {
background: var(--background);
font-family: 'Source Sans Pro', sans-serif;
}
.main-content {
background: var(--background);
}

.usa-logo a {
color: #ffffff;
Expand Down
148 changes: 72 additions & 76 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,67 +7,51 @@ import { ContentContainer } from './components/ContentContainer/ContentContainer
import { LinkButton } from './components/LinkButton/LinkButton';
import { useHeroInit } from './hooks/useHeroInit';
import { homePageHero, homeContent } from './data/home';
import { ImageCard } from './components/ImageCard/ImageCard';
import { Heading, Paragraph } from './_ui';

export default function Home() {
useHeroInit(homePageHero);
return (
<>
<DibbsSection />
<ValueSection />
<JurisdictionSection />
<InvitationCta />
</>
);
}

function DibbsSection() {
return (
<ContentContainer align>
<div className="grid grid-cols-1 justify-items-center gap-4 xl:grid-cols-[1fr_2fr] xl:justify-items-start xl:gap-14">
<div className="order-1">
<Image
className="xl:max-h-[20rem] xl:max-w-[30rem]"
src={`${basePath}/images/placeholder.png`}
width={480}
height={320}
alt="Placeholder"
/>
</div>
<div className="order-2 flex flex-col gap-5">
<h2 className="min-w-full text-center text-[1.5rem] font-bold text-[#224a58] xl:text-left xl:text-[2rem]">
Introducing Data Integration Building Blocks
</h2>
<div className="flex flex-col gap-2">
<p className="m-0 max-w-[39.7rem] p-0 text-base font-normal leading-relaxed text-[#224a58]">
{homeContent.dibbs.description}
</p>
<ul className="text-base font-semibold leading-relaxed text-[#224a58]">
{homeContent.dibbs.benefits.map((benefit, index) => (
<li className="min-w-full" key={`benefit-${index}`}>
{benefit}
</li>
))}
</ul>
</div>
</div>
const DibbsSection = () => (
<ContentContainer align>
<ImageCard
imageUrl={`${basePath}/images/homepage-1.jpeg`}
imageAlt="Data Integration Building Blocks illustration"
imageFirst={true}
imageStyle={{
transform: 'scale(1.4) translate(-8%, 3%)',
}}
>
<Heading className="min-w-full text-center xl:text-left">
Introducing Data Integration Building Blocks
</Heading>
<div className="flex flex-col gap-2">
<Paragraph className="m-0 max-w-[39.7rem] p-0">
{homeContent.dibbs.description}
</Paragraph>
<ul className="text-base font-semibold leading-relaxed text-[#224a58]">
{homeContent.dibbs.benefits.map((benefit, index) => (
<li className="min-w-full" key={`benefit-${index}`}>
{benefit}
</li>
))}
</ul>
</div>
</ContentContainer>
);
}
</ImageCard>
</ContentContainer>
);

function ValueSection() {
const ValueSection = () => {
const { valueSection } = homeContent;

return (
<ContentContainer align>
<div className="grid grid-cols-1 justify-items-center gap-4 xl:grid-cols-[2fr_3fr] xl:justify-items-start xl:gap-0">
<div className="order-2 justify-items-center xl:order-1 xl:justify-items-start">
<h2 className="text-center text-[1.5rem] font-bold text-[#224a58] xl:max-w-[23.25rem] xl:text-start xl:text-[2rem]">
<Heading className="text-center xl:max-w-[23.25rem] xl:text-start">
{valueSection.title}
</h2>
<p className="text-base font-normal leading-relaxed text-[#224a58] xl:max-w-[28.13rem]">
</Heading>
<Paragraph className="xl:max-w-[28.13rem]">
{valueSection.description}
</p>
</Paragraph>
<LinkButton href={valueSection.ctaHref} variant="primary">
{valueSection.ctaText}
</LinkButton>
Expand All @@ -78,15 +62,16 @@ function ValueSection() {
src={`${basePath}/images/placeholder.png`}
width={480}
height={320}
alt="Placeholder"
alt="Value section illustration"
priority
/>
</div>
</div>
</ContentContainer>
);
}
};

function JurisdictionSection() {
const JurisdictionSection = () => {
const { jurisdictions } = homeContent;

return (
Expand All @@ -95,12 +80,10 @@ function JurisdictionSection() {
<Grid row gap>
<Grid col={12}>
<div className="flex flex-col items-center">
<h2 className="text-center text-[1.5rem] font-bold text-[#224a58] xl:text-[2rem]">
{jurisdictions.title}
</h2>
<p className="text-center text-base font-normal leading-relaxed text-[#224a58]">
<Heading className="text-center">{jurisdictions.title}</Heading>
<Paragraph className="text-center">
{jurisdictions.description}
</p>
</Paragraph>
</div>
</Grid>
</Grid>
Expand All @@ -110,24 +93,37 @@ function JurisdictionSection() {
</div>
</>
);
}
};

const InvitationCta = () => (
<section className="usa-graphic-list usa-section usa-section--light-blue">
<GridContainer>
<div className="flex flex-col items-center justify-center gap-5 self-stretch">
<Heading className="self-stretch text-center">
{homeContent.cta.title}
</Heading>
<Paragraph className="self-stretch text-center">
{homeContent.cta.description}
</Paragraph>
<LinkButton href={homeContent.cta.ctaHref} variant="secondary">
{homeContent.cta.ctaText}
</LinkButton>
</div>
</GridContainer>
</section>
);

const Home = () => {
useHeroInit(homePageHero);

function InvitationCta() {
return (
<section className="usa-graphic-list usa-section usa-section--light-blue">
<GridContainer>
<div className="flex flex-col items-center justify-center gap-5 self-stretch">
<div className="self-stretch text-center text-[1.5rem] font-bold text-[#224a58] xl:text-[2rem]">
{homeContent.cta.title}
</div>
<div className="self-stretch text-center text-base font-normal leading-relaxed text-[#224a58]">
{homeContent.cta.description}
</div>
<LinkButton href={homeContent.cta.ctaHref} variant="secondary">
{homeContent.cta.ctaText}
</LinkButton>
</div>
</GridContainer>
</section>
<>
<DibbsSection />
<ValueSection />
<JurisdictionSection />
<InvitationCta />
</>
);
}
};

export default Home;

0 comments on commit 158c002

Please sign in to comment.