Files
julien e3e7800ecb
CI / scan (push) Successful in 2m0s
CI / commits (push) Has been skipped
CI / check (push) Successful in 2m35s
CI / a11y (push) Successful in 2m4s
CI / perf (push) Successful in 3m44s
feat(portal-admin): header brand logo + sidebar background covers full column (#148)
## Summary

Two small portal-admin polish items so the admin shell stops looking like a scaffold:

1. **APF mark in the header**, before the `APF Portal` wordmark — same lock-up portal-shell already ships.
2. **Sidebar gray background + right border now cover the entire column**, not just the rail of nav links.

## What lands

### Header — brand logo

[`apps/portal-admin/src/app/components/header/header.html`](apps/portal-admin/src/app/components/header/header.html) — `<img>` slipped in before the wordmark inside the `.brand` flex row:

```html
<img src="logos/apf-logo.svg" alt="" aria-hidden="true" width="28" height="28" class="brand-logo" />
```

The image is **decorative**: `alt=""` + `aria-hidden="true"`. The accessible name of the brand link is already carried by `APF Portal` + the `Admin` badge — adding a non-empty `alt` here would just produce noise for screen-reader users (WCAG 1.1.1 / Decorative images).

Sized at 28×28 (1.75rem) to keep the lock-up proportionate to the admin header's compact 3.5rem height — portal-shell uses 36×36 in a 4rem header. The new `.brand-logo` SCSS rule pins `display: block; flex-shrink: 0; height/width: 1.75rem` so the SVG can't be squashed by other header content.

### Sidebar — full-column chrome

[`apps/portal-admin/src/app/components/sidebar/sidebar.scss`](apps/portal-admin/src/app/components/sidebar/sidebar.scss) — the gray background and right border move from the inner `<nav class="admin-sidebar">` to `:host` (i.e. the `<app-admin-sidebar>` element itself). Result: the chrome covers the whole flex column, not just the area the link list occupies.

Three things had to move together for the visual to land:

- **`background-color` + `border-right`** — what the user asked for.
- **`width: 16rem` + `flex: 0 0 16rem`** — the host is the direct flex child of `.shell-body`; sizing must live on the flex item, not on a grandchild.
- **`display: flex; flex-direction: column`** — Angular custom elements default to `display: inline`. Without an explicit display, background and border don't render on the host, regardless of the parent's `align-items: stretch`.

The inner `<nav>` now keeps just its content concerns: `padding` for the list breathing room, `overflow-y: auto` for the scroll, and `flex: 1 1 auto` so it grows to fill the host envelope.

Dark-mode variants follow the same move — `:host-context(.dark)` swaps the host's background + border-color directly.

### Assets

`apps/portal-admin/public/logos/{apf-logo.svg, apf-portal.svg}` mirror the portal-shell `public/logos/` layout; Angular's build pipeline picks them up at `/logos/*` per the standard static-asset convention.

## Test plan

- [x] `pnpm nx test portal-admin` — **45 specs pass**, unchanged. Header spec asserts on `.brand-wordmark` + `.brand-badge` (untouched); sidebar spec asserts on the `<nav>` landmark + RouterLinks (also untouched).
- [x] `pnpm nx lint portal-admin` — clean.
- [x] `pnpm nx build portal-admin` — clean; lazy chunks unchanged (`audit` 4.35 KB gzip, `users` 3.76 KB gzip).
- [ ] Visual smoke in dev — sign in, confirm the APF mark renders to the left of the wordmark, then navigate to `/audit` and `/users` and confirm the gray background + right border extend the full height of the sidebar column.

---------

Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr>
Reviewed-on: #148
2026-05-15 13:59:16 +02:00

2.0 KiB