[PULSE-36] Funnels UI - builder and report #8

Merged
uz1mani merged 12 commits from staging into main 2026-02-04 23:16:04 +00:00
7 changed files with 743 additions and 5 deletions
Showing only changes of commit 45577d5cfa - Show all commits

View File

@@ -1,12 +1,10 @@
'use client'
greptile-apps[bot] commented 2026-02-04 22:07:42 +00:00 (Migrated from github.com)
Review

ReferenceError on mount

useEffect calls loadData() before loadData is defined (const loadData = async () => { ... }), which throws ReferenceError: Cannot access 'loadData' before initialization on first render. Move the loadData definition above the useEffect (or switch to a hoisted function loadData() {}) so the page doesn’t crash.

Prompt To Fix With AI
This is a comment left during a code review.
Path: app/sites/[id]/funnels/[funnelId]/page.tsx
Line: 46:52

Comment:
**ReferenceError on mount**

`useEffect` calls `loadData()` before `loadData` is defined (`const loadData = async () => { ... }`), which throws `ReferenceError: Cannot access 'loadData' before initialization` on first render. Move the `loadData` definition above the `useEffect` (or switch to a hoisted `function loadData() {}`) so the page doesn’t crash.

How can I resolve this? If you propose a fix, please make it concise.
**ReferenceError on mount** `useEffect` calls `loadData()` before `loadData` is defined (`const loadData = async () => { ... }`), which throws `ReferenceError: Cannot access 'loadData' before initialization` on first render. Move the `loadData` definition above the `useEffect` (or switch to a hoisted `function loadData() {}`) so the page doesn’t crash. <details><summary>Prompt To Fix With AI</summary> `````markdown This is a comment left during a code review. Path: app/sites/[id]/funnels/[funnelId]/page.tsx Line: 46:52 Comment: **ReferenceError on mount** `useEffect` calls `loadData()` before `loadData` is defined (`const loadData = async () => { ... }`), which throws `ReferenceError: Cannot access 'loadData' before initialization` on first render. Move the `loadData` definition above the `useEffect` (or switch to a hoisted `function loadData() {}`) so the page doesn’t crash. How can I resolve this? If you propose a fix, please make it concise. ````` </details>
uz1mani commented 2026-02-04 22:17:09 +00:00 (Migrated from github.com)
Review

Change: The loadData definition was moved above the useEffect that calls it.
Why: const loadData = async () => { ... } is not hoisted, so when the effect ran on the first render it was still in the temporal dead zone and threw “Cannot access 'loadData' before initialization”. Defining loadData before the useEffect ensures it exists when the effect runs.

Change: The loadData definition was moved above the useEffect that calls it. Why: const loadData = async () => { ... } is not hoisted, so when the effect ran on the first render it was still in the temporal dead zone and threw “Cannot access 'loadData' before initialization”. Defining loadData before the useEffect ensures it exists when the effect runs.
greptile-apps[bot] commented 2026-02-04 22:21:40 +00:00 (Migrated from github.com)
Review

Missing loadData in dependency array causes React exhaustive-deps warning and stale closure issues. Either add loadData to the dependency array or use useCallback to memoize loadData.

Prompt To Fix With AI
This is a comment left during a code review.
Path: app/sites/[id]/funnels/[funnelId]/page.tsx
Line: 50:52

Comment:
Missing `loadData` in dependency array causes React exhaustive-deps warning and stale closure issues. Either add `loadData` to the dependency array or use `useCallback` to memoize `loadData`.

How can I resolve this? If you propose a fix, please make it concise.
Missing `loadData` in dependency array causes React exhaustive-deps warning and stale closure issues. Either add `loadData` to the dependency array or use `useCallback` to memoize `loadData`. <details><summary>Prompt To Fix With AI</summary> `````markdown This is a comment left during a code review. Path: app/sites/[id]/funnels/[funnelId]/page.tsx Line: 50:52 Comment: Missing `loadData` in dependency array causes React exhaustive-deps warning and stale closure issues. Either add `loadData` to the dependency array or use `useCallback` to memoize `loadData`. How can I resolve this? If you propose a fix, please make it concise. ````` </details>
greptile-apps[bot] commented 2026-02-04 22:21:42 +00:00 (Migrated from github.com)
Review

Date comparison using string equality (dateRange.start === getDateRange(7).start) creates new Date objects on every render, causing unnecessary re-renders and always evaluating to false since objects are different references.

Prompt To Fix With AI
This is a comment left during a code review.
Path: app/sites/[id]/funnels/[funnelId]/page.tsx
Line: 132:143

Comment:
Date comparison using string equality (`dateRange.start === getDateRange(7).start`) creates new Date objects on every render, causing unnecessary re-renders and always evaluating to false since objects are different references.

How can I resolve this? If you propose a fix, please make it concise.
Date comparison using string equality (`dateRange.start === getDateRange(7).start`) creates new Date objects on every render, causing unnecessary re-renders and always evaluating to false since objects are different references. <details><summary>Prompt To Fix With AI</summary> `````markdown This is a comment left during a code review. Path: app/sites/[id]/funnels/[funnelId]/page.tsx Line: 132:143 Comment: Date comparison using string equality (`dateRange.start === getDateRange(7).start`) creates new Date objects on every render, causing unnecessary re-renders and always evaluating to false since objects are different references. How can I resolve this? If you propose a fix, please make it concise. ````` </details>
greptile-apps[bot] commented 2026-02-04 22:21:45 +00:00 (Migrated from github.com)
Review

Unused import useAuth - not referenced in the component.

Prompt To Fix With AI
This is a comment left during a code review.
Path: app/sites/[id]/funnels/[funnelId]/page.tsx
Line: 3:3

Comment:
Unused import `useAuth` - not referenced in the component.

How can I resolve this? If you propose a fix, please make it concise.
Unused import `useAuth` - not referenced in the component. <details><summary>Prompt To Fix With AI</summary> `````markdown This is a comment left during a code review. Path: app/sites/[id]/funnels/[funnelId]/page.tsx Line: 3:3 Comment: Unused import `useAuth` - not referenced in the component. How can I resolve this? If you propose a fix, please make it concise. ````` </details>
greptile-apps[bot] commented 2026-02-04 22:21:47 +00:00 (Migrated from github.com)
Review

Opacity calculation can go negative for funnels with more than 6 steps, causing render issues. Wrap in Math.max(0.1, ...) to prevent negative opacity.

Prompt To Fix With AI
This is a comment left during a code review.
Path: app/sites/[id]/funnels/[funnelId]/page.tsx
Line: 218:218

Comment:
Opacity calculation can go negative for funnels with more than 6 steps, causing render issues. Wrap in `Math.max(0.1, ...)` to prevent negative opacity.

How can I resolve this? If you propose a fix, please make it concise.
Opacity calculation can go negative for funnels with more than 6 steps, causing render issues. Wrap in `Math.max(0.1, ...)` to prevent negative opacity. <details><summary>Prompt To Fix With AI</summary> `````markdown This is a comment left during a code review. Path: app/sites/[id]/funnels/[funnelId]/page.tsx Line: 218:218 Comment: Opacity calculation can go negative for funnels with more than 6 steps, causing render issues. Wrap in `Math.max(0.1, ...)` to prevent negative opacity. How can I resolve this? If you propose a fix, please make it concise. ````` </details>
uz1mani commented 2026-02-04 22:28:23 +00:00 (Migrated from github.com)
Review

Change: Replaced fillOpacity={1 - (index * 0.15)} with fillOpacity={Math.max(0.1, 1 - index * 0.15)}.
Why: For index ≥ 7, 1 - index * 0.15 becomes negative; capping with Math.max(0.1, ...) keeps opacity in a valid range and avoids render issues.

Change: Replaced fillOpacity={1 - (index * 0.15)} with fillOpacity={Math.max(0.1, 1 - index * 0.15)}. Why: For index ≥ 7, 1 - index * 0.15 becomes negative; capping with Math.max(0.1, ...) keeps opacity in a valid range and avoids render issues.
uz1mani commented 2026-02-04 22:28:33 +00:00 (Migrated from github.com)
Review

Change: Removed import { useAuth } from '@/lib/auth/context' from app/sites/[id]/funnels/[funnelId]/page.tsx.
Why: The report page doesn’t use useAuth.

Change: Removed import { useAuth } from '@/lib/auth/context' from app/sites/[id]/funnels/[funnelId]/page.tsx. Why: The report page doesn’t use useAuth.
uz1mani commented 2026-02-04 22:29:04 +00:00 (Migrated from github.com)
Review

Change: Introduced datePreset state: '7' | '30' | 'custom', default '30'. The Select uses value={datePreset}. In onChange: for '7'/'30' we call setDateRange(getDateRange(7)) / setDateRange(getDateRange(30)) and setDatePreset('7') / setDatePreset('30'); for 'custom' we only open the picker. In the DatePicker onApply we call setDatePreset('custom') when applying a custom range.
Why: We no longer call getDateRange(7) / getDateRange(30) on every render to derive the Select value; the value comes from datePreset, so no extra Date allocations or reference issues.

Change: Introduced datePreset state: '7' | '30' | 'custom', default '30'. The Select uses value={datePreset}. In onChange: for '7'/'30' we call setDateRange(getDateRange(7)) / setDateRange(getDateRange(30)) and setDatePreset('7') / setDatePreset('30'); for 'custom' we only open the picker. In the DatePicker onApply we call setDatePreset('custom') when applying a custom range. Why: We no longer call getDateRange(7) / getDateRange(30) on every render to derive the Select value; the value comes from datePreset, so no extra Date allocations or reference issues.
uz1mani commented 2026-02-04 22:29:23 +00:00 (Migrated from github.com)
Review

Change: Wrapped the loader in useCallback with deps [siteId, funnelId, dateRange], and made the effect depend only on [loadData].
Why: loadData is now stable per (siteId, funnelId, dateRange), so the effect runs when any of those change and satisfies exhaustive-deps without stale closures.

Change: Wrapped the loader in useCallback with deps [siteId, funnelId, dateRange], and made the effect depend only on [loadData]. Why: loadData is now stable per (siteId, funnelId, dateRange), so the effect runs when any of those change and satisfies exhaustive-deps without stale closures.
import { useAuth } from '@/lib/auth/context'
import { useEffect, useState } from 'react'
import { useCallback, useEffect, useMemo, useState } from 'react'
greptile-apps[bot] commented 2026-02-04 22:35:37 +00:00 (Migrated from github.com)
Review

Unused auth import

useAuth is imported here but never referenced, which will fail lint/typecheck in projects enforcing no-unused-vars. Remove the import to avoid CI failures.

Prompt To Fix With AI
This is a comment left during a code review.
Path: app/sites/[id]/funnels/[funnelId]/page.tsx
Line: 1:3

Comment:
**Unused auth import**

`useAuth` is imported here but never referenced, which will fail lint/typecheck in projects enforcing `no-unused-vars`. Remove the import to avoid CI failures.

How can I resolve this? If you propose a fix, please make it concise.
**Unused auth import** `useAuth` is imported here but never referenced, which will fail lint/typecheck in projects enforcing `no-unused-vars`. Remove the import to avoid CI failures. <details><summary>Prompt To Fix With AI</summary> `````markdown This is a comment left during a code review. Path: app/sites/[id]/funnels/[funnelId]/page.tsx Line: 1:3 Comment: **Unused auth import** `useAuth` is imported here but never referenced, which will fail lint/typecheck in projects enforcing `no-unused-vars`. Remove the import to avoid CI failures. How can I resolve this? If you propose a fix, please make it concise. ````` </details>
uz1mani commented 2026-02-04 22:38:27 +00:00 (Migrated from github.com)
Review

Already fixed.

Already fixed.
import { useParams, useRouter } from 'next/navigation'
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 Link from 'next/link'
import { useMemo } from 'react'
import {
BarChart,
Bar,
@@ -45,9 +43,10 @@ export default function FunnelReportPage() {
const [stats, setStats] = useState<FunnelStats | null>(null)
const [loading, setLoading] = useState(true)
const [dateRange, setDateRange] = useState(getDateRange(30))
const [datePreset, setDatePreset] = useState<'7' | '30' | 'custom'>('30')
const [isDatePickerOpen, setIsDatePickerOpen] = useState(false)
const loadData = async () => {
const loadData = useCallback(async () => {
try {
setLoading(true)
const [funnelData, statsData] = await Promise.all([
@@ -61,11 +60,11 @@ export default function FunnelReportPage() {
} finally {
setLoading(false)
}
}
}, [siteId, funnelId, dateRange])
useEffect(() => {
loadData()
}, [siteId, funnelId, dateRange])
}, [loadData])
const { resolvedTheme } = useTheme()
const chartColors = useMemo(
@@ -129,17 +128,17 @@ export default function FunnelReportPage() {
<div className="flex items-center gap-2">
<Select
value={
dateRange.start === getDateRange(7).start
? '7'
: dateRange.start === getDateRange(30).start
? '30'
: 'custom'
}
value={datePreset}
onChange={(value) => {
if (value === '7') setDateRange(getDateRange(7))
else if (value === '30') setDateRange(getDateRange(30))
else if (value === 'custom') setIsDatePickerOpen(true)
if (value === '7') {
greptile-apps[bot] commented 2026-02-04 23:03:01 +00:00 (Migrated from github.com)
Review

Misleading error state

When loadData() fails (network/5xx/permission), funnel/stats remain null and the render falls through to if (!funnel || !stats) showing "Funnel not found". That message is only correct for a 404; for transient errors it incorrectly looks like a permanent missing resource and provides no retry path. Consider tracking an explicit error/notFound state and only rendering "not found" on an actual 404 response.

Prompt To Fix With AI
This is a comment left during a code review.
Path: app/sites/[id]/funnels/[funnelId]/page.tsx
Line: 91:96

Comment:
**Misleading error state**

When `loadData()` fails (network/5xx/permission), `funnel`/`stats` remain `null` and the render falls through to `if (!funnel || !stats)` showing "Funnel not found". That message is only correct for a 404; for transient errors it incorrectly looks like a permanent missing resource and provides no retry path. Consider tracking an explicit `error`/`notFound` state and only rendering "not found" on an actual 404 response.

How can I resolve this? If you propose a fix, please make it concise.
**Misleading error state** When `loadData()` fails (network/5xx/permission), `funnel`/`stats` remain `null` and the render falls through to `if (!funnel || !stats)` showing "Funnel not found". That message is only correct for a 404; for transient errors it incorrectly looks like a permanent missing resource and provides no retry path. Consider tracking an explicit `error`/`notFound` state and only rendering "not found" on an actual 404 response. <details><summary>Prompt To Fix With AI</summary> `````markdown This is a comment left during a code review. Path: app/sites/[id]/funnels/[funnelId]/page.tsx Line: 91:96 Comment: **Misleading error state** When `loadData()` fails (network/5xx/permission), `funnel`/`stats` remain `null` and the render falls through to `if (!funnel || !stats)` showing "Funnel not found". That message is only correct for a 404; for transient errors it incorrectly looks like a permanent missing resource and provides no retry path. Consider tracking an explicit `error`/`notFound` state and only rendering "not found" on an actual 404 response. How can I resolve this? If you propose a fix, please make it concise. ````` </details>
uz1mani commented 2026-02-04 23:05:05 +00:00 (Migrated from github.com)
Review

Change:
Added loadError state: 'not_found' | 'error' | null, default null.
In loadData: at the start, setLoadError(null); in the catch, if error instanceof ApiError && error.status === 404 then setLoadError('not_found'), else setLoadError('error') and toast.error('Failed to load funnel data') (toast only for non-404).
Render logic:
loadError === 'not_found' or (!funnel && !stats && !loadError) → show "Funnel not found" (no retry).
loadError === 'error' → show "Failed to load funnel data" and a "Try again" button that calls loadData().
Otherwise, if !funnel || !stats → fallback "Funnel not found".
Why: 404 is shown as “Funnel not found”; other failures (network/5xx/permission) are shown as “Failed to load funnel data” with a retry, so transient errors are no longer treated as a permanent missing resource.

Change: Added loadError state: 'not_found' | 'error' | null, default null. In loadData: at the start, setLoadError(null); in the catch, if error instanceof ApiError && error.status === 404 then setLoadError('not_found'), else setLoadError('error') and toast.error('Failed to load funnel data') (toast only for non-404). Render logic: loadError === 'not_found' or (!funnel && !stats && !loadError) → show "Funnel not found" (no retry). loadError === 'error' → show "Failed to load funnel data" and a "Try again" button that calls loadData(). Otherwise, if !funnel || !stats → fallback "Funnel not found". Why: 404 is shown as “Funnel not found”; other failures (network/5xx/permission) are shown as “Failed to load funnel data” with a retry, so transient errors are no longer treated as a permanent missing resource.
setDateRange(getDateRange(7))
setDatePreset('7')
} else if (value === '30') {
setDateRange(getDateRange(30))
setDatePreset('30')
} else if (value === 'custom') {
setIsDatePickerOpen(true)
}
}}
options={[
{ value: '7', label: 'Last 7 days' },
@@ -215,7 +214,7 @@ export default function FunnelReportPage() {
/>
<Bar dataKey="visitors" radius={[4, 4, 0, 0]} barSize={60}>
{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>
</BarChart>
@@ -285,6 +284,7 @@ export default function FunnelReportPage() {
onClose={() => setIsDatePickerOpen(false)}
onApply={(range) => {
setDateRange(range)
setDatePreset('custom')
setIsDatePickerOpen(false)
}}
initialRange={dateRange}

View File

@@ -1,6 +1,5 @@
'use client'
greptile-apps[bot] commented 2026-02-04 22:21:44 +00:00 (Migrated from github.com)
Review

Unused import useAuth - not referenced in the component.

Prompt To Fix With AI
This is a comment left during a code review.
Path: app/sites/[id]/funnels/new/page.tsx
Line: 3:3

Comment:
Unused import `useAuth` - not referenced in the component.

How can I resolve this? If you propose a fix, please make it concise.
Unused import `useAuth` - not referenced in the component. <details><summary>Prompt To Fix With AI</summary> `````markdown This is a comment left during a code review. Path: app/sites/[id]/funnels/new/page.tsx Line: 3:3 Comment: Unused import `useAuth` - not referenced in the component. How can I resolve this? If you propose a fix, please make it concise. ````` </details>
uz1mani commented 2026-02-04 22:28:56 +00:00 (Migrated from github.com)
Review

Change: Removed import { useAuth } from '@/lib/auth/context' from app/sites/[id]/funnels/new/page.tsx.
Why: The component doesn’t use useAuth.

Change: Removed import { useAuth } from '@/lib/auth/context' from app/sites/[id]/funnels/new/page.tsx. Why: The component doesn’t use useAuth.
import { useAuth } from '@/lib/auth/context'
import { useState } from 'react'
greptile-apps[bot] commented 2026-02-04 22:35:38 +00:00 (Migrated from github.com)
Review

Unused auth import

useAuth is imported but not used in this page, which will trip no-unused-vars/typecheck in many setups. Remove the import.

Prompt To Fix With AI
This is a comment left during a code review.
Path: app/sites/[id]/funnels/new/page.tsx
Line: 1:3

Comment:
**Unused auth import**

`useAuth` is imported but not used in this page, which will trip `no-unused-vars`/typecheck in many setups. Remove the import.

How can I resolve this? If you propose a fix, please make it concise.
**Unused auth import** `useAuth` is imported but not used in this page, which will trip `no-unused-vars`/typecheck in many setups. Remove the import. <details><summary>Prompt To Fix With AI</summary> `````markdown This is a comment left during a code review. Path: app/sites/[id]/funnels/new/page.tsx Line: 1:3 Comment: **Unused auth import** `useAuth` is imported but not used in this page, which will trip `no-unused-vars`/typecheck in many setups. Remove the import. How can I resolve this? If you propose a fix, please make it concise. ````` </details>
uz1mani commented 2026-02-04 22:38:31 +00:00 (Migrated from github.com)
Review

Already fixed.

Already fixed.
import { useParams, useRouter } from 'next/navigation'
import { createFunnel, type CreateFunnelRequest, type FunnelStep } from '@/lib/api/funnels'

View File

@@ -1,14 +1,12 @@
'use client'
greptile-apps[bot] commented 2026-02-04 22:07:43 +00:00 (Migrated from github.com)
Review

ReferenceError on mount

Same pattern as the report page: useEffect calls loadFunnels() before const loadFunnels = async () => { ... } is initialized, so this page will throw ReferenceError: Cannot access 'loadFunnels' before initialization on mount. Define loadFunnels above the effect (or use a hoisted function declaration).

Prompt To Fix With AI
This is a comment left during a code review.
Path: app/sites/[id]/funnels/page.tsx
Line: 15:21

Comment:
**ReferenceError on mount**

Same pattern as the report page: `useEffect` calls `loadFunnels()` before `const loadFunnels = async () => { ... }` is initialized, so this page will throw `ReferenceError: Cannot access 'loadFunnels' before initialization` on mount. Define `loadFunnels` above the effect (or use a hoisted function declaration).

How can I resolve this? If you propose a fix, please make it concise.
**ReferenceError on mount** Same pattern as the report page: `useEffect` calls `loadFunnels()` before `const loadFunnels = async () => { ... }` is initialized, so this page will throw `ReferenceError: Cannot access 'loadFunnels' before initialization` on mount. Define `loadFunnels` above the effect (or use a hoisted function declaration). <details><summary>Prompt To Fix With AI</summary> `````markdown This is a comment left during a code review. Path: app/sites/[id]/funnels/page.tsx Line: 15:21 Comment: **ReferenceError on mount** Same pattern as the report page: `useEffect` calls `loadFunnels()` before `const loadFunnels = async () => { ... }` is initialized, so this page will throw `ReferenceError: Cannot access 'loadFunnels' before initialization` on mount. Define `loadFunnels` above the effect (or use a hoisted function declaration). How can I resolve this? If you propose a fix, please make it concise. ````` </details>
uz1mani commented 2026-02-04 22:17:00 +00:00 (Migrated from github.com)
Review

Change: The loadFunnels definition was moved above the useEffect that calls it.
Why: Same pattern as the report page: the effect was calling loadFunnels() before the const loadFunnels = async () => { ... } was initialized. Defining loadFunnels before the useEffect fixes the ReferenceError on mount.

Change: The loadFunnels definition was moved above the useEffect that calls it. Why: Same pattern as the report page: the effect was calling loadFunnels() before the const loadFunnels = async () => { ... } was initialized. Defining loadFunnels before the useEffect fixes the ReferenceError on mount.
greptile-apps[bot] commented 2026-02-04 22:21:41 +00:00 (Migrated from github.com)
Review

Missing loadFunnels in dependency array causes React exhaustive-deps warning and stale closure issues. Either add loadFunnels to the dependency array or use useCallback to memoize loadFunnels.

Prompt To Fix With AI
This is a comment left during a code review.
Path: app/sites/[id]/funnels/page.tsx
Line: 19:21

Comment:
Missing `loadFunnels` in dependency array causes React exhaustive-deps warning and stale closure issues. Either add `loadFunnels` to the dependency array or use `useCallback` to memoize `loadFunnels`.

How can I resolve this? If you propose a fix, please make it concise.
Missing `loadFunnels` in dependency array causes React exhaustive-deps warning and stale closure issues. Either add `loadFunnels` to the dependency array or use `useCallback` to memoize `loadFunnels`. <details><summary>Prompt To Fix With AI</summary> `````markdown This is a comment left during a code review. Path: app/sites/[id]/funnels/page.tsx Line: 19:21 Comment: Missing `loadFunnels` in dependency array causes React exhaustive-deps warning and stale closure issues. Either add `loadFunnels` to the dependency array or use `useCallback` to memoize `loadFunnels`. How can I resolve this? If you propose a fix, please make it concise. ````` </details>
greptile-apps[bot] commented 2026-02-04 22:21:44 +00:00 (Migrated from github.com)
Review

Unused variable user destructured from useAuth() - not referenced in the component.

Prompt To Fix With AI
This is a comment left during a code review.
Path: app/sites/[id]/funnels/page.tsx
Line: 11:11

Comment:
Unused variable `user` destructured from `useAuth()` - not referenced in the component.

How can I resolve this? If you propose a fix, please make it concise.
Unused variable `user` destructured from `useAuth()` - not referenced in the component. <details><summary>Prompt To Fix With AI</summary> `````markdown This is a comment left during a code review. Path: app/sites/[id]/funnels/page.tsx Line: 11:11 Comment: Unused variable `user` destructured from `useAuth()` - not referenced in the component. How can I resolve this? If you propose a fix, please make it concise. ````` </details>
uz1mani commented 2026-02-04 22:28:45 +00:00 (Migrated from github.com)
Review

Change: Removed useAuth() and its import from app/sites/[id]/funnels/page.tsx (the list page).
Why: Only user was destructured and it wasn’t used, so the whole hook and import were removed.

Change: Removed useAuth() and its import from app/sites/[id]/funnels/page.tsx (the list page). Why: Only user was destructured and it wasn’t used, so the whole hook and import were removed.
uz1mani commented 2026-02-04 22:29:13 +00:00 (Migrated from github.com)
Review

Change: Wrapped loadFunnels in useCallback with deps [siteId], and set the effect dependency array to [loadFunnels].
Why: Same as above: correct deps and no stale closure.

Change: Wrapped loadFunnels in useCallback with deps [siteId], and set the effect dependency array to [loadFunnels]. Why: Same as above: correct deps and no stale closure.
import { useAuth } from '@/lib/auth/context'
import { useEffect, useState } from 'react'
import { useCallback, useEffect, useState } from 'react'
import { useParams, useRouter } from 'next/navigation'
import { listFunnels, deleteFunnel, type Funnel } from '@/lib/api/funnels'
import { toast, LoadingOverlay, PlusIcon, ArrowRightIcon, ChevronLeftIcon, TrashIcon } from '@ciphera-net/ui'
import Link from 'next/link'
export default function FunnelsPage() {
const { user } = useAuth()
const params = useParams()
const router = useRouter()
const siteId = params.id as string
@@ -16,7 +14,7 @@ export default function FunnelsPage() {
const [funnels, setFunnels] = useState<Funnel[]>([])
const [loading, setLoading] = useState(true)
const loadFunnels = async () => {
const loadFunnels = useCallback(async () => {
try {
setLoading(true)
const data = await listFunnels(siteId)
@@ -26,11 +24,11 @@ export default function FunnelsPage() {
} finally {
setLoading(false)
}
}
}, [siteId])
useEffect(() => {
loadFunnels()
}, [siteId])
}, [loadFunnels])
const handleDelete = async (e: React.MouseEvent, funnelId: string) => {
e.preventDefault() // Prevent navigation