'use client' import { useEffect, useState } from 'react' import { useParams } from 'next/navigation' import { getDateRange, formatDate } from '@ciphera-net/ui' import { Select, DatePicker } from '@ciphera-net/ui' import ColumnJourney from '@/components/journeys/ColumnJourney' import TopPathsTable from '@/components/journeys/TopPathsTable' import { JourneysSkeleton, useMinimumLoading, useSkeletonFade } from '@/components/skeletons' import { useDashboard, useJourneyTransitions, useJourneyTopPaths, useJourneyEntryPoints, } from '@/lib/swr/dashboard' const DEPTH_STEPS = [2, 3, 4, 5, 6, 7, 8, 9, 10] function getThisWeekRange(): { start: string; end: string } { const today = new Date() const dayOfWeek = today.getDay() const monday = new Date(today) monday.setDate(today.getDate() - (dayOfWeek === 0 ? 6 : dayOfWeek - 1)) return { start: formatDate(monday), end: formatDate(today) } } function getThisMonthRange(): { start: string; end: string } { const today = new Date() const firstOfMonth = new Date(today.getFullYear(), today.getMonth(), 1) return { start: formatDate(firstOfMonth), end: formatDate(today) } } export default function JourneysPage() { const params = useParams() const siteId = params.id as string const [period, setPeriod] = useState('30') const [dateRange, setDateRange] = useState(() => getDateRange(30)) const [isDatePickerOpen, setIsDatePickerOpen] = useState(false) const [depth, setDepth] = useState(3) const [displayDepth, setDisplayDepth] = useState(3) const [entryPath, setEntryPath] = useState('') const sliderIndex = DEPTH_STEPS.indexOf(displayDepth) const { data: transitionsData, isLoading: transitionsLoading } = useJourneyTransitions( siteId, dateRange.start, dateRange.end, depth, 1, entryPath || undefined ) const { data: topPaths, isLoading: topPathsLoading } = useJourneyTopPaths( siteId, dateRange.start, dateRange.end, 20, 1, entryPath || undefined ) const { data: entryPoints } = useJourneyEntryPoints(siteId, dateRange.start, dateRange.end) const { data: dashboard } = useDashboard(siteId, dateRange.start, dateRange.end) useEffect(() => { const domain = dashboard?.site?.domain document.title = domain ? `Journeys \u00b7 ${domain} | Pulse` : 'Journeys | Pulse' }, [dashboard?.site?.domain]) const showSkeleton = useMinimumLoading(transitionsLoading && !transitionsData) const fadeClass = useSkeletonFade(showSkeleton) const entryPointOptions = [ { value: '', label: 'All entry points' }, ...(entryPoints ?? []).map((ep) => ({ value: ep.path, label: `${ep.path} (${ep.session_count.toLocaleString()})`, })), ] if (showSkeleton) return const totalSessions = transitionsData?.total_sessions ?? 0 return (
{/* Header */}

Journeys

How visitors navigate through your site

setDisplayDepth(DEPTH_STEPS[parseInt(e.target.value)])} onMouseUp={(e) => setDepth(DEPTH_STEPS[parseInt((e.target as HTMLInputElement).value)])} onTouchEnd={(e) => setDepth(DEPTH_STEPS[parseInt((e.target as HTMLInputElement).value)])} aria-label="Journey depth" aria-valuetext={`${displayDepth} steps deep`} className="w-full h-2 bg-neutral-200 rounded-lg appearance-none cursor-pointer dark:bg-neutral-700 accent-brand-orange focus:outline-none" />
{/* Entry point + Reset */}