From e464b874718c4ffc0e9d6675ad3c5e9d5eb0b95f Mon Sep 17 00:00:00 2001
From: Usman Baig
Date: Thu, 19 Mar 2026 10:11:28 +0100
Subject: [PATCH] feat: add filtered traffic page to admin dashboard
Add admin page at /admin/filtered-traffic showing domains blocked by the
referrer spam filter with reason badges and date range selector. Helps
operators monitor spam filtering and catch false positives.
---
app/admin/filtered-traffic/page.tsx | 91 +++++++++++++++++++++++++++++
app/admin/page.tsx | 10 ++++
lib/api/admin.ts | 15 +++++
3 files changed, 116 insertions(+)
create mode 100644 app/admin/filtered-traffic/page.tsx
diff --git a/app/admin/filtered-traffic/page.tsx b/app/admin/filtered-traffic/page.tsx
new file mode 100644
index 0000000..488f829
--- /dev/null
+++ b/app/admin/filtered-traffic/page.tsx
@@ -0,0 +1,91 @@
+'use client'
+
+import { useEffect, useState } from 'react'
+import { LoadingOverlay } from '@ciphera-net/ui'
+import { getFilteredReferrers, FilteredReferrer } from '@/lib/api/admin'
+
+export default function FilteredTrafficPage() {
+ const [referrers, setReferrers] = useState([])
+ const [loading, setLoading] = useState(true)
+ const [days, setDays] = useState(30)
+
+ useEffect(() => {
+ setLoading(true)
+ const endDate = new Date().toISOString().split('T')[0]
+ const startDate = new Date(Date.now() - days * 86400000).toISOString().split('T')[0]
+ getFilteredReferrers(startDate, endDate)
+ .then(setReferrers)
+ .finally(() => setLoading(false))
+ }, [days])
+
+ if (loading) {
+ return
+ }
+
+ const totalBlocked = referrers.reduce((sum, r) => sum + r.count, 0)
+
+ return (
+
+
+
+
Filtered Traffic
+
+ {totalBlocked.toLocaleString()} spam referrers blocked in the last {days} days
+
+
+
+ {[7, 30, 90].map((d) => (
+
+ ))}
+
+
+
+
+ {referrers.length === 0 ? (
+
+ No filtered referrers in this period
+
+ ) : (
+
+
+
+ | Domain |
+ Reason |
+ Blocked |
+
+
+
+ {referrers.map((r) => (
+
+ | {r.domain} |
+
+
+ {r.reason}
+
+ |
+
+ {r.count.toLocaleString()}
+ |
+
+ ))}
+
+
+ )}
+
+
+ )
+}
diff --git a/app/admin/page.tsx b/app/admin/page.tsx
index 02050a0..e4aa99d 100644
--- a/app/admin/page.tsx
+++ b/app/admin/page.tsx
@@ -15,6 +15,16 @@ export default function AdminDashboard() {
View all organizations, check billing status, and manually grant plans.
+
+ Filtered Traffic
+ Monitor blocked referrer spam
+
+ View domains blocked by the spam filter and check for false positives.
+
+
)
}
diff --git a/lib/api/admin.ts b/lib/api/admin.ts
index 01c009f..f9ab143 100644
--- a/lib/api/admin.ts
+++ b/lib/api/admin.ts
@@ -60,3 +60,18 @@ export async function grantPlan(orgId: string, params: GrantPlanParams): Promise
body: JSON.stringify(params),
})
}
+
+export interface FilteredReferrer {
+ domain: string
+ reason: string
+ count: number
+}
+
+export async function getFilteredReferrers(startDate?: string, endDate?: string): Promise {
+ const params = new URLSearchParams()
+ if (startDate) params.set('start_date', startDate)
+ if (endDate) params.set('end_date', endDate)
+ const query = params.toString() ? `?${params.toString()}` : ''
+ const data = await authFetch<{ filtered_referrers: FilteredReferrer[] }>(`/api/admin/filtered-referrers${query}`)
+ return data.filtered_referrers || []
+}
--
2.49.1