Files
jobtrackingapp/job-tracker-ui/src/components/AiPrivacySettingsCard.tsx
T

75 lines
2.8 KiB
TypeScript

import React, { useEffect, useState } from "react";
import { Alert, Box, Button, FormControlLabel, Skeleton, Switch, Typography } from "@mui/material";
import { PageSection } from "../layout/PageLayout";
import { api } from "../api";
import { useI18n } from "../i18n/I18nProvider";
import { useToast } from "../toast";
type AiSettings = {
enabled: boolean;
externalProcessingAllowed: boolean;
externalProcessingAvailable: boolean;
effectiveExternalProcessing: boolean;
provider: string;
};
export default function AiPrivacySettingsCard() {
const { t } = useI18n();
const { toast } = useToast();
const [settings, setSettings] = useState<AiSettings | null>(null);
const [failed, setFailed] = useState(false);
const [saving, setSaving] = useState(false);
useEffect(() => {
let active = true;
api.get<AiSettings>("/ai/settings")
.then((response) => { if (active) setSettings(response.data); })
.catch(() => { if (active) setFailed(true); });
return () => { active = false; };
}, []);
const save = async () => {
if (!settings) return;
setSaving(true);
setFailed(false);
try {
const response = await api.put<AiSettings>("/ai/settings", {
enabled: settings.enabled,
externalProcessingAllowed: settings.externalProcessingAllowed,
});
setSettings(response.data);
toast(t("settingsAiSaved"), "success");
} catch {
setFailed(true);
} finally {
setSaving(false);
}
};
return (
<PageSection surface title={t("settingsAiPrivacyTitle")} description={t("settingsAiPrivacyBody")}>
{failed ? <Alert severity="error" sx={{ mb: 1.5 }}>{t("settingsAiPrivacyUnavailable")}</Alert> : null}
{!settings ? <Skeleton variant="rounded" height={96} /> : <Box sx={{ display: "grid", gap: 1 }}>
<FormControlLabel
control={<Switch checked={settings.enabled} onChange={(event) => setSettings({ ...settings, enabled: event.target.checked })} />}
label={t("settingsAiEnabled")}
/>
<FormControlLabel
control={<Switch
checked={settings.externalProcessingAllowed}
disabled={!settings.externalProcessingAvailable && !settings.externalProcessingAllowed}
onChange={(event) => setSettings({ ...settings, externalProcessingAllowed: event.target.checked })}
/>}
label={t("settingsAiExternalAllowed")}
/>
<Typography variant="caption" sx={{ color: "text.secondary" }}>
{settings.externalProcessingAvailable
? t("settingsAiExternalAvailable")
: t("settingsAiExternalLocalOnly")}
</Typography>
<Box><Button variant="contained" disabled={saving} onClick={() => void save()}>{t("settingsAiSave")}</Button></Box>
</Box>}
</PageSection>
);
}