From cbf2125f0a24b47b817e20a5e223625895eabd83 Mon Sep 17 00:00:00 2001 From: Usman Baig Date: Wed, 25 Mar 2026 21:59:36 +0100 Subject: [PATCH] fix: batch PageSpeed frequency and notification toggles into save flow --- .../settings/unified/UnifiedSettingsModal.tsx | 2 +- .../settings/unified/tabs/SitePrivacyTab.tsx | 61 +++++++++++-------- .../tabs/WorkspaceNotificationsTab.tsx | 52 ++++++++++------ 3 files changed, 71 insertions(+), 44 deletions(-) diff --git a/components/settings/unified/UnifiedSettingsModal.tsx b/components/settings/unified/UnifiedSettingsModal.tsx index f482c70..89029e8 100644 --- a/components/settings/unified/UnifiedSettingsModal.tsx +++ b/components/settings/unified/UnifiedSettingsModal.tsx @@ -202,7 +202,7 @@ function TabContent({ case 'general': return case 'billing': return case 'members': return - case 'notifications': return + case 'notifications': return case 'audit': return } } diff --git a/components/settings/unified/tabs/SitePrivacyTab.tsx b/components/settings/unified/tabs/SitePrivacyTab.tsx index a6532bd..003d79e 100644 --- a/components/settings/unified/tabs/SitePrivacyTab.tsx +++ b/components/settings/unified/tabs/SitePrivacyTab.tsx @@ -40,6 +40,7 @@ export default function SitePrivacyTab({ siteId, onDirtyChange, onRegisterSave } const [hideUnknownLocations, setHideUnknownLocations] = useState(false) const [dataRetention, setDataRetention] = useState(6) const [excludedPaths, setExcludedPaths] = useState('') + const [psiFrequency, setPsiFrequency] = useState('weekly') const [snippetCopied, setSnippetCopied] = useState(false) const initialRef = useRef('') @@ -55,25 +56,40 @@ export default function SitePrivacyTab({ siteId, onDirtyChange, onRegisterSave } setHideUnknownLocations(site.hide_unknown_locations ?? false) setDataRetention(site.data_retention_months ?? 6) setExcludedPaths((site.excluded_paths || []).join('\n')) - initialRef.current = JSON.stringify({ - collectPagePaths: site.collect_page_paths ?? true, - collectReferrers: site.collect_referrers ?? true, - collectDeviceInfo: site.collect_device_info ?? true, - collectScreenRes: site.collect_screen_resolution ?? true, - collectGeoData: site.collect_geo_data ?? 'full', - hideUnknownLocations: site.hide_unknown_locations ?? false, - dataRetention: site.data_retention_months ?? 6, - excludedPaths: (site.excluded_paths || []).join('\n'), - }) hasInitialized.current = true }, [site]) + // Sync PSI frequency separately (comes from a different SWR hook) + const psiInitialized = useRef(false) + useEffect(() => { + if (!psiConfig || psiInitialized.current) return + setPsiFrequency(psiConfig.frequency || 'weekly') + psiInitialized.current = true + }, [psiConfig]) + + // Build initial snapshot once both site + psi are loaded + useEffect(() => { + if (!hasInitialized.current || !initialRef.current && site) { + initialRef.current = JSON.stringify({ + collectPagePaths: site?.collect_page_paths ?? true, + collectReferrers: site?.collect_referrers ?? true, + collectDeviceInfo: site?.collect_device_info ?? true, + collectScreenRes: site?.collect_screen_resolution ?? true, + collectGeoData: site?.collect_geo_data ?? 'full', + hideUnknownLocations: site?.hide_unknown_locations ?? false, + dataRetention: site?.data_retention_months ?? 6, + excludedPaths: (site?.excluded_paths || []).join('\n'), + psiFrequency: psiConfig?.frequency || 'weekly', + }) + } + }, [site, psiConfig]) + // Track dirty state useEffect(() => { if (!initialRef.current) return - const current = JSON.stringify({ collectPagePaths, collectReferrers, collectDeviceInfo, collectScreenRes, collectGeoData, hideUnknownLocations, dataRetention, excludedPaths }) + const current = JSON.stringify({ collectPagePaths, collectReferrers, collectDeviceInfo, collectScreenRes, collectGeoData, hideUnknownLocations, dataRetention, excludedPaths, psiFrequency }) onDirtyChange?.(current !== initialRef.current) - }, [collectPagePaths, collectReferrers, collectDeviceInfo, collectScreenRes, collectGeoData, hideUnknownLocations, dataRetention, excludedPaths, onDirtyChange]) + }, [collectPagePaths, collectReferrers, collectDeviceInfo, collectScreenRes, collectGeoData, hideUnknownLocations, dataRetention, excludedPaths, psiFrequency, onDirtyChange]) const handleSave = useCallback(async () => { try { @@ -88,14 +104,19 @@ export default function SitePrivacyTab({ siteId, onDirtyChange, onRegisterSave } data_retention_months: dataRetention, excluded_paths: excludedPaths.split('\n').map(p => p.trim()).filter(Boolean), }) + // Save PSI frequency separately if it changed + if (psiConfig?.enabled && psiFrequency !== (psiConfig.frequency || 'weekly')) { + await updatePageSpeedConfig(siteId, { enabled: psiConfig.enabled, frequency: psiFrequency }) + mutatePSIConfig() + } await mutate() - initialRef.current = JSON.stringify({ collectPagePaths, collectReferrers, collectDeviceInfo, collectScreenRes, collectGeoData, hideUnknownLocations, dataRetention, excludedPaths }) + initialRef.current = JSON.stringify({ collectPagePaths, collectReferrers, collectDeviceInfo, collectScreenRes, collectGeoData, hideUnknownLocations, dataRetention, excludedPaths, psiFrequency }) onDirtyChange?.(false) toast.success('Privacy settings updated') } catch { toast.error('Failed to save') } - }, [siteId, site?.name, collectPagePaths, collectReferrers, collectDeviceInfo, collectScreenRes, collectGeoData, hideUnknownLocations, dataRetention, excludedPaths, mutate, onDirtyChange]) + }, [siteId, site?.name, collectPagePaths, collectReferrers, collectDeviceInfo, collectScreenRes, collectGeoData, hideUnknownLocations, dataRetention, excludedPaths, psiFrequency, psiConfig, mutatePSIConfig, mutate, onDirtyChange]) // Register save handler with modal useEffect(() => { @@ -195,16 +216,8 @@ export default function SitePrivacyTab({ siteId, onDirtyChange, onRegisterSave } {psiConfig?.enabled ? (