-
Notifications
You must be signed in to change notification settings - Fork 1
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
Add expenses dashboard component #44
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, good job! There are few minor issues related to the use of plain JS directly in JSX, making more utility functions outside of the component would solve the problem. See comments below
import { Container } from "./style"; | ||
import PieChart from "../../../components/Charts/doughnut"; | ||
|
||
const months = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider taking this out of the component. I would suggest renaming it to MONTHS
and placing it under Dashboard.constants.js
with a named export.
let currentMonthExpenses = expenses | ||
.filter( | ||
(expense) => | ||
moment.utc(expense.spentAt).format("MMMM YYYY") === |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
moment
seems to be an overkill, we can achieve the same result with native Intl.DateTimeFormat
. Something like this should work just fine:
const formatDate = (date) => {
const options = { month: "short", day: "numeric", year: "numeric" };
return new Intl.DateTimeFormat("en-US", options).format(new Date(date));
};
<ExpenseString> | ||
<ColumnContainer> | ||
<ExpenseCategory> | ||
{expense.expenseCategory.name.length > 16 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would suggest extracting logic of truncation into a helper function
const truncateString = (string, maxLength = 16) =>
string.length > maxLength ? `${string.slice(0, maxLength)}...` : string;
<ExpenseCategory>{truncateString(expense.expenseCategory.name)}</ExpenseCategory>
</ExpenseDate> | ||
</ColumnContainer> | ||
<ExpenseAmount> | ||
{`${currency} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider extracting currency formatting logic outside of the JSX with a helper function.
const formatCurrency = (amount, currency) =>
`${currency} ${parseFloat(amount).toFixed(2)}`;
<FixedDataContainer> | ||
<> | ||
<Heading>{`${months[monthIndex]} ${year}`}</Heading> | ||
{currentMonthExpenses.map((expense, index) => ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider destructuring expense properties in the map.
{currentMonthExpenses.map(({ spentAt, expenseCategory, amount }, index) => ( ...
|
||
return ( | ||
<Container> | ||
<DataContainer> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand that <DataContainer>
is intended to hold the <PieChart>
, I'd suggest renaming it to something like ChartContainer
for semantic clarity.
<> | ||
<Heading>{`${months[monthIndex]} ${year}`}</Heading> | ||
{currentMonthExpenses.map((expense, index) => ( | ||
<div key={index}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not use index as a key (see https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key for more info). I would suggest to use expense.id
instead.
"December", | ||
]; | ||
|
||
const currentYear = new Date().getFullYear(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider creating a single Date instance and reusing it for both getFullYear()
and getMonth()
.
const currentDate = new Date();
const currentYear = currentDate.getFullYear();
const currentMonthIndex = currentDate.getMonth();
const currentMonthIndex = new Date().getMonth(); | ||
|
||
const Expenses = ({ expenses, currency }) => { | ||
const [year, setYear] = useState(currentYear); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not just any year, but currentYear
consider renaming state vars accordingly.
<ExpenseString> | ||
<ColumnContainer> | ||
<ExpenseCategory> | ||
{expense.expenseCategory.name.length > 16 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The maximum length of the title is indeed 16 symbols, however, the requirement for this component states, that when the length is exceeded not only do we show the truncated title, but on hover user can also see a Popover component with the full title. https://impensa.atlassian.net/browse/KDE-10.
I would suggest to integrate this component here https://ui.shadcn.com/docs/components/popover
This PR introduces
Dashboard
component.