edit company profile get call corrected

This commit is contained in:
Senthamilselvi 2025-11-06 16:50:33 +05:30
parent 1455eed578
commit 9d0aca9f59
3 changed files with 210 additions and 289 deletions

View File

@ -278,11 +278,11 @@ function App() {
}
/>
</Route> */}
<Route path="/profile*" element={
<RequireRole allowedRoles={['EstablishmentUser']}>
<EditCompanyProfile />
</RequireRole>
} />
<Route path="/profile/edit/:id" element={
<RequireRole allowedRoles={['EstablishmentUser']}>
<EditCompanyProfile />
</RequireRole>
} />
{/* <Route
path="/admin/configuration/profile/:id?"
element={

View File

@ -116,29 +116,24 @@ const EstablishmentInfo = ({
[field]: event.target.value,
});
};
const handleEditProfile = (e) => {
const handleEditProfile = (e) => {
e.preventDefault();
// Get establishment_id directly from sessionStorage
const establishmentId = sessionStorage.getItem('establishment_id');
console.log('Edit Profile clicked, establishment_id:', establishmentId);
if (!establishmentId) {
alert('No establishment ID found in session');
return;
}
// Save current page to return after editing (optional)
localStorage.setItem('returnTo', window.location.pathname);
// Store context info
sessionStorage.setItem('edit_profile_from', 'EstablishmentUser');
// Navigate to profile edit page
console.log('Navigating to:', `/profile/edit/${establishmentId}`);
navigate(`/profile/edit/${establishmentId}`);
};
const handleEmployeeChange = (field) => (event) => {
onChange({
...info,

View File

@ -1,5 +1,5 @@
import React, { useState, useMemo, useCallback, useEffect, useRef } from "react";
import { useNavigate, useParams } from 'react-router-dom';
import { useNavigate, useParams, useSearchParams } from 'react-router-dom';
import { TextField, SelectField, PhoneField } from "@/components/common/FormControls";
import Loader from "@/components/common/Loader";
import { fetchEstablishmentDetail, updateEstablishment } from '@/services/establishments/establishmentService';
@ -7,31 +7,57 @@ import { fetchEmirates, fetchCityTowns } from '@/services/masters/masterService'
// Helper functions
const createEmptyProfile = () => ({
// Add all form fields with empty/default values here
userProfileName: '',
userProfileEmail: '',
// Add other fields as needed
permanentFactoryCode: '',
uniqueLicenseNumber: '',
industryCodeBusiness: '',
industryCodeCurrent: '',
contactName: '',
contactAddress: '',
contactCityTown: '',
contactCityTownId: '',
contactEmirate: '',
contactEmirateId: '',
contactMakaniNumber: '',
contactPersonName: '',
contactMobileNumber: '',
contactEmail: '',
contactPostalCode: '',
contactPoBox: '',
contactWebsite: '',
corporateName: '',
corporateAddress: '',
corporateCityTown: '',
corporateCityTownId: '',
corporateEmirate: '',
corporateEmirateId: '',
corporateMakaniNumber: '',
corporateContactPersonName: '',
corporateMobileNumber: '',
corporateEmail: '',
corporatePostalCode: '',
corporatePoBox: '',
corporateWebsite: '',
corporateSameAs: false,
employmentEmiratiMale: 0,
employmentEmiratiFemale: 0,
employmentNonEmiratiMale: 0,
employmentNonEmiratiFemale: 0,
});
const mapApiEstablishmentToProfile = (apiData) => {
console.log('API Data to map:', apiData);
// If the API response has a data property, use that
const data = apiData.data || apiData;
// Map API response to form fields
return {
// User Profile (using first user from users array)
userProfileName: data.users?.[0]?.name || '',
userProfileEmail: data.users?.[0]?.email || '',
// Identification Particulars
permanentFactoryCode: data.permanent_factory_code || '',
uniqueLicenseNumber: data.license_number || '',
industryCodeBusiness: data.isic_code || '',
industryCodeCurrent: data.isic_code || '',
// Establishment Contact Details
contactName: data.factory_name || '',
contactAddress: data.establishment_address || '',
contactCityTown: data.establishment_city?.name || '',
@ -45,8 +71,6 @@ const mapApiEstablishmentToProfile = (apiData) => {
contactPostalCode: data.establishment_postal_code || '',
contactPoBox: data.establishment_po_box || '',
contactWebsite: data.establishment_website || '',
// Corporate/Head Office
corporateName: data.corporate_name || '',
corporateAddress: data.corporate_address || '',
corporateCityTown: data.corporate_city?.name || '',
@ -61,8 +85,6 @@ const mapApiEstablishmentToProfile = (apiData) => {
corporatePoBox: data.corporate_po_box || '',
corporateWebsite: data.corporate_website || '',
corporateSameAs: data.corporate_same_as_establishment || false,
// Employment
employmentEmiratiMale: data.emirati_male || 0,
employmentEmiratiFemale: data.emirati_female || 0,
employmentNonEmiratiMale: data.non_emirati_male || 0,
@ -112,8 +134,8 @@ const captureCorporateValues = (data) => {
const EditCompanyProfile = ({ onClose: propOnClose }) => {
const navigate = useNavigate();
const { id: establishmentId } = useParams();
// Define default onClose function that navigates to survey page
console.log('EditCompanyProfile mounted, establishmentId from params:', establishmentId);
const onClose = propOnClose || (() => navigate('/survey'));
const [loading, setLoading] = useState(false);
const [form, setForm] = useState(createEmptyProfile());
@ -123,7 +145,6 @@ const EditCompanyProfile = ({ onClose: propOnClose }) => {
const [confirmError, setConfirmError] = useState("");
const [passwordReuseError, setPasswordReuseError] = useState("");
// State for emirate and city options
const [emirateOptions, setEmirateOptions] = useState([]);
const [emirateLookup, setEmirateLookup] = useState({});
const [contactCityOptions, setContactCityOptions] = useState([]);
@ -185,7 +206,6 @@ const EditCompanyProfile = ({ onClose: propOnClose }) => {
);
const validateStepFields = useCallback((stepIndex) => {
// Reset password reuse error when validating
setPasswordReuseError("");
const requiredFields = requiredFieldsByStep[stepIndex] || [];
if (!requiredFields.length) return true;
@ -205,7 +225,6 @@ const EditCompanyProfile = ({ onClose: propOnClose }) => {
}, [form, requiredFieldsByStep]);
const handleFormChange = useCallback((field, value) => {
// Handle city selection
if (field === 'contactCityTown') {
const foundCity = contactCityOptions.find(option => option.value === value || option.label === value);
setForm(prev => ({
@ -225,10 +244,10 @@ const EditCompanyProfile = ({ onClose: propOnClose }) => {
}));
return;
}
setForm((prev) => ({ ...prev, [field]: value }));
setFieldErrors((prev) => ({ ...prev, [field]: "" }));
// Clear password errors when user starts typing
if (field === 'userProfilePassword') {
setPasswordError("");
setPasswordReuseError("");
@ -236,83 +255,7 @@ const EditCompanyProfile = ({ onClose: propOnClose }) => {
if (field === 'userProfileConfirmPassword') {
setConfirmError("");
}
}, []);
const handleFormSubmit = async (e) => {
e.preventDefault();
if (validateStepFields(activeStep)) {
if (activeStep < formSteps.length - 1) {
setActiveStep(activeStep + 1);
} else {
try {
setLoading(true);
// Prepare the data for API
const establishmentData = {
factory_name: form.contactName,
establishment_address: form.contactAddress,
establishment_city: form.contactCityTownId,
establishment_emirate: form.contactEmirateId,
establishment_makani_number: form.contactMakaniNumber,
establishment_contact_person_name: form.contactPersonName,
establishment_mobile_number: form.contactMobileNumber,
establishment_contact_email: form.contactEmail,
establishment_postal_code: form.contactPostalCode,
establishment_po_box: form.contactPoBox,
establishment_website: form.contactWebsite,
// Corporate/Head Office
corporate_name: form.corporateName,
corporate_address: form.corporateAddress,
corporate_city: form.corporateCityTownId,
corporate_emirate: form.corporateEmirateId,
corporate_makani_number: form.corporateMakaniNumber,
corporate_contact_person_name: form.corporateContactPersonName,
corporate_mobile_number: form.corporateMobileNumber,
corporate_email: form.corporateEmail,
corporate_postal_code: form.corporatePostalCode,
corporate_po_box: form.corporatePoBox,
corporate_website: form.corporateWebsite,
corporate_same_as_establishment: form.corporateSameAs,
// Employment
emirati_male: form.employmentEmiratiMale || 0,
emirati_female: form.employmentEmiratiFemale || 0,
non_emirati_male: form.employmentNonEmiratiMale || 0,
non_emirati_female: form.employmentNonEmiratiFemale || 0,
};
console.log('Submitting establishment data:', {
establishmentId,
establishmentData
});
// If establishmentId exists, update the establishment
if (establishmentId) {
console.log('Updating establishment with ID:', establishmentId);
const response = await updateEstablishment(establishmentId, establishmentData);
console.log('Update response:', response);
// Show success message
alert('Establishment updated successfully!');
// Redirect to the dashboard or previous page
navigate('/dashboard');
} else {
// Handle case where no establishmentId is provided
console.error('No establishment ID provided for update');
alert('Error: No establishment ID provided for update');
}
} catch (error) {
console.error('Error updating establishment:', error);
alert('Failed to update establishment. Please try again.');
} finally {
setLoading(false);
}
}
}
};
}, [contactCityOptions, corporateCityOptions]);
const handleNext = useCallback(() => {
if (validateStepFields(activeStep)) {
@ -326,87 +269,11 @@ const EditCompanyProfile = ({ onClose: propOnClose }) => {
if (activeStep > 0) setActiveStep(activeStep - 1);
}, [activeStep]);
// Fetch establishment details when ID is provided
useEffect(() => {
const fetchData = async () => {
if (!establishmentId) {
return;
}
try {
setLoading(true);
console.log('Fetching establishment details for ID:', establishmentId);
const response = await fetchEstablishmentDetail(establishmentId)
.then(res => {
console.log('Raw API Response:', res);
return res;
})
.catch(error => {
console.error('API call failed:', {
message: error.message,
status: error.response?.status,
data: error.response?.data,
config: error.config
});
throw error;
});
console.log('API Response:', response);
if (!response) {
console.error('Empty response received');
return;
}
const mappedProfile = mapApiEstablishmentToProfile(response);
console.log('Mapped Profile:', mappedProfile);
const formData = {
...createEmptyProfile(),
...mappedProfile,
apiId: establishmentId,
corporateSameAs: Boolean(mappedProfile.corporateSameAs)
};
console.log('Form Data before corporate same as:', formData);
if (formData.corporateSameAs) {
Object.entries(contactToCorporateMap).forEach(([source, target]) => {
formData[target] = formData[source];
});
}
const totals = computeEmploymentTotals(formData);
Object.assign(formData, totals);
console.log('Final Form Data:', formData);
setForm(formData);
initialSnapshotRef.current = formData;
corporateBackupRef.current = captureCorporateValues(formData);
} catch (error) {
console.error('Failed to load establishment details:', {
error,
message: error.message,
response: error.response?.data,
status: error.response?.status
});
} finally {
setLoading(false);
}
};
fetchData();
}, [establishmentId]);
// Load cities based on selected emirate
const loadCities = useCallback(async (emirateId, setCityOptions) => {
if (!emirateId) {
setCityOptions([]);
return;
return [];
}
try {
@ -429,6 +296,66 @@ const EditCompanyProfile = ({ onClose: propOnClose }) => {
}
}, []);
useEffect(() => {
console.log('useEffect triggered, establishmentId:', establishmentId);
const fetchData = async () => {
if (!establishmentId) {
console.log('No establishmentId found, skipping fetch');
return;
}
try {
setLoading(true);
console.log('Starting API call to fetch establishment details for ID:', establishmentId);
const response = await fetchEstablishmentDetail(establishmentId);
console.log('API Response received:', response);
if (!response) {
console.error('Empty response received');
return;
}
const mappedProfile = mapApiEstablishmentToProfile(response);
console.log('Mapped Profile:', mappedProfile);
const formData = {
...createEmptyProfile(),
...mappedProfile,
apiId: establishmentId,
corporateSameAs: Boolean(mappedProfile.corporateSameAs)
};
console.log('Form Data before corporate same as:', formData);
if (formData.corporateSameAs) {
Object.entries(contactToCorporateMap).forEach(([source, target]) => {
formData[target] = formData[source];
});
}
const totals = computeEmploymentTotals(formData);
Object.assign(formData, totals);
console.log('Final Form Data:', formData);
setForm(formData);
initialSnapshotRef.current = formData;
corporateBackupRef.current = captureCorporateValues(formData);
} catch (error) {
console.error('Failed to load establishment details:', error);
alert('Failed to load company details. Please try again.');
} finally {
setLoading(false);
}
};
fetchData();
}, [establishmentId]);
// Load emirates on component mount
useEffect(() => {
let cancelled = false;
@ -467,49 +394,31 @@ const EditCompanyProfile = ({ onClose: propOnClose }) => {
};
}, []);
// Load contact cities when emirate changes
// Load contact cities when emirate ID changes
useEffect(() => {
const loadContactCities = async () => {
if (form.contactEmirateId) {
await loadCities(form.contactEmirateId, setContactCityOptions);
// If we have a city ID but it's not in the options, try to find and add it
if (form.contactCityTownId && !contactCityOptions.some(city => city.id === form.contactCityTownId)) {
const cities = await loadCities(form.contactEmirateId, setContactCityOptions);
const currentCity = cities.find(city => city.id === form.contactCityTownId);
if (currentCity) {
setContactCityOptions(prev => [...prev, currentCity]);
}
}
} else {
setContactCityOptions([]);
}
};
loadContactCities();
}, [form.contactEmirateId, form.contactCityTownId, loadCities]);
}, [form.contactEmirateId, loadCities]);
// Load corporate cities when emirate changes
// Load corporate cities when emirate ID changes
useEffect(() => {
const loadCorporateCities = async () => {
if (form.corporateEmirateId) {
await loadCities(form.corporateEmirateId, setCorporateCityOptions);
// If we have a city ID but it's not in the options, try to find and add it
if (form.corporateCityTownId && !corporateCityOptions.some(city => city.id === form.corporateCityTownId)) {
const cities = await loadCities(form.corporateEmirateId, setCorporateCityOptions);
const currentCity = cities.find(city => city.id === form.corporateCityTownId);
if (currentCity) {
setCorporateCityOptions(prev => [...prev, currentCity]);
}
}
} else {
setCorporateCityOptions([]);
}
};
loadCorporateCities();
}, [form.corporateEmirateId, form.corporateCityTownId, loadCities]);
}, [form.corporateEmirateId, loadCities]);
// Calculate totals when employment numbers change
useEffect(() => {
@ -525,84 +434,91 @@ const EditCompanyProfile = ({ onClose: propOnClose }) => {
form.employmentNonEmiratiFemale
]);
// Handle corporate same as establishment
useEffect(() => {
if (form.corporateSameAs) {
// Save current corporate values if this is the first time checking
if (!corporateBackupRef.current) {
corporateBackupRef.current = captureCorporateValues(form);
}
// Handle corporate same as establishment checkbox
const handleCorporateSameAsChange = useCallback((checked) => {
if (checked) {
// Save current corporate values before overwriting
corporateBackupRef.current = captureCorporateValues(form);
// Copy contact details to corporate
const corporateUpdates = {};
const corporateUpdates = { corporateSameAs: true };
Object.entries(contactToCorporateMap).forEach(([source, target]) => {
corporateUpdates[target] = form[source];
// Also copy the ID fields
if (source.endsWith('CityTown')) {
corporateUpdates[`${target}Id`] = form[`${source}Id`];
} else if (source.endsWith('Emirate')) {
corporateUpdates[`${target}Id`] = form[`${source}Id`];
}
});
setForm(prev => ({
...prev,
...corporateUpdates
}));
} else if (corporateBackupRef.current) {
} else {
// Restore original corporate values
setForm(prev => ({
...prev,
...corporateBackupRef.current
corporateSameAs: false,
...(corporateBackupRef.current || {})
}));
corporateBackupRef.current = null;
}
}, [form.corporateSameAs, form.contactName, form.contactAddress, form.contactCityTown, form.contactEmirate, form.contactCityTownId, form.contactEmirateId]);
}, [form]);
const handleSave = async () => {
console.log("Submitted data:", form);
try {
setLoading(true);
// Prepare the data for API
const establishmentData = {
factory_name: form.contactName,
establishment_address: form.contactAddress,
establishment_city: form.contactCityTownId,
establishment_emirate: form.contactEmirateId,
establishment_makani_number: form.contactMakaniNumber,
establishment_contact_person_name: form.contactPersonName,
establishment_mobile_number: form.contactMobileNumber,
establishment_contact_email: form.contactEmail,
establishment_postal_code: form.contactPostalCode,
establishment_po_box: form.contactPoBox,
establishment_website: form.contactWebsite,
// Corporate/Head Office
corporate_name: form.corporateName,
corporate_address: form.corporateAddress,
corporate_city: form.corporateCityTownId,
corporate_emirate: form.corporateEmirateId,
corporate_makani_number: form.corporateMakaniNumber,
corporate_contact_person_name: form.corporateContactPersonName,
corporate_mobile_number: form.corporateMobileNumber,
corporate_email: form.corporateEmail,
corporate_postal_code: form.corporatePostalCode,
corporate_po_box: form.corporatePoBox,
corporate_website: form.corporateWebsite,
corporate_same_as_establishment: form.corporateSameAs,
// Employment
emirati_male: form.employmentEmiratiMale || 0,
emirati_female: form.employmentEmiratiFemale || 0,
non_emirati_male: form.employmentNonEmiratiMale || 0,
non_emirati_female: form.employmentNonEmiratiFemale || 0,
establishment_code: form.uniqueLicenseNumber || "",
factory_name: form.contactName || "",
permanent_factory_code: form.permanentFactoryCode || "",
industry_code: form.industryCodeBusiness || "",
license_number: form.uniqueLicenseNumber || "",
isic_code: form.industryCodeCurrent || "",
description: form.industryDescription || "",
establishment_address: form.contactAddress || "",
establishment_city_town_id: form.contactCityTownId ? Number(form.contactCityTownId) : null,
establishment_emirate_id: form.contactEmirateId ? Number(form.contactEmirateId) : null,
corporate_city_town_id: form.corporateCityTownId ? Number(form.corporateCityTownId) : null,
corporate_emirate_id: form.corporateEmirateId ? Number(form.corporateEmirateId) : null,
establishment_postal_code: form.contactPostalCode || "",
establishment_po_box: form.contactPoBox || "",
establishment_makani_number: form.contactMakaniNumber || "",
establishment_contact_person_name: form.contactPersonName || "",
establishment_contact_person_designation: form.contactPersonDesignation || "",
establishment_mobile_number: form.contactMobileNumber || "",
establishment_contact_email: form.contactEmail || "",
establishment_website: form.contactWebsite || "",
corporate_same_as_establishment: Boolean(form.corporateSameAs),
corporate_name: form.corporateName || "",
corporate_address: form.corporateAddress || "",
corporate_postal_code: form.corporatePostalCode || "",
corporate_po_box: form.corporatePoBox || "",
corporate_makani_number: form.corporateMakaniNumber || "",
corporate_contact_person_name: form.corporateContactPersonName || "",
corporate_contact_person_designation: form.corporateContactPersonDesignation || "",
corporate_mobile_number: form.corporateMobileNumber || "",
corporate_email: form.corporateEmail || "",
corporate_website: form.corporateWebsite || "",
emirati_male: Number(form.employmentEmiratiMale) || 0,
emirati_female: Number(form.employmentEmiratiFemale) || 0,
non_emirati_male: Number(form.employmentNonEmiratiMale) || 0,
non_emirati_female: Number(form.employmentNonEmiratiFemale) || 0,
total_emirati:
(Number(form.employmentEmiratiMale) || 0) +
(Number(form.employmentEmiratiFemale) || 0),
total_employees:
(Number(form.employmentEmiratiMale) || 0) +
(Number(form.employmentEmiratiFemale) || 0) +
(Number(form.employmentNonEmiratiMale) || 0) +
(Number(form.employmentNonEmiratiFemale) || 0),
updated_by: 1
};
console.log("Payload sent:", establishmentData);
if (establishmentId) {
console.log('Updating establishment with ID:', establishmentId);
await updateEstablishment(establishmentId, establishmentData);
await updateEstablishment(establishmentId, establishmentData);
alert('Profile updated successfully!');
onClose();
} else {
@ -616,7 +532,8 @@ const EditCompanyProfile = ({ onClose: propOnClose }) => {
setLoading(false);
}
};
const renderStepContent = () => {
switch (activeStep) {
case 0:
@ -765,15 +682,11 @@ const EditCompanyProfile = ({ onClose: propOnClose }) => {
const selectedValue = e.target.value;
const selectedEmirate = emirateOptions.find(opt => opt.value === selectedValue);
// Update emirate fields
handleFormChange("contactEmirate", selectedEmirate?.name || '');
handleFormChange("contactEmirateId", selectedEmirate?.id || '');
// Clear city fields
handleFormChange("contactCityTown", '');
handleFormChange("contactCityTownId", '');
// Load cities for the selected emirate
if (selectedEmirate?.id) {
const cities = await loadCities(selectedEmirate.id, setContactCityOptions);
setContactCityOptions(cities);
@ -869,7 +782,6 @@ const EditCompanyProfile = ({ onClose: propOnClose }) => {
required
error={fieldErrors.contactEmail}
/>
<TextField
label="Website"
value={form.contactWebsite || ""}
@ -883,21 +795,20 @@ const EditCompanyProfile = ({ onClose: propOnClose }) => {
case 3:
return (
<div className="space-y-4">
<div className="flex flex-col gap-2 md:flex-row md:items-center md:justify-between">
<div>
<h4 className="text-[16px] font-semibold text-[#232528]">Corporate/Head Office Contact</h4>
</div>
<label className="inline-flex items-center gap-2 text-sm text-[#232528]">
<input
type="checkbox"
checked={form.corporateSameAs}
onChange={(e) => handleCorporateSameAsChange(e.target.checked)}
className="h-4 w-4 rounded border-2 border-[#CBA344] text-[#92722A] focus:ring-[#92722A]"
/>
Same as Establishment Contact
</label>
</div>
{/* </div> */}
<div className="flex flex-col gap-2 md:flex-row md:items-center md:justify-between">
<div>
<h4 className="text-[16px] font-semibold text-[#232528]">Corporate/Head Office Contact</h4>
</div>
<label className="inline-flex items-center gap-2 text-sm text-[#232528]">
<input
type="checkbox"
checked={form.corporateSameAs}
onChange={(e) => handleCorporateSameAsChange(e.target.checked)}
className="h-4 w-4 rounded border-2 border-[#CBA344] text-[#92722A] focus:ring-[#92722A]"
/>
Same as Establishment Contact
</label>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
<TextField
label="Name"
@ -939,11 +850,26 @@ const EditCompanyProfile = ({ onClose: propOnClose }) => {
<SelectField
label="Emirate"
name="corporateEmirate"
value={form.corporateEmirate || ""}
onChange={(e) => handleFormChange("corporateEmirate", e.target.value)}
value={form.corporateEmirateId || ""}
onChange={async (e) => {
const selectedValue = e.target.value;
const selectedEmirate = emirateOptions.find(opt => opt.value === selectedValue);
handleFormChange("corporateEmirate", selectedEmirate?.name || '');
handleFormChange("corporateEmirateId", selectedEmirate?.id || '');
handleFormChange("corporateCityTown", '');
handleFormChange("corporateCityTownId", '');
if (selectedEmirate?.id) {
const cities = await loadCities(selectedEmirate.id, setCorporateCityOptions);
setCorporateCityOptions(cities);
} else {
setCorporateCityOptions([]);
}
}}
options={emirateOptions.map(opt => ({
value: opt.name,
label: opt.name
value: opt.value,
label: opt.label
}))}
placeholder="Select Emirate"
width="100%"
@ -1240,4 +1166,4 @@ const EditCompanyProfile = ({ onClose: propOnClose }) => {
);
};
export default EditCompanyProfile;
export default EditCompanyProfile;