feat: add data retention settings to SiteSettingsPage, including subscription-based options and UI updates for user interaction
This commit is contained in:
@@ -13,6 +13,8 @@ import { PasswordInput } from '@ciphera-net/ui'
|
||||
import { Select, Modal, Button } from '@ciphera-net/ui'
|
||||
import { APP_URL } from '@/lib/api/client'
|
||||
import { generatePrivacySnippet } from '@/lib/utils/privacySnippet'
|
||||
import { getSubscription, type SubscriptionDetails } from '@/lib/api/billing'
|
||||
import { getRetentionOptionsForPlan, formatRetentionMonths } from '@/lib/plans'
|
||||
import { motion, AnimatePresence } from 'framer-motion'
|
||||
import { useAuth } from '@/lib/auth/context'
|
||||
import {
|
||||
@@ -68,8 +70,11 @@ export default function SiteSettingsPage() {
|
||||
// Performance insights setting
|
||||
enable_performance_insights: false,
|
||||
// Bot and noise filtering
|
||||
filter_bots: true
|
||||
filter_bots: true,
|
||||
// Data retention
|
||||
data_retention_months: 12
|
||||
})
|
||||
const [subscription, setSubscription] = useState<SubscriptionDetails | null>(null)
|
||||
const [linkCopied, setLinkCopied] = useState(false)
|
||||
const [snippetCopied, setSnippetCopied] = useState(false)
|
||||
const [showVerificationModal, setShowVerificationModal] = useState(false)
|
||||
@@ -83,6 +88,7 @@ export default function SiteSettingsPage() {
|
||||
|
||||
useEffect(() => {
|
||||
loadSite()
|
||||
loadSubscription()
|
||||
}, [siteId])
|
||||
|
||||
useEffect(() => {
|
||||
@@ -91,6 +97,15 @@ export default function SiteSettingsPage() {
|
||||
}
|
||||
}, [activeTab, siteId])
|
||||
|
||||
const loadSubscription = async () => {
|
||||
try {
|
||||
const sub = await getSubscription()
|
||||
setSubscription(sub)
|
||||
} catch {
|
||||
// * Non-critical; free tier assumed if billing unavailable
|
||||
}
|
||||
}
|
||||
|
||||
const loadSite = async () => {
|
||||
try {
|
||||
setLoading(true)
|
||||
@@ -111,7 +126,9 @@ export default function SiteSettingsPage() {
|
||||
// Performance insights setting (default to false)
|
||||
enable_performance_insights: data.enable_performance_insights ?? false,
|
||||
// Bot and noise filtering (default to true)
|
||||
filter_bots: data.filter_bots ?? true
|
||||
filter_bots: data.filter_bots ?? true,
|
||||
// Data retention
|
||||
data_retention_months: data.data_retention_months ?? 12
|
||||
})
|
||||
if (data.has_password) {
|
||||
setIsPasswordEnabled(true)
|
||||
@@ -226,7 +243,9 @@ export default function SiteSettingsPage() {
|
||||
// Performance insights setting
|
||||
enable_performance_insights: formData.enable_performance_insights,
|
||||
// Bot and noise filtering
|
||||
filter_bots: formData.filter_bots
|
||||
filter_bots: formData.filter_bots,
|
||||
// Data retention
|
||||
data_retention_months: formData.data_retention_months
|
||||
})
|
||||
toast.success('Site updated successfully')
|
||||
loadSite()
|
||||
@@ -821,6 +840,44 @@ export default function SiteSettingsPage() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Data Retention */}
|
||||
<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">Data Retention</h3>
|
||||
<div className="p-4 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">Keep raw event data for</h4>
|
||||
<p className="text-sm text-neutral-500 dark:text-neutral-400 mt-0.5">
|
||||
Events older than this are automatically deleted. Aggregated daily stats are kept permanently.
|
||||
</p>
|
||||
</div>
|
||||
<Select
|
||||
value={String(formData.data_retention_months)}
|
||||
onChange={(v) => setFormData({ ...formData, data_retention_months: Number(v) })}
|
||||
options={getRetentionOptionsForPlan(subscription?.plan_id).map(opt => ({
|
||||
value: String(opt.value),
|
||||
label: opt.label,
|
||||
}))}
|
||||
variant="input"
|
||||
align="right"
|
||||
className="min-w-[160px]"
|
||||
/>
|
||||
</div>
|
||||
{subscription?.plan_id && subscription.plan_id !== 'free' && (
|
||||
<p className="text-xs text-neutral-400 dark:text-neutral-500 mt-3">
|
||||
Your {subscription.plan_id} plan supports up to {formatRetentionMonths(
|
||||
getRetentionOptionsForPlan(subscription.plan_id).at(-1)?.value ?? 6
|
||||
)} of data retention.
|
||||
</p>
|
||||
)}
|
||||
{(!subscription?.plan_id || subscription.plan_id === 'free') && (
|
||||
<p className="text-xs text-neutral-400 dark:text-neutral-500 mt-3">
|
||||
Free plan supports up to 6 months. <a href="/pricing" className="text-brand-orange hover:underline">Upgrade</a> for longer retention.
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Excluded Paths */}
|
||||
<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>
|
||||
|
||||
Reference in New Issue
Block a user