Files
frontend/packages/ui/src/EntryCard/EntryCard.tsx
T
codex-bot 71126c91f0
Frontend verify / commits (push) Skipped
Frontend verify / security (push) Successful in 9s
Frontend verify / verify (push) Failing after 6m1s
feat: group all-account rows by instrument and day (WealthLedger/main#47) (#126)
2026-10-30 07:28:19 +03:00

90 lines
1.9 KiB
TypeScript

import type { FC, ReactNode } from "react";
import { Avatar, Paper, Stack, Text } from "@mantine/core";
import classes from "./EntryCard.module.css";
type EntryCardProps = {
actions?: ReactNode;
color?: string;
details?: ReactNode;
icon?: ReactNode;
imageSrc?: null | string;
initial: string;
metadata: string;
title: string;
tone: "negative"
| "neutral"
| "positive";
value: ReactNode;
valueLabel: string;
wrap?: boolean;
};
const EntryCard: FC<EntryCardProps> = (props) => {
const surfaceStyle = props.color
? {
background: `color-mix(in srgb, var(--mantine-color-${props.color}-0) 45%, var(--wl-color-surface))`,
}
: undefined;
const titleLineClamp = props.wrap ? undefined : 1;
const valueContainerClass = props.actions ? classes.valueFooter : undefined;
const valueLabelClass = `${classes[props.tone]} ${props.actions ? classes.valueLabel : ""}`;
const valueComponent = typeof props.value === "string" ? undefined : "div";
return (
<Paper
className={classes.row}
data-wrap={props.wrap || undefined}
style={surfaceStyle}
withBorder
>
<Avatar
alt=""
aria-hidden="true"
radius="md"
size={40}
src={props.imageSrc}
>
{props.icon ?? props.initial}
</Avatar>
<Stack className={classes.identity} gap={2}>
<Text fw={700} lineClamp={titleLineClamp}>
{props.title}
</Text>
<Text c="dimmed" size="sm">
{props.metadata}
</Text>
{props.details}
</Stack>
<Stack className={classes.value} gap={2}>
<Text
className={classes[props.tone]}
component={valueComponent}
fw={700}
>
{props.value}
</Text>
<div className={valueContainerClass}>
<Text className={valueLabelClass} size="sm">
{props.valueLabel}
</Text>
{Boolean(props.actions) && (
<div className={classes.actions}>{props.actions}</div>
)}
</div>
</Stack>
</Paper>
);
};
export { EntryCard };