import dayjs, { Dayjs } from 'dayjs'; import { t } from 'i18next'; import { useEffect, useState } from 'react'; import { useParams } from 'react-router-dom'; import { toast } from 'sonner'; import DayPicker from '../../../../components/button/DayPicker'; import MultiSelectDropdown from '../../../../components/dropdown/MultiSelectDropdown'; import SelectDropdown from '../../../../components/dropdown/SelectDropdown'; import SimpleInput from '../../../../components/input/SimpleInput'; import TextArea from '../../../../components/text/TextArea'; import TopMenu from '../../../../components/topmenu/Topmenu'; import type { AuditById, Client, Company, Language, Template, UpdateAudit, User as Collaborator, } from '../../../../services/audits'; import { getAuditById, getClients, getCollaborators, getCompanies, getLanguages, getTemplates, updateAudit, } from '../../../../services/audits'; import { GeneralDivWrapper } from './GeneralDivWrapper'; type ListItem = { id: number; value: string; label?: string; }; export const General = () => { const { auditId } = useParams(); const [dataAudit, setDataAudit] = useState(); const [nameAudit, setNameAudit] = useState(''); const [auditType, setAuditType] = useState(''); const [languageOptions, setLanguageOptions] = useState([]); const [currentLanguage, setCurrentLanguage] = useState(null); const [loadingLanguages, setLoadingLanguages] = useState(true); const [templates, setTemplates] = useState([]); const [templateOptions, setTemplateOptions] = useState([]); const [currentTemplate, setCurrentTemplate] = useState(null); const [loadingTemplates, setLoadingTemplates] = useState(true); const [companies, setCompanies] = useState([]); const [companyOptions, setCompanyOptions] = useState([]); const [currentCompany, setCurrentCompany] = useState(null); const [loadingCompanies, setLoadingCompanies] = useState(true); const [clients, setClients] = useState([]); const [clientOptions, setClientOptions] = useState([]); const [currentClient, setCurrentClient] = useState(null); const [loadingClients, setLoadingClients] = useState(true); const [collaborators, setCollaborators] = useState([]); const [collaboratorOptions, setCollaboratorOptions] = useState( [], ); const [currentCollaborators, setCurrentCollaborators] = useState( [], ); const [loadingCollaborators, setLoadingCollaborators] = useState(true); const [startDate, setStartDate] = useState(null); const [endDate, setEndDate] = useState(null); const [reportingDate, setReportingDate] = useState(null); const [scope, setScope] = useState([]); const changeScope = (value: string) => { setScope(value.split('\n')); }; const [loading, setLoading] = useState(true); useEffect(() => { const fetchData = async () => { try { const dataLanguages = await getLanguages(); const languageNames = dataLanguages.datas.map( (item: Language, index: number): ListItem => ({ id: index, value: item.locale, label: item.language, }), ); setLanguageOptions(languageNames); setLoadingLanguages(false); const dataTemplates = await getTemplates(); setTemplates(dataTemplates.datas); const templateNames = dataTemplates.datas.map( (item: Template, index: number): ListItem => ({ id: index, value: item.name, label: item.name, }), ); setTemplateOptions(templateNames); setLoadingTemplates(false); const dataCompanies = await getCompanies(); setCompanies(dataCompanies.datas); const companyNames = dataCompanies.datas.map( (item: Company, index: number): ListItem => ({ id: index, value: item._id, label: item.name, }), ); setCompanyOptions(companyNames.length > 0 ? companyNames : []); setLoadingCompanies(false); const dataClients = await getClients(); setClients(dataClients.datas); const clientNames = dataClients.datas.map( (item: Client, index: number): ListItem => ({ id: index, value: item._id, label: item.email, }), ); setClientOptions(clientNames.length > 0 ? clientNames : []); setLoadingClients(false); const dataCollaborators = await getCollaborators(); setCollaborators(dataCollaborators.datas); const collaboratorNames = dataCollaborators.datas.map( (item: Collaborator, index: number): ListItem => ({ id: index, value: `${item._id}`, label: `${item.firstname} ${item.lastname}`, }), ); setCollaboratorOptions(collaboratorNames); setLoadingCollaborators(false); setLoadingCollaborators(false); setLoading(false); } catch (err) { setLoading(false); } }; fetchData().catch(console.error); }, []); useEffect(() => { if (currentCompany) { setClientOptions( clients .filter(client => client.company.name === currentCompany.label) .map( (client: Client, index: number): ListItem => ({ id: index, value: client._id, label: client.email, }), ), ); } else { getClients() .then(res => { setClients(res.datas); }) .catch(console.error); } // Se deshabilita porque no se debe volver a ejecutar cuando se actualizan los clientes, a fin de no crear un loop // eslint-disable-next-line react-hooks/exhaustive-deps }, [currentCompany]); useEffect(() => { if (currentClient && !currentCompany) { setCurrentCompany( companyOptions.find( company => company.label === clients.filter(client => client._id === currentClient.value)[0] .company.name, ) ?? null, ); } }, [clients, companyOptions, currentClient, currentCompany]); useEffect(() => { const fetchAuditData = async () => { if (!auditId) { return; } try { const dataAudit = await getAuditById(auditId); setDataAudit(dataAudit.datas); setNameAudit(dataAudit.datas.name); setAuditType(dataAudit.datas.auditType); const selectedLanguage = languageOptions.find( item => item.value === dataAudit.datas.language, ) ?? null; setCurrentLanguage(selectedLanguage); if (!('template' in dataAudit.datas)) { setCurrentTemplate(null); } else { const selectedTemplate = templateOptions.find( item => item.value === dataAudit.datas.template.name, ) ?? null; setCurrentTemplate(selectedTemplate ?? null); } const selectedCompany = companyOptions.find( item => item.value === dataAudit.datas.company?._id, ); setCurrentCompany(selectedCompany ?? null); const selectedClient = clientOptions.find( item => item.value === dataAudit.datas.client?._id, ); setCurrentClient(selectedClient ?? null); const selectedCollaborators = dataAudit.datas.collaborators.map( (item: Collaborator, index: number): ListItem => ({ id: index, value: item._id, label: `${item.firstname} ${item.lastname}`, }), ); setCurrentCollaborators(selectedCollaborators); setStartDate(dayjs(dataAudit.datas.date_start)); setEndDate(dayjs(dataAudit.datas.date_end)); setReportingDate(dayjs(dataAudit.datas.date)); setScope(dataAudit.datas.scope.map(item => item.name)); } catch (error) { console.error('Error fetching audit data:', error); } }; if ( auditId && languageOptions.length > 0 && templateOptions.length > 0 && collaboratorOptions.length > 0 ) { fetchAuditData().catch(console.error); } // Se deshabilita porque no se debe volver a ejecutar cuando se actualizan las opciones, debido a filtrado por compañía de cliente // eslint-disable-next-line react-hooks/exhaustive-deps }, [auditId, collaboratorOptions]); const getClientData = () => { if (!currentClient) { return undefined; } const clientData = clients.find( client => client._id === currentClient.value, ); return clientData ? { _id: clientData._id, company: { _id: currentCompany?.value ?? '', name: clientData.company.name, }, email: clientData.email, firstname: clientData.firstname, lastname: clientData.lastname, } : { _id: '', company: { _id: '', name: '' }, email: '', firstname: '', lastname: '', }; }; const getCollaboratorsData = () => { return collaborators .filter(collaborator => currentCollaborators.some(item => item.value === collaborator._id), ) .map(collaborator => ({ _id: collaborator._id, firstname: collaborator.firstname, lastname: collaborator.lastname, username: collaborator.username, })); }; const getCompanyData = () => { const companyData = companies.find( company => company._id === currentCompany?.value, ); return companyData ? { __v: 0, _id: companyData._id, createdAt: dataAudit?.company?.createdAt ?? '', name: companyData.name, shortName: companyData.shortName, updatedAt: dataAudit?.company?.updatedAt ?? '', } : { __v: 0, _id: '', name: '', shortName: '', createdAt: '', updatedAt: '', }; }; const handleSaveButton = async () => { if (!auditId) { console.error('No audit ID available'); return; } const updatedAudit: UpdateAudit = { _id: auditId, auditType, name: nameAudit, language: currentLanguage?.value ?? '', client: getClientData(), collaborators: getCollaboratorsData(), company: getCompanyData(), creator: { _id: dataAudit?.creator._id ?? '', firstname: dataAudit?.creator.firstname ?? '', lastname: dataAudit?.creator.lastname ?? '', username: dataAudit?.creator.username ?? '', }, customFields: [], date: reportingDate ? reportingDate.toISOString() : '', date_end: endDate ? endDate.toISOString() : '', date_start: startDate ? startDate.toISOString() : '', reviewers: [], scope, template: templates.find(template => template.name === currentTemplate?.value) ?._id ?? '', }; try { await updateAudit(auditId, updatedAudit); toast.success(t('msg.auditUpdatedOk')); } catch (error) { toast.error(t('err.failedUpdateAudit')); } }; return ( {loading ? (
) : ( <>
{!loadingLanguages ? ( ) : null}
{!loadingTemplates ? ( ) : null}
{!loadingCompanies ? ( ) : null}
{!loadingClients ? ( ) : null}
{!loadingCollaborators ? ( ) : null}