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
This commit was merged in pull request #148.
This commit is contained in:
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!-- Generator: Gravitdesign.com --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="0 0 1024 1024" width="1024pt" height="1024pt"><defs><clipPath id="_clipPath_B4TZ570FigxU4c50hle9QrZwbv6YvFBZ"><rect width="1024" height="1024"/></clipPath></defs><g clip-path="url(#_clipPath_B4TZ570FigxU4c50hle9QrZwbv6YvFBZ)"><path d=" M 302.7 566.118 C 355.817 515.422 427.036 483.173 501.691 480.62 C 626.026 477.14 721.654 557.185 738.018 669.829 C 734.571 656.604 628.618 409.16 302.701 566.118 L 302.7 566.118 Z " fill="rgb(255, 255, 255)"/><g><path d=" M 732.849 505.91 C 675.421 450.11 499.114 228.071 514.048 161.831 C 530.416 89.558 636.371 30.51 735.43 0 C 719.64 2.552 706.724 5.104 694.661 8.585 C 586.122 37.355 472.984 99.302 454.893 175.868 C 439.96 241.297 498.247 315.31 562.572 378.65 C 584.25 400.069 569.598 402.126 540.415 406.219 C 515.859 409.664 481.014 414.554 448.867 433.637 C 527.084 402.036 655.737 470.669 711.434 500.382 C 735.478 513.208 745.922 518.782 732.849 505.91 L 732.849 505.91 Z " fill="rgb(255, 255, 255)"/><path d=" M 711.885 266.354 C 737.15 226.331 785.688 206.494 821.289 222.039 C 856.897 237.816 865.799 283.06 841.394 323.894 C 816.989 363.917 768.451 384.102 732.85 368.325 C 697.242 352.78 687.774 307.538 711.885 266.354 Z " fill="rgb(255, 255, 255)"/><path d=" M 307.282 582.591 C 617.41 441.409 727.668 675.86 732.836 700.109 C 735.416 720.173 735.416 742.1 731.969 763.679 C 711.878 907.414 578.07 1024 433.052 1024 C 288.045 1024 187.249 907.414 207.353 763.679 C 217.694 693.146 255.022 629.459 307.282 582.591 L 307.282 582.591 Z M 450.565 937.11 C 546.769 937.11 636.357 859.614 649.278 763.679 C 663.344 668.089 595.583 590.364 499.101 590.364 C 467.005 590.364 435.702 598.966 407.73 613.965 C 388.702 624.169 371.215 637.334 356.069 652.766 C 326.553 682.839 305.925 721.522 300.1 763.679 C 286.323 859.614 354.084 937.11 450.566 937.11 L 450.565 937.11 Z " fill-rule="evenodd" fill="rgb(255, 255, 255)"/></g></g></svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 11 KiB |
@@ -1,5 +1,13 @@
|
||||
<header class="admin-header">
|
||||
<a class="brand" routerLink="/">
|
||||
<img
|
||||
src="logos/apf-logo.svg"
|
||||
alt=""
|
||||
aria-hidden="true"
|
||||
width="28"
|
||||
height="28"
|
||||
class="brand-logo"
|
||||
/>
|
||||
<span class="brand-wordmark">APF Portal</span>
|
||||
<span class="brand-badge">Admin</span>
|
||||
</a>
|
||||
|
||||
@@ -30,6 +30,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
.brand-logo {
|
||||
display: block;
|
||||
flex-shrink: 0;
|
||||
height: 1.75rem;
|
||||
width: 1.75rem;
|
||||
}
|
||||
|
||||
// "Admin" pill — distinct color from the wordmark so it reads as a
|
||||
// status badge even in dense headers. Keeps the surface
|
||||
// immediately recognisable per ADR-0020 §"Discoverability for
|
||||
|
||||
@@ -1,18 +1,28 @@
|
||||
.admin-sidebar {
|
||||
// The host element owns the sidebar envelope (width + chrome) so
|
||||
// the gray background + right border cover the full column, not
|
||||
// just the rail of links. The inner <nav> handles the scrolling
|
||||
// list inside that envelope.
|
||||
:host {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 16rem;
|
||||
flex: 0 0 16rem;
|
||||
background-color: #f3f4f6;
|
||||
border-right: 1px solid #e5e7eb;
|
||||
padding: 0.75rem 0;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
:host-context(.dark) .admin-sidebar {
|
||||
:host-context(.dark) {
|
||||
background-color: #0f172a;
|
||||
border-right-color: #1f2937;
|
||||
color: #e5e7eb;
|
||||
}
|
||||
|
||||
.admin-sidebar {
|
||||
flex: 1 1 auto;
|
||||
padding: 0.75rem 0;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.nav-list {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
|
||||
Reference in New Issue
Block a user