Management und Administration koennen oben rechts eine Frage in Worten stellen - "wie viele Stunden im August", "welches Projekt hat noch Budget", "wie ist die Auslastung". Aufbau: das Modell bekommt eine Uebersicht (Kunden, laufende Projekte, Eckdaten) und vier Werkzeuge - auswertung, projekte, buchungen, personen. Damit fragt es gezielt nach, statt dass ihm der ganze Bestand vorgelegt wird; 19.000 Buchungen passen in keinen Kontext. Die Werkzeuge rechnen mit loadEntries und loadProjects, also mit denselben Funktionen wie die Reports - der Assistent kann so keine zweite Wahrheit erzeugen. Was einfliesst, begrenzt visibleUserIds wie ueberall sonst. Benutzt wird die Responses-API von OpenAI: die neueren Modelle nehmen Werkzeuge in /v1/chat/completions nur ohne Nachdenken an. Mit "store: false" bleibt nichts bei OpenAI liegen, der Verlauf geht deshalb je Runde komplett mit. Der Schluessel liegt verschluesselt in den Einstellungen (AES-256-GCM wie das SSO-Secret) und wird nie ausgeliefert; das Modell ist einstellbar, Vorgabe gpt-5.6-luna. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
73 lines
3.0 KiB
TypeScript
73 lines
3.0 KiB
TypeScript
import React from 'react';
|
|
import { useTheme } from '../../lib/theme';
|
|
import { THEME_PALETTES, THEME_PALETTE_LABELS } from '../../types';
|
|
import { Icon } from '../ui/Icon';
|
|
import { PulseMark } from './PulseMark';
|
|
import { Assistant } from '../assistant/Assistant';
|
|
|
|
interface HeaderProps {
|
|
title: string;
|
|
subtitle?: string;
|
|
onToggleSidebar: () => void;
|
|
isMobile: boolean;
|
|
}
|
|
|
|
export const Header: React.FC<HeaderProps> = ({ title, subtitle, onToggleSidebar, isMobile }) => {
|
|
const { theme, preference, toggle, useSystem, palette, setPalette } = useTheme();
|
|
const isDark = theme === 'dark';
|
|
|
|
return (
|
|
/* Feste Hoehe (--app-bar-height), damit die Seitenleiste bündig anschließt. */
|
|
<header className="app-header relative flex h-[var(--app-bar-height)] shrink-0 items-center gap-3 border-b border-ink-200 bg-surface px-4 md:px-6">
|
|
{isMobile ? (
|
|
<PulseMark size={34} />
|
|
) : (
|
|
<button
|
|
onClick={onToggleSidebar}
|
|
className="rounded-lg p-2 text-ink-500 transition hover:bg-ink-100 hover:text-ink-800"
|
|
title="Menü ein-/ausklappen"
|
|
aria-label="Menü ein-/ausklappen"
|
|
>
|
|
<Icon name="menu" strokeWidth={2} />
|
|
</button>
|
|
)}
|
|
|
|
<div className="min-w-0 flex-1">
|
|
<h1 className="truncate text-lg leading-tight text-ink-900">{title}</h1>
|
|
{subtitle && <p className="truncate text-xs font-semibold text-ink-400">{subtitle}</p>}
|
|
</div>
|
|
|
|
<div className="flex shrink-0 items-center gap-2">
|
|
{/* Nur Management und Administration - zeigt Zahlen ueber alle Mitarbeiter. */}
|
|
<Assistant />
|
|
<label className="sr-only" htmlFor="theme-palette">
|
|
Design
|
|
</label>
|
|
<select
|
|
id="theme-palette"
|
|
value={palette}
|
|
onChange={(event) => setPalette(event.target.value as typeof palette)}
|
|
title={`Design: ${THEME_PALETTE_LABELS[palette].hint}`}
|
|
className="max-w-[110px] rounded-xl border border-ink-200 bg-surface px-2.5 py-2 text-xs font-bold text-ink-600 outline-none transition hover:border-brand-300 hover:text-brand-700 focus:border-brand-500 sm:max-w-none sm:px-3"
|
|
>
|
|
{THEME_PALETTES.map((option) => (
|
|
<option key={option} value={option}>
|
|
{THEME_PALETTE_LABELS[option].name}
|
|
</option>
|
|
))}
|
|
</select>
|
|
<button
|
|
onClick={toggle}
|
|
onDoubleClick={useSystem}
|
|
title={`${isDark ? 'Helles' : 'Dunkles'} Design${preference === null ? ' (folgt dem System)' : ' · Doppelklick: dem System folgen'}`}
|
|
aria-label={`${isDark ? 'Helles' : 'Dunkles'} Design einschalten`}
|
|
className="flex items-center gap-2 rounded-xl border border-ink-200 px-2.5 py-2 text-xs font-bold text-ink-600 transition hover:border-brand-300 hover:text-brand-700 sm:px-3"
|
|
>
|
|
<Icon name={isDark ? 'sun' : 'moon'} className="h-4 w-4" />
|
|
<span className="hidden lg:inline">{isDark ? 'Hell' : 'Dunkel'}</span>
|
|
</button>
|
|
</div>
|
|
</header>
|
|
);
|
|
};
|