feat: replace filter dropdown with modal, add click-to-filter on all panels

- Filter button is now a solid pill that opens a centered modal with
  dimension grid and operator/value selection
- Clicking any row in TopReferrers, TechSpecs, Locations, or ContentStats
  adds an "is" filter for that dimension and value
- ContentStats preserves the external link icon separately via stopPropagation
This commit is contained in:
Usman Baig
2026-03-06 21:15:27 +01:00
parent 5677f30f3b
commit 0865774686
6 changed files with 147 additions and 107 deletions

View File

@@ -8,17 +8,19 @@ import { getReferrerDisplayName, getReferrerFavicon, getReferrerIcon, mergeRefer
import { Modal, GlobeIcon } from '@ciphera-net/ui'
import { ListSkeleton } from '@/components/skeletons'
import { getTopReferrers, TopReferrer } from '@/lib/api/stats'
import { type DimensionFilter } from '@/lib/filters'
interface TopReferrersProps {
referrers: Array<{ referrer: string; pageviews: number }>
collectReferrers?: boolean
siteId: string
dateRange: { start: string, end: string }
onFilter?: (filter: DimensionFilter) => void
}
const LIMIT = 7
export default function TopReferrers({ referrers, collectReferrers = true, siteId, dateRange }: TopReferrersProps) {
export default function TopReferrers({ referrers, collectReferrers = true, siteId, dateRange, onFilter }: TopReferrersProps) {
const [isModalOpen, setIsModalOpen] = useState(false)
const [fullData, setFullData] = useState<TopReferrer[]>([])
const [isLoadingFull, setIsLoadingFull] = useState(false)
@@ -103,7 +105,11 @@ export default function TopReferrers({ referrers, collectReferrers = true, siteI
) : hasData ? (
<>
{displayedReferrers.map((ref) => (
<div key={ref.referrer} className="flex items-center justify-between h-9 group hover:bg-neutral-50 dark:hover:bg-neutral-800 rounded-lg px-2 -mx-2 transition-colors">
<div
key={ref.referrer}
onClick={() => onFilter?.({ dimension: 'referrer', operator: 'is', values: [ref.referrer] })}
className={`flex items-center justify-between h-9 group hover:bg-neutral-50 dark:hover:bg-neutral-800 rounded-lg px-2 -mx-2 transition-colors${onFilter ? ' cursor-pointer' : ''}`}
>
<div className="flex-1 truncate text-neutral-900 dark:text-white flex items-center gap-3">
{renderReferrerIcon(ref.referrer)}
<span className="truncate" title={ref.referrer}>{getReferrerDisplayName(ref.referrer)}</span>