import React, { useEffect, useMemo, useState } from "react"; import { Box, Button, Checkbox, FormControl, FormControlLabel, InputLabel, MenuItem, Paper, Popover, Select, Tab, Tabs, TextField, Typography, } from "@mui/material"; import { useNavigate } from "react-router-dom"; import { JobTableColumns } from "./JobTable"; import ImportExportJobs from "./ImportExportJobs"; import GoogleAuthCard from "./GoogleAuthCard"; import EmailProviderConnections from "./EmailProviderConnections"; import RulesSettingsCard from "./RulesSettingsCard"; import BackupCard from "./BackupCard"; import QuickCaptureCard from "./QuickCaptureCard"; import AuthStatusCard from "./AuthStatusCard"; import { ThemeModePref } from "../themePrefs"; import { useI18n } from "../i18n/I18nProvider"; interface Props { pageSize: 15 | 20 | 25; onPageSizeChange: (n: 15 | 20 | 25) => void; columns: JobTableColumns; onColumnsChange: (next: JobTableColumns) => void; themeMode: ThemeModePref; onThemeModeChange: (v: ThemeModePref) => void; accentColor: string; onAccentColorChange: (v: string) => void; onResetAccentColor: () => void; } function TabPanel({ value, index, children }: { value: number; index: number; children: React.ReactNode }) { if (value !== index) return null; return {children}; } const ACCENTS = ["#6366f1", "#22d3ee", "#2563eb", "#8b5cf6", "#15803d", "#16a34a", "#0f766e", "#f97316"]; const NOTIFICATION_PREFS_KEY = "settings.notificationPrefs"; type NotificationPrefs = { emailFollowUpReminders: boolean; emailGhostedJobAlerts: boolean; inAppReminderHighlights: boolean; }; function loadNotificationPrefs(): NotificationPrefs { try { const raw = window.localStorage.getItem(NOTIFICATION_PREFS_KEY); if (!raw) { return { emailFollowUpReminders: true, emailGhostedJobAlerts: true, inAppReminderHighlights: true, }; } return { emailFollowUpReminders: true, emailGhostedJobAlerts: true, inAppReminderHighlights: true, ...JSON.parse(raw), }; } catch { return { emailFollowUpReminders: true, emailGhostedJobAlerts: true, inAppReminderHighlights: true, }; } } export default function SettingsView({ pageSize, onPageSizeChange, columns, onColumnsChange, themeMode, onThemeModeChange, accentColor, onAccentColorChange, onResetAccentColor, }: Props) { const navigate = useNavigate(); const [tab, setTab] = useState(0); const { language, setLanguage, t } = useI18n(); const [accentAnchor, setAccentAnchor] = useState(null); const [accentDraft, setAccentDraft] = useState(accentColor); const [notificationPrefs, setNotificationPrefs] = useState(() => loadNotificationPrefs()); const accentOk = useMemo(() => /^#[0-9a-fA-F]{6}$/.test(accentColor), [accentColor]); const accentDraftOk = useMemo(() => /^#[0-9a-fA-F]{6}$/.test(accentDraft), [accentDraft]); useEffect(() => { setAccentDraft(accentOk ? accentColor : "#15803d"); }, [accentColor, accentOk]); useEffect(() => { window.localStorage.setItem(NOTIFICATION_PREFS_KEY, JSON.stringify(notificationPrefs)); }, [notificationPrefs]); const applyAccent = () => { if (!accentDraftOk) return; onAccentColorChange(accentDraft); setAccentAnchor(null); }; const resetAccent = () => { onResetAccentColor(); setAccentDraft("#15803d"); setAccentAnchor(null); }; return ( {t("settingsTitle")} {t("settingsSubtitle")} setTab(v)} sx={{ mb: 1 }}> {t("settingsAppearance")} {t("settingsTheme")} {t("settingsAccent")} setAccentAnchor(null)} anchorOrigin={{ vertical: "bottom", horizontal: "left" }} > {t("settingsAccent")} setAccentDraft(e.target.value)} style={{ width: "100%", height: 52, border: "none", background: "transparent", padding: 0, cursor: "pointer" }} /> setAccentDraft(e.target.value)} error={!accentDraftOk} helperText={accentDraftOk ? t("settingsAccentHelp") : t("settingsAccentInvalid")} fullWidth /> {ACCENTS.map((c) => ( {t("settingsSavedPerUser")} {t("settingsLanguageTitle")} {t("settingsLanguageBody")} {t("settingsPreferredLanguage")} {t("settingsMorePagesSoon")} {t("settingsJobs")} {t("settingsPagination")} {t("settingsRowsPerPage")} {t("settingsColumns")} {( [ ["status", t("settingsColumnStatus")], ["dateApplied", t("settingsColumnDateApplied")], ["daysSince", t("settingsColumnDays")], ["jobUrl", t("settingsColumnJobUrl")], ] as const ).map(([key, label]) => ( onColumnsChange({ ...columns, [key]: !columns[key] })} />} label={label} /> ))} {t("settingsNotificationsTitle")} {t("settingsNotificationsBody")} setNotificationPrefs((prev) => ({ ...prev, emailFollowUpReminders: e.target.checked }))} />} label={t("settingsNotificationsFollowUpReminders")} /> setNotificationPrefs((prev) => ({ ...prev, emailGhostedJobAlerts: e.target.checked }))} />} label={t("settingsNotificationsGhostedJobs")} /> setNotificationPrefs((prev) => ({ ...prev, inAppReminderHighlights: e.target.checked }))} />} label={t("settingsNotificationsInAppReminders")} /> {t("settingsNotificationsDelivery")} ); }