feat(05-02): add widget settings panel with search provider form
- Settings > Dashboard page with per-widget-instance config
- Clock config: timezone select (IANA list) + date toggle (D-12/D-13)
- Note config: editable title field (D-17)
- Search config: SearchProviderForm with add/delete and {query} validation (D-15)
- Calendar config: link to calendar-specific settings
- i18n keys for search provider management (en + de)
- Fix useRef initialization for React 19 strict mode (note-widget)
- Fix unknown type narrowing in widget title display
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
'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 [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">Loading...</p>
|
||||
) : widgets.length === 0 ? (
|
||||
<p className="text-sm text-muted-foreground">
|
||||
No widgets placed on dashboard yet.
|
||||
</p>
|
||||
) : (
|
||||
<WidgetSettingsPanel
|
||||
widgets={widgets}
|
||||
onWidgetUpdate={(id, config) => {
|
||||
setWidgets((prev) =>
|
||||
prev.map((w) =>
|
||||
w.id === id ? { ...w, config: { ...w.config, ...config } } : w,
|
||||
),
|
||||
);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user