feat: Réorganiser la navigation admin en catégories pour améliorer l'UX mobile-first
Le menu d'administration contenait 13 liens à plat dans le header, ce qui débordait sur desktop et rendait le drawer mobile trop long à scanner. Les liens sont maintenant regroupés en 4 catégories (Personnes, Organisation, Année scolaire, Paramètres) avec des dropdowns au survol sur desktop et des accordéons repliables dans le drawer mobile. Le nombre d'éléments visibles passe de 13 à 5 (1 lien direct + 4 catégories), la catégorie active s'auto-déplie dans le menu mobile.
This commit is contained in:
@@ -119,6 +119,7 @@ test.describe('Admin Responsive Navigation', () => {
|
||||
const drawer = page.locator('[role="dialog"][aria-modal="true"]');
|
||||
await expect(drawer).toBeVisible();
|
||||
|
||||
// Active category "Personnes" should be auto-expanded
|
||||
const activeLink = drawer.locator('.mobile-nav-link.active');
|
||||
await expect(activeLink).toHaveText('Utilisateurs');
|
||||
});
|
||||
@@ -128,11 +129,13 @@ test.describe('Admin Responsive Navigation', () => {
|
||||
await page.goto(`${ALPHA_URL}/admin/users`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
// Open menu and click Classes
|
||||
// Open menu and expand "Organisation" section to find "Classes"
|
||||
await page.getByRole('button', { name: /ouvrir le menu/i }).click();
|
||||
const drawer = page.locator('[role="dialog"][aria-modal="true"]');
|
||||
await expect(drawer).toBeVisible();
|
||||
|
||||
// Expand "Organisation" accordion
|
||||
await drawer.getByRole('button', { name: 'Organisation' }).click();
|
||||
await drawer.getByRole('link', { name: 'Classes' }).click();
|
||||
|
||||
// Menu should close and page should navigate
|
||||
@@ -143,6 +146,30 @@ test.describe('Admin Responsive Navigation', () => {
|
||||
const label = page.locator('.mobile-section-label');
|
||||
await expect(label).toHaveText('Classes');
|
||||
});
|
||||
|
||||
test('accordion sections expand and collapse', async ({ page }) => {
|
||||
await loginAsAdmin(page);
|
||||
await page.goto(`${ALPHA_URL}/admin/users`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
await page.getByRole('button', { name: /ouvrir le menu/i }).click();
|
||||
const drawer = page.locator('[role="dialog"][aria-modal="true"]');
|
||||
await expect(drawer).toBeVisible();
|
||||
|
||||
// "Personnes" should be auto-expanded (active category)
|
||||
await expect(drawer.getByRole('link', { name: 'Utilisateurs' })).toBeVisible();
|
||||
|
||||
// "Organisation" should be collapsed initially
|
||||
await expect(drawer.getByRole('link', { name: 'Classes' })).not.toBeVisible();
|
||||
|
||||
// Expand "Organisation"
|
||||
await drawer.getByRole('button', { name: 'Organisation' }).click();
|
||||
await expect(drawer.getByRole('link', { name: 'Classes' })).toBeVisible();
|
||||
|
||||
// Collapse "Organisation"
|
||||
await drawer.getByRole('button', { name: 'Organisation' }).click();
|
||||
await expect(drawer.getByRole('link', { name: 'Classes' })).not.toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
// =========================================================================
|
||||
@@ -163,7 +190,7 @@ test.describe('Admin Responsive Navigation', () => {
|
||||
await expect(desktopNav).not.toBeVisible();
|
||||
});
|
||||
|
||||
test('drawer opens and works', async ({ page }) => {
|
||||
test('drawer opens and shows grouped nav', async ({ page }) => {
|
||||
await loginAsAdmin(page);
|
||||
await page.goto(`${ALPHA_URL}/admin/users`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
@@ -172,8 +199,11 @@ test.describe('Admin Responsive Navigation', () => {
|
||||
const drawer = page.locator('[role="dialog"][aria-modal="true"]');
|
||||
await expect(drawer).toBeVisible();
|
||||
|
||||
// All nav links should be visible in drawer
|
||||
// "Personnes" auto-expanded (contains active link Utilisateurs)
|
||||
await expect(drawer.getByRole('link', { name: 'Utilisateurs' })).toBeVisible();
|
||||
|
||||
// Expand "Organisation" to see its links
|
||||
await drawer.getByRole('button', { name: 'Organisation' }).click();
|
||||
await expect(drawer.getByRole('link', { name: 'Classes' })).toBeVisible();
|
||||
await expect(drawer.getByRole('link', { name: 'Matières' })).toBeVisible();
|
||||
});
|
||||
@@ -197,18 +227,42 @@ test.describe('Admin Responsive Navigation', () => {
|
||||
await expect(desktopNav).toBeVisible();
|
||||
});
|
||||
|
||||
test('desktop nav shows all navigation links', async ({ page }) => {
|
||||
test('desktop nav shows category dropdowns', async ({ page }) => {
|
||||
await loginAsAdmin(page);
|
||||
await page.goto(`${ALPHA_URL}/admin/users`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
const nav = page.locator('.desktop-nav');
|
||||
await expect(nav.getByRole('link', { name: 'Utilisateurs' })).toBeVisible();
|
||||
await expect(nav.getByRole('link', { name: 'Classes' })).toBeVisible();
|
||||
await expect(nav.getByRole('link', { name: 'Matières' })).toBeVisible();
|
||||
await expect(nav.getByRole('link', { name: 'Affectations' })).toBeVisible();
|
||||
await expect(nav.getByRole('link', { name: 'Périodes' })).toBeVisible();
|
||||
await expect(nav.getByRole('link', { name: 'Pédagogie' })).toBeVisible();
|
||||
|
||||
// Category triggers should be visible
|
||||
await expect(nav.getByRole('button', { name: /personnes/i })).toBeVisible();
|
||||
await expect(nav.getByRole('button', { name: /organisation/i })).toBeVisible();
|
||||
await expect(nav.getByRole('button', { name: /année scolaire/i })).toBeVisible();
|
||||
await expect(nav.getByRole('button', { name: /paramètres/i })).toBeVisible();
|
||||
|
||||
// Hover "Personnes" to reveal dropdown
|
||||
await nav.getByRole('button', { name: /personnes/i }).hover();
|
||||
const dropdown = nav.locator('.dropdown-panel').first();
|
||||
await expect(dropdown).toBeVisible();
|
||||
await expect(dropdown.getByRole('menuitem', { name: 'Utilisateurs' })).toBeVisible();
|
||||
await expect(dropdown.getByRole('menuitem', { name: 'Élèves' })).toBeVisible();
|
||||
|
||||
// Hover "Organisation"
|
||||
await nav.getByRole('button', { name: /organisation/i }).hover();
|
||||
const orgDropdown = nav.locator('.dropdown-panel').first();
|
||||
await expect(orgDropdown.getByRole('menuitem', { name: 'Classes' })).toBeVisible();
|
||||
await expect(orgDropdown.getByRole('menuitem', { name: 'Matières' })).toBeVisible();
|
||||
await expect(orgDropdown.getByRole('menuitem', { name: 'Affectations' })).toBeVisible();
|
||||
});
|
||||
|
||||
test('active category trigger is highlighted', async ({ page }) => {
|
||||
await loginAsAdmin(page);
|
||||
await page.goto(`${ALPHA_URL}/admin/users`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
const nav = page.locator('.desktop-nav');
|
||||
const personnesTrigger = nav.getByRole('button', { name: /personnes/i });
|
||||
await expect(personnesTrigger).toHaveClass(/active/);
|
||||
});
|
||||
|
||||
test('hides mobile section label', async ({ page }) => {
|
||||
|
||||
Reference in New Issue
Block a user