2868ffee20
- 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>
56 lines
1.5 KiB
TypeScript
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>
|
|
);
|
|
}
|