Viewing File: /home/ubuntu/misabloom-frontend-base/src/components/Profile/NewAddressForm.jsx
import { apiConstants } from "../Constant/constants";
import Map, { GoogleApiWrapper, Marker } from "google-maps-react";
import React, { useEffect, useRef, useState } from "react";
import {
Row,
Col,
Container,
Form,
Image,
Button,
Tab,
Nav,
FormControl,
} from "react-bootstrap";
import { withTranslation, useTranslation } from "react-multi-lang";
import {
saveDeliveryAddressesStart,
fetchDeliveryAddressesListStart,
getCountriesStart,
getStatesStart,
} from "../store/actions/DeliveryAction";
import { Formik, Form as FORM, Field, ErrorMessage } from "formik";
import * as Yup from "yup";
import { connect } from "react-redux";
import Select from "react-select";
import {
CountrySelect,
StateSelect,
CitySelect,
GetCity,
} from "react-country-state-city";
import "react-country-state-city/dist/react-country-state-city.css";
import { GetCountries, GetState, GetAllCities } from "react-country-state-city";
import axios from "axios";
const NewAddressForm = ({ isModal = false, ...props }) => {
const t = useTranslation();
const [address, setAddress] = useState("");
const [skipRender, setSkipRender] = useState(true);
const [manualPincode, setManualPincode] = useState(false);
const validationSchema = Yup.object().shape({
name: Yup.string(),
contact_number: Yup.string()
.matches(/^(?:\+91[6-9]\d{9}|91[6-9]\d{9}|[6-9]\d{9})$/, t("invalid_mobile_number"))
.required(t("required")), city: Yup.string().required(t("required")),
state: Yup.string().required(t("required")),
country: Yup.string().required(t("required")),
pincode: Yup.string().required(t("required"))
.matches(/^[1-9][0-9]{5}$/, t("invalid")),
landmark: Yup.string().required(t("required")),
address: Yup.string().required(t("required")),
});
const [country, setCountry] = useState(null);
const [currentState, setCurrentState] = useState(null);
const [currentCity, setCurrentCity] = useState(null);
const [currentPinCode, setCurrentPinCode] = useState(null);
const [countriesList, setCountriesList] = useState([]);
const [stateList, setStateList] = useState([]);
const [citiesList, setCitiesList] = useState([]);
const [pincodeList, setPincodeList] = useState([]);
const [loading, setLoading] = useState(false);
const handleSubmit = (values) => {
props.dispatch(
saveDeliveryAddressesStart(
props?.editAddress?.delivery_address_id
? {
...values,
delivery_address_id: props.editAddress.delivery_address_id,
}
: {
...values,
}
)
);
};
useEffect(() => {
props.dispatch(getCountriesStart({ all_countries: 1 }));
}, []);
useEffect(() => {
GetCountries().then((result) =>
setCountriesList(
result.filter(item => item.name == "India").map((items) => ({
label: items.name,
value: items.name,
...items,
}))
)
);
}, []);
useEffect(() => {
if (country && Object.keys(country).length > 0 && country.id)
GetState(parseInt(country.id)).then((result) => {
setStateList(
result.map((items) => ({
label: items.name,
value: items.name,
...items,
}))
);
});
}, [country]);
useEffect(() => {
if (currentState && Object.keys(currentState).length > 0 && currentState.id)
GetCity(parseInt(country.id), parseInt(currentState.id)).then(
(result) => {
setCitiesList(
result.map((items) => ({
label: items.name,
value: items.name,
...items,
}))
);
}
);
}, [currentState]);
useEffect(() => {
if (currentCity) {
let decoded = decodeURIComponent(currentCity.value);
let cityName = decoded.split(" ");
let pins = fetchPinCodeList(cityName[0]);
}
}, [currentCity]);
const fetchPinCodeList = async (data) => {
let pins = [];
setLoading(true);
const apiUrl = `https://api.postalpincode.in/postoffice/${data}`;
await axios.get(apiUrl).then((response) => {
pins = response.data[0]?.PostOffice?.map((office) => ({
label: office.Pincode + ` (${office.Name})`,
value: office.Pincode,
}));
setPincodeList(pins || []);
if(!pins.length > 0){
setManualPincode(true)
}
});
setLoading(false);
return pins;
};
useEffect(() => {
if (
!skipRender &&
!props.deliveryAddressesSave.loading &&
Object.keys(props.deliveryAddressesSave.data).length > 0
) {
if (!isModal) {
props.setActiveTab("saved_billing");
props.dispatch(fetchDeliveryAddressesListStart());
}
}
setSkipRender(false);
}, [props.deliveryAddressesSave]);
const customStyles = {
///.....
menuPortal: (provided) => ({ ...provided, zIndex: 9999 }),
menu: (provided) => ({
...provided,
zIndex: 9999,
left: "0px",
borderRadius: "0px",
overflow: "hidden",
}),
menuList: (provided) => ({
...provided,
padding: 0,
minWidth: 250,
// fontSize: "0.85em",
"&::-webkit-scrollbar-track": {
boxShadow: "inset 0 0 6px rgba(0,0,0,0.3)",
borderRadius: "8px",
backgroundColor: "#fff",
},
"&::-webkit-scrollbar": {
width: "4px",
backgroundColor: "#fff",
},
"&::-webkit-scrollbar-thumb": {
borderRadius: "3px",
boxShadow: "inset 0 0 6px rgba(0, 0, 0, .3)",
backgroundColor: "#555",
},
}),
container: (provided) => ({ ...provided, width: "auto" }),
control: (provided) => ({
...provided,
backgroundColor: "transparent!important",
border: "1px solid #E7E7E7!important",
borderRadius: "8px!important",
boxShadow: "none!important",
height: "45px",
minWidth: "150px",
cursor: "pointer",
// fontSize: "0.9em",
}),
placeholder: (provided) => ({
...provided,
color: "#212529",
// fontSize: "0.85em",
fontWeight: "600",
}),
singleValue: (provided) => ({
...provided,
color: "#212529",
display: "flex",
alignItems: "center",
gap: "0.5em",
// fontSize: "0.9em",
fontWeight: "600",
}),
indicatorContainer: (provided) => ({
...provided,
color: "#212529!important",
}),
indicatorContainer: (provided) => ({
...provided,
fill: "#212529!important",
}),
indicatorSeparator: (base) => ({
...base,
display: "none",
}),
dropdownIndicator: (provided) => ({
...provided,
svg: {
fill: "#212529",
},
}),
// option: (styles, { data, isDisabled, isFocused, isSelected }) => {
// return {
// ...styles,
// backgroundColor: isSelected ? "#f7f7f7" : "#fff",
// color: "#000",
// };
// },
option: (provided, state) => ({
...provided,
backgroundColor: state.isFocused || state.isSelected ? '#19264f' : '#fff',
color: state.isFocused || state.isSelected ? '#fff' : '#000',
":hover": {
backgroundColor: "#19264f",
color: "#fff"
},
}),
};
return (
<div className="new-address-sec mt-4">
<div className="login-form">
<Formik
initialValues={{
name: "",
contact_number: "",
city: "",
state: "",
country: "",
pincode: "",
landmark: "",
address: "",
}}
validationSchema={validationSchema}
onSubmit={(values) => handleSubmit(values)}
enableReinitialize={true}
>
{({ values, errors, touched, setFieldValue }) => (
<FORM>
<Row>
<Col md={12} xl={6} lg={6}>
<Form.Group
className="mb-4 select-address-type"
controlId="exampleForm.ControlInput1"
>
<Form.Label>
{t("name")} <span>*</span>
</Form.Label>
<Field
type="text"
className="form-control"
name="name"
placeholder={t("address_choose")}
/>
<ErrorMessage
component={"div"}
name="name"
className="text-danger"
/>
<div className="select-address-type-btn">
<Button
className="text-btn"
type="button"
onClick={(e) => setFieldValue("name", "Home")}
>
{t("home")}
</Button>
<Button
className="text-btn"
type="button"
onClick={() => setFieldValue("name", "Work")}
>
{t("work")}
</Button>
<Button
className="text-btn"
type="button"
onClick={() => setFieldValue("name", "Others")}
>
{t("others")}
</Button>
</div>
</Form.Group>
</Col>
<Col md={12} xl={6} lg={6}>
<Form.Group
className="mb-4"
controlId="exampleForm.ControlInput1"
>
<Form.Label>
{t("contact_number")} <span>*</span>
</Form.Label>
<Field
type="number"
className="form-control"
name="contact_number"
placeholder={t("contact_placeholder")}
min="0"
/>
<ErrorMessage
component={"div"}
name="contact_number"
className="text-danger"
/>
</Form.Group>
</Col>
<Col md={6}>
<Form.Group
className="mb-4"
controlId="exampleForm.ControlInput1"
>
<Form.Label>
{t("country")} <span>*</span>
</Form.Label>
<Select
styles={customStyles}
options={countriesList || []}
value={country}
onChange={(selected) => {
if (selected) {
setCountry(selected);
setFieldValue("country", selected.value);
setCurrentState(null);
setCurrentCity(null);
setCurrentPinCode(null);
setFieldValue("state", "");
setFieldValue("city", "");
setFieldValue("pincode", "");
} else {
setCountry(null);
setFieldValue("country", "");
}
}}
placeholder={t("country_placeholder")}
noOptionsMessage={() => t("no_countries")}
/>
<ErrorMessage
component={"div"}
name="country"
className="text-danger"
/>
</Form.Group>
</Col>
<Col md={6}>
<Form.Group
className="mb-4"
controlId="exampleForm.ControlInput1"
>
<Form.Label>
{t("state")} <span>*</span>
</Form.Label>
<Select
styles={customStyles}
options={stateList || []}
value={currentState}
onChange={(selected) => {
if (selected) {
setCurrentState(selected);
setFieldValue("state", selected.value);
setCurrentCity(null);
setFieldValue("city", "");
setCurrentPinCode(null);
setFieldValue("pincode", "");
} else {
setCurrentState(null);
setFieldValue("state", "");
}
}}
placeholder={t("state_placeholder")}
noOptionsMessage={() => t("no_states")}
/>
<ErrorMessage
component={"div"}
name="state"
className="text-danger"
/>
</Form.Group>
</Col>
<Col md={6}>
<Form.Group controlId="formBasicEmail">
<Form.Label>
{t("city")} <span>*</span>
</Form.Label>
<Select
styles={customStyles}
options={citiesList || []}
value={currentCity}
onChange={(selected) => {
if (selected) {
setCurrentCity(selected);
setFieldValue("city", selected.value);
setCurrentPinCode(null);
setFieldValue("pincode", "");
} else {
setCurrentCity(null);
setFieldValue("city", "");
}
}}
placeholder={t("city_placeholder")}
noOptionsMessage={() => t("no_city")}
/>
<ErrorMessage
component={"div"}
name="city"
className="text-danger"
/>
</Form.Group>
</Col>
<Col md={6}>
<Form.Group
className="mb-4"
controlId="exampleForm.ControlInput1"
>
<div style={{display:"flex", justifyContent:"space-between", alignItems:"center", marginBottom:"0.5em"}}>
<Form.Label className="mb-0">
{t("pincode")} <span>*</span>
</Form.Label>
<Button className="manual-btn" onClick={()=> setManualPincode(!manualPincode)}>
{!manualPincode ? "Enter Manually" : "Select Pincode"}
</Button>
</div>
{!manualPincode ? <Select
styles={customStyles}
options={pincodeList}
value={currentPinCode}
onChange={(selected) => {
if (selected) {
setCurrentPinCode(selected);
setFieldValue("pincode", selected.value);
} else {
setCurrentPinCode(null);
setFieldValue("pincode", "");
}
}}
placeholder="Select your pincode"
noOptionsMessage={() => t("no_pincode")}
/> :
<Field
type="text"
className="form-control"
name="pincode"
placeholder={t("pincode")}
/>
}
<ErrorMessage
component={"div"}
name="pincode"
className="text-danger"
/>
</Form.Group>
</Col>
<Col md={12}>
<Form.Group
className="mb-4"
controlId="exampleForm.ControlInput1"
>
<Form.Label>
{t("landmark")} <span>*</span>
</Form.Label>
<Field
type="text"
className="form-control"
name="landmark"
placeholder={t("landmark_placeholder")}
min="0"
/>
<ErrorMessage
component={"div"}
name="landmark"
className="text-danger"
/>
</Form.Group>
</Col>
<Col md={12}>
<Form.Group
className="mb-4"
controlId="exampleForm.ControlTextarea1"
>
<Form.Label>
{t("address_area")} <span>*</span>
</Form.Label>
<Field
as="textarea"
className="form-control"
name="address"
placeholder={t("address_placeholder")}
min="0"
/>
<ErrorMessage
component={"div"}
name="address"
className="text-danger"
/>
</Form.Group>
</Col>
</Row>
<Form.Group
className="mb-3 form-check-custom"
controlId="formBasicCheckbox"
>
<Form.Check type="checkbox" label={t("use_as_default_add")} />
</Form.Group>
<div className="default-btn-sec">
<Button
type="submit"
className="subscribe-btn"
disabled={props.deliveryAddressesSave.buttonDisable}
>
{props.deliveryAddressesSave.loadingButtonContent
? props.deliveryAddressesSave.loadingButtonContent
: t("save")}
</Button>
</div>
</FORM>
)}
</Formik>
</div>
</div>
);
};
const mapStateToPros = (state) => ({
deliveryAddressesSave: state.delivery.deliveryAddressesSave,
deliveryAddressesList: state.delivery.deliveryAddressesList,
countries: state.delivery.countries,
states: state.delivery.states,
});
function mapDispatchToProps(dispatch) {
return { dispatch };
}
export default connect(
mapStateToPros,
mapDispatchToProps
)(withTranslation(NewAddressForm));
Back to Directory
File Manager