'use client' import { useCallback, useEffect, useState } from 'react' import { useParams } from 'next/navigation' import { getDateRange, formatDate, getThisWeekRange, getThisMonthRange } from '@/lib/utils/dateRanges' import { Select, DatePicker } from '@ciphera-net/ui' import dynamic from 'next/dynamic' import { getRageClicks, getDeadClicks } from '@/lib/api/stats' import FrustrationSummaryCards from '@/components/behavior/FrustrationSummaryCards' import FrustrationTable from '@/components/behavior/FrustrationTable' import FrustrationByPageTable from '@/components/behavior/FrustrationByPageTable' import FrustrationTrend from '@/components/behavior/FrustrationTrend' import { useDashboard, useBehavior } from '@/lib/swr/dashboard' import { BehaviorSkeleton, useMinimumLoading, useSkeletonFade } from '@/components/skeletons' const ScrollDepth = dynamic(() => import('@/components/dashboard/ScrollDepth')) export default function BehaviorPage() { 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) // Single request for all frustration data const { data: behavior, isLoading: loading, error: behaviorError } = useBehavior(siteId, dateRange.start, dateRange.end) // Fetch dashboard data for scroll depth (goal_counts + stats) const { data: dashboard } = useDashboard(siteId, dateRange.start, dateRange.end) const showSkeleton = useMinimumLoading(loading && !behavior) const fadeClass = useSkeletonFade(showSkeleton) useEffect(() => { const domain = dashboard?.site?.domain document.title = domain ? `Behavior · ${domain} | Pulse` : 'Behavior | Pulse' }, [dashboard?.site?.domain]) // On-demand fetchers for modal "view all" const fetchAllRage = useCallback( () => getRageClicks(siteId, dateRange.start, dateRange.end, 100), [siteId, dateRange.start, dateRange.end] ) const fetchAllDead = useCallback( () => getDeadClicks(siteId, dateRange.start, dateRange.end, 100), [siteId, dateRange.start, dateRange.end] ) const summary = behavior?.summary ?? null const rageClicks = behavior?.rage_clicks ?? { items: [], total: 0 } const deadClicks = behavior?.dead_clicks ?? { items: [], total: 0 } const byPage = behavior?.by_page ?? [] if (showSkeleton) return return (
{/* Header */}

Behavior

Frustration signals and user engagement patterns