diff --git a/src/lib/query/dashboard.ts b/src/lib/query/dashboard.ts index 415dace6..c6d87c4c 100644 --- a/src/lib/query/dashboard.ts +++ b/src/lib/query/dashboard.ts @@ -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"; @@ -77,7 +77,6 @@ export function fetchDashboardSalesStatisticsOptions( .then((res) => ({ ...res, headers: null })), enabled: isEnabled(options), staleTime: 1000 * 60 * 1, // 1 minute - placeholderData: keepPreviousData, }); } @@ -117,7 +116,6 @@ export function fetchDashboardRentalStatisticsOptions( .then((res) => ({ ...res, headers: null })), enabled: isEnabled(options), staleTime: 1000 * 60 * 1, // 1 minute - placeholderData: keepPreviousData, }); } @@ -160,7 +158,6 @@ export function fetchDashboardVehicleStatusCountsOptions( .then((res) => ({ ...res, headers: null })), enabled: isEnabled(options), staleTime: 1000 * 60 * 1, // 1 minute - placeholderData: keepPreviousData, }); } diff --git a/src/routes/_auth/(dashboard)/-components/widget-grid/widgets/sales-status.tsx b/src/routes/_auth/(dashboard)/-components/widget-grid/widgets/sales-status.tsx index 96aae1ee..b6e23a08 100644 --- a/src/routes/_auth/(dashboard)/-components/widget-grid/widgets/sales-status.tsx +++ b/src/routes/_auth/(dashboard)/-components/widget-grid/widgets/sales-status.tsx @@ -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"; @@ -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 ( + +
+ {widgetName} + +
+ }> + + +
+ ); +} + const chartConfig = { previousTotal: { label: "Last year", @@ -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 ( - -
- {widgetName} - -
- {salesQuery.status === "pending" ? ( - - ) : ( - - - - - } - formatter={(value) => - t("intlCurrency", { - value: Number(value ?? 0), - ns: "format", - }) - } - /> - - - - - )} -
+ + + + + } + formatter={(value) => + t("intlCurrency", { + value: Number(value ?? 0), + ns: "format", + }) + } + /> + + + + ); } diff --git a/src/routes/_auth/(dashboard)/-components/widget-grid/widgets/vehicle-status.tsx b/src/routes/_auth/(dashboard)/-components/widget-grid/widgets/vehicle-status.tsx index 1070a7cd..4dd28c12 100644 --- a/src/routes/_auth/(dashboard)/-components/widget-grid/widgets/vehicle-status.tsx +++ b/src/routes/_auth/(dashboard)/-components/widget-grid/widgets/vehicle-status.tsx @@ -1,5 +1,5 @@ import * as React from "react"; -import { useQuery } from "@tanstack/react-query"; +import { useQuery, useSuspenseQuery } from "@tanstack/react-query"; import { Link } from "@tanstack/react-router"; import { Button, buttonVariants } from "@/components/ui/button"; @@ -43,55 +43,18 @@ import { cn } from "@/lib/utils/styles"; import { WidgetSkeleton, type CommonWidgetProps } from "./_common"; export default function VehicleStatusWidget(props: CommonWidgetProps) { - const { auth, selectedLocationIds, widgetId } = props; - - const widgetName = useWidgetName(widgetId); + const widgetName = useWidgetName(props.widgetId); const [vehicleTypeId, setVehicleTypeId] = React.useState("0"); - const statusCounts = useQuery( - fetchDashboardVehicleStatusCountsOptions({ - auth: auth, - filters: { - vehicleTypeId, - locationIds: selectedLocationIds, - clientDate: new Date(), - }, - }) - ); - - const data = statusCounts.data?.status === 200 ? statusCounts.data?.body : []; - - const vehicleStatuses = useQuery( - fetchVehiclesStatusesOptions({ auth: props.auth }) + const vehicleTypesList = useQuery( + fetchVehiclesTypesOptions({ auth: props.auth }) ); - - const getStatusIdByName = React.useCallback( - (name: string) => { - const status = vehicleStatuses.data?.find((s) => s.name === name); - return status?.id || 0; - }, - [vehicleStatuses.data] + const vehicleTypes = React.useMemo( + () => vehicleTypesList.data ?? [], + [vehicleTypesList.data] ); - const sortedData = data.sort((a, b) => { - if (a.total < b.total) return 1; - if (a.total > b.total) return -1; - return 0; - }); - - const totalVehicles = sortedData.reduce((acc, item) => acc + item.total, 0); - - const vehicleTypesList = useQuery(fetchVehiclesTypesOptions({ auth })); - - const vehicleTypes = vehicleTypesList.data ?? []; - - const [rowCountStr] = useLocalStorage( - STORAGE_KEYS.tableRowCount, - STORAGE_DEFAULTS.tableRowCount - ); - const defaultRowCount = parseInt(rowCountStr, 10); - return (
@@ -127,36 +90,90 @@ export default function VehicleStatusWidget(props: CommonWidgetProps) {
- {statusCounts.status === "pending" ? ( - - ) : totalVehicles <= 0 ? ( - - ) : ( - -
- {sortedData.map((item, idx) => ( - - ))} -
-
- )} + }> + +
); } +function VehicleStatusChart( + props: CommonWidgetProps & { vehicleTypeId: string } +) { + const statusCountQuery = useSuspenseQuery( + fetchDashboardVehicleStatusCountsOptions({ + auth: props.auth, + filters: { + vehicleTypeId: props.vehicleTypeId, + locationIds: props.selectedLocationIds, + clientDate: new Date(), + }, + }) + ); + + const data = React.useMemo( + () => + statusCountQuery.data.status === 200 ? statusCountQuery.data.body : [], + [statusCountQuery.data.body, statusCountQuery.data.status] + ); + + const vehicleStatusesQuery = useSuspenseQuery( + fetchVehiclesStatusesOptions({ auth: props.auth }) + ); + + const vehicleStatuses = React.useMemo( + () => vehicleStatusesQuery.data ?? [], + [vehicleStatusesQuery.data] + ); + + const getStatusIdByName = React.useCallback( + (name: string) => { + const status = vehicleStatuses.find((s) => s.name === name); + return status?.id || 0; + }, + [vehicleStatuses] + ); + + const sortedData = data.sort((a, b) => { + if (a.total < b.total) return 1; + if (a.total > b.total) return -1; + return 0; + }); + + const totalVehicles = sortedData.reduce((acc, item) => acc + item.total, 0); + + const [rowCountStr] = useLocalStorage( + STORAGE_KEYS.tableRowCount, + STORAGE_DEFAULTS.tableRowCount + ); + const defaultRowCount = parseInt(rowCountStr, 10); + + return totalVehicles <= 0 ? ( + + ) : ( + +
+ {sortedData.map((item, idx) => ( + + ))} +
+
+ ); +} + interface VehicleStatusItemProps { item: VehicleStatusCountResponse; totalItems: number;