mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-04-03 16:51:26 +00:00
feat: Page Structure : suppression de la possibilité de faire des actions d'admin [N3WTS-8]
This commit is contained in:
@ -52,7 +52,7 @@ export default function Page() {
|
||||
);
|
||||
|
||||
const csrfToken = useCsrfToken();
|
||||
const { selectedEstablishmentId } = useEstablishment();
|
||||
const { selectedEstablishmentId, profileRole } = useEstablishment();
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedEstablishmentId) {
|
||||
@ -316,35 +316,39 @@ export default function Page() {
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'Fees',
|
||||
label: 'Tarifs',
|
||||
content: (
|
||||
<div className="h-full overflow-y-auto p-4">
|
||||
<FeesManagement
|
||||
registrationDiscounts={registrationDiscounts}
|
||||
setRegistrationDiscounts={setRegistrationDiscounts}
|
||||
tuitionDiscounts={tuitionDiscounts}
|
||||
setTuitionDiscounts={setTuitionDiscounts}
|
||||
registrationFees={registrationFees}
|
||||
setRegistrationFees={setRegistrationFees}
|
||||
tuitionFees={tuitionFees}
|
||||
setTuitionFees={setTuitionFees}
|
||||
registrationPaymentPlans={registrationPaymentPlans}
|
||||
setRegistrationPaymentPlans={setRegistrationPaymentPlans}
|
||||
tuitionPaymentPlans={tuitionPaymentPlans}
|
||||
setTuitionPaymentPlans={setTuitionPaymentPlans}
|
||||
registrationPaymentModes={registrationPaymentModes}
|
||||
setRegistrationPaymentModes={setRegistrationPaymentModes}
|
||||
tuitionPaymentModes={tuitionPaymentModes}
|
||||
setTuitionPaymentModes={setTuitionPaymentModes}
|
||||
handleCreate={handleCreate}
|
||||
handleEdit={handleEdit}
|
||||
handleDelete={handleDelete}
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
...(profileRole !== 0
|
||||
? [
|
||||
{
|
||||
id: 'Fees',
|
||||
label: 'Tarifs',
|
||||
content: (
|
||||
<div className="h-full overflow-y-auto p-4">
|
||||
<FeesManagement
|
||||
registrationDiscounts={registrationDiscounts}
|
||||
setRegistrationDiscounts={setRegistrationDiscounts}
|
||||
tuitionDiscounts={tuitionDiscounts}
|
||||
setTuitionDiscounts={setTuitionDiscounts}
|
||||
registrationFees={registrationFees}
|
||||
setRegistrationFees={setRegistrationFees}
|
||||
tuitionFees={tuitionFees}
|
||||
setTuitionFees={setTuitionFees}
|
||||
registrationPaymentPlans={registrationPaymentPlans}
|
||||
setRegistrationPaymentPlans={setRegistrationPaymentPlans}
|
||||
tuitionPaymentPlans={tuitionPaymentPlans}
|
||||
setTuitionPaymentPlans={setTuitionPaymentPlans}
|
||||
registrationPaymentModes={registrationPaymentModes}
|
||||
setRegistrationPaymentModes={setRegistrationPaymentModes}
|
||||
tuitionPaymentModes={tuitionPaymentModes}
|
||||
setTuitionPaymentModes={setTuitionPaymentModes}
|
||||
handleCreate={handleCreate}
|
||||
handleEdit={handleEdit}
|
||||
handleDelete={handleDelete}
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
{
|
||||
id: 'Files',
|
||||
label: 'Documents',
|
||||
@ -353,6 +357,7 @@ export default function Page() {
|
||||
<FilesGroupsManagement
|
||||
csrfToken={csrfToken}
|
||||
selectedEstablishmentId={selectedEstablishmentId}
|
||||
profileRole={profileRole}
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
|
||||
@ -7,7 +7,6 @@ import CheckBox from '@/components/Form/CheckBox';
|
||||
import Button from '@/components/Form/Button';
|
||||
import { useEstablishment } from '@/context/EstablishmentContext';
|
||||
import {
|
||||
fetchEstablishmentCompetencies,
|
||||
createEstablishmentCompetencies,
|
||||
deleteEstablishmentCompetencies,
|
||||
} from '@/app/actions/schoolAction';
|
||||
@ -44,7 +43,7 @@ export default function CompetenciesList({
|
||||
3: false,
|
||||
4: false,
|
||||
});
|
||||
const { selectedEstablishmentId } = useEstablishment();
|
||||
const { selectedEstablishmentId, profileRole } = useEstablishment();
|
||||
const csrfToken = useCsrfToken();
|
||||
const { showNotification } = useNotification();
|
||||
|
||||
@ -280,17 +279,19 @@ export default function CompetenciesList({
|
||||
</div>
|
||||
{/* Bouton submit centré en bas */}
|
||||
<div className="flex justify-center mb-2 mt-6">
|
||||
<Button
|
||||
text="Sauvegarder"
|
||||
className={`px-6 py-2 rounded-md shadow ${
|
||||
!hasSelection
|
||||
? 'bg-gray-300 text-gray-500 cursor-not-allowed'
|
||||
: 'bg-emerald-500 text-white hover:bg-emerald-600'
|
||||
}`}
|
||||
onClick={handleSubmit}
|
||||
primary
|
||||
disabled={!hasSelection}
|
||||
/>
|
||||
{profileRole !== 0 && (
|
||||
<Button
|
||||
text="Sauvegarder"
|
||||
className={`px-6 py-2 rounded-md shadow ${
|
||||
!hasSelection
|
||||
? 'bg-gray-300 text-gray-500 cursor-not-allowed'
|
||||
: 'bg-emerald-500 text-white hover:bg-emerald-600'
|
||||
}`}
|
||||
onClick={handleSubmit}
|
||||
primary
|
||||
disabled={!hasSelection}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
{/* Légende en dessous du bouton, alignée à gauche */}
|
||||
<div className="flex flex-row items-center gap-4 mb-4">
|
||||
|
||||
@ -5,6 +5,7 @@ import React, {
|
||||
useImperativeHandle,
|
||||
} from 'react';
|
||||
import { CheckCircle, Circle } from 'lucide-react';
|
||||
import { useEstablishment } from '@/context/EstablishmentContext';
|
||||
|
||||
const TreeView = forwardRef(function TreeView(
|
||||
{ data, expandAll, onSelectionChange },
|
||||
@ -72,6 +73,8 @@ const TreeView = forwardRef(function TreeView(
|
||||
clearSelection: () => setSelectedCompetencies({}),
|
||||
}));
|
||||
|
||||
const { profileRole } = useEstablishment();
|
||||
|
||||
return (
|
||||
<div>
|
||||
{data.map((domaine) => (
|
||||
@ -112,12 +115,18 @@ const TreeView = forwardRef(function TreeView(
|
||||
? 'text-emerald-600 font-semibold cursor-pointer'
|
||||
: 'text-gray-500 cursor-pointer hover:text-emerald-600'
|
||||
}`}
|
||||
onClick={() => handleCompetenceClick(competence)}
|
||||
onClick={
|
||||
profileRole !== 0
|
||||
? () => handleCompetenceClick(competence)
|
||||
: undefined
|
||||
}
|
||||
style={{
|
||||
cursor:
|
||||
competence.state === 'required'
|
||||
? 'default'
|
||||
: 'pointer',
|
||||
: profileRole !== 0
|
||||
? 'pointer'
|
||||
: 'default',
|
||||
userSelect: 'none',
|
||||
}}
|
||||
>
|
||||
|
||||
@ -130,9 +130,7 @@ const ClassesSection = ({
|
||||
const [removePopupVisible, setRemovePopupVisible] = useState(false);
|
||||
const [removePopupMessage, setRemovePopupMessage] = useState('');
|
||||
const [removePopupOnConfirm, setRemovePopupOnConfirm] = useState(() => {});
|
||||
const [detailsModalVisible, setDetailsModalVisible] = useState(false);
|
||||
const [selectedClass, setSelectedClass] = useState(null);
|
||||
const { selectedEstablishmentId } = useEstablishment();
|
||||
const { selectedEstablishmentId, profileRole } = useEstablishment();
|
||||
const { addSchedule, reloadPlanning, reloadEvents } = usePlanning();
|
||||
const { getNiveauxLabels, allNiveaux } = useClasses();
|
||||
const router = useRouter();
|
||||
@ -449,6 +447,25 @@ const ClassesSection = ({
|
||||
case 'MISE A JOUR':
|
||||
return classe.updated_date_formatted;
|
||||
case 'ACTIONS':
|
||||
// Affichage des actions en mode affichage (hors édition/création)
|
||||
if (profileRole === 0) {
|
||||
// Si professeur, uniquement le bouton ZoomIn
|
||||
return (
|
||||
<div className="flex justify-center space-x-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
const url = `${FE_ADMIN_STRUCTURE_SCHOOLCLASS_MANAGEMENT_URL}?schoolClassId=${classe.id}`;
|
||||
router.push(`${url}`);
|
||||
}}
|
||||
className="text-gray-500 hover:text-gray-700"
|
||||
>
|
||||
<ZoomIn className="w-5 h-5" />
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
// Sinon, toutes les actions (admin)
|
||||
return (
|
||||
<div className="flex justify-center space-x-2">
|
||||
<button
|
||||
@ -534,7 +551,7 @@ const ClassesSection = ({
|
||||
icon={Users}
|
||||
title="Liste des classes"
|
||||
description="Gérez les classes de votre école"
|
||||
button={true}
|
||||
button={profileRole !== 0}
|
||||
onClick={handleAddClass}
|
||||
/>
|
||||
<Table
|
||||
|
||||
@ -29,7 +29,7 @@ const SpecialitiesSection = ({
|
||||
const [removePopupMessage, setRemovePopupMessage] = useState('');
|
||||
const [removePopupOnConfirm, setRemovePopupOnConfirm] = useState(() => {});
|
||||
|
||||
const { selectedEstablishmentId } = useEstablishment();
|
||||
const { selectedEstablishmentId, profileRole } = useEstablishment();
|
||||
|
||||
// Récupération des messages d'erreur
|
||||
const getError = (field) => {
|
||||
@ -239,7 +239,7 @@ const SpecialitiesSection = ({
|
||||
const columns = [
|
||||
{ name: 'LIBELLE', label: 'Libellé' },
|
||||
{ name: 'MISE A JOUR', label: 'Date mise à jour' },
|
||||
{ name: 'ACTIONS', label: 'Actions' },
|
||||
...(profileRole !== 0 ? [{ name: 'ACTIONS', label: 'Actions' }] : []),
|
||||
];
|
||||
|
||||
return (
|
||||
@ -249,7 +249,7 @@ const SpecialitiesSection = ({
|
||||
icon={BookOpen}
|
||||
title="Liste des spécialités"
|
||||
description="Gérez les spécialités de votre école"
|
||||
button={true}
|
||||
button={profileRole !== 0}
|
||||
onClick={handleAddSpeciality}
|
||||
/>
|
||||
<Table
|
||||
|
||||
@ -3,8 +3,7 @@ import { Edit3, Trash2, GraduationCap, Check, X, Hand } from 'lucide-react';
|
||||
import Table from '@/components/Table';
|
||||
import Popup from '@/components/Popup';
|
||||
import ToggleSwitch from '@/components/Form/ToggleSwitch';
|
||||
import { useCsrfToken } from '@/context/CsrfContext';
|
||||
import { DndProvider, useDrag, useDrop } from 'react-dnd';
|
||||
import { DndProvider, useDrop } from 'react-dnd';
|
||||
import { HTML5Backend } from 'react-dnd-html5-backend';
|
||||
import InputText from '@/components/Form/InputText';
|
||||
import SpecialityItem from '@/components/Structure/Configuration/SpecialityItem';
|
||||
@ -128,7 +127,6 @@ const TeachersSection = ({
|
||||
handleEdit,
|
||||
handleDelete,
|
||||
}) => {
|
||||
const csrfToken = useCsrfToken();
|
||||
const [editingTeacher, setEditingTeacher] = useState(null);
|
||||
const [newTeacher, setNewTeacher] = useState(null);
|
||||
const [formData, setFormData] = useState({});
|
||||
@ -140,7 +138,7 @@ const TeachersSection = ({
|
||||
const [removePopupMessage, setRemovePopupMessage] = useState('');
|
||||
const [removePopupOnConfirm, setRemovePopupOnConfirm] = useState(() => {});
|
||||
|
||||
const { selectedEstablishmentId } = useEstablishment();
|
||||
const { selectedEstablishmentId, profileRole } = useEstablishment();
|
||||
|
||||
// --- UTILS ---
|
||||
|
||||
@ -520,7 +518,7 @@ const TeachersSection = ({
|
||||
{ name: 'SPECIALITES', label: 'Spécialités' },
|
||||
{ name: 'ADMINISTRATEUR', label: 'Profil' },
|
||||
{ name: 'MISE A JOUR', label: 'Mise à jour' },
|
||||
{ name: 'ACTIONS', label: 'Actions' },
|
||||
...(profileRole !== 0 ? [{ name: 'ACTIONS', label: 'Actions' }] : []),
|
||||
];
|
||||
|
||||
return (
|
||||
@ -530,7 +528,7 @@ const TeachersSection = ({
|
||||
icon={GraduationCap}
|
||||
title="Liste des enseignants.es"
|
||||
description="Gérez les enseignants.es de votre école"
|
||||
button={true}
|
||||
button={profileRole !== 0}
|
||||
onClick={handleAddTeacher}
|
||||
/>
|
||||
<Table
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import {
|
||||
Edit,
|
||||
Trash2,
|
||||
@ -192,8 +192,8 @@ function SimpleList({
|
||||
export default function FilesGroupsManagement({
|
||||
csrfToken,
|
||||
selectedEstablishmentId,
|
||||
profileRole
|
||||
}) {
|
||||
const [showFilePreview, setShowFilePreview] = useState(false);
|
||||
const [schoolFileMasters, setSchoolFileMasters] = useState([]);
|
||||
const [parentFiles, setParentFileMasters] = useState([]);
|
||||
const [groups, setGroups] = useState([]);
|
||||
@ -211,7 +211,6 @@ export default function FilesGroupsManagement({
|
||||
const [selectedGroupId, setSelectedGroupId] = useState(null);
|
||||
const [showHelp, setShowHelp] = useState(false);
|
||||
const { showNotification } = useNotification();
|
||||
const [isFileUploadOpen, setIsFileUploadOpen] = useState(false);
|
||||
const [isParentFileModalOpen, setIsParentFileModalOpen] = useState(false);
|
||||
const [editingParentFile, setEditingParentFile] = useState(null);
|
||||
|
||||
@ -819,13 +818,15 @@ export default function FilesGroupsManagement({
|
||||
<div className="flex items-center mb-4">
|
||||
<SectionTitle title="Liste des dossiers d'inscriptions" />
|
||||
<div className="flex-1" />
|
||||
<button
|
||||
className="flex items-center justify-center bg-emerald-500 hover:bg-emerald-600 text-white px-3 py-2 rounded-lg shadow transition text-base font-semibold"
|
||||
onClick={() => setIsGroupModalOpen(true)}
|
||||
title="Créer un nouveau dossier"
|
||||
>
|
||||
<Plus className="w-5 h-5" />
|
||||
</button>
|
||||
{profileRole !== 0 && (
|
||||
<button
|
||||
className="flex items-center justify-center bg-emerald-500 hover:bg-emerald-600 text-white px-3 py-2 rounded-lg shadow transition text-base font-semibold"
|
||||
onClick={() => setIsGroupModalOpen(true)}
|
||||
title="Créer un nouveau dossier"
|
||||
>
|
||||
<Plus className="w-5 h-5" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<SimpleList
|
||||
items={groups}
|
||||
@ -865,52 +866,54 @@ export default function FilesGroupsManagement({
|
||||
<div className="flex flex-col w-2/3">
|
||||
<div className="flex items-center mb-4">
|
||||
<SectionTitle title="Liste des documents" />
|
||||
<div className="flex-1" />
|
||||
<DropdownMenu
|
||||
buttonContent={
|
||||
<span className="flex items-center">
|
||||
<Plus className="w-5 h-5" />
|
||||
<ChevronDown className="w-4 h-4 ml-1" />
|
||||
</span>
|
||||
}
|
||||
items={[
|
||||
{
|
||||
type: 'item',
|
||||
label: (
|
||||
<div className="flex-1" />
|
||||
{profileRole !== 0 && (
|
||||
<DropdownMenu
|
||||
buttonContent={
|
||||
<span className="flex items-center">
|
||||
<Star className="w-5 h-5 mr-2 text-yellow-600" />
|
||||
Formulaire personnalisé
|
||||
<Plus className="w-5 h-5" />
|
||||
<ChevronDown className="w-4 h-4 ml-1" />
|
||||
</span>
|
||||
),
|
||||
onClick: () => handleDocDropdownSelect('formulaire'),
|
||||
},
|
||||
{
|
||||
type: 'item',
|
||||
label: (
|
||||
<span className="flex items-center">
|
||||
<FileText className="w-5 h-5 mr-2 text-gray-600" />
|
||||
Formulaire existant
|
||||
</span>
|
||||
),
|
||||
onClick: () => handleDocDropdownSelect('formulaire_existant'),
|
||||
},
|
||||
{
|
||||
type: 'item',
|
||||
label: (
|
||||
<span className="flex items-center">
|
||||
<Plus className="w-5 h-5 mr-2 text-orange-500" />
|
||||
Pièce à fournir
|
||||
</span>
|
||||
),
|
||||
onClick: () => handleDocDropdownSelect('parent'),
|
||||
},
|
||||
]}
|
||||
buttonClassName="flex items-center justify-center bg-emerald-500 hover:bg-emerald-600 text-white px-3 py-2 rounded-lg shadow transition text-base font-semibold"
|
||||
menuClassName="absolute right-0 mt-2 w-56 bg-white border border-gray-200 rounded shadow-lg z-20"
|
||||
dropdownOpen={isDocDropdownOpen}
|
||||
setDropdownOpen={setIsDocDropdownOpen}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
items={[
|
||||
{
|
||||
type: 'item',
|
||||
label: (
|
||||
<span className="flex items-center">
|
||||
<Star className="w-5 h-5 mr-2 text-yellow-600" />
|
||||
Formulaire personnalisé
|
||||
</span>
|
||||
),
|
||||
onClick: () => handleDocDropdownSelect('formulaire'),
|
||||
},
|
||||
{
|
||||
type: 'item',
|
||||
label: (
|
||||
<span className="flex items-center">
|
||||
<FileText className="w-5 h-5 mr-2 text-gray-600" />
|
||||
Formulaire existant
|
||||
</span>
|
||||
),
|
||||
onClick: () => handleDocDropdownSelect('formulaire_existant'),
|
||||
},
|
||||
{
|
||||
type: 'item',
|
||||
label: (
|
||||
<span className="flex items-center">
|
||||
<Plus className="w-5 h-5 mr-2 text-orange-500" />
|
||||
Pièce à fournir
|
||||
</span>
|
||||
),
|
||||
onClick: () => handleDocDropdownSelect('parent'),
|
||||
},
|
||||
]}
|
||||
buttonClassName="flex items-center justify-center bg-emerald-500 hover:bg-emerald-600 text-white px-3 py-2 rounded-lg shadow transition text-base font-semibold"
|
||||
menuClassName="absolute right-0 mt-2 w-56 bg-white border border-gray-200 rounded shadow-lg z-20"
|
||||
dropdownOpen={isDocDropdownOpen}
|
||||
setDropdownOpen={setIsDocDropdownOpen}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
{!selectedGroupId ? (
|
||||
<div className="flex items-center justify-center h-40 text-gray-400 text-lg italic border border-gray-200 rounded bg-white">
|
||||
Sélectionner un dossier d'inscription
|
||||
|
||||
Reference in New Issue
Block a user