Skip to content

Commit

Permalink
About section (#2)
Browse files Browse the repository at this point in the history
* fix: remove lineHeight whitespace

* feat: mobile about

* feat: tablet about

Fixing Typescript "Cannot find module" for svg assets:
[svgr d.ts](gregberge/svgr#551 (comment))

* feat: desktop about
  • Loading branch information
JoeDravarol committed Feb 14, 2023
1 parent a8e30b5 commit 3ec11cd
Show file tree
Hide file tree
Showing 8 changed files with 306 additions and 3 deletions.
9 changes: 9 additions & 0 deletions declarations.d.ts
@@ -0,0 +1,9 @@
declare module '*.svg?url' {
import type { ComponentType, SVGProps } from 'react';

type SvgComponent = ComponentType<SVGProps>;

const Svg: SvgComponent;

export = Svg;
}
6 changes: 6 additions & 0 deletions next.config.js
Expand Up @@ -4,8 +4,14 @@ const nextConfig = {
config.module.rules.push({
test: /\.svg$/i,
issuer: /\.[jt]sx?$/,
resourceQuery: { not: [/url/] }, // exclude react component if *.svg?url
use: ['@svgr/webpack'],
});
config.module.rules.push({
test: /\.svg$/i,
type: 'asset',
resourceQuery: /url/, // *.svg?url
});

return config;
},
Expand Down
4 changes: 2 additions & 2 deletions src/components/Container.tsx
Expand Up @@ -7,9 +7,9 @@ type Props = ContainerProps & {
component?: React.ElementType
}

const Container: React.FC<Props> = ({ children, ...rest }) => {
const Container: React.FC<Props> = ({ children, sx, ...rest }) => {
return (
<MuiContainer sx={{ fontSize: 0 }} {...rest}>
<MuiContainer sx={{ fontSize: 0, lineHeight: 0, ...sx }} {...rest}>
<PatternDivide />
{children}
</MuiContainer>
Expand Down
12 changes: 12 additions & 0 deletions src/config/theme.ts
Expand Up @@ -117,6 +117,18 @@ const theme = createTheme({
desktop: 1439,
},
},
components: {
MuiCssBaseline: {
styleOverrides: {
html: {
overflowX: 'hidden', // Prevent horizontal scrollbar
},
body: {
overflowX: 'hidden', // Prevent horizontal scrollbar
},
},
},
},
});

export default theme;
159 changes: 159 additions & 0 deletions src/features/About.tsx
@@ -0,0 +1,159 @@
import Box from '@mui/material/Box';
import { styled } from '@mui/material/styles';
import React from 'react';

import desktopEnjoyablePlaceSm from '@/assets/homepage/enjoyable-place-desktop.jpg';
import desktopEnjoyablePlaceMd from '@/assets/homepage/enjoyable-place-desktop@2x.jpg';
import mobileEnjoyablePlaceSm from '@/assets/homepage/enjoyable-place-mobile.jpg';
import mobileEnjoyablePlaceMd from '@/assets/homepage/enjoyable-place-mobile@2x.jpg';
import tabletEnjoyablePlaceSm from '@/assets/homepage/enjoyable-place-tablet.jpg';
import tabletEnjoyablePlaceMd from '@/assets/homepage/enjoyable-place-tablet@2x.jpg';
import desktopLocallySourceSm from '@/assets/homepage/locally-sourced-desktop.jpg';
import desktopLocallySourceMd from '@/assets/homepage/locally-sourced-desktop@2x.jpg';
import mobileLocallySourceSm from '@/assets/homepage/locally-sourced-mobile.jpg';
import mobileLocallySourceMd from '@/assets/homepage/locally-sourced-mobile@2x.jpg';
import tabletLocallySourceSm from '@/assets/homepage/locally-sourced-tablet.jpg';
import tabletLocallySourceMd from '@/assets/homepage/locally-sourced-tablet@2x.jpg';
import patternCurveTopLeft from '@/assets/patterns/pattern-curve-top-left.svg?url';
import patternCurveTopRight from '@/assets/patterns/pattern-curve-top-right.svg?url';
import patternLines from '@/assets/patterns/pattern-lines.svg?url';

import InfoCard from './InfoCard';

const StyledBox = styled(Box)(({ theme }) => ({
[theme.breakpoints.up('tablet')]: {
position: 'relative',
'&::before, &::after': {
content: '""',
width: 895, // default svg width
height: 320, // default svg height
backgroundImage: `url(${patternCurveTopRight})`,
position: 'absolute',
top: 196,
left: -516, // svgWidth - (tabletSize / 2) + adjustment
zIndex: 1,
},
'&::after': {
backgroundImage: `url(${patternCurveTopLeft})`,
top: 'revert',
left: 'revert',
right: -511, // svgWidth - (tabletSize / 2)
bottom: -118, // Last InfoCard bottom margin
},
'.bg-pattern::after': {
content: '""',
width: 160, // default svg width
height: 76, // default svg height
backgroundImage: `url(${patternLines})`,
position: 'absolute',
top: 228,
left: 471,
zIndex: 5,
},
[theme.breakpoints.up('desktop')]: {
width: 1110,
marginInline: 'auto',

'&::before': {
left: -165,
top: 320,
},
'&::after': {
right: -165,
bottom: 0,
},
'.bg-pattern picture': {
marginBottom: -80,
},
'.bg-pattern::after': {
left: 1064,
top: 282,
},
},
},
}));

const About: React.FC = () => {
const enjoyablePlace = {
title: 'Enjoyable place for all the family',
description: `
Our relaxed surroundings make dining with us a great experience for everyone. We can even arrange
a tour of the farm before your meal.
`,
img: {
src: mobileEnjoyablePlaceSm.src,
alt: 'Country landscape',
sources: [
{
srcSet: desktopEnjoyablePlaceMd.src,
media: '(min-width: 1920px)',
},
{
srcSet: desktopEnjoyablePlaceSm.src,
media: '(min-width: 1440px)',
},
{
srcSet: tabletEnjoyablePlaceMd.src,
media: '(min-width: 900px)',
},
{
srcSet: tabletEnjoyablePlaceSm.src,
media: '(min-width: 768px)',
},
{
srcSet: mobileEnjoyablePlaceMd.src,
media: '(min-width: 400px)',
},
],
},
};
const locallySourcedFood = {
title: 'The most locally sourced food',
description: `
All our ingredients come directly from our farm or local fishery. So you can be sure that you're eating
the freshest, most sustainable food.
`,
img: {
src: mobileLocallySourceSm.src,
alt: 'Country landscape',
sources: [
{
srcSet: desktopLocallySourceMd.src,
media: '(min-width: 1920px)',
},
{
srcSet: desktopLocallySourceSm.src,
media: '(min-width: 1440px)',
},
{
srcSet: tabletLocallySourceMd.src,
media: '(min-width: 900px)',
},
{
srcSet: tabletLocallySourceSm.src,
media: '(min-width: 768px)',
},
{
srcSet: mobileLocallySourceMd.src,
media: '(min-width: 400px)',
},
],
},
};

return (
<StyledBox>
<InfoCard
sx={{
marginTop: { mobile: '-72px', tablet: '-96px', desktop: '-70px' },
marginBottom: { desktop: '121px' },
}}
{...enjoyablePlace}
/>

<InfoCard className="bg-pattern" {...locallySourcedFood} />
</StyledBox>
);
};

export default About;
113 changes: 113 additions & 0 deletions src/features/InfoCard.tsx
@@ -0,0 +1,113 @@
import Card, { CardProps } from '@mui/material/Card';
import CardContent from '@mui/material/CardContent';
import CardMedia from '@mui/material/CardMedia';
import { styled } from '@mui/material/styles';
import Typography from '@mui/material/Typography';
import React from 'react';

import Container from '@/components/Container';

type Props = CardProps & {
title: string;
description: string;
img: {
src: string;
alt: string;
sources: {
srcSet: string;
media: string;
}[]
}
}

const StyledCard = styled(Card)(({ theme }) => ({
marginInline: theme.spacing(3),
marginBottom: 101,
overflow: 'revert', // Prevent square box shadow
position: 'relative',

[theme.breakpoints.up('tablet')]: {
marginInline: 'auto',
marginBottom: 118,
maxWidth: 573,
},
[theme.breakpoints.up('desktop')]: {
display: 'grid',
gridTemplateColumns: '540px 445px',
gridAutoFlow: 'column',
gridGap: 125,
alignItems: 'center',
margin: 'revert',

'&:nth-of-type(even)': {
gridTemplateColumns: '445px 540px',
picture: {
gridColumn: '2',
},
},
},
}));

const StyledCardMedia = styled(CardMedia)(() => ({
boxShadow: '0 75px 100px -50px rgba(56, 66, 85, 0.5)',
position: 'relative',
zIndex: 5,
})) as typeof CardMedia;

const StyledCardContent = styled(CardContent)(({ theme }) => ({
padding: 'revert',
'&:last-child': {
padding: 'revert',
},

[theme.breakpoints.up('tablet')]: {
maxWidth: 457,
marginInline: 'auto',
},
}));

const InfoCard: React.FC<Props> = ({ img, title, description, ...props }) => {
return (
<StyledCard elevation={0} {...props}>
<picture>
{img.sources.map((source, i) => (
<source key={`${img.alt}-${i}`} srcSet={source.srcSet} media={source.media} />
))}
<StyledCardMedia component="img" src={img.src} alt={img.alt} />
</picture>

<Container
sx={{
marginTop: { mobile: 6.375, tablet: 7 },
textAlign: { mobile: 'center', desktop: 'revert' },
}}
disableGutters
>
<StyledCardContent>
<Typography
variant="h2"
fontSize={{ mobile: '2rem', tablet: '3rem' }}
lineHeight={{ mobile: '2.5rem', tablet: '3rem' }}
letterSpacing={{ mobile: '-0.003rem', tablet: '-0.031rem' }}
px={{ mobile: 4, tablet: 4.25, desktop: 'revert' }}
pr={{ desktop: 6.75 }}
mt={{ mobile: 4.5, tablet: 4.875, desktop: 6.875 }}
mb={{ mobile: 1.625, tablet: 3.375 }}
>
{title}
</Typography>

<Typography
variant="body2"
fontSize={{ tablet: '1.25rem' }}
lineHeight={{ mobile: '1.625rem', tablet: '1.875rem' }}
>
{description}
</Typography>
</StyledCardContent>
</Container>
</StyledCard>
);
};

export default InfoCard;
4 changes: 4 additions & 0 deletions src/pages/index.tsx
@@ -1,5 +1,6 @@
import Head from 'next/head';

import About from '@/features/About';
import Hero from '@/features/Hero';

export default function Home() {
Expand All @@ -12,6 +13,9 @@ export default function Home() {
<link rel="icon" href="/favicon.ico" />
</Head>
<Hero />
<main>
<About />
</main>
</>
);
}
2 changes: 1 addition & 1 deletion tsconfig.json
Expand Up @@ -21,6 +21,6 @@
"@features/*": ["features/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"include": ["next-env.d.ts", "declarations.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}

0 comments on commit 3ec11cd

Please sign in to comment.