refactor(statistics): improve component structure and enhance state management
- Introduced Suspense for lazy loading in StatisticsPage to optimize rendering. - Refactored StatisticsPage to separate inner logic into StatisticsPageInner for better readability. - Updated PeriodSelector to utilize useCallback for handling state changes, improving performance and clarity. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import { useCallback, useEffect, useMemo, useState } from "react"
|
import { Suspense, useCallback, useEffect, useMemo, useState } from "react"
|
||||||
import { useRouter, useSearchParams } from "next/navigation"
|
import { useSearchParams } from "next/navigation"
|
||||||
import {
|
import {
|
||||||
ActivityIcon,
|
ActivityIcon,
|
||||||
DatabaseIcon,
|
DatabaseIcon,
|
||||||
@@ -254,8 +254,7 @@ function chipList(slices: CubeSlices): { key: string; label: string }[] {
|
|||||||
return chips
|
return chips
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function StatisticsPage() {
|
function StatisticsPageInner() {
|
||||||
const router = useRouter()
|
|
||||||
const searchParams = useSearchParams()
|
const searchParams = useSearchParams()
|
||||||
const { mode, backendUrl, prefsHydrated } = useDataSource()
|
const { mode, backendUrl, prefsHydrated } = useDataSource()
|
||||||
const isLive = mode === "live"
|
const isLive = mode === "live"
|
||||||
@@ -282,9 +281,10 @@ export default function StatisticsPage() {
|
|||||||
else sp.delete(k)
|
else sp.delete(k)
|
||||||
}
|
}
|
||||||
const qs = sp.toString()
|
const qs = sp.toString()
|
||||||
router.replace(qs ? `/statistics?${qs}` : "/statistics")
|
if (qs === searchParams.toString()) return
|
||||||
|
window.history.replaceState(null, "", qs ? `/statistics?${qs}` : "/statistics")
|
||||||
},
|
},
|
||||||
[router, searchParams],
|
[searchParams],
|
||||||
)
|
)
|
||||||
|
|
||||||
const setRange = useCallback(
|
const setRange = useCallback(
|
||||||
@@ -548,3 +548,11 @@ export default function StatisticsPage() {
|
|||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default function StatisticsPage() {
|
||||||
|
return (
|
||||||
|
<Suspense fallback={null}>
|
||||||
|
<StatisticsPageInner />
|
||||||
|
</Suspense>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import { useMemo } from "react"
|
import { useCallback, useMemo, useState } from "react"
|
||||||
import { format } from "date-fns"
|
import { format } from "date-fns"
|
||||||
import { ru } from "date-fns/locale"
|
import { ru } from "date-fns/locale"
|
||||||
import { CalendarIcon } from "lucide-react"
|
import { CalendarIcon } from "lucide-react"
|
||||||
@@ -130,14 +130,19 @@ export function PeriodSelector({
|
|||||||
range: DateRangeYmd
|
range: DateRangeYmd
|
||||||
onChange: (next: DateRangeYmd) => void
|
onChange: (next: DateRangeYmd) => void
|
||||||
}) {
|
}) {
|
||||||
|
const [open, setOpen] = useState(false)
|
||||||
const selectorValue = useMemo(() => rangeToSelector(range), [range])
|
const selectorValue = useMemo(() => rangeToSelector(range), [range])
|
||||||
|
|
||||||
function handleSelectorChange(value: DateSelectorValue) {
|
const handleSelectorChange = useCallback(
|
||||||
const next = dateSelectorToRange(value)
|
(value: DateSelectorValue) => {
|
||||||
if (!next) return
|
const next = dateSelectorToRange(value)
|
||||||
if (next.from === range.from && next.to === range.to) return
|
if (!next) return
|
||||||
onChange(next)
|
if (next.from === range.from && next.to === range.to) return
|
||||||
}
|
onChange(next)
|
||||||
|
setOpen(false)
|
||||||
|
},
|
||||||
|
[onChange, range.from, range.to],
|
||||||
|
)
|
||||||
|
|
||||||
const activePreset = PRESETS.find((p) => {
|
const activePreset = PRESETS.find((p) => {
|
||||||
const r = rangeForPreset(p.id)
|
const r = rangeForPreset(p.id)
|
||||||
@@ -157,7 +162,7 @@ export function PeriodSelector({
|
|||||||
{p.label}
|
{p.label}
|
||||||
</Button>
|
</Button>
|
||||||
))}
|
))}
|
||||||
<Popover>
|
<Popover open={open} onOpenChange={setOpen} modal={false}>
|
||||||
<PopoverTrigger
|
<PopoverTrigger
|
||||||
render={
|
render={
|
||||||
<Button type="button" variant="outline" size="sm" className="min-w-40 justify-between" />
|
<Button type="button" variant="outline" size="sm" className="min-w-40 justify-between" />
|
||||||
|
|||||||
Generated
+15
@@ -14875,6 +14875,21 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"zod": "^4.4.1"
|
"zod": "^4.4.1"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/swc-win32-x64-msvc": {
|
||||||
|
"version": "16.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.2.4.tgz",
|
||||||
|
"integrity": "sha512-kMVGgsqhO5YTYODD9IPGGhA6iprWidQckK3LmPeW08PIFENRmgfb4MjXHO+p//d+ts2rpjvK5gXWzXSMrPl9cw==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user