Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimizations #61

Merged
merged 8 commits into from
Jul 14, 2024
9 changes: 7 additions & 2 deletions app/components/BottomSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ type BottomSheetProps = {
className?: string;
setShow: React.Dispatch<React.SetStateAction<boolean>>;
closeButtonSize?: "sm" | "lg";
addToHistoryStack?: boolean;
onCloseClick?: () => void;
children?: any;
};

Expand All @@ -16,10 +18,12 @@ export const BottomSheet = ({
className,
setShow,
closeButtonSize,
addToHistoryStack = true,
onCloseClick = () => {},
children,
}: BottomSheetProps) => {
useEffect(() => {
if (show) {
if (show && addToHistoryStack) {
history.pushState(null, document.title, window.location.href);
window.onpopstate = async () => {
window.onpopstate = () => {};
Expand Down Expand Up @@ -49,7 +53,7 @@ export const BottomSheet = ({
{/* Bottom Sheet */}
<div
className={clsx(
"flex flex-col items-center bg-base p-5 w-full h-fit md:w-3/4 lg:w-2/3 left-1/2 -translate-x-1/2 fixed bottom-0 transition-all duration-300 rounded-lg z-50 shadow-2xl",
"flex flex-col items-center bg-base p-5 w-full h-fit max-h-[80%] overflow-y-scroll md:w-3/4 lg:w-2/3 left-1/2 -translate-x-1/2 fixed bottom-0 transition-all duration-300 rounded-lg z-50 shadow-2xl",
{
"translate-y-full": !show,
"translate-y-0": show,
Expand All @@ -67,6 +71,7 @@ export const BottomSheet = ({
closeButtonSize === "sm" ? "btn-secondary-sm" : "btn-secondary"
}`}
onClick={() => {
typeof onCloseClick === "function" && onCloseClick();
setShow(false);
window.onpopstate = () => {};
history.back();
Expand Down
9 changes: 8 additions & 1 deletion app/components/MonthYearSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export default function MonthYearSelector({
submitAction,
isSubscriptionRequired,
context,
onSubmit,
}: {
startMonth: number;
startYear: number;
Expand All @@ -32,6 +33,7 @@ export default function MonthYearSelector({
submitAction: string;
isSubscriptionRequired: boolean;
context: AppContext;
onSubmit?: () => void;
}) {
const [compareSettingContainer] = useAutoAnimate<HTMLDivElement>();
const [showCompareSettingButton, setShowCompareSettingButton] = useState(true);
Expand All @@ -45,7 +47,11 @@ export default function MonthYearSelector({
}
}, []);
return (
<Form replace method="GET" className="lg:flex lg:justify-center flex-grow">
<Form
replace
method="GET"
className="lg:flex lg:justify-center flex-grow bg-elevated-10 p-3 rounded-lg"
>
{showCompareSettingButton && (
<div className="flex w-full">
<Ripple>
Expand Down Expand Up @@ -155,6 +161,7 @@ export default function MonthYearSelector({
className="btn-secondary w-full whitespace-nowrap"
onClick={(e) => {
e.preventDefault();
typeof onSubmit === "function" && onSubmit();
isMobileDevice() && setShowCompareSetting(false);
submit(e.currentTarget, {
method: "GET",
Expand Down
39 changes: 22 additions & 17 deletions app/modules/reports/reports.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,7 @@ type TrendReportResponse = {
date: string;
budget: Prisma.Decimal;
expense: Prisma.Decimal;
income: Prisma.Decimal;
incomeEarned: Prisma.Decimal;
investment: Prisma.Decimal;
investmentDone: Prisma.Decimal;
}[];
totalExpense: Prisma.Decimal;
Expand All @@ -67,20 +65,20 @@ export type ExpenseTrendReportResponse = Omit<
TrendReportResponse,
"totalIncomeEarned" | "totalInvestmentDone"
> & {
categoryExpensesByCategory: { [key: string]: CategoryExpenseDate[] };
expensesByPaymentMode: { [key: string]: CategoryExpenseDate[] };
categoryExpensesByCategory: { [key: string]: ExpensePerDate[] };
expensesByPaymentMode: { [key: string]: ExpensePerDate[] };
};

export type InvestmentTrendReportResponse = Omit<
TrendReportResponse,
"totalExpense" | "totalIncomeEarned"
> & {
categoryInvestmentsByCategory: { [key: string]: CategoryInvestmentDate[] };
investmentsByPaymentMode: { [key: string]: CategoryInvestmentDate[] };
categoryInvestmentsByCategory: { [key: string]: InvestmentPerDate[] };
investmentsByPaymentMode: { [key: string]: InvestmentPerDate[] };
};

export type IncomeTrendReportResponse = TrendReportResponse & {
categoryIncomeByCategory: { [key: string]: CategoryIncomeDate[] };
categoryIncomeByCategory: { [key: string]: IncomePerDate[] };
};

export async function getThisMonthReport(
Expand Down Expand Up @@ -286,8 +284,12 @@ export async function getExpenseTrendReport(
return {
targets,
totalExpense,
categoryExpensesByCategory: Object.fromEntries(groupBy(categoryExpenses, "category")),
expensesByPaymentMode: Object.fromEntries(groupBy(expensesByPaymentMode, "category")),
categoryExpensesByCategory: Object.fromEntries(
groupBy(categoryExpenses, "category", true)
),
expensesByPaymentMode: Object.fromEntries(
groupBy(expensesByPaymentMode, "category", true)
),
};
}

Expand Down Expand Up @@ -328,10 +330,10 @@ export async function getInvestmentTrendReport(
targets,
totalInvestmentDone,
categoryInvestmentsByCategory: Object.fromEntries(
groupBy(categoryInvestments, "category")
groupBy(categoryInvestments, "category", true)
),
investmentsByPaymentMode: Object.fromEntries(
groupBy(investmentsByPaymentMode, "category")
groupBy(investmentsByPaymentMode, "category", true)
),
};
}
Expand Down Expand Up @@ -379,7 +381,9 @@ export async function getIncomeTrendReport(
totalExpense,
totalIncomeEarned,
totalInvestmentDone,
categoryIncomeByCategory: Object.fromEntries(groupBy(categoryIncomes, "category")),
categoryIncomeByCategory: Object.fromEntries(
groupBy(categoryIncomes, "category", true)
),
};
}

Expand Down Expand Up @@ -565,9 +569,12 @@ type CategoryAmount<T, K extends TransactionType> = CategoryDate & {
[prop in K]: T;
};

export type CategoryExpenseDate = CategoryAmount<Prisma.Decimal, "expense">;
export type CategoryInvestmentDate = CategoryAmount<Prisma.Decimal, "investment">;
export type CategoryIncomeDate = CategoryAmount<Prisma.Decimal, "income">;
export type ExpensePerDate = Omit<CategoryAmount<Prisma.Decimal, "expense">, "category">;
export type InvestmentPerDate = Omit<
CategoryAmount<Prisma.Decimal, "investment">,
"category"
>;
export type IncomePerDate = Omit<CategoryAmount<Prisma.Decimal, "income">, "category">;

async function getAmountPerCategoryForTimeRange(
userId: string,
Expand Down Expand Up @@ -641,9 +648,7 @@ async function getTargets(userId: string, startDate: Date, endDate: Date) {
date: true,
budget: true,
expense: true,
income: true,
incomeEarned: true,
investment: true,
investmentDone: true,
},
where: {
Expand Down
8 changes: 6 additions & 2 deletions app/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
import styles from "./styles/app.css";
import Report from "./components/Report";
import GenericError from "./components/GenericError";
import type { ReactElement } from "react";
import type { ReactElement, ReactNode } from "react";
import { useEffect, useRef, useState } from "react";
import { Spacer } from "./components/Spacer";
import { isNotNullAndEmpty } from "./utils/text.utils";
Expand Down Expand Up @@ -154,7 +154,7 @@ export const shouldRevalidate: ShouldRevalidateFunction = ({

export type DialogProps = {
title: string;
message: string;
message: ReactNode | string;
showDialog: boolean;
positiveButton?: string;
negativeButton?: string;
Expand All @@ -173,6 +173,8 @@ export type BottomSheetProps = {
show: boolean;
content: ReactElement;
closeButtonSize?: "sm" | "lg";
addToHistoryStack?: boolean;
onCloseClick?: () => void;
};

export type AppContext = {
Expand Down Expand Up @@ -532,7 +534,9 @@ export default function App() {

<BottomSheet
show={bottomSheetProps.show}
addToHistoryStack={bottomSheetProps.addToHistoryStack}
closeButtonSize={bottomSheetProps.closeButtonSize}
onCloseClick={bottomSheetProps.onCloseClick}
setShow={() => {
setBottomSheetProps((prev) => ({ ...prev, show: !prev.show }));
}}
Expand Down
4 changes: 2 additions & 2 deletions app/routes/reports/trend/expense.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ export default function ExpenseTrendReport() {
const trendingReportContext = useOutletContext<TrendingReportContext>();

const expenseDistribution = Object.entries(categoryExpensesByCategory)
.map(([category, categoryExpenses]) => {
.map(([category, expensePerDate]) => {
return {
name: category.toString(),
value: sum(categoryExpenses.map((c) => c.expense)),
value: sum(expensePerDate.map((c) => c.expense)),
};
})
.sort((a, b) => (calculate(b.value).minus(a.value).gt(0) ? 1 : -1));
Expand Down
10 changes: 8 additions & 2 deletions app/utils/array.utils.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import { formatDate_MMMM_YYYY } from "./date.utils";
import { isNullOrEmpty } from "./text.utils";

export function groupBy<T>(array: T[], key: keyof T) {
export function groupBy<T>(array: T[], key: keyof T, includeKeyInObject = false) {
let map = new Map<string, T[]>();
for (const item of array) {
for (let item of array) {
const searchKey = (item[key] as unknown as string).trim();
if (isNullOrEmpty(searchKey)) continue;
if (includeKeyInObject) {
item = { ...item };
delete item[key];
}
if (map.has(searchKey)) {
map.get(searchKey)!.push(item);
} else {
Expand Down
Loading