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:
+40
-36
@@ -1,38 +1,44 @@
|
||||
import { Paper, Stack, Text, Title } from "@mantine/core";
|
||||
import type { FC } from "react";
|
||||
|
||||
import { Paper, Stack, Text, Title } from "@mantine/core";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { formatMoney } from "@/shared/lib";
|
||||
import classes from "../AccountIncomePage.module.css";
|
||||
|
||||
import type { IncomeDisplayModel } from "../AccountIncomePage.vm";
|
||||
|
||||
type IncomeComparisonsProps = {
|
||||
comparison: IncomeDisplayModel["comparison"];
|
||||
title: string;
|
||||
notice: string;
|
||||
};
|
||||
import classes from "../AccountIncomePage.module.css";
|
||||
|
||||
type ComparisonProps = NonNullable<IncomeDisplayModel["comparison"]> & {
|
||||
title: string;
|
||||
};
|
||||
type ComparisonValuesProps = {
|
||||
kind: "selected" | "compared" | "difference";
|
||||
kind: "compared" | "difference" | "selected";
|
||||
label: string;
|
||||
values: ComparisonProps["values"][number]["selected"];
|
||||
percentages?: ComparisonProps["values"][number]["percentages"];
|
||||
values: ComparisonProps["values"][number]["selected"];
|
||||
};
|
||||
type IncomeComparisonsProps = {
|
||||
comparison: IncomeDisplayModel["comparison"];
|
||||
notice: string;
|
||||
title: string;
|
||||
};
|
||||
|
||||
const IncomeComparisons: FC<IncomeComparisonsProps> = (props) => {
|
||||
return (
|
||||
<Stack>
|
||||
<Title order={2}>{props.title}</Title>
|
||||
{props.comparison ? (
|
||||
<Comparison {...props.comparison} title={props.title} />
|
||||
) : (
|
||||
<Paper p="sm" radius="md" className={classes.comparisonNotice}>
|
||||
<Text size="sm" c="gray.7" role="status" aria-live="polite">
|
||||
{props.notice}
|
||||
</Text>
|
||||
</Paper>
|
||||
)}
|
||||
{props.comparison
|
||||
? (
|
||||
<Comparison {...props.comparison} title={props.title} />
|
||||
)
|
||||
: (
|
||||
<Paper className={classes.comparisonNotice} p="sm" radius="md">
|
||||
<Text aria-live="polite" c="gray.7" role="status" size="sm">
|
||||
{props.notice}
|
||||
</Text>
|
||||
</Paper>
|
||||
)}
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
@@ -42,12 +48,12 @@ const Comparison: FC<ComparisonProps> = (props) => {
|
||||
return (
|
||||
<section aria-label={props.title} className={classes.comparison}>
|
||||
<Stack gap="md">
|
||||
{props.values.map((value) => (
|
||||
{props.values.map(value => (
|
||||
<Stack
|
||||
aria-label={value.currency}
|
||||
gap="xs"
|
||||
key={value.currency}
|
||||
role="group"
|
||||
aria-label={value.currency}
|
||||
>
|
||||
<div className={classes.comparisonGrid}>
|
||||
<ComparisonValues
|
||||
@@ -63,17 +69,17 @@ const Comparison: FC<ComparisonProps> = (props) => {
|
||||
<ComparisonValues
|
||||
kind="difference"
|
||||
label={t("income.difference")}
|
||||
values={value.difference}
|
||||
percentages={value.percentages}
|
||||
values={value.difference}
|
||||
/>
|
||||
</div>
|
||||
</Stack>
|
||||
))}
|
||||
{props.values.length === 0 ? (
|
||||
<Text size="sm" c="gray.7">
|
||||
{props.values.length === 0 && ((
|
||||
<Text c="gray.7" size="sm">
|
||||
{t("income.comparisonEmpty")}
|
||||
</Text>
|
||||
) : null}
|
||||
))}
|
||||
</Stack>
|
||||
</section>
|
||||
);
|
||||
@@ -87,30 +93,28 @@ const ComparisonValues: FC<ComparisonValuesProps> = (props) => {
|
||||
className={classes.comparisonPanel}
|
||||
data-kind={props.kind}
|
||||
data-tone={
|
||||
props.kind === "difference"
|
||||
? differenceTone(props.values.total.value)
|
||||
: undefined
|
||||
(props.kind === "difference") ? (differenceTone(props.values.total.value)) : undefined
|
||||
}
|
||||
>
|
||||
<Text size="sm" fw={600} className={classes.comparisonLabel}>
|
||||
<Text className={classes.comparisonLabel} fw={600} size="sm">
|
||||
{props.label}
|
||||
</Text>
|
||||
<dl className={classes.comparisonValues}>
|
||||
{(["total", "coupon", "dividend"] as const).map((key) => {
|
||||
const money = props.values[key];
|
||||
const percentage = props.percentages?.[key];
|
||||
const tone =
|
||||
props.kind === "difference"
|
||||
const money = /* eslint-disable-line security/detect-object-injection -- This lookup uses a fixed typed key set, not an arbitrary external property name. */ props.values[key];
|
||||
const percentage = /* eslint-disable-line security/detect-object-injection -- This lookup uses a fixed typed key set, not an arbitrary external property name. */ props.percentages?.[key];
|
||||
const tone
|
||||
= props.kind === "difference"
|
||||
? differenceTone(money.value)
|
||||
: undefined;
|
||||
return (
|
||||
<div
|
||||
key={key}
|
||||
className={
|
||||
key === "total"
|
||||
? classes.comparisonTotal
|
||||
: classes.comparisonDetail
|
||||
}
|
||||
key={key}
|
||||
>
|
||||
<dt>{t(`income.${key}`)}</dt>
|
||||
<dd data-tone={tone}>
|
||||
@@ -118,11 +122,11 @@ const ComparisonValues: FC<ComparisonValuesProps> = (props) => {
|
||||
{tone === "positive" ? "+" : ""}
|
||||
{formatMoney(money)}
|
||||
</span>
|
||||
{percentage ? (
|
||||
{!!(percentage) && ((
|
||||
<span className={classes.comparisonPercent}>
|
||||
{percentage}
|
||||
</span>
|
||||
) : null}
|
||||
))}
|
||||
</dd>
|
||||
</div>
|
||||
);
|
||||
@@ -132,7 +136,7 @@ const ComparisonValues: FC<ComparisonValuesProps> = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
function differenceTone(value: string): "positive" | "negative" | "neutral" {
|
||||
function differenceTone(value: string): "negative" | "neutral" | "positive" {
|
||||
if (!/[1-9]/.test(value)) return "neutral";
|
||||
return value.startsWith("-") ? "negative" : "positive";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user