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 +
+ ) : ( + + + + + + + + + + {referrers.map((r) => ( + + + + + + ))} + +
DomainReasonBlocked
{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 || [] +}