"use client"; /** * Settings > System > Preview features. * * One switch per preview feature, each off until the person turns it on, each * saved the moment it changes (`PATCH /api/settings/preview-features`). A * preview adds something beside what is there and never replaces a page. * * The `topics` flag is stored and shown here; the topic overview pages that * read it arrive in a later release, and the card says so rather than * promising a change the switch does not make yet. */ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import Link from "next/link"; import { LayoutDashboard } from "lucide-react"; import { toastWrittenOutcome } from "@/components/outcome/outcome-toast"; import { SettingsCard } from "@/components/settings/settings-card"; import { SettingsCardHeader } from "@/components/settings/_card-header"; import { InlineAction } from "@/components/ui/inline-action"; import { QueryErrorRow } from "@/components/ui/query-error-row"; import { Switch } from "@/components/ui/switch"; import { apiGet, apiPatch } from "@/lib/api/api-fetch"; import { showErrorToast } from "@/lib/errors/error-toast"; import { useTranslations } from "@/lib/i18n/context"; import { queryKeys } from "@/lib/query-keys"; import { DEFAULT_PREVIEW_FEATURES, type PreviewFeatures, } from "@/lib/settings/preview-features"; const DISCUSSIONS_URL = "https://github.com/MBombeck/HealthLog/discussions"; export function PreviewSection() { const { t } = useTranslations(); const queryClient = useQueryClient(); const key = queryKeys.previewFeatures(); const query = useQuery({ queryKey: key, queryFn: () => apiGet("/api/settings/preview-features"), }); const features = query.data ?? DEFAULT_PREVIEW_FEATURES; const toggle = useMutation({ mutationKey: key, mutationFn: (topics: boolean) => apiPatch("/api/settings/preview-features", { topics }), onMutate: async (topics) => { await queryClient.cancelQueries({ queryKey: key }); const previous = queryClient.getQueryData(key); queryClient.setQueryData(key, { ...(previous ?? DEFAULT_PREVIEW_FEATURES), topics, }); return { previous }; }, onSuccess: (saved, topics) => { if (saved) queryClient.setQueryData(key, saved); toastWrittenOutcome( "success", topics ? t("settings.preview.topics.savedOn") : t("settings.preview.topics.savedOff"), ); }, onError: (failure, _topics, context) => { queryClient.setQueryData(key, context?.previous); showErrorToast(t("settings.savingError"), { cause: failure }); }, }); return ( toggle.mutate(next)} aria-labelledby="settings-preview-topics-title" /> } /> {query.isError ? ( void query.refetch()} /> ) : null}

{t("settings.preview.topics.detail")}

{t("settings.preview.feedbackLink")}

); }