mirror of
https://github.com/vercel/commerce.git
synced 2025-07-21 11:51:20 +00:00
✨ feat: Account Page
This commit is contained in:
parent
dcafcba48b
commit
db1efeada2
@ -13,16 +13,6 @@ interface AccountPageProps {
|
|||||||
|
|
||||||
const AccountPage = ({} : AccountPageProps) => {
|
const AccountPage = ({} : AccountPageProps) => {
|
||||||
const waiting = [
|
const waiting = [
|
||||||
{
|
|
||||||
id: "NO 123456",
|
|
||||||
products: ["Tomato", "Fish", "Pork", "Onion"],
|
|
||||||
totalPrice : 1000
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "NO 123456",
|
|
||||||
products: ["Tomato", "Fish", "Pork", "Onion"],
|
|
||||||
totalPrice : 1000
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: "NO 123456",
|
id: "NO 123456",
|
||||||
products: ["Tomato", "Fish", "Pork", "Onion"],
|
products: ["Tomato", "Fish", "Pork", "Onion"],
|
||||||
@ -31,16 +21,6 @@ const AccountPage = ({} : AccountPageProps) => {
|
|||||||
]
|
]
|
||||||
|
|
||||||
const delivering = [
|
const delivering = [
|
||||||
{
|
|
||||||
id: "NO 123456",
|
|
||||||
products: ["Tomato", "Fish", "Pork", "Onion"],
|
|
||||||
totalPrice : 1000
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "NO 123456",
|
|
||||||
products: ["Tomato", "Fish", "Pork", "Onion"],
|
|
||||||
totalPrice : 1000
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: "NO 123456",
|
id: "NO 123456",
|
||||||
products: ["Tomato", "Fish", "Pork", "Onion"],
|
products: ["Tomato", "Fish", "Pork", "Onion"],
|
||||||
@ -49,16 +29,6 @@ const AccountPage = ({} : AccountPageProps) => {
|
|||||||
]
|
]
|
||||||
|
|
||||||
const delivered = [
|
const delivered = [
|
||||||
{
|
|
||||||
id: "NO 123456",
|
|
||||||
products: ["Tomato", "Fish", "Pork", "Onion"],
|
|
||||||
totalPrice : 1000
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "NO 123456",
|
|
||||||
products: ["Tomato", "Fish", "Pork", "Onion"],
|
|
||||||
totalPrice : 1000
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: "NO 123456",
|
id: "NO 123456",
|
||||||
products: ["Tomato", "Fish", "Pork", "Onion"],
|
products: ["Tomato", "Fish", "Pork", "Onion"],
|
||||||
@ -66,10 +36,12 @@ const AccountPage = ({} : AccountPageProps) => {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
const account = {
|
let account = {
|
||||||
name: "vu duong",
|
name: "vu duong",
|
||||||
email: "vuduong@gmail.com",
|
email: "vuduong@gmail.com",
|
||||||
address: "234 Dien Bien Phu Bis, Dakao ward, District 1, HCMC",
|
address: "234 Dien Bien Phu Bis, Dakao ward",
|
||||||
|
state: "District 1",
|
||||||
|
city: "HCMC",
|
||||||
postalCode: "700000",
|
postalCode: "700000",
|
||||||
phoneNumber: "(+84) 937 937 195"
|
phoneNumber: "(+84) 937 937 195"
|
||||||
}
|
}
|
||||||
@ -117,7 +89,7 @@ const AccountPage = ({} : AccountPageProps) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={s.pageRight}>
|
<div className={s.pageRight}>
|
||||||
<AccountInfomation active={accountInfoActive} account={account} clickShowEditForm={showEditForm} />
|
<AccountInfomation active={accountInfoActive} account={account} showEditForm={showEditForm} />
|
||||||
<OrderInfomation active={orderInfoActive} waiting={waiting} delivering={delivering} delivered={delivered} />
|
<OrderInfomation active={orderInfoActive} waiting={waiting} delivering={delivering} delivered={delivered} />
|
||||||
|
|
||||||
{/* Thieu cai favorite */}
|
{/* Thieu cai favorite */}
|
||||||
@ -126,7 +98,7 @@ const AccountPage = ({} : AccountPageProps) => {
|
|||||||
|
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
<EditInfoModal closeModal={closeModal} visible={modalVisible} />
|
<EditInfoModal accountInfo={account} closeModal={closeModal} visible={modalVisible} />
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -5,12 +5,15 @@ import Image from "next/image"
|
|||||||
import avatar from '../../assets/avatar.png';
|
import avatar from '../../assets/avatar.png';
|
||||||
|
|
||||||
interface AccountInfomationProps {
|
interface AccountInfomationProps {
|
||||||
account: {name: string, email: string, address: string, postalCode: string, phoneNumber: string};
|
account: {name: string, email: string, address: string, state: string, city: string, postalCode: string, phoneNumber: string};
|
||||||
active: boolean;
|
active: boolean;
|
||||||
clickShowEditForm: ()=>void;
|
showEditForm: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const AccountInfomation = ({ account, active=false, clickShowEditForm } : AccountInfomationProps) => {
|
const AccountInfomation = ({ account, active=false, showEditForm } : AccountInfomationProps) => {
|
||||||
|
|
||||||
|
// need to handle call back when edit account information
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className={s.accountInfomation}>
|
<section className={s.accountInfomation}>
|
||||||
{
|
{
|
||||||
@ -31,14 +34,14 @@ const AccountInfomation = ({ account, active=false, clickShowEditForm } : Accoun
|
|||||||
<div className={s.shippingInfo}>Shipping Infomation</div>
|
<div className={s.shippingInfo}>Shipping Infomation</div>
|
||||||
|
|
||||||
<div className={s.accountAddress}>
|
<div className={s.accountAddress}>
|
||||||
{account.address + `, ${account.postalCode}`}
|
{account.address + `, ${account.state}, ${account.city}, ${account.postalCode}`}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={s.accountPhoneNumber}>
|
<div className={s.accountPhoneNumber}>
|
||||||
{account.phoneNumber}
|
{account.phoneNumber}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div onClick={clickShowEditForm} className={s.editInfoBtn}>Edit</div>
|
<div onClick={showEditForm} className={s.editInfoBtn}>Edit</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,13 +10,28 @@
|
|||||||
padding: 1.6rem;
|
padding: 1.6rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.inputState {
|
.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;
|
@apply bg-white;
|
||||||
margin-bottom: 1.6rem;
|
margin-bottom: 1.6rem;
|
||||||
margin-right: 1.6rem;
|
margin-right: 1.6rem;
|
||||||
border: 2px solid #EBEBEB;
|
border: 2px solid #EBEBEB;
|
||||||
border-radius: .8rem;
|
border-radius: .8rem;
|
||||||
padding: 1.6rem;
|
padding: 1.6rem;
|
||||||
|
|
||||||
|
.inputState {
|
||||||
|
@apply bg-white cursor-pointer;
|
||||||
|
border: white;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.inputPostalCode {
|
.inputPostalCode {
|
||||||
@ -43,9 +58,10 @@
|
|||||||
@apply bg-white text-center font-bold;
|
@apply bg-white text-center font-bold;
|
||||||
color: #141414;
|
color: #141414;
|
||||||
border: 1px solid #141414;
|
border: 1px solid #141414;
|
||||||
border-radius: 2.5rem;
|
border-radius: 40% 30% 35% 20%/ 65% 55% 45% 50%;
|
||||||
padding: 1.6rem;
|
padding: 1.6rem;
|
||||||
margin-right: 1.6rem;
|
margin-right: 1.6rem;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
@apply cursor-pointer;
|
@apply cursor-pointer;
|
||||||
@ -56,9 +72,9 @@
|
|||||||
@apply text-center font-bold;
|
@apply text-center font-bold;
|
||||||
background-color: var(--primary);
|
background-color: var(--primary);
|
||||||
color: white;
|
color: white;
|
||||||
border-radius: 2.5rem;
|
border-radius: 40% 30% 35% 20%/ 65% 55% 45% 50%;
|
||||||
padding: 1.6rem;
|
padding: 1.6rem;
|
||||||
|
width: 100%;
|
||||||
&:hover {
|
&:hover {
|
||||||
@apply cursor-pointer;
|
@apply cursor-pointer;
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,24 @@
|
|||||||
import classNames from "classnames"
|
import classNames from "classnames"
|
||||||
import React from "react"
|
import React, { useState } from "react"
|
||||||
import s from './EditInfoModal.module.scss'
|
import s from './EditInfoModal.module.scss'
|
||||||
|
|
||||||
import {ModalCommon, MenuDropdown} from '../../../../../common'
|
import {ModalCommon, MenuDropdown} from '../../../../../common'
|
||||||
|
|
||||||
interface EditInfoModalProps {
|
interface EditInfoModalProps {
|
||||||
|
accountInfo: {name: string, email: string, address: string, state: string, city: string, postalCode: string, phoneNumber: string};
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
closeModal: () => void;
|
closeModal: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const EditInfoModal = ({ visible = false, closeModal }: EditInfoModalProps) => {
|
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() {
|
function saveInfo() {
|
||||||
console.log("saved !!!");
|
console.log("saved !!!");
|
||||||
@ -17,28 +26,48 @@ const EditInfoModal = ({ visible = false, closeModal }: EditInfoModalProps) => {
|
|||||||
closeModal();
|
closeModal();
|
||||||
}
|
}
|
||||||
|
|
||||||
const options = [
|
const states = [
|
||||||
{name: "hihi"},
|
{name: "D1", onClick: () => {setState("D1")}},
|
||||||
{name: "hihi"},
|
{name: "D2", onClick: () => {setState("D2")}},
|
||||||
{name: "hihi"}
|
{name: "D3", onClick: () => {setState("D3")}}
|
||||||
]
|
]
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ModalCommon onClose={closeModal} visible={visible} title="Edit Infomation">
|
<ModalCommon onClose={closeModal} visible={visible} title="Edit Infomation">
|
||||||
<section className={s.editInfoModal}>
|
<section className={s.editInfoModal}>
|
||||||
<div><input className={s.input} type="text" name="" placeholder="Name" /></div>
|
|
||||||
<div><input className={s.input} type="text" name="" placeholder="Email" /></div>
|
|
||||||
<div><input className={s.input} type="text" name="" placeholder="Address" /></div>
|
|
||||||
<div><input className={s.input} type="text" name="" placeholder="City" /></div>
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
{/* <MenuDropdown options={options} isHasArrow={false} > */}
|
<input className={s.input} type="text" name="name" placeholder="Name"
|
||||||
<input className={s.inputState} type="text" name="" placeholder="State" />
|
value={name} onChange={e => {setName(e.target.value)}} />
|
||||||
{/* </MenuDropdown> */}
|
</div>
|
||||||
<input className={s.inputPostalCode} type="text" name="" placeholder="hehe" />
|
<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>
|
||||||
|
|
||||||
<div><input className={s.inputPhoneNumber} type="text" name="" placeholder="Phone number" /></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 className={s.buttons}>
|
||||||
<div onClick={closeModal} className={s.buttonCancel}>Cancel</div>
|
<div onClick={closeModal} className={s.buttonCancel}>Cancel</div>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, {useState} from "react"
|
import React, {useRef, useState, RefObject} from "react"
|
||||||
import s from './OrderInformation.module.scss'
|
import s from './OrderInformation.module.scss'
|
||||||
|
|
||||||
import { TabCommon } from '../../../../../common'
|
import { TabCommon } from '../../../../../common'
|
||||||
@ -14,12 +14,31 @@ interface OrderInformationProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const OrderInformation = ({ waiting, delivering, delivered, active=true } : OrderInformationProps) => {
|
const OrderInformation = ({ waiting, delivering, delivered, active=true } : OrderInformationProps) => {
|
||||||
const [activeTabPane, setActiveTabPane] = useState("waiting");
|
|
||||||
|
|
||||||
function changeTabPane(tab: string) {
|
const [activeTab, setActiveTab] = useState(0);
|
||||||
setActiveTabPane(tab);
|
const [activeTabPane, setActiveTabPane] = useState("waiting");
|
||||||
|
const slider = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
function slide(ref: RefObject<HTMLLIElement>) {
|
||||||
|
const width = ref.current.offsetWidth;
|
||||||
|
const left = ref.current.offsetLeft;
|
||||||
|
|
||||||
|
slider.current.style.width = (width-48).toString()+"px";
|
||||||
|
slider.current.style.left = left.toString()+"px";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onTabClick(tabIndex: number, tabPane: string) {
|
||||||
|
setActiveTab(tabIndex);
|
||||||
|
setActiveTabPane(tabPane);
|
||||||
|
slide(tabs[tabIndex].ref)
|
||||||
|
}
|
||||||
|
|
||||||
|
const tabs = [
|
||||||
|
{ref: useRef<HTMLLIElement>(null), tabName: "Wait for comfirmation", active: activeTab === 0, onClick: () => onTabClick(0, "waiting") },
|
||||||
|
{ref: useRef<HTMLLIElement>(null), tabName: "Delivering", active: activeTab === 1, onClick: () => onTabClick(1, "delivering") },
|
||||||
|
{ref: useRef<HTMLLIElement>(null), tabName: "Delivered", active: activeTab === 2, onClick: () => onTabClick(2, "delivered") },
|
||||||
|
]
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className={s.orderInformation}>
|
<section className={s.orderInformation}>
|
||||||
{
|
{
|
||||||
@ -27,7 +46,7 @@ const OrderInformation = ({ waiting, delivering, delivered, active=true } : Orde
|
|||||||
<div className={s.title}>Order Information</div>
|
<div className={s.title}>Order Information</div>
|
||||||
|
|
||||||
<div className={s.tabs}>
|
<div className={s.tabs}>
|
||||||
<TabCommon changeTabPane={changeTabPane} />
|
<TabCommon tabs={tabs} defaultActiveTab={activeTab} sliderRef={slider} slideToTab={slide} />
|
||||||
|
|
||||||
<div className={s.tabPanes}>
|
<div className={s.tabPanes}>
|
||||||
<TabPane active={activeTabPane==="waiting" ? `active` : ""}>
|
<TabPane active={activeTabPane==="waiting" ? `active` : ""}>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user