Skip to content

Commit

Permalink
fix: layout shift with the dashboard sales and vehicle status widgets
Browse files Browse the repository at this point in the history
  • Loading branch information
SeanCassiere committed Aug 2, 2024
1 parent a9cbb30 commit 0002891
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 152 deletions.
5 changes: 1 addition & 4 deletions src/lib/query/dashboard.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { keepPreviousData, queryOptions } from "@tanstack/react-query";
import { queryOptions } from "@tanstack/react-query";

import { getDashboardMessagesAndFilter } from "@/lib/api/get-dashboard-messages";
import { saveDashboardWidgets } from "@/lib/api/save-dashboard-widgets";
Expand Down Expand Up @@ -77,7 +77,6 @@ export function fetchDashboardSalesStatisticsOptions(
.then((res) => ({ ...res, headers: null })),
enabled: isEnabled(options),
staleTime: 1000 * 60 * 1, // 1 minute
placeholderData: keepPreviousData,
});
}

Expand Down Expand Up @@ -117,7 +116,6 @@ export function fetchDashboardRentalStatisticsOptions(
.then((res) => ({ ...res, headers: null })),
enabled: isEnabled(options),
staleTime: 1000 * 60 * 1, // 1 minute
placeholderData: keepPreviousData,
});
}

Expand Down Expand Up @@ -160,7 +158,6 @@ export function fetchDashboardVehicleStatusCountsOptions(
.then((res) => ({ ...res, headers: null })),
enabled: isEnabled(options),
staleTime: 1000 * 60 * 1, // 1 minute
placeholderData: keepPreviousData,
});
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from "react";
import { useQuery } from "@tanstack/react-query";
import { useSuspenseQuery } from "@tanstack/react-query";
import { useTranslation } from "react-i18next";
import { CartesianGrid, Line, LineChart, XAxis } from "recharts";

Expand All @@ -18,6 +18,30 @@ import { useWidgetName } from "@/routes/_auth/(dashboard)/-components/useWidgetN

import { WidgetSkeleton, type CommonWidgetProps } from "./_common";

export default function SalesStatusWidget(props: CommonWidgetProps) {
const widgetName = useWidgetName(props.widgetId);

return (
<React.Fragment>
<div className="flex max-h-8 shrink-0 items-center justify-between gap-2">
<span className="font-medium">{widgetName}</span>
<Button
type="button"
variant="ghost"
className="h-8"
{...props.draggableAttributes}
{...props.draggableListeners}
>
<icons.GripVertical className="h-3 w-3" />
</Button>
</div>
<React.Suspense fallback={<WidgetSkeleton />}>
<SalesChart locations={props.selectedLocationIds} auth={props.auth} />
</React.Suspense>
</React.Fragment>
);
}

const chartConfig = {
previousTotal: {
label: "Last year",
Expand All @@ -29,93 +53,81 @@ const chartConfig = {
},
} satisfies ChartConfig;

export default function SalesStatusWidget(props: CommonWidgetProps) {
const { auth, selectedLocationIds, widgetId } = props;

const widgetName = useWidgetName(widgetId);

function SalesChart({
locations,
auth,
}: {
locations: CommonWidgetProps["selectedLocationIds"];
auth: CommonWidgetProps["auth"];
}) {
const { t } = useTranslation();
const salesQuery = useQuery(

const query = useSuspenseQuery(
fetchDashboardSalesStatisticsOptions({
auth,
filters: {
locationIds: selectedLocationIds,
locationIds: locations,
clientDate: new Date(),
},
})
);

const sales = salesQuery.data?.status === 200 ? salesQuery.data.body : [];
const sales = React.useMemo(
() => (query.data.status === 200 ? query.data.body : []),
[query.data.status, query.data.body]
);

return (
<React.Fragment>
<div className="flex max-h-8 shrink-0 items-center justify-between gap-2">
<span className="font-medium">{widgetName}</span>
<Button
type="button"
variant="ghost"
className="h-8"
{...props.draggableAttributes}
{...props.draggableListeners}
>
<icons.GripVertical className="h-3 w-3" />
</Button>
</div>
{salesQuery.status === "pending" ? (
<WidgetSkeleton />
) : (
<ChartContainer config={chartConfig} className="min-h-[250px] w-full">
<LineChart
accessibilityLayer
data={sales}
margin={{
left: 12,
right: 12,
}}
>
<CartesianGrid vertical={false} />
<XAxis
dataKey="monthName"
tickLine={false}
axisLine={false}
tickMargin={8}
/>
<ChartTooltip
content={<ChartTooltipContent indicator="dot" />}
formatter={(value) =>
t("intlCurrency", {
value: Number(value ?? 0),
ns: "format",
})
}
/>
<Line
dataKey="total"
type="monotone"
stroke="var(--color-total)"
strokeWidth={2}
dot={{
fill: "var(--color-total)",
}}
activeDot={{
r: 6,
}}
/>
<Line
dataKey="previousTotal"
type="monotone"
stroke="var(--color-previousTotal)"
strokeWidth={2}
dot={{
fill: "var(--color-previousTotal)",
}}
activeDot={{
r: 6,
}}
/>
</LineChart>
</ChartContainer>
)}
</React.Fragment>
<ChartContainer config={chartConfig} className="min-h-[250px] w-full">
<LineChart
accessibilityLayer
data={sales}
margin={{
left: 12,
right: 12,
}}
>
<CartesianGrid vertical={false} />
<XAxis
dataKey="monthName"
tickLine={false}
axisLine={false}
tickMargin={8}
/>
<ChartTooltip
content={<ChartTooltipContent indicator="dot" />}
formatter={(value) =>
t("intlCurrency", {
value: Number(value ?? 0),
ns: "format",
})
}
/>
<Line
dataKey="total"
type="monotone"
stroke="var(--color-total)"
strokeWidth={2}
dot={{
fill: "var(--color-total)",
}}
activeDot={{
r: 6,
}}
/>
<Line
dataKey="previousTotal"
type="monotone"
stroke="var(--color-previousTotal)"
strokeWidth={2}
dot={{
fill: "var(--color-previousTotal)",
}}
activeDot={{
r: 6,
}}
/>
</LineChart>
</ChartContainer>
);
}
Loading

0 comments on commit 0002891

Please sign in to comment.