'use client' import type { TopPath } from '@/lib/api/journeys' import { TableSkeleton } from '@/components/skeletons' import { Path, ArrowRight, Clock } from '@phosphor-icons/react' interface TopPathsTableProps { paths: TopPath[] loading: boolean } function formatDuration(seconds: number): string { if (seconds <= 0) return '0s' const m = Math.floor(seconds / 60) const s = Math.round(seconds % 60) if (m === 0) return `${s}s` return `${m}m ${s}s` } function smartLabel(path: string): string { if (path === '/') return '/' const segments = path.replace(/\/$/, '').split('/') if (segments.length <= 2) return path return `…/${segments[segments.length - 1]}` } function truncateSequence(seq: string[], max: number): (string | null)[] { if (seq.length <= max) return seq const head = seq.slice(0, 3) const tail = seq.slice(-2) return [...head, null, ...tail] } export default function TopPathsTable({ paths, loading }: TopPathsTableProps) { const hasData = paths.length > 0 const maxCount = hasData ? paths[0].session_count : 0 return (

Top Paths

Most common navigation paths across sessions

{loading ? ( ) : hasData ? (
{paths.map((path, i) => { const barWidth = maxCount > 0 ? (path.session_count / maxCount) * 75 : 0 const displaySeq = truncateSequence(path.page_sequence, 7) return (
{/* Background bar */}
{/* Content */}
{/* Path sequence */}
{displaySeq.map((page, j) => (
{j > 0 && ( )} {page === null ? ( ) : ( {smartLabel(page)} )}
))}
{/* Stats */}
{path.avg_duration > 0 && ( {formatDuration(path.avg_duration)} )} {path.session_count.toLocaleString()}
) })}
) : (

No path data yet

Common navigation paths will appear here as visitors browse your site.

)}
) }