mirror of
https://github.com/vercel/commerce.git
synced 2025-07-22 20:26:49 +00:00
init: PaymentInfoForm
This commit is contained in:
@@ -1,17 +1,12 @@
|
|||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import {
|
import {
|
||||||
CardItemCheckout,
|
|
||||||
CheckoutBill,
|
CheckoutBill,
|
||||||
CustomerInfoForm,
|
|
||||||
Layout,
|
Layout,
|
||||||
ShippingInfoForm,
|
|
||||||
} from 'src/components/common'
|
} from 'src/components/common'
|
||||||
import { CardItemCheckoutProps } from 'src/components/common/CardItemCheckout/CardItemCheckout'
|
import { CardItemCheckoutProps } from 'src/components/common/CardItemCheckout/CardItemCheckout'
|
||||||
import CheckoutCollapse from 'src/components/common/CheckoutCollapse/CheckoutCollapse'
|
import TabPane from 'src/components/common/TabCommon/components/TabPane/TabPane'
|
||||||
import PaginationCommon from 'src/components/common/PaginationCommon/PaginationCommon'
|
import TabCommon from 'src/components/common/TabCommon/TabCommon'
|
||||||
import { CheckoutInfo } from 'src/components/modules/checkout'
|
import { CheckoutInfo } from 'src/components/modules/checkout'
|
||||||
import image5 from '../public/assets/images/image5.png'
|
|
||||||
import image6 from '../public/assets/images/image6.png'
|
|
||||||
import image7 from '../public/assets/images/image7.png'
|
import image7 from '../public/assets/images/image7.png'
|
||||||
import image8 from '../public/assets/images/image8.png'
|
import image8 from '../public/assets/images/image8.png'
|
||||||
const dataTest:CardItemCheckoutProps[] = [
|
const dataTest:CardItemCheckoutProps[] = [
|
||||||
@@ -43,27 +38,34 @@ const dataTest:CardItemCheckoutProps[] = [
|
|||||||
quantity:2
|
quantity:2
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
export default function Test() {
|
export default function Test() {
|
||||||
const [visible, setVisible] = useState(false)
|
|
||||||
const onClose = () => {
|
|
||||||
setVisible(false)
|
|
||||||
}
|
|
||||||
const onOpen = () => {
|
|
||||||
setVisible(true)
|
|
||||||
}
|
|
||||||
const [visible2, setVisible2] = useState(false)
|
|
||||||
const onClose2 = () => {
|
|
||||||
setVisible2(false)
|
|
||||||
}
|
|
||||||
const onOpen2 = () => {
|
|
||||||
setVisible2(true)
|
|
||||||
}
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="w-full flex justify-between" style={{padding: "0 3.2rem"}} >
|
<div className="w-full flex justify-between" style={{padding: "0 3.2rem"}} >
|
||||||
<CheckoutInfo/>
|
<CheckoutInfo/>
|
||||||
<CheckoutBill data={dataTest}/>
|
<CheckoutBill data={dataTest}/>
|
||||||
</div>
|
</div>
|
||||||
|
<TabCommon center={true}>
|
||||||
|
<TabPane
|
||||||
|
active={true}
|
||||||
|
tabName={'dat datdat datdatdatdatdatdat'}
|
||||||
|
>
|
||||||
|
<div className="w-full">
|
||||||
|
datdatdatdatdatdatdatdatdatdatdatdatdatdatdatdatdatdatdatdatdatdatdatdatdatdatdatdatdatdatdatdatdatdatdatdat
|
||||||
|
</div>
|
||||||
|
</TabPane>
|
||||||
|
<TabPane active={true} tabName={'1234567890'}>
|
||||||
|
<div className="w-full">
|
||||||
|
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Suscipit harum sint maiores optio? Perspiciatis, necessitatibus pariatur, ut sed aperiam minus reiciendis alias deleniti eligendi obcaecati illum id maxime accusantium beatae.
|
||||||
|
</div>
|
||||||
|
</TabPane>
|
||||||
|
<TabPane active={true} tabName={'1'}>
|
||||||
|
<div className="w-full">
|
||||||
|
11111111111111111111111111111111111111111111111111111111111
|
||||||
|
</div>
|
||||||
|
</TabPane>
|
||||||
|
</TabCommon>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@@ -1,15 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import TabCommon from 'src/components/common/TabCommon/TabCommon'
|
|
||||||
|
|
||||||
interface PaymentInfoFormProps {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const PaymentInfoForm = ({}: PaymentInfoFormProps) => {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default PaymentInfoForm
|
|
@@ -1,21 +1,28 @@
|
|||||||
@import '../../../styles/utilities';
|
@import '../../../styles/utilities';
|
||||||
|
.tabWapper{
|
||||||
.tabCommon {
|
@apply flex flex-col w-full;
|
||||||
@apply flex;
|
.tabHeader{
|
||||||
position: relative;
|
@apply relative;
|
||||||
border-bottom: 2px solid #FBFBFB;
|
.tabList {
|
||||||
padding-top: 1.6rem;
|
@apply flex;
|
||||||
padding-bottom: 1.6rem;
|
position: relative;
|
||||||
width: 100%;
|
border-bottom: 2px solid #FBFBFB;
|
||||||
|
padding: 0.8rem 0;
|
||||||
.slider {
|
width: 100%;
|
||||||
@apply inline-block;
|
&.center{
|
||||||
height: .2rem;
|
@apply justify-center;
|
||||||
border-radius: 3px;
|
}
|
||||||
background-color: var(--primary);
|
|
||||||
position: absolute;
|
}
|
||||||
z-index: 1200;
|
.slider {
|
||||||
bottom: 0;
|
@apply inline-block;
|
||||||
transition: all .4s linear;
|
height: .2rem;
|
||||||
|
border-radius: 3px;
|
||||||
|
background-color: var(--primary);
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1200;
|
||||||
|
bottom: 0;
|
||||||
|
transition: all .25s linear;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,36 +1,85 @@
|
|||||||
import React, { RefObject, useEffect } from "react"
|
import React, {
|
||||||
|
Children,
|
||||||
|
PropsWithChildren,
|
||||||
|
ReactElement,
|
||||||
|
RefObject,
|
||||||
|
useEffect,
|
||||||
|
useRef,
|
||||||
|
useState,
|
||||||
|
cloneElement,
|
||||||
|
} from 'react'
|
||||||
import s from './TabCommon.module.scss'
|
import s from './TabCommon.module.scss'
|
||||||
|
|
||||||
import TabItem from './components/TabItem/TabItem'
|
import TabItem from './components/TabItem/TabItem'
|
||||||
|
import { TabPaneProps } from './components/TabPane/TabPane'
|
||||||
|
import classNames from 'classnames'
|
||||||
|
|
||||||
interface TabCommonProps {
|
interface TabCommonProps {
|
||||||
tabs: {ref:RefObject<HTMLLIElement>, tabName: string, active: boolean, onClick: (tabIndex: number, tabPane?: string) => void}[];
|
defaultActiveTab?: number
|
||||||
defaultActiveTab: number;
|
children: React.ReactNode
|
||||||
sliderRef : RefObject<HTMLDivElement>;
|
center?:boolean
|
||||||
slideToTab: (ref: any) => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const TabCommon = ({ tabs, defaultActiveTab, sliderRef, slideToTab } : TabCommonProps) => {
|
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(() => {
|
useEffect(() => {
|
||||||
slideToTab(tabs[defaultActiveTab].ref);
|
slide(active)
|
||||||
}, [])
|
}, [active])
|
||||||
|
|
||||||
return (
|
function slide(index: number) {
|
||||||
<ul className={s.tabCommon}>
|
const active = headerRef.current?.children
|
||||||
{
|
.item(index)
|
||||||
tabs.map((tab) => {
|
?.getBoundingClientRect()
|
||||||
return (
|
const current = slider.current
|
||||||
<li key={tab.tabName} ref={tab.ref}>
|
if (current && active) {
|
||||||
<TabItem onClick={tab.onClick} active={tab.active}>{tab.tabName}</TabItem>
|
let width = active.width - 24 <= 0 ? 24 : active.width - 24
|
||||||
</li>
|
let left = active.left
|
||||||
)
|
current.style.width = width.toString() + 'px'
|
||||||
})
|
current.style.left = left.toString() + 'px'
|
||||||
}
|
}
|
||||||
|
}
|
||||||
<div ref={sliderRef} className={s.slider}></div>
|
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>
|
||||||
|
)
|
||||||
|
})}
|
||||||
</ul>
|
</ul>
|
||||||
)
|
<div ref={slider} className={s.slider}></div>
|
||||||
|
</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
|
||||||
|
@@ -1,22 +1,14 @@
|
|||||||
@import '../../../../styles/utilities';
|
@import '../../../../../styles/utilities';
|
||||||
|
|
||||||
.tabItem {
|
.tabItem {
|
||||||
margin-right: 4.8rem;
|
margin-right:2.4rem;
|
||||||
padding-top: 1.6rem;
|
padding: 0.8rem 0;
|
||||||
padding-bottom: 1.6rem;
|
min-width: 2.4rem;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
@apply cursor-pointer;
|
@apply cursor-pointer;
|
||||||
}
|
}
|
||||||
}
|
&.tabItemActive {
|
||||||
|
@apply font-bold;
|
||||||
.tabItemActive {
|
|
||||||
@apply font-bold;
|
|
||||||
margin-right: 4.8rem;
|
|
||||||
padding-top: 1.6rem;
|
|
||||||
padding-bottom: 1.6rem;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
@apply cursor-pointer;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,19 +1,32 @@
|
|||||||
import React from "react"
|
import classNames from 'classnames'
|
||||||
|
import React, { RefObject, useRef } from 'react'
|
||||||
import s from './TabItem.module.scss'
|
import s from './TabItem.module.scss'
|
||||||
|
|
||||||
interface TabItemProps {
|
interface TabItemProps {
|
||||||
active: boolean;
|
active: boolean
|
||||||
children: string;
|
children: string
|
||||||
onClick: (tabIndex: number, tabPane: string) => void;
|
onClick?: (tabIndex: number) => void
|
||||||
|
tabIndex: number
|
||||||
}
|
}
|
||||||
|
|
||||||
const TabItem = ({ active = false, children, onClick } : TabItemProps) => {
|
const TabItem = ({
|
||||||
|
active = false,
|
||||||
return (
|
children,
|
||||||
<span onClick={onClick} className={active ? s.tabItemActive : s.tabItem} >
|
onClick,
|
||||||
{children}
|
tabIndex,
|
||||||
</span>
|
}: TabItemProps) => {
|
||||||
)
|
const handleClick = () => {
|
||||||
|
onClick && onClick(tabIndex)
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<span
|
||||||
|
onClick={handleClick}
|
||||||
|
// className={active ? s.tabItemActive : s.tabItem}
|
||||||
|
className={classNames(s.tabItem, {[s.tabItemActive]:active})}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</span>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TabItem;
|
export default TabItem
|
||||||
|
@@ -1,20 +1,20 @@
|
|||||||
@import '../../../../../../styles/utilities';
|
@import "../../../../../styles/utilities";
|
||||||
|
|
||||||
.tabPane {
|
.tabPane {
|
||||||
@apply hidden;
|
@apply hidden;
|
||||||
animation-duration: 0.6s;
|
transition: all 0.6s;
|
||||||
animation-name: appear;
|
// animation-duration: 0.6s;
|
||||||
@keyframes appear {
|
// animation-name: appear;
|
||||||
from {
|
// @keyframes appear {
|
||||||
margin-left: 100%;
|
// from {
|
||||||
width: 200%;
|
// margin-left: 100%;
|
||||||
}
|
// width: 200%;
|
||||||
|
// }
|
||||||
|
|
||||||
to {
|
// to {
|
||||||
margin-left: 0%;
|
// margin-left: 0%;
|
||||||
width: 100%;
|
// width: 100%;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
|
@@ -2,15 +2,16 @@ import classNames from "classnames"
|
|||||||
import React from "react"
|
import React from "react"
|
||||||
import s from './TabPane.module.scss'
|
import s from './TabPane.module.scss'
|
||||||
|
|
||||||
interface TabPaneProps {
|
export interface TabPaneProps {
|
||||||
active: string;
|
active: boolean;
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
|
tabName: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const TabPane = ({ active="", children } : TabPaneProps) => {
|
const TabPane = ({ active, children } : TabPaneProps) => {
|
||||||
return (
|
return (
|
||||||
<section className={classNames(s.tabPane, {
|
<section className={classNames(s.tabPane, {
|
||||||
[s[active]] : active
|
[s.active] : active
|
||||||
})}>
|
})}>
|
||||||
{children}
|
{children}
|
||||||
</section>
|
</section>
|
||||||
|
@@ -37,9 +37,6 @@ export { default as CardBlog} from './CardBlog/CardBlog'
|
|||||||
export { default as RelevantBlogPosts} from './RelevantBlogPosts/RelevantBlogPosts'
|
export { default as RelevantBlogPosts} from './RelevantBlogPosts/RelevantBlogPosts'
|
||||||
export { default as CollapseCommon} from './CollapseCommon/CollapseCommon'
|
export { default as CollapseCommon} from './CollapseCommon/CollapseCommon'
|
||||||
export { default as CheckoutBill} from './CheckoutBill/CheckoutBill'
|
export { default as CheckoutBill} from './CheckoutBill/CheckoutBill'
|
||||||
export { default as CustomerInfoForm} from './CustomerInfoForm/CustomerInfoForm'
|
|
||||||
export { default as ShippingInfoForm} from './ShippingInfoForm/ShippingInfoForm'
|
|
||||||
export { default as PaymentInfoForm} from './PaymentInfoForm/PaymentInfoForm'
|
|
||||||
export { default as ImgWithLink} from './ImgWithLink/ImgWithLink'
|
export { default as ImgWithLink} from './ImgWithLink/ImgWithLink'
|
||||||
export { default as RecipeDetail} from './RecipeDetail/RecipeDetail'
|
export { default as RecipeDetail} from './RecipeDetail/RecipeDetail'
|
||||||
export { default as DrawerCommon} from './DrawerCommon/DrawerCommon'
|
export { default as DrawerCommon} from './DrawerCommon/DrawerCommon'
|
||||||
|
@@ -1,8 +1,10 @@
|
|||||||
import React, { useState } from 'react'
|
import React, { useState } from 'react'
|
||||||
import { CustomerInfoForm, Logo, ShippingInfoForm } from 'src/components/common'
|
import { Logo } from 'src/components/common'
|
||||||
import CheckoutCollapse from 'src/components/common/CheckoutCollapse/CheckoutCollapse'
|
import CheckoutCollapse from 'src/components/common/CheckoutCollapse/CheckoutCollapse'
|
||||||
import { CheckOutForm } from 'src/utils/types.utils'
|
import { CheckOutForm } from 'src/utils/types.utils'
|
||||||
import s from './CheckoutInfo.module.scss'
|
import s from './CheckoutInfo.module.scss'
|
||||||
|
import CustomerInfoForm from './components/CustomerInfoForm/CustomerInfoForm'
|
||||||
|
import ShippingInfoForm from './components/ShippingInfoForm/ShippingInfoForm'
|
||||||
interface CheckoutInfoProps {}
|
interface CheckoutInfoProps {}
|
||||||
|
|
||||||
const CheckoutInfo = ({}: CheckoutInfoProps) => {
|
const CheckoutInfo = ({}: CheckoutInfoProps) => {
|
||||||
|
@@ -0,0 +1,9 @@
|
|||||||
|
.warpper{
|
||||||
|
.title{
|
||||||
|
min-width: 19.4rem;
|
||||||
|
@apply text-label;
|
||||||
|
}
|
||||||
|
.hightlight{
|
||||||
|
@apply text-active;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,24 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import s from './BankTransfer.module.scss'
|
||||||
|
interface BankTransferProps {}
|
||||||
|
|
||||||
|
const BankTransfer = ({}: BankTransferProps) => {
|
||||||
|
return (
|
||||||
|
<div className={s.warpper}>
|
||||||
|
<div className={s.line}>
|
||||||
|
<div className={s.title}>Account Name:</div>
|
||||||
|
<div className={s.hightlight}>Duong Dinh Vu</div>
|
||||||
|
</div>
|
||||||
|
<div className={s.line}>
|
||||||
|
<div className={s.title}>Account Number:</div>
|
||||||
|
<div className={s.hightlight}>1234 1234 1234 1234</div>
|
||||||
|
</div>
|
||||||
|
<div className={s.line}>
|
||||||
|
<div className={s.title}>Bank Name:</div>
|
||||||
|
<div className={s.hightlight}>Techcombank - HCMC</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default BankTransfer
|
@@ -1,4 +1,4 @@
|
|||||||
@import "../../../styles/utilities";
|
@import "../../../../../../styles/utilities";
|
||||||
.warpper{
|
.warpper{
|
||||||
@apply u-form;
|
@apply u-form;
|
||||||
padding: 0 5.6rem;
|
padding: 0 5.6rem;
|
@@ -0,0 +1,21 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import TabPane from 'src/components/common/TabCommon/components/TabPane/TabPane'
|
||||||
|
import TabCommon from 'src/components/common/TabCommon/TabCommon'
|
||||||
|
import s from "./PaymentInfoForm.module.scss"
|
||||||
|
interface PaymentInfoFormProps {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const PaymentInfoForm = ({}: PaymentInfoFormProps) => {
|
||||||
|
return (
|
||||||
|
<div className={s.warpper}>
|
||||||
|
<TabCommon>
|
||||||
|
{/* <TabPane tabName="Bank Transfer">
|
||||||
|
|
||||||
|
</TabPane> */}
|
||||||
|
</TabCommon>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PaymentInfoForm
|
@@ -1,4 +1,4 @@
|
|||||||
@import "../../../styles/utilities";
|
@import "../../../../../../styles/utilities";
|
||||||
|
|
||||||
.warpper{
|
.warpper{
|
||||||
@apply u-form;
|
@apply u-form;
|
Reference in New Issue
Block a user