mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-01-29 07:53:23 +00:00
fix: Uniformisation des Modales et Popup [#35]
This commit is contained in:
@ -99,7 +99,8 @@ export default function Page() {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Popup
|
<Popup
|
||||||
visible={popupVisible}
|
isOpen={popupVisible}
|
||||||
|
setIsOpen={setPopupVisible}
|
||||||
message={popupMessage}
|
message={popupMessage}
|
||||||
onConfirm={() => {
|
onConfirm={() => {
|
||||||
setPopupVisible(false);
|
setPopupVisible(false);
|
||||||
@ -107,6 +108,7 @@ export default function Page() {
|
|||||||
}}
|
}}
|
||||||
onCancel={() => setPopupVisible(false)}
|
onCancel={() => setPopupVisible(false)}
|
||||||
uniqueConfirmButton={true}
|
uniqueConfirmButton={true}
|
||||||
|
popupClassName="w-full max-w-xs sm:max-w-md"
|
||||||
/>
|
/>
|
||||||
<div className="container max mx-auto p-4">
|
<div className="container max mx-auto p-4">
|
||||||
<div className="flex justify-center mb-4">
|
<div className="flex justify-center mb-4">
|
||||||
|
|||||||
@ -144,7 +144,8 @@ export default function Page() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Popup
|
<Popup
|
||||||
visible={popupVisible}
|
isOpen={popupVisible}
|
||||||
|
setIsOpen={setPopupVisible}
|
||||||
message={popupMessage}
|
message={popupMessage}
|
||||||
onConfirm={() => {
|
onConfirm={() => {
|
||||||
setPopupVisible(false);
|
setPopupVisible(false);
|
||||||
@ -152,6 +153,7 @@ export default function Page() {
|
|||||||
}}
|
}}
|
||||||
onCancel={() => setPopupVisible(false)}
|
onCancel={() => setPopupVisible(false)}
|
||||||
uniqueConfirmButton={true}
|
uniqueConfirmButton={true}
|
||||||
|
popupClassName="w-full max-w-xs sm:max-w-md"
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,12 +1,14 @@
|
|||||||
import {
|
import {
|
||||||
|
BE_GESTIONMESSAGERIE_CONVERSATIONS_URL,
|
||||||
|
BE_GESTIONMESSAGERIE_CONVERSATION_MESSAGES_URL,
|
||||||
|
BE_GESTIONMESSAGERIE_MARK_AS_READ_URL,
|
||||||
BE_GESTIONMESSAGERIE_MESSAGES_URL,
|
BE_GESTIONMESSAGERIE_MESSAGES_URL,
|
||||||
BE_GESTIONMESSAGERIE_SEND_MESSAGE_URL,
|
|
||||||
BE_GESTIONMESSAGERIE_SEARCH_RECIPIENTS_URL,
|
BE_GESTIONMESSAGERIE_SEARCH_RECIPIENTS_URL,
|
||||||
} from '@/utils/Url';
|
} from '@/utils/Url';
|
||||||
import { errorHandler, requestResponseHandler } from './actionsHandlers';
|
import { errorHandler, requestResponseHandler } from './actionsHandlers';
|
||||||
|
|
||||||
export const fetchMessages = (id) => {
|
export const fetchConversations = (profileId) => {
|
||||||
return fetch(`${BE_GESTIONMESSAGERIE_MESSAGES_URL}/${id}`, {
|
return fetch(`${BE_GESTIONMESSAGERIE_CONVERSATIONS_URL}/${profileId}/`, {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
@ -15,12 +17,24 @@ export const fetchMessages = (id) => {
|
|||||||
.catch(errorHandler);
|
.catch(errorHandler);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const sendMessage = (data, csrfToken) => {
|
export const fetchMessages = (conversationId) => {
|
||||||
return fetch(`${BE_GESTIONMESSAGERIE_SEND_MESSAGE_URL}`, {
|
return fetch(
|
||||||
|
`${BE_GESTIONMESSAGERIE_CONVERSATION_MESSAGES_URL}/${conversationId}/`,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then(requestResponseHandler)
|
||||||
|
.catch(errorHandler);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const sendMessage = (data) => {
|
||||||
|
return fetch(`${BE_GESTIONMESSAGERIE_MESSAGES_URL}`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'X-CSRFToken': csrfToken,
|
|
||||||
},
|
},
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
})
|
})
|
||||||
@ -28,6 +42,18 @@ export const sendMessage = (data, csrfToken) => {
|
|||||||
.catch(errorHandler);
|
.catch(errorHandler);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const markAsRead = (conversationId, profileId) => {
|
||||||
|
return fetch(`${BE_GESTIONMESSAGERIE_MARK_AS_READ_URL}/${conversationId}/`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ profile_id: profileId }),
|
||||||
|
})
|
||||||
|
.then(requestResponseHandler)
|
||||||
|
.catch(errorHandler);
|
||||||
|
};
|
||||||
|
|
||||||
export const searchRecipients = (establishmentId, query) => {
|
export const searchRecipients = (establishmentId, query) => {
|
||||||
const url = `${BE_GESTIONMESSAGERIE_SEARCH_RECIPIENTS_URL}/?establishment_id=${establishmentId}&q=${encodeURIComponent(query)}`;
|
const url = `${BE_GESTIONMESSAGERIE_SEARCH_RECIPIENTS_URL}/?establishment_id=${establishmentId}&q=${encodeURIComponent(query)}`;
|
||||||
return fetch(url, {
|
return fetch(url, {
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { usePlanning, RecurrenceType } from '@/context/PlanningContext';
|
|||||||
import { format } from 'date-fns';
|
import { format } from 'date-fns';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useNotification } from '@/context/NotificationContext';
|
import { useNotification } from '@/context/NotificationContext';
|
||||||
|
import Modal from '@/components/Modal';
|
||||||
|
|
||||||
export default function EventModal({
|
export default function EventModal({
|
||||||
isOpen,
|
isOpen,
|
||||||
@ -86,255 +87,254 @@ export default function EventModal({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
|
<Modal
|
||||||
<div className="bg-white p-6 rounded-lg w-full max-w-md">
|
isOpen={isOpen}
|
||||||
<h2 className="text-xl font-semibold mb-4">
|
setIsOpen={onClose}
|
||||||
{eventData.id ? "Modifier l'événement" : 'Nouvel événement'}
|
title={eventData.id ? "Modifier l'événement" : 'Nouvel événement'}
|
||||||
</h2>
|
modalClassName="w-full max-w-md"
|
||||||
|
>
|
||||||
|
<form onSubmit={handleSubmit} className="space-y-4">
|
||||||
|
{/* Titre */}
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||||
|
Titre
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={eventData.title || ''}
|
||||||
|
onChange={(e) =>
|
||||||
|
setEventData({ ...eventData, title: e.target.value })
|
||||||
|
}
|
||||||
|
className="w-full p-2 border rounded focus:outline-none focus:ring-2 focus:ring-emerald-500"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<form onSubmit={handleSubmit} className="space-y-4">
|
{/* Description */}
|
||||||
{/* Titre */}
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||||
|
Description
|
||||||
|
</label>
|
||||||
|
<textarea
|
||||||
|
value={eventData.description || ''}
|
||||||
|
onChange={(e) =>
|
||||||
|
setEventData({ ...eventData, description: e.target.value })
|
||||||
|
}
|
||||||
|
className="w-full p-2 border rounded focus:outline-none focus:ring-2 focus:ring-emerald-500"
|
||||||
|
rows="3"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Planning */}
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||||
|
Planning
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
value={eventData.planning || schedules[0]?.id}
|
||||||
|
onChange={(e) => {
|
||||||
|
const selectedSchedule = schedules.find(
|
||||||
|
(s) => s.id === e.target.value
|
||||||
|
);
|
||||||
|
setEventData({
|
||||||
|
...eventData,
|
||||||
|
planning: e.target.value,
|
||||||
|
color: selectedSchedule?.color || '#10b981',
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
className="w-full p-2 border rounded focus:outline-none focus:ring-2 focus:ring-emerald-500"
|
||||||
|
required
|
||||||
|
>
|
||||||
|
{schedules.map((schedule) => (
|
||||||
|
<option key={schedule.id} value={schedule.id}>
|
||||||
|
{schedule.name}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Couleur */}
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||||
|
Couleur
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="color"
|
||||||
|
value={
|
||||||
|
eventData.color ||
|
||||||
|
schedules.find((s) => s.id === eventData.planning)?.color ||
|
||||||
|
'#10b981'
|
||||||
|
}
|
||||||
|
onChange={(e) =>
|
||||||
|
setEventData({ ...eventData, color: e.target.value })
|
||||||
|
}
|
||||||
|
className="w-full h-10 p-1 rounded border"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Récurrence */}
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||||
|
Récurrence
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
value={eventData.recursionType || RecurrenceType.NONE}
|
||||||
|
onChange={(e) => {
|
||||||
|
return setEventData({
|
||||||
|
...eventData,
|
||||||
|
recursionType: e.target.value,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
className="w-full p-2 border rounded focus:outline-none focus:ring-2 focus:ring-emerald-500"
|
||||||
|
>
|
||||||
|
{recurrenceOptions.map((option) => (
|
||||||
|
<option key={option.value} value={option.value}>
|
||||||
|
{option.label}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Paramètres de récurrence personnalisée */}
|
||||||
|
{eventData.recursionType == RecurrenceType.CUSTOM && (
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
||||||
|
Jours de répétition
|
||||||
|
</label>
|
||||||
|
<div className="flex gap-2 flex-wrap">
|
||||||
|
{daysOfWeek.map((day) => (
|
||||||
|
<button
|
||||||
|
key={day.value}
|
||||||
|
type="button"
|
||||||
|
onClick={() => {
|
||||||
|
const days = eventData.selectedDays || [];
|
||||||
|
const newDays = days.includes(day.value)
|
||||||
|
? days.filter((d) => d !== day.value)
|
||||||
|
: [...days, day.value];
|
||||||
|
setEventData({ ...eventData, selectedDays: newDays });
|
||||||
|
}}
|
||||||
|
className={`px-3 py-1 rounded-full text-sm ${
|
||||||
|
(eventData.selectedDays || []).includes(day.value)
|
||||||
|
? 'bg-emerald-100 text-emerald-800'
|
||||||
|
: 'bg-gray-100 text-gray-600'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{day.label}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Date de fin de récurrence */}
|
||||||
|
{eventData.recursionType != RecurrenceType.NONE && (
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||||
Titre
|
Fin de récurrence
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="date"
|
||||||
value={eventData.title || ''}
|
value={
|
||||||
onChange={(e) =>
|
eventData.recursionEnd
|
||||||
setEventData({ ...eventData, title: e.target.value })
|
? format(new Date(eventData.recursionEnd), 'yyyy-MM-dd')
|
||||||
|
: ''
|
||||||
}
|
}
|
||||||
className="w-full p-2 border rounded focus:outline-none focus:ring-2 focus:ring-emerald-500"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Description */}
|
|
||||||
<div>
|
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
|
||||||
Description
|
|
||||||
</label>
|
|
||||||
<textarea
|
|
||||||
value={eventData.description || ''}
|
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
setEventData({ ...eventData, description: e.target.value })
|
|
||||||
}
|
|
||||||
className="w-full p-2 border rounded focus:outline-none focus:ring-2 focus:ring-emerald-500"
|
|
||||||
rows="3"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Planning */}
|
|
||||||
<div>
|
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
|
||||||
Planning
|
|
||||||
</label>
|
|
||||||
<select
|
|
||||||
value={eventData.planning || schedules[0]?.id}
|
|
||||||
onChange={(e) => {
|
|
||||||
const selectedSchedule = schedules.find(
|
|
||||||
(s) => s.id === e.target.value
|
|
||||||
);
|
|
||||||
setEventData({
|
setEventData({
|
||||||
...eventData,
|
...eventData,
|
||||||
planning: e.target.value,
|
recursionEnd: e.target.value
|
||||||
color: selectedSchedule?.color || '#10b981',
|
? new Date(e.target.value).toISOString()
|
||||||
});
|
: null,
|
||||||
}}
|
})
|
||||||
|
}
|
||||||
|
className="w-full p-2 border rounded focus:outline-none focus:ring-2 focus:ring-emerald-500"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Dates */}
|
||||||
|
<div className="grid grid-cols-2 gap-4">
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||||
|
Début
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="datetime-local"
|
||||||
|
value={format(new Date(eventData.start), "yyyy-MM-dd'T'HH:mm")}
|
||||||
|
onChange={(e) =>
|
||||||
|
setEventData({
|
||||||
|
...eventData,
|
||||||
|
start: new Date(e.target.value).toISOString(),
|
||||||
|
})
|
||||||
|
}
|
||||||
className="w-full p-2 border rounded focus:outline-none focus:ring-2 focus:ring-emerald-500"
|
className="w-full p-2 border rounded focus:outline-none focus:ring-2 focus:ring-emerald-500"
|
||||||
required
|
required
|
||||||
>
|
|
||||||
{schedules.map((schedule) => (
|
|
||||||
<option key={schedule.id} value={schedule.id}>
|
|
||||||
{schedule.name}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Couleur */}
|
|
||||||
<div>
|
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
|
||||||
Couleur
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
type="color"
|
|
||||||
value={
|
|
||||||
eventData.color ||
|
|
||||||
schedules.find((s) => s.id === eventData.planning)?.color ||
|
|
||||||
'#10b981'
|
|
||||||
}
|
|
||||||
onChange={(e) =>
|
|
||||||
setEventData({ ...eventData, color: e.target.value })
|
|
||||||
}
|
|
||||||
className="w-full h-10 p-1 rounded border"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Récurrence */}
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||||
Récurrence
|
Fin
|
||||||
</label>
|
</label>
|
||||||
<select
|
<input
|
||||||
value={eventData.recursionType || RecurrenceType.NONE}
|
type="datetime-local"
|
||||||
onChange={(e) => {
|
value={format(new Date(eventData.end), "yyyy-MM-dd'T'HH:mm")}
|
||||||
return setEventData({
|
onChange={(e) =>
|
||||||
|
setEventData({
|
||||||
...eventData,
|
...eventData,
|
||||||
recursionType: e.target.value,
|
end: new Date(e.target.value).toISOString(),
|
||||||
});
|
})
|
||||||
}}
|
|
||||||
className="w-full p-2 border rounded focus:outline-none focus:ring-2 focus:ring-emerald-500"
|
|
||||||
>
|
|
||||||
{recurrenceOptions.map((option) => (
|
|
||||||
<option key={option.value} value={option.value}>
|
|
||||||
{option.label}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Paramètres de récurrence personnalisée */}
|
|
||||||
{eventData.recursionType == RecurrenceType.CUSTOM && (
|
|
||||||
<div>
|
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
||||||
Jours de répétition
|
|
||||||
</label>
|
|
||||||
<div className="flex gap-2 flex-wrap">
|
|
||||||
{daysOfWeek.map((day) => (
|
|
||||||
<button
|
|
||||||
key={day.value}
|
|
||||||
type="button"
|
|
||||||
onClick={() => {
|
|
||||||
const days = eventData.selectedDays || [];
|
|
||||||
const newDays = days.includes(day.value)
|
|
||||||
? days.filter((d) => d !== day.value)
|
|
||||||
: [...days, day.value];
|
|
||||||
setEventData({ ...eventData, selectedDays: newDays });
|
|
||||||
}}
|
|
||||||
className={`px-3 py-1 rounded-full text-sm ${
|
|
||||||
(eventData.selectedDays || []).includes(day.value)
|
|
||||||
? 'bg-emerald-100 text-emerald-800'
|
|
||||||
: 'bg-gray-100 text-gray-600'
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{day.label}
|
|
||||||
</button>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Date de fin de récurrence */}
|
|
||||||
{eventData.recursionType != RecurrenceType.NONE && (
|
|
||||||
<div>
|
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
|
||||||
Fin de récurrence
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
type="date"
|
|
||||||
value={
|
|
||||||
eventData.recursionEnd
|
|
||||||
? format(new Date(eventData.recursionEnd), 'yyyy-MM-dd')
|
|
||||||
: ''
|
|
||||||
}
|
|
||||||
onChange={(e) =>
|
|
||||||
setEventData({
|
|
||||||
...eventData,
|
|
||||||
recursionEnd: e.target.value
|
|
||||||
? new Date(e.target.value).toISOString()
|
|
||||||
: null,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
className="w-full p-2 border rounded focus:outline-none focus:ring-2 focus:ring-emerald-500"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Dates */}
|
|
||||||
<div className="grid grid-cols-2 gap-4">
|
|
||||||
<div>
|
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
|
||||||
Début
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
type="datetime-local"
|
|
||||||
value={format(new Date(eventData.start), "yyyy-MM-dd'T'HH:mm")}
|
|
||||||
onChange={(e) =>
|
|
||||||
setEventData({
|
|
||||||
...eventData,
|
|
||||||
start: new Date(e.target.value).toISOString(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
className="w-full p-2 border rounded focus:outline-none focus:ring-2 focus:ring-emerald-500"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
|
||||||
Fin
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
type="datetime-local"
|
|
||||||
value={format(new Date(eventData.end), "yyyy-MM-dd'T'HH:mm")}
|
|
||||||
onChange={(e) =>
|
|
||||||
setEventData({
|
|
||||||
...eventData,
|
|
||||||
end: new Date(e.target.value).toISOString(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
className="w-full p-2 border rounded focus:outline-none focus:ring-2 focus:ring-emerald-500"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Lieu */}
|
|
||||||
<div>
|
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
|
||||||
Lieu
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
value={eventData.location || ''}
|
|
||||||
onChange={(e) =>
|
|
||||||
setEventData({ ...eventData, location: e.target.value })
|
|
||||||
}
|
}
|
||||||
className="w-full p-2 border rounded focus:outline-none focus:ring-2 focus:ring-emerald-500"
|
className="w-full p-2 border rounded focus:outline-none focus:ring-2 focus:ring-emerald-500"
|
||||||
|
required
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Boutons */}
|
{/* Lieu */}
|
||||||
<div className="flex justify-between gap-2 mt-6">
|
<div>
|
||||||
<div>
|
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||||
{eventData.id && (
|
Lieu
|
||||||
<button
|
</label>
|
||||||
type="button"
|
<input
|
||||||
onClick={handleDelete}
|
type="text"
|
||||||
className="px-4 py-2 text-red-600 hover:bg-red-50 rounded"
|
value={eventData.location || ''}
|
||||||
>
|
onChange={(e) =>
|
||||||
Supprimer
|
setEventData({ ...eventData, location: e.target.value })
|
||||||
</button>
|
}
|
||||||
)}
|
className="w-full p-2 border rounded focus:outline-none focus:ring-2 focus:ring-emerald-500"
|
||||||
</div>
|
/>
|
||||||
<div className="flex gap-2">
|
</div>
|
||||||
|
|
||||||
|
{/* Boutons */}
|
||||||
|
<div className="flex justify-between gap-2 mt-6">
|
||||||
|
<div>
|
||||||
|
{eventData.id && (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={onClose}
|
onClick={handleDelete}
|
||||||
className="px-4 py-2 text-gray-600 hover:bg-gray-100 rounded"
|
className="px-4 py-2 text-red-600 hover:bg-red-50 rounded"
|
||||||
>
|
>
|
||||||
Annuler
|
Supprimer
|
||||||
</button>
|
</button>
|
||||||
<button
|
)}
|
||||||
type="submit"
|
|
||||||
className="px-4 py-2 bg-emerald-600 text-white rounded hover:bg-emerald-700"
|
|
||||||
>
|
|
||||||
{eventData.id ? 'Modifier' : 'Créer'}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
<div className="flex gap-2">
|
||||||
</div>
|
<button
|
||||||
</div>
|
type="button"
|
||||||
|
onClick={onClose}
|
||||||
|
className="px-4 py-2 text-gray-600 hover:bg-gray-100 rounded"
|
||||||
|
>
|
||||||
|
Annuler
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className="px-4 py-2 bg-emerald-600 text-white rounded hover:bg-emerald-700"
|
||||||
|
>
|
||||||
|
{eventData.id ? 'Modifier' : 'Créer'}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</Modal>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -96,146 +96,143 @@ const FilesModal = ({
|
|||||||
{title}
|
{title}
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
ContentComponent={() => (
|
>
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
{/* Section Fiche élève */}
|
{/* Section Fiche élève */}
|
||||||
{files.registrationFile && (
|
{files.registrationFile && (
|
||||||
<div>
|
<div>
|
||||||
<h3 className="text-lg font-semibold text-gray-800 mb-4">
|
<h3 className="text-lg font-semibold text-gray-800 mb-4">
|
||||||
Fiche élève
|
Fiche élève
|
||||||
</h3>
|
</h3>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<FileText className="w-5 h-5 text-gray-500" />
|
<FileText className="w-5 h-5 text-gray-500" />
|
||||||
<a
|
<a
|
||||||
href={files.registrationFile.url}
|
href={files.registrationFile.url}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
className="text-blue-500 hover:text-blue-700 underline"
|
className="text-blue-500 hover:text-blue-700 underline"
|
||||||
>
|
>
|
||||||
{files.registrationFile.name}
|
{files.registrationFile.name}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Section Documents fusionnés */}
|
{/* Section Documents fusionnés */}
|
||||||
{files.fusionFile && (
|
{files.fusionFile && (
|
||||||
<div>
|
<div>
|
||||||
<h3 className="text-lg font-semibold text-gray-800 mb-4">
|
<h3 className="text-lg font-semibold text-gray-800 mb-4">
|
||||||
Documents fusionnés
|
Documents fusionnés
|
||||||
</h3>
|
</h3>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<FileText className="w-5 h-5 text-gray-500" />
|
<FileText className="w-5 h-5 text-gray-500" />
|
||||||
<a
|
<a
|
||||||
href={files.fusionFile.url}
|
href={files.fusionFile.url}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
className="text-blue-500 hover:text-blue-700 underline"
|
className="text-blue-500 hover:text-blue-700 underline"
|
||||||
>
|
>
|
||||||
{files.fusionFile.name}
|
{files.fusionFile.name}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
|
||||||
|
|
||||||
<hr className="border-t border-gray-300" />
|
|
||||||
|
|
||||||
{/* Section Fichiers École */}
|
|
||||||
<div>
|
|
||||||
<h3 className="text-lg font-semibold text-gray-800 mb-4">
|
|
||||||
Formulaires de l'établissement
|
|
||||||
</h3>
|
|
||||||
<ul className="space-y-2">
|
|
||||||
{files.schoolFiles.length > 0 ? (
|
|
||||||
files.schoolFiles.map((file, index) => (
|
|
||||||
<li key={index} className="flex items-center gap-2">
|
|
||||||
<FileText className="w-5 h-5 text-gray-500" />
|
|
||||||
{file.url ? (
|
|
||||||
<a
|
|
||||||
href={file.url}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="text-blue-500 hover:text-blue-700 underline"
|
|
||||||
>
|
|
||||||
{file.name}
|
|
||||||
</a>
|
|
||||||
) : (
|
|
||||||
<span className="text-gray-400">
|
|
||||||
{file.name} (Non disponible)
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</li>
|
|
||||||
))
|
|
||||||
) : (
|
|
||||||
<p className="text-gray-500">
|
|
||||||
Aucun fichier scolaire disponible.
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<hr className="border-t border-gray-300" />
|
<hr className="border-t border-gray-300" />
|
||||||
|
|
||||||
{/* Section Fichiers Parent */}
|
{/* Section Fichiers École */}
|
||||||
<div>
|
<div>
|
||||||
<h3 className="text-lg font-semibold text-gray-800 mb-4">
|
<h3 className="text-lg font-semibold text-gray-800 mb-4">
|
||||||
Pièces fournies
|
Formulaires de l'établissement
|
||||||
</h3>
|
</h3>
|
||||||
<ul className="space-y-2">
|
<ul className="space-y-2">
|
||||||
{files.parentFiles.length > 0 ? (
|
{files.schoolFiles.length > 0 ? (
|
||||||
files.parentFiles.map((file, index) => (
|
files.schoolFiles.map((file, index) => (
|
||||||
<li key={index} className="flex items-center gap-2">
|
<li key={index} className="flex items-center gap-2">
|
||||||
<FileText className="w-5 h-5 text-gray-500" />
|
<FileText className="w-5 h-5 text-gray-500" />
|
||||||
{file.url ? (
|
{file.url ? (
|
||||||
<a
|
<a
|
||||||
href={file.url}
|
href={file.url}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
className="text-blue-500 hover:text-blue-700 underline"
|
className="text-blue-500 hover:text-blue-700 underline"
|
||||||
>
|
>
|
||||||
{file.name}
|
{file.name}
|
||||||
</a>
|
</a>
|
||||||
) : (
|
) : (
|
||||||
<span className="text-gray-400">
|
<span className="text-gray-400">
|
||||||
{file.name} (Non disponible)
|
{file.name} (Non disponible)
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</li>
|
</li>
|
||||||
))
|
))
|
||||||
) : (
|
|
||||||
<p className="text-gray-500">
|
|
||||||
Aucun fichier parent disponible.
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr className="border-t border-gray-300" />
|
|
||||||
|
|
||||||
{/* Section Mandat SEPA */}
|
|
||||||
<div>
|
|
||||||
<h3 className="text-lg font-semibold text-gray-800 mb-4">
|
|
||||||
Mandat SEPA
|
|
||||||
</h3>
|
|
||||||
{files.sepaFile ? (
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<FileText className="w-5 h-5 text-gray-500" />
|
|
||||||
<a
|
|
||||||
href={files.sepaFile.url}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="text-blue-500 hover:text-blue-700 underline"
|
|
||||||
>
|
|
||||||
{files.sepaFile.name}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
) : (
|
) : (
|
||||||
<p className="text-gray-500">Aucun mandat SEPA disponible.</p>
|
<p className="text-gray-500">
|
||||||
|
Aucun fichier scolaire disponible.
|
||||||
|
</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
)}
|
|
||||||
/>
|
<hr className="border-t border-gray-300" />
|
||||||
|
|
||||||
|
{/* Section Fichiers Parent */}
|
||||||
|
<div>
|
||||||
|
<h3 className="text-lg font-semibold text-gray-800 mb-4">
|
||||||
|
Pièces fournies
|
||||||
|
</h3>
|
||||||
|
<ul className="space-y-2">
|
||||||
|
{files.parentFiles.length > 0 ? (
|
||||||
|
files.parentFiles.map((file, index) => (
|
||||||
|
<li key={index} className="flex items-center gap-2">
|
||||||
|
<FileText className="w-5 h-5 text-gray-500" />
|
||||||
|
{file.url ? (
|
||||||
|
<a
|
||||||
|
href={file.url}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="text-blue-500 hover:text-blue-700 underline"
|
||||||
|
>
|
||||||
|
{file.name}
|
||||||
|
</a>
|
||||||
|
) : (
|
||||||
|
<span className="text-gray-400">
|
||||||
|
{file.name} (Non disponible)
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</li>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<p className="text-gray-500">Aucun fichier parent disponible.</p>
|
||||||
|
)}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr className="border-t border-gray-300" />
|
||||||
|
|
||||||
|
{/* Section Mandat SEPA */}
|
||||||
|
<div>
|
||||||
|
<h3 className="text-lg font-semibold text-gray-800 mb-4">
|
||||||
|
Mandat SEPA
|
||||||
|
</h3>
|
||||||
|
{files.sepaFile ? (
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<FileText className="w-5 h-5 text-gray-500" />
|
||||||
|
<a
|
||||||
|
href={files.sepaFile.url}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="text-blue-500 hover:text-blue-700 underline"
|
||||||
|
>
|
||||||
|
{files.sepaFile.name}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<p className="text-gray-500">Aucun mandat SEPA disponible.</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@ const Modal = ({
|
|||||||
isOpen,
|
isOpen,
|
||||||
setIsOpen,
|
setIsOpen,
|
||||||
title,
|
title,
|
||||||
ContentComponent,
|
children,
|
||||||
modalClassName,
|
modalClassName,
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
@ -12,43 +12,42 @@ const Modal = ({
|
|||||||
<Dialog.Portal>
|
<Dialog.Portal>
|
||||||
{/* Overlay avec un z-index élevé et un effet de flou */}
|
{/* Overlay avec un z-index élevé et un effet de flou */}
|
||||||
<Dialog.Overlay className="fixed inset-0 bg-black bg-opacity-50 backdrop-blur-sm z-[9998] transition-opacity" />
|
<Dialog.Overlay className="fixed inset-0 bg-black bg-opacity-50 backdrop-blur-sm z-[9998] transition-opacity" />
|
||||||
<Dialog.Content className="fixed inset-0 flex items-center justify-center p-4 z-[9999]">
|
<Dialog.Content className="fixed inset-0 flex items-center justify-center p-2 sm:p-4 z-[9999]">
|
||||||
<div
|
<div
|
||||||
className={`relative bg-white rounded-xl px-8 py-6 text-left shadow-2xl transform transition-all sm:my-8 ${modalClassName ? modalClassName : 'min-w-[500px] max-w-[90%] max-h-[80vh] overflow-auto'}`}
|
className={`relative bg-white rounded-xl px-2 py-4 sm:px-8 sm:py-6 text-left shadow-2xl transform transition-all w-full max-w-lg sm:min-w-[400px] sm:max-w-[90%] max-h-[90vh] overflow-auto ${modalClassName ? modalClassName : ''}`}
|
||||||
>
|
>
|
||||||
{/* En-tête de la modale */}
|
{/* En-tête de la modale si title fourni */}
|
||||||
<div className="flex justify-between items-center mb-6">
|
{title && (
|
||||||
<Dialog.Title className="text-2xl font-semibold text-gray-800">
|
<div className="flex justify-between items-center mb-4 sm:mb-6">
|
||||||
{title}
|
<Dialog.Title className="text-lg sm:text-2xl font-semibold text-gray-800">
|
||||||
</Dialog.Title>
|
{title}
|
||||||
<Dialog.Close asChild>
|
</Dialog.Title>
|
||||||
<button
|
<Dialog.Close asChild>
|
||||||
onClick={() => setIsOpen(false)}
|
<button
|
||||||
className="text-gray-500 hover:text-gray-700 focus:outline-none"
|
onClick={() => setIsOpen(false)}
|
||||||
>
|
className="text-gray-500 hover:text-gray-700 focus:outline-none"
|
||||||
<span className="sr-only">Fermer</span>
|
|
||||||
<svg
|
|
||||||
className="h-6 w-6"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
stroke="currentColor"
|
|
||||||
>
|
>
|
||||||
<path
|
<span className="sr-only">Fermer</span>
|
||||||
strokeLinecap="round"
|
<svg
|
||||||
strokeLinejoin="round"
|
className="h-6 w-6"
|
||||||
strokeWidth="2"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
d="M6 18L18 6M6 6l12 12"
|
fill="none"
|
||||||
/>
|
viewBox="0 0 24 24"
|
||||||
</svg>
|
stroke="currentColor"
|
||||||
</button>
|
>
|
||||||
</Dialog.Close>
|
<path
|
||||||
</div>
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth="2"
|
||||||
|
d="M6 18L18 6M6 6l12 12"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</Dialog.Close>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
{/* Contenu de la modale */}
|
{/* Contenu de la modale */}
|
||||||
<div className="w-full h-full">
|
<div className="w-full h-full">{children}</div>
|
||||||
<ContentComponent />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</Dialog.Content>
|
</Dialog.Content>
|
||||||
</Dialog.Portal>
|
</Dialog.Portal>
|
||||||
|
|||||||
@ -1,23 +1,31 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
|
||||||
|
|
||||||
const Popup = ({
|
const Popup = ({
|
||||||
visible,
|
isOpen,
|
||||||
|
setIsOpen,
|
||||||
message,
|
message,
|
||||||
onConfirm,
|
onConfirm,
|
||||||
onCancel,
|
onCancel,
|
||||||
uniqueConfirmButton = false,
|
uniqueConfirmButton = false,
|
||||||
|
popupClassName,
|
||||||
}) => {
|
}) => {
|
||||||
if (!visible) return null;
|
if (!isOpen) return null;
|
||||||
|
|
||||||
// Vérifier si le message est une chaîne de caractères
|
// Vérifier si le message est une chaîne de caractères
|
||||||
const isStringMessage = typeof message === 'string';
|
const isStringMessage = typeof message === 'string';
|
||||||
// Diviser le message en lignes seulement si c'est une chaîne
|
|
||||||
const messageLines = isStringMessage ? message.split('\n') : null;
|
const messageLines = isStringMessage ? message.split('\n') : null;
|
||||||
|
|
||||||
return ReactDOM.createPortal(
|
return (
|
||||||
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-60">
|
<div className="fixed inset-0 z-[9999] flex items-center justify-center">
|
||||||
<div className="bg-white p-6 rounded-xl shadow-2xl max-w-lg w-full">
|
{/* Overlay noir semi-transparent */}
|
||||||
|
<div
|
||||||
|
className="fixed inset-0 bg-black bg-opacity-60 transition-opacity z-[9998]"
|
||||||
|
onClick={() => setIsOpen(false)}
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
className={`relative bg-white p-4 sm:p-6 rounded-xl shadow-2xl w-full max-w-xs sm:max-w-md ${popupClassName ? popupClassName : ''}`}
|
||||||
|
style={{ zIndex: 9999 }}
|
||||||
|
>
|
||||||
{/* Titre ou message */}
|
{/* Titre ou message */}
|
||||||
<div className="mb-6">
|
<div className="mb-6">
|
||||||
{isStringMessage
|
{isStringMessage
|
||||||
@ -28,27 +36,31 @@ const Popup = ({
|
|||||||
))
|
))
|
||||||
: message}
|
: message}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Boutons d'action */}
|
{/* Boutons d'action */}
|
||||||
<div className="flex justify-end space-x-4">
|
<div className="flex justify-end space-x-4">
|
||||||
{!uniqueConfirmButton && (
|
{!uniqueConfirmButton && (
|
||||||
<button
|
<button
|
||||||
className="px-4 py-2 bg-gray-200 text-gray-800 rounded-lg hover:bg-gray-300 focus:outline-none transition"
|
className="px-4 py-2 bg-gray-200 text-gray-800 rounded-lg hover:bg-gray-300 focus:outline-none transition"
|
||||||
onClick={onCancel}
|
onClick={() => {
|
||||||
|
setIsOpen(false);
|
||||||
|
if (onCancel) onCancel();
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
Annuler
|
Annuler
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
<button
|
<button
|
||||||
className="px-4 py-2 bg-emerald-500 text-white rounded-lg hover:bg-emerald-600 focus:outline-none transition"
|
className="px-4 py-2 bg-emerald-500 text-white rounded-lg hover:bg-emerald-600 focus:outline-none transition"
|
||||||
onClick={onConfirm}
|
onClick={() => {
|
||||||
|
setIsOpen(false);
|
||||||
|
if (onConfirm) onConfirm();
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{uniqueConfirmButton ? 'Fermer' : 'Confirmer'}
|
{uniqueConfirmButton ? 'Fermer' : 'Confirmer'}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>,
|
</div>
|
||||||
document.body
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -331,7 +331,7 @@ export default function FilesGroupsManagement({
|
|||||||
|
|
||||||
setRemovePopupVisible(true);
|
setRemovePopupVisible(true);
|
||||||
setRemovePopupMessage(
|
setRemovePopupMessage(
|
||||||
`Attentions ! \nÊtes-vous sûr de vouloir supprimer ce groupe ?`
|
'Attentions ! \nÊtes-vous sûr de vouloir supprimer ce groupe ?'
|
||||||
);
|
);
|
||||||
setRemovePopupOnConfirm(() => () => {
|
setRemovePopupOnConfirm(() => () => {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
@ -508,16 +508,15 @@ export default function FilesGroupsManagement({
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
title={isEditing ? 'Modification du document' : 'Ajouter un document'}
|
title={isEditing ? 'Modification du document' : 'Ajouter un document'}
|
||||||
ContentComponent={() => (
|
|
||||||
<FileUploadDocuSeal
|
|
||||||
handleCreateTemplateMaster={handleCreateTemplateMaster}
|
|
||||||
handleEditTemplateMaster={handleEditTemplateMaster}
|
|
||||||
fileToEdit={fileToEdit}
|
|
||||||
onSuccess={handleReloadTemplates}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
modalClassName="w-4/5 h-4/5"
|
modalClassName="w-4/5 h-4/5"
|
||||||
/>
|
>
|
||||||
|
<FileUploadDocuSeal
|
||||||
|
handleCreateTemplateMaster={handleCreateTemplateMaster}
|
||||||
|
handleEditTemplateMaster={handleEditTemplateMaster}
|
||||||
|
fileToEdit={fileToEdit}
|
||||||
|
onSuccess={handleReloadTemplates}
|
||||||
|
/>
|
||||||
|
</Modal>
|
||||||
|
|
||||||
{/* Modal pour les groupes */}
|
{/* Modal pour les groupes */}
|
||||||
<Modal
|
<Modal
|
||||||
@ -526,13 +525,12 @@ export default function FilesGroupsManagement({
|
|||||||
title={
|
title={
|
||||||
groupToEdit ? 'Modifier le dossier' : "Création d'un nouveau dossier"
|
groupToEdit ? 'Modifier le dossier' : "Création d'un nouveau dossier"
|
||||||
}
|
}
|
||||||
ContentComponent={() => (
|
>
|
||||||
<RegistrationFileGroupForm
|
<RegistrationFileGroupForm
|
||||||
onSubmit={handleGroupSubmit}
|
onSubmit={handleGroupSubmit}
|
||||||
initialData={groupToEdit}
|
initialData={groupToEdit}
|
||||||
/>
|
/>
|
||||||
)}
|
</Modal>
|
||||||
/>
|
|
||||||
|
|
||||||
{/* Section Groupes de fichiers */}
|
{/* Section Groupes de fichiers */}
|
||||||
<div className="mt-8 w-3/5">
|
<div className="mt-8 w-3/5">
|
||||||
|
|||||||
@ -334,17 +334,21 @@ const FeesSection = ({
|
|||||||
renderCell={renderFeeCell}
|
renderCell={renderFeeCell}
|
||||||
/>
|
/>
|
||||||
<Popup
|
<Popup
|
||||||
visible={popupVisible}
|
isOpen={popupVisible}
|
||||||
|
setIsOpen={setPopupVisible}
|
||||||
message={popupMessage}
|
message={popupMessage}
|
||||||
onConfirm={() => setPopupVisible(false)}
|
onConfirm={() => setPopupVisible(false)}
|
||||||
onCancel={() => setPopupVisible(false)}
|
onCancel={() => setPopupVisible(false)}
|
||||||
uniqueConfirmButton={true}
|
uniqueConfirmButton={true}
|
||||||
|
popupClassName="w-full max-w-xs sm:max-w-md"
|
||||||
/>
|
/>
|
||||||
<Popup
|
<Popup
|
||||||
visible={removePopupVisible}
|
isOpen={removePopupVisible}
|
||||||
|
setIsOpen={setRemovePopupVisible}
|
||||||
message={removePopupMessage}
|
message={removePopupMessage}
|
||||||
onConfirm={removePopupOnConfirm}
|
onConfirm={removePopupOnConfirm}
|
||||||
onCancel={() => setRemovePopupVisible(false)}
|
onCancel={() => setRemovePopupVisible(false)}
|
||||||
|
popupClassName="w-full max-w-xs sm:max-w-md"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user