refactor: clarify frontend model ownership
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
import type { FC } from "react";
|
||||
|
||||
import { Accordion, Alert, Badge, Group, Paper, Stack, Text } from "@mantine/core";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import type { BondCoupons as Coupons } from "@/entities/bond";
|
||||
|
||||
import { InstrumentSection, type SectionState } from "@/features/instrument-details";
|
||||
import { formatDate, formatMoney, formatSnapshotTime } from "@/shared/lib";
|
||||
|
||||
import { Metric } from "./Metric.view";
|
||||
|
||||
type BondCouponsProps = {
|
||||
coupons?: Coupons;
|
||||
pastCoupons: Coupons["coupons"];
|
||||
state: SectionState;
|
||||
upcoming: Coupons["coupons"];
|
||||
};
|
||||
|
||||
const BondCoupons: FC<BondCouponsProps> = (props) => {
|
||||
const { coupons, pastCoupons, state, upcoming } = props;
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<InstrumentSection
|
||||
state={state}
|
||||
title={t("bond.upcomingCoupons")}
|
||||
>
|
||||
{!!coupons && (
|
||||
<Stack gap="md">
|
||||
{!!(coupons.estimateUnavailable || coupons.positionIsStale) && (
|
||||
<Alert aria-live="polite" color="orange" role="status">
|
||||
{t("stock.estimateUnavailable")}
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
{upcoming.length > 0
|
||||
? (
|
||||
upcoming.map(coupon => (
|
||||
<Coupon
|
||||
coupon={coupon}
|
||||
key={`${coupon.number}:${coupon.paymentDate}`}
|
||||
/>
|
||||
))
|
||||
)
|
||||
: <Text c="dimmed">{t("bond.noCoupons")}</Text>}
|
||||
|
||||
<Text c="dimmed" size="xs">
|
||||
{t("bond.couponWindow", {
|
||||
from: formatDate(coupons.from),
|
||||
to: formatDate(coupons.to),
|
||||
})}
|
||||
</Text>
|
||||
|
||||
<Text c="dimmed" size="xs">
|
||||
{t("bond.couponNote")}
|
||||
</Text>
|
||||
|
||||
{!!coupons.positionAt && (
|
||||
<Text c="dimmed" size="xs">
|
||||
{t("stock.snapshotAt", {
|
||||
date: formatSnapshotTime(coupons.positionAt),
|
||||
})}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
<Accordion radius="md" variant="contained">
|
||||
<Accordion.Item value="history">
|
||||
<Accordion.Control>{t("bond.couponHistory")}</Accordion.Control>
|
||||
|
||||
<Accordion.Panel>
|
||||
<Stack gap="sm">
|
||||
{pastCoupons.length > 0
|
||||
? (
|
||||
pastCoupons.map(coupon => (
|
||||
<Coupon
|
||||
coupon={coupon}
|
||||
key={`${coupon.number}:${coupon.paymentDate}`}
|
||||
/>
|
||||
))
|
||||
)
|
||||
: <Text c="dimmed">{t("bond.noCoupons")}</Text>}
|
||||
</Stack>
|
||||
</Accordion.Panel>
|
||||
</Accordion.Item>
|
||||
</Accordion>
|
||||
</Stack>
|
||||
)}
|
||||
</InstrumentSection>
|
||||
);
|
||||
};
|
||||
|
||||
type CouponProps = {
|
||||
coupon: Coupons["coupons"][number];
|
||||
};
|
||||
|
||||
const Coupon: FC<CouponProps> = (props) => {
|
||||
const { coupon } = props;
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Paper p="md" radius="md" withBorder>
|
||||
<Group align="start" justify="space-between">
|
||||
<div>
|
||||
<Text fw={600}>
|
||||
{coupon.paymentDate
|
||||
? formatDate(coupon.paymentDate)
|
||||
: t("stock.dateUnknown")}
|
||||
</Text>
|
||||
|
||||
<Text c="dimmed" size="xs">
|
||||
{t("bond.couponNumber", {
|
||||
number: coupon.number ?? t("bond.unknown"),
|
||||
})}
|
||||
</Text>
|
||||
</div>
|
||||
|
||||
<Metric label={t("bond.perBond")} value={formatMoney(coupon.perBond)} />
|
||||
|
||||
{!!coupon.estimatedAmount && (
|
||||
<Metric
|
||||
label={t("stock.yourEstimate")}
|
||||
value={formatMoney(coupon.estimatedAmount)}
|
||||
/>
|
||||
)}
|
||||
</Group>
|
||||
|
||||
<Group gap="md" mt="sm">
|
||||
<Badge color="gray" variant="light">
|
||||
{t(`bond.couponTypes.${coupon.couponType}`, {
|
||||
defaultValue: t("bond.unknown"),
|
||||
})}
|
||||
</Badge>
|
||||
|
||||
{coupon.periodDays != undefined && (
|
||||
<Text c="dimmed" size="xs">
|
||||
{t("bond.couponDays", { count: coupon.periodDays })}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
{!!coupon.recordDate && (
|
||||
<Text c="dimmed" size="xs">
|
||||
{t("stock.record")}: {formatDate(coupon.recordDate)}
|
||||
</Text>
|
||||
)}
|
||||
</Group>
|
||||
</Paper>
|
||||
);
|
||||
};
|
||||
|
||||
export { BondCoupons };
|
||||
Reference in New Issue
Block a user