549 lines
16 KiB
JavaScript
549 lines
16 KiB
JavaScript
import React, { useState, useEffect } from "react";
|
|
import {
|
|
TextField,
|
|
Button,
|
|
Card,
|
|
Grid,
|
|
Typography,
|
|
Autocomplete,
|
|
CircularProgress,
|
|
} from "@mui/material";
|
|
import { useNavigate } from "react-router-dom";
|
|
import { toast } from "react-hot-toast";
|
|
import axios from "axios";
|
|
import { isAutheticated } from "src/auth";
|
|
import { City, State } from "country-state-city";
|
|
|
|
const AddRetailDistributor = () => {
|
|
const navigate = useNavigate();
|
|
const token = isAutheticated();
|
|
|
|
const [user, setUser] = useState({
|
|
name: "",
|
|
email: "",
|
|
trade_name: "",
|
|
address: "",
|
|
state: "",
|
|
city: "",
|
|
district: "",
|
|
pincode: "",
|
|
mobile_number: "",
|
|
pan_number: "",
|
|
aadhar_number: "",
|
|
gst_number: "",
|
|
});
|
|
|
|
const [files, setFiles] = useState({
|
|
selfieEntranceImg: null,
|
|
panImg: null,
|
|
aadharImg: null,
|
|
gstImg: null,
|
|
pesticideLicenseImg: null,
|
|
fertilizerLicenseImg: null,
|
|
});
|
|
|
|
const [loading, setLoading] = useState(false);
|
|
const [stateOptions, setStateOptions] = useState([]);
|
|
const [cityOptions, setCityOptions] = useState([]);
|
|
const [selectedState, setSelectedState] = useState(null);
|
|
const [selectedCity, setSelectedCity] = useState(null);
|
|
const [errors, setErrors] = useState({});
|
|
|
|
useEffect(() => {
|
|
const fetchStates = async () => {
|
|
const states = State.getStatesOfCountry("IN").map((state) => ({
|
|
label: state.name,
|
|
value: state.isoCode,
|
|
}));
|
|
setStateOptions(states);
|
|
};
|
|
fetchStates();
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
const fetchCities = async () => {
|
|
if (selectedState) {
|
|
const cities = City.getCitiesOfState("IN", selectedState.value).map(
|
|
(city) => ({
|
|
label: city.name,
|
|
value: city.name,
|
|
})
|
|
);
|
|
setCityOptions(cities);
|
|
}
|
|
};
|
|
fetchCities();
|
|
}, [selectedState]);
|
|
|
|
const handleInputChange = (e) => {
|
|
setUser({ ...user, [e.target.name]: e.target.value });
|
|
};
|
|
|
|
const handleStateChange = (event, newValue) => {
|
|
setSelectedState(newValue);
|
|
};
|
|
|
|
const handleCityChange = (event, newValue) => {
|
|
setSelectedCity(newValue);
|
|
};
|
|
|
|
const handleFileChange = (e) => {
|
|
const { name, files } = e.target;
|
|
if (files.length > 0) {
|
|
const file = files[0];
|
|
if (["image/png", "image/jpeg", "image/jpg"].includes(file.type)) {
|
|
setFiles((prev) => ({ ...prev, [name]: file }));
|
|
} else {
|
|
toast.error("Only PNG, JPG, and JPEG files are allowed.");
|
|
}
|
|
}
|
|
};
|
|
|
|
const handleFormSubmit = async (e) => {
|
|
e.preventDefault();
|
|
try {
|
|
// Validate input fields
|
|
if (
|
|
!user.name ||
|
|
!user.email ||
|
|
!user.trade_name ||
|
|
!user.address ||
|
|
!user.mobile_number ||
|
|
!user.pan_number ||
|
|
!user.aadhar_number ||
|
|
!user.gst_number ||
|
|
!selectedState ||
|
|
!selectedCity
|
|
) {
|
|
setErrors({ message: "Fill all required fields!" });
|
|
return;
|
|
}
|
|
|
|
setLoading(true);
|
|
|
|
const formData = new FormData();
|
|
formData.append("name", user.name);
|
|
formData.append("email", user.email);
|
|
formData.append("trade_name", user.trade_name);
|
|
formData.append("address", user.address);
|
|
formData.append("state", selectedState.label);
|
|
formData.append("city", selectedCity.value);
|
|
formData.append("district", user.district);
|
|
formData.append("pincode", user.pincode);
|
|
formData.append("mobile_number", user.mobile_number);
|
|
formData.append("pan_number", user.pan_number);
|
|
formData.append("aadhar_number", user.aadhar_number);
|
|
formData.append("gst_number", user.gst_number);
|
|
|
|
// Ensure files are included only if they exist
|
|
Object.keys(files).forEach((key) => {
|
|
if (files[key]) {
|
|
formData.append(key, files[key]);
|
|
}
|
|
});
|
|
|
|
// Attempt to create distributor
|
|
const response = await axios.post("/api/kyc/create-admin/", formData, {
|
|
headers: {
|
|
"Content-Type": "multipart/form-data",
|
|
"Authorization": `Bearer ${token}`,
|
|
},
|
|
});
|
|
|
|
if (response.data.success) {
|
|
toast.success("Retailers created successfully!");
|
|
navigate("/retail-distributor");
|
|
}
|
|
} catch (error) {
|
|
setLoading(false);
|
|
if (error.response && error.response.data) {
|
|
toast.error(error.response.data.message || "Something went wrong!");
|
|
} else {
|
|
toast.error("Something went wrong!");
|
|
}
|
|
}
|
|
};
|
|
|
|
const handleCancel = () => {
|
|
navigate("/retail-distributor");
|
|
};
|
|
return (
|
|
<div>
|
|
<Card
|
|
sx={{ padding: "1rem", marginBottom: "1rem", position: "relative" }}
|
|
>
|
|
<Button
|
|
variant="outlined"
|
|
color="secondary"
|
|
onClick={handleCancel}
|
|
sx={{ position: "absolute", top: "10px", right: "10px" }}
|
|
>
|
|
Cancel
|
|
</Button>
|
|
<Typography variant="h5" sx={{ mb: 3 }}>
|
|
Add Retailer
|
|
</Typography>
|
|
<form onSubmit={handleFormSubmit}>
|
|
<Typography variant="h5" sx={{ mb: 2 }}>
|
|
Basic Information
|
|
</Typography>
|
|
<Grid container spacing={2} sx={{ mb: 2 }}>
|
|
{/* Name */}
|
|
<Grid item xs={12} className="d-flex align-items-center">
|
|
<Grid item xs={2}>
|
|
<Typography
|
|
variant="body1"
|
|
htmlFor="name"
|
|
className="form-label"
|
|
>
|
|
Name*
|
|
</Typography>
|
|
</Grid>
|
|
<Grid item xs={10}>
|
|
<TextField
|
|
id="name"
|
|
required
|
|
type="text"
|
|
fullWidth
|
|
name="name"
|
|
value={user.name}
|
|
variant="outlined"
|
|
onChange={handleInputChange}
|
|
/>
|
|
</Grid>
|
|
</Grid>
|
|
<Grid item xs={12} className="d-flex align-items-center">
|
|
<Grid item xs={2}>
|
|
<Typography
|
|
variant="body1"
|
|
htmlFor="email"
|
|
className="form-label"
|
|
>
|
|
Email*
|
|
</Typography>
|
|
</Grid>
|
|
<Grid item xs={10}>
|
|
<TextField
|
|
id="email"
|
|
required
|
|
type="text"
|
|
fullWidth
|
|
name="email"
|
|
value={user.email}
|
|
variant="outlined"
|
|
onChange={handleInputChange}
|
|
/>
|
|
</Grid>
|
|
</Grid>
|
|
{/* Trade Name */}
|
|
<Grid item xs={12} className="d-flex align-items-center">
|
|
<Grid item xs={2}>
|
|
<Typography
|
|
variant="body1"
|
|
htmlFor="trade_name"
|
|
className="form-label"
|
|
>
|
|
Trade Name*
|
|
</Typography>
|
|
</Grid>
|
|
<Grid item xs={10}>
|
|
<TextField
|
|
id="trade_name"
|
|
required
|
|
type="text"
|
|
fullWidth
|
|
name="trade_name"
|
|
value={user.trade_name}
|
|
variant="outlined"
|
|
onChange={handleInputChange}
|
|
/>
|
|
</Grid>
|
|
</Grid>
|
|
|
|
{/* Address */}
|
|
<Grid item xs={12} className="d-flex align-items-center">
|
|
<Grid item xs={2}>
|
|
<Typography
|
|
variant="body1"
|
|
htmlFor="address"
|
|
className="form-label"
|
|
>
|
|
Address*
|
|
</Typography>
|
|
</Grid>
|
|
<Grid item xs={10}>
|
|
<TextField
|
|
id="address"
|
|
required
|
|
type="text"
|
|
fullWidth
|
|
name="address"
|
|
value={user.address}
|
|
variant="outlined"
|
|
onChange={handleInputChange}
|
|
/>
|
|
</Grid>
|
|
</Grid>
|
|
|
|
{/* Mobile Number */}
|
|
<Grid item xs={12} className="d-flex align-items-center">
|
|
<Grid item xs={2}>
|
|
<Typography
|
|
variant="body1"
|
|
htmlFor="mobile_number"
|
|
className="form-label"
|
|
>
|
|
Mobile Number*
|
|
</Typography>
|
|
</Grid>
|
|
<Grid item xs={10}>
|
|
<TextField
|
|
id="mobile_number"
|
|
required
|
|
type="text"
|
|
fullWidth
|
|
name="mobile_number"
|
|
value={user.mobile_number}
|
|
variant="outlined"
|
|
onChange={handleInputChange}
|
|
/>
|
|
</Grid>
|
|
</Grid>
|
|
|
|
{/* PAN Number */}
|
|
<Grid item xs={12} className="d-flex align-items-center">
|
|
<Grid item xs={2}>
|
|
<Typography
|
|
variant="body1"
|
|
htmlFor="pan_number"
|
|
className="form-label"
|
|
>
|
|
PAN Number*
|
|
</Typography>
|
|
</Grid>
|
|
<Grid item xs={10}>
|
|
<TextField
|
|
id="pan_number"
|
|
required
|
|
type="text"
|
|
fullWidth
|
|
name="pan_number"
|
|
value={user.pan_number}
|
|
variant="outlined"
|
|
onChange={handleInputChange}
|
|
/>
|
|
</Grid>
|
|
</Grid>
|
|
|
|
{/* Aadhar Number */}
|
|
<Grid item xs={12} className="d-flex align-items-center">
|
|
<Grid item xs={2}>
|
|
<Typography
|
|
variant="body1"
|
|
htmlFor="aadhar_number"
|
|
className="form-label"
|
|
>
|
|
Aadhar Number*
|
|
</Typography>
|
|
</Grid>
|
|
<Grid item xs={10}>
|
|
<TextField
|
|
id="aadhar_number"
|
|
required
|
|
type="text"
|
|
fullWidth
|
|
name="aadhar_number"
|
|
value={user.aadhar_number}
|
|
variant="outlined"
|
|
onChange={handleInputChange}
|
|
/>
|
|
</Grid>
|
|
</Grid>
|
|
|
|
{/* GST Number */}
|
|
<Grid item xs={12} className="d-flex align-items-center">
|
|
<Grid item xs={2}>
|
|
<Typography
|
|
variant="body1"
|
|
htmlFor="gst_number"
|
|
className="form-label"
|
|
>
|
|
GST Number*
|
|
</Typography>
|
|
</Grid>
|
|
<Grid item xs={10}>
|
|
<TextField
|
|
id="gst_number"
|
|
required
|
|
type="text"
|
|
fullWidth
|
|
name="gst_number"
|
|
value={user.gst_number}
|
|
variant="outlined"
|
|
onChange={handleInputChange}
|
|
/>
|
|
</Grid>
|
|
</Grid>
|
|
|
|
{/* State */}
|
|
<Grid item xs={12} className="d-flex align-items-center">
|
|
<Grid item xs={2}>
|
|
<Typography
|
|
variant="body1"
|
|
htmlFor="state"
|
|
className="form-label"
|
|
>
|
|
State*
|
|
</Typography>
|
|
</Grid>
|
|
<Grid item xs={10}>
|
|
<Autocomplete
|
|
options={stateOptions}
|
|
value={selectedState}
|
|
onChange={handleStateChange}
|
|
renderInput={(params) => (
|
|
<TextField
|
|
{...params}
|
|
id="state"
|
|
required
|
|
variant="outlined"
|
|
/>
|
|
)}
|
|
/>
|
|
</Grid>
|
|
</Grid>
|
|
|
|
{/* City */}
|
|
<Grid item xs={12} className="d-flex align-items-center">
|
|
<Grid item xs={2}>
|
|
<Typography
|
|
variant="body1"
|
|
htmlFor="city"
|
|
className="form-label"
|
|
>
|
|
City*
|
|
</Typography>
|
|
</Grid>
|
|
<Grid item xs={10}>
|
|
<Autocomplete
|
|
options={cityOptions}
|
|
value={selectedCity}
|
|
onChange={handleCityChange}
|
|
renderInput={(params) => (
|
|
<TextField
|
|
{...params}
|
|
id="city"
|
|
required
|
|
variant="outlined"
|
|
/>
|
|
)}
|
|
/>
|
|
</Grid>
|
|
</Grid>
|
|
|
|
{/* District */}
|
|
<Grid item xs={12} className="d-flex align-items-center">
|
|
<Grid item xs={2}>
|
|
<Typography
|
|
variant="body1"
|
|
htmlFor="district"
|
|
className="form-label"
|
|
>
|
|
District*
|
|
</Typography>
|
|
</Grid>
|
|
<Grid item xs={10}>
|
|
<TextField
|
|
id="district"
|
|
type="text"
|
|
fullWidth
|
|
name="district"
|
|
value={user.district}
|
|
variant="outlined"
|
|
onChange={handleInputChange}
|
|
/>
|
|
</Grid>
|
|
</Grid>
|
|
|
|
{/* Pincode */}
|
|
<Grid item xs={12} className="d-flex align-items-center">
|
|
<Grid item xs={2}>
|
|
<Typography
|
|
variant="body1"
|
|
htmlFor="pincode"
|
|
className="form-label"
|
|
>
|
|
Pincode*
|
|
</Typography>
|
|
</Grid>
|
|
<Grid item xs={10}>
|
|
<TextField
|
|
id="pincode"
|
|
type="text"
|
|
fullWidth
|
|
name="pincode"
|
|
value={user.pincode}
|
|
variant="outlined"
|
|
onChange={handleInputChange}
|
|
/>
|
|
</Grid>
|
|
</Grid>
|
|
|
|
{/* File Uploads */}
|
|
{[
|
|
{ label: "Selfie Entrance Image*", name: "selfieEntranceImg" },
|
|
{ label: "PAN Image*", name: "panImg" },
|
|
{ label: "Aadhar Image*", name: "aadharImg" },
|
|
{ label: "GST Image*", name: "gstImg" },
|
|
{ label: "Pesticide License Image*", name: "pesticideLicenseImg" },
|
|
{ label: "Fertilizer License Image*", name: "fertilizerLicenseImg" },
|
|
].map(({ label, name }) => (
|
|
<Grid item xs={12} className="d-flex align-items-center" key={name}>
|
|
<Grid item xs={2}>
|
|
<Typography
|
|
variant="body1"
|
|
htmlFor={name}
|
|
className="form-label"
|
|
>
|
|
{label}
|
|
</Typography>
|
|
</Grid>
|
|
<Grid item xs={10}>
|
|
<input
|
|
type="file"
|
|
id={name}
|
|
name={name}
|
|
onChange={handleFileChange}
|
|
accept=".png,.jpg,.jpeg"
|
|
/>
|
|
</Grid>
|
|
</Grid>
|
|
))}
|
|
|
|
{/* Submit Button */}
|
|
<Grid item xs={12} className="d-flex align-items-center">
|
|
<Grid item xs={2}></Grid>
|
|
<Grid item xs={10}>
|
|
<Button
|
|
type="submit"
|
|
variant="contained"
|
|
color="primary"
|
|
disabled={loading}
|
|
>
|
|
{loading ? (
|
|
<CircularProgress size={24} />
|
|
) : (
|
|
"Submit"
|
|
)}
|
|
</Button>
|
|
</Grid>
|
|
</Grid>
|
|
</Grid>
|
|
</form>
|
|
</Card>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default AddRetailDistributor;
|