refactor: optimize data loading in FunnelsPage and FunnelReportPage by utilizing useCallback for improved performance and dependency management

This commit is contained in:
Usman Baig
2026-02-04 23:29:32 +01:00
parent 8bbe508657
commit 45577d5cfa
3 changed files with 21 additions and 24 deletions

View File

@@ -1,12 +1,10 @@
'use client' 'use client'
import { useAuth } from '@/lib/auth/context' import { useCallback, useEffect, useMemo, useState } from 'react'
import { useEffect, useState } from 'react'
import { useParams, useRouter } from 'next/navigation' import { useParams, useRouter } from 'next/navigation'
import { getFunnel, getFunnelStats, deleteFunnel, type Funnel, type FunnelStats } from '@/lib/api/funnels' import { getFunnel, getFunnelStats, deleteFunnel, type Funnel, type FunnelStats } from '@/lib/api/funnels'
import { toast, LoadingOverlay, Select, DatePicker, ChevronLeftIcon, ArrowRightIcon, TrashIcon, useTheme } from '@ciphera-net/ui' import { toast, LoadingOverlay, Select, DatePicker, ChevronLeftIcon, ArrowRightIcon, TrashIcon, useTheme } from '@ciphera-net/ui'
import Link from 'next/link' import Link from 'next/link'
import { useMemo } from 'react'
import { import {
BarChart, BarChart,
Bar, Bar,
@@ -45,9 +43,10 @@ export default function FunnelReportPage() {
const [stats, setStats] = useState<FunnelStats | null>(null) const [stats, setStats] = useState<FunnelStats | null>(null)
const [loading, setLoading] = useState(true) const [loading, setLoading] = useState(true)
const [dateRange, setDateRange] = useState(getDateRange(30)) const [dateRange, setDateRange] = useState(getDateRange(30))
const [datePreset, setDatePreset] = useState<'7' | '30' | 'custom'>('30')
const [isDatePickerOpen, setIsDatePickerOpen] = useState(false) const [isDatePickerOpen, setIsDatePickerOpen] = useState(false)
const loadData = async () => { const loadData = useCallback(async () => {
try { try {
setLoading(true) setLoading(true)
const [funnelData, statsData] = await Promise.all([ const [funnelData, statsData] = await Promise.all([
@@ -61,11 +60,11 @@ export default function FunnelReportPage() {
} finally { } finally {
setLoading(false) setLoading(false)
} }
} }, [siteId, funnelId, dateRange])
useEffect(() => { useEffect(() => {
loadData() loadData()
}, [siteId, funnelId, dateRange]) }, [loadData])
const { resolvedTheme } = useTheme() const { resolvedTheme } = useTheme()
const chartColors = useMemo( const chartColors = useMemo(
@@ -129,17 +128,17 @@ export default function FunnelReportPage() {
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Select <Select
value={ value={datePreset}
dateRange.start === getDateRange(7).start
? '7'
: dateRange.start === getDateRange(30).start
? '30'
: 'custom'
}
onChange={(value) => { onChange={(value) => {
if (value === '7') setDateRange(getDateRange(7)) if (value === '7') {
else if (value === '30') setDateRange(getDateRange(30)) setDateRange(getDateRange(7))
else if (value === 'custom') setIsDatePickerOpen(true) setDatePreset('7')
} else if (value === '30') {
setDateRange(getDateRange(30))
setDatePreset('30')
} else if (value === 'custom') {
setIsDatePickerOpen(true)
}
}} }}
options={[ options={[
{ value: '7', label: 'Last 7 days' }, { value: '7', label: 'Last 7 days' },
@@ -215,7 +214,7 @@ export default function FunnelReportPage() {
/> />
<Bar dataKey="visitors" radius={[4, 4, 0, 0]} barSize={60}> <Bar dataKey="visitors" radius={[4, 4, 0, 0]} barSize={60}>
{chartData.map((entry, index) => ( {chartData.map((entry, index) => (
<Cell key={`cell-${index}`} fill={BRAND_ORANGE} fillOpacity={1 - (index * 0.15)} /> <Cell key={`cell-${index}`} fill={BRAND_ORANGE} fillOpacity={Math.max(0.1, 1 - index * 0.15)} />
))} ))}
</Bar> </Bar>
</BarChart> </BarChart>
@@ -285,6 +284,7 @@ export default function FunnelReportPage() {
onClose={() => setIsDatePickerOpen(false)} onClose={() => setIsDatePickerOpen(false)}
onApply={(range) => { onApply={(range) => {
setDateRange(range) setDateRange(range)
setDatePreset('custom')
setIsDatePickerOpen(false) setIsDatePickerOpen(false)
}} }}
initialRange={dateRange} initialRange={dateRange}

View File

@@ -1,6 +1,5 @@
'use client' 'use client'
import { useAuth } from '@/lib/auth/context'
import { useState } from 'react' import { useState } from 'react'
import { useParams, useRouter } from 'next/navigation' import { useParams, useRouter } from 'next/navigation'
import { createFunnel, type CreateFunnelRequest, type FunnelStep } from '@/lib/api/funnels' import { createFunnel, type CreateFunnelRequest, type FunnelStep } from '@/lib/api/funnels'

View File

@@ -1,14 +1,12 @@
'use client' 'use client'
import { useAuth } from '@/lib/auth/context' import { useCallback, useEffect, useState } from 'react'
import { useEffect, useState } from 'react'
import { useParams, useRouter } from 'next/navigation' import { useParams, useRouter } from 'next/navigation'
import { listFunnels, deleteFunnel, type Funnel } from '@/lib/api/funnels' import { listFunnels, deleteFunnel, type Funnel } from '@/lib/api/funnels'
import { toast, LoadingOverlay, PlusIcon, ArrowRightIcon, ChevronLeftIcon, TrashIcon } from '@ciphera-net/ui' import { toast, LoadingOverlay, PlusIcon, ArrowRightIcon, ChevronLeftIcon, TrashIcon } from '@ciphera-net/ui'
import Link from 'next/link' import Link from 'next/link'
export default function FunnelsPage() { export default function FunnelsPage() {
const { user } = useAuth()
const params = useParams() const params = useParams()
const router = useRouter() const router = useRouter()
const siteId = params.id as string const siteId = params.id as string
@@ -16,7 +14,7 @@ export default function FunnelsPage() {
const [funnels, setFunnels] = useState<Funnel[]>([]) const [funnels, setFunnels] = useState<Funnel[]>([])
const [loading, setLoading] = useState(true) const [loading, setLoading] = useState(true)
const loadFunnels = async () => { const loadFunnels = useCallback(async () => {
try { try {
setLoading(true) setLoading(true)
const data = await listFunnels(siteId) const data = await listFunnels(siteId)
@@ -26,11 +24,11 @@ export default function FunnelsPage() {
} finally { } finally {
setLoading(false) setLoading(false)
} }
} }, [siteId])
useEffect(() => { useEffect(() => {
loadFunnels() loadFunnels()
}, [siteId]) }, [loadFunnels])
const handleDelete = async (e: React.MouseEvent, funnelId: string) => { const handleDelete = async (e: React.MouseEvent, funnelId: string) => {
e.preventDefault() // Prevent navigation e.preventDefault() // Prevent navigation