You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
675 lines
20 KiB
675 lines
20 KiB
import React, { useState, useEffect } from "react"; |
|
import { connect } from "react-redux"; |
|
import { useNavigate, useLocation } from "react-router-dom"; |
|
import { publicApi, userAddress, dialog, user } from "../../redux/actions"; |
|
import onInput from "../../utils/onInput"; |
|
import location from "../../utils/location"; |
|
import Input from "../../components/Input"; |
|
import Select from "../../components/Select"; |
|
import Button from "../../components/Button"; |
|
import ReverseMap from "../../components/ReverseMap"; |
|
import Loading from "../../components/Loading"; |
|
import Radio from "../../components/Radio"; |
|
|
|
//assets |
|
import dropdownIcon from "../../assets/icons/white-dropdown.svg"; |
|
import lightGreenArrow from "../../assets/icons/light-green-arrow.svg"; |
|
|
|
import arrowBlueIcon from "../../assets/icons/arrow-right-blue.svg"; |
|
import arrowWhiteIcon from "../../assets/icons/arrow-left-white.svg"; |
|
|
|
export const Address = ({ |
|
city, |
|
province, |
|
getCity, |
|
getProvince, |
|
provinces, |
|
cities, |
|
createAddress, |
|
loading, |
|
setPhase, |
|
cityLoading, |
|
isMobile, |
|
isDark, |
|
setDialog, |
|
profilePage, |
|
editPage, |
|
setProfileFields, |
|
profileFields, |
|
setProfile, |
|
user, |
|
setHeaderOptions, |
|
headerOptions, |
|
getAddress, |
|
addressInfo, |
|
updateAddress, |
|
}) => { |
|
const [addressFields, setAddressFields] = useState({}); |
|
const [mapAddress, setMapAddress] = useState(null); |
|
const navigation = useNavigate(); |
|
const location = useLocation(); |
|
console.log({ provinces }); |
|
useEffect(() => { |
|
setHeaderOptions(headerOptions); |
|
if (province.length <= 1) { |
|
getProvince(); |
|
} |
|
if (isMobile) { |
|
if (editPage || profilePage) { |
|
setHeaderOptions(headerOptions); |
|
} else { |
|
setHeaderOptions({ |
|
shown: true, |
|
back: true, |
|
title: "آدرس", |
|
}); |
|
} |
|
} |
|
if (editPage) { |
|
getAddress({ id: location.getId() }); |
|
} |
|
}, []); |
|
|
|
useEffect(() => { |
|
if (editPage && addressInfo) { |
|
const { |
|
firstName, |
|
lastName, |
|
cellphone, |
|
phone, |
|
provinceId, |
|
address, |
|
cityId, |
|
postalCode, |
|
} = addressInfo; |
|
setAddressFields({ |
|
firstName, |
|
lastName, |
|
cellphone, |
|
phone, |
|
provinceId, |
|
cityId, |
|
postalCode, |
|
}); |
|
setMapAddress(address); |
|
} |
|
}, [addressInfo]); |
|
|
|
useEffect(() => { |
|
if (addressFields?.provinceId) { |
|
console.log({ addressFields }); |
|
getCity({ |
|
provinceId: addressFields?.provinceId, |
|
}); |
|
} |
|
}, [addressFields]); |
|
|
|
useEffect(() => { |
|
if (profileFields?.provinceId) { |
|
getCity({ |
|
provinceId: profileFields?.provinceId, |
|
}); |
|
} |
|
}, [profileFields]); |
|
|
|
const onChange = (name, value) => { |
|
console.log({ name, value }); |
|
setAddressFields({ ...addressFields, [name]: value }); |
|
}; |
|
|
|
const submitProfile = () => { |
|
if (user.cellphone && user.cellphone.length < 11) { |
|
setDialog({ |
|
text: "شماره موبایل خود را وارد کنید.", |
|
type: "alert", |
|
accept: () => {}, |
|
open: true, |
|
}); |
|
return; |
|
} |
|
const postalCode = profileFields?.postalCode || user.postalCode; |
|
if (postalCode && postalCode.length < 10) { |
|
setDialog({ |
|
text: "شماره کد پستی خود را وارد کنید.", |
|
type: "alert", |
|
accept: () => {}, |
|
open: true, |
|
}); |
|
return; |
|
} |
|
const data = { |
|
firstName: profileFields?.firstName || user.firstName, |
|
lastName: profileFields?.lastName || user.lastName, |
|
username: profileFields?.username || user.username, |
|
cellphone: user.cellphone, |
|
password: profileFields?.password || user.password, |
|
postalCode, |
|
address: profileFields?.address || user.address, |
|
email: profileFields?.email || user.email, |
|
phone: profileFields?.phone || user.phone, |
|
nationalId: profileFields?.nationalId || user.nationalId, |
|
picFileId: profileFields?.picFileId || user.picFileId, |
|
gender: profileFields?.gender || user.gender, |
|
birthDate: profileFields?.birthDate || user.birthDate, |
|
schools: profileFields?.schools || user.schools, |
|
gradeIds: profileFields?.gradeIds || user.gradeIds, |
|
provinceId: profileFields?.provinceId || user.provinceId, |
|
cityId: profileFields?.cityId || user.cityId, |
|
docFileIds: profileFields?.docFileIds || user.docFileIds, |
|
}; |
|
setProfile(data); |
|
}; |
|
|
|
const [activeCheckbox, setActiveCheckbox] = useState(true); |
|
|
|
const submit = () => { |
|
const { |
|
firstName, |
|
lastName, |
|
cellphone, |
|
phone, |
|
address, |
|
provinceId, |
|
cityId, |
|
postalCode, |
|
} = addressFields; |
|
|
|
if (!activeCheckbox && !firstName) { |
|
setDialog({ |
|
text: "نام خود را وارد کنید.", |
|
type: "alert", |
|
accept: () => {}, |
|
open: true, |
|
}); |
|
return; |
|
} |
|
if (!activeCheckbox && !lastName) { |
|
setDialog({ |
|
text: "نام خانوادگی خود را وارد کنید.", |
|
type: "alert", |
|
accept: () => {}, |
|
open: true, |
|
}); |
|
return; |
|
} |
|
if (!activeCheckbox && (!cellphone || cellphone.length < 11)) { |
|
setDialog({ |
|
text: "شماره موبایل خود را وارد کنید.", |
|
type: "alert", |
|
accept: () => {}, |
|
open: true, |
|
}); |
|
return; |
|
} |
|
if (!activeCheckbox && !phone) { |
|
setDialog({ |
|
text: "شماره تلفن خود را وارد کنید.", |
|
type: "alert", |
|
accept: () => {}, |
|
open: true, |
|
}); |
|
return; |
|
} |
|
if (!provinceId) { |
|
setDialog({ |
|
text: "نام استان خود را وارد کنید.", |
|
type: "alert", |
|
accept: () => {}, |
|
open: true, |
|
}); |
|
return; |
|
} |
|
if (!cityId) { |
|
setDialog({ |
|
text: "نام شهرستان خود را وارد کنید.", |
|
type: "alert", |
|
accept: () => {}, |
|
open: true, |
|
}); |
|
return; |
|
} |
|
if (!postalCode || postalCode.length < 10) { |
|
setDialog({ |
|
text: "کد پستی خود را وارد کنید.", |
|
type: "alert", |
|
accept: () => {}, |
|
open: true, |
|
}); |
|
return; |
|
} |
|
if (!mapAddress) { |
|
setDialog({ |
|
text: "آدرس خود را از روی نقشه انتخاب کن", |
|
type: "alert", |
|
accept: () => {}, |
|
open: true, |
|
}); |
|
return; |
|
} |
|
if (editPage) { |
|
updateAddress({ |
|
id: addressInfo.id, |
|
firstName, |
|
lastName, |
|
cellphone, |
|
phone, |
|
address: mapAddress, |
|
provinceId, |
|
cityId, |
|
postalCode, |
|
location: null, |
|
}); |
|
} else { |
|
createAddress({ |
|
firstName, |
|
lastName, |
|
cellphone, |
|
phone, |
|
address: mapAddress, |
|
provinceId, |
|
cityId, |
|
postalCode, |
|
location: null, |
|
}); |
|
} |
|
|
|
if (editPage) { |
|
navigation(-1); |
|
} else { |
|
setPhase("deliveryForm"); |
|
} |
|
}; |
|
|
|
const Header = ({ title, text }) => { |
|
return ( |
|
<div className="flex flex-col lg:flex-row lg:items-center gap-2 lg:mb-4 mt-2 lg:mt-0"> |
|
<strong className="text-green4F text-base dark:text-white"> |
|
{title} |
|
</strong> |
|
<p className="mt-1 inline flex-1 text-sm text-gray70 dark:text-white"> |
|
{text} |
|
</p> |
|
</div> |
|
); |
|
}; |
|
console.log({ state: location?.state }); |
|
|
|
return ( |
|
<div |
|
className={`flex flex-col lg:flex-row-reverse px-4 flex-1 lg:pt-0 pb-20 gap-5 lg:divide-x lg:divide-solid lg:divide-gray-200 ${ |
|
location?.state?.panel === isMobile ? "mt-2" : "mt-32 px-10" |
|
} `} |
|
// style={{ minHeight: "calc(100vh - 500px)" }} |
|
> |
|
{!profilePage && ( |
|
<div className="flex flex-col w-full lg:w-1/2"> |
|
<Input |
|
width="100%" |
|
label={"ادرس انتخاب شده در نقشه"} |
|
regex={(val) => onInput.numberOnly(val)} |
|
name="address" |
|
onChange={(name, value) => setMapAddress(value)} |
|
value={mapAddress} |
|
align="text-right" |
|
direction="rtl" |
|
/> |
|
<div |
|
className="w-full overflow-hidden rounded-md mt-6" |
|
style={{ height: isMobile ? "calc(100vh / 4)" : "calc(100vh / 2)" }} |
|
> |
|
<ReverseMap setAddress={(val) => setMapAddress(val)} /> |
|
</div> |
|
<div className="hidden lg:flex w-full items-end mt-8 flex-col"> |
|
<div className="flex flex-col items-cente w-2/5"> |
|
<Button |
|
loading={loading} |
|
title="ثبت آدرس" |
|
backgroundColor="bg-blueC0" |
|
border={{ color: "#196EC055", width: "0px" }} |
|
width="100%" |
|
color="text-white" |
|
onClick={() => submit()} |
|
/> |
|
<button |
|
className="bg-transparent mt-4 text-base lg:text-tiny border border-blueC0 text-blueC0 font-bold rounded-md py-3.5 lg:py-4 flex flex-row justify-center items-center" |
|
onClick={() => setPhase("deliveryForm")} |
|
> |
|
بازگشت |
|
<img |
|
src={dropdownIcon} |
|
alt="" |
|
className="w-4 transform rotate-90" |
|
/> |
|
</button> |
|
</div> |
|
</div> |
|
</div> |
|
)} |
|
|
|
<div |
|
className={`flex flex-col w-full lg:w-1/2 lg:pl-4 ${ |
|
profilePage ? "mx-auto" : "" |
|
}`} |
|
> |
|
{!profilePage && ( |
|
<> |
|
<div className="flex item-center gap-x-4"> |
|
{/* my self */} |
|
<div |
|
className={`flex flex-row items-center mb-7 cursor-pointer |
|
`} |
|
onClick={() => { |
|
setActiveCheckbox(true); |
|
}} |
|
> |
|
<div className="w-4 h-4 flex flex-col items-center justify-center ml-1 bg-gray-200 rounded-full"> |
|
<div |
|
className={`w-2 h-2 rounded-full ${ |
|
activeCheckbox === true ? "bg-blueC0" : "" |
|
}`} |
|
></div> |
|
</div> |
|
<p className="font-bold text-sm">برای خودم</p> |
|
</div> |
|
{/* someone else */} |
|
<div |
|
className={`flex flex-row items-center mb-7 cursor-pointer |
|
`} |
|
onClick={() => { |
|
setActiveCheckbox(false); |
|
}} |
|
> |
|
<div className="w-4 h-4 flex flex-col items-center justify-center ml-1 bg-gray-200 rounded-full"> |
|
<div |
|
className={`w-2 h-2 rounded-full ${ |
|
activeCheckbox === false ? "bg-blueC0" : "" |
|
}`} |
|
></div> |
|
</div> |
|
<p className="font-bold text-sm ">گیرنده فرد دیگری است</p> |
|
</div> |
|
</div> |
|
</> |
|
)} |
|
|
|
{profilePage || activeCheckbox === false ? ( |
|
<> |
|
<Header |
|
title="اطلاعات هویتی" |
|
text="( لطفا نام و نام خانوادگی خود را به طور کامل وارد نمایید )" |
|
/> |
|
|
|
<div className="flex flex-col lg:flex-row items-center lg:gap-5 w-full mb-4"> |
|
<Input |
|
width={isMobile ? "100%" : "50%"} |
|
label={"نام"} |
|
regex={(val) => val} |
|
name="firstName" |
|
onChange={(name, value) => |
|
profilePage |
|
? setProfileFields({ ...profileFields, firstName: value }) |
|
: onChange(name, value) |
|
} |
|
value={ |
|
profilePage |
|
? profileFields.firstName || user.firstName |
|
: addressFields?.firstName |
|
} |
|
align="text-right" |
|
direction="rtl" |
|
/> |
|
|
|
<Input |
|
width={isMobile ? "100%" : "50%"} |
|
label={"نام خانوادگی"} |
|
regex={(val) => val} |
|
name="lastName" |
|
onChange={(name, value) => |
|
profilePage |
|
? setProfileFields({ ...profileFields, lastName: value }) |
|
: onChange(name, value) |
|
} |
|
value={ |
|
profilePage |
|
? profileFields.lastName || user.lastName |
|
: addressFields?.lastName |
|
} |
|
align="text-right" |
|
direction="rtl" |
|
/> |
|
</div> |
|
|
|
<Header |
|
title="شماره تماس" |
|
text="( شماره موبایل و شماره تلفن ثابت خود را |
|
به همراه پیش شماره وارد کنید )" |
|
/> |
|
|
|
<div className="flex flex-col lg:flex-row items-center lg:gap-5 w-full mb-4"> |
|
<Input |
|
width={isMobile ? "100%" : "50%"} |
|
label={"شماره موبایل"} |
|
regex={(val) => onInput.phonenumber(val)} |
|
name="cellphone" |
|
value={ |
|
profilePage |
|
? profileFields.cellphone || user.cellphone |
|
: addressFields?.cellphone |
|
} |
|
onChange={(name, value) => |
|
profilePage |
|
? setProfileFields({ ...profileFields, cellphone: value }) |
|
: onChange(name, value) |
|
} |
|
align="text-right" |
|
direction="ltr" |
|
maxLength={11} |
|
/> |
|
<Input |
|
width={isMobile ? "100%" : "50%"} |
|
label={"شماره تلفن"} |
|
regex={(val) => onInput.numberOnly(val)} |
|
name="phone" |
|
value={ |
|
profilePage |
|
? profileFields.phone || user.phone |
|
: addressFields?.phone |
|
} |
|
onChange={(name, value) => |
|
profilePage |
|
? setProfileFields({ ...profileFields, phone: value }) |
|
: onChange(name, value) |
|
} |
|
align="text-right" |
|
direction="ltr" |
|
maxLength={11} |
|
/> |
|
</div> |
|
</> |
|
) : null} |
|
|
|
{profilePage && ( |
|
<Input |
|
width={isMobile ? "100%" : "50%"} |
|
label={"کد ملی"} |
|
regex={(val) => onInput.phonenumber(val)} |
|
name="nationalId" |
|
onChange={(name, value) => |
|
setProfileFields({ ...profileFields, nationalId: value }) |
|
} |
|
value={profileFields.nationalId || user.nationalId} |
|
align="text-right" |
|
direction="ltr" |
|
/> |
|
)} |
|
|
|
{!isMobile && <></>} |
|
|
|
{!isMobile && <></>} |
|
|
|
<Header |
|
title="آدرس" |
|
text="( لطفا نام استان و شهرستان و آدرس |
|
خود را با دقت تکمیل نمایید )" |
|
/> |
|
|
|
<div className="flex flex-col lg:flex-row items-center gap-3 lg:gap-5 w-full"> |
|
<Select |
|
options={provinces.map((e) => ({ value: e.id, name: e.name }))} |
|
name="provinceId" |
|
defaultValue={ |
|
profilePage |
|
? profileFields.provinceId || provinces[0]?.id |
|
: provinces[0]?.id |
|
} |
|
onChange={(name, value) => |
|
value === "استان" |
|
? {} |
|
: profilePage |
|
? setProfileFields({ ...profileFields, provinceId: value }) |
|
: onChange(name, value) |
|
} |
|
width={isMobile ? "w-full" : "w-1/2"} |
|
backgroundColor={ |
|
isDark ? "dark:bg-transparent dark:text-white" : "bg-white" |
|
} |
|
fill={isDark ? "fill-white" : "fill-gray-600"} |
|
/> |
|
{!cityLoading ? ( |
|
// <div>fdfds</div> |
|
<Select |
|
options={cities.map((e) => ({ value: e.id, name: e.name }))} |
|
name="cityId" |
|
defaultValue={ |
|
profilePage |
|
? profileFields.cityId || cities[0]?.id |
|
: cities[0]?.id |
|
} |
|
onChange={(name, value) => |
|
value === "شهر" |
|
? {} |
|
: profilePage |
|
? setProfileFields({ ...profileFields, cityId: value }) |
|
: onChange(name, value) |
|
} |
|
width={isMobile ? "w-full" : "w-1/2"} |
|
backgroundColor={ |
|
isDark ? "dark:bg-transparent dark:text-white" : "bg-white" |
|
} |
|
fill={isDark ? "fill-white" : "fill-gray-600"} |
|
/> |
|
) : ( |
|
<div className="flex justify-between border-gray-300 border border-solid rounded-md w-1/2 py-3.5 px-2"> |
|
<Loading size={3.5} color="bg-gray-500" /> |
|
<svg |
|
className={`'bg-gray-400 h-5 w-5`} |
|
xmlns="http://www.w3.org/2000/svg" |
|
viewBox="0 0 20 20" |
|
> |
|
<path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z" /> |
|
</svg> |
|
</div> |
|
)} |
|
</div> |
|
|
|
<Input |
|
width={isMobile ? "100%" : "50%"} |
|
label={"کد پستی"} |
|
regex={(val) => onInput.numberOnly(val)} |
|
name="postalCode" |
|
value={ |
|
profilePage |
|
? profileFields.postalCode || user.postalCode |
|
: addressFields?.postalCode |
|
} |
|
onChange={(name, value) => |
|
profilePage |
|
? setProfileFields({ ...profileFields, postalCode: value }) |
|
: onChange(name, value) |
|
} |
|
align="text-right" |
|
direction="ltr" |
|
maxLength={10} |
|
/> |
|
|
|
<div |
|
className={`flex ${ |
|
profilePage ? "mt-10" : "lg:hidden" |
|
} flex-col items-end w-full mt-3`} |
|
> |
|
<Button |
|
loading={loading} |
|
title={ |
|
!profilePage ? "ذخیره اطلاعات و بازگشت به صفحه قبل" : "ارسال" |
|
} |
|
backgroundColor="bg-blueC0" |
|
border={{ color: "#196EC055", width: "0px" }} |
|
width={profilePage ? "30%" : "100%"} |
|
color="text-white" |
|
onClick={() => (profilePage ? submitProfile() : submit())} |
|
/> |
|
{!isMobile && ( |
|
<button |
|
style={{ width: "30%" }} |
|
className="flex justify-center items-center mt-4 py-3 text-blueC0 text-base lg:text-tiny border-2 border-blueC0 cursor-pointer rounded-md" |
|
onClick={() => setPhase("deliveryForm")} |
|
> |
|
بازگشت |
|
<img |
|
src={lightGreenArrow} |
|
alt="" |
|
className="w-3.5 transform rotate-90" |
|
/> |
|
</button> |
|
)} |
|
</div> |
|
</div> |
|
{/* {isMobile && ( |
|
<div |
|
className="fixed top-0 left-0 flex justify-between items-center py-3 px-4 w-full" |
|
style={{ |
|
backgroundColor: isDark ? "#061B30" : "white", |
|
}} |
|
> |
|
<strong className="text-green4F text-lg font-semibold dark:text-white"> |
|
آدرس جدید |
|
</strong> |
|
<img |
|
src={isDark ? arrowWhiteIcon : arrowBlueIcon} |
|
alt="back" |
|
className={`w-6 transform ${isDark ? " rotate-0" : "rotate-180"}`} |
|
onClick={() => setPhase("deliveryForm")} |
|
/> |
|
</div> |
|
)} */} |
|
</div> |
|
); |
|
}; |
|
|
|
const mapStateToProps = (state) => ({ |
|
province: state.publicApi.province, |
|
city: state.publicApi.city, |
|
provinces: state.publicApi.provinces, |
|
cities: state.publicApi.cities, |
|
loading: state.userAddress.loading, |
|
user: state.user.status, |
|
cityLoading: state.publicApi.loading, |
|
isMobile: state.publicApi.isMobile, |
|
isDark: state.publicApi.isDark, |
|
profileFields: state.user.profileFields, |
|
addressInfo: state.userAddress.info, |
|
}); |
|
|
|
const mapDispatchToProps = { |
|
getProvince: publicApi.getProvince, |
|
getCity: publicApi.getCity, |
|
createAddress: userAddress.add, |
|
updateAddress: userAddress.update, |
|
getAddress: userAddress.info, |
|
setDialog: dialog.set, |
|
setProfileFields: user.setProfileFields, |
|
setProfile: user.setProfile, |
|
setHeaderOptions: publicApi.setHeaderOptions, |
|
}; |
|
|
|
export default connect(mapStateToProps, mapDispatchToProps)(Address);
|
|
|