| @@ -1,8 +1,11 @@ | |||
| import { Button, Typography } from '@mui/material'; | |||
| import { Box } from '@mui/system'; | |||
| import Image from 'next/image'; | |||
| import { useRouter } from 'next/router'; | |||
| import { PRODUCTS_PAGE } from '../../constants/pages'; | |||
| const Hero = () => { | |||
| const router = useRouter(); | |||
| return ( | |||
| <> | |||
| <Box sx={{ display: 'flex', width: '100%', height: '100vh' }}> | |||
| @@ -41,6 +44,7 @@ const Hero = () => { | |||
| sx={{ | |||
| width: '100%', | |||
| display: 'flex', | |||
| mt: 5, | |||
| }} | |||
| > | |||
| <Button | |||
| @@ -52,8 +56,8 @@ const Hero = () => { | |||
| ml: 10, | |||
| color: 'white', | |||
| }} | |||
| onClick={() => router.push(PRODUCTS_PAGE)} | |||
| > | |||
| {' '} | |||
| Explore the Shop | |||
| </Button> | |||
| <Button | |||
| @@ -74,7 +78,6 @@ const Hero = () => { | |||
| /> | |||
| } | |||
| > | |||
| {' '} | |||
| How to make | |||
| </Button> | |||
| </Box> | |||
| @@ -1,7 +1,86 @@ | |||
| import Box from '@mui/material/Box'; | |||
| import Typography from '@mui/material/Typography'; | |||
| 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 = () => { | |||
| return ( | |||
| @@ -36,19 +115,7 @@ const Footer = () => { | |||
| 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 | |||
| sx={{ | |||
| @@ -2,31 +2,17 @@ import AppBar from '@mui/material/AppBar'; | |||
| import Box from '@mui/material/Box'; | |||
| import Typography from '@mui/material/Typography'; | |||
| 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 { 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 ( | |||
| <AppBar | |||
| @@ -50,15 +36,85 @@ const Navbar = () => { | |||
| px: 10, | |||
| }} | |||
| > | |||
| {pages.map((page) => ( | |||
| <Link key="home" href={BASE_PAGE}> | |||
| <Typography | |||
| key={page} | |||
| 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> | |||
| ))} | |||
| </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 | |||
| sx={{ | |||
| @@ -74,26 +130,34 @@ const Navbar = () => { | |||
| <Box | |||
| sx={{ | |||
| 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 | |||
| sx={{ | |||
| mr: 6, | |||
| 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> | |||
| </AppBar> | |||
| ); | |||
| }; | |||
| export default Navbar; | |||
| @@ -3,7 +3,8 @@ import PropType from 'prop-types'; | |||
| import ProductImage from './ProductImage'; | |||
| import ProductInfo from './ProductInfo'; | |||
| const FeaturedProduct = ({ bColor, image, side }) => { | |||
| const FeaturedProduct = ({ product, bColor, image, side }) => { | |||
| const data = { name: product.name, description: product.description }; | |||
| return ( | |||
| <Box | |||
| sx={{ | |||
| @@ -17,10 +18,10 @@ const FeaturedProduct = ({ bColor, image, side }) => { | |||
| {side === 'left' ? ( | |||
| <ProductImage image={image}></ProductImage> | |||
| ) : ( | |||
| <ProductInfo bColor={bColor} side={side}></ProductInfo> | |||
| <ProductInfo bColor={bColor} side={side} data={data}></ProductInfo> | |||
| )} | |||
| {side === 'left' ? ( | |||
| <ProductInfo bColor={bColor} side={side}></ProductInfo> | |||
| <ProductInfo bColor={bColor} side={side} data={data}></ProductInfo> | |||
| ) : ( | |||
| <ProductImage image={image}></ProductImage> | |||
| )} | |||
| @@ -29,6 +30,20 @@ const FeaturedProduct = ({ bColor, image, side }) => { | |||
| }; | |||
| 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, | |||
| image: PropType.string, | |||
| side: PropType.string, | |||
| @@ -3,7 +3,7 @@ import { Box } from '@mui/system'; | |||
| import Image from 'next/image'; | |||
| import PropType from 'prop-types'; | |||
| const ProductInfo = ({ bColor, side }) => { | |||
| const ProductInfo = ({ data, bColor, side }) => { | |||
| return ( | |||
| <Box | |||
| sx={{ | |||
| @@ -15,8 +15,8 @@ const ProductInfo = ({ bColor, side }) => { | |||
| 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> | |||
| <Box | |||
| sx={{ | |||
| @@ -38,14 +38,13 @@ const ProductInfo = ({ bColor, side }) => { | |||
| 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> | |||
| <Box | |||
| sx={{ | |||
| width: '100%', | |||
| display: 'flex', | |||
| mt: 4, | |||
| }} | |||
| > | |||
| <ButtonGroup | |||
| @@ -105,6 +104,10 @@ const ProductInfo = ({ bColor, side }) => { | |||
| }; | |||
| ProductInfo.propTypes = { | |||
| data: PropType.shape({ | |||
| name: PropType.string, | |||
| description: PropType.string, | |||
| }), | |||
| bColor: PropType.string, | |||
| side: PropType.string, | |||
| }; | |||
| @@ -1,7 +1,8 @@ | |||
| import { Box } from '@mui/system'; | |||
| import PropType from 'prop-types'; | |||
| import FeaturedProduct from '../featured-product/FeaturedProduct'; | |||
| const FeaturedProductsList = () => { | |||
| const FeaturedProductsList = ({ featuredProducts }) => { | |||
| return ( | |||
| <Box | |||
| sx={{ | |||
| @@ -11,18 +12,38 @@ const FeaturedProductsList = () => { | |||
| 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> | |||
| ); | |||
| }; | |||
| 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; | |||
| @@ -3,6 +3,7 @@ export const CHECKOUT_PAGE = '/checkout'; | |||
| export const CART_PAGE = '/cart'; | |||
| export const SHIPPING_PAGE = '/shipping'; | |||
| export const REVIEW_PAGE = '/review'; | |||
| export const PRODUCTS_PAGE = '/products'; | |||
| export const LOGIN_PAGE = '/auth'; | |||
| export const PROFILE_PAGE = '/profile'; | |||
| export const REGISTER_PAGE = '/auth/register'; | |||
| @@ -23,19 +23,19 @@ async function handler(req, res) { | |||
| if (productCount === 0) { | |||
| res.status(200).json({ | |||
| message: 'There are currently no products in our database.', | |||
| Product: [], | |||
| ProductCount: 0, | |||
| product: [], | |||
| productCount: 0, | |||
| }); | |||
| break; | |||
| } | |||
| if ((pageIndex - 1) * 4 >= productCount) { | |||
| if ((pageIndex - 1) * 9 >= productCount) { | |||
| throw new Error('Page does not exist!'); | |||
| } | |||
| const product = await Product.find({}) | |||
| .skip((pageIndex - 1) * 4) | |||
| .limit(4); | |||
| .skip((pageIndex - 1) * 9) | |||
| .limit(9); | |||
| if (!product) { | |||
| throw new Error('There are currently no products in our database.'); | |||
| @@ -14,7 +14,7 @@ async function handler(req, res) { | |||
| if (productCount === 0) { | |||
| res.status(200).json({ | |||
| message: 'There are currently no products in our database.', | |||
| ProductIds: [], | |||
| productIds: [], | |||
| }); | |||
| break; | |||
| } | |||
| @@ -4,8 +4,9 @@ import CompanyInfo from '../components/company-info/CompanyInfo'; | |||
| import Features from '../components/features/Features'; | |||
| import Hero from '../components/hero/Hero'; | |||
| import FeaturedProductsList from '../components/products/featured-products-list/FeaturedPorductsList'; | |||
| import { getFeaturedProducts } from '../requests/products/featuredProductsRequest'; | |||
| const Home = () => { | |||
| const Home = (props) => { | |||
| return ( | |||
| <> | |||
| <Box sx={{ width: '100%', height: '100%' }}> | |||
| @@ -14,7 +15,9 @@ const Home = () => { | |||
| <meta name="description" content="Random data with pagination..." /> | |||
| </Head> | |||
| <Hero></Hero> | |||
| <FeaturedProductsList></FeaturedProductsList> | |||
| <FeaturedProductsList | |||
| featuredProducts={props.featuredProducts} | |||
| ></FeaturedProductsList> | |||
| <Features></Features> | |||
| <CompanyInfo></CompanyInfo> | |||
| </Box> | |||
| @@ -22,17 +25,23 @@ const Home = () => { | |||
| ); | |||
| }; | |||
| // 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; | |||