chore: finish frontend ESLint migration #18

Enable every plugin recommended preset and replace Biome with ESLint formatting.

Preserve API contracts and JSX whitespace; verify source, tests, builds and tooling.
This commit is contained in:
2026-09-28 16:36:40 +03:00
committed by ksv741
parent 57630102e4
commit 72d7835227
253 changed files with 10059 additions and 8864 deletions
@@ -1,53 +1,54 @@
import { useEffect, useState } from "react";
import { useParams, useSearchParams } from "react-router";
import { z } from "zod";
import {
type BrokerageEvent,
useBrokerageEvents,
} from "@/entities/brokerage-event";
import { useScreenSync } from "@/features/tbank-connection";
type AccountEventsPageViewModel =
| { state: "loading" }
| { state: "error"; retry: () => void; onReset: () => void }
| {
state: "loaded";
events: BrokerageEvent[];
sourceError?: boolean;
lastSuccessfulAt?: string | null;
partial?: boolean;
refreshing: boolean;
refreshError: boolean;
retry: () => void;
draftFrom: string | null;
draftTo: string | null;
canApply: boolean;
onDraftFromChange: (value: string | null) => void;
onDraftToChange: (value: string | null) => void;
onApply: () => void;
onReset: () => void;
};
type AccountEventsPageViewModel
= | {
canApply: boolean;
draftFrom: null | string;
draftTo: null | string;
events: BrokerageEvent[];
lastSuccessfulAt?: null | string;
onApply: () => void;
onDraftFromChange: (value: null | string) => void;
onDraftToChange: (value: null | string) => void;
onReset: () => void;
partial?: boolean;
refreshError: boolean;
refreshing: boolean;
retry: () => void;
sourceError?: boolean;
state: "loaded";
}
| { onReset: () => void; retry: () => void; state: "error" }
| { state: "loading" };
function useAccountEventsPageViewModel(
scopeId?: string,
): AccountEventsPageViewModel {
const { accountId: routeAccountId } = useParams();
const accountId = scopeId ?? routeAccountId ?? "";
const [searchParams, setSearchParams] = useSearchParams();
const urlFrom = searchParams.get("from");
const urlTo = searchParams.get("to");
const validUrlPeriod = isValidPeriod(urlFrom, urlTo);
const appliedFrom = validUrlPeriod ? urlFrom : null;
const appliedTo = validUrlPeriod ? urlTo : null;
const [draftFrom, setDraftFrom] = useState<string | null>(appliedFrom);
const [draftTo, setDraftTo] = useState<string | null>(appliedTo);
const [searchParameters, setSearchParameters] = useSearchParams();
const urlFrom = searchParameters.get("from");
const urlTo = searchParameters.get("to");
const isValidUrlPeriod = isValidPeriod(urlFrom, urlTo);
const appliedFrom = isValidUrlPeriod ? urlFrom : /* eslint-disable-line unicorn/no-null -- Preserve the nullable domain value consumed by this view model. */ null;
const appliedTo = isValidUrlPeriod ? urlTo : /* eslint-disable-line unicorn/no-null -- Preserve the nullable domain value consumed by this view model. */ null;
const [draftFrom, setDraftFrom] = useState<null | string>(appliedFrom);
const [draftTo, setDraftTo] = useState<null | string>(appliedTo);
useEffect(() => {
if (validUrlPeriod) return;
const normalized = new URLSearchParams(searchParams);
if (isValidUrlPeriod) return;
const normalized = new URLSearchParams(searchParameters);
normalized.delete("from");
normalized.delete("to");
setSearchParams(normalized, { replace: true });
}, [validUrlPeriod, searchParams, setSearchParams]);
setSearchParameters(normalized, { replace: true });
}, [isValidUrlPeriod, searchParameters, setSearchParameters]);
const [previousPeriod, setPreviousPeriod] = useState([
appliedFrom,
appliedTo,
@@ -58,69 +59,69 @@ function useAccountEventsPageViewModel(
setDraftTo(appliedTo);
}
const events = useBrokerageEvents(accountId, {
...(appliedFrom ? { from: appliedFrom } : {}),
...(appliedTo ? { to: appliedTo } : {}),
...(appliedFrom && { from: appliedFrom }),
...(appliedTo && { to: appliedTo }),
});
const sync = useScreenSync(
{
screen: "events",
accountId,
...(appliedFrom ? { from: appliedFrom } : {}),
...(appliedTo ? { to: appliedTo } : {}),
screen: "events",
...(appliedFrom && { from: appliedFrom }),
...(appliedTo && { to: appliedTo }),
},
[events],
);
if (events.isLoading) return { state: "loading" };
const onReset = () => {
setDraftFrom(null);
setDraftTo(null);
setSearchParams({});
setSearchParameters({});
};
if (events.isLoading) return { state: "loading" };
if ((events.isError || events.meta?.sync.state === "failed") && !events.data)
return {
state: "error",
onReset,
retry: () => {
void sync.retry();
},
state: "error",
};
if (!events.data) return { state: "loading" };
return {
state: "loaded",
canApply:
(draftFrom !== appliedFrom || draftTo !== appliedTo)
&& isValidPeriod(draftFrom, draftTo),
draftFrom,
draftTo,
events: events.data.events,
sourceError: sync.sourceError,
lastSuccessfulAt: events.meta?.lastSuccessfulAt,
onApply: () => {
if (!isValidPeriod(draftFrom, draftTo)) return;
setSearchParameters({
...(draftFrom && { from: draftFrom }),
...(draftTo && { to: draftTo }),
});
},
onDraftFromChange: setDraftFrom,
onDraftToChange: setDraftTo,
onReset,
partial: events.meta?.availability !== "complete",
refreshing: events.isFetching || sync.refreshing,
refreshError: events.isError || sync.sourceError || sync.transportError,
refreshing: events.isFetching || sync.refreshing,
retry: () => {
void sync.retry();
},
draftFrom,
draftTo,
canApply:
(draftFrom !== appliedFrom || draftTo !== appliedTo) &&
isValidPeriod(draftFrom, draftTo),
onDraftFromChange: setDraftFrom,
onDraftToChange: setDraftTo,
onApply: () => {
if (!isValidPeriod(draftFrom, draftTo)) return;
setSearchParams({
...(draftFrom ? { from: draftFrom } : {}),
...(draftTo ? { to: draftTo } : {}),
});
},
onReset,
sourceError: sync.sourceError,
state: "loaded",
};
}
const calendarDate = z.string().date();
function isValidPeriod(from: string | null, to: string | null) {
const calendarDate = z.iso.date();
function isValidPeriod(from: null | string, to: null | string) {
return (
[from, to].every(
(date) => date === null || calendarDate.safeParse(date).success,
) &&
(!from || !to || from <= to)
date => date === null || calendarDate.safeParse(date).success,
)
&& (!from || !to || from <= to)
);
}