forked from aws-samples/amplify-next-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add financials to account page
- Loading branch information
Carsten Koch
committed
Oct 31, 2024
1 parent
2ec25ae
commit 7b0de11
Showing
7 changed files
with
233 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import { Account } from "@/api/ContextAccounts"; | ||
import { | ||
RevenueMonth, | ||
setAccountColumnDataFromMrr, | ||
setAccountColumnDefFromMrr, | ||
setLastMonthsRevenue, | ||
setTotalRevenueFromRevenueMonth, | ||
} from "@/helpers/analytics/account-data"; | ||
import { formatDate, formatRevenue } from "@/helpers/functional"; | ||
import { ColumnDef } from "@tanstack/react-table"; | ||
import { flow } from "lodash/fp"; | ||
import { FC, useEffect, useState } from "react"; | ||
import AnalyticsTable from "../analytics/analytics-table"; | ||
import { AccountMrr } from "../analytics/analytics-table-column"; | ||
import MrrFilterBtnGrp from "../analytics/mrr-filter-btn-grp"; | ||
import { useMrrFilter, withMrrFilter } from "../analytics/useMrrFilter"; | ||
import DefaultAccordionItem from "../ui-elements/accordion/DefaultAccordionItem"; | ||
|
||
type AccountFinancialsProps = { | ||
account: Account; | ||
showFinancials?: boolean; | ||
}; | ||
|
||
const AccountFinancials: FC<AccountFinancialsProps> = ({ | ||
account, | ||
showFinancials, | ||
}) => { | ||
const { mrrFilter, mrr } = useMrrFilter(); | ||
const [noOfMonths, setNoOfMonths] = useState(0); | ||
const [columnDef, setColumnDef] = useState<ColumnDef<AccountMrr>[]>([]); | ||
const [columnData, setColumnData] = useState<AccountMrr[]>([]); | ||
const [revenueLastMonths, setRevenueLastMonths] = useState<RevenueMonth[]>( | ||
[] | ||
); | ||
const [totalRevenue, setTotalRevenue] = useState(0); | ||
|
||
useEffect(() => { | ||
flow(parseInt, setNoOfMonths)(mrrFilter); | ||
}, [mrrFilter]); | ||
|
||
useEffect(() => { | ||
setAccountColumnDefFromMrr(mrr, noOfMonths, setColumnDef); | ||
}, [mrr, noOfMonths]); | ||
|
||
useEffect(() => { | ||
setAccountColumnDataFromMrr(account.name, mrr, noOfMonths, setColumnData); | ||
}, [mrr, noOfMonths, account]); | ||
|
||
useEffect(() => { | ||
setLastMonthsRevenue(3, account.name, mrr, setRevenueLastMonths); | ||
}, [mrr, account]); | ||
|
||
useEffect(() => { | ||
setTotalRevenueFromRevenueMonth(revenueLastMonths, setTotalRevenue); | ||
}, [revenueLastMonths]); | ||
|
||
return ( | ||
<DefaultAccordionItem | ||
value="financials" | ||
triggerTitle="AWS Revenue" | ||
triggerSubTitle={revenueLastMonths.map( | ||
({ month, mrr }) => | ||
`${formatDate("MMM yyyy")(month)}: ${formatRevenue(mrr)}` | ||
)} | ||
isVisible={!!showFinancials && totalRevenue > 0} | ||
> | ||
<div className="space-y-6"> | ||
<MrrFilterBtnGrp /> | ||
<AnalyticsTable columns={columnDef} data={columnData} /> | ||
</div> | ||
</DefaultAccordionItem> | ||
); | ||
}; | ||
|
||
export default withMrrFilter(AccountFinancials); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
import { Mrr } from "@/api/useMrr"; | ||
import { | ||
AccountMrr, | ||
getMonthName, | ||
MonthMrr, | ||
} from "@/components/analytics/analytics-table-column"; | ||
import RenderMonthMrr from "@/components/analytics/render-month-mrr"; | ||
import RenderPayerHeader from "@/components/analytics/render-payer-header"; | ||
import { ColumnDef } from "@tanstack/react-table"; | ||
import { | ||
filter, | ||
flow, | ||
identity, | ||
map, | ||
sortBy, | ||
sum, | ||
takeRight, | ||
times, | ||
uniq, | ||
} from "lodash/fp"; | ||
import { Dispatch, SetStateAction } from "react"; | ||
import { byAccount, byMonth, parseMonthToInt } from "./analytics"; | ||
import { | ||
getLastMonthMrrByAccountAndPayer, | ||
getUniqMonths, | ||
mapPayerMrrData, | ||
} from "./prep-table-data"; | ||
|
||
export type RevenueMonth = { | ||
month: Date; | ||
mrr: number; | ||
}; | ||
|
||
export const setAccountColumnDataFromMrr = ( | ||
account: string, | ||
mrr: Mrr[] | undefined, | ||
noOfMonths: number, | ||
setColumnData: Dispatch<SetStateAction<AccountMrr[]>> | ||
) => | ||
!mrr | ||
? [] | ||
: flow( | ||
identity<Mrr[]>, | ||
filter(byAccount(account)), | ||
map("awsAccountNumber"), | ||
uniq, | ||
map(mapPayerMrrData(mrr, account, noOfMonths)), | ||
sortBy(getLastMonthMrrByAccountAndPayer(mrr, account)), | ||
setColumnData | ||
)(mrr); | ||
|
||
export const setAccountColumnDefFromMrr = ( | ||
mrr: Mrr[] | undefined, | ||
noOfMonths: number, | ||
setColumnDef: Dispatch<SetStateAction<ColumnDef<AccountMrr>[]>> | ||
) => | ||
!mrr ? [] : flow(identity<number>, getColumnDef, setColumnDef)(noOfMonths); | ||
|
||
export const setLastMonthsRevenue = ( | ||
noOfMonths: number, | ||
account: string, | ||
mrr: Mrr[] | undefined, | ||
setRevenue: Dispatch<SetStateAction<RevenueMonth[]>> | ||
) => | ||
!mrr | ||
? [] | ||
: flow( | ||
identity<Mrr[]>, | ||
getUniqMonths, | ||
sortBy(parseMonthToInt), | ||
takeRight(noOfMonths), | ||
map(getMonthAccountRevenue(account, mrr)), | ||
setRevenue | ||
)(mrr); | ||
|
||
export const setTotalRevenueFromRevenueMonth = ( | ||
revenueLastMonths: RevenueMonth[], | ||
setTotalRevenue: Dispatch<SetStateAction<number>> | ||
) => | ||
flow( | ||
identity<RevenueMonth[]>, | ||
map("mrr"), | ||
sum, | ||
setTotalRevenue | ||
)(revenueLastMonths); | ||
|
||
const getColumnDef = (noOfMonths: number): ColumnDef<AccountMrr>[] => [ | ||
{ accessorKey: "id" }, | ||
{ accessorKey: "isReseller" }, | ||
{ | ||
accessorKey: "accountOrPayer", | ||
header: "Payer", | ||
cell: ({ row, getValue }) => ( | ||
<RenderPayerHeader | ||
id={row.getValue("id")} | ||
label={getValue<string>()} | ||
isReseller={row.getValue("isReseller")} | ||
/> | ||
), | ||
}, | ||
...getMonthlyMrrColumnDef(noOfMonths), | ||
]; | ||
|
||
const getMonthAccountRevenue = | ||
(account: string, mrr: Mrr[]) => | ||
(month: string): RevenueMonth => | ||
flow( | ||
identity<Mrr[]>, | ||
filter(byAccount(account)), | ||
filter(byMonth(month)), | ||
map("mrr"), | ||
sum, | ||
(mrrTotal) => ({ month: new Date(`${month}-01`), mrr: mrrTotal }) | ||
)(mrr); | ||
|
||
const getMonthlyMrrColumnDef = (noOfMonths: number): ColumnDef<AccountMrr>[] => | ||
flow( | ||
identity<number>, | ||
times(identity), | ||
map( | ||
(id: number): ColumnDef<AccountMrr> => ({ | ||
accessorKey: `month${id}Mrr`, | ||
header: getMonthName(noOfMonths, id), | ||
cell: ({ getValue }) => ( | ||
<RenderMonthMrr | ||
monthMrr={getValue<MonthMrr>()} | ||
noOfMonths={noOfMonths} | ||
/> | ||
), | ||
}) | ||
) | ||
)(noOfMonths); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters