feat: integrate interval selection for dashboard charts based on date range
This commit is contained in:
@@ -212,28 +212,6 @@ export default function SiteDashboardPage() {
|
|||||||
{ value: 'custom', label: 'Custom' },
|
{ value: 'custom', label: 'Custom' },
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
{dateRange.start === new Date().toISOString().split('T')[0] && dateRange.end === new Date().toISOString().split('T')[0] && (
|
|
||||||
<Select
|
|
||||||
value={todayInterval}
|
|
||||||
onChange={(value) => setTodayInterval(value as 'minute' | 'hour')}
|
|
||||||
options={[
|
|
||||||
{ value: 'minute', label: '1 min' },
|
|
||||||
{ value: 'hour', label: '1 hour' },
|
|
||||||
]}
|
|
||||||
className="min-w-[100px]"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{dateRange.start !== dateRange.end && (
|
|
||||||
<Select
|
|
||||||
value={multiDayInterval}
|
|
||||||
onChange={(value) => setMultiDayInterval(value as 'hour' | 'day')}
|
|
||||||
options={[
|
|
||||||
{ value: 'hour', label: '1 hour' },
|
|
||||||
{ value: 'day', label: '1 day' },
|
|
||||||
]}
|
|
||||||
className="min-w-[100px]"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{canEdit && (
|
{canEdit && (
|
||||||
<button
|
<button
|
||||||
onClick={() => router.push(`/sites/${siteId}/settings`)}
|
onClick={() => router.push(`/sites/${siteId}/settings`)}
|
||||||
@@ -254,6 +232,11 @@ export default function SiteDashboardPage() {
|
|||||||
stats={stats}
|
stats={stats}
|
||||||
prevStats={prevStats}
|
prevStats={prevStats}
|
||||||
interval={dateRange.start === dateRange.end ? todayInterval : multiDayInterval}
|
interval={dateRange.start === dateRange.end ? todayInterval : multiDayInterval}
|
||||||
|
dateRange={dateRange}
|
||||||
|
todayInterval={todayInterval}
|
||||||
|
setTodayInterval={setTodayInterval}
|
||||||
|
multiDayInterval={multiDayInterval}
|
||||||
|
setMultiDayInterval={setMultiDayInterval}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import {
|
|||||||
} from 'recharts'
|
} from 'recharts'
|
||||||
import type { TooltipProps } from 'recharts'
|
import type { TooltipProps } from 'recharts'
|
||||||
import { formatNumber, formatDuration } from '@/lib/utils/format'
|
import { formatNumber, formatDuration } from '@/lib/utils/format'
|
||||||
import { ArrowUpRightIcon, ArrowDownRightIcon, BarChartIcon } from '@ciphera-net/ui'
|
import { ArrowUpRightIcon, ArrowDownRightIcon, BarChartIcon, Select } from '@ciphera-net/ui'
|
||||||
import { Checkbox } from '@ciphera-net/ui'
|
import { Checkbox } from '@ciphera-net/ui'
|
||||||
|
|
||||||
const COLORS = {
|
const COLORS = {
|
||||||
@@ -62,6 +62,11 @@ interface ChartProps {
|
|||||||
stats: Stats
|
stats: Stats
|
||||||
prevStats?: Stats
|
prevStats?: Stats
|
||||||
interval: 'minute' | 'hour' | 'day' | 'month'
|
interval: 'minute' | 'hour' | 'day' | 'month'
|
||||||
|
dateRange: { start: string, end: string }
|
||||||
|
todayInterval: 'minute' | 'hour'
|
||||||
|
setTodayInterval: (interval: 'minute' | 'hour') => void
|
||||||
|
multiDayInterval: 'hour' | 'day'
|
||||||
|
setMultiDayInterval: (interval: 'hour' | 'day') => void
|
||||||
}
|
}
|
||||||
|
|
||||||
type MetricType = 'pageviews' | 'visitors' | 'bounce_rate' | 'avg_duration'
|
type MetricType = 'pageviews' | 'visitors' | 'bounce_rate' | 'avg_duration'
|
||||||
@@ -159,7 +164,18 @@ function formatAxisValue(value: number): string {
|
|||||||
return String(value)
|
return String(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Chart({ data, prevData, stats, prevStats, interval }: ChartProps) {
|
export default function Chart({
|
||||||
|
data,
|
||||||
|
prevData,
|
||||||
|
stats,
|
||||||
|
prevStats,
|
||||||
|
interval,
|
||||||
|
dateRange,
|
||||||
|
todayInterval,
|
||||||
|
setTodayInterval,
|
||||||
|
multiDayInterval,
|
||||||
|
setMultiDayInterval
|
||||||
|
}: ChartProps) {
|
||||||
const [metric, setMetric] = useState<MetricType>('visitors')
|
const [metric, setMetric] = useState<MetricType>('visitors')
|
||||||
const [showComparison, setShowComparison] = useState(false)
|
const [showComparison, setShowComparison] = useState(false)
|
||||||
const { resolvedTheme } = useTheme()
|
const { resolvedTheme } = useTheme()
|
||||||
@@ -347,6 +363,29 @@ export default function Chart({ data, prevData, stats, prevStats, interval }: Ch
|
|||||||
|
|
||||||
{/* Right side: Controls */}
|
{/* Right side: Controls */}
|
||||||
<div className="flex items-center gap-3 self-end sm:self-auto">
|
<div className="flex items-center gap-3 self-end sm:self-auto">
|
||||||
|
{dateRange.start === dateRange.end && (
|
||||||
|
<Select
|
||||||
|
value={todayInterval}
|
||||||
|
onChange={(value) => setTodayInterval(value as 'minute' | 'hour')}
|
||||||
|
options={[
|
||||||
|
{ value: 'minute', label: '1 min' },
|
||||||
|
{ value: 'hour', label: '1 hour' },
|
||||||
|
]}
|
||||||
|
className="min-w-[100px]"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{dateRange.start !== dateRange.end && (
|
||||||
|
<Select
|
||||||
|
value={multiDayInterval}
|
||||||
|
onChange={(value) => setMultiDayInterval(value as 'hour' | 'day')}
|
||||||
|
options={[
|
||||||
|
{ value: 'hour', label: '1 hour' },
|
||||||
|
{ value: 'day', label: '1 day' },
|
||||||
|
]}
|
||||||
|
className="min-w-[100px]"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
{prevData?.length ? (
|
{prevData?.length ? (
|
||||||
<Checkbox
|
<Checkbox
|
||||||
checked={showComparison}
|
checked={showComparison}
|
||||||
|
|||||||
Reference in New Issue
Block a user