Parcourir la source

perf: on landing page - next links, featured products from DB

landing-page
ntasicc il y a 3 ans
Parent
révision
4d1d2a43ae

+ 5
- 2
components/hero/Hero.jsx Voir le fichier

import { Button, Typography } from '@mui/material'; import { Button, Typography } from '@mui/material';
import { Box } from '@mui/system'; import { Box } from '@mui/system';
import Image from 'next/image'; import Image from 'next/image';
import { useRouter } from 'next/router';
import { PRODUCTS_PAGE } from '../../constants/pages';


const Hero = () => { const Hero = () => {
const router = useRouter();
return ( return (
<> <>
<Box sx={{ display: 'flex', width: '100%', height: '100vh' }}> <Box sx={{ display: 'flex', width: '100%', height: '100vh' }}>
sx={{ sx={{
width: '100%', width: '100%',
display: 'flex', display: 'flex',
mt: 5,
}} }}
> >
<Button <Button
ml: 10, ml: 10,
color: 'white', color: 'white',
}} }}
onClick={() => router.push(PRODUCTS_PAGE)}
> >
{' '}
Explore the Shop Explore the Shop
</Button> </Button>
<Button <Button
/> />
} }
> >
{' '}
How to make How to make
</Button> </Button>
</Box> </Box>

+ 81
- 14
components/layout/footer/Footer.jsx Voir le fichier

import Box from '@mui/material/Box'; import Box from '@mui/material/Box';
import Typography from '@mui/material/Typography'; import Typography from '@mui/material/Typography';
import Image from 'next/image'; import Image from 'next/image';
const pages = ['Home', 'Menu', 'About', 'Store', 'Contact'];
import Link from 'next/link';
import { BASE_PAGE, PRODUCTS_PAGE } from '../../../constants/pages';

const pages = [
<Link key="home" href={BASE_PAGE}>
<Typography
textAlign="center"
sx={{
px: 1.5,
fontSize: 20,
fontWeight: 500,
color: 'black',
textDecoration: 'none',
cursor: 'pointer',
}}
>
Home
</Typography>
</Link>,
<Link key="menu" href={BASE_PAGE}>
<Typography
textAlign="center"
sx={{
px: 1.5,
fontSize: 20,
fontWeight: 500,
color: 'black',
textDecoration: 'none',
cursor: 'pointer',
}}
>
Menu
</Typography>
</Link>,
<Link key="about" href={BASE_PAGE}>
<Typography
textAlign="center"
sx={{
px: 1.5,
fontSize: 20,
fontWeight: 500,
color: 'black',
textDecoration: 'none',
cursor: 'pointer',
}}
>
About
</Typography>
</Link>,
<Link key="store" href={PRODUCTS_PAGE}>
<Typography
textAlign="center"
sx={{
px: 1.5,
fontSize: 20,
fontWeight: 500,
color: 'black',
textDecoration: 'none',
cursor: 'pointer',
}}
>
Store
</Typography>
</Link>,
<Link key="contact" href={BASE_PAGE}>
<Typography
textAlign="center"
sx={{
px: 1.5,
fontSize: 20,
fontWeight: 500,
color: 'black',
textDecoration: 'none',
cursor: 'pointer',
}}
>
Contact
</Typography>
</Link>,
];


const Footer = () => { const Footer = () => {
return ( return (
justifyContent: 'center', justifyContent: 'center',
}} }}
> >
{pages.map((page) => (
<Typography
key={page}
sx={{
fontSize: 20,
fontWeight: 500,
px: 1.5,
color: 'primary.main',
}}
>
{page}
</Typography>
))}
{pages.map((page) => page)}
</Box> </Box>
<Box <Box
sx={{ sx={{

+ 99
- 35
components/layout/navbar/Navbar.jsx Voir le fichier

import Box from '@mui/material/Box'; import Box from '@mui/material/Box';
import Typography from '@mui/material/Typography'; import Typography from '@mui/material/Typography';
import Image from 'next/image'; import Image from 'next/image';
const pages = ['Home', 'Menu', 'About', 'Store', 'Contact'];
import Link from 'next/link';
import { useRouter } from 'next/router';
import {
BASE_PAGE,
CART_PAGE,
PRODUCTS_PAGE,
PROFILE_PAGE,
} from '../../../constants/pages';


const Navbar = () => { const Navbar = () => {
// const { data: session } = useSession();
// const [anchorElNav, setAnchorElNav] = useState(null);
// const [anchorElUser, setAnchorElUser] = useState(null);

// const handleOpenNavMenu = (event) => {
// setAnchorElNav(event.currentTarget);
// };
// const handleOpenUserMenu = (event) => {
// setAnchorElUser(event.currentTarget);
// };

// const handleCloseNavMenu = () => {
// setAnchorElNav(null);
// };

// const handleCloseUserMenu = () => {
// setAnchorElUser(null);
// };

// function logoutHandler() {
// signOut();
// }
const router = useRouter();


return ( return (
<AppBar <AppBar
px: 10, px: 10,
}} }}
> >
{pages.map((page) => (
<Link key="home" href={BASE_PAGE}>
<Typography <Typography
key={page}
textAlign="center" textAlign="center"
sx={{ mx: 'auto', fontSize: 20, fontWeight: 500, color: 'black' }}
sx={{
mx: 'auto',
fontSize: 20,
fontWeight: 500,
color: router.pathname === '/' ? 'white' : 'black',
textDecoration: 'none',
cursor: 'pointer',
}}
> >
{page}
Home
</Typography> </Typography>
))}
</Link>

<Link key="menu" href={BASE_PAGE}>
<Typography
textAlign="center"
sx={{
mx: 'auto',
fontSize: 20,
fontWeight: 500,
color: router.pathname === '/' ? 'white' : 'black',
textDecoration: 'none',
cursor: 'pointer',
}}
>
Menu
</Typography>
</Link>

<Link key="about" href={BASE_PAGE}>
<Typography
textAlign="center"
sx={{
mx: 'auto',
fontSize: 20,
fontWeight: 500,
color: router.pathname === '/' ? 'white' : 'black',
textDecoration: 'none',
cursor: 'pointer',
}}
>
About
</Typography>
</Link>

<Link key="store" href={PRODUCTS_PAGE}>
<Typography
textAlign="center"
sx={{
mx: 'auto',
fontSize: 20,
fontWeight: 500,
color: router.pathname === '/' ? 'white' : 'black',
textDecoration: 'none',
cursor: 'pointer',
}}
>
Store
</Typography>
</Link>

<Link key="contact" href={BASE_PAGE}>
<Typography
textAlign="center"
sx={{
mx: 'auto',
fontSize: 20,
fontWeight: 500,
color: router.pathname === '/' ? 'white' : 'black',
textDecoration: 'none',
cursor: 'pointer',
}}
>
Contact
</Typography>
</Link>
</Box> </Box>
<Box <Box
sx={{ sx={{
<Box <Box
sx={{ sx={{
mx: 2, mx: 2,
cursor: 'pointer',
}} }}
> >
<Image
src="/images/profile.svg"
alt="profile"
width={24}
height={24}
/>
<Link key="home" href={PROFILE_PAGE}>
<Image
src="/images/profile.svg"
alt="profile"
width={24}
height={24}
/>
</Link>
</Box> </Box>
<Box <Box
sx={{ sx={{
mr: 6, mr: 6,
ml: 2, ml: 2,
cursor: 'pointer',
}} }}
> >
<Image src="/images/cart.svg" alt="cart" width={24} height={24} />
<Link key="home" href={CART_PAGE}>
<Image src="/images/cart.svg" alt="cart" width={24} height={24} />
</Link>
,
</Box> </Box>
</Box> </Box>
</Box> </Box>
</AppBar> </AppBar>
); );
}; };

export default Navbar; export default Navbar;

+ 18
- 3
components/products/featured-product/FeaturedProduct.jsx Voir le fichier

import ProductImage from './ProductImage'; import ProductImage from './ProductImage';
import ProductInfo from './ProductInfo'; import ProductInfo from './ProductInfo';


const FeaturedProduct = ({ bColor, image, side }) => {
const FeaturedProduct = ({ product, bColor, image, side }) => {
const data = { name: product.name, description: product.description };
return ( return (
<Box <Box
sx={{ sx={{
{side === 'left' ? ( {side === 'left' ? (
<ProductImage image={image}></ProductImage> <ProductImage image={image}></ProductImage>
) : ( ) : (
<ProductInfo bColor={bColor} side={side}></ProductInfo>
<ProductInfo bColor={bColor} side={side} data={data}></ProductInfo>
)} )}
{side === 'left' ? ( {side === 'left' ? (
<ProductInfo bColor={bColor} side={side}></ProductInfo>
<ProductInfo bColor={bColor} side={side} data={data}></ProductInfo>
) : ( ) : (
<ProductImage image={image}></ProductImage> <ProductImage image={image}></ProductImage>
)} )}
}; };


FeaturedProduct.propTypes = { FeaturedProduct.propTypes = {
product: PropType.shape({
category: PropType.string,
name: PropType.string,
image: PropType.string,
description: PropType.string,
place: PropType.string,
people: PropType.string,
process: PropType.string,
pairing: PropType.string,
available: PropType.Boolean,
isFeatured: PropType.Boolean,
price: PropType.number,
customID: PropType.string,
}),
bColor: PropType.string, bColor: PropType.string,
image: PropType.string, image: PropType.string,
side: PropType.string, side: PropType.string,

+ 9
- 6
components/products/featured-product/ProductInfo.jsx Voir le fichier

import Image from 'next/image'; import Image from 'next/image';
import PropType from 'prop-types'; import PropType from 'prop-types';


const ProductInfo = ({ bColor, side }) => {
const ProductInfo = ({ data, bColor, side }) => {
return ( return (
<Box <Box
sx={{ sx={{
pl: side === 'right' ? '10%' : 0, pl: side === 'right' ? '10%' : 0,
}} }}
> >
<Typography variant="h3" sx={{ height: 100, mt: 15, color: 'white' }}>
Frapuccino coffee
<Typography variant="h3" sx={{ height: 60, mt: 15, color: 'white' }}>
{data.name}
</Typography> </Typography>
<Box <Box
sx={{ sx={{
color: 'white', color: 'white',
}} }}
> >
If you drink coffee regulary you will know the difference between fresh
coffee and old coffee. Our goal is to provide the freshest coffee beans
in each day.
{data.description}
</Typography> </Typography>
<Box <Box
sx={{ sx={{
width: '100%', width: '100%',
display: 'flex', display: 'flex',
mt: 4,
}} }}
> >
<ButtonGroup <ButtonGroup
}; };


ProductInfo.propTypes = { ProductInfo.propTypes = {
data: PropType.shape({
name: PropType.string,
description: PropType.string,
}),
bColor: PropType.string, bColor: PropType.string,
side: PropType.string, side: PropType.string,
}; };

+ 32
- 11
components/products/featured-products-list/FeaturedPorductsList.jsx Voir le fichier

import { Box } from '@mui/system'; import { Box } from '@mui/system';
import PropType from 'prop-types';
import FeaturedProduct from '../featured-product/FeaturedProduct'; import FeaturedProduct from '../featured-product/FeaturedProduct';


const FeaturedProductsList = () => {
const FeaturedProductsList = ({ featuredProducts }) => {
return ( return (
<Box <Box
sx={{ sx={{
flexDirection: 'column', flexDirection: 'column',
}} }}
> >
<FeaturedProduct
bColor="dark"
image="/images/coffee-bag 1.png"
side="left"
></FeaturedProduct>
<FeaturedProduct
bColor="light"
image="/images/Item 2.png"
side="right"
></FeaturedProduct>
{featuredProducts.map((product, i) => {
return (
<FeaturedProduct
key={i}
product={product}
bColor={i % 2 === 0 ? 'dark' : 'light'}
image="/images/Item 2.png"
side={i % 2 === 0 ? 'left' : 'right'}
></FeaturedProduct>
);
})}
</Box> </Box>
); );
}; };


FeaturedProduct.propTypes = {
featuredProducts: PropType.arrayOf(
PropType.shape({
category: PropType.string,
name: PropType.string,
image: PropType.string,
description: PropType.string,
place: PropType.string,
people: PropType.string,
process: PropType.string,
pairing: PropType.string,
available: PropType.Boolean,
isFeatured: PropType.Boolean,
price: PropType.number,
customID: PropType.string,
})
),
};

export default FeaturedProductsList; export default FeaturedProductsList;

+ 1
- 0
constants/pages.js Voir le fichier

export const CART_PAGE = '/cart'; export const CART_PAGE = '/cart';
export const SHIPPING_PAGE = '/shipping'; export const SHIPPING_PAGE = '/shipping';
export const REVIEW_PAGE = '/review'; export const REVIEW_PAGE = '/review';
export const PRODUCTS_PAGE = '/products';
export const LOGIN_PAGE = '/auth'; export const LOGIN_PAGE = '/auth';
export const PROFILE_PAGE = '/profile'; export const PROFILE_PAGE = '/profile';
export const REGISTER_PAGE = '/auth/register'; export const REGISTER_PAGE = '/auth/register';

+ 5
- 5
pages/api/product/index.js Voir le fichier

if (productCount === 0) { if (productCount === 0) {
res.status(200).json({ res.status(200).json({
message: 'There are currently no products in our database.', message: 'There are currently no products in our database.',
Product: [],
ProductCount: 0,
product: [],
productCount: 0,
}); });
break; break;
} }


if ((pageIndex - 1) * 4 >= productCount) {
if ((pageIndex - 1) * 9 >= productCount) {
throw new Error('Page does not exist!'); throw new Error('Page does not exist!');
} }


const product = await Product.find({}) const product = await Product.find({})
.skip((pageIndex - 1) * 4)
.limit(4);
.skip((pageIndex - 1) * 9)
.limit(9);


if (!product) { if (!product) {
throw new Error('There are currently no products in our database.'); throw new Error('There are currently no products in our database.');

+ 1
- 1
pages/api/product/productIds.js Voir le fichier

if (productCount === 0) { if (productCount === 0) {
res.status(200).json({ res.status(200).json({
message: 'There are currently no products in our database.', message: 'There are currently no products in our database.',
ProductIds: [],
productIds: [],
}); });
break; break;
} }

+ 23
- 14
pages/index.js Voir le fichier

import Features from '../components/features/Features'; import Features from '../components/features/Features';
import Hero from '../components/hero/Hero'; import Hero from '../components/hero/Hero';
import FeaturedProductsList from '../components/products/featured-products-list/FeaturedPorductsList'; import FeaturedProductsList from '../components/products/featured-products-list/FeaturedPorductsList';
import { getFeaturedProducts } from '../requests/products/featuredProductsRequest';


const Home = () => {
const Home = (props) => {
return ( return (
<> <>
<Box sx={{ width: '100%', height: '100%' }}> <Box sx={{ width: '100%', height: '100%' }}>
<meta name="description" content="Random data with pagination..." /> <meta name="description" content="Random data with pagination..." />
</Head> </Head>
<Hero></Hero> <Hero></Hero>
<FeaturedProductsList></FeaturedProductsList>
<FeaturedProductsList
featuredProducts={props.featuredProducts}
></FeaturedProductsList>
<Features></Features> <Features></Features>
<CompanyInfo></CompanyInfo> <CompanyInfo></CompanyInfo>
</Box> </Box>
); );
}; };


// export async function getStaticProps({ locale }) {
// const queryClient = new QueryClient();

// await queryClient.prefetchQuery(['randomData', 1], () => getData(1));

// return {
// props: {
// dehydratedState: dehydrate(queryClient),
// ...(await serverSideTranslations(locale, ['pagination'])),
// },
// };
// }
export async function getStaticProps() {
try {
const { message, featuredProducts } = await getFeaturedProducts();
return {
props: {
message,
featuredProducts,
},
};
} catch (error) {
return {
props: {
errorMessage: error,
featuredProducts: [],
},
};
}
}


export default Home; export default Home;

Chargement…
Annuler
Enregistrer