address of pd add edit and delete also change ui of product table
This commit is contained in:
parent
54b64f5b64
commit
7f6ee992b2
@ -52,21 +52,21 @@ const AddMultiplePd = () => {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
// console.log(data);
|
console.log(data);
|
||||||
if (data.errors && data.errors.length > 0) {
|
if (data?.errors && data?.errors?.length > 0) {
|
||||||
setErrors(data.errors);
|
setErrors(data.errors);
|
||||||
}
|
}
|
||||||
if (data.newlyCreated && data.newlyCreated.length > 0) {
|
if (data?.newlyCreated && data?.newlyCreated?.length > 0) {
|
||||||
setNewlyCreated(data.newlyCreated);
|
setNewlyCreated(data?.newlyCreated);
|
||||||
}
|
}
|
||||||
if (data.updatedDistributors && data.updatedDistributors.length > 0) {
|
if (data?.updatedDistributors && data?.updatedDistributors?.length > 0) {
|
||||||
setUpdatedDistributors(data.updatedDistributors);
|
setUpdatedDistributors(data?.updatedDistributors);
|
||||||
// console.log(data.updatedDistributors);
|
// console.log(data.updatedDistributors);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Redirect or display success message
|
// Redirect or display success message
|
||||||
if (data.errors && data.errors.length > 0) {
|
if (data?.errors && data?.errors.length > 0) {
|
||||||
setErrors(data.errors);
|
setErrors(data?.errors);
|
||||||
swal({
|
swal({
|
||||||
title: "SpreadSheet Upload Successful",
|
title: "SpreadSheet Upload Successful",
|
||||||
text: "A few Principal Distributor have errors. Please fix them and upload again.",
|
text: "A few Principal Distributor have errors. Please fix them and upload again.",
|
||||||
@ -74,8 +74,8 @@ const AddMultiplePd = () => {
|
|||||||
button: "OK",
|
button: "OK",
|
||||||
});
|
});
|
||||||
} else if (
|
} else if (
|
||||||
data.processedUsers.newlyCreated > 0 ||
|
data?.newlyCreated > 0 ||
|
||||||
data.processedUsers.updatedDistributors > 0
|
data?.updatedDistributors > 0
|
||||||
) {
|
) {
|
||||||
swal({
|
swal({
|
||||||
title: "SpreadSheet Upload Successful",
|
title: "SpreadSheet Upload Successful",
|
||||||
@ -85,7 +85,7 @@ const AddMultiplePd = () => {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
toast.success("File processed successfully with no new entries.");
|
toast.success("File processed successfully with no new entries.");
|
||||||
navigate("/principal-distributors");
|
navigate("/principal-distributor");
|
||||||
}
|
}
|
||||||
setFile(null); // Clear the file input
|
setFile(null); // Clear the file input
|
||||||
document.querySelector('input[type="file"]').value = "";
|
document.querySelector('input[type="file"]').value = "";
|
||||||
|
@ -121,6 +121,9 @@ const AddPrincipalDistributor = () => {
|
|||||||
`/api/shipping/address/admin/new/${userId}`,
|
`/api/shipping/address/admin/new/${userId}`,
|
||||||
{
|
{
|
||||||
...data,
|
...data,
|
||||||
|
Name: user.name,
|
||||||
|
phoneNumber: user.phone,
|
||||||
|
isDefault: true,
|
||||||
state: selectedState.label, // Send selected state label
|
state: selectedState.label, // Send selected state label
|
||||||
city: selectedCity.label, // Send selected city label
|
city: selectedCity.label, // Send selected city label
|
||||||
},
|
},
|
||||||
|
@ -1,11 +1,16 @@
|
|||||||
import { Typography, Button } from "@mui/material";
|
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import React, { useCallback, useEffect, useState, useRef } from "react";
|
import React, { useCallback, useEffect, useState, useRef } from "react";
|
||||||
import { Link, useParams, useNavigate } from "react-router-dom";
|
import { Link, useParams, useNavigate } from "react-router-dom";
|
||||||
import swal from "sweetalert";
|
import swal from "sweetalert";
|
||||||
import { isAutheticated } from "src/auth";
|
import { isAutheticated } from "src/auth";
|
||||||
|
import { City, State } from "country-state-city";
|
||||||
|
import { Modal, Button } from "react-bootstrap";
|
||||||
|
import { Autocomplete, TextField, Typography, Box } from "@mui/material";
|
||||||
|
|
||||||
const SinglePrincipalDistributorAllDetails = () => {
|
const SinglePrincipalDistributorAllDetails = () => {
|
||||||
|
const token = isAutheticated();
|
||||||
|
const { _id } = useParams();
|
||||||
|
|
||||||
const [user, setUser] = useState(null);
|
const [user, setUser] = useState(null);
|
||||||
const [userOrder, setUserOrder] = useState({
|
const [userOrder, setUserOrder] = useState({
|
||||||
totalOrders: 0,
|
totalOrders: 0,
|
||||||
@ -13,9 +18,185 @@ const SinglePrincipalDistributorAllDetails = () => {
|
|||||||
lastPurchaseOrderDate: null,
|
lastPurchaseOrderDate: null,
|
||||||
});
|
});
|
||||||
const [userAllAddress, setUserAllAddress] = useState([]);
|
const [userAllAddress, setUserAllAddress] = useState([]);
|
||||||
|
const [gstNumber, setGstNumber] = useState(null);
|
||||||
|
const [panNumber, setPanNumber] = useState(null);
|
||||||
|
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: "",
|
||||||
|
gstNumber: "",
|
||||||
|
panNumber: "",
|
||||||
|
phoneNumber: "",
|
||||||
|
street: "",
|
||||||
|
city: "",
|
||||||
|
state: "",
|
||||||
|
postalCode: "",
|
||||||
|
country: "India",
|
||||||
|
isDefault: false,
|
||||||
|
});
|
||||||
|
|
||||||
const token = isAutheticated();
|
// Fetch states when the component mounts
|
||||||
const { _id } = useParams();
|
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,
|
||||||
|
gstNumber: gstNumber,
|
||||||
|
panNumber: panNumber,
|
||||||
|
phoneNumber: "",
|
||||||
|
street: "",
|
||||||
|
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: "",
|
||||||
|
gstNumber: "",
|
||||||
|
panNumber: "",
|
||||||
|
phoneNumber: "",
|
||||||
|
street: "",
|
||||||
|
city: "",
|
||||||
|
state: "",
|
||||||
|
postalCode: "",
|
||||||
|
country: "India",
|
||||||
|
isDefault: false,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Save address logic for adding or updating
|
||||||
|
const handleSaveAddress = async () => {
|
||||||
|
try {
|
||||||
|
const updatedAddress = {
|
||||||
|
...currentAddress,
|
||||||
|
gstNumber: gstNumber,
|
||||||
|
panNumber: panNumber,
|
||||||
|
tradeName: tradeName,
|
||||||
|
};
|
||||||
|
const apiUrl = isEditMode
|
||||||
|
? `/api/shipping/address/update/${currentAddress._id}`
|
||||||
|
: `/api/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
|
// Fetch Shipping address of the individual user
|
||||||
const getUserAddress = useCallback(async () => {
|
const getUserAddress = useCallback(async () => {
|
||||||
@ -28,7 +209,11 @@ const SinglePrincipalDistributorAllDetails = () => {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
// console.log(response.data);
|
||||||
setUserAllAddress(response.data?.UserShippingAddress || []);
|
setUserAllAddress(response.data?.UserShippingAddress || []);
|
||||||
|
setGstNumber(response.data?.UserShippingAddress[0]?.gstNumber || "");
|
||||||
|
setPanNumber(response.data?.UserShippingAddress[0]?.panNumber || "");
|
||||||
|
setTradeName(response.data?.UserShippingAddress[0]?.tradeName || "");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
swal({
|
swal({
|
||||||
title: "Warning",
|
title: "Warning",
|
||||||
@ -68,6 +253,7 @@ const SinglePrincipalDistributorAllDetails = () => {
|
|||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
// console.log(response.data);
|
||||||
setUser(response.data.user);
|
setUser(response.data.user);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
swal({
|
swal({
|
||||||
@ -85,6 +271,37 @@ const SinglePrincipalDistributorAllDetails = () => {
|
|||||||
getUserAddress();
|
getUserAddress();
|
||||||
getUserDetails();
|
getUserDetails();
|
||||||
}, [_id, getOrdersCount, getUserAddress, getUserDetails]);
|
}, [_id, getOrdersCount, getUserAddress, getUserDetails]);
|
||||||
|
const handledeleteAddress = async (id) => {
|
||||||
|
try {
|
||||||
|
const response = await axios.delete(
|
||||||
|
`/api/shipping/address/delete/${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,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@ -96,17 +313,7 @@ const SinglePrincipalDistributorAllDetails = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="page-title-right">
|
<div className="page-title-right">
|
||||||
<Link to="/principal-distributor">
|
<Link to="/principal-distributor">
|
||||||
<Button
|
<Button className="btn btn-danger btn-sm">Back</Button>
|
||||||
variant="contained"
|
|
||||||
color="secondary"
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
marginBottom: "1rem",
|
|
||||||
textTransform: "capitalize",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Back
|
|
||||||
</Button>
|
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -210,10 +417,18 @@ const SinglePrincipalDistributorAllDetails = () => {
|
|||||||
<div style={{ marginTop: "2rem" }}>
|
<div style={{ marginTop: "2rem" }}>
|
||||||
<h5 style={{ fontWeight: "bold", marginBottom: "1rem" }}>
|
<h5 style={{ fontWeight: "bold", marginBottom: "1rem" }}>
|
||||||
• Addresses{" "}
|
• Addresses{" "}
|
||||||
</h5>{" "}
|
|
||||||
<h5 style={{ fontWeight: "bold", marginLeft: "1rem" }}>
|
|
||||||
• Total Addresses : {userAllAddress?.length}{" "}
|
|
||||||
</h5>
|
</h5>
|
||||||
|
<div className="d-flex justify-content-between align-items-center mb-3">
|
||||||
|
<h5 style={{ fontWeight: "bold" }}>
|
||||||
|
• Total Addresses: {userAllAddress?.length || 0}{" "}
|
||||||
|
</h5>
|
||||||
|
<Button
|
||||||
|
className="btn btn-primary"
|
||||||
|
onClick={() => handleOpenModal()} // Open modal for adding
|
||||||
|
>
|
||||||
|
Add Address
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
{userAllAddress?.length > 0 && (
|
{userAllAddress?.length > 0 && (
|
||||||
<div className="table-responsive table-shoot mt-3">
|
<div className="table-responsive table-shoot mt-3">
|
||||||
<table
|
<table
|
||||||
@ -225,41 +440,264 @@ const SinglePrincipalDistributorAllDetails = () => {
|
|||||||
style={{ background: "rgb(140, 213, 213)" }}
|
style={{ background: "rgb(140, 213, 213)" }}
|
||||||
>
|
>
|
||||||
<tr>
|
<tr>
|
||||||
<th>SL No.</th>
|
<th style={{ width: "5%" }}>SL No.</th>
|
||||||
<th>Address </th>
|
<th style={{ width: "20%" }}>Trade Name</th>
|
||||||
{/* <th>Profile Image</th> */}
|
<th style={{ width: "10%" }}>GST</th>
|
||||||
|
<th style={{ width: "10%" }}>PAN</th>
|
||||||
|
<th style={{ width: "37%" }}>Address</th>
|
||||||
|
<th style={{ width: "7%" }}>Default</th>
|
||||||
|
<th style={{ width: "11%" }}>Action</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{userAllAddress?.length === 0 && (
|
{userAllAddress?.map((address, i) => (
|
||||||
<tr className="text-center">
|
<tr key={address._id || i}>
|
||||||
<td colSpan="6">
|
<td className="text-start">
|
||||||
<h5>No Data Available</h5>
|
<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.gstNumber}</strong>
|
||||||
|
</td>
|
||||||
|
<td className="text-start">
|
||||||
|
<strong>{address.panNumber}</strong>
|
||||||
|
</td>
|
||||||
|
<td className="text-start">
|
||||||
|
<strong>
|
||||||
|
{address?.Name}-{address?.street}, {address?.city},{" "}
|
||||||
|
{address?.state}, {address?.country},{" "}
|
||||||
|
{address?.postalCode}
|
||||||
|
</strong>
|
||||||
|
</td>
|
||||||
|
<td className="text-center">
|
||||||
|
<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>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
)}
|
))}
|
||||||
{userAllAddress?.map((address, i) => {
|
|
||||||
return (
|
|
||||||
<tr key={i}>
|
|
||||||
<td className="text-start">{i + 1}</td>
|
|
||||||
<td style={{ maxWidth: "400px" }}>
|
|
||||||
<strong>
|
|
||||||
{address?.first_Name} {address?.last_name}
|
|
||||||
{address.tradeName
|
|
||||||
? `${address.tradeName},`
|
|
||||||
: "No tradeName "}
|
|
||||||
{address.gstNumber ? `${address.gstNumber},` : ""}
|
|
||||||
{address?.street},{address?.city},{address?.state},
|
|
||||||
{address?.country},{address?.postalCode}
|
|
||||||
</strong>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</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">
|
||||||
|
{/* GST Number and PAN Number */}
|
||||||
|
<div className="col-md-6">
|
||||||
|
<label>GST Number</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={currentAddress?.gstNumber || ""}
|
||||||
|
onChange={(e) =>
|
||||||
|
setCurrentAddress({
|
||||||
|
...currentAddress,
|
||||||
|
gstNumber: e.target.value,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
className="form-control mb-3"
|
||||||
|
placeholder="Enter GST number"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6">
|
||||||
|
<label>PAN Number</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={currentAddress?.panNumber || ""}
|
||||||
|
onChange={(e) =>
|
||||||
|
setCurrentAddress({
|
||||||
|
...currentAddress,
|
||||||
|
panNumber: e.target.value,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
className="form-control mb-3"
|
||||||
|
placeholder="Enter PAN number"
|
||||||
|
/>
|
||||||
|
</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>Country</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
disabled
|
||||||
|
value={currentAddress?.country || ""}
|
||||||
|
className="form-control mb-3"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="row">
|
||||||
|
<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="secondary" onClick={handleCloseModal}>
|
||||||
|
Cancel
|
||||||
|
</Button> */}
|
||||||
|
<Button variant="primary" onClick={handleSaveAddress}>
|
||||||
|
Save
|
||||||
|
</Button>
|
||||||
|
</Modal.Footer>
|
||||||
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -322,176 +322,183 @@ const Products = () => {
|
|||||||
style={{ background: "#ecdddd" }}
|
style={{ background: "#ecdddd" }}
|
||||||
>
|
>
|
||||||
<tr>
|
<tr>
|
||||||
<th className="text-start">Image</th>
|
<th className="text-start" style={{ width: "8%" }}>
|
||||||
<th className="text-start">SKU</th>
|
Image
|
||||||
<th className="text-start">Product</th>
|
</th>
|
||||||
<th className="text-start">Category Name</th>
|
<th className="text-start" style={{ width: "10%" }}>
|
||||||
<th className="text-start">Brand Name</th>
|
SKU
|
||||||
<th className="text-start">Price</th>
|
</th>
|
||||||
<th className="text-start">Status</th>
|
<th className="text-start" style={{ width: "20%" }}>
|
||||||
|
Product
|
||||||
<th className="text-start">Added On</th>
|
</th>
|
||||||
<th className="text-start">Actions</th>
|
<th className="text-start" style={{ width: "15%" }}>
|
||||||
|
Category Name
|
||||||
|
</th>
|
||||||
|
<th className="text-start" style={{ width: "15%" }}>
|
||||||
|
Brand Name
|
||||||
|
</th>
|
||||||
|
<th className="text-start" style={{ width: "10%" }}>
|
||||||
|
Price
|
||||||
|
</th>
|
||||||
|
<th className="text-start" style={{ width: "10%" }}>
|
||||||
|
Status
|
||||||
|
</th>
|
||||||
|
<th className="text-start" style={{ width: "12%" }}>
|
||||||
|
Added On
|
||||||
|
</th>
|
||||||
|
<th className="text-start" style={{ width: "12%" }}>
|
||||||
|
Actions
|
||||||
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<tr>
|
<tr>
|
||||||
<td className="text-center" colSpan="6">
|
<td className="text-center" colSpan="9">
|
||||||
Loading...
|
Loading...
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
) : productsData?.length > 0 ? (
|
) : productsData?.length > 0 ? (
|
||||||
productsData?.map((product, i) => {
|
productsData?.map((product, i) => (
|
||||||
return (
|
<tr key={i}>
|
||||||
<tr key={i}>
|
<td>
|
||||||
<th>
|
{product?.image &&
|
||||||
{product?.image &&
|
product?.image?.length !== 0 ? (
|
||||||
product?.image?.length !== 0 ? (
|
<img
|
||||||
<>
|
src={product?.image[0]?.url}
|
||||||
<img
|
width="50"
|
||||||
src={product?.image[0]?.url}
|
alt="preview"
|
||||||
width="50"
|
style={{ borderRadius: "5px" }}
|
||||||
alt="preview"
|
/>
|
||||||
/>
|
) : (
|
||||||
</>
|
<div style={{ fontSize: "13px" }}>
|
||||||
) : (
|
<p className="m-0">No</p>
|
||||||
<div
|
<p className="m-0">image</p>
|
||||||
className=""
|
<p className="m-0">uploaded!</p>
|
||||||
style={{ fontSize: "13px" }}
|
</div>
|
||||||
>
|
)}
|
||||||
<p className="m-0">No</p>
|
</td>
|
||||||
<p className="m-0">image</p>
|
<td
|
||||||
<p className="m-0">uploaded!</p>
|
className="text-start"
|
||||||
</div>
|
style={{
|
||||||
)}
|
whiteSpace: "nowrap",
|
||||||
</th>
|
overflow: "hidden",
|
||||||
<td className="text-start">{product.SKU}</td>
|
textOverflow: "ellipsis",
|
||||||
<td className="text-start">{product.name}</td>
|
}}
|
||||||
<td className="text-start">
|
>
|
||||||
{product.category?.categoryName !== ""
|
{product.SKU}
|
||||||
? product.category?.categoryName
|
</td>
|
||||||
: "Category Not selected "}
|
<td
|
||||||
</td>
|
className="text-start"
|
||||||
<td className="text-start">
|
style={{
|
||||||
{product.brand?.brandName !== ""
|
whiteSpace: "nowrap",
|
||||||
? product.brand?.brandName
|
overflow: "hidden",
|
||||||
: "Brand Not selected "}
|
textOverflow: "ellipsis",
|
||||||
</td>
|
}}
|
||||||
<th className="text-start">
|
>
|
||||||
{currencyDetails?.CurrencySymbol}
|
{product.name}
|
||||||
{product?.price}
|
</td>
|
||||||
</th>
|
<td
|
||||||
<td className="text-start">
|
className="text-start"
|
||||||
<span className=""></span>
|
style={{
|
||||||
|
whiteSpace: "nowrap",
|
||||||
|
overflow: "hidden",
|
||||||
|
textOverflow: "ellipsis",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{product.category?.categoryName ||
|
||||||
|
"Category Not selected"}
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
className="text-start"
|
||||||
|
style={{
|
||||||
|
whiteSpace: "nowrap",
|
||||||
|
overflow: "hidden",
|
||||||
|
textOverflow: "ellipsis",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{product.brand?.brandName ||
|
||||||
|
"Brand Not selected"}
|
||||||
|
</td>
|
||||||
|
<td className="text-start">
|
||||||
|
{currencyDetails?.CurrencySymbol}
|
||||||
|
{product?.price}
|
||||||
|
</td>
|
||||||
|
<td className="text-start">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className={`badge text-white ${
|
||||||
|
product?.product_Status === "Active"
|
||||||
|
? "text-bg-success"
|
||||||
|
: "text-bg-danger"
|
||||||
|
}`}
|
||||||
|
onClick={() => handleStatus(product._id)}
|
||||||
|
>
|
||||||
|
{product?.product_Status}
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
<td className="text-start">
|
||||||
|
{new Date(product.createdAt).toLocaleString(
|
||||||
|
"en-IN",
|
||||||
|
{
|
||||||
|
weekday: "short",
|
||||||
|
month: "short",
|
||||||
|
day: "numeric",
|
||||||
|
year: "numeric",
|
||||||
|
hour: "numeric",
|
||||||
|
minute: "numeric",
|
||||||
|
hour12: true,
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
<td className="text-start">
|
||||||
|
<Link
|
||||||
|
to={`/product/view/${product._id}`}
|
||||||
|
state={{ currencyDetails }}
|
||||||
|
>
|
||||||
<button
|
<button
|
||||||
type="button"
|
|
||||||
className={`badge text-white ${
|
|
||||||
product?.product_Status === "Active"
|
|
||||||
? "text-bg-success"
|
|
||||||
: "text-bg-danger"
|
|
||||||
}`}
|
|
||||||
onClick={() => {
|
|
||||||
handleStatus(product._id);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{product?.product_Status}
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
<td className="text-start">
|
|
||||||
{new Date(product.createdAt).toLocaleString(
|
|
||||||
"en-IN",
|
|
||||||
{
|
|
||||||
weekday: "short",
|
|
||||||
month: "short",
|
|
||||||
day: "numeric",
|
|
||||||
year: "numeric",
|
|
||||||
hour: "numeric",
|
|
||||||
minute: "numeric",
|
|
||||||
hour12: true,
|
|
||||||
}
|
|
||||||
)}
|
|
||||||
</td>
|
|
||||||
<td className="text-start">
|
|
||||||
<Link
|
|
||||||
to={`/product/view/${product._id}`}
|
|
||||||
state={{ currencyDetails }}
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
style={{
|
|
||||||
color: "white",
|
|
||||||
marginRight: "1rem",
|
|
||||||
}}
|
|
||||||
type="button"
|
|
||||||
className="
|
|
||||||
btn btn-primary btn-sm
|
|
||||||
waves-effect waves-light
|
|
||||||
btn-table
|
|
||||||
mx-1
|
|
||||||
mt-1
|
|
||||||
"
|
|
||||||
>
|
|
||||||
View
|
|
||||||
</button>
|
|
||||||
</Link>
|
|
||||||
|
|
||||||
<Link to={`/product/edit/${product._id}`}>
|
|
||||||
<button
|
|
||||||
style={{
|
|
||||||
color: "white",
|
|
||||||
marginRight: "1rem",
|
|
||||||
}}
|
|
||||||
type="button"
|
|
||||||
className="
|
|
||||||
btn btn-info btn-sm
|
|
||||||
waves-effect waves-light
|
|
||||||
btn-table
|
|
||||||
mt-1
|
|
||||||
mx-1
|
|
||||||
"
|
|
||||||
>
|
|
||||||
Edit
|
|
||||||
</button>
|
|
||||||
</Link>
|
|
||||||
|
|
||||||
<Link
|
|
||||||
to={"#"}
|
|
||||||
style={{
|
style={{
|
||||||
marginRight: "1rem",
|
color: "white",
|
||||||
|
marginRight: "0.5rem",
|
||||||
}}
|
}}
|
||||||
|
type="button"
|
||||||
|
className="btn btn-primary btn-sm waves-effect waves-light btn-table mx-1 mt-1"
|
||||||
>
|
>
|
||||||
<button
|
View
|
||||||
style={{ color: "white" }}
|
</button>
|
||||||
type="button"
|
</Link>
|
||||||
className="
|
|
||||||
btn btn-danger btn-sm
|
|
||||||
waves-effect waves-light
|
|
||||||
btn-table
|
|
||||||
mt-1
|
|
||||||
mx-1
|
|
||||||
|
|
||||||
"
|
<Link to={`/product/edit/${product._id}`}>
|
||||||
onClick={() => {
|
<button
|
||||||
handleDelete(product._id);
|
style={{
|
||||||
}}
|
color: "white",
|
||||||
>
|
marginRight: "0.5rem",
|
||||||
Delete
|
}}
|
||||||
</button>
|
type="button"
|
||||||
</Link>
|
className="btn btn-info btn-sm waves-effect waves-light btn-table mt-1 mx-1"
|
||||||
</td>
|
>
|
||||||
</tr>
|
Edit
|
||||||
);
|
</button>
|
||||||
})
|
</Link>
|
||||||
) : (
|
|
||||||
!loading &&
|
<button
|
||||||
productsData?.length === 0 && (
|
style={{ color: "white" }}
|
||||||
<tr className="text-center">
|
type="button"
|
||||||
<td colSpan="6">
|
className="btn btn-danger btn-sm waves-effect waves-light btn-table mt-1 mx-1"
|
||||||
<h5>No Product Available...</h5>
|
onClick={() => handleDelete(product._id)}
|
||||||
|
>
|
||||||
|
Delete
|
||||||
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
)
|
))
|
||||||
|
) : (
|
||||||
|
<tr className="text-center">
|
||||||
|
<td colSpan="9">
|
||||||
|
<h5>No Product Available...</h5>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
)}
|
)}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
Loading…
Reference in New Issue
Block a user