mirror of
https://github.com/vercel/commerce.git
synced 2025-07-22 12:24:18 +00:00
🔀 merge: branch 'common' of https://github.com/KieIO/grocery-vercel-commerce into m6-quangnhanimproveui
:%s
This commit is contained in:
3
next-env.d.ts
vendored
3
next-env.d.ts
vendored
@@ -1,3 +1,6 @@
|
|||||||
/// <reference types="next" />
|
/// <reference types="next" />
|
||||||
/// <reference types="next/types/global" />
|
/// <reference types="next/types/global" />
|
||||||
/// <reference types="next/image-types/global" />
|
/// <reference types="next/image-types/global" />
|
||||||
|
|
||||||
|
// NOTE: This file should not be edited
|
||||||
|
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
||||||
|
9
pages/_error.tsx
Normal file
9
pages/_error.tsx
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { Layout } from 'src/components/common'
|
||||||
|
import { ErrorContent } from 'src/components/modules/error-page'
|
||||||
|
|
||||||
|
export default function NotFound() {
|
||||||
|
return (
|
||||||
|
<ErrorContent/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
NotFound.Layout = Layout
|
@@ -6,6 +6,7 @@ import MenuNavigationProductList from 'src/components/common/MenuNavigationProdu
|
|||||||
// import { RecipeListPage } from 'src/components/modules/recipes';
|
// import { RecipeListPage } from 'src/components/modules/recipes';
|
||||||
import { OPTION_ALL, QUERY_KEY, ROUTE } from 'src/utils/constanst.utils';
|
import { OPTION_ALL, QUERY_KEY, ROUTE } from 'src/utils/constanst.utils';
|
||||||
import { useModalCommon } from 'src/components/hooks';
|
import { useModalCommon } from 'src/components/hooks';
|
||||||
|
|
||||||
const CATEGORY = [
|
const CATEGORY = [
|
||||||
{
|
{
|
||||||
name: 'All',
|
name: 'All',
|
||||||
@@ -33,7 +34,6 @@ const CATEGORY = [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
const BRAND = [
|
const BRAND = [
|
||||||
|
|
||||||
{
|
{
|
||||||
name: 'Maggi',
|
name: 'Maggi',
|
||||||
link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=veggie`,
|
link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=veggie`,
|
||||||
@@ -67,15 +67,14 @@ const FEATURED = [
|
|||||||
link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=viewed`,
|
link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=viewed`,
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
import CheckoutSuccess from 'src/components/modules/checkout/CheckoutSuccess/CheckoutSuccess'
|
||||||
|
import LoadingCommon from 'src/components/common/LoadingCommon/LoadingCommon'
|
||||||
|
import SkeletonParagraph from 'src/components/common/SkeletonCommon/SkeletonParagraph/SkeletonParagraph'
|
||||||
|
import SkeletonImage from 'src/components/common/SkeletonCommon/SkeletonImage/SkeletonImage'
|
||||||
|
|
||||||
export default function Test() {
|
export default function Test() {
|
||||||
const { visible: visibleMenuFilter, openModal, closeModal: closeMenuFilter } = useModalCommon({ initialValue: false })
|
|
||||||
const toggle = () => {
|
|
||||||
if (visibleMenuFilter) {
|
|
||||||
closeMenuFilter()
|
|
||||||
} else {
|
|
||||||
openModal()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="shape-common-border">
|
<div className="shape-common-border">
|
||||||
|
@@ -8,7 +8,7 @@ interface Props {
|
|||||||
|
|
||||||
const option = {
|
const option = {
|
||||||
slidesPerView: 1,
|
slidesPerView: 1,
|
||||||
breakpoints: {}
|
mode: 'free',
|
||||||
}
|
}
|
||||||
const Banner = memo(({ data }: Props) => {
|
const Banner = memo(({ data }: Props) => {
|
||||||
if (data.length === 1) {
|
if (data.length === 1) {
|
||||||
|
@@ -6,20 +6,28 @@
|
|||||||
left: 0;
|
left: 0;
|
||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
margin-bottom: 3.2rem;
|
margin-bottom: 3.2rem;
|
||||||
@screen md {
|
|
||||||
@apply relative;
|
|
||||||
}
|
|
||||||
&.full {
|
&.full {
|
||||||
@apply shadow-none;
|
@apply shadow-none;
|
||||||
border: 1px solid var(--border-line);
|
|
||||||
}
|
}
|
||||||
.menu {
|
.menu {
|
||||||
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
|
||||||
padding-left: 3.2rem;
|
padding-left: 3.2rem;
|
||||||
padding-right: 3.2rem;
|
padding-right: 3.2rem;
|
||||||
}
|
}
|
||||||
.logo {
|
.logo {
|
||||||
@apply font-logo;
|
@apply font-logo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@screen md {
|
||||||
|
@apply relative;
|
||||||
|
&.full {
|
||||||
|
border: 1px solid var(--border-line);
|
||||||
|
}
|
||||||
|
.menu {
|
||||||
|
@apply shadow-none;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.headerSticky {
|
.headerSticky {
|
||||||
|
@@ -1,4 +1,3 @@
|
|||||||
import classNames from 'classnames'
|
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import { memo, useMemo } from 'react'
|
import { memo, useMemo } from 'react'
|
||||||
@@ -37,6 +36,10 @@ const HeaderMenu = memo(({ visibleFilter,openModalAuthen, openModalInfo, toggleF
|
|||||||
link: '/account-not-login',
|
link: '/account-not-login',
|
||||||
name: 'Account Not Login',
|
name: 'Account Not Login',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
link: ROUTE.NOTIFICATION,
|
||||||
|
name: 'Notifications',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
link: ROUTE.ACCOUNT,
|
link: ROUTE.ACCOUNT,
|
||||||
name: 'Account',
|
name: 'Account',
|
||||||
|
@@ -25,7 +25,7 @@ const OPTION_MENU = [
|
|||||||
isMarked: false,
|
isMarked: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
link: `${ROUTE.ACCOUNT}?${QUERY_KEY.TAB}=${ACCOUNT_TAB.NOTIFICATION}`,
|
link: ROUTE.NOTIFICATION,
|
||||||
name: 'Notifications',
|
name: 'Notifications',
|
||||||
icon: <IconNoti />,
|
icon: <IconNoti />,
|
||||||
isMarked: true,
|
isMarked: true,
|
||||||
|
@@ -3,7 +3,7 @@ import { useRouter } from 'next/router'
|
|||||||
import { FC } from 'react'
|
import { FC } from 'react'
|
||||||
import { useModalCommon } from 'src/components/hooks'
|
import { useModalCommon } from 'src/components/hooks'
|
||||||
import { BRAND, CATEGORY, FEATURED } from 'src/utils/constanst.utils'
|
import { BRAND, CATEGORY, FEATURED } from 'src/utils/constanst.utils'
|
||||||
import { CustomShapeSvg } from '..'
|
import { CustomShapeSvg, ScrollToTop } from '..'
|
||||||
import Footer from '../Footer/Footer'
|
import Footer from '../Footer/Footer'
|
||||||
import Header from '../Header/Header'
|
import Header from '../Header/Header'
|
||||||
import MenuNavigationProductList from '../MenuNavigationProductList/MenuNavigationProductList'
|
import MenuNavigationProductList from '../MenuNavigationProductList/MenuNavigationProductList'
|
||||||
@@ -34,6 +34,7 @@ const Layout: FC<Props> = ({ children }) => {
|
|||||||
|
|
||||||
<CustomShapeSvg/>
|
<CustomShapeSvg/>
|
||||||
<div className={s.filter}><MenuNavigationProductList categories={CATEGORY} brands={BRAND} featured={FEATURED} visible={visibleFilter} onClose={closeFilter}/> </div>
|
<div className={s.filter}><MenuNavigationProductList categories={CATEGORY} brands={BRAND} featured={FEATURED} visible={visibleFilter} onClose={closeFilter}/> </div>
|
||||||
|
<ScrollToTop visibilityHeight={1500} />
|
||||||
<Footer />
|
<Footer />
|
||||||
</div>
|
</div>
|
||||||
</CommerceProvider>
|
</CommerceProvider>
|
||||||
|
@@ -0,0 +1,24 @@
|
|||||||
|
@import '../../../styles/utilities';
|
||||||
|
|
||||||
|
.wrapper {
|
||||||
|
@apply text-center;
|
||||||
|
|
||||||
|
.loadingCommon {
|
||||||
|
@apply bg-white;
|
||||||
|
height: 7rem;
|
||||||
|
width: 7rem;
|
||||||
|
animation: spin 2s linear infinite;
|
||||||
|
margin: auto;
|
||||||
|
background: url('./assets/carrot.png') top 50% left 50% no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
@apply font-bold;
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
0% { transform: rotate(0deg); }
|
||||||
|
100% { transform: rotate(360deg); }
|
||||||
|
}
|
15
src/components/common/LoadingCommon/LoadingCommon.tsx
Normal file
15
src/components/common/LoadingCommon/LoadingCommon.tsx
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import React from "react";
|
||||||
|
import s from './LoadingCommon.module.scss'
|
||||||
|
|
||||||
|
const LoadingCommon = () => {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={s.wrapper}>
|
||||||
|
<div className={s.loadingCommon}>
|
||||||
|
</div>
|
||||||
|
<p className={s.text}>Loading...</p>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default LoadingCommon
|
BIN
src/components/common/LoadingCommon/assets/carrot.png
Normal file
BIN
src/components/common/LoadingCommon/assets/carrot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
@@ -1,20 +1,20 @@
|
|||||||
@import '../../../styles/utilities';
|
@import "../../../styles/utilities";
|
||||||
|
|
||||||
.scrollToTop {
|
.scrollToTop {
|
||||||
@apply hidden;
|
@apply hidden;
|
||||||
|
z-index: 9999;
|
||||||
|
|
||||||
@screen md {
|
@screen md {
|
||||||
&.show {
|
&.show {
|
||||||
@apply block rounded-lg fixed cursor-pointer;
|
@apply block rounded-lg fixed cursor-pointer;
|
||||||
right: 11.2rem;
|
right: 6.4rem;
|
||||||
bottom: 21.6rem;
|
bottom: 21.6rem;
|
||||||
width: 6.4rem;
|
width: 6.4rem;
|
||||||
height: 6.4rem;
|
height: 6.4rem;
|
||||||
background-color: var(--border-line);
|
background-color: var(--border-line);
|
||||||
|
@screen lg {
|
||||||
|
right: 11.2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.hide {
|
|
||||||
@apply hidden;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,44 +1,41 @@
|
|||||||
import React, { useState, useEffect, MutableRefObject } from 'react'
|
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import ArrowUp from '../../icons/IconArrowUp'
|
||||||
import s from './ScrollToTop.module.scss'
|
import s from './ScrollToTop.module.scss'
|
||||||
|
|
||||||
import ArrowUp from '../../icons/IconArrowUp'
|
|
||||||
|
|
||||||
interface ScrollToTopProps {
|
interface ScrollToTopProps {
|
||||||
visibilityHeight?: number;
|
visibilityHeight?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ScrollToTop = ({ visibilityHeight=450 }: ScrollToTopProps) => {
|
const ScrollToTop = ({ visibilityHeight = 450 }: ScrollToTopProps) => {
|
||||||
|
const [showScrollToTop, setShowScrollToTop] = useState<boolean>();
|
||||||
const [scrollPosition, setSrollPosition] = useState(0);
|
|
||||||
const [showScrollToTop, setShowScrollToTop] = useState("hide");
|
|
||||||
|
|
||||||
function handleVisibleButton() {
|
function handleVisibleButton() {
|
||||||
const position = window.pageYOffset;
|
const scrollPosition = window.scrollY;
|
||||||
setSrollPosition(position);
|
|
||||||
|
|
||||||
if (scrollPosition > visibilityHeight) {
|
if (scrollPosition > visibilityHeight) {
|
||||||
return setShowScrollToTop("show")
|
setShowScrollToTop(true)
|
||||||
} else if (scrollPosition < visibilityHeight) {
|
} else {
|
||||||
return setShowScrollToTop("hide");
|
setShowScrollToTop(false)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
window.addEventListener("scroll", handleVisibleButton);
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener("scroll", handleVisibleButton);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
function handleScrollUp() {
|
function handleScrollUp() {
|
||||||
window.scrollTo(0, 0);
|
window.scrollTo(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function addEventScroll() {
|
|
||||||
window.addEventListener("scroll", handleVisibleButton);
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
addEventScroll();
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classNames(s.scrollToTop, {
|
<div className={classNames(s.scrollToTop, {
|
||||||
[s[`${showScrollToTop}`]]: showScrollToTop
|
[s.show]: showScrollToTop
|
||||||
})}
|
})}
|
||||||
onClick={handleScrollUp}
|
onClick={handleScrollUp}
|
||||||
>
|
>
|
||||||
|
@@ -0,0 +1,53 @@
|
|||||||
|
@import '../../../../styles/utilities';
|
||||||
|
|
||||||
|
.skeletonImage {
|
||||||
|
@apply relative;
|
||||||
|
background: #DDDBDD;
|
||||||
|
|
||||||
|
&.small {
|
||||||
|
width: 10rem;
|
||||||
|
height: 10rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.default {
|
||||||
|
width: 15rem;
|
||||||
|
height: 15rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.large {
|
||||||
|
width: 20rem;
|
||||||
|
height: 20rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.left {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.center {
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
transform: translateX(-100%);
|
||||||
|
background-image: linear-gradient(
|
||||||
|
90deg,
|
||||||
|
rgba(#fff, 0) 0,
|
||||||
|
rgba(#fff, 0.2) 20%,
|
||||||
|
rgba(#fff, 0.5) 60%,
|
||||||
|
rgba(#fff, 0)
|
||||||
|
);
|
||||||
|
animation: shimmer 2s infinite;
|
||||||
|
content: '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shimmer {
|
||||||
|
100% {
|
||||||
|
transform: translateX(100%);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,20 @@
|
|||||||
|
import classNames from "classnames";
|
||||||
|
import React from "react";
|
||||||
|
import s from './SkeletonImage.module.scss'
|
||||||
|
|
||||||
|
interface SkeletonImageProps {
|
||||||
|
align?: "left" | "center"
|
||||||
|
size?: "small" | "default" | "large"
|
||||||
|
}
|
||||||
|
|
||||||
|
const SkeletonImage = ({ align="center", size="default" }: SkeletonImageProps) => {
|
||||||
|
return (
|
||||||
|
<div className={classNames(s.skeletonImage, {
|
||||||
|
[s[size]] : size,
|
||||||
|
[s[align]] : align
|
||||||
|
})}>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SkeletonImage
|
@@ -0,0 +1,65 @@
|
|||||||
|
@import '../../../../styles/utilities';
|
||||||
|
|
||||||
|
.skeletonParagraph {
|
||||||
|
margin: 0 1.6rem;
|
||||||
|
|
||||||
|
.row {
|
||||||
|
display: inline-block;
|
||||||
|
height: 2rem;
|
||||||
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: #DDDBDD;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
transform: translateX(-100%);
|
||||||
|
background-image: linear-gradient(
|
||||||
|
90deg,
|
||||||
|
rgba(#fff, 0) 0,
|
||||||
|
rgba(#fff, 0.2) 20%,
|
||||||
|
rgba(#fff, 0.5) 60%,
|
||||||
|
rgba(#fff, 0)
|
||||||
|
);
|
||||||
|
animation: shimmer 2s infinite;
|
||||||
|
content: '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.lastRow {
|
||||||
|
display: inline-block;
|
||||||
|
height: 2rem;
|
||||||
|
width: 80%;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: #DDDBDD;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
transform: translateX(-100%);
|
||||||
|
background-image: linear-gradient(
|
||||||
|
90deg,
|
||||||
|
rgba(#fff, 0) 0,
|
||||||
|
rgba(#fff, 0.2) 20%,
|
||||||
|
rgba(#fff, 0.5) 60%,
|
||||||
|
rgba(#fff, 0)
|
||||||
|
);
|
||||||
|
animation: shimmer 2s infinite;
|
||||||
|
content: '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shimmer {
|
||||||
|
100% {
|
||||||
|
transform: translateX(100%);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,23 @@
|
|||||||
|
import React from "react";
|
||||||
|
import s from './SkeletonParagraph.module.scss'
|
||||||
|
|
||||||
|
interface SkeletonParagraphProps {
|
||||||
|
rows?: number // number of rows in paragraph
|
||||||
|
}
|
||||||
|
|
||||||
|
const SkeletonParagraph = ({ rows=2 }: SkeletonParagraphProps) => {
|
||||||
|
return (
|
||||||
|
<div className={s.skeletonParagraph}>
|
||||||
|
{
|
||||||
|
[...Array(rows)].map((e, i) => {
|
||||||
|
if (i === rows-1) {
|
||||||
|
return <div key={i} className={s.lastRow}></div>
|
||||||
|
}
|
||||||
|
return <div key={i} className={s.row}></div>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SkeletonParagraph
|
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
background-color: white;
|
background-color: white;
|
||||||
.inner{
|
.inner{
|
||||||
height: 100vh;
|
height: 70vh;
|
||||||
.logo{
|
.logo{
|
||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,38 @@
|
|||||||
|
@import '../../../../styles/utilities';
|
||||||
|
|
||||||
|
.checkoutSuccessWrapper {
|
||||||
|
@apply flex items-center justify-center;
|
||||||
|
margin-top: -3.2rem;
|
||||||
|
|
||||||
|
.checkoutSuccess {
|
||||||
|
border-radius: 80% 90% 18% 10% / 20% 10% 27% 20%;
|
||||||
|
max-width: 77.6rem;
|
||||||
|
height: fit-content;
|
||||||
|
background:
|
||||||
|
url('./assets/veget.png') left 0 top 0 no-repeat,
|
||||||
|
url('./assets/fish.png') right 0 top 0 no-repeat,
|
||||||
|
url('./assets/freezeShrimp.png') right 0 bottom 0 no-repeat,
|
||||||
|
url('./assets/coffeeBean.png') left 0 bottom 0 no-repeat;
|
||||||
|
background-color: #E3F2E9;
|
||||||
|
|
||||||
|
.checkoutContent {
|
||||||
|
@apply text-center;
|
||||||
|
margin: 7.2rem 4.8rem 6.4rem 4.8rem;
|
||||||
|
|
||||||
|
.checkoutMsg {
|
||||||
|
@apply heading-1 font-heading;
|
||||||
|
margin-top: 3.2rem;
|
||||||
|
margin-bottom: 1.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkoutSubMsg {
|
||||||
|
@apply sub-headline;
|
||||||
|
margin-bottom: 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.backToHomeBtn {
|
||||||
|
@apply flex justify-center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,34 @@
|
|||||||
|
import React from "react";
|
||||||
|
import s from './CheckoutSuccess.module.scss';
|
||||||
|
|
||||||
|
import Link from "next/link";
|
||||||
|
|
||||||
|
import checkIcon from './assets/checkIcon.png';
|
||||||
|
|
||||||
|
import { ButtonCommon, StaticImage } from "src/components/common";
|
||||||
|
import { IconArrowRight } from "src/components/icons";
|
||||||
|
|
||||||
|
const CheckoutSuccess = () => {
|
||||||
|
return (
|
||||||
|
<div className={s.checkoutSuccessWrapper}>
|
||||||
|
<div className={s.checkoutSuccess}>
|
||||||
|
<div className={s.checkoutContent}>
|
||||||
|
<StaticImage src={checkIcon} alt="check icon" />
|
||||||
|
|
||||||
|
<div className={s.checkoutMsg}>Your purchase has been successed!</div>
|
||||||
|
<div className={s.checkoutSubMsg}>Last call! Shop deep deals on 100+ bulk picks while you can.</div>
|
||||||
|
|
||||||
|
<div className={s.backToHomeBtn}>
|
||||||
|
<Link href="/">
|
||||||
|
<a>
|
||||||
|
<ButtonCommon size="large" icon={<IconArrowRight />} isIconSuffix={true}>Back to home</ButtonCommon>
|
||||||
|
</a>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CheckoutSuccess
|
Binary file not shown.
After Width: | Height: | Size: 2.4 KiB |
Binary file not shown.
After Width: | Height: | Size: 4.1 KiB |
BIN
src/components/modules/checkout/CheckoutSuccess/assets/fish.png
Normal file
BIN
src/components/modules/checkout/CheckoutSuccess/assets/fish.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.7 KiB |
Binary file not shown.
After Width: | Height: | Size: 6.6 KiB |
BIN
src/components/modules/checkout/CheckoutSuccess/assets/veget.png
Normal file
BIN
src/components/modules/checkout/CheckoutSuccess/assets/veget.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.5 KiB |
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
background-color: white;
|
background-color: white;
|
||||||
.inner{
|
.inner{
|
||||||
height: 100vh;
|
height: 70vh;
|
||||||
.logo{
|
.logo{
|
||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
}
|
}
|
@@ -1,12 +1,12 @@
|
|||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ButtonCommon } from 'src/components/common';
|
import { ButtonCommon } from 'src/components/common';
|
||||||
import s from './ErrorPage.module.scss';
|
import s from './ErrorContent.module.scss';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
}
|
}
|
||||||
|
|
||||||
const ErrorPage = ({ }: Props) => {
|
const ErrorContent = ({ }: Props) => {
|
||||||
return (
|
return (
|
||||||
|
|
||||||
<div className={s.wrapper}>
|
<div className={s.wrapper}>
|
||||||
@@ -26,4 +26,4 @@ const ErrorPage = ({ }: Props) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ErrorPage
|
export default ErrorContent
|
1
src/components/modules/error-page/index.tsx
Normal file
1
src/components/modules/error-page/index.tsx
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export {default as ErrorContent} from './ErrorContent/ErrorContent';
|
@@ -1 +0,0 @@
|
|||||||
export {default as ErrorPage} from './ErrorPage/ErrorPage';
|
|
@@ -31,11 +31,15 @@
|
|||||||
width: min-content;
|
width: min-content;
|
||||||
|
|
||||||
color: var(--white);
|
color: var(--white);
|
||||||
font-size: 8.8rem;
|
font-size: 7rem;
|
||||||
line-height: 8rem;
|
line-height: 8rem;
|
||||||
letter-spacing: -0.03em;
|
letter-spacing: -0.03em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
|
|
||||||
|
@screen 2xl {
|
||||||
|
line-height: 8rem;
|
||||||
|
}
|
||||||
&::after {
|
&::after {
|
||||||
@apply absolute;
|
@apply absolute;
|
||||||
content: "";
|
content: "";
|
||||||
|
@@ -21,6 +21,7 @@ export const ROUTE = {
|
|||||||
RECIPES: '/recipes',
|
RECIPES: '/recipes',
|
||||||
RECIPE_DETAIL: '/recipe',
|
RECIPE_DETAIL: '/recipe',
|
||||||
|
|
||||||
|
NOTIFICATION: '/notifications',
|
||||||
BUSSINESS: '/bussiness',
|
BUSSINESS: '/bussiness',
|
||||||
CONTACT: '/contact',
|
CONTACT: '/contact',
|
||||||
CHECKOUT: '/checkout',
|
CHECKOUT: '/checkout',
|
||||||
@@ -35,7 +36,6 @@ export const ACCOUNT_TAB = {
|
|||||||
CUSTOMER_INFO: '',
|
CUSTOMER_INFO: '',
|
||||||
ORDER: 'orders',
|
ORDER: 'orders',
|
||||||
FAVOURITE: 'wishlist',
|
FAVOURITE: 'wishlist',
|
||||||
NOTIFICATION: 'notification',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const QUERY_KEY = {
|
export const QUERY_KEY = {
|
||||||
|
Reference in New Issue
Block a user