feat: Début de suppression de docuseal côté Front [#N3WTS-17]

This commit is contained in:
N3WT DE COMPET
2025-11-29 12:20:14 +01:00
parent 0fb668b212
commit 1e5bc6ccba
19 changed files with 129 additions and 512 deletions

View File

@ -42,14 +42,9 @@ const nextConfig = {
NEXT_PUBLIC_USE_FAKE_DATA: process.env.NEXT_PUBLIC_USE_FAKE_DATA || 'false', NEXT_PUBLIC_USE_FAKE_DATA: process.env.NEXT_PUBLIC_USE_FAKE_DATA || 'false',
AUTH_SECRET: process.env.AUTH_SECRET || 'false', AUTH_SECRET: process.env.AUTH_SECRET || 'false',
NEXTAUTH_URL: process.env.NEXTAUTH_URL || 'http://localhost:3000', NEXTAUTH_URL: process.env.NEXTAUTH_URL || 'http://localhost:3000',
DOCUSEAL_API_KEY: process.env.DOCUSEAL_API_KEY,
}, },
async rewrites() { async rewrites() {
return [ return [
{
source: '/api/documents/:path*',
destination: 'https://api.docuseal.com/v1/documents/:path*',
},
{ {
source: '/api/auth/:path*', source: '/api/auth/:path*',
destination: '/api/auth/:path*', // Exclure les routes NextAuth des réécritures de proxy destination: '/api/auth/:path*', // Exclure les routes NextAuth des réécritures de proxy

View File

@ -8,7 +8,6 @@
"name": "n3wt-school-front-end", "name": "n3wt-school-front-end",
"version": "0.0.3", "version": "0.0.3",
"dependencies": { "dependencies": {
"@docuseal/react": "^1.0.56",
"@radix-ui/react-dialog": "^1.1.2", "@radix-ui/react-dialog": "^1.1.2",
"@tailwindcss/forms": "^0.5.9", "@tailwindcss/forms": "^0.5.9",
"date-fns": "^4.1.0", "date-fns": "^4.1.0",
@ -537,11 +536,6 @@
"integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
"dev": true "dev": true
}, },
"node_modules/@docuseal/react": {
"version": "1.0.66",
"resolved": "https://registry.npmjs.org/@docuseal/react/-/react-1.0.66.tgz",
"integrity": "sha512-rYG58gv8Uw1cTtjbHdgWgWBWpLMbIwDVsS3kN27w4sz/eDJilZieePUDS4eLKJ8keBN05BSjxD/iWQpaTBKZLg=="
},
"node_modules/@eslint-community/eslint-utils": { "node_modules/@eslint-community/eslint-utils": {
"version": "4.7.0", "version": "4.7.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz",
@ -11269,11 +11263,6 @@
"integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
"dev": true "dev": true
}, },
"@docuseal/react": {
"version": "1.0.66",
"resolved": "https://registry.npmjs.org/@docuseal/react/-/react-1.0.66.tgz",
"integrity": "sha512-rYG58gv8Uw1cTtjbHdgWgWBWpLMbIwDVsS3kN27w4sz/eDJilZieePUDS4eLKJ8keBN05BSjxD/iWQpaTBKZLg=="
},
"@eslint-community/eslint-utils": { "@eslint-community/eslint-utils": {
"version": "4.7.0", "version": "4.7.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz",

View File

@ -14,7 +14,6 @@
"test:coverage": "jest --coverage" "test:coverage": "jest --coverage"
}, },
"dependencies": { "dependencies": {
"@docuseal/react": "^1.0.56",
"@radix-ui/react-dialog": "^1.1.2", "@radix-ui/react-dialog": "^1.1.2",
"@tailwindcss/forms": "^0.5.9", "@tailwindcss/forms": "^0.5.9",
"date-fns": "^4.1.0", "date-fns": "^4.1.0",

View File

@ -36,7 +36,6 @@ export default function DashboardPage() {
const { const {
selectedEstablishmentId, selectedEstablishmentId,
selectedEstablishmentTotalCapacity, selectedEstablishmentTotalCapacity,
apiDocuseal,
} = useEstablishment(); } = useEstablishment();
const [statusDistribution, setStatusDistribution] = useState([ const [statusDistribution, setStatusDistribution] = useState([
@ -165,25 +164,6 @@ export default function DashboardPage() {
return ( return (
<div key={selectedEstablishmentId} className="p-6"> <div key={selectedEstablishmentId} className="p-6">
<div className="flex items-center gap-3 mb-6">
<span
className={`inline-flex items-center px-3 py-1 rounded-full text-sm font-semibold ${
apiDocuseal
? 'bg-green-100 text-green-700 border border-green-300'
: 'bg-red-100 text-red-700 border border-red-300'
}`}
>
{apiDocuseal ? (
<CheckCircle2 className="w-4 h-4 mr-2 text-green-500" />
) : (
<AlertTriangle className="w-4 h-4 mr-2 text-red-500" />
)}
{apiDocuseal
? 'Clé API Docuseal renseignée'
: 'Clé API Docuseal manquante'}
</span>
</div>
{/* Statistiques principales */} {/* Statistiques principales */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-6"> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-6">
<StatCard <StatCard

View File

@ -52,7 +52,7 @@ export default function Page() {
); );
const csrfToken = useCsrfToken(); const csrfToken = useCsrfToken();
const { selectedEstablishmentId, apiDocuseal } = useEstablishment(); const { selectedEstablishmentId } = useEstablishment();
useEffect(() => { useEffect(() => {
if (selectedEstablishmentId) { if (selectedEstablishmentId) {
@ -353,7 +353,6 @@ export default function Page() {
<FilesGroupsManagement <FilesGroupsManagement
csrfToken={csrfToken} csrfToken={csrfToken}
selectedEstablishmentId={selectedEstablishmentId} selectedEstablishmentId={selectedEstablishmentId}
apiDocuseal={apiDocuseal}
/> />
</div> </div>
), ),

View File

@ -35,7 +35,6 @@ import {
fetchRegistrationFileGroups, fetchRegistrationFileGroups,
fetchRegistrationSchoolFileMasters, fetchRegistrationSchoolFileMasters,
fetchRegistrationParentFileMasters, fetchRegistrationParentFileMasters,
cloneTemplate,
createRegistrationSchoolFileTemplate, createRegistrationSchoolFileTemplate,
createRegistrationParentFileTemplate, createRegistrationParentFileTemplate,
} from '@/app/actions/registerFileGroupAction'; } from '@/app/actions/registerFileGroupAction';
@ -96,7 +95,7 @@ export default function CreateSubscriptionPage() {
const { getNiveauLabel } = useClasses(); const { getNiveauLabel } = useClasses();
const formDataRef = useRef(formData); const formDataRef = useRef(formData);
const { selectedEstablishmentId, apiDocuseal } = useEstablishment(); const { selectedEstablishmentId } = useEstablishment();
const csrfToken = useCsrfToken(); const csrfToken = useCsrfToken();
const router = useRouter(); const router = useRouter();
@ -530,16 +529,28 @@ export default function CreateSubscriptionPage() {
const parentMasters = parentFileMasters.filter((file) => const parentMasters = parentFileMasters.filter((file) =>
file.groups.includes(selectedFileGroup) file.groups.includes(selectedFileGroup)
); );
createRegistrationSchoolFileTemplate(
const clonePromises = masters.map((templateMaster) => cloneData,
cloneTemplate( csrfToken
templateMaster.id,
formDataRef.current.guardianEmail,
templateMaster.is_required,
selectedEstablishmentId,
apiDocuseal
) )
.then((clonedDocument) => { .then((response) =>
logger.debug('Template enregistré avec succès:', response)
)
.catch((error) => {
setIsLoading(false);
logger.error(
"Erreur lors de l'enregistrement du template:",
error
);
showNotification(
"Erreur lors de la création du dossier d'inscription",
'error',
'Erreur',
'ERR_ADM_SUB_03'
);
});
const clonePromises = masters.map((templateMaster) => {
const cloneData = { const cloneData = {
name: `${templateMaster.name}_${formDataRef.current.studentFirstName}_${formDataRef.current.studentLastName}`, name: `${templateMaster.name}_${formDataRef.current.studentFirstName}_${formDataRef.current.studentLastName}`,
slug: clonedDocument.slug, slug: clonedDocument.slug,
@ -568,18 +579,7 @@ export default function CreateSubscriptionPage() {
'ERR_ADM_SUB_03' 'ERR_ADM_SUB_03'
); );
}); });
}) });
.catch((error) => {
setIsLoading(false);
logger.error('Error during cloning or sending:', error);
showNotification(
"Erreur lors de la création du dossier d'inscription",
'error',
'Erreur',
'ERR_ADM_SUB_05'
);
})
);
// Clonage des parentFileTemplates // Clonage des parentFileTemplates
const parentClonePromises = parentMasters.map((parentMaster) => { const parentClonePromises = parentMasters.map((parentMaster) => {

View File

@ -19,7 +19,7 @@ export default function Page() {
const [formErrors, setFormErrors] = useState({}); const [formErrors, setFormErrors] = useState({});
const csrfToken = useCsrfToken(); const csrfToken = useCsrfToken();
const { selectedEstablishmentId, apiDocuseal } = useEstablishment(); const { selectedEstablishmentId } = useEstablishment();
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const handleSubmit = (data) => { const handleSubmit = (data) => {
@ -59,7 +59,6 @@ export default function Page() {
studentId={studentId} studentId={studentId}
csrfToken={csrfToken} csrfToken={csrfToken}
selectedEstablishmentId={selectedEstablishmentId} selectedEstablishmentId={selectedEstablishmentId}
apiDocuseal = {apiDocuseal}
onSubmit={handleSubmit} onSubmit={handleSubmit}
cancelUrl={FE_ADMIN_SUBSCRIPTIONS_URL} cancelUrl={FE_ADMIN_SUBSCRIPTIONS_URL}
errors={formErrors} errors={formErrors}

View File

@ -17,7 +17,7 @@ export default function Page() {
const enable = searchParams.get('enabled') === 'true'; const enable = searchParams.get('enabled') === 'true';
const router = useRouter(); const router = useRouter();
const csrfToken = useCsrfToken(); const csrfToken = useCsrfToken();
const { selectedEstablishmentId, apiDocuseal } = useEstablishment(); const { selectedEstablishmentId } = useEstablishment();
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const handleSubmit = (data) => { const handleSubmit = (data) => {
@ -53,7 +53,6 @@ export default function Page() {
studentId={studentId} studentId={studentId}
csrfToken={csrfToken} csrfToken={csrfToken}
selectedEstablishmentId={selectedEstablishmentId} selectedEstablishmentId={selectedEstablishmentId}
apiDocuseal = {apiDocuseal}
onSubmit={handleSubmit} onSubmit={handleSubmit}
cancelUrl={FE_PARENTS_HOME_URL} cancelUrl={FE_PARENTS_HOME_URL}
enable={enable} enable={enable}

View File

@ -3,11 +3,7 @@ import {
BE_SUBSCRIPTION_REGISTRATION_SCHOOL_FILE_TEMPLATES_URL, BE_SUBSCRIPTION_REGISTRATION_SCHOOL_FILE_TEMPLATES_URL,
BE_SUBSCRIPTION_REGISTRATION_SCHOOL_FILE_MASTERS_URL, BE_SUBSCRIPTION_REGISTRATION_SCHOOL_FILE_MASTERS_URL,
BE_SUBSCRIPTION_REGISTRATION_PARENT_FILE_MASTERS_URL, BE_SUBSCRIPTION_REGISTRATION_PARENT_FILE_MASTERS_URL,
BE_SUBSCRIPTION_REGISTRATION_PARENT_FILE_TEMPLATES_URL, BE_SUBSCRIPTION_REGISTRATION_PARENT_FILE_TEMPLATES_URL
FE_API_DOCUSEAL_CLONE_URL,
FE_API_DOCUSEAL_DOWNLOAD_URL,
FE_API_DOCUSEAL_GENERATE_TOKEN,
FE_API_DOCUSEAL_DELETE_URL
} from '@/utils/Url'; } from '@/utils/Url';
import { errorHandler, requestResponseHandler } from './actionsHandlers'; import { errorHandler, requestResponseHandler } from './actionsHandlers';
@ -327,62 +323,3 @@ export const deleteRegistrationParentFileTemplate = (id, csrfToken) => {
} }
); );
}; };
// API requests
export const removeTemplate = (templateId, selectedEstablishmentId, apiDocuseal) => {
return fetch(`${FE_API_DOCUSEAL_DELETE_URL}`, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
templateId,
establishment_id :selectedEstablishmentId,
apiDocuseal
}),
})
.then(requestResponseHandler)
.catch(errorHandler);
};
export const cloneTemplate = (templateId, email, is_required, selectedEstablishmentId, apiDocuseal) => {
return fetch(`${FE_API_DOCUSEAL_CLONE_URL}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
templateId,
email,
is_required,
establishment_id :selectedEstablishmentId,
apiDocuseal
}),
})
.then(requestResponseHandler)
.catch(errorHandler);
};
export const downloadTemplate = (slug, selectedEstablishmentId, apiDocuseal) => {
const url = `${FE_API_DOCUSEAL_DOWNLOAD_URL}/${slug}?establishment_id=${selectedEstablishmentId}&apiDocuseal=${apiDocuseal}`;
return fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
})
.then(requestResponseHandler)
.catch(errorHandler);
};
export const generateToken = (email, id = null, selectedEstablishmentId, apiDocuseal) => {
return fetch(`${FE_API_DOCUSEAL_GENERATE_TOKEN}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ user_email: email, id, establishment_id :selectedEstablishmentId, apiDocuseal }),
})
.then(requestResponseHandler)
.catch(errorHandler);
};

View File

@ -24,8 +24,7 @@ const ProfileSelector = ({ onRoleChange, className = '' }) => {
setSelectedEstablishmentEvaluationFrequency, setSelectedEstablishmentEvaluationFrequency,
setSelectedEstablishmentTotalCapacity, setSelectedEstablishmentTotalCapacity,
selectedEstablishmentLogo, selectedEstablishmentLogo,
setSelectedEstablishmentLogo, setSelectedEstablishmentLogo
setApiDocuseal
} = useEstablishment(); } = useEstablishment();
const { isConnected, connectionStatus } = useChatConnection(); const { isConnected, connectionStatus } = useChatConnection();
const [dropdownOpen, setDropdownOpen] = useState(false); const [dropdownOpen, setDropdownOpen] = useState(false);
@ -41,8 +40,6 @@ const ProfileSelector = ({ onRoleChange, className = '' }) => {
user.roles[roleId].establishment__total_capacity; user.roles[roleId].establishment__total_capacity;
const establishmentLogo = const establishmentLogo =
user.roles[roleId].establishment__logo; user.roles[roleId].establishment__logo;
const establishmentApiDocuseal =
user.roles[roleId].establishment__api_docuseal;
setProfileRole(role); setProfileRole(role);
setSelectedEstablishmentId(establishmentId); setSelectedEstablishmentId(establishmentId);
setSelectedEstablishmentEvaluationFrequency( setSelectedEstablishmentEvaluationFrequency(
@ -50,7 +47,6 @@ const ProfileSelector = ({ onRoleChange, className = '' }) => {
); );
setSelectedEstablishmentTotalCapacity(establishmentTotalCapacity); setSelectedEstablishmentTotalCapacity(establishmentTotalCapacity);
setSelectedEstablishmentLogo(establishmentLogo); setSelectedEstablishmentLogo(establishmentLogo);
setApiDocuseal(establishmentApiDocuseal);
setSelectedRoleId(roleId); setSelectedRoleId(roleId);
if (onRoleChange) { if (onRoleChange) {
onRoleChange(roleId); onRoleChange(roleId);

View File

@ -2,10 +2,7 @@ import React, { useState, useEffect } from 'react';
import { import {
fetchRegistrationFileGroups, fetchRegistrationFileGroups,
createRegistrationSchoolFileTemplate, createRegistrationSchoolFileTemplate,
cloneTemplate,
generateToken,
} from '@/app/actions/registerFileGroupAction'; } from '@/app/actions/registerFileGroupAction';
import { DocusealBuilder } from '@docuseal/react';
import logger from '@/utils/logger'; import logger from '@/utils/logger';
import MultiSelect from '@/components/Form/MultiSelect'; // Import du composant MultiSelect import MultiSelect from '@/components/Form/MultiSelect'; // Import du composant MultiSelect
import { useCsrfToken } from '@/context/CsrfContext'; import { useCsrfToken } from '@/context/CsrfContext';
@ -19,7 +16,6 @@ export default function FileUploadDocuSeal({
onSuccess, onSuccess,
}) { }) {
const [groups, setGroups] = useState([]); const [groups, setGroups] = useState([]);
const [token, setToken] = useState(null);
const [templateMaster, setTemplateMaster] = useState(null); const [templateMaster, setTemplateMaster] = useState(null);
const [uploadedFileName, setUploadedFileName] = useState(''); const [uploadedFileName, setUploadedFileName] = useState('');
const [selectedGroups, setSelectedGroups] = useState([]); const [selectedGroups, setSelectedGroups] = useState([]);
@ -30,7 +26,7 @@ export default function FileUploadDocuSeal({
const csrfToken = useCsrfToken(); const csrfToken = useCsrfToken();
const { selectedEstablishmentId, user, apiDocuseal } = useEstablishment(); const { selectedEstablishmentId, user } = useEstablishment();
useEffect(() => { useEffect(() => {
fetchRegistrationFileGroups(selectedEstablishmentId).then((data) => fetchRegistrationFileGroups(selectedEstablishmentId).then((data) =>
@ -47,15 +43,6 @@ export default function FileUploadDocuSeal({
if (!user && !user?.email) { if (!user && !user?.email) {
return; return;
} }
const id = fileToEdit ? fileToEdit.id : null;
generateToken(user?.email, id, selectedEstablishmentId, apiDocuseal)
.then((data) => {
setToken(data.token);
})
.catch((error) =>
logger.error('Erreur lors de la génération du token:', error)
);
}, [fileToEdit]); }, [fileToEdit]);
const handleGroupChange = (selectedGroups) => { const handleGroupChange = (selectedGroups) => {
@ -121,15 +108,6 @@ export default function FileUploadDocuSeal({
guardianDetails.forEach((guardian, index) => { guardianDetails.forEach((guardian, index) => {
logger.debug('creation du clone avec required : ', is_required); logger.debug('creation du clone avec required : ', is_required);
cloneTemplate(
templateMaster?.id,
guardian.email,
is_required,
selectedEstablishmentId,
apiDocuseal
)
.then((clonedDocument) => {
// Sauvegarde des schoolFileTemplates clonés dans la base de données
const data = { const data = {
name: `${uploadedFileName}_${guardian.first_name}_${guardian.last_name}`, name: `${uploadedFileName}_${guardian.first_name}_${guardian.last_name}`,
slug: clonedDocument.slug, slug: clonedDocument.slug,
@ -149,13 +127,6 @@ export default function FileUploadDocuSeal({
error error
); );
}); });
// Logique pour envoyer chaque template au submitter
logger.debug('Sending template to:', guardian.email);
})
.catch((error) => {
logger.error('Error during cloning or sending:', error);
});
}); });
} }
}; };
@ -212,32 +183,7 @@ export default function FileUploadDocuSeal({
{/* Zone de configuration des documents */} {/* Zone de configuration des documents */}
<div className="col-span-8 bg-white p-6 rounded-lg shadow-md border border-gray-200"> <div className="col-span-8 bg-white p-6 rounded-lg shadow-md border border-gray-200">
{token && (
<div className="h-full overflow-auto">
{/* Description de l'étape */}
<p className="text-gray-700 text-base font-medium mb-4">
Étape 2 - Sélectionnez un document
</p>
<DocusealBuilder
token={token}
headers={{
Authorization: `Bearer ${token}`,
}}
withSendButton={false}
withSignYourselfButton={false}
autosave={false}
withDocumentsList={false}
language={'fr'}
onLoad={handleLoad}
onUpload={handleUpload}
onChange={handleChange}
onSave={handleSubmit}
className="h-full overflow-auto"
style={{ maxHeight: '65vh' }}
/>
</div>
)}
</div> </div>
</div> </div>
)} )}

View File

@ -2,7 +2,6 @@ import React, { useState, useEffect } from 'react';
import { Download, Edit3, Trash2, FolderPlus, Signature, AlertTriangle } from 'lucide-react'; import { Download, Edit3, Trash2, FolderPlus, Signature, AlertTriangle } from 'lucide-react';
import Modal from '@/components/Modal'; import Modal from '@/components/Modal';
import Table from '@/components/Table'; import Table from '@/components/Table';
import FileUploadDocuSeal from '@/components/Structure/Files/FileUploadDocuSeal';
import { BASE_URL } from '@/utils/Url'; import { BASE_URL } from '@/utils/Url';
import { import {
// GET // GET
@ -33,11 +32,11 @@ import Popup from '@/components/Popup';
import Loader from '@/components/Loader'; import Loader from '@/components/Loader';
import { useNotification } from '@/context/NotificationContext'; import { useNotification } from '@/context/NotificationContext';
import AlertMessage from '@/components/AlertMessage'; import AlertMessage from '@/components/AlertMessage';
import FileUploadDocuSeal from '@/components/Structure/Files/FileUploadDocuSeal';
export default function FilesGroupsManagement({ export default function FilesGroupsManagement({
csrfToken, csrfToken,
selectedEstablishmentId, selectedEstablishmentId
apiDocuseal
}) { }) {
const [schoolFileMasters, setSchoolFileMasters] = useState([]); const [schoolFileMasters, setSchoolFileMasters] = useState([]);
const [schoolFileTemplates, setSchoolFileTemplates] = useState([]); const [schoolFileTemplates, setSchoolFileTemplates] = useState([]);
@ -116,23 +115,6 @@ export default function FilesGroupsManagement({
); );
setRemovePopupOnConfirm(() => () => { setRemovePopupOnConfirm(() => () => {
setIsLoading(true); setIsLoading(true);
// Supprimer les clones associés via l'API DocuSeal
const removeClonesPromises = [
...schoolFileTemplates
.filter((template) => template.master === templateMaster.id)
.map((template) =>
removeTemplate(template.id, selectedEstablishmentId, apiDocuseal)
),
removeTemplate(templateMaster.id, selectedEstablishmentId, apiDocuseal),
];
// Attendre que toutes les suppressions dans DocuSeal soient terminées
Promise.all(removeClonesPromises)
.then((responses) => {
const allSuccessful = responses.every((response) => response && response.id);
if (allSuccessful) {
logger.debug('Master et clones supprimés avec succès de DocuSeal.');
// Supprimer le template master de la base de données // Supprimer le template master de la base de données
deleteRegistrationSchoolFileMaster(templateMaster.id, csrfToken) deleteRegistrationSchoolFileMaster(templateMaster.id, csrfToken)
.then((response) => { .then((response) => {
@ -170,26 +152,6 @@ export default function FilesGroupsManagement({
setRemovePopupVisible(false); setRemovePopupVisible(false);
setIsLoading(false); setIsLoading(false);
}); });
} else {
showNotification(
`Erreur lors de la suppression du document "${templateMaster.name}".`,
'error',
'Erreur'
);
setRemovePopupVisible(false);
setIsLoading(false);
}
})
.catch((error) => {
logger.error('Error removing template from DocuSeal:', error);
showNotification(
`Erreur lors de la suppression du document "${templateMaster.name}".`,
'error',
'Erreur'
);
setRemovePopupVisible(false);
setIsLoading(false);
});
}); });
}; };
@ -542,25 +504,13 @@ export default function FilesGroupsManagement({
icon={Signature} icon={Signature}
title="Formulaires à remplir" title="Formulaires à remplir"
description="Gérez les formulaires nécessitant une signature électronique." description="Gérez les formulaires nécessitant une signature électronique."
button={apiDocuseal} button={true}
buttonOpeningModal={true} buttonOpeningModal={true}
onClick={() => { onClick={() => {
setIsModalOpen(true); setIsModalOpen(true);
setIsEditing(false); setIsEditing(false);
}} }}
/> />
<div className="mb-4">
<span
className={`inline-flex items-center px-3 py-1 rounded-full text-sm font-semibold ${
!apiDocuseal && 'bg-red-100 text-red-700 border border-red-300'
}`}
>
{!apiDocuseal && (
<AlertTriangle className="w-4 h-4 mr-2 text-red-500" />
)}
{!apiDocuseal && 'Clé API Docuseal manquante'}
</span>
</div>
<Table <Table
data={filteredFiles} data={filteredFiles}
columns={columnsFiles} columns={columnsFiles}

View File

@ -46,10 +46,6 @@ export const EstablishmentProvider = ({ children }) => {
const storedUser = sessionStorage.getItem('user'); const storedUser = sessionStorage.getItem('user');
return storedUser ? JSON.parse(storedUser) : null; return storedUser ? JSON.parse(storedUser) : null;
}); });
const [apiDocuseal, setApiDocusealState] = useState(() => {
const storedApiDocuseal = sessionStorage.getItem('apiDocuseal');
return storedApiDocuseal ? JSON.parse(storedApiDocuseal) : null;
});
const [selectedEstablishmentLogo, setSelectedEstablishmentLogoState] = useState(() => { const [selectedEstablishmentLogo, setSelectedEstablishmentLogoState] = useState(() => {
const storedLogo = sessionStorage.getItem('selectedEstablishmentLogo'); const storedLogo = sessionStorage.getItem('selectedEstablishmentLogo');
return storedLogo ? JSON.parse(storedLogo) : null; return storedLogo ? JSON.parse(storedLogo) : null;
@ -94,11 +90,6 @@ export const EstablishmentProvider = ({ children }) => {
sessionStorage.setItem('user', JSON.stringify(user)); sessionStorage.setItem('user', JSON.stringify(user));
}; };
const setApiDocuseal = (api) => {
setApiDocusealState(api);
sessionStorage.setItem('apiDocuseal', JSON.stringify(api));
};
const setSelectedEstablishmentLogo = (logo) => { const setSelectedEstablishmentLogo = (logo) => {
setSelectedEstablishmentLogoState(logo); setSelectedEstablishmentLogoState(logo);
sessionStorage.setItem('selectedEstablishmentLogo', JSON.stringify(logo)); sessionStorage.setItem('selectedEstablishmentLogo', JSON.stringify(logo));
@ -122,7 +113,6 @@ export const EstablishmentProvider = ({ children }) => {
name: role.establishment__name, name: role.establishment__name,
evaluation_frequency: role.establishment__evaluation_frequency, evaluation_frequency: role.establishment__evaluation_frequency,
total_capacity: role.establishment__total_capacity, total_capacity: role.establishment__total_capacity,
api_docuseal: role.establishment__api_docuseal,
logo: role.establishment__logo, logo: role.establishment__logo,
role_id: i, role_id: i,
role_type: role.role_type, role_type: role.role_type,
@ -143,9 +133,6 @@ export const EstablishmentProvider = ({ children }) => {
setSelectedEstablishmentTotalCapacity( setSelectedEstablishmentTotalCapacity(
userEstablishments[roleIndexDefault].total_capacity userEstablishments[roleIndexDefault].total_capacity
); );
setApiDocuseal(
userEstablishments[roleIndexDefault].api_docuseal
);
setSelectedEstablishmentLogo( setSelectedEstablishmentLogo(
userEstablishments[roleIndexDefault].logo userEstablishments[roleIndexDefault].logo
); );
@ -168,7 +155,6 @@ export const EstablishmentProvider = ({ children }) => {
setUserState(null); setUserState(null);
setSelectedEstablishmentEvaluationFrequencyState(null); setSelectedEstablishmentEvaluationFrequencyState(null);
setSelectedEstablishmentTotalCapacityState(null); setSelectedEstablishmentTotalCapacityState(null);
setApiDocusealState(null);
setSelectedEstablishmentLogoState(null); setSelectedEstablishmentLogoState(null);
sessionStorage.clear(); sessionStorage.clear();
}; };
@ -184,8 +170,6 @@ export const EstablishmentProvider = ({ children }) => {
setSelectedEstablishmentEvaluationFrequency, setSelectedEstablishmentEvaluationFrequency,
selectedEstablishmentTotalCapacity, selectedEstablishmentTotalCapacity,
setSelectedEstablishmentTotalCapacity, setSelectedEstablishmentTotalCapacity,
apiDocuseal,
setApiDocuseal,
selectedEstablishmentLogo, selectedEstablishmentLogo,
setSelectedEstablishmentLogo, setSelectedEstablishmentLogo,
selectedRoleId, selectedRoleId,

View File

@ -1,41 +0,0 @@
import logger from '@/utils/logger';
import { BE_DOCUSEAL_CLONE_TEMPLATE } from '@/utils/Url';
export default function handler(req, res) {
if (req.method === 'POST') {
const { templateId, email, is_required, establishment_id, apiDocuseal } = req.body;
fetch(BE_DOCUSEAL_CLONE_TEMPLATE, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Auth-Token': apiDocuseal,
},
body: JSON.stringify({
templateId,
email,
is_required,
establishment_id,
}),
})
.then((response) => {
if (!response.ok) {
return response.json().then((err) => {
throw new Error(err.message);
});
}
return response.json();
})
.then((data) => {
logger.debug('Template cloned successfully:', data);
res.status(200).json(data);
})
.catch((error) => {
logger.error('Error cloning template:', error);
res.status(500).json({ error: 'Internal Server Error' });
});
} else {
res.setHeader('Allow', ['POST']);
res.status(405).end(`Method ${req.method} Not Allowed`);
}
}

View File

@ -1,35 +0,0 @@
import logger from '@/utils/logger';
import { BE_DOCUSEAL_DOWNLOAD_TEMPLATE } from '@/utils/Url';
export default function handler(req, res) {
if (req.method === 'GET') {
const { slug, establishment_id, apiDocuseal } = req.query;
logger.debug('slug : ', slug);
fetch(`${BE_DOCUSEAL_DOWNLOAD_TEMPLATE}/${slug}?establishment_id=${establishment_id}`, {
method: 'GET',
headers: {
'X-Auth-Token': apiDocuseal,
},
})
.then((response) => {
if (!response.ok) {
return response.json().then((err) => {
throw new Error(err.message);
});
}
return response.json();
})
.then((data) => {
logger.debug('Template downloaded successfully:', data);
res.status(200).json(data);
})
.catch((error) => {
logger.error('Error downloading template:', error);
res.status(500).json({ error: 'Internal Server Error' });
});
} else {
res.setHeader('Allow', ['GET']);
res.status(405).end(`Method ${req.method} Not Allowed`);
}
}

View File

@ -1,34 +0,0 @@
import logger from '@/utils/logger';
import { BE_DOCUSEAL_GET_JWT } from '@/utils/Url';
export default function handler(req, res) {
if (req.method === 'POST') {
const { apiDocuseal, ...rest } = req.body;
fetch(BE_DOCUSEAL_GET_JWT, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Auth-Token': apiDocuseal,
},
body: JSON.stringify(rest),
})
.then((response) => {
logger.debug('Response status:', response.status);
return response
.json()
.then((data) => ({ status: response.status, data }));
})
.then(({ status, data }) => {
logger.debug('Response data:', data);
res.status(status).json(data);
})
.catch((error) => {
logger.error('Error:', error);
res.status(500).json({ error: 'Internal Server Error' });
});
} else {
res.setHeader('Allow', ['POST']);
res.status(405).end(`Method ${req.method} Not Allowed`);
}
}

View File

@ -1,34 +0,0 @@
import logger from '@/utils/logger';
import { BE_DOCUSEAL_REMOVE_TEMPLATE } from '@/utils/Url';
export default function handler(req, res) {
if (req.method === 'DELETE') {
const { templateId, establishment_id, apiDocuseal } = req.body;
fetch(`${BE_DOCUSEAL_REMOVE_TEMPLATE}/${templateId}?establishment_id=${establishment_id}`, {
method: 'DELETE',
headers: {
'X-Auth-Token': apiDocuseal,
},
})
.then((response) => {
if (!response.ok) {
return response.json().then((err) => {
throw new Error(err.message);
});
}
return response.json();
})
.then((data) => {
logger.debug('Template removed successfully:', data);
res.status(200).json(data);
})
.catch((error) => {
logger.error('Error removing template:', error);
res.status(500).json({ error: 'Internal Server Error' });
});
} else {
res.setHeader('Allow', ['DELETE']);
res.status(405).end(`Method ${req.method} Not Allowed`);
}
}

View File

@ -4,12 +4,6 @@ export const WS_BASE_URL = process.env.NEXT_PUBLIC_WSAPI_URL;
//URL-Back-End //URL-Back-End
// GESTION DocuSeal
export const BE_DOCUSEAL_GET_JWT = `${BASE_URL}/DocuSeal/generateToken`;
export const BE_DOCUSEAL_CLONE_TEMPLATE = `${BASE_URL}/DocuSeal/cloneTemplate`;
export const BE_DOCUSEAL_REMOVE_TEMPLATE = `${BASE_URL}/DocuSeal/removeTemplate`;
export const BE_DOCUSEAL_DOWNLOAD_TEMPLATE = `${BASE_URL}/DocuSeal/downloadTemplate`;
// GESTION LOGIN // GESTION LOGIN
export const BE_AUTH_NEW_PASSWORD_URL = `${BASE_URL}/Auth/newPassword`; export const BE_AUTH_NEW_PASSWORD_URL = `${BASE_URL}/Auth/newPassword`;
export const BE_AUTH_REGISTER_URL = `${BASE_URL}/Auth/subscribe`; export const BE_AUTH_REGISTER_URL = `${BASE_URL}/Auth/subscribe`;
@ -131,12 +125,6 @@ export const FE_PARENTS_HOME_URL = '/parents';
export const FE_PARENTS_MESSAGERIE_URL = '/parents/messagerie'; export const FE_PARENTS_MESSAGERIE_URL = '/parents/messagerie';
export const FE_PARENTS_EDIT_SUBSCRIPTION_URL = '/parents/editSubscription'; export const FE_PARENTS_EDIT_SUBSCRIPTION_URL = '/parents/editSubscription';
// API DOCUSEAL
export const FE_API_DOCUSEAL_GENERATE_TOKEN = '/api/docuseal/generateToken';
export const FE_API_DOCUSEAL_CLONE_URL = '/api/docuseal/cloneTemplate';
export const FE_API_DOCUSEAL_DOWNLOAD_URL = '/api/docuseal/downloadTemplate';
export const FE_API_DOCUSEAL_DELETE_URL = '/api/docuseal/removeTemplate';
/** /**
* Fonction pour obtenir l'URL de redirection en fonction du rôle * Fonction pour obtenir l'URL de redirection en fonction du rôle
* @param {RIGHTS} role * @param {RIGHTS} role

View File

@ -10,10 +10,10 @@ services:
database: database:
image: "postgres:latest" image: "postgres:latest"
expose: ports:
- 5432 - "5432:5432"
volumes: volumes:
- postgres-data:/var/lib/postgresql/data - postgres-data:/var/lib/postgresql
environment: environment:
POSTGRES_USER: postgres POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres POSTGRES_PASSWORD: postgres