"use client"; import { useState } from "react"; import type { HousekeepingResult, HousekeepingWidgetDefinition, } from "../contracts"; import type { HousekeepingPreferences } from "../preferences/schema"; export type HousekeepingPreferenceSaver = ( preferences: HousekeepingPreferences, ) => Promise>; export function toggleOptionalWidget( preferences: HousekeepingPreferences, widgetId: string, ): HousekeepingPreferences { const enabled = preferences.enabledOptionalWidgetIds.includes(widgetId); return { ...preferences, widgetOrder: !enabled && !preferences.widgetOrder.includes(widgetId) ? [...preferences.widgetOrder, widgetId] : [...preferences.widgetOrder], enabledOptionalWidgetIds: enabled ? preferences.enabledOptionalWidgetIds.filter((id) => id !== widgetId) : [...preferences.enabledOptionalWidgetIds, widgetId], }; } export function preferencesAfterSave( current: HousekeepingPreferences, _proposed: HousekeepingPreferences, result: HousekeepingResult, ): { preferences: HousekeepingPreferences; error?: string } { return result.ok ? { preferences: result.data } : { preferences: current, error: result.error.messageKey }; } export interface WidgetSettingsLabels { readonly title: string; readonly mandatory: string; readonly error: string; } export function WidgetSettings({ preferences: initialPreferences, widgets, savePreferences, labels, titles = {}, }: { readonly preferences: HousekeepingPreferences; readonly widgets: readonly HousekeepingWidgetDefinition[]; readonly savePreferences: HousekeepingPreferenceSaver; readonly labels: WidgetSettingsLabels; readonly titles?: Readonly>; }) { const [preferences, setPreferences] = useState(initialPreferences); const [savingId, setSavingId] = useState(null); const [error, setError] = useState(null); const toggle = async (widgetId: string) => { const proposed = toggleOptionalWidget(preferences, widgetId); setSavingId(widgetId); setError(null); try { const outcome = preferencesAfterSave( preferences, proposed, await savePreferences(proposed), ); setPreferences(outcome.preferences); setError(outcome.error ?? null); } catch { setError(labels.error); } finally { setSavingId(null); } }; return (

{labels.title}

{error ? (

{error === labels.error ? error : labels.error}

) : null}
    {widgets.map((widget) => { const mandatory = widget.kind === "mandatory"; const checked = mandatory || preferences.enabledOptionalWidgetIds.includes(widget.id); return (
  • {mandatory ? ( {labels.mandatory} ) : null}
  • ); })}
); }