feat: Page Structure : suppression de la possibilité de faire des actions d'admin [N3WTS-8]

This commit is contained in:
N3WT DE COMPET
2026-02-15 18:40:14 +01:00
parent 195579e217
commit 05c68ebfaa
7 changed files with 145 additions and 112 deletions

View File

@ -52,7 +52,7 @@ export default function Page() {
); );
const csrfToken = useCsrfToken(); const csrfToken = useCsrfToken();
const { selectedEstablishmentId } = useEstablishment(); const { selectedEstablishmentId, profileRole } = useEstablishment();
useEffect(() => { useEffect(() => {
if (selectedEstablishmentId) { if (selectedEstablishmentId) {
@ -316,6 +316,8 @@ export default function Page() {
</div> </div>
), ),
}, },
...(profileRole !== 0
? [
{ {
id: 'Fees', id: 'Fees',
label: 'Tarifs', label: 'Tarifs',
@ -345,6 +347,8 @@ export default function Page() {
</div> </div>
), ),
}, },
]
: []),
{ {
id: 'Files', id: 'Files',
label: 'Documents', label: 'Documents',
@ -353,6 +357,7 @@ export default function Page() {
<FilesGroupsManagement <FilesGroupsManagement
csrfToken={csrfToken} csrfToken={csrfToken}
selectedEstablishmentId={selectedEstablishmentId} selectedEstablishmentId={selectedEstablishmentId}
profileRole={profileRole}
/> />
</div> </div>
), ),

View File

@ -7,7 +7,6 @@ import CheckBox from '@/components/Form/CheckBox';
import Button from '@/components/Form/Button'; import Button from '@/components/Form/Button';
import { useEstablishment } from '@/context/EstablishmentContext'; import { useEstablishment } from '@/context/EstablishmentContext';
import { import {
fetchEstablishmentCompetencies,
createEstablishmentCompetencies, createEstablishmentCompetencies,
deleteEstablishmentCompetencies, deleteEstablishmentCompetencies,
} from '@/app/actions/schoolAction'; } from '@/app/actions/schoolAction';
@ -44,7 +43,7 @@ export default function CompetenciesList({
3: false, 3: false,
4: false, 4: false,
}); });
const { selectedEstablishmentId } = useEstablishment(); const { selectedEstablishmentId, profileRole } = useEstablishment();
const csrfToken = useCsrfToken(); const csrfToken = useCsrfToken();
const { showNotification } = useNotification(); const { showNotification } = useNotification();
@ -280,6 +279,7 @@ export default function CompetenciesList({
</div> </div>
{/* Bouton submit centré en bas */} {/* Bouton submit centré en bas */}
<div className="flex justify-center mb-2 mt-6"> <div className="flex justify-center mb-2 mt-6">
{profileRole !== 0 && (
<Button <Button
text="Sauvegarder" text="Sauvegarder"
className={`px-6 py-2 rounded-md shadow ${ className={`px-6 py-2 rounded-md shadow ${
@ -291,6 +291,7 @@ export default function CompetenciesList({
primary primary
disabled={!hasSelection} disabled={!hasSelection}
/> />
)}
</div> </div>
{/* Légende en dessous du bouton, alignée à gauche */} {/* Légende en dessous du bouton, alignée à gauche */}
<div className="flex flex-row items-center gap-4 mb-4"> <div className="flex flex-row items-center gap-4 mb-4">

View File

@ -5,6 +5,7 @@ import React, {
useImperativeHandle, useImperativeHandle,
} from 'react'; } from 'react';
import { CheckCircle, Circle } from 'lucide-react'; import { CheckCircle, Circle } from 'lucide-react';
import { useEstablishment } from '@/context/EstablishmentContext';
const TreeView = forwardRef(function TreeView( const TreeView = forwardRef(function TreeView(
{ data, expandAll, onSelectionChange }, { data, expandAll, onSelectionChange },
@ -72,6 +73,8 @@ const TreeView = forwardRef(function TreeView(
clearSelection: () => setSelectedCompetencies({}), clearSelection: () => setSelectedCompetencies({}),
})); }));
const { profileRole } = useEstablishment();
return ( return (
<div> <div>
{data.map((domaine) => ( {data.map((domaine) => (
@ -112,12 +115,18 @@ const TreeView = forwardRef(function TreeView(
? 'text-emerald-600 font-semibold cursor-pointer' ? 'text-emerald-600 font-semibold cursor-pointer'
: 'text-gray-500 cursor-pointer hover:text-emerald-600' : 'text-gray-500 cursor-pointer hover:text-emerald-600'
}`} }`}
onClick={() => handleCompetenceClick(competence)} onClick={
profileRole !== 0
? () => handleCompetenceClick(competence)
: undefined
}
style={{ style={{
cursor: cursor:
competence.state === 'required' competence.state === 'required'
? 'default' ? 'default'
: 'pointer', : profileRole !== 0
? 'pointer'
: 'default',
userSelect: 'none', userSelect: 'none',
}} }}
> >

View File

@ -130,9 +130,7 @@ const ClassesSection = ({
const [removePopupVisible, setRemovePopupVisible] = useState(false); const [removePopupVisible, setRemovePopupVisible] = useState(false);
const [removePopupMessage, setRemovePopupMessage] = useState(''); const [removePopupMessage, setRemovePopupMessage] = useState('');
const [removePopupOnConfirm, setRemovePopupOnConfirm] = useState(() => {}); const [removePopupOnConfirm, setRemovePopupOnConfirm] = useState(() => {});
const [detailsModalVisible, setDetailsModalVisible] = useState(false); const { selectedEstablishmentId, profileRole } = useEstablishment();
const [selectedClass, setSelectedClass] = useState(null);
const { selectedEstablishmentId } = useEstablishment();
const { addSchedule, reloadPlanning, reloadEvents } = usePlanning(); const { addSchedule, reloadPlanning, reloadEvents } = usePlanning();
const { getNiveauxLabels, allNiveaux } = useClasses(); const { getNiveauxLabels, allNiveaux } = useClasses();
const router = useRouter(); const router = useRouter();
@ -449,6 +447,25 @@ const ClassesSection = ({
case 'MISE A JOUR': case 'MISE A JOUR':
return classe.updated_date_formatted; return classe.updated_date_formatted;
case 'ACTIONS': 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 ( return (
<div className="flex justify-center space-x-2"> <div className="flex justify-center space-x-2">
<button <button
@ -534,7 +551,7 @@ const ClassesSection = ({
icon={Users} icon={Users}
title="Liste des classes" title="Liste des classes"
description="Gérez les classes de votre école" description="Gérez les classes de votre école"
button={true} button={profileRole !== 0}
onClick={handleAddClass} onClick={handleAddClass}
/> />
<Table <Table

View File

@ -29,7 +29,7 @@ const SpecialitiesSection = ({
const [removePopupMessage, setRemovePopupMessage] = useState(''); const [removePopupMessage, setRemovePopupMessage] = useState('');
const [removePopupOnConfirm, setRemovePopupOnConfirm] = useState(() => {}); const [removePopupOnConfirm, setRemovePopupOnConfirm] = useState(() => {});
const { selectedEstablishmentId } = useEstablishment(); const { selectedEstablishmentId, profileRole } = useEstablishment();
// Récupération des messages d'erreur // Récupération des messages d'erreur
const getError = (field) => { const getError = (field) => {
@ -239,7 +239,7 @@ const SpecialitiesSection = ({
const columns = [ const columns = [
{ name: 'LIBELLE', label: 'Libellé' }, { name: 'LIBELLE', label: 'Libellé' },
{ name: 'MISE A JOUR', label: 'Date mise à jour' }, { name: 'MISE A JOUR', label: 'Date mise à jour' },
{ name: 'ACTIONS', label: 'Actions' }, ...(profileRole !== 0 ? [{ name: 'ACTIONS', label: 'Actions' }] : []),
]; ];
return ( return (
@ -249,7 +249,7 @@ const SpecialitiesSection = ({
icon={BookOpen} icon={BookOpen}
title="Liste des spécialités" title="Liste des spécialités"
description="Gérez les spécialités de votre école" description="Gérez les spécialités de votre école"
button={true} button={profileRole !== 0}
onClick={handleAddSpeciality} onClick={handleAddSpeciality}
/> />
<Table <Table

View File

@ -3,8 +3,7 @@ import { Edit3, Trash2, GraduationCap, Check, X, Hand } from 'lucide-react';
import Table from '@/components/Table'; import Table from '@/components/Table';
import Popup from '@/components/Popup'; import Popup from '@/components/Popup';
import ToggleSwitch from '@/components/Form/ToggleSwitch'; import ToggleSwitch from '@/components/Form/ToggleSwitch';
import { useCsrfToken } from '@/context/CsrfContext'; import { DndProvider, useDrop } from 'react-dnd';
import { DndProvider, useDrag, useDrop } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend'; import { HTML5Backend } from 'react-dnd-html5-backend';
import InputText from '@/components/Form/InputText'; import InputText from '@/components/Form/InputText';
import SpecialityItem from '@/components/Structure/Configuration/SpecialityItem'; import SpecialityItem from '@/components/Structure/Configuration/SpecialityItem';
@ -128,7 +127,6 @@ const TeachersSection = ({
handleEdit, handleEdit,
handleDelete, handleDelete,
}) => { }) => {
const csrfToken = useCsrfToken();
const [editingTeacher, setEditingTeacher] = useState(null); const [editingTeacher, setEditingTeacher] = useState(null);
const [newTeacher, setNewTeacher] = useState(null); const [newTeacher, setNewTeacher] = useState(null);
const [formData, setFormData] = useState({}); const [formData, setFormData] = useState({});
@ -140,7 +138,7 @@ const TeachersSection = ({
const [removePopupMessage, setRemovePopupMessage] = useState(''); const [removePopupMessage, setRemovePopupMessage] = useState('');
const [removePopupOnConfirm, setRemovePopupOnConfirm] = useState(() => {}); const [removePopupOnConfirm, setRemovePopupOnConfirm] = useState(() => {});
const { selectedEstablishmentId } = useEstablishment(); const { selectedEstablishmentId, profileRole } = useEstablishment();
// --- UTILS --- // --- UTILS ---
@ -520,7 +518,7 @@ const TeachersSection = ({
{ name: 'SPECIALITES', label: 'Spécialités' }, { name: 'SPECIALITES', label: 'Spécialités' },
{ name: 'ADMINISTRATEUR', label: 'Profil' }, { name: 'ADMINISTRATEUR', label: 'Profil' },
{ name: 'MISE A JOUR', label: 'Mise à jour' }, { name: 'MISE A JOUR', label: 'Mise à jour' },
{ name: 'ACTIONS', label: 'Actions' }, ...(profileRole !== 0 ? [{ name: 'ACTIONS', label: 'Actions' }] : []),
]; ];
return ( return (
@ -530,7 +528,7 @@ const TeachersSection = ({
icon={GraduationCap} icon={GraduationCap}
title="Liste des enseignants.es" title="Liste des enseignants.es"
description="Gérez les enseignants.es de votre école" description="Gérez les enseignants.es de votre école"
button={true} button={profileRole !== 0}
onClick={handleAddTeacher} onClick={handleAddTeacher}
/> />
<Table <Table

View File

@ -1,4 +1,4 @@
import React, { useState, useEffect, useRef } from 'react'; import React, { useState, useEffect } from 'react';
import { import {
Edit, Edit,
Trash2, Trash2,
@ -192,8 +192,8 @@ function SimpleList({
export default function FilesGroupsManagement({ export default function FilesGroupsManagement({
csrfToken, csrfToken,
selectedEstablishmentId, selectedEstablishmentId,
profileRole
}) { }) {
const [showFilePreview, setShowFilePreview] = useState(false);
const [schoolFileMasters, setSchoolFileMasters] = useState([]); const [schoolFileMasters, setSchoolFileMasters] = useState([]);
const [parentFiles, setParentFileMasters] = useState([]); const [parentFiles, setParentFileMasters] = useState([]);
const [groups, setGroups] = useState([]); const [groups, setGroups] = useState([]);
@ -211,7 +211,6 @@ export default function FilesGroupsManagement({
const [selectedGroupId, setSelectedGroupId] = useState(null); const [selectedGroupId, setSelectedGroupId] = useState(null);
const [showHelp, setShowHelp] = useState(false); const [showHelp, setShowHelp] = useState(false);
const { showNotification } = useNotification(); const { showNotification } = useNotification();
const [isFileUploadOpen, setIsFileUploadOpen] = useState(false);
const [isParentFileModalOpen, setIsParentFileModalOpen] = useState(false); const [isParentFileModalOpen, setIsParentFileModalOpen] = useState(false);
const [editingParentFile, setEditingParentFile] = useState(null); const [editingParentFile, setEditingParentFile] = useState(null);
@ -819,6 +818,7 @@ export default function FilesGroupsManagement({
<div className="flex items-center mb-4"> <div className="flex items-center mb-4">
<SectionTitle title="Liste des dossiers d'inscriptions" /> <SectionTitle title="Liste des dossiers d'inscriptions" />
<div className="flex-1" /> <div className="flex-1" />
{profileRole !== 0 && (
<button <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" 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)} onClick={() => setIsGroupModalOpen(true)}
@ -826,6 +826,7 @@ export default function FilesGroupsManagement({
> >
<Plus className="w-5 h-5" /> <Plus className="w-5 h-5" />
</button> </button>
)}
</div> </div>
<SimpleList <SimpleList
items={groups} items={groups}
@ -866,6 +867,7 @@ export default function FilesGroupsManagement({
<div className="flex items-center mb-4"> <div className="flex items-center mb-4">
<SectionTitle title="Liste des documents" /> <SectionTitle title="Liste des documents" />
<div className="flex-1" /> <div className="flex-1" />
{profileRole !== 0 && (
<DropdownMenu <DropdownMenu
buttonContent={ buttonContent={
<span className="flex items-center"> <span className="flex items-center">
@ -910,6 +912,7 @@ export default function FilesGroupsManagement({
dropdownOpen={isDocDropdownOpen} dropdownOpen={isDocDropdownOpen}
setDropdownOpen={setIsDocDropdownOpen} setDropdownOpen={setIsDocDropdownOpen}
/> />
)}
</div> </div>
{!selectedGroupId ? ( {!selectedGroupId ? (
<div className="flex items-center justify-center h-40 text-gray-400 text-lg italic border border-gray-200 rounded bg-white"> <div className="flex items-center justify-center h-40 text-gray-400 text-lg italic border border-gray-200 rounded bg-white">