retailer distributor address add,edit and delete

This commit is contained in:
Sibunnayak 2024-10-16 12:05:23 +05:30
parent f19babfd6b
commit e2a2b02ff5
5 changed files with 529 additions and 37 deletions

View File

@ -52,7 +52,7 @@ const AddMultiplePd = () => {
},
}
);
console.log(data);
// console.log(data);
if (data?.errors && data?.errors?.length > 0) {
setErrors(data.errors);
}
@ -74,8 +74,8 @@ const AddMultiplePd = () => {
button: "OK",
});
} else if (
data?.newlyCreated > 0 ||
data?.updatedDistributors > 0
data?.newlyCreated.length > 0 ||
data?.updatedDistributors.length > 0
) {
swal({
title: "SpreadSheet Upload Successful",

View File

@ -75,8 +75,8 @@ const AddMultiplerd = () => {
button: "OK",
});
} else if (
data.newlyCreated > 0 ||
data.updatedDistributors > 0
data.newlyCreated.length > 0 ||
data.updatedDistributors.length > 0
) {
swal({
title: "SpreadSheet Upload Successful",

View File

@ -10,12 +10,16 @@ import {
Dialog,
DialogContent,
DialogTitle,
Autocomplete,
TextField,
} from "@mui/material";
import { useParams, useNavigate } from "react-router-dom";
import { format } from "date-fns";
import { isAutheticated } from "../../auth";
import CancelIcon from "@mui/icons-material/Cancel"; // Add this import
import { City, State } from "country-state-city";
import { Modal, Button } from "react-bootstrap";
import swal from "sweetalert";
const SingleRetailDistributor = () => {
const { id } = useParams();
const [retailerDetails, setRetailerDetails] = useState(null);
@ -24,6 +28,233 @@ const SingleRetailDistributor = () => {
const token = isAutheticated();
const navigate = useNavigate();
const [userAllAddress, setUserAllAddress] = useState([]);
const [tradeName, setTradeName] = useState(null);
const [showModal, setShowModal] = useState(false);
const [isEditMode, setIsEditMode] = useState(false);
const [stateOptions, setStateOptions] = useState([]);
const [cityOptions, setCityOptions] = useState([]);
const [selectedState, setSelectedState] = useState(null);
const [selectedCity, setSelectedCity] = useState(null);
const [currentAddress, setCurrentAddress] = useState({
Name: "",
tradeName: "",
phoneNumber: "",
street: "",
district: "",
city: "",
state: "",
postalCode: "",
country: "India",
isDefault: false,
});
// Fetch states when the component mounts
useEffect(() => {
const fetchStates = () => {
const states = State.getStatesOfCountry("IN").map((state) => ({
label: state.name,
value: state.isoCode,
}));
setStateOptions(states);
};
fetchStates();
}, []);
// Fetch cities when a state is selected
useEffect(() => {
const fetchCities = () => {
if (selectedState) {
const cities = City.getCitiesOfState("IN", selectedState.value).map(
(city) => ({
label: city.name,
value: city.name,
})
);
setCityOptions(cities);
} else {
setCityOptions([]); // Clear cities if no state is selected
}
};
fetchCities();
}, [selectedState]);
// Open modal for add or edit mode
const handleOpenModal = (address = null) => {
setIsEditMode(!!address); // Set edit mode if address is provided
const initialAddress = address || {
Name: "",
tradeName: tradeName,
phoneNumber: "",
street: "",
district: "",
city: "",
state: "",
postalCode: "",
country: "India",
isDefault: false,
};
setCurrentAddress(initialAddress);
// Fetch city options based on the state from the backend
if (address) {
const state =
stateOptions.find((option) => option.label === address.state) || null;
// Set selected state from backend address
setSelectedState(state);
// Fetch cities if state is found
if (state) {
const cities = City.getCitiesOfState("IN", state.value).map((city) => ({
label: city.name,
value: city.name,
}));
setCityOptions(cities);
// Set selected city if it exists in the fetched city options
const city =
cities.find((option) => option.label === address.city) || null;
setSelectedCity(city); // Set the selected city
}
} else {
setSelectedState(null);
setSelectedCity(null);
setCityOptions([]); // Clear city options if no address is provided
}
setShowModal(true);
};
// Close modal without saving changes
const handleCloseModal = () => {
setShowModal(false);
// Reset selections to previous state when modal is closed
setSelectedState(null); // Reset state selection
setSelectedCity(null); // Reset city selection
setCurrentAddress({
Name: "",
tradeName: "",
phoneNumber: "",
street: "",
district: "",
city: "",
state: "",
postalCode: "",
country: "India",
isDefault: false,
});
};
// Save address logic for adding or updating
const handleSaveAddress = async () => {
try {
const updatedAddress = {
...currentAddress,
tradeName: tradeName,
};
const apiUrl = isEditMode
? `/api/rd/shipping/address/update/${currentAddress._id}`
: `/api/rd/shipping/address/admin/new/${id}`;
// console.log(currentAddress);
const method = isEditMode ? "patch" : "post";
// Prepare the headers with the token
const headers = {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
};
// Make the API call with the headers
await axios[method](apiUrl, updatedAddress, { headers });
swal(
"Success!",
`Address ${isEditMode ? "updated" : "added"} successfully!`,
"success"
);
handleCloseModal();
getUserAddress();
} catch (error) {
console.error("Error saving address:", error);
swal("Error!", "There was an error saving the address.", "error");
}
};
const handleStateChange = (event, newValue) => {
setSelectedState(newValue);
setCurrentAddress((prev) => ({
...prev,
state: newValue ? newValue.label : "",
city: "", // Clear city when state changes
}));
setSelectedCity(null); // Reset city selection
setCityOptions([]); // Clear city options on state change
};
const handleCityChange = (event, newValue) => {
setSelectedCity(newValue);
setCurrentAddress((prev) => ({
...prev,
city: newValue ? newValue.label : "",
}));
};
// Fetch Shipping address of the individual user
const getUserAddress = useCallback(async () => {
try {
const response = await axios.get(
`/api/rd/shipping/address/user/address/${id}`,
{
headers: {
Authorization: `Bearer ${token}`,
},
}
);
// console.log(response.data);
setUserAllAddress(response.data?.UserShippingAddress || []);
} catch (error) {
swal({
title: "Warning",
text: error.message,
icon: "error",
button: "Close",
dangerMode: true,
});
}
}, [id, token]);
const handledeleteAddress = async (address_id) => {
try {
const response = await axios.delete(
`/api/rd/shipping/address/delete/${address_id}`, // Address ID in the URL
{
headers: {
Authorization: `Bearer ${token}`, // Authorization header
},
data: { userId: id }, // User ID in the request body
}
);
swal({
title: "Success",
text: response.data.message,
icon: "success",
button: "Close",
});
getUserAddress();
} catch (error) {
// Handle errors here, ensuring that you access the error message correctly
swal({
title: "Warning",
text: error.response?.data?.message || error.message, // Improved error handling
icon: "error",
button: "Close",
dangerMode: true,
});
}
};
const getUserDetails = useCallback(async () => {
try {
// Commented out the API call and using dummy data
@ -36,6 +267,7 @@ const SingleRetailDistributor = () => {
});
setRetailerDetails(response.data);
// console.log('Retailer Details: ', response.data);
setTradeName(response.data?.kyc?.trade_name || "");
} catch (error) {
console.error("Error fetching data: ", error);
}
@ -44,7 +276,8 @@ const SingleRetailDistributor = () => {
// Fetch retailer details on mount
useEffect(() => {
getUserDetails();
}, [id, getUserDetails]);
getUserAddress();
}, [id, getUserDetails, getUserAddress]);
const handleOpenPopup = (imageUrl) => {
setSelectedImage(imageUrl);
@ -136,14 +369,14 @@ const SingleRetailDistributor = () => {
<strong>PAN Number:</strong> {retailerDetails.kyc.pan_number}
</Typography>
{retailerDetails?.kyc?.pan_img ? (
<Avatar
variant="square"
src={retailerDetails?.kyc?.pan_img?.url}
sx={{ width: 100, height: 100, mb: 2, cursor: "pointer" }}
onClick={() =>
handleOpenPopup(retailerDetails?.kyc?.pan_img?.url)
}
/>
<Avatar
variant="square"
src={retailerDetails?.kyc?.pan_img?.url}
sx={{ width: 100, height: 100, mb: 2, cursor: "pointer" }}
onClick={() =>
handleOpenPopup(retailerDetails?.kyc?.pan_img?.url)
}
/>
) : (
<Typography>Img not available</Typography>
)}
@ -152,14 +385,14 @@ const SingleRetailDistributor = () => {
{retailerDetails.kyc.aadhar_number}
</Typography>
{retailerDetails?.kyc?.aadhar_img ? (
<Avatar
variant="square"
src={retailerDetails?.kyc?.aadhar_img?.url}
sx={{ width: 100, height: 100, mb: 2, cursor: "pointer" }}
onClick={() =>
handleOpenPopup(retailerDetails?.kyc?.aadhar_img?.url)
}
/>
<Avatar
variant="square"
src={retailerDetails?.kyc?.aadhar_img?.url}
sx={{ width: 100, height: 100, mb: 2, cursor: "pointer" }}
onClick={() =>
handleOpenPopup(retailerDetails?.kyc?.aadhar_img?.url)
}
/>
) : (
<Typography>Img not available</Typography>
)}
@ -167,14 +400,14 @@ const SingleRetailDistributor = () => {
<strong>GST Number:</strong> {retailerDetails.kyc.gst_number}
</Typography>
{retailerDetails?.kyc?.gst_img ? (
<Avatar
variant="square"
src={retailerDetails?.kyc?.gst_img?.url}
sx={{ width: 100, height: 100, mb: 2, cursor: "pointer" }}
onClick={() =>
handleOpenPopup(retailerDetails?.kyc?.gst_img?.url)
}
/>
<Avatar
variant="square"
src={retailerDetails?.kyc?.gst_img?.url}
sx={{ width: 100, height: 100, mb: 2, cursor: "pointer" }}
onClick={() =>
handleOpenPopup(retailerDetails?.kyc?.gst_img?.url)
}
/>
) : (
<Typography>Img not available</Typography>
)}
@ -256,6 +489,265 @@ const SingleRetailDistributor = () => {
</Grid>
</Grid>
</Paper>
{/* Address of retail distributor */}
<Paper sx={{ p: 2, mb: 3 }}>
<h5 style={{ fontWeight: "bold", marginBottom: "1rem" }}>
&bull; Addresses{" "}
</h5>
<div className="d-flex justify-content-between align-items-center mb-3">
<h5 style={{ fontWeight: "bold" }}>
&bull; Total Addresses: {userAllAddress?.length || 0}{" "}
</h5>
<Button
className="btn btn-primary"
onClick={() => handleOpenModal()} // Open modal for adding
>
Add Address
</Button>
</div>
{userAllAddress?.length > 0 && (
<div className="table-responsive table-shoot mt-3">
<table
className="table table-centered table-nowrap"
style={{ border: "1px solid" }}
>
<thead
className="thead-info"
style={{ background: "rgb(140, 213, 213)" }}
>
<tr>
<th style={{ width: "5%" }}>SL No.</th>
<th style={{ width: "20%" }}>Trade Name</th>
<th style={{ width: "15%" }}>RD Name</th>
<th style={{ width: "40%" }}>Address</th>
<th style={{ width: "7%" }}>Default</th>
<th style={{ width: "13%" }}>Action</th>
</tr>
</thead>
<tbody>
{userAllAddress?.map((address, i) => (
<tr key={address._id || i}>
<td className="text-start">
<strong>{i + 1}</strong>
</td>
<td className="text-start">
<strong>
{address?.tradeName
? `${address.tradeName}`
: "No Trade Name"}
</strong>
</td>
<td className="text-start">
<strong>
{address?.Name ? `${address.Name}` : "No RD Name"}
</strong>
</td>
<td className="text-start">
<strong>
{address?.street}, {address?.city}, {address?.district}, {address?.state},{" "}
{address?.country}, {address?.postalCode}
</strong>
</td>
<td className="text-start">
<strong>{address.isDefault ? "Yes" : "No"}</strong>
</td>
<td className="text-start">
<Button
className="btn btn-warning btn-sm me-2"
onClick={() => handleOpenModal(address)} // Open modal for editing
>
Edit
</Button>
<Button
className="btn btn-danger btn-sm"
onClick={() => handledeleteAddress(address._id)}
>
Delete
</Button>
</td>
</tr>
))}
</tbody>
</table>
</div>
)}
{/* Modal for Adding/Editing Address */}
<Modal
show={showModal}
onHide={handleCloseModal}
dialogClassName="modal-lg"
>
<Modal.Header closeButton>
<Modal.Title>
{isEditMode ? "Edit Shipping Address" : "Add Shipping Address"}
</Modal.Title>
</Modal.Header>
<Modal.Body>
<div className="container">
<div className="row">
{/* Name and Trade Name */}
<div className="col-md-6">
<label>Name</label>
<input
type="text"
value={currentAddress?.Name || ""}
onChange={(e) =>
setCurrentAddress({
...currentAddress,
Name: e.target.value,
})
}
className="form-control mb-3"
placeholder="Enter name"
/>
</div>
<div className="col-md-6">
<label>Trade Name</label>
<input
type="text"
value={currentAddress?.tradeName || ""}
onChange={(e) =>
setCurrentAddress({
...currentAddress,
tradeName: e.target.value,
})
}
className="form-control mb-3"
placeholder="Enter trade name"
/>
</div>
</div>
<div className="row">
{/* Phone Number and Street */}
<div className="col-md-6">
<label>Phone Number</label>
<input
type="text"
value={currentAddress?.phoneNumber || ""}
onChange={(e) =>
setCurrentAddress({
...currentAddress,
phoneNumber: e.target.value,
})
}
className="form-control mb-3"
placeholder="Enter phone number"
/>
</div>
<div className="col-md-6">
<label>Street</label>
<input
type="text"
value={currentAddress?.street || ""}
onChange={(e) =>
setCurrentAddress({
...currentAddress,
street: e.target.value,
})
}
className="form-control mb-3"
placeholder="Enter street"
/>
</div>
</div>
<div className="row">
{/* State and City */}
<div className="col-md-6">
<Autocomplete
options={stateOptions}
value={selectedState}
onChange={handleStateChange}
renderInput={(params) => (
<TextField {...params} label="Select State" />
)}
/>
</div>
<div className="col-md-6">
<Autocomplete
options={cityOptions}
value={selectedCity}
onChange={handleCityChange}
isOptionEqualToValue={(option, value) =>
option.value === value.value
}
renderInput={(params) => (
<TextField {...params} label="Select City" />
)}
/>
</div>
</div>
<div className="row">
{/* Postal Code and Country */}
<div className="col-md-6">
<label>Postal Code</label>
<input
type="text"
value={currentAddress?.postalCode || ""}
onChange={(e) =>
setCurrentAddress({
...currentAddress,
postalCode: e.target.value,
})
}
className="form-control mb-3"
placeholder="Enter postal code"
/>
</div>
<div className="col-md-6">
<label>District</label>
<input
type="text"
value={currentAddress?.district || ""}
onChange={(e) =>
setCurrentAddress({
...currentAddress,
district: e.target.value,
})
}
className="form-control mb-3"
placeholder="Enter District"
/>
</div>
</div>
<div className="row">
<div className="col-md-6">
<label>Country</label>
<input
type="text"
disabled
value={currentAddress?.country || ""}
className="form-control mb-3"
/>
</div>
<div className="col-md-6">
<label>Is Default Address</label>
<select
className="form-control mb-3"
value={currentAddress.isDefault ? "Yes" : "No"}
onChange={(e) =>
setCurrentAddress({
...currentAddress,
isDefault: e.target.value === "Yes", // Convert Yes/No to true/false
})
}
>
<option value="Yes">Yes</option>
<option value="No">No</option>
</select>
</div>
</div>
</div>
</Modal.Body>
<Modal.Footer>
<Button variant="primary" onClick={handleSaveAddress}>
Save
</Button>
</Modal.Footer>
</Modal>
</Paper>
<Dialog
open={openPopup}
onClose={handleClosePopup}

View File

@ -75,8 +75,8 @@ const AddMultiplesc = () => {
button: "OK",
});
} else if (
data.newlyCreated > 0 ||
data.updatedsalesCoordinators > 0
data.newlyCreated.length > 0 ||
data.updatedsalesCoordinators.length > 0
) {
swal({
title: "SpreadSheet Upload Successful",

View File

@ -75,8 +75,8 @@ const AddMultipletm = () => {
button: "OK",
});
} else if (
data.newlyCreated > 0 ||
data.updatedtrritoryManagers > 0
data.newlyCreated.length > 0 ||
data.updatedtrritoryManagers.length > 0
) {
swal({
title: "SpreadSheet Upload Successful",