Merge branch 'common' of github.com:KieIO/grocery-vercel-commerce into m5-datnguyen

This commit is contained in:
unknown
2021-09-10 18:09:37 +07:00
69 changed files with 1504 additions and 204 deletions

2
.gitignore vendored
View File

@@ -35,3 +35,5 @@ yarn-error.log*
# vercel
.vercel
.eslintrc

View File

@@ -1,27 +0,0 @@
{
"schema": {
"https://buybutton.store/graphql": {
"headers": {
"Authorization": "Bearer xzy"
}
}
},
"documents": [
{
"./framework/bigcommerce/api/**/*.ts": {
"noRequire": true
}
}
],
"generates": {
"./framework/bigcommerce/schema.d.ts": {
"plugins": ["typescript", "typescript-operations"]
},
"./framework/bigcommerce/schema.graphql": {
"plugins": ["schema-ast"]
}
},
"hooks": {
"afterAllFileWrite": ["prettier --write"]
}
}

3
next-env.d.ts vendored
View File

@@ -1,3 +1,6 @@
/// <reference types="next" />
/// <reference types="next/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.

View File

@@ -13,6 +13,16 @@ const isVendure = provider === 'vendure'
module.exports = withCommerceConfig({
commerce,
typescript: { // todo: remove it
// !! WARN !!
// Dangerously allow production builds to successfully complete even if
// your project has type errors.
// !! WARN !!
ignoreBuildErrors: true,
},
eslint: {
ignoreDuringBuilds: true,
},
images: {
// todo: replace domains for images
domains: ['user-images.githubusercontent.com'],

14
pages/blogs.tsx Normal file
View File

@@ -0,0 +1,14 @@
import { Layout } from 'src/components/common';
import { BlogsList, FeaturedCardBlog, BlogHeading, BlogBreadCrumb } from 'src/components/modules/blogs';
export default function BlogsPage() {
return(
<>
<BlogBreadCrumb />
<BlogHeading />
<FeaturedCardBlog />
<BlogsList />
</>
)
}
BlogsPage.Layout = Layout

View File

@@ -13,7 +13,7 @@ export default function Home() {
<HomeRecipe />
<HomeSubscribe />
{/* // todo: uncomment */}
{/* // todo: uncomment
{/* <ModalCreateUserInfo/> */}
</>
)

12
pages/privacy-policy.tsx Normal file
View File

@@ -0,0 +1,12 @@
import { Layout } from "src/components/common"
import { DeliveryAndPolicyContent, DeliveryAndPolicyBreadCrumb } from "src/components/modules/delivery-policy"
export default function DeliveryAndPolicyPage () {
return (
<>
<DeliveryAndPolicyBreadCrumb />
<DeliveryAndPolicyContent />
</>
)
}
DeliveryAndPolicyPage.Layout = Layout

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

View File

@@ -1,7 +1,7 @@
import React from 'react'
interface BreadcrumbSeparatorProps {
children?: React.ReactNode
children?: React.ReactNode;
}
const BreadcrumbSeparator = ({ children }: BreadcrumbSeparatorProps) => {

View File

@@ -3,7 +3,6 @@
.cardBlogWarpper {
@apply inline-flex flex-col justify-start;
max-width: 39.2rem;
min-height: 34.4rem;
.image {
width: 100%;
max-height: 22rem;
@@ -11,6 +10,9 @@
&:hover {
cursor: pointer;
}
img{
border-radius: 2.4rem;
}
}
.title {
padding: 1.6rem 0.8rem 0.4rem 0.8rem;

View File

@@ -52,7 +52,8 @@
}
}
.contentContainer {
@apply hidden pb-16;
@apply hidden pb-16 whitespace-pre-line;
padding-top: 1.6rem;
}
@keyframes ContentAnimationIn {
0% {

View File

@@ -1,11 +1,10 @@
import s from './CollapseChild.module.scss'
import { useState } from 'react'
import classNames from 'classnames'
import CollapseContent from './CollapseContent/CollapseContent'
interface CollapseProps{
title?: string,
content: Array<string>,
content: string,
isToggle?: boolean,
}
const CollapseChild = ({title, content, isToggle=false}: CollapseProps) => {
@@ -26,9 +25,7 @@ const CollapseChild = ({title, content, isToggle=false}: CollapseProps) => {
<div className={s.toggle}></div>
</div>
<div className={s.contentContainer}>
{
content.map(item => <CollapseContent key={item} content={item} />)
}
{content}
</div>
</div>
)

View File

@@ -1,3 +0,0 @@
.content {
margin-top: 1.6rem;
}

View File

@@ -1,15 +0,0 @@
import s from './CollapseContent.module.scss'
interface CollapseContentProps{
content: string
}
const CollapseContent = ({content}: CollapseContentProps) => {
return (
<div className={s.content}>
{content}
</div>
)
}
export default CollapseContent

View File

@@ -1,15 +1,15 @@
import CollapseChild from './CollapseChild/CollapseChild'
interface CollapseCommonProps{
data: {title: string, content: Array<string>}[],
data: {title: string, content: string}[],
}
const CollapseCommon = ({data}: CollapseCommonProps) => {
return (
<section>
{
data.map(item =>
<CollapseChild key={item.title} title={item.title} content={item.content}/>
data.map((item,index) =>
<CollapseChild key={`${item.title}-${index}`} title={item.title} content={item.content} />
)
}
</section>

View File

@@ -48,11 +48,11 @@ const FOOTER_COLUMNS = [
},
{
name: 'Privacy Policy',
link: ROUTE.TERM_CONDITION,
link: ROUTE.PRIVACY_POLICY,
},
{
name: 'Blog',
link: ROUTE.TERM_CONDITION,
link: ROUTE.BLOGS,
},
]
}

View File

@@ -1,3 +1,4 @@
@import '../../../styles/utilities';
.tabWapper{
@apply flex flex-col w-full;

View File

@@ -1,86 +1,85 @@
import React, {
Children,
PropsWithChildren,
ReactElement,
RefObject,
useEffect,
useRef,
useState,
cloneElement,
} from 'react'
import s from './TabCommon.module.scss'
Children,
PropsWithChildren,
ReactElement,
useEffect,
useRef,
useState,
cloneElement,
} from 'react'
import s from './TabCommon.module.scss'
import TabItem from './components/TabItem/TabItem'
import { TabPaneProps } from './components/TabPane/TabPane'
import classNames from 'classnames'
import TabItem from './components/TabItem/TabItem'
import { TabPaneProps } from './components/TabPane/TabPane'
import classNames from 'classnames'
interface TabCommonProps {
defaultActiveTab?: number
children: React.ReactNode
center?:boolean
}
interface TabCommonProps {
defaultActiveTab?: number
children: React.ReactNode
center?:boolean
}
const TabCommon = ({
defaultActiveTab = 0,
children,
center
}: TabCommonProps) => {
const [active, setActive] = useState(0)
const slider = useRef<HTMLDivElement>(null)
const headerRef = useRef<HTMLUListElement>(null)
useEffect(() => {
setActive(defaultActiveTab)
}, [])
const TabCommon = ({
defaultActiveTab = 0,
children,
center
}: TabCommonProps) => {
const [active, setActive] = useState(0)
const slider = useRef<HTMLDivElement>(null)
const headerRef = useRef<HTMLUListElement>(null)
useEffect(() => {
setActive(defaultActiveTab)
}, [])
useEffect(() => {
slide(active)
}, [active])
useEffect(() => {
slide(active)
}, [active])
function slide(index: number) {
const active = headerRef.current?.children
.item(index)
?.getBoundingClientRect()
const header = headerRef.current?.getBoundingClientRect()
const current = slider.current
if (current && active && header) {
let width = active.width - 24 <= 0 ? 24 : active.width - 24
let left = active.left - header.left
current.style.width = width.toString() + 'px'
current.style.left = left.toString() + 'px'
function slide(index: number) {
const active = headerRef.current?.children
.item(index)
?.getBoundingClientRect()
const header = headerRef.current?.getBoundingClientRect()
const current = slider.current
if (current && active && header) {
let width = active.width - 24 <= 0 ? 24 : active.width - 24
let left = active.left - header.left
current.style.width = width.toString() + 'px'
current.style.left = left.toString() + 'px'
}
}
const onTabClick = (index: number) => {
setActive(index)
}
return (
<section className={s.tabWapper}>
<div className={s.tabHeader}>
<ul className={classNames(s.tabList,{[s.center]:center})} ref={headerRef}>
{Children.map(children, (tab, index) => {
let item = tab as ReactElement<PropsWithChildren<TabPaneProps>>
return (
<li key={item.props.tabName}>
<TabItem
active={active === index}
onClick={onTabClick}
tabIndex={index}
>
{item.props.tabName}
</TabItem>
</li>
)
})}
<div ref={slider} className={s.slider}></div>
</ul>
</div>
<div className={s.tabBody}>
{Children.map(children, (tab, index) => {
let item = tab as ReactElement<PropsWithChildren<TabPaneProps>>
return cloneElement(item, { active:index===active });
})
}</div>
</section>
)
}
const onTabClick = (index: number) => {
setActive(index)
}
return (
<section className={s.tabWapper}>
<div className={s.tabHeader}>
<ul className={classNames(s.tabList,{[s.center]:center})} ref={headerRef}>
{Children.map(children, (tab, index) => {
let item = tab as ReactElement<PropsWithChildren<TabPaneProps>>
return (
<li key={item.props.tabName}>
<TabItem
active={active === index}
onClick={onTabClick}
tabIndex={index}
>
{item.props.tabName}
</TabItem>
</li>
)
})}
<div ref={slider} className={s.slider}></div>
</ul>
</div>
<div className={s.tabBody}>
{Children.map(children, (tab, index) => {
let item = tab as ReactElement<PropsWithChildren<TabPaneProps>>
return cloneElement(item, { active:index===active });
})
}</div>
</section>
)
}
export default TabCommon
export default TabCommon

View File

@@ -0,0 +1,22 @@
@import '../../../../styles/utilities';
.tabItem {
margin-right: 4.8rem;
padding-top: 1.6rem;
padding-bottom: 1.6rem;
&:hover {
@apply cursor-pointer;
}
}
.tabItemActive {
@apply font-bold;
margin-right: 4.8rem;
padding-top: 1.6rem;
padding-bottom: 1.6rem;
&:hover {
@apply cursor-pointer;
}
}

View File

@@ -0,0 +1,19 @@
import React from "react"
import s from './TabItem.module.scss'
interface TabItemProps {
active: boolean;
children: string;
onClick: (tabIndex: number, tabPane?: string) => void;
}
const TabItem = ({ active = false, children, onClick } : TabItemProps) => {
return (
<span onClick={onClick} className={active ? s.tabItemActive : s.tabItem} >
{children}
</span>
)
}
export default TabItem;

View File

@@ -11,4 +11,3 @@
@apply font-bold;
}
}

View File

@@ -1,5 +1,9 @@
import classNames from 'classnames'
<<<<<<< HEAD
import React, { RefObject, useRef } from 'react'
=======
import React from 'react'
>>>>>>> 88f90912429447f6ae7bafa77484465965e0ee13
import s from './TabItem.module.scss'
interface TabItemProps {
@@ -21,7 +25,6 @@ const TabItem = ({
return (
<span
onClick={handleClick}
// className={active ? s.tabItemActive : s.tabItem}
className={classNames(s.tabItem, {[s.tabItemActive]:active})}
>
{children}
@@ -29,4 +32,8 @@ const TabItem = ({
)
}
<<<<<<< HEAD
export default TabItem
=======
export default TabItem
>>>>>>> 88f90912429447f6ae7bafa77484465965e0ee13

View File

@@ -36,6 +36,7 @@ export { default as CardItemCheckout} from './CardItemCheckout/CardItemCheckout'
export { default as CardBlog} from './CardBlog/CardBlog'
export { default as RelevantBlogPosts} from './RelevantBlogPosts/RelevantBlogPosts'
export { default as CollapseCommon} from './CollapseCommon/CollapseCommon'
export { default as BreadcrumbCommon } from './BreadcrumbCommon/BreadcrumbCommon'
export { default as ImgWithLink} from './ImgWithLink/ImgWithLink'
export { default as RecipeDetail} from './RecipeDetail/RecipeDetail'
export { default as DrawerCommon} from './DrawerCommon/DrawerCommon'

View File

@@ -1,5 +1,27 @@
@import '../../../../styles/utilities';
.accountNavigation {
@apply spacing-horizontal;
@apply flex;
width: 100%;
.slider {
@apply inline-block;
width: 0.2rem;
height: 4.8rem;
border-radius: 3px;
background-color: var(--primary);
position: absolute;
left: 11.2rem;
transition: all .2s linear;
}
.tabList {
margin-top: 3.8rem;
margin-right: 12.4rem;
}
.tabBody {
margin-top: -4.7rem;
width: 100%;
}
}

View File

@@ -1,65 +1,67 @@
import React, { useState, useRef, RefObject, useEffect } from "react"
import React, { useRef, useEffect, Children, ReactElement, PropsWithChildren, useState, cloneElement } from "react"
import s from './AccountNavigation.module.scss'
import AccountNavigationItem from './components/AccountNavigationItem'
import AccountNavigationItem from './components/AccountNavigationItem/AccountNavigationItem'
import {TabPaneProps} from '../../../common/TabCommon/components/TabPane/TabPane'
interface AccountNavigationProps {
defaultActiveIndex: number;
children: React.ReactNode
}
const AccountNavigation = ({ } : AccountNavigationProps) => {
const active = "active", unActive = "";
const AccountNavigation = ({ defaultActiveIndex, children } : AccountNavigationProps) => {
const [active, setActive] = useState(defaultActiveIndex)
const sliderRef = useRef<HTMLDivElement>(null);
const headerRef = useRef<HTMLUListElement>(null)
const [item1Active, setItem1Active] = useState(unActive);
const [item2Active, setItem2Active] = useState(active);
const [item3Active, setItem3Active] = useState(unActive);
const item1 = useRef<HTMLDivElement>(null);
const item2 = useRef<HTMLDivElement>(null);
const item3 = useRef<HTMLDivElement>(null);
const slider = useRef<HTMLDivElement>(null);
function slide(ref: RefObject<HTMLDivElement>) {
const top = ref.current.offsetTop;
slider.current.style.top = top.toString()+"px";
const onTabClick = (index: number) => {
setActive(index)
}
function toggleItem1():void {
setItem1Active(active)
function slide(index: number) {
const active = headerRef.current?.children.item(index)?.getBoundingClientRect()
const header = headerRef.current?.getBoundingClientRect()
const current = sliderRef.current
setItem2Active(unActive)
setItem3Active(unActive)
slide(item1);
}
function toggleItem2():void {
setItem2Active(active)
setItem1Active(unActive)
setItem3Active(unActive)
slide(item2);
}
function toggleItem3():void {
setItem3Active(active)
setItem1Active(unActive)
setItem2Active(unActive)
slide(item3);
if (current && active && header) {
const top = active.top;
current.style.top = top.toString()+"px";
}
}
useEffect(() => {
slide(item2);
}, [])
slide(active);
}, [active])
return (
<section className={s.accountNavigation}>
<div ref={item1}>
<AccountNavigationItem onClick={toggleItem1} active={item1Active}>Customer Information</AccountNavigationItem>
</div>
<div ref={item2}>
<AccountNavigationItem onClick={toggleItem2} active={item2Active}>Your Orders</AccountNavigationItem>
</div>
<div ref={item3}>
<AccountNavigationItem onClick={toggleItem3} active={item3Active}>Favourites</AccountNavigationItem>
<ul className={s.tabList} ref={headerRef}>
{
Children.map(children, (tab, index) => {
let item = tab as ReactElement<PropsWithChildren<TabPaneProps>>
return (
<li key={item.props.tabName}>
<AccountNavigationItem
active={active === index}
onClick={onTabClick}
tabIndex={index}
>
{item.props.tabName}
</AccountNavigationItem>
</li>
)
})
}
<div ref={sliderRef} className={s.slider}></div>
</ul>
<div className={s.tabBody}>
{
Children.map(children, (tab, index) => {
let item = tab as ReactElement<PropsWithChildren<TabPaneProps>>
return cloneElement(item, { active: index === active });
})
}
</div>
<div ref={slider} className={s.slider}></div>
</section>

View File

@@ -1,7 +1,6 @@
@import '../../../../../styles/utilities';
@import '../../../../../../styles/utilities';
.accountNavigationItem {
@apply bg-gray;
width: 28rem;
padding: 1.2rem 0 1.2rem 1.6rem;
margin-bottom: 1.2rem;
@@ -14,6 +13,5 @@
&.active {
background-color: #FBFBFB;
border-radius: 0 1.6rem 1.6rem 0;
border-left: 2px solid var(--primary);
}
}

View File

@@ -4,15 +4,19 @@ import s from './AccountNavigationItem.module.scss'
interface AccountNavigationItemProps {
children?: string;
active?: string;
target?: string;
onClick: () => void;
active?: boolean;
tabIndex: number
onClick: (index: number) => void;
}
const AccountNavigationItem = ({ children, active="", onClick } : AccountNavigationItemProps) => {
const AccountNavigationItem = ({ children, active, tabIndex, onClick } : AccountNavigationItemProps) => {
const handleClick = () => {
onClick(tabIndex)
}
return (
<div onClick={onClick} className={classNames(s.accountNavigationItem, {
[s[active]]:active
<div onClick={handleClick} className={classNames(s.accountNavigationItem, {
[s.active]:active
})}>
{children}
</div>

View File

@@ -0,0 +1,26 @@
@import '../../../../styles/utilities';
.accountPage {
@apply spacing-horizontal;
background-color: #F5F4F2;
margin-top: -3.2rem;
padding-top: 3.2rem;
padding-bottom: 3.2rem;
@screen md {
padding-left: 3.2rem;
padding-right: 3.2rem;
}
@screen xl {
@apply spacing-horizontal
}
.header {
margin-bottom: 1.2rem;
@screen md {
margin-bottom: 3.8rem;
}
}
}

View File

@@ -0,0 +1,86 @@
import React, { useState } from "react"
import s from './AccountPage.module.scss'
import AccountNavigation from '../AccountNavigation/AccountNavigation'
import HeadingCommon from '../../../common/HeadingCommon/HeadingCommon'
import AccountInfomation from "./components/AccountInfomation/AccountInfomation"
import OrderInfomation from './components/OrderInformation/OrderInformation'
import EditInfoModal from './components/EditInfoModal/EditInfoModal'
import TabPane from "src/components/common/TabCommon/components/TabPane/TabPane"
const waiting = [
{
id: "NO 123456",
products: ["Tomato", "Fish", "Pork", "Onion"],
totalPrice : 1000
}
]
const delivering = [
{
id: "NO 123456",
products: ["Tomato", "Fish", "Pork", "Onion", "Tomato", "Fish", "Pork", "Onion"],
totalPrice : 1000
}
]
const delivered = [
{
id: "NO 123456",
products: ["Tomato", "Fish", "Pork", "Onion", "Tomato", "Fish", "Pork", "Onion"],
totalPrice : 1000
}
]
let account = {
name: "vu duong",
email: "vuduong@gmail.com",
address: "234 Dien Bien Phu Bis, Dakao ward",
state: "District 1",
city: "HCMC",
postalCode: "700000",
phoneNumber: "(+84) 937 937 195"
}
interface AccountPageProps {
defaultActiveContent?: "info" | "orders" | "favorites"
}
const AccountPage = ({defaultActiveContent="orders"} : AccountPageProps) => {
const [activeTab] = useState(defaultActiveContent==="info" ? 0 : defaultActiveContent==="orders" ? 1 : 2)
const [modalVisible, setModalVisible] = useState(false);
function showModal() {
setModalVisible(true);
}
function closeModal() {
setModalVisible(false);
}
return (
<>
<section className={s.accountPage}>
<div className={s.header}>
<HeadingCommon>Account</HeadingCommon>
</div>
<AccountNavigation defaultActiveIndex={activeTab}>
<TabPane tabName="Customer Information">
<AccountInfomation account={account} onClick={showModal} />
</TabPane>
<TabPane tabName="Your Orders">
<OrderInfomation waiting={waiting} delivering={delivering} delivered={delivered} />
</TabPane>
<TabPane tabName="Favourite">
{/* <FavoriteProduct active={activeTab === 2} favProducts={favProducts} /> */}
</TabPane>
</AccountNavigation>
</section>
<EditInfoModal accountInfo={account} closeModal={closeModal} visible={modalVisible} />
</>
)
}
export default AccountPage

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@@ -0,0 +1,67 @@
@import '../../../../../../styles/utilities';
.accountInfomation {
@apply flex justify-center items-center;
text-align: center;
margin-top: 1.6rem;
@screen md {
@apply block;
text-align: left;
margin-top: 0;
}
.avatar {
height: 22rem;
width: 22rem;
border-radius: 50%;
margin: auto;
margin-bottom: 4rem;
@screen md {
margin-left: 0
}
}
.accountName {
@apply heading-3 font-heading;
}
.horizontalSeparator{
border: 1px solid var(--disabled);
max-width: 39.2rem;
min-width: 30rem;
margin-top: 2.4rem;
margin-bottom: 2.4rem;
}
.shippingInfo {
@apply heading-3 font-heading;
}
.accountAddress {
max-width: 31rem;
min-width: none;
}
.editInfoBtn {
@apply text-center font-bold custom-border-radius;
margin: auto;
margin-top: 2.4rem;
margin-bottom: 2.4rem;
padding: .8rem 1.6rem;
color: #141414;
border: 1px solid #141414;
max-width: 8.8rem;
&:hover {
@apply cursor-pointer;
background-color: #FBFBFB;
}
@screen md {
margin-left: 0;
}
}
}

View File

@@ -0,0 +1,56 @@
import React from "react"
import s from './AccountInfomation.module.scss'
import Image from "next/image"
import avatar from '../../assets/avatar.png';
interface AccountProps {
name: string, email: string, address: string, state: string, city: string, postalCode: string, phoneNumber: string
}
interface AccountInfomationProps {
account: AccountProps;
onClick: () => void;
}
const AccountInfomation = ({ account, onClick } : AccountInfomationProps) => {
// need to handle call back when edit account information
const showEditForm = () => onClick()
return (
<section className={s.accountInfomation}>
{
<div>
<div className={s.avatar}>
<Image src={avatar} alt="avatar" />
</div>
<div className={s.accountName}>
{account.name}
</div>
<div className={s.accountEmail}>
{account.email}
</div>
<div className={s.horizontalSeparator}></div>
<div className={s.shippingInfo}>Shipping Infomation</div>
<div className={s.accountAddress}>
{account.address + `, ${account.state}, ${account.city}, ${account.postalCode}`}
</div>
<div className={s.accountPhoneNumber}>
{account.phoneNumber}
</div>
<div onClick={showEditForm} className={s.editInfoBtn}>Edit</div>
</div>
}
</section>
)
}
export default AccountInfomation

View File

@@ -0,0 +1,81 @@
@import '../../../../../../styles/utilities';
.editInfoModal {
.input {
@apply bg-white;
margin-bottom: 1.6rem;
width: 100%;
border: 2px solid #EBEBEB;
border-radius: .8rem;
padding: 1.6rem;
}
.inputDisable {
margin-bottom: 1.6rem;
width: 100%;
border: 2px solid #EBEBEB;
border-radius: .8rem;
padding: 1.6rem;
background-color: #EBEBEB;
color: #CCCCCC;
}
.inputStateWrapper {
@apply bg-white;
margin-bottom: 1.6rem;
margin-right: 1.6rem;
border: 2px solid #EBEBEB;
border-radius: .8rem;
padding: 1.6rem;
.inputState {
@apply bg-white cursor-pointer;
border: white;
}
}
.inputPostalCode {
@apply bg-white;
margin-bottom: 1.6rem;
border: 2px solid #EBEBEB;
border-radius: .8rem;
padding: 1.6rem;
}
.inputPhoneNumber {
@apply bg-white;
margin-bottom: 4rem;
width: 100%;
border: 2px solid #EBEBEB;
border-radius: .8rem;
padding: 1.6rem;
}
.buttons {
@apply flex;
.buttonCancel {
@apply bg-white text-center font-bold custom-border-radius-lg;
color: #141414;
border: 1px solid #141414;
padding: 1.6rem;
margin-right: 1.6rem;
width: 100%;
&:hover {
@apply cursor-pointer;
}
}
.buttonSave {
@apply text-center font-bold custom-border-radius-lg;
background-color: var(--primary);
color: white;
padding: 1.6rem;
width: 100%;
&:hover {
@apply cursor-pointer;
}
}
}
}

View File

@@ -0,0 +1,83 @@
import classNames from "classnames"
import React, { useState } from "react"
import s from './EditInfoModal.module.scss'
import {ModalCommon, MenuDropdown} from '../../../../../common'
import {ButtonCommon} from '../../../../../common'
interface EditInfoModalProps {
accountInfo: {name: string, email: string, address: string, state: string, city: string, postalCode: string, phoneNumber: string};
visible: boolean;
closeModal: () => void;
}
const EditInfoModal = ({ accountInfo, visible = false, closeModal }: EditInfoModalProps) => {
const [name, setName] = useState(accountInfo.name);
const [email, setEmail] = useState(accountInfo.email);
const [address, setAddress] = useState(accountInfo.address);
const [state, setState] = useState(accountInfo.state);
const [city, setCity] = useState(accountInfo.city);
const [postalCode, setPostalCode] = useState(accountInfo.postalCode);
const [phoneNumber, setPhoneNumber] = useState(accountInfo.phoneNumber);
function saveInfo() {
console.log("saved !!!");
closeModal();
}
const states = [
{name: "D1", onClick: () => {setState("D1")}},
{name: "D2", onClick: () => {setState("D2")}},
{name: "D3", onClick: () => {setState("D3")}}
]
return (
<ModalCommon onClose={closeModal} visible={visible} title="Edit Infomation">
<section className={s.editInfoModal}>
<div>
<input className={s.input} type="text" name="name" placeholder="Name"
value={name} onChange={e => {setName(e.target.value)}} />
</div>
<div>
<input className={s.inputDisable} type="text" name="email" placeholder="Email"
value={email} onChange={e => {setEmail(e.target.value)}} />
</div>
<div>
<input className={s.input} type="text" name="address" placeholder="Address"
value={address} onChange={e => {setAddress(e.target.value)}}/>
</div>
<div>
<input className={s.input} type="text" name="city" placeholder="City"
value={city} onChange={e => {setCity(e.target.value)}} />
</div>
<div className="flex">
<div className={s.inputStateWrapper}>
<MenuDropdown options={states} isHasArrow={true} >
<input className={s.inputState} type="text" name="state" placeholder="State"
value={state} disabled />
</MenuDropdown>
</div>
<input className={s.inputPostalCode} type="text" name="postalCode" placeholder="Postal code"
value={postalCode} onChange={e => {setPostalCode(e.target.value)}} />
</div>
<div>
<input className={s.inputPhoneNumber} type="text" name="phoneNumber" placeholder="Phone number"
value={phoneNumber} onChange={e => {setPhoneNumber(e.target.value)}} />
</div>
<div className={s.buttons}>
<div onClick={closeModal} className={s.buttonCancel}>Cancel</div>
<div onClick={saveInfo} className={s.buttonSave}>Save</div>
</div>
</section>
</ModalCommon>
)
}
export default EditInfoModal

View File

@@ -0,0 +1,16 @@
@import '../../../../../../styles/utilities';
.orderInformation {
.title {
@apply heading-3 font-heading;
margin-top: 1.6rem;
}
.tabs {
margin-top: 3.2rem;
.blank {
margin-bottom: 2.4rem;
}
}
}

View File

@@ -0,0 +1,66 @@
import React from "react"
import s from './OrderInformation.module.scss'
import { TabCommon } from '../../../../../common'
import TabPane from 'src/components/common/TabCommon/components/TabPane/TabPane'
import DeliveryItem from '../../../DeliveryItem/DeliveryItem'
interface OrderInformationProps {
waiting: {id: string, products: string[], totalPrice: number}[],
delivering: {id: string, products: string[], totalPrice: number}[],
delivered: {id: string, products: string[], totalPrice: number}[],
// active?: boolean
}
const OrderInformation = ({ waiting, delivering, delivered} : OrderInformationProps) => {
return (
<section className={s.orderInformation}>
{
<div>
<div className={s.title}>Order Information</div>
<div className={s.tabs}>
<TabCommon>
<TabPane tabName={"Wait for Comfirmation"} >
<div className={s.blank}></div>
{
waiting.map((order, i) => {
return (
<DeliveryItem key={order.id} id={order.id} status="waiting" products={order.products} totalPrice={order.totalPrice} />
)
})
}
</TabPane>
<TabPane tabName={"Delivering"}>
<div className={s.blank}></div>
{
delivering.map((order, i) => {
return (
<DeliveryItem key={order.id} id={order.id} status="delivering" products={order.products} totalPrice={order.totalPrice} />
)
})
}
</TabPane>
<TabPane tabName={"Delivered"}>
<div className={s.blank}></div>
{
delivered.map((order, i) => {
return (
<DeliveryItem key={order.id} id={order.id} status="delivered" products={order.products} totalPrice={order.totalPrice} />
)
})
}
</TabPane>
</TabCommon>
</div>
</div>
}
</section>
)
}
export default OrderInformation

View File

@@ -0,0 +1,26 @@
@import '../../../../styles/utilities';
.deliveryItem {
@apply flex bg-white items-center custom-border-radius;
margin-bottom: 1.6rem;
border: 1px solid var(--primary)
}
.separator {
border-left: 2px dashed #EBEBEB;
max-height: 9.2rem;
min-height: 8.6rem;
margin-left: .6rem;
margin-right: .6rem;
@screen md {
margin-left: .8rem;
margin-right: .8rem;
}
@screen lg {
margin-left: 2.4rem;
margin-right: 2.4rem;
}
}

View File

@@ -0,0 +1,30 @@
import React from "react"
import s from './DeliveryItem.module.scss'
import IdAndStatus from './components/IdAndStatus/IdAndStatus'
import Products from './components/Products/Products'
import TotalPrice from './components/TotalPrice/TotalPrice'
import ReOrder from './components/ReOrder/ReOrder'
interface DeliveryItemProps {
id: string;
status: "waiting" | "delivering" | "delivered";
products: string[];
totalPrice: number;
reOrderLink?: string;
}
const DeliveryItem = ({ id, status, products, totalPrice, reOrderLink } : DeliveryItemProps) => {
return (
<section className={s.deliveryItem}>
<IdAndStatus id={id} status={status} />
<div className={s.separator}></div>
<Products products={products} />
<TotalPrice totalPrice={totalPrice} />
<ReOrder show={status==="delivered" ? true : false} href={reOrderLink} />
</section>
)
}
export default DeliveryItem

View File

@@ -0,0 +1,75 @@
@import '../../../../../../styles/utilities';
.idAndStatus {
@apply items-center;
padding: 2.4rem 0 2.4rem 1rem;
@screen md {
padding: 2.4rem 0 2.4rem 1.2rem;
}
@screen lg {
padding: 2.4rem 0 2.4rem 2.4rem;
}
.id {
@apply font-bold;
margin-bottom: .8rem;
}
.deliveryStatus {
@apply font-bold text-white;
font-size: 1.2rem;
line-height: 2rem;
padding: 0 .8rem;
border-radius: 0.5rem;
width: fit-content;
&.waiting {
background-color: #D9A645;
}
&.delivering {
background-color: var(--info-dark);
}
&.delivered {
background-color: var(--primary);
}
}
}@import '../../../../../../styles/utilities';
.idAndStatus {
@apply items-center;
padding: 2.4rem 0 2.4rem 1rem;
@screen md {
padding: 2.4rem 0 2.4rem 1.2rem;
}
@screen lg {
padding: 2.4rem 0 2.4rem 2.4rem;
}
.id {
@apply font-bold;
margin-bottom: .8rem;
}
.deliveryStatus {
@apply font-bold text-white;
font-size: 1.2rem;
line-height: 2rem;
padding: 0 .8rem;
border-radius: 0.5rem;
width: fit-content;
&.waiting {
background-color: #D9A645;
}
&.delivering {
background-color: var(--info-dark);
}
&.delivered {
background-color: var(--primary);
}
}
}

View File

@@ -0,0 +1,25 @@
import classNames from "classnames"
import React from "react"
import s from './IdAndStatus.module.scss'
interface IdAndStatusProps {
id?: string;
status: "waiting" | "delivering" | "delivered";
}
const IdAndStatus = ({ id, status="waiting" } : IdAndStatusProps) => {
return (
<div className={s.idAndStatus}>
<div className={s.id}>
{id}
</div>
<div className={classNames(s.deliveryStatus, {
[s[status]]: status
})}> {status}
</div>
</div>
)
}
export default IdAndStatus

View File

@@ -0,0 +1,12 @@
@import '../../../../../../styles/utilities';
.products {
margin-top: .8rem;
max-width: 32%;
min-width: none;
@screen lg {
margin-top: 0;
margin-bottom: 0;
}
}

View File

@@ -0,0 +1,29 @@
import React from "react"
import s from './Products.module.scss'
interface ProductsProps {
products: string[];
}
const Products = ({ products } : ProductsProps) => {
function toString(products:string[]): string {
let strProducts = "";
products.map((prod, i) => {
if (i === 0) {
strProducts += prod;
} else {
strProducts += `, ${prod}`
}
});
return strProducts;
}
return (
<div className={s.products}>
{toString(products)}
</div>
)
}
export default Products

View File

@@ -0,0 +1,27 @@
@import '../../../../../../styles/utilities';
.reOrder {
@apply text-white custom-border-radius hidden font-bold;
padding: .4rem .6rem;
margin-right: 1rem;
background-color: var(--primary);
@screen md {
padding: .4rem .6rem;
margin-right: 1.2rem;
}
@screen lg {
padding: .8rem 1.2rem;
margin-right: 2.4rem;
}
&.show {
@apply block;
}
&:hover {
@apply cursor-pointer;
}
}

View File

@@ -0,0 +1,23 @@
import classNames from "classnames"
import React from "react"
import s from './ReOrder.module.scss'
import Link from 'next/link'
interface ReOrderProps {
show: boolean;
href?: string;
}
const ReOrder = ({ show=false, href="#" } : ReOrderProps) => {
return (
<div className={classNames(s.reOrder, {
[s.show]: show
})}>
<Link href={href}>
<a>Re-Order</a>
</Link>
</div>
)
}
export default ReOrder

View File

@@ -0,0 +1,26 @@
@import '../../../../../../styles/utilities';
.totalPrice {
margin-left: auto;
margin-right: 1rem;
@screen md {
margin-right: 1.2rem;
}
@screen lg {
margin-right: 2.4rem;
}
.price {
@apply font-bold ;
@screen md {
@apply topline
}
@screen lg {
@apply sub-headline;
}
}
}

View File

@@ -0,0 +1,18 @@
import React from "react"
import s from './TotalPrice.module.scss'
interface TotalPriceProps {
totalPrice: number;
}
const TotalPrice = ({ totalPrice } : TotalPriceProps) => {
return (
<section className={s.totalPrice}>
<div className="text-right">Total</div>
<div className={s.price}>Rp {totalPrice}</div>
</section>
)
}
export default TotalPrice

View File

@@ -0,0 +1,3 @@
export { default as AccountNavigation } from './AccountNavigation/AccountNavigation'
export { default as DeliveryItem } from './DeliveryItem/DeliveryItem'
export { default as AccountPage } from './AccountPage/AccountPage'

View File

@@ -0,0 +1,7 @@
@import "../../../../styles/utilities";
.breadCrumbWrapper {
@apply py-12 spacing-horizontal;
@screen lg {
padding-left: 3.2rem;
}
}

View File

@@ -0,0 +1,16 @@
import { BreadcrumbCommon } from "src/components/common"
import s from './BlogBreadCrumb.module.scss'
const BLOG_DATA = [
{link: "/blogs", name: "Blog"},
];
const BlogBreadCrumb = () => {
return (
<section className={s.breadCrumbWrapper}>
<BreadcrumbCommon crumbs={BLOG_DATA} showHomePage={true}/>
</section>
)
}
export default BlogBreadCrumb

View File

@@ -0,0 +1,9 @@
@import "../../../../styles/utilities";
.headingWrapper {
@apply flex spacing-horizontal-left pb-16 justify-center;
.heading{
max-width: 121.6rem;
flex-grow: 1;
}
}

View File

@@ -0,0 +1,18 @@
import { HeadingCommon } from "src/components/common"
import s from './BlogHeading.module.scss'
interface BlogHeadingProps {
children?: React.ReactNode,
heading?: string,
}
const BlogHeading = ({heading = "BLOG"}: BlogHeadingProps) => {
return (
<section className={s.headingWrapper}>
<div className={s.heading}>
<HeadingCommon>{heading}</HeadingCommon>
</div>
</section>
)
}
export default BlogHeading

View File

@@ -0,0 +1,23 @@
@import "../../../../styles/utilities";
.wrapper {
@apply flex flex-col spacing-horizontal items-center;
padding-bottom: 16.8rem;
.list {
@apply grid grid-cols-1 gap-8;
max-width: 121.6rem;
@screen md {
@apply grid-cols-2;
}
@screen lg {
@apply grid-cols-3;
}
}
.card {
@apply pb-16;
}
.pagination {
@apply flex justify-center items-center ;
padding-top: 0.8rem;
}
}

View File

@@ -0,0 +1,157 @@
import React, { useState } from 'react'
import CardBlog, { BlogCardProps } from 'src/components/common/CardBlog/CardBlog'
import PaginationCommon from 'src/components/common/PaginationCommon/PaginationCommon'
import s from "./BlogsList.module.scss"
import { DEFAULT_BLOG_PAGE_SIZE } from 'src/utils/constanst.utils'
import image15 from '../../../../../public/assets/images/image15.png'
import image16 from '../../../../../public/assets/images/image16.png'
import image17 from '../../../../../public/assets/images/image17.png'
import image21 from '../../../../../public/assets/images/image21.png'
import image22 from '../../../../../public/assets/images/image22.png'
import image23 from '../../../../../public/assets/images/image23.png'
interface BlogsListProps {
data?: BlogCardProps[],
}
const BLOGSLIST_DATA = [
{
imageSrc: image15.src,
title: "1",
description: "The DEBM diet stands for "+"Delicious Happy Fun Diet"+". This diet was popularized by Robert...",
slug: "happy-diet"
},
{
imageSrc: image16.src,
title: "2",
description: "Aloe vera or aloe vera is a green plant, has thorns on the side of the skin with yellowish patches and...",
slug: "happy-diet"
},
{
imageSrc: image17.src,
title: "3",
description: "Dragon fruit is a type of fruit that is a favorite for many people because of its delicious and fresh...",
slug: "happy-diet"
},
{
imageSrc: image21.src,
title: "4",
description: "The DEBM diet stands for "+"Delicious Happy Fun Diet"+". This diet was popularized by Robert...",
slug: "happy-diet"
},
{
imageSrc: image22.src,
title: "5",
description: "Aloe vera or aloe vera is a green plant, has thorns on the side of the skin with yellowish patches and...",
slug: "happy-diet"
},
{
imageSrc: image23.src,
title: "6",
description: "Dragon fruit is a type of fruit that is a favorite for many people because of its delicious and fresh...",
slug: "happy-diet"
},
{
imageSrc: image15.src,
title: "7",
description: "The DEBM diet stands for "+"Delicious Happy Fun Diet"+". This diet was popularized by Robert...",
slug: "happy-diet"
},
{
imageSrc: image16.src,
title: "8",
description: "Aloe vera or aloe vera is a green plant, has thorns on the side of the skin with yellowish patches and...",
slug: "happy-diet"
},
{
imageSrc: image17.src,
title: "9",
description: "Dragon fruit is a type of fruit that is a favorite for many people because of its delicious and fresh...",
slug: "happy-diet"
},
{
imageSrc: image23.src,
title: "10",
description: "Dragon fruit is a type of fruit that is a favorite for many people because of its delicious and fresh...",
slug: "happy-diet"
},
{
imageSrc: image21.src,
title: "11",
description: "The DEBM diet stands for "+"Delicious Happy Fun Diet"+". This diet was popularized by Robert...",
slug: "happy-diet"
},
{
imageSrc: image22.src,
title: "12",
description: "Aloe vera or aloe vera is a green plant, has thorns on the side of the skin with yellowish patches and...",
slug: "happy-diet"
},
{
imageSrc: image15.src,
title: "13",
description: "The DEBM diet stands for "+"Delicious Happy Fun Diet"+". This diet was popularized by Robert...",
slug: "happy-diet"
},
{
imageSrc: image16.src,
title: "14",
description: "Aloe vera or aloe vera is a green plant, has thorns on the side of the skin with yellowish patches and...",
slug: "happy-diet"
},
{
imageSrc: image17.src,
title: "15",
description: "Dragon fruit is a type of fruit that is a favorite for many people because of its delicious and fresh...",
slug: "happy-diet"
},
{
imageSrc: image21.src,
title: "16",
description: "The DEBM diet stands for "+"Delicious Happy Fun Diet"+". This diet was popularized by Robert...",
slug: "happy-diet"
},
{
imageSrc: image23.src,
title: "17",
description: "Dragon fruit is a type of fruit that is a favorite for many people because of its delicious and fresh...",
slug: "happy-diet"
},
{
imageSrc: image22.src,
title: "18",
description: "Aloe vera or aloe vera is a green plant, has thorns on the side of the skin with yellowish patches and...",
slug: "happy-diet"
},
]
const BlogsList = ({ data = BLOGSLIST_DATA }:BlogsListProps) => {
const [currentPage, setCurrentPage] = useState(0)
const onPageChange = (page:number) => {
setCurrentPage(page)
}
return (
<section>
<div className={s.wrapper}>
<div className={s.list}>
{
data.slice(currentPage*DEFAULT_BLOG_PAGE_SIZE,(currentPage+1)*DEFAULT_BLOG_PAGE_SIZE).map((product,index)=> {
return(
<div className={s.card} key={`${product.title}-${index}`}>
<CardBlog {...product} />
</div>
)
})
}
</div>
<div className={s.pagination}>
<PaginationCommon total={data.length} pageSize={DEFAULT_BLOG_PAGE_SIZE} onChange={onPageChange}/>
</div>
</div>
</section>
)
}
export default BlogsList

View File

@@ -0,0 +1,34 @@
@import "../../../../styles/utilities";
.featuredCard {
@apply flex flex-row justify-center spacing-horizontal pb-16;
.featuredCardWrapper {
@apply flex flex-col;
@screen lg {
@apply flex-row justify-between;
}
max-width: 121.6rem;
}
}
.left {
max-width: 59.8rem;
img {
border-radius: 2.4rem;
}
}
.right {
flex-shrink: 3;
@screen lg {
margin-left: 6.4rem;
}
}
.titleWrapper {
@apply flex flex-col items-start font-heading heading-3;
margin-bottom: 1.6rem;
.title {
margin-top: 0.4rem;
}
}
.content {
margin-top: 1.6rem
}

View File

@@ -0,0 +1,52 @@
import s from './FeaturedCardBlog.module.scss'
import { Author, DateTime } from 'src/components/common'
import Image from "next/image";
import image20 from '../../../../../public/assets/images/image20.png'
import author from '../../../../../public/assets/images/author.png'
interface FeaturedCardBlogProps{
title?: string,
content?: string,
imgSrc?: any,
imgAuthor?: any,
date?: string,
authorName?: string,
}
const FEATURED_DATA = {
title: "Flammekueche with green asparagus",
content: "Traditionally, the Flammekueche is made with rapeseed oil, which, contrary to popular belief, is indeed an oil that can be cooked hot and is not limited to seasoning. It is important to vary the oils in the kitchen to take advantage of the benefits of each. Rapeseed oil is an oil rich in omega 3 which participate in the proper functioning of the cardiovascular system as well as in vitamins E which contributes to the protection of cells against oxidative stress. In short, oils are your friends 😉",
imgSrc: image20,
imgAuthor: author.src,
date: "APRIL 30, 2021",
author: "Alessandro Del Piero"
}
const FeaturedCardBlog = ({
title = FEATURED_DATA.title,
content = FEATURED_DATA.content,
imgSrc = FEATURED_DATA.imgSrc,
imgAuthor = FEATURED_DATA.imgAuthor,
date = FEATURED_DATA.date,
authorName = FEATURED_DATA.author
}: FeaturedCardBlogProps) => {
return (
<section className={s.featuredCard}>
<div className={s.featuredCardWrapper}>
<div className={s.left}>
<Image src={imgSrc} alt="image feature card"/>
</div>
<div className={s.right}>
<div className={s.titleWrapper}>
<DateTime date={date}/>
<a className={s.title}>{title}</a>
</div>
<Author name={authorName} image={imgAuthor}/>
<div className={s.content}>{content}</div>
</div>
</div>
</section>
)
}
export default FeaturedCardBlog

View File

@@ -0,0 +1,4 @@
export { default as FeaturedCardBlog } from './FeaturedCardBlog/FeaturedCardBlog'
export { default as BlogsList } from './BlogsList/BlogsList'
export { default as BlogHeading } from './BlogHeading/BlogHeading'
export { default as BlogBreadCrumb } from './BlogBreadcrumb/BlogBreadcrumb'

View File

@@ -0,0 +1,8 @@
@import "../../../../styles/utilities";
.breadCrumb {
@apply absolute z-10 pt-12 spacing-horizontal;
@screen lg{
padding-left: 3.2rem;
}
}

View File

@@ -0,0 +1,17 @@
import { BreadcrumbCommon } from 'src/components/common'
import s from './DeliveryAndPolicyBreadCrumb.module.scss'
const CRUMB_DATA = [
{
link: "/delivery-policy",
name: "Delivery And Policy"
}
]
const DeliveryAndPolicyBreadCrumb = () => {
return (
<section className={s.breadCrumb}>
<BreadcrumbCommon crumbs={CRUMB_DATA}/>
</section>
)
}
export default DeliveryAndPolicyBreadCrumb

View File

@@ -0,0 +1,26 @@
@import "../../../../styles/utilities";
.wrapper {
@apply flex justify-center pt-20 pb-28 spacing-horizontal;
.deliveryAndPolicyContentWrapper {
max-width: 80.4rem;
min-height: 4rem;
.titleWrapper {
@apply flex flex-col items-start;
.date {
@apply inline flex flex-row;
margin-bottom: 0.4rem;
.update {
@apply uppercase leading-8;
color:var(--text-label);
font-size: 1.2rem;
letter-spacing: 0.01em;
}
}
}
.content {
@apply pb-16 whitespace-pre-line;
padding-top: 1.6rem;
}
}
}

View File

@@ -0,0 +1,81 @@
import { CollapseCommon, DateTime, HeadingCommon } from 'src/components/common'
import s from './DeliveryAndPolicyContent.module.scss'
interface DeliveryAndPolicyContentProps{
title?: string,
date?: string,
content?: string,
}
const HEADER_CONTENT =
`When youre trying to eat healthier but want something more substantial than a leafy green salad, broccoli salad is there for you. I love the crunch and heft of broccoli, especially when its cut up into bite size spoonable pieces.
Some people arent into raw broccoli, but I love it! I always go for the raw broccoli on those vegetable platters that seem to be at every potluck/party you go to.
This is a simple broccoli salad: you have the bulk of it, raw broccoli; crunchy red onions for a bit of acidity and raw crunch, craisins for sweetness, almonds for a nutty counter point; and a sweet and tangy soy-rice vinegar-sesame dressing.`;
const DELIVERYANDPOLICY_DATA = [
{
title: "This is a subtitle",
content: `When youre trying to eat healthier but want something more substantial than a leafy green salad, broccoli salad is there for you. I love the crunch and heft of broccoli, especially when its cut up into bite size spoonable pieces.
Some people arent into raw broccoli, but I love it! I always go for the raw broccoli on those vegetable platters that seem to be at every potluck/party you go to.
This is a simple broccoli salad: you have the bulk of it, raw broccoli; crunchy red onions for a bit of acidity and raw crunch, craisins for sweetness, almonds for a nutty counter point; and a sweet and tangy soy-rice vinegar-sesame dressing.`,
},
{
title: "This is a subtitle",
content: `When youre trying to eat healthier but want something more substantial than a leafy green salad, broccoli salad is there for you. I love the crunch and heft of broccoli, especially when its cut up into bite size spoonable pieces.
Some people arent into raw broccoli, but I love it! I always go for the raw broccoli on those vegetable platters that seem to be at every potluck/party you go to.
This is a simple broccoli salad: you have the bulk of it, raw broccoli; crunchy red onions for a bit of acidity and raw crunch, craisins for sweetness, almonds for a nutty counter point; and a sweet and tangy soy-rice vinegar-sesame dressing.`,
},
{
title: "This is a subtitle",
content: `When youre trying to eat healthier but want something more substantial than a leafy green salad, broccoli salad is there for you. I love the crunch and heft of broccoli, especially when its cut up into bite size spoonable pieces.
Some people arent into raw broccoli, but I love it! I always go for the raw broccoli on those vegetable platters that seem to be at every potluck/party you go to.
This is a simple broccoli salad: you have the bulk of it, raw broccoli; crunchy red onions for a bit of acidity and raw crunch, craisins for sweetness, almonds for a nutty counter point; and a sweet and tangy soy-rice vinegar-sesame dressing.`,
},
{
title: "This is a subtitle",
content: `When youre trying to eat healthier but want something more substantial than a leafy green salad, broccoli salad is there for you. I love the crunch and heft of broccoli, especially when its cut up into bite size spoonable pieces.
Some people arent into raw broccoli, but I love it! I always go for the raw broccoli on those vegetable platters that seem to be at every potluck/party you go to.
This is a simple broccoli salad: you have the bulk of it, raw broccoli; crunchy red onions for a bit of acidity and raw crunch, craisins for sweetness, almonds for a nutty counter point; and a sweet and tangy soy-rice vinegar-sesame dressing.`,
},
{
title: "This is a subtitle",
content: `When youre trying to eat healthier but want something more substantial than a leafy green salad, broccoli salad is there for you. I love the crunch and heft of broccoli, especially when its cut up into bite size spoonable pieces.
Some people arent into raw broccoli, but I love it! I always go for the raw broccoli on those vegetable platters that seem to be at every potluck/party you go to.
This is a simple broccoli salad: you have the bulk of it, raw broccoli; crunchy red onions for a bit of acidity and raw crunch, craisins for sweetness, almonds for a nutty counter point; and a sweet and tangy soy-rice vinegar-sesame dressing.`,
},
]
const DeliveryAndPolicyContent = ( { title="Delivery & Policy", date="APRIL 30, 2021", content = HEADER_CONTENT } : DeliveryAndPolicyContentProps) => {
return (
<section className={s.wrapper}>
<div className={s.deliveryAndPolicyContentWrapper}>
<div className={s.titleWrapper}>
<div className={s.date}>
<div className={s.update}>LASTEST UPDATED:&nbsp;</div>
<DateTime date={date} />
</div>
<HeadingCommon>{title}</HeadingCommon>
</div>
<div className={s.content}>
{content}
</div>
<CollapseCommon data={DELIVERYANDPOLICY_DATA} />
</div>
</section>
)
}
export default DeliveryAndPolicyContent

View File

@@ -0,0 +1,2 @@
export { default as DeliveryAndPolicyContent } from './DeliveryAndPolicyContent/DeliveryAndPolicyContent'
export { default as DeliveryAndPolicyBreadCrumb } from './DeliveryAndPolicyBreadCrumb/DeliveryAndPolicyBreadCrumb'

View File

@@ -116,3 +116,4 @@ export const FEATURED = [
},
]
export const DEFAULT_BLOG_PAGE_SIZE=6;

View File

@@ -12,7 +12,6 @@
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"noUnusedLocals": true,
@@ -26,7 +25,8 @@
"@commerce/*": ["framework/commerce/*"],
"@framework": ["framework/vendure"],
"@framework/*": ["framework/vendure/*"]
}
},
"isolatedModules": true
},
"include": ["next-env.d.ts", "**/*.d.ts", "**/*.ts", "**/*.tsx", "**/*.js"],
"exclude": [