diff --git a/next.config.js b/next.config.js
index 515b2ae7c..d3ad64f4a 100644
--- a/next.config.js
+++ b/next.config.js
@@ -13,6 +13,10 @@ const isVendure = provider === 'vendure'
module.exports = withCommerceConfig({
commerce,
+ images: {
+ // todo: replace domains for images
+ domains: ['user-images.githubusercontent.com'],
+ },
i18n: {
locales: ['en-US', 'es'],
defaultLocale: 'en-US',
diff --git a/src/components/common/CartDrawer/CartDrawer.module.scss b/src/components/common/CartDrawer/CartDrawer.module.scss
new file mode 100644
index 000000000..126028d3c
--- /dev/null
+++ b/src/components/common/CartDrawer/CartDrawer.module.scss
@@ -0,0 +1,12 @@
+@import '../../../styles/utilities';
+
+
+.cartDrawer {
+ @apply flex flex-col h-full;
+ .body {
+ @apply overflow-y-auto overflow-x-hidden h-full custom-scroll;
+ }
+ .bottom {
+ padding-top: 1.6rem;
+ }
+}
\ No newline at end of file
diff --git a/src/components/common/CartDrawer/CartDrawer.tsx b/src/components/common/CartDrawer/CartDrawer.tsx
new file mode 100644
index 000000000..0a432bb65
--- /dev/null
+++ b/src/components/common/CartDrawer/CartDrawer.tsx
@@ -0,0 +1,35 @@
+import React from 'react';
+import { PRODUCT_CART_DATA_TEST } from 'src/utils/demo-data';
+import { DrawerCommon } from '..';
+import s from './CartDrawer.module.scss';
+import CartCheckoutButton from './components/CartCheckoutButton/CartCheckoutButton';
+import CartMessage from './components/CartMessage/CartMessage';
+import CartRecommendation from './components/CartRecommendation/CartRecommendation';
+import ProductsInCart from './components/ProductsInCart/ProductsInCart';
+
+interface Props {
+ visible: boolean
+ onClose: () => void
+}
+
+const CartDrawer = ({ visible, onClose }: Props) => {
+ return (
+
+
+
+ )
+}
+
+export default CartDrawer;
\ No newline at end of file
diff --git a/src/components/common/CartDrawer/components/CartCheckoutButton/CartCheckoutButton.module.scss b/src/components/common/CartDrawer/components/CartCheckoutButton/CartCheckoutButton.module.scss
new file mode 100644
index 000000000..3f90bffbd
--- /dev/null
+++ b/src/components/common/CartDrawer/components/CartCheckoutButton/CartCheckoutButton.module.scss
@@ -0,0 +1,6 @@
+.cartCheckoutButton {
+ padding: 1.6rem;
+ button {
+ width: 100%;
+ }
+}
diff --git a/src/components/common/CartDrawer/components/CartCheckoutButton/CartCheckoutButton.tsx b/src/components/common/CartDrawer/components/CartCheckoutButton/CartCheckoutButton.tsx
new file mode 100644
index 000000000..0cd7d00a2
--- /dev/null
+++ b/src/components/common/CartDrawer/components/CartCheckoutButton/CartCheckoutButton.tsx
@@ -0,0 +1,13 @@
+import React, { memo } from 'react';
+import { ButtonCommon } from 'src/components/common';
+import s from './CartCheckoutButton.module.scss';
+
+const CartCheckoutButton = memo(() => {
+ return (
+
+ Check out - Rp 120.500
+
+ )
+})
+
+export default CartCheckoutButton;
\ No newline at end of file
diff --git a/src/components/common/CartDrawer/components/CartMessage/CartMessage.module.scss b/src/components/common/CartDrawer/components/CartMessage/CartMessage.module.scss
new file mode 100644
index 000000000..18d6f96cc
--- /dev/null
+++ b/src/components/common/CartDrawer/components/CartMessage/CartMessage.module.scss
@@ -0,0 +1,15 @@
+@import "../../../../../styles/utilities";
+
+.cartMessage {
+ @apply flex bg-info;
+ padding: 1.2rem 1.6rem;
+ .text {
+ font-weight: bold;
+ margin-right: 0.8rem;
+ }
+ .icon {
+ svg path {
+ fill: var(--text-placeholder);
+ }
+ }
+}
diff --git a/src/components/common/CartDrawer/components/CartMessage/CartMessage.tsx b/src/components/common/CartDrawer/components/CartMessage/CartMessage.tsx
new file mode 100644
index 000000000..2cc85fb49
--- /dev/null
+++ b/src/components/common/CartDrawer/components/CartMessage/CartMessage.tsx
@@ -0,0 +1,18 @@
+import React, { memo } from 'react';
+import { IconInfo } from 'src/components/icons';
+import s from './CartMessage.module.scss';
+
+const CartMessage = memo(() => {
+ return (
+
+
+ You save - Rp 150
+
+
+
+
+
+ )
+})
+
+export default CartMessage;
\ No newline at end of file
diff --git a/src/components/common/CartDrawer/components/CartRecommendation/CartRecommendation.module.scss b/src/components/common/CartDrawer/components/CartRecommendation/CartRecommendation.module.scss
new file mode 100644
index 000000000..5b1a5ffa6
--- /dev/null
+++ b/src/components/common/CartDrawer/components/CartRecommendation/CartRecommendation.module.scss
@@ -0,0 +1,25 @@
+@import '../../../../../styles/utilities';
+
+.cartRecommendation {
+ @apply w-full bg-background-gray;
+ .top {
+ @apply flex justify-between items-center;
+ padding: 1.6rem;
+ .heading {
+ @apply font-bold text-active sm-headline;
+ }
+ }
+ .productCardWarpper {
+ padding-left: 1.6rem;
+ :global(.customArrow) {
+ @screen lg {
+ &:global(.leftArrow) {
+ left: calc(-6.4rem - 2rem);
+ }
+ &:global(.rightArrow) {
+ right: calc(-6.4rem - 2rem);
+ }
+ }
+ }
+ }
+}
diff --git a/src/components/common/CartDrawer/components/CartRecommendation/CartRecommendation.tsx b/src/components/common/CartDrawer/components/CartRecommendation/CartRecommendation.tsx
new file mode 100644
index 000000000..bbc40647e
--- /dev/null
+++ b/src/components/common/CartDrawer/components/CartRecommendation/CartRecommendation.tsx
@@ -0,0 +1,43 @@
+import { TOptionsEvents } from 'keen-slider';
+import React from 'react';
+import { CarouselCommon, ViewAllItem } from 'src/components/common';
+import ProductCard, { ProductCardProps } from 'src/components/common/ProductCard/ProductCard';
+import { ROUTE } from 'src/utils/constanst.utils';
+import { PRODUCT_DATA_TEST } from 'src/utils/demo-data';
+import s from './CartRecommendation.module.scss';
+
+const option: TOptionsEvents = {
+ slidesPerView: 2,
+ mode: 'free',
+ breakpoints: {
+ '(min-width: 640px)': {
+ slidesPerView: 1,
+ },
+ '(min-width: 768px)': {
+ slidesPerView: 2.5,
+ }
+ },
+}
+
+const CartRecommendation = () => {
+ return (
+
+
+
+
+ data={PRODUCT_DATA_TEST}
+ Component={ProductCard}
+ itemKey="cart-recommendation"
+ option={option}
+ />
+
+
+ )
+}
+
+export default CartRecommendation;
diff --git a/src/components/common/CartDrawer/components/ProductCartItem/ProductCartItem.module.scss b/src/components/common/CartDrawer/components/ProductCartItem/ProductCartItem.module.scss
new file mode 100644
index 000000000..e8bd0e3ec
--- /dev/null
+++ b/src/components/common/CartDrawer/components/ProductCartItem/ProductCartItem.module.scss
@@ -0,0 +1,50 @@
+@import "../../../../../styles/utilities";
+
+.productCartItem {
+ @apply grid;
+ grid-template-columns: 2fr 1fr;
+ padding-bottom: 1.6rem;
+ padding-top: 1.6rem;
+ border-bottom: 1px solid var(--border-line);
+ .info {
+ @apply flex;
+ .imgWrap {
+ width: 11rem;
+ height: 7.5rem;
+ margin-right: 1.6rem;
+ img {
+ object-fit: contain;
+ }
+ }
+ .detail {
+ min-height: 9rem;
+ .price {
+ margin-top: 0.8rem;
+ .old {
+ margin-bottom: 0.8rem;
+ .number {
+ margin-right: 0.8rem;
+ color: var(--text-label);
+ text-decoration: line-through;
+ }
+ }
+ .current {
+ @apply text-active font-bold sm-headline;
+ }
+ }
+ }
+ }
+
+ .actions {
+ @apply flex flex-col justify-between items-end;
+ margin-left: 1.6rem;
+ .iconDelete {
+ @apply cursor-pointer;
+ &:hover {
+ svg path {
+ fill: var(--negative);
+ }
+ }
+ }
+ }
+}
diff --git a/src/components/common/CartDrawer/components/ProductCartItem/ProductCartItem.tsx b/src/components/common/CartDrawer/components/ProductCartItem/ProductCartItem.tsx
new file mode 100644
index 000000000..7ec3ecbdb
--- /dev/null
+++ b/src/components/common/CartDrawer/components/ProductCartItem/ProductCartItem.tsx
@@ -0,0 +1,56 @@
+import React from 'react';
+import Link from 'next/link'
+import { QuanittyInput } from 'src/components/common';
+import { IconDelete } from 'src/components/icons';
+import { ROUTE } from 'src/utils/constanst.utils';
+import { ProductProps } from 'src/utils/types.utils';
+import ImgWithLink from '../../../ImgWithLink/ImgWithLink';
+import LabelCommon from '../../../LabelCommon/LabelCommon';
+import s from './ProductCartItem.module.scss';
+
+export interface ProductCartItempProps extends ProductProps {
+ quantity: number,
+}
+
+const ProductCartItem = ({ name, slug, weight, price, oldPrice, discount, imageSrc, quantity }: ProductCartItempProps) => {
+ return (
+
+ )
+}
+
+export default ProductCartItem;
\ No newline at end of file
diff --git a/src/components/common/CartDrawer/components/ProductsInCart/ProductsInCart.module.scss b/src/components/common/CartDrawer/components/ProductsInCart/ProductsInCart.module.scss
new file mode 100644
index 000000000..96df763b8
--- /dev/null
+++ b/src/components/common/CartDrawer/components/ProductsInCart/ProductsInCart.module.scss
@@ -0,0 +1,5 @@
+
+.productsInCart {
+ padding: 1.6rem 1.6rem 0 1.6rem;
+ margin-bottom: -1px;
+}
\ No newline at end of file
diff --git a/src/components/common/CartDrawer/components/ProductsInCart/ProductsInCart.tsx b/src/components/common/CartDrawer/components/ProductsInCart/ProductsInCart.tsx
new file mode 100644
index 000000000..5eddc1c25
--- /dev/null
+++ b/src/components/common/CartDrawer/components/ProductsInCart/ProductsInCart.tsx
@@ -0,0 +1,28 @@
+import React from 'react';
+import ProductCartItem, { ProductCartItempProps } from '../ProductCartItem/ProductCartItem';
+import s from './ProductsInCart.module.scss';
+
+interface Props {
+ data: ProductCartItempProps[]
+}
+
+const ProductsInCart = ({ data }: Props) => {
+ return (
+
+ {
+ data.map(item =>
)
+ }
+
+ )
+}
+
+export default ProductsInCart;
\ No newline at end of file
diff --git a/src/components/common/DrawerCommon/DrawerCommon.module.scss b/src/components/common/DrawerCommon/DrawerCommon.module.scss
index fc9de8a8a..18d992741 100644
--- a/src/components/common/DrawerCommon/DrawerCommon.module.scss
+++ b/src/components/common/DrawerCommon/DrawerCommon.module.scss
@@ -2,6 +2,7 @@
.drawerCommon {
@apply fixed flex justify-end transition-all duration-200;
+ overflow: hidden;
top: 0;
right: 0;
height: 100vh;
@@ -13,12 +14,15 @@
}
.inner {
- @apply bg-white;
+ @apply flex flex-col bg-white;
width: fit-content;
height: 100vh;
min-width: 48rem;
width: 100%;
margin-right: 0;
+ @screen md {
+ max-width: 50rem;
+ }
.top {
@apply flex justify-between items-center;
padding: 1.6rem;
@@ -37,6 +41,7 @@
}
.content {
overflow-y: auto;
+ height: 100%;
}
&.hide {
transform: translateX(110%);
diff --git a/src/components/common/ImgWithLink/ImgWithLink.module.scss b/src/components/common/ImgWithLink/ImgWithLink.module.scss
index b1587bfa6..413f96cdb 100644
--- a/src/components/common/ImgWithLink/ImgWithLink.module.scss
+++ b/src/components/common/ImgWithLink/ImgWithLink.module.scss
@@ -1,4 +1,9 @@
.imgWithLink {
- @apply w-full h-full;
- object-fit: cover;
+ position: relative;
+ min-width: 5rem;
+ width: 100%;
+ height: 100%;
+ img {
+ object-fit: cover;
+ }
}
diff --git a/src/components/common/ImgWithLink/ImgWithLink.tsx b/src/components/common/ImgWithLink/ImgWithLink.tsx
index 43ac1caa6..092322085 100644
--- a/src/components/common/ImgWithLink/ImgWithLink.tsx
+++ b/src/components/common/ImgWithLink/ImgWithLink.tsx
@@ -1,5 +1,6 @@
import React from 'react'
import s from './ImgWithLink.module.scss'
+import Image from 'next/image'
export interface ImgWithLinkProps {
src: string,
@@ -8,8 +9,9 @@ export interface ImgWithLinkProps {
const ImgWithLink = ({ src, alt }: ImgWithLinkProps) => {
return (
-
-
+
+
+
)
}
diff --git a/src/components/common/Layout/Layout.tsx b/src/components/common/Layout/Layout.tsx
index e7190f404..ea09855ff 100644
--- a/src/components/common/Layout/Layout.tsx
+++ b/src/components/common/Layout/Layout.tsx
@@ -2,7 +2,7 @@ import { CommerceProvider } from '@framework'
import { useRouter } from 'next/router'
import { FC } from 'react'
import { useModalCommon } from 'src/components/hooks'
-import { DrawerCommon, ScrollToTop } from '..'
+import { CartDrawer } from '..'
import Footer from '../Footer/Footer'
import Header from '../Header/Header'
import s from './Layout.module.scss'
@@ -30,8 +30,7 @@ const Layout: FC = ({ children }) => {
{children}
-
diff --git a/src/components/common/ListProductWithInfo/ListProductWithInfo.module.scss b/src/components/common/ListProductWithInfo/ListProductWithInfo.module.scss
index d2443dccc..ddd8ed901 100644
--- a/src/components/common/ListProductWithInfo/ListProductWithInfo.module.scss
+++ b/src/components/common/ListProductWithInfo/ListProductWithInfo.module.scss
@@ -11,7 +11,7 @@
padding-top: 5.6rem;
padding-bottom: 5.6rem;
border: none;
- background-color: #f5f4f2;
+ background-color: var(--background-gray);
}
.productsWrap {
@apply spacing-horizontal-left;
diff --git a/src/components/common/index.ts b/src/components/common/index.ts
index edbc5f0a6..e7bddb459 100644
--- a/src/components/common/index.ts
+++ b/src/components/common/index.ts
@@ -35,3 +35,4 @@ export { default as ModalCreateUserInfo} from './ModalCreateUserInfo/ModalCreate
export { default as ImgWithLink} from './ImgWithLink/ImgWithLink'
export { default as RecipeDetail} from './RecipeDetail/RecipeDetail'
export { default as DrawerCommon} from './DrawerCommon/DrawerCommon'
+export { default as CartDrawer} from './CartDrawer/CartDrawer'
diff --git a/src/components/icons/IconDelete.tsx b/src/components/icons/IconDelete.tsx
new file mode 100644
index 000000000..4daff3f80
--- /dev/null
+++ b/src/components/icons/IconDelete.tsx
@@ -0,0 +1,11 @@
+import React from 'react'
+
+const IconDelete = () => {
+ return (
+
+ )
+}
+
+export default IconDelete
diff --git a/src/components/icons/index.ts b/src/components/icons/index.ts
index 3430e52af..fcc739706 100644
--- a/src/components/icons/index.ts
+++ b/src/components/icons/index.ts
@@ -24,3 +24,4 @@ export { default as IconTime } from './IconTime'
export { default as IconPeople } from './IconPeople'
export { default as IconLocation } from './IconLocation'
export { default as IconClose } from './IconClose'
+export { default as IconDelete } from './IconDelete'
diff --git a/src/styles/_base.scss b/src/styles/_base.scss
index e90a6434f..e8719581f 100644
--- a/src/styles/_base.scss
+++ b/src/styles/_base.scss
@@ -6,7 +6,7 @@
--primary-lightest: #effaf4;
--info-dark: #00317a;
- --info: #297fff;
+ --info: #3468B7;
--info-border-line: #d6e7ff;
--info-light: #ebf3ff;
@@ -33,6 +33,7 @@
--disabled: #cccccc;
--border-line: #ebebeb;
--background: #fff;
+ --background-gray: #F5F4F2;
--gray: #f8f8f8;
--white: #fff;
--background-arrow:rgba(20, 20, 20, 0.05);
diff --git a/src/styles/_utilities.scss b/src/styles/_utilities.scss
index 56f9494ec..cc13ea3cf 100644
--- a/src/styles/_utilities.scss
+++ b/src/styles/_utilities.scss
@@ -120,6 +120,25 @@
font-family: var(--font-logo);
}
+ .custom-scroll {
+ overflow-y: auto;
+ &::-webkit-scrollbar-track {
+ background-color: var(--background-gray);
+ border-radius: 10px;
+ }
+
+ &::-webkit-scrollbar {
+ border-radius: 10px;
+ width: 6px;
+ background-color: var(--background-gray);
+ }
+
+ &::-webkit-scrollbar-thumb {
+ border-radius: 10px;
+ background-color: var(--primary)
+ }
+ }
+
.u-form {
.body {
> div {
diff --git a/src/utils/demo-data.ts b/src/utils/demo-data.ts
index b22668e15..64c8128ae 100644
--- a/src/utils/demo-data.ts
+++ b/src/utils/demo-data.ts
@@ -3,6 +3,7 @@ import { RecipeCardProps } from "src/components/common/RecipeCard/RecipeCard"
export const PRODUCT_DATA_TEST = [
{
name: 'Tomato',
+ slug: 'tomato',
weight: '250g',
category: 'VEGGIE',
price: 'Rp 27.500',
@@ -10,6 +11,7 @@ export const PRODUCT_DATA_TEST = [
},
{
name: 'Cucumber',
+ slug: 'tomato',
weight: '250g',
category: 'VEGGIE',
price: 'Rp 27.500',
@@ -17,6 +19,7 @@ export const PRODUCT_DATA_TEST = [
},
{
name: 'Carrot',
+ slug: 'tomato',
weight: '250g',
category: 'VEGGIE',
price: 'Rp 27.500',
@@ -24,6 +27,7 @@ export const PRODUCT_DATA_TEST = [
},
{
name: 'Salad',
+ slug: 'tomato',
weight: '250g',
category: 'VEGGIE',
price: 'Rp 27.500',
@@ -31,6 +35,7 @@ export const PRODUCT_DATA_TEST = [
},
{
name: 'Tomato',
+ slug: 'tomato',
weight: '250g',
category: 'VEGGIE',
price: 'Rp 27.500',
@@ -38,6 +43,7 @@ export const PRODUCT_DATA_TEST = [
},
{
name: 'Cucumber',
+ slug: 'tomato',
weight: '250g',
category: 'VEGGIE',
price: 'Rp 27.500',
@@ -45,6 +51,7 @@ export const PRODUCT_DATA_TEST = [
},
{
name: 'Tomato',
+ slug: 'tomato',
weight: '250g',
category: 'VEGGIE',
price: 'Rp 27.500',
@@ -52,6 +59,7 @@ export const PRODUCT_DATA_TEST = [
},
{
name: 'Cucumber',
+ slug: 'tomato',
weight: '250g',
category: 'VEGGIE',
price: 'Rp 27.500',
@@ -59,9 +67,55 @@ export const PRODUCT_DATA_TEST = [
},
]
+export const PRODUCT_CART_DATA_TEST = [
+ {
+ name: 'Tomato',
+ slug: 'tomato',
+ weight: '250g',
+ category: 'VEGGIE',
+ price: 'Rp 27.500',
+ imageSrc: "https://user-images.githubusercontent.com/76729908/131646211-d56b77ac-83f1-4dd2-b55c-e3f1e0ba4e49.png",
+ oldPrice: 'Rp 32.000',
+ discount: '15%',
+ quantity: 1,
+ },
+ {
+ name: 'Cucumber',
+ slug: 'tomato',
+ weight: '250g',
+ category: 'VEGGIE',
+ price: 'Rp 27.500',
+ imageSrc: "https://user-images.githubusercontent.com/76729908/131646211-d56b77ac-83f1-4dd2-b55c-e3f1e0ba4e49.png",
+ oldPrice: 'Rp 32.000',
+ discount: '15%',
+ quantity: 2,
+ },
+ {
+ name: 'Carrot',
+ slug: 'tomato',
+ weight: '250g',
+ category: 'VEGGIE',
+ price: 'Rp 27.500',
+ imageSrc: "https://user-images.githubusercontent.com/76729908/131646217-23b86160-45c9-4845-8dcc-b3e1a4483edd.png",
+ oldPrice: 'Rp 32.000',
+ discount: '20%',
+ quantity: 3,
+ },
+ {
+ name: 'Salad',
+ slug: 'tomato',
+ weight: '250g',
+ category: 'VEGGIE',
+ price: 'Rp 27.500',
+ imageSrc: "https://user-images.githubusercontent.com/76729908/131646221-aaa1d48d-bb80-470f-9400-ae2aa47285b6.png",
+ quantity: 1,
+ },
+]
+
export const INGREDIENT_DATA_TEST = [
{
name: 'Tomato',
+ slug: 'tomato',
weight: '250g',
category: 'VEGGIE',
price: 'Rp 27.500',
@@ -69,6 +123,7 @@ export const INGREDIENT_DATA_TEST = [
},
{
name: 'Cucumber',
+ slug: 'tomato',
weight: '250g',
category: 'VEGGIE',
price: 'Rp 27.500',
@@ -77,6 +132,7 @@ export const INGREDIENT_DATA_TEST = [
},
{
name: 'Carrot',
+ slug: 'tomato',
weight: '250g',
category: 'VEGGIE',
price: 'Rp 27.500',
@@ -84,6 +140,7 @@ export const INGREDIENT_DATA_TEST = [
},
{
name: 'Salad',
+ slug: 'tomato',
weight: '250g',
category: 'VEGGIE',
price: 'Rp 27.500',
@@ -92,6 +149,7 @@ export const INGREDIENT_DATA_TEST = [
},
{
name: 'Tomato',
+ slug: 'tomato',
weight: '250g',
category: 'VEGGIE',
price: 'Rp 27.500',
@@ -99,6 +157,7 @@ export const INGREDIENT_DATA_TEST = [
},
{
name: 'Cucumber',
+ slug: 'tomato',
weight: '250g',
category: 'VEGGIE',
price: 'Rp 27.500',
@@ -106,6 +165,7 @@ export const INGREDIENT_DATA_TEST = [
},
{
name: 'Tomato',
+ slug: 'tomato',
weight: '250g',
category: 'VEGGIE',
price: 'Rp 27.500',
@@ -113,6 +173,7 @@ export const INGREDIENT_DATA_TEST = [
},
{
name: 'Cucumber',
+ slug: 'tomato',
weight: '250g',
category: 'VEGGIE',
price: 'Rp 27.500',
diff --git a/src/utils/types.utils.ts b/src/utils/types.utils.ts
index 3d2383495..c87305f2b 100644
--- a/src/utils/types.utils.ts
+++ b/src/utils/types.utils.ts
@@ -1,8 +1,11 @@
export interface ProductProps {
- category: string
+ category?: string
name: string
+ slug: string
weight: string
price: string
+ oldPrice?: string
+ discount?: string
imageSrc: string
isNotSell?: boolean
}
@@ -17,7 +20,7 @@ export interface FeaturedProductProps {
export interface RecipeProps {
title: string
- description:string
+ description: string
imageSrc: string
}
diff --git a/tailwind.config.js b/tailwind.config.js
index 894a7ab6e..69ab1ade5 100644
--- a/tailwind.config.js
+++ b/tailwind.config.js
@@ -47,6 +47,7 @@ module.exports = {
'line': 'var(--border-line)',
'background': 'var(--background)',
+ 'background-gray': 'var(--background-gray)',
'white': 'var(--white)',
'background-arrow': 'var(--background-arrow)',