83 lines
2.8 KiB
TypeScript
83 lines
2.8 KiB
TypeScript
/**
|
|
* Appearance section (U9 / KTD-10).
|
|
*
|
|
* Theme mode, color theme, dashboard font scale, language, and the
|
|
* session-banner suppression toggle. The three-tier device-local prefs
|
|
* (theme/language/font scale) keep their hooks in the shell — this section only
|
|
* relays their current values and change callbacks, mirroring the original
|
|
* inline JSX exactly (it both writes the modal form AND calls the write-through
|
|
* callback so the live UI updates immediately).
|
|
*/
|
|
import type { ReactNode } from "react";
|
|
import { useTranslation } from "react-i18next";
|
|
import type { ThemeMode, ColorTheme } from "@fusion/core";
|
|
import { ThemeSelector } from "../../ThemeSelector";
|
|
import { LanguageSelector } from "../../LanguageSelector";
|
|
import type { SectionBaseProps } from "./context";
|
|
|
|
export interface AppearanceSectionProps extends SectionBaseProps {
|
|
scopeBanner: ReactNode;
|
|
themeMode: ThemeMode;
|
|
colorTheme: ColorTheme;
|
|
dashboardFontScalePct: number;
|
|
onThemeModeChange?: (mode: ThemeMode) => void;
|
|
onColorThemeChange?: (theme: ColorTheme) => void;
|
|
onDashboardFontScaleChange?: (scalePct: number) => void;
|
|
sessionBannersHidden: boolean;
|
|
setSessionBannersHidden: (hidden: boolean) => void;
|
|
}
|
|
|
|
export function AppearanceSection({
|
|
scopeBanner,
|
|
setForm,
|
|
themeMode,
|
|
colorTheme,
|
|
dashboardFontScalePct,
|
|
onThemeModeChange,
|
|
onColorThemeChange,
|
|
onDashboardFontScaleChange,
|
|
sessionBannersHidden,
|
|
setSessionBannersHidden,
|
|
}: AppearanceSectionProps) {
|
|
const { t } = useTranslation("app");
|
|
return (
|
|
<>
|
|
{scopeBanner}
|
|
<h4 className="settings-section-heading">{t("settings.appearance.title", "Appearance")}</h4>
|
|
<ThemeSelector
|
|
themeMode={themeMode}
|
|
colorTheme={colorTheme}
|
|
dashboardFontScalePct={dashboardFontScalePct}
|
|
onThemeModeChange={(mode) => {
|
|
setForm((f) => ({ ...f, themeMode: mode }));
|
|
onThemeModeChange?.(mode);
|
|
}}
|
|
onColorThemeChange={(theme) => {
|
|
setForm((f) => ({ ...f, colorTheme: theme }));
|
|
onColorThemeChange?.(theme);
|
|
}}
|
|
onDashboardFontScaleChange={(scalePct) => {
|
|
setForm((f) => ({ ...f, dashboardFontScalePct: scalePct }));
|
|
onDashboardFontScaleChange?.(scalePct);
|
|
}}
|
|
/>
|
|
<LanguageSelector />
|
|
<div className="form-group">
|
|
<label className="checkbox-label">
|
|
<input
|
|
type="checkbox"
|
|
checked={sessionBannersHidden}
|
|
onChange={(e) => setSessionBannersHidden(e.target.checked)}
|
|
/>
|
|
<span>Hide AI session notification banners</span>
|
|
</label>
|
|
<small className="form-text text-muted">
|
|
Suppress the “needs your input” banner that appears when AI sessions are awaiting input or have failed.
|
|
</small>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|
|
|
|
export default AppearanceSection;
|