add range picker on dashboard
This commit is contained in:
@@ -4,12 +4,16 @@ import { api } from "@/utils/api";
|
|||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { PageTitle } from "@/components/PageTitle";
|
import { PageTitle } from "@/components/PageTitle";
|
||||||
import { useOrganizationParams } from "@/hooks/useOrganizationParams";
|
import { useOrganizationParams } from "@/hooks/useOrganizationParams";
|
||||||
import { Suspense, useMemo } from "react";
|
import { Suspense, useMemo, useState } from "react";
|
||||||
import { createServerSideProps } from "@/server/getServerSideProps";
|
import { createServerSideProps } from "@/server/getServerSideProps";
|
||||||
import { Chart } from "@/components/report/chart";
|
import { Chart } from "@/components/report/chart";
|
||||||
import { timeRanges } from "@/utils/constants";
|
import { timeRanges } from "@/utils/constants";
|
||||||
|
import { type IChartRange } from "@/types";
|
||||||
|
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
|
||||||
|
import { cn } from "@/utils/cn";
|
||||||
|
import { getRangeLabel } from "@/utils/getRangeLabel";
|
||||||
|
|
||||||
export const getServerSideProps = createServerSideProps()
|
export const getServerSideProps = createServerSideProps();
|
||||||
|
|
||||||
export default function Dashboard() {
|
export default function Dashboard() {
|
||||||
const params = useOrganizationParams();
|
const params = useOrganizationParams();
|
||||||
@@ -22,16 +26,35 @@ export default function Dashboard() {
|
|||||||
const dashboard = query.data?.dashboard ?? null;
|
const dashboard = query.data?.dashboard ?? null;
|
||||||
const reports = useMemo(() => {
|
const reports = useMemo(() => {
|
||||||
return query.data?.reports ?? [];
|
return query.data?.reports ?? [];
|
||||||
}, [query])
|
}, [query]);
|
||||||
|
|
||||||
|
const [range, setRange] = useState<null | IChartRange>(null);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MainLayout>
|
<MainLayout>
|
||||||
<Container>
|
<Container>
|
||||||
<Suspense fallback="Loading">
|
<Suspense fallback="Loading">
|
||||||
<PageTitle>{dashboard?.name}</PageTitle>
|
<PageTitle>{dashboard?.name}</PageTitle>
|
||||||
|
|
||||||
|
<RadioGroup className="mb-8">
|
||||||
|
{timeRanges.map((item) => {
|
||||||
|
return (
|
||||||
|
<RadioGroupItem
|
||||||
|
key={item.range}
|
||||||
|
active={item.range === range}
|
||||||
|
onClick={() => {
|
||||||
|
setRange((p) => (p === item.range ? null : item.range));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{item.title}
|
||||||
|
</RadioGroupItem>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</RadioGroup>
|
||||||
|
|
||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-2 gap-4">
|
||||||
{reports.map((report) => {
|
{reports.map((report) => {
|
||||||
const range = timeRanges.find((item) => item.range === report.range)
|
const chartRange = getRangeLabel(report.range);
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="rounded-md border border-border bg-white shadow"
|
className="rounded-md border border-border bg-white shadow"
|
||||||
@@ -42,13 +65,22 @@ export default function Dashboard() {
|
|||||||
className="block border-b border-border p-4 leading-none hover:underline"
|
className="block border-b border-border p-4 leading-none hover:underline"
|
||||||
>
|
>
|
||||||
<div className="font-medium">{report.name}</div>
|
<div className="font-medium">{report.name}</div>
|
||||||
{range && <div className="text-sm mt-2">{range.title}</div>}
|
{chartRange && (
|
||||||
|
<div className="mt-2 text-sm flex gap-2">
|
||||||
|
<span className={range ? "line-through" : ""}>{chartRange}</span>
|
||||||
|
{range && <span>{getRangeLabel(range)}</span>}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</Link>
|
</Link>
|
||||||
<div className="p-4 pl-2 aspect-[1.8/1] overflow-auto">
|
<div className="aspect-[1.8/1] overflow-auto p-4 pl-2">
|
||||||
<Chart {...report} editMode={false} />
|
<Chart
|
||||||
|
{...report}
|
||||||
|
range={range ?? report.range}
|
||||||
|
editMode={false}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
|
|||||||
8
apps/web/src/utils/getRangeLabel.ts
Normal file
8
apps/web/src/utils/getRangeLabel.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { type IChartRange } from "@/types";
|
||||||
|
import { timeRanges } from "./constants";
|
||||||
|
|
||||||
|
export function getRangeLabel(range: IChartRange) {
|
||||||
|
return timeRanges.find(
|
||||||
|
(item) => item.range === range,
|
||||||
|
)?.title ?? null
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user