feat(pagespeed): move frequency selector to site settings
Revert inline frequency toggle from pagespeed page. Add PageSpeed Monitoring section to site settings under the Data tab with a Select dropdown for Daily/Weekly/Monthly. Shows "Not enabled" when PSI is off.
This commit is contained in:
@@ -471,34 +471,7 @@ export default function PageSpeedPage() {
|
|||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
{/* Frequency selector */}
|
{config?.frequency && (
|
||||||
{canEdit && config && (
|
|
||||||
<div className="flex items-center gap-0.5 ml-1 bg-neutral-100 dark:bg-neutral-800 rounded-md p-0.5">
|
|
||||||
{(['daily', 'weekly', 'monthly'] as const).map(f => (
|
|
||||||
<button
|
|
||||||
key={f}
|
|
||||||
onClick={async () => {
|
|
||||||
if (f === config.frequency) return
|
|
||||||
try {
|
|
||||||
await updatePageSpeedConfig(siteId, { enabled: true, frequency: f })
|
|
||||||
mutateConfig()
|
|
||||||
toast.success(`Frequency updated to ${f}`)
|
|
||||||
} catch {
|
|
||||||
toast.error('Failed to update frequency')
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
className={`px-2 py-0.5 text-[11px] font-medium rounded transition-colors ${
|
|
||||||
config.frequency === f
|
|
||||||
? 'bg-white dark:bg-neutral-700 text-neutral-900 dark:text-white shadow-sm'
|
|
||||||
: 'text-neutral-400 dark:text-neutral-500 hover:text-neutral-600 dark:hover:text-neutral-300'
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{f.charAt(0).toUpperCase() + f.slice(1)}
|
|
||||||
</button>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{!canEdit && config?.frequency && (
|
|
||||||
<span className="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-neutral-100 dark:bg-neutral-800 text-neutral-600 dark:text-neutral-400">
|
<span className="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-neutral-100 dark:bg-neutral-800 text-neutral-600 dark:text-neutral-400">
|
||||||
{config.frequency}
|
{config.frequency}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ import { Select, Modal, Button } from '@ciphera-net/ui'
|
|||||||
import { APP_URL } from '@/lib/api/client'
|
import { APP_URL } from '@/lib/api/client'
|
||||||
import { generatePrivacySnippet } from '@/lib/utils/privacySnippet'
|
import { generatePrivacySnippet } from '@/lib/utils/privacySnippet'
|
||||||
import { useUnsavedChanges } from '@/lib/hooks/useUnsavedChanges'
|
import { useUnsavedChanges } from '@/lib/hooks/useUnsavedChanges'
|
||||||
import { useSite, useGoals, useReportSchedules, useAlertSchedules, useSubscription, useGSCStatus, useBunnyStatus, useSessions, useBotFilterStats } from '@/lib/swr/dashboard'
|
import { useSite, useGoals, useReportSchedules, useAlertSchedules, useSubscription, useGSCStatus, useBunnyStatus, useSessions, useBotFilterStats, usePageSpeedConfig } from '@/lib/swr/dashboard'
|
||||||
|
import { updatePageSpeedConfig } from '@/lib/api/pagespeed'
|
||||||
import { getRetentionOptionsForPlan, formatRetentionMonths } from '@/lib/plans'
|
import { getRetentionOptionsForPlan, formatRetentionMonths } from '@/lib/plans'
|
||||||
import { motion, AnimatePresence } from 'framer-motion'
|
import { motion, AnimatePresence } from 'framer-motion'
|
||||||
import { useAuth } from '@/lib/auth/context'
|
import { useAuth } from '@/lib/auth/context'
|
||||||
@@ -130,6 +131,7 @@ export default function SiteSettingsPage() {
|
|||||||
const [gscConnecting, setGscConnecting] = useState(false)
|
const [gscConnecting, setGscConnecting] = useState(false)
|
||||||
const [gscDisconnecting, setGscDisconnecting] = useState(false)
|
const [gscDisconnecting, setGscDisconnecting] = useState(false)
|
||||||
const { data: bunnyStatus, mutate: mutateBunnyStatus } = useBunnyStatus(siteId)
|
const { data: bunnyStatus, mutate: mutateBunnyStatus } = useBunnyStatus(siteId)
|
||||||
|
const { data: psiConfig, mutate: mutatePSIConfig } = usePageSpeedConfig(siteId)
|
||||||
const [bunnyApiKey, setBunnyApiKey] = useState('')
|
const [bunnyApiKey, setBunnyApiKey] = useState('')
|
||||||
const [bunnyPullZones, setBunnyPullZones] = useState<BunnyPullZone[]>([])
|
const [bunnyPullZones, setBunnyPullZones] = useState<BunnyPullZone[]>([])
|
||||||
const [bunnySelectedZone, setBunnySelectedZone] = useState<BunnyPullZone | null>(null)
|
const [bunnySelectedZone, setBunnySelectedZone] = useState<BunnyPullZone | null>(null)
|
||||||
@@ -1345,6 +1347,47 @@ export default function SiteSettingsPage() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* PageSpeed Monitoring */}
|
||||||
|
<div className="space-y-4 pt-6 border-t border-neutral-100 dark:border-neutral-800">
|
||||||
|
<h3 className="text-sm font-medium text-neutral-700 dark:text-neutral-300">PageSpeed Monitoring</h3>
|
||||||
|
<div className="p-6 bg-neutral-50 dark:bg-neutral-900/50 rounded-2xl border border-neutral-100 dark:border-neutral-800">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div>
|
||||||
|
<h4 className="font-medium text-neutral-900 dark:text-white">Check frequency</h4>
|
||||||
|
<p className="text-sm text-neutral-500 dark:text-neutral-400 mt-0.5">
|
||||||
|
How often PageSpeed Insights runs automated checks on your site.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{psiConfig?.enabled ? (
|
||||||
|
<Select
|
||||||
|
value={psiConfig.frequency}
|
||||||
|
onChange={async (v) => {
|
||||||
|
try {
|
||||||
|
await updatePageSpeedConfig(siteId, { enabled: true, frequency: v })
|
||||||
|
mutatePSIConfig()
|
||||||
|
toast.success(`PageSpeed frequency updated to ${v}`)
|
||||||
|
} catch {
|
||||||
|
toast.error('Failed to update frequency')
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
options={[
|
||||||
|
{ value: 'daily', label: 'Daily' },
|
||||||
|
{ value: 'weekly', label: 'Weekly' },
|
||||||
|
{ value: 'monthly', label: 'Monthly' },
|
||||||
|
]}
|
||||||
|
variant="input"
|
||||||
|
align="right"
|
||||||
|
className="min-w-[130px]"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<span className="text-sm text-neutral-400 dark:text-neutral-500">
|
||||||
|
Not enabled
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Excluded Paths */}
|
{/* Excluded Paths */}
|
||||||
<div className="space-y-4 pt-6 border-t border-neutral-100 dark:border-neutral-800">
|
<div className="space-y-4 pt-6 border-t border-neutral-100 dark:border-neutral-800">
|
||||||
<h3 className="text-sm font-medium text-neutral-700 dark:text-neutral-300">Path Filtering</h3>
|
<h3 className="text-sm font-medium text-neutral-700 dark:text-neutral-300">Path Filtering</h3>
|
||||||
|
|||||||
Reference in New Issue
Block a user