style(web): Reiter zurueck in die Kopfzeile, Begruessung in die Seitenleiste

Rueckmeldung Runde 3: die Reiter in der Seitenleiste gefallen nicht -
zurueck auf den Stand vor 8532b63 (Umschalter in der Kopfzeile). Statt
dessen sitzt die Begruessung jetzt zweizeilig im sonst leeren unteren
Bereich der Seitenleiste ueber "Einklappen"; ueber den Kacheln bleibt nur
die Befehlsleiste rechts.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-28 16:05:34 +02:00
parent 8532b63097
commit 8440db8c6e
8 changed files with 49 additions and 259 deletions
@@ -4,10 +4,3 @@
* zeichnen per `createPortal` hinein (heute: die Dashboard-Reiter).
*/
export const HEADER_CENTER_SLOT_ID = 'header-center-slot';
/**
* Einhaengepunkt unter „Dashboard“ in der Seitenleiste (Design „Mosaik“,
* Runde 3). Nur in der aufgeklappten Seitenleiste am Desktop vorhanden; dort
* zeichnen die Dashboard-Reiter hinein, sonst in {@link HEADER_CENTER_SLOT_ID}.
*/
export const SIDEBAR_DASHBOARD_SLOT_ID = 'sidebar-dashboard-slot';
@@ -66,6 +66,10 @@ vi.mock('@/components/layout/sidebar-footer', () => ({
// Das Abzeichen ruft `loadApiVersion()` und damit `fetch` — ohne Modul-Mock
// bekaeme es das Modul-Array aus `stubFetch()` (quick-260914-ku1).
vi.mock('@/components/dashboard/dashboard-greeting', () => ({
DashboardGreeting: () => <div data-testid="dashboard-greeting" />,
}));
vi.mock('@/components/layout/app-version-badge', () => ({
AppVersionBadge: () => <div data-testid="app-version-badge" />,
}));
+12 -10
View File
@@ -12,7 +12,7 @@ import { AppVersionBadge } from '@/components/layout/app-version-badge';
import { ModuleTile } from '@/components/modules/module-tile';
import { useCategoryLabel } from '@/lib/use-category-label';
import { useNavStore } from '@/lib/stores/nav-store';
import { SIDEBAR_DASHBOARD_SLOT_ID } from '@/components/layout/header-slot';
import { DashboardGreeting } from '@/components/dashboard/dashboard-greeting';
/** Fluent-Auswahlmarke: 3 x 16 px Pille am linken Rand des gewaehlten Eintrags. */
function SelectionPill() {
@@ -129,10 +129,7 @@ export function Sidebar() {
</svg>
);
// `inDrawer`: die mobile Schublade rendert denselben Inhalt ein zweites
// Mal — der Einhaengepunkt der Dashboard-Reiter darf nur einmal im DOM
// stehen und gehoert zur Desktop-Leiste.
const renderContent = (inDrawer: boolean) => (
const sidebarContent = (
<div className="flex h-full flex-col bg-sidebar">
<nav className={`flex-1 overflow-y-auto py-3 ${isCollapsed ? 'px-2' : 'px-3'}`}>
<ul className="flex flex-col gap-0.5">
@@ -149,9 +146,6 @@ export function Sidebar() {
)}
{!isCollapsed && <span className="truncate">{t('dashboard')}</span>}
</Link>
{/* Dashboard-Reiter (Runde 3): `DashboardTabs` zeichnet per Portal
hierher, der Punkt bleibt im React-Baum der Leiste leer. */}
{!inDrawer && !isCollapsed && <div id={SIDEBAR_DASHBOARD_SLOT_ID} />}
</li>
<li>
<Link href="/marketplace" className={linkClass('/marketplace')} aria-label={t('marketplace')} title={isCollapsed ? t('marketplace') : undefined}>
@@ -245,6 +239,14 @@ export function Sidebar() {
)}
</nav>
{/* Begruessung (Design „Mosaik“, Runde 3): im sonst leeren unteren
Bereich der Leiste statt ueber den Kacheln; eingeklappt entfaellt sie. */}
{!isCollapsed && (
<div className="border-t border-sidebar-border px-5 py-2.5">
<DashboardGreeting />
</div>
)}
<div className="hidden border-t border-sidebar-border px-3 py-2 md:block">
<button
type="button"
@@ -282,7 +284,7 @@ export function Sidebar() {
: 'var(--sidebar-width)',
}}
>
{renderContent(false)}
{sidebarContent}
</aside>
{isMobileOpen && (
@@ -314,7 +316,7 @@ export function Sidebar() {
</svg>
</button>
</div>
<div className="min-h-0 flex-1">{renderContent(true)}</div>
<div className="min-h-0 flex-1">{sidebarContent}</div>
</aside>
</div>
)}