Skip to content

Commit

Permalink
39 adding the next.js frontend app to the code base
Browse files Browse the repository at this point in the history
  • Loading branch information
xoscar committed Jul 26, 2022
1 parent 3e873e2 commit 290c7b8
Show file tree
Hide file tree
Showing 57 changed files with 1,094 additions and 354 deletions.
4 changes: 3 additions & 1 deletion src/web/.eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
"root": true,
"globals": {},
"rules": {
"@typescript-eslint/no-non-null-assertion": "off",
"react-hooks/exhaustive-deps": "warn",
"no-unused-vars": "error",
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": "error",
"max-len": [
"error",
{
Expand Down
10 changes: 8 additions & 2 deletions src/web/components/Ad/Ad.styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,16 @@ import RouterLink from 'next/link';

export const Ad = styled.section`
position: relative;
background-color: #ff9a9b;
font-size: 24px;
background-color: ${({ theme }) => theme.colors.otelYellow};
font-size: ${({ theme }) => theme.sizes.dMedium};
text-align: center;
padding: 48px;
* {
color: ${({ theme }) => theme.colors.white};
margin: 0;
cursor: pointer;
}
`;

export const Link = styled(RouterLink)`
Expand Down
4 changes: 3 additions & 1 deletion src/web/components/Ad/Ad.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ const Ad = () => {

return (
<S.Ad>
<S.Link href={redirectUrl}>{text}</S.Link>
<S.Link href={redirectUrl}>
<p>{text}</p>
</S.Link>
</S.Ad>
);
};
Expand Down
56 changes: 56 additions & 0 deletions src/web/components/Banner/Banner.styled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import styled from 'styled-components';
import Button from '../Button';

export const Banner = styled.div`
display: flex;
flex-direction: column;
${({ theme }) => theme.breakpoints.desktop} {
flex-direction: row-reverse;
padding-bottom: 38px;
background: ${({ theme }) => theme.colors.backgroundGray};
}
`;

export const BannerImg = styled.img.attrs({
src: '/images/Banner.png',
})`
width: 100%;
height: auto;
`;

export const ImageContainer = styled.div`
${({ theme }) => theme.breakpoints.desktop} {
min-width: 50%;
}
`;

export const TextContainer = styled.div`
padding: 20px;
${({ theme }) => theme.breakpoints.desktop} {
display: flex;
flex-direction: column;
justify-content: center;
align-items: start;
width: 50%;
padding: 100px 160px 100px 100px;
}
`;

export const Title = styled.h1`
font-size: ${({ theme }) => theme.sizes.mxLarge};
font-weight: ${({ theme }) => theme.fonts.bold};
${({ theme }) => theme.breakpoints.desktop} {
font-size: ${({ theme }) => theme.sizes.dxLarge};
}
`;

export const GoShoppingButton = styled(Button)`
width: 100%;
${({ theme }) => theme.breakpoints.desktop} {
width: auto;
}
`;
17 changes: 17 additions & 0 deletions src/web/components/Banner/Banner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import * as S from './Banner.styled';

const Banner = () => {
return (
<S.Banner>
<S.ImageContainer>
<S.BannerImg />
</S.ImageContainer>
<S.TextContainer>
<S.Title>The best telescopes to see the world closer</S.Title>
<S.GoShoppingButton>Go Shopping</S.GoShoppingButton>
</S.TextContainer>
</S.Banner>
);
};

export default Banner;
1 change: 1 addition & 0 deletions src/web/components/Banner/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './Banner';
23 changes: 17 additions & 6 deletions src/web/components/Button/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,32 @@
import styled, { css } from 'styled-components';

const Button = styled.button<{ $type?: 'primary' | 'secondary' }>`
background-color: #ce0631;
const Button = styled.button<{ $type?: 'primary' | 'secondary' | 'link' }>`
background-color: #5262a8;
color: white;
display: inline-block;
border: solid 1px #ce0631;
border: solid 1px #5262a8;
padding: 8px 16px;
outline: none;
font-size: 14px;
border-radius: 22px;
font-weight: 700;
font-size: 20px;
line-height: 27px;
border-radius: 10px;
height: 62px;
cursor: pointer;
${({ $type = 'primary' }) =>
$type === 'secondary' &&
css`
background: none;
color: #ce0631;
color: #5262a8;
`};
${({ $type = 'primary' }) =>
$type === 'link' &&
css`
background: none;
color: #5262a8;
border: none;
`};
`;

Expand Down
91 changes: 91 additions & 0 deletions src/web/components/CartDropdown/CartDropdown.styled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import Image from 'next/image';
import styled from 'styled-components';
import Button from '../Button';

export const CartDropdown = styled.div`
position: fixed;
top: 0;
right: 0;
width: 100%;
height: 100%;
max-height: 100%;
overflow-y: scroll;
padding: 25px;
display: flex;
flex-direction: column;
justify-content: space-between;
gap: 24px;
background: ${({ theme }) => theme.colors.white};
z-index: 1000;
border-radius: 5px;
box-shadow: 0 2px 2px 0 rgb(0 0 0 / 14%), 0 3px 1px -2px rgb(0 0 0 / 12%), 0 1px 5px 0 rgb(0 0 0 / 20%);
${({ theme }) => theme.breakpoints.desktop} {
position: absolute;
width: 400px;
top: 95px;
right: 17px;
max-height: 650px;
}
`;

export const Title = styled.h5`
margin: 0px;
font-size: ${({ theme }) => theme.sizes.mxLarge};
${({ theme }) => theme.breakpoints.desktop} {
font-size: ${({ theme }) => theme.sizes.dLarge};
}
`;

export const ItemList = styled.div`
${({ theme }) => theme.breakpoints.desktop} {
max-height: 450px;
overflow-y: scroll;
}
`;

export const Item = styled.div`
display: grid;
grid-template-columns: 29% 59%;
gap: 2%;
padding: 25px 0;
border-bottom: 1px solid ${({ theme }) => theme.colors.textLightGray};
`;

export const ItemImage = styled(Image).attrs({
width: '80px',
height: '80px',
})`
border-radius: 5px;
`;

export const ItemName = styled.p`
margin: 0px;
font-size: ${({ theme }) => theme.sizes.mLarge};
font-weight: ${({ theme }) => theme.fonts.regular};
`;

export const ItemDetails = styled.div`
display: flex;
flex-direction: column;
gap: 5px;
`;

export const ItemQuantity = styled(ItemName)`
font-size: ${({ theme }) => theme.sizes.mMedium};
`;

export const CartButton = styled(Button)``;

export const Header = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
${({ theme }) => theme.breakpoints.desktop} {
span {
display: none;
}
}
`;
60 changes: 60 additions & 0 deletions src/web/components/CartDropdown/CartDropdown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import Link from 'next/link';
import { useEffect, useRef } from 'react';
import { IProductCartItem } from '../../types/Cart';
import ProductPrice from '../ProductPrice';
import * as S from './CartDropdown.styled';

interface IProps {
isOpen: boolean;
onClose(): void;
productList: IProductCartItem[];
}

const CartDropdown = ({ productList, isOpen, onClose }: IProps) => {
const ref = useRef<HTMLDivElement>(null);

useEffect(() => {
const handleClickOutside = (event: Event) => {
if (ref.current && !ref.current.contains(event.target as Node)) {
onClose();
}
}
// Bind the event listener
document.addEventListener('mousedown', handleClickOutside);

return () => {
// Unbind the event listener on clean up
document.removeEventListener('mousedown', handleClickOutside);
};
}, [ref]);

return isOpen ? (
<S.CartDropdown ref={ref}>
<div>
<S.Header>
<S.Title>Shopping Cart</S.Title>
<span onClick={onClose}>Close</span>
</S.Header>
<S.ItemList>
{productList.map(
({ quantity, product: { name, picture, id, priceUsd = { nanos: 0, currencyCode: 'USD', units: 0 } } }) => (
<S.Item key={id}>
<S.ItemImage src={picture} alt={name} />
<S.ItemDetails>
<S.ItemName>{name}</S.ItemName>
<ProductPrice price={priceUsd} />
<S.ItemQuantity>Quantity: {quantity}</S.ItemQuantity>
</S.ItemDetails>
</S.Item>
)
)}
</S.ItemList>
</div>
<Link href="/cart">
<S.CartButton>Go to Shipping Data</S.CartButton>
</Link>
</S.CartDropdown>
) : null;
};

export default CartDropdown;
1 change: 1 addition & 0 deletions src/web/components/CartDropdown/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './CartDropdown';
31 changes: 16 additions & 15 deletions src/web/components/CartIcon/CartIcon.styled.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import Link from 'next/link';
import Image from 'next/image';
import styled from 'styled-components';

export const CartIcon = styled(Link).attrs({
as: 'a',
})`
export const CartIcon = styled.a`
position: relative;
display: block;
margin-left: 25px;
display: flex;
flex-flow: column;
align-items: center;
justify-content: center;
cursor: pointer;
`;

export const Icon = styled.img`
width: 20px;
height: 20px;
export const Icon = styled(Image).attrs({
width: '24px',
height: '24px',
})`
margin-bottom: 3px;
`;

Expand All @@ -24,12 +24,13 @@ export const ItemsCount = styled.span`
align-items: center;
justify-content: center;
position: absolute;
top: 24px;
left: 11px;
width: 16px;
height: 16px;
font-size: 11px;
border-radius: 4px 4px 0 4px;
color: white;
background-color: #853b5c;
top: 9px;
left: 15px;
width: 15px;
height: 15px;
font-size: ${({ theme }) => theme.sizes.nano};
border-radius: 50%;
border: 1px solid ${({ theme }) => theme.colors.white};
color: ${({ theme }) => theme.colors.white};
background: ${({ theme }) => theme.colors.otelRed};
`;
12 changes: 8 additions & 4 deletions src/web/components/CartIcon/CartIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
import { useState } from 'react';
import { useCart } from '../../providers/Cart.provider';
import CartDropdown from '../CartDropdown';
import * as S from './CartIcon.styled';

const CartIcon = () => {
const [isOpen, setIsOpen] = useState(false);
const {
cart: { items },
} = useCart();

return (
<S.CartIcon href="/cart">
<>
<>
<S.CartIcon onClick={() => !!items.length && setIsOpen(true)}>
<S.Icon src="/icons/Hipster_CartIcon.svg" alt="Cart icon" title="Cart" />
{!!items.length && <S.ItemsCount>{items.length}</S.ItemsCount>}
</>
</S.CartIcon>
</S.CartIcon>
<CartDropdown productList={items} isOpen={isOpen} onClose={() => setIsOpen(false)} />
</>
);
};

Expand Down
Loading

0 comments on commit 290c7b8

Please sign in to comment.