"use client"
import { useMemo } from "react"
import { Area, AreaChart, Bar, BarChart, CartesianGrid, Line, LineChart, XAxis } from "recharts"
import { intervalToDuration } from "date-fns"
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card"
import {
ChartContainer,
ChartTooltip,
ChartTooltipContent,
type ChartConfig,
} from "@/components/ui/chart"
import {
DashboardCardActionsDropdown,
DashboardOverviewCardV3,
} from "@/components/dashboards/dashboard-card"
import { DashboardWidgetWrapper } from "@/components/dashboards/dashboard-widget-wrapper"
import { formatDuration, formatPercent } from "@/lib/utils"
// --- Mock Data ---
interface OverviewType {
uniqueVisitors: {
averageValue: number
percentageChange: number
perMonth: { month: string; value: number }[]
}
averageSessionDuration: {
averageValue: number
percentageChange: number
perMonth: { month: string; value: number; fill: string }[]
}
bounceRate: {
averageValue: number
percentageChange: number
perMonth: { month: string; value: number }[]
}
conversionRate: {
averageValue: number
percentageChange: number
perMonth: { month: string; value: number }[]
}
}
export const overviewData: OverviewType = {
uniqueVisitors: {
averageValue: 15091.67,
percentageChange: 0.07,
perMonth: [
{ month: "January", value: 12000 },
{ month: "February", value: 16000 },
{ month: "March", value: 15050 },
{ month: "April", value: 14000 },
{ month: "May", value: 17500 },
{ month: "June", value: 16000 },
],
},
averageSessionDuration: {
averageValue: 73333.33,
percentageChange: -0.04,
perMonth: [
{ month: "January", value: 110000, fill: "var(--chart-1)" },
{ month: "February", value: -90000, fill: "var(--chart-2)" },
{ month: "March", value: 220000, fill: "var(--chart-1)" },
{ month: "April", value: -130000, fill: "var(--chart-2)" },
{ month: "May", value: 135000, fill: "var(--chart-1)" },
{ month: "June", value: 195000, fill: "var(--chart-1)" },
],
},
bounceRate: {
averageValue: 0.5933,
percentageChange: 0.05,
perMonth: [
{ month: "January", value: 0.12 },
{ month: "February", value: 0.55 },
{ month: "March", value: 0.68 },
{ month: "April", value: 0.48 },
{ month: "May", value: 0.7 },
{ month: "June", value: 0.53 },
],
},
conversionRate: {
averageValue: 0.5631,
percentageChange: 0.038,
perMonth: [
{ month: "January", value: 0.4 },
{ month: "February", value: 0.48 },
{ month: "March", value: 0.43 },
{ month: "April", value: 0.6 },
{ month: "May", value: 0.52 },
{ month: "June", value: 0.75 },
],
},
}
// --- Hooks ---
function useIsRtl() {
// Simplified for this demo
return false
}
function useRadius() {
return 8
}
// --- Chart Components ---
// 1. Unique Visitors Chart
const uniqueVisitorsConfig = {
value: {
label: "Visitors",
},
} satisfies ChartConfig
function UniqueVisitorsChart({
data,
}: {
data: OverviewType["uniqueVisitors"]["perMonth"]
}) {
const isRtl = useIsRtl()
return (
<ChartContainer
config={uniqueVisitorsConfig}
className="h-32 w-full rounded-b-md overflow-hidden"
>
<AreaChart
accessibilityLayer
data={data}
margin={{
left: 0,
right: 0,
}}
>
<CartesianGrid vertical={false} />
<XAxis
reversed={isRtl}
dataKey="month"
tickLine={false}
axisLine={false}
tickMargin={8}
hide
tickFormatter={(value) => value.slice(0, 3)}
/>
<ChartTooltip cursor={false} content={<ChartTooltipContent />} />
<Area
dataKey="value"
type="natural"
fill="var(--chart-1)"
fillOpacity={0.4}
stroke="var(--chart-1)"
/>
</AreaChart>
</ChartContainer>
)
}
function UniqueVisitors({
data,
}: {
data: OverviewType["uniqueVisitors"]
}) {
return (
<DashboardOverviewCardV3
data={{
value: data.averageValue,
percentageChange: data.percentageChange,
}}
title="Unique Visitors"
action={<DashboardCardActionsDropdown />}
chart={<UniqueVisitorsChart data={data.perMonth} />}
/>
)
}
// 2. Average Session Duration Chart
const avgSessionConfig = {
value: {
label: "Duration",
},
} satisfies ChartConfig
function ModifiedDurationTooltipContent(props: any) {
if (!props.payload || props.payload.length === 0) return null
return (
<ChartTooltipContent
{...props}
payload={props.payload.map((item: any) => ({
...item,
value: formatDuration(Number(item.value)),
}))}
/>
)
}
function AverageSessionDurationChart({
data,
}: {
data: OverviewType["averageSessionDuration"]["perMonth"]
}) {
const isRtl = useIsRtl()
const radius = useRadius()
return (
<ChartContainer
config={avgSessionConfig}
className="h-32 w-full rounded-b-md overflow-hidden"
>
<BarChart accessibilityLayer data={data}>
<CartesianGrid vertical={false} />
<ChartTooltip
cursor={false}
content={<ModifiedDurationTooltipContent />}
/>
<XAxis reversed={isRtl} dataKey="month" hide />
<Bar dataKey="value" barSize={44} radius={radius} />
</BarChart>
</ChartContainer>
)
}
function AverageSessionDuration({
data,
}: {
data: OverviewType["averageSessionDuration"]
}) {
return (
<DashboardOverviewCardV3
data={{
value: data.averageValue,
percentageChange: data.percentageChange,
}}
title="Avg. Session Duration"
action={<DashboardCardActionsDropdown />}
chart={<AverageSessionDurationChart data={data.perMonth} />}
formatStyle="duration"
/>
)
}
// 3. Bounce Rate Chart
const bounceRateConfig = {
value: {
label: "Rate",
},
} satisfies ChartConfig
function ModifiedPercentTooltipContent(props: any) {
if (!props.payload || props.payload.length === 0) return null
return (
<ChartTooltipContent
{...props}
payload={props.payload.map((item: any) => ({
...item,
value: formatPercent(Number(item.value)),
}))}
/>
)
}
function BounceRateChart({
data,
}: {
data: OverviewType["bounceRate"]["perMonth"]
}) {
const isRtl = useIsRtl()
return (
<ChartContainer
config={bounceRateConfig}
className="h-32 w-full rounded-b-md overflow-hidden"
>
<LineChart
accessibilityLayer
data={data}
margin={{
left: 0,
right: 0,
}}
>
<CartesianGrid vertical={false} />
<XAxis reversed={isRtl} dataKey="month" hide />
<ChartTooltip
cursor={false}
content={<ModifiedPercentTooltipContent />}
/>
<Line
dataKey="value"
type="linear"
stroke="var(--chart-3)"
strokeWidth={2}
dot={false}
/>
</LineChart>
</ChartContainer>
)
}
function BounceRate({ data }: { data: OverviewType["bounceRate"] }) {
return (
<DashboardOverviewCardV3
data={{
value: data.averageValue,
percentageChange: data.percentageChange,
}}
title="Bounce Rate"
action={<DashboardCardActionsDropdown />}
chart={<BounceRateChart data={data.perMonth} />}
formatStyle="percent"
/>
)
}
// 4. Conversion Rate Chart
const conversionRateConfig = {
value: {
label: "Rate",
},
} satisfies ChartConfig
function ConversionRateChart({
data,
}: {
data: OverviewType["conversionRate"]["perMonth"]
}) {
const isRtl = useIsRtl()
return (
<ChartContainer
config={conversionRateConfig}
className="h-32 w-full rounded-b-md overflow-hidden"
>
<AreaChart
accessibilityLayer
data={data}
margin={{
left: 0,
right: 0,
}}
>
<CartesianGrid vertical={false} />
<XAxis reversed={isRtl} dataKey="month" hide />
<ChartTooltip
cursor={false}
content={<ModifiedPercentTooltipContent />}
/>
<Area
dataKey="value"
type="step"
fill="var(--chart-4)"
stroke="var(--chart-4)"
strokeWidth={2}
dot={false}
/>
</AreaChart>
</ChartContainer>
)
}
function ConversionRate({
data,
}: {
data: OverviewType["conversionRate"]
}) {
return (
<DashboardOverviewCardV3
data={{
value: data.averageValue,
percentageChange: data.percentageChange,
}}
title="Conversion Rate"
action={<DashboardCardActionsDropdown />}
chart={<ConversionRateChart data={data.perMonth} />}
formatStyle="percent"
/>
)
}
// --- Main Widget Component ---
export function WidgetAnalyticsOverview() {
return (
<DashboardWidgetWrapper>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 md:col-span-full md:grid-cols-4">
<UniqueVisitors data={overviewData.uniqueVisitors} />
<AverageSessionDuration data={overviewData.averageSessionDuration} />
<BounceRate data={overviewData.bounceRate} />
<ConversionRate data={overviewData.conversionRate} />
</div>
</DashboardWidgetWrapper>
)
}