From 1274e0d36ca7df26d4f429776a88567a288139e9 Mon Sep 17 00:00:00 2001 From: Sami Lafrance Date: Fri, 15 Nov 2024 14:10:52 +0100 Subject: [PATCH 1/2] Create pull request From cc84d466e417780b3bd5c915ac368c852af5ddb3 Mon Sep 17 00:00:00 2001 From: Sami Lafrance Date: Fri, 15 Nov 2024 17:52:37 +0100 Subject: [PATCH 2/2] feat(financial): budget --- .../budget-available-cards.tsx | 4 +- .../budget-available-cards.tsx | 4 +- .../budget-available-cards.tsx | 98 +++++++++++++++++ .../budget-available-cards.types.ts | 17 +++ .../budget-available.en.json | 11 ++ .../financial-column-chart.en.json | 1 + .../financial-column-chart.tsx | 3 + .../transactions-trigger.tsx | 28 +++++ .../financial-section/financial-section.tsx | 104 ++++++++++++++---- .../_translations/my-dashboard.en.json | 15 ++- .../_translations/my-dashboard.translate.ts | 5 + app/my-dashboard/page.tsx | 2 + .../budget-available-cards.tsx | 4 +- .../financial-detail-sidepanel.en.json | 9 ++ .../financial-detail-sidepanel.types.ts | 8 +- 15 files changed, 283 insertions(+), 30 deletions(-) create mode 100644 app/my-dashboard/_sections/financial-section/_components/budget-available-cards/budget-available-cards.tsx create mode 100644 app/my-dashboard/_sections/financial-section/_components/budget-available-cards/budget-available-cards.types.ts create mode 100644 app/my-dashboard/_sections/financial-section/_components/budget-available-cards/budget-available.en.json create mode 100644 app/my-dashboard/_sections/financial-section/_components/financial-column-chart/financial-column-chart.en.json create mode 100644 app/my-dashboard/_sections/financial-section/_components/financial-column-chart/financial-column-chart.tsx create mode 100644 app/my-dashboard/_sections/financial-section/_components/transactions-trigger/transactions-trigger.tsx diff --git a/app/financials/[sponsorId]/_sections/financial-section/components/budget-available-cards/budget-available-cards.tsx b/app/financials/[sponsorId]/_sections/financial-section/components/budget-available-cards/budget-available-cards.tsx index e95c3f22b..bc74b6bc4 100644 --- a/app/financials/[sponsorId]/_sections/financial-section/components/budget-available-cards/budget-available-cards.tsx +++ b/app/financials/[sponsorId]/_sections/financial-section/components/budget-available-cards/budget-available-cards.tsx @@ -6,7 +6,7 @@ import { CardFinancialLoading } from "@/design-system/molecules/cards/card-finan import { FinancialCardItem } from "@/shared/features/financial-card-item/financial-card-item"; import { useFinancialDetailSidepanel } from "@/shared/panels/financial-detail-sidepanel/financial-detail-sidepanel.hooks"; -import { PanelType } from "@/shared/panels/financial-detail-sidepanel/financial-detail-sidepanel.types"; +import { PanelMaintainerType } from "@/shared/panels/financial-detail-sidepanel/financial-detail-sidepanel.types"; export function BudgetAvailableCards() { const { sponsorId = "" } = useParams<{ sponsorId: string }>(); @@ -37,7 +37,7 @@ export function BudgetAvailableCards() { return null; } - function openPanel(panelType: PanelType) { + function openPanel(panelType: PanelMaintainerType) { if (data) { open({ panelType, diff --git a/app/manage-projects/[projectSlug]/_sections/financial-section/components/budget-available-cards/budget-available-cards.tsx b/app/manage-projects/[projectSlug]/_sections/financial-section/components/budget-available-cards/budget-available-cards.tsx index 7d14e7103..6e04ffac4 100644 --- a/app/manage-projects/[projectSlug]/_sections/financial-section/components/budget-available-cards/budget-available-cards.tsx +++ b/app/manage-projects/[projectSlug]/_sections/financial-section/components/budget-available-cards/budget-available-cards.tsx @@ -6,7 +6,7 @@ import { CardFinancialLoading } from "@/design-system/molecules/cards/card-finan import { FinancialCardItem } from "@/shared/features/financial-card-item/financial-card-item"; import { useFinancialDetailSidepanel } from "@/shared/panels/financial-detail-sidepanel/financial-detail-sidepanel.hooks"; -import { PanelType } from "@/shared/panels/financial-detail-sidepanel/financial-detail-sidepanel.types"; +import { PanelMaintainerType } from "@/shared/panels/financial-detail-sidepanel/financial-detail-sidepanel.types"; export function BudgetAvailableCards() { const { projectSlug = "" } = useParams<{ projectSlug: string }>(); @@ -33,7 +33,7 @@ export function BudgetAvailableCards() { return null; } - function openPanel(panelType: Exclude) { + function openPanel(panelType: Exclude) { if (data) { open({ panelType, diff --git a/app/my-dashboard/_sections/financial-section/_components/budget-available-cards/budget-available-cards.tsx b/app/my-dashboard/_sections/financial-section/_components/budget-available-cards/budget-available-cards.tsx new file mode 100644 index 000000000..34e6104ec --- /dev/null +++ b/app/my-dashboard/_sections/financial-section/_components/budget-available-cards/budget-available-cards.tsx @@ -0,0 +1,98 @@ +import { BiReactQueryAdapter } from "@/core/application/react-query-adapter/bi"; +import { DetailedTotalMoneyTotalPerCurrency } from "@/core/kernel/money/money.types"; + +import { CardFinancialLoading } from "@/design-system/molecules/cards/card-financial/card-financial.loading"; + +import { FinancialCardItem } from "@/shared/features/financial-card-item/financial-card-item"; +import { useAuthUser } from "@/shared/hooks/auth/use-auth-user"; +import { useFinancialDetailSidepanel } from "@/shared/panels/financial-detail-sidepanel/financial-detail-sidepanel.hooks"; +import { PanelContributorType } from "@/shared/panels/financial-detail-sidepanel/financial-detail-sidepanel.types"; + +export function BudgetAvailableCards() { + const { open } = useFinancialDetailSidepanel(); + + const { githubUserId } = useAuthUser(); + + const { data, isLoading } = BiReactQueryAdapter.client.useGetBiStatsFinancials({ + queryParams: { + recipientId: githubUserId, + showEmpty: true, + }, + options: { + enabled: Boolean(githubUserId), + }, + }); + + if (isLoading) { + return ( +
+ + + +
+ ); + } + + if (!data) { + return null; + } + + const rewardPendingAmount = { + totalUsdEquivalent: data.stats[0].totalRewarded.totalUsdEquivalent - data.stats[0].totalPaid.totalUsdEquivalent, + totalPerCurrency: data.stats[0].totalRewarded.totalPerCurrency + ?.map(rewarded => { + const paid = data.stats[0].totalPaid.totalPerCurrency?.find(p => p.currency.id === rewarded.currency.id) || { + usdEquivalent: 0, + }; + + const pendingUsdEquivalent = (rewarded.usdEquivalent || 0) - (paid.usdEquivalent || 0); + + if (pendingUsdEquivalent !== 0) { + return { + ...rewarded, + usdEquivalent: pendingUsdEquivalent, + }; + } + + return null; + }) + .filter(item => item !== null), + }; + + function openPanel( + panelType: PanelContributorType, + total: { totalUsdEquivalent: number; totalPerCurrency?: DetailedTotalMoneyTotalPerCurrency[] } + ) { + if (data) { + open({ + panelType, + total, + }); + } + } + + return ( +
+ openPanel("rewardedAmount", data.stats[0].totalRewarded)} + /> + + openPanel("rewardPendingAmount", rewardPendingAmount)} + /> + + openPanel("rewardPaid", data.stats[0].totalPaid)} + /> +
+ ); +} diff --git a/app/my-dashboard/_sections/financial-section/_components/budget-available-cards/budget-available-cards.types.ts b/app/my-dashboard/_sections/financial-section/_components/budget-available-cards/budget-available-cards.types.ts new file mode 100644 index 000000000..1b6a0aa72 --- /dev/null +++ b/app/my-dashboard/_sections/financial-section/_components/budget-available-cards/budget-available-cards.types.ts @@ -0,0 +1,17 @@ +import { ProjectFinancial } from "@/core/domain/project/models/project-financial-model"; +import { AnyType } from "@/core/kernel/types"; + +import { CardFinancialPort } from "@/design-system/molecules/cards/card-financial/card-financial.types"; + +import { TranslateProps } from "@/shared/translation/components/translate/translate.types"; + +export interface CreateAvatarGroupProps { + total: ProjectFinancial["totalAvailable" | "totalGranted" | "totalRewarded"]; +} + +export interface FinancialCardItemProps { + title: TranslateProps["token"]; + total: ProjectFinancial["totalAvailable" | "totalGranted" | "totalRewarded"]; + color: CardFinancialPort["color"]; + onClick?: () => void; +} diff --git a/app/my-dashboard/_sections/financial-section/_components/budget-available-cards/budget-available.en.json b/app/my-dashboard/_sections/financial-section/_components/budget-available-cards/budget-available.en.json new file mode 100644 index 000000000..b27d23c5f --- /dev/null +++ b/app/my-dashboard/_sections/financial-section/_components/budget-available-cards/budget-available.en.json @@ -0,0 +1,11 @@ +{ + "rewarded": { + "title": "Rewarded amount" + }, + "pending": { + "title": "Pending amount" + }, + "paid": { + "title": "Paid" + } +} diff --git a/app/my-dashboard/_sections/financial-section/_components/financial-column-chart/financial-column-chart.en.json b/app/my-dashboard/_sections/financial-section/_components/financial-column-chart/financial-column-chart.en.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/app/my-dashboard/_sections/financial-section/_components/financial-column-chart/financial-column-chart.en.json @@ -0,0 +1 @@ +{} diff --git a/app/my-dashboard/_sections/financial-section/_components/financial-column-chart/financial-column-chart.tsx b/app/my-dashboard/_sections/financial-section/_components/financial-column-chart/financial-column-chart.tsx new file mode 100644 index 000000000..8b4cea851 --- /dev/null +++ b/app/my-dashboard/_sections/financial-section/_components/financial-column-chart/financial-column-chart.tsx @@ -0,0 +1,3 @@ +export function FinancialColumnChart() { + return

Charts

; +} diff --git a/app/my-dashboard/_sections/financial-section/_components/transactions-trigger/transactions-trigger.tsx b/app/my-dashboard/_sections/financial-section/_components/transactions-trigger/transactions-trigger.tsx new file mode 100644 index 000000000..872d641f0 --- /dev/null +++ b/app/my-dashboard/_sections/financial-section/_components/transactions-trigger/transactions-trigger.tsx @@ -0,0 +1,28 @@ +import { ChevronRight } from "lucide-react"; + +import { Button } from "@/design-system/atoms/button/variants/button-default"; + +export function TransactionsTrigger() { + function togglePanel() { + console.log("togglePanel"); + } + + return ( + <> +