Files
tessera-ctl/apps/web/src/app/(portal)/settings/dashboard/page.tsx
T
schalli 2868ffee20 feat(quick-260917-gyd): Widgets-Seite uebersetzt, CHANGELOG ergaenzt
- settings/dashboard/page.tsx: Lade-/Leerhinweis ueber i18n (common.loading, settings.widgets.empty) statt hartkodiertem Englisch
- de.json/en.json: neuer Schluessel settings.widgets.empty (additiv)
- CHANGELOG.md: drei Stichpunkte unter Behoben (Ruecksprung nach Anmeldung, Abmeldung bei toter Sitzung, Uebersetzung Widgets-Seite)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 12:30:19 +02:00

56 lines
1.5 KiB
TypeScript

'use client';
import { useEffect, useState } from 'react';
import { useTranslations } from 'next-intl';
import { WidgetSettingsPanel } from '@/components/settings/widget-settings-panel';
import { fetchWidgets } from '@/lib/dashboard-api';
/**
* Settings > Dashboard > Widgets page (D-03).
* Fetches user's widget instances and renders per-instance config forms.
*/
export default function WidgetSettingsPage() {
const t = useTranslations('settings');
const tCommon = useTranslations('common');
const [widgets, setWidgets] = useState<
Array<{ id: string; widgetType: string; config: Record<string, unknown> }>
>([]);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
fetchWidgets()
.then(setWidgets)
.catch(() => {
// Silent fail — empty widget list shown
})
.finally(() => setIsLoading(false));
}, []);
return (
<div>
<h1 className="mb-6 text-lg font-semibold text-foreground">
{t('categoryWidgets')}
</h1>
{isLoading ? (
<p className="text-sm text-muted-foreground">{tCommon('loading')}</p>
) : widgets.length === 0 ? (
<p className="text-sm text-muted-foreground">
{t('widgets.empty')}
</p>
) : (
<WidgetSettingsPanel
widgets={widgets}
onWidgetUpdate={(id, config) => {
setWidgets((prev) =>
prev.map((w) =>
w.id === id ? { ...w, config: { ...w.config, ...config } } : w,
),
);
}}
/>
)}
</div>
);
}