feat: unify income payment cards and remove comparisons (WealthLedger/main#33) (#74)
feat: unify income payment cards and remove comparisons (WealthLedger/main#33)
This commit was merged in pull request #74.
This commit is contained in:
@@ -36,6 +36,12 @@ function entryLabelKey(operation: BrokerageOperation): string {
|
||||
return `ledger.category.${operation.category}`;
|
||||
}
|
||||
|
||||
function isIncomePayment(operation: BrokerageOperation): boolean {
|
||||
return [OperationType.Coupon, OperationType.Dividend].some(type =>
|
||||
isOperationType(operation.type, type),
|
||||
);
|
||||
}
|
||||
|
||||
function isOperationType(value: unknown, expected: OperationType): boolean {
|
||||
return value === expected;
|
||||
}
|
||||
@@ -109,4 +115,4 @@ function paymentPresentation(
|
||||
};
|
||||
}
|
||||
|
||||
export { operationLabelKey, paymentPresentation };
|
||||
export { isIncomePayment, operationLabelKey, paymentPresentation };
|
||||
|
||||
@@ -11,10 +11,11 @@ import {
|
||||
formatSnapshotTime,
|
||||
instrumentLogoUrl,
|
||||
} from "@/shared/lib";
|
||||
import { PayoutCard } from "@/shared/ui";
|
||||
|
||||
import type { BrokerageOperation } from "../api/useBrokerageOperations";
|
||||
|
||||
import { operationLabelKey, paymentPresentation } from "../model/display";
|
||||
import { isIncomePayment, operationLabelKey, paymentPresentation } from "../model/display";
|
||||
|
||||
type LedgerEntryRowProps = {
|
||||
operation: BrokerageOperation;
|
||||
@@ -75,6 +76,28 @@ const LedgerEntryRow: FC<LedgerEntryRowProps> = (props) => {
|
||||
}
|
||||
else details = undefined;
|
||||
|
||||
if (isIncomePayment(operation)) {
|
||||
const extraMetadata = [
|
||||
instrument,
|
||||
props.withDetails ? null : operation.account?.name,
|
||||
].filter(Boolean).join(" · ");
|
||||
|
||||
return (
|
||||
<PayoutCard
|
||||
details={details}
|
||||
extraMetadata={extraMetadata}
|
||||
imageSrc={instrumentLogoUrl(operation.logoName)}
|
||||
initial={(instrument.trim()[0] ?? "?").toUpperCase()}
|
||||
kind="executed"
|
||||
occurredAt={formatSnapshotTime(operation.occurredAt)}
|
||||
payment={operation.payment}
|
||||
title={operation.description || t(operationLabelKey(operation.type))}
|
||||
typeLabel={t(paymentPresentation(operation).label)}
|
||||
wrap={props.wrap}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<EntryCard
|
||||
details={details}
|
||||
|
||||
@@ -4,6 +4,7 @@ import { EntryCard } from "@wealthledger/ui";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { formatDate, formatMoney, instrumentLogoUrl } from "@/shared/lib";
|
||||
import { PayoutCard } from "@/shared/ui";
|
||||
|
||||
import type { BrokerageEvent } from "../api/useBrokerageEvents";
|
||||
|
||||
@@ -15,6 +16,27 @@ const BrokerageEventCard: FC<BrokerageEventCardProps> = (props) => {
|
||||
|
||||
const date = formatDate(event.date);
|
||||
|
||||
if (event.type === "coupon" || event.type === "dividend") {
|
||||
const title = [t(`events.type.${event.type}`), event.displayName].join(" · ");
|
||||
|
||||
const extraMetadata = [event.isin, event.account?.name]
|
||||
.filter(Boolean)
|
||||
.join(" · ");
|
||||
|
||||
return (
|
||||
<PayoutCard
|
||||
date={date}
|
||||
dateKind={event.dateKind}
|
||||
extraMetadata={extraMetadata}
|
||||
imageSrc={instrumentLogoUrl(event.logoName)}
|
||||
initial={(event.ticker.trim()[0] ?? "?").toUpperCase()}
|
||||
kind="forecast"
|
||||
projectedAmount={event.projectedAmount}
|
||||
title={title}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const metadata = [
|
||||
date,
|
||||
event.dateKind === "registry"
|
||||
@@ -40,7 +62,7 @@ const BrokerageEventCard: FC<BrokerageEventCardProps> = (props) => {
|
||||
title={[t(`events.type.${event.type}`), event.displayName].join(" · ")}
|
||||
tone="neutral"
|
||||
value={projectedAmount}
|
||||
valueLabel={t("events.projectedAmount")}
|
||||
valueLabel={t("payout.forecast")}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -4,9 +4,6 @@ type IncomeAnalytics = NonNullable<
|
||||
paths["/api/v1/brokerage-accounts/{accountId}/income-analytics"]["get"]["responses"][200]["content"]["application/json"]["data"]
|
||||
>;
|
||||
|
||||
type IncomeAnalyticsMeta
|
||||
= paths["/api/v1/brokerage-accounts/{accountId}/income-analytics"]["get"]["responses"][200]["content"]["application/json"]["meta"];
|
||||
|
||||
type IncomeSummary = NonNullable<
|
||||
paths["/api/v1/brokerage-accounts/{accountId}/income-summary"]["get"]["responses"][200]["content"]["application/json"]["data"]
|
||||
>;
|
||||
@@ -47,7 +44,6 @@ function useIncomeSummary(accountId?: string) {
|
||||
|
||||
export {
|
||||
type IncomeAnalytics,
|
||||
type IncomeAnalyticsMeta,
|
||||
type IncomeSummary,
|
||||
useIncomeAnalytics,
|
||||
useIncomeSummary,
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
export {
|
||||
type IncomeAnalytics,
|
||||
type IncomeAnalyticsMeta,
|
||||
type IncomeSummary,
|
||||
useIncomeAnalytics,
|
||||
useIncomeSummary,
|
||||
|
||||
Reference in New Issue
Block a user