feat(cards): filter operations by date range

This commit is contained in:
2026-09-12 21:52:13 +03:00
parent 8e58c016d2
commit 9bb385b9f0
7 changed files with 188 additions and 47 deletions
+39 -13
View File
@@ -11,8 +11,8 @@ import {
Text,
Title,
} from "@mantine/core";
import { MonthPickerInput } from "@mantine/dates";
import { type FC, useLayoutEffect, useRef } from "react";
import { DatePickerInput } from "@mantine/dates";
import { type FC, useLayoutEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { Link } from "react-router";
import {
@@ -25,6 +25,39 @@ import { EntryCard, LoadingSkeleton, StateView } from "@/shared/ui";
import classes from "./CardPage.module.css";
import type { CardPageVm } from "./CardPage.vm";
type PeriodPickerProps = {
period: CardPageVm["period"];
onChange: CardPageVm["setPeriod"];
};
const PeriodPicker: FC<PeriodPickerProps> = (props) => {
const { period, onChange } = props;
const { t } = useTranslation();
const scope = `${period.from}-${period.to}`;
const [draft, setDraft] = useState<{
scope: string;
value: [string | null, string | null];
}>();
const value: [string | null, string | null] =
draft?.scope === scope ? draft.value : [period.from, period.to];
return (
<DatePickerInput
type="range"
allowSingleDateInRange
label={t("bank.period")}
valueFormat="DD.MM.YYYY"
value={value}
onChange={(next) => {
setDraft({ scope, value: next });
onChange(next);
}}
popoverProps={{
returnFocus: true,
middlewares: { shift: { crossAxis: true } },
}}
/>
);
};
type CardPageViewProps = { vm: CardPageVm };
const CardPageView: FC<CardPageViewProps> = (props) => {
const { vm } = props;
@@ -36,7 +69,7 @@ const CardPageView: FC<CardPageViewProps> = (props) => {
page: number;
top: number;
} | null>(null);
const scope = `${card?.id}-${vm.month}-${vm.pageSize}`;
const scope = `${card?.id}-${vm.period.from}-${vm.period.to}-${vm.pageSize}`;
useLayoutEffect(() => {
const pending = pendingPage.current;
if (!pending) return;
@@ -143,14 +176,7 @@ const CardPageView: FC<CardPageViewProps> = (props) => {
retry={() => void vm.cards.refetch()}
/>
)}
<MonthPickerInput
label={t("bank.month")}
value={`${vm.month}-01`}
onChange={(value) => {
if (value) vm.setMonth(value.slice(0, 7));
}}
popoverProps={{ middlewares: { shift: { crossAxis: true } } }}
/>
<PeriodPicker period={vm.period} onChange={vm.setPeriod} />
<BankSummaryView
data={vm.summary.data}
loading={vm.summary.isLoading}
@@ -177,7 +203,7 @@ const CardPageView: FC<CardPageViewProps> = (props) => {
/>
</Group>
<Stack
key={`${vm.month}-${vm.pageSize}-${vm.history.data?.page ?? "loading"}`}
key={`${vm.period.from}-${vm.period.to}-${vm.pageSize}-${vm.history.data?.page ?? "loading"}`}
gap="lg"
className={classes.operations}
aria-busy={vm.history.isFetching}
@@ -209,7 +235,7 @@ const CardPageView: FC<CardPageViewProps> = (props) => {
row.otherCard ? (
<Anchor
component={Link}
to={`/cards/${row.otherCard}?month=${vm.month}`}
to={`/cards/${row.otherCard}?from=${vm.period.from}&to=${vm.period.to}`}
>
{t("bank.card")}
</Anchor>