feat: group all-account rows by instrument and day (WealthLedger/main#47) (#126)
This commit was merged in pull request #126.
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
.group {
|
||||
overflow: hidden;
|
||||
border-color: var(--wl-color-border);
|
||||
background: var(--wl-color-subtle);
|
||||
}
|
||||
|
||||
.accounts {
|
||||
padding: 0 var(--mantine-spacing-md) var(--mantine-spacing-sm);
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.accountRow {
|
||||
display: flex;
|
||||
gap: var(--mantine-spacing-sm);
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: var(--mantine-spacing-sm) 0;
|
||||
border-top: 1px solid var(--wl-color-border);
|
||||
}
|
||||
|
||||
.accountValue {
|
||||
flex-shrink: 0;
|
||||
text-align: right;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.accountCardRow {
|
||||
display: flex;
|
||||
gap: var(--mantine-spacing-sm);
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: var(--mantine-spacing-sm) var(--mantine-spacing-md);
|
||||
border-color: var(--wl-color-border);
|
||||
background: var(--wl-color-surface);
|
||||
}
|
||||
|
||||
@media (max-width: 36em) {
|
||||
.accountRow {
|
||||
align-items: flex-start;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
import type { FC, PropsWithChildren, ReactNode } from "react";
|
||||
|
||||
import { Paper, Stack, Text, VisuallyHidden } from "@mantine/core";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { formatMoney } from "@/shared/lib";
|
||||
|
||||
import classes from "./EntryGroup.module.css";
|
||||
|
||||
type AccountRowProps = {
|
||||
accountName: string;
|
||||
value: string;
|
||||
valueLabel: string;
|
||||
};
|
||||
|
||||
type EntryGroupProps = PropsWithChildren<{
|
||||
header: ReactNode;
|
||||
label: string;
|
||||
}>;
|
||||
|
||||
type EntryGroupTotalProps = {
|
||||
isSigned?: boolean;
|
||||
totals: null | { currency: string; value: string }[];
|
||||
};
|
||||
|
||||
const AccountRow: FC<AccountRowProps> = (props) => {
|
||||
const accessibleName = `${props.accountName}, ${props.value}`;
|
||||
|
||||
return (
|
||||
<li aria-label={accessibleName} className={classes.accountRow}>
|
||||
<Text>{props.accountName}</Text>
|
||||
|
||||
<Stack className={classes.accountValue} gap={2}>
|
||||
<Text fw={700}>{props.value}</Text>
|
||||
|
||||
<Text c="dimmed" size="xs">{props.valueLabel}</Text>
|
||||
</Stack>
|
||||
</li>
|
||||
);
|
||||
};
|
||||
|
||||
const AccountCardRow: FC<AccountRowProps> = props => (
|
||||
<li aria-label={`${props.accountName}, ${props.value}`}>
|
||||
<Paper className={classes.accountCardRow} withBorder>
|
||||
<Text fw={700}>{props.accountName}</Text>
|
||||
|
||||
<Stack className={classes.accountValue} gap={2}>
|
||||
<Text fw={700}>{props.value}</Text>
|
||||
|
||||
<Text c="dimmed" size="xs">{props.valueLabel}</Text>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</li>
|
||||
);
|
||||
|
||||
const EntryGroup: FC<EntryGroupProps> = props => (
|
||||
<Paper className={classes.group} component="li" withBorder>
|
||||
{props.header}
|
||||
|
||||
<Stack
|
||||
aria-label={props.label}
|
||||
className={classes.accounts}
|
||||
component="ul"
|
||||
gap={0}
|
||||
>
|
||||
{props.children}
|
||||
</Stack>
|
||||
</Paper>
|
||||
);
|
||||
|
||||
const EntryGroupTotal: FC<EntryGroupTotalProps> = (props) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
if (!props.totals) {
|
||||
return <VisuallyHidden>{t("entryGroup.totalUnavailable")}</VisuallyHidden>;
|
||||
}
|
||||
|
||||
const isSigned = props.isSigned === true;
|
||||
|
||||
return (
|
||||
<Stack gap={2}>
|
||||
{props.totals.map(total => (
|
||||
<span key={`${total.currency}-${total.value}`}>
|
||||
{formatMoney(total, { withSign: isSigned || undefined })}
|
||||
</span>
|
||||
))}
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
export {
|
||||
AccountCardRow,
|
||||
AccountRow,
|
||||
EntryGroup,
|
||||
EntryGroupTotal,
|
||||
};
|
||||
Reference in New Issue
Block a user