@mattstuddert
Posted
Hey APG,
Congrats on completing your 30th (!!) challenge overall and your 1st Guru level challenge! I'd agree with Em and say this is your best one yet (although you've posted lots of brilliant solutions!) π
Here are some thoughts related to some of the bugs and issues you mentioned in your README.md
:
- You can use lots of different approaches to structure React applications, as I'm sure you've noticed! On Frontend Mentor, I use an altered version of a domain-driven architecture. This is mostly because we use Redux for state management. If I were starting fresh today, I'd probably go a different route. The way you've structured your code works well for this size project, though. It's easy to navigate, you've separated the components nicely, and you've created good utility functions.
- I'd agree that using CSS custom properties instead of using Styled Component themes is a better approach. I'm feeling this pain on the Frontend Mentor codebase and will look to refactor at some point!
- The quick flash of light will most likely come from the fact that the app needs to pull the state from
localStorage
. So it's partially rendered by the time it can read the state. In a typical app where you're pulling data, this configuration would be stored as a user preference in the database. This means it wouldn't have the flash, as everything would be set during server-side rendering in Next.js. That might not be the issue, but that would be my guess anyway. - You're right about the custom dropdown not being accessible. As it is, the focus never goes into the dropdown if navigating by keyboard. This is because you've got
display: none;
on theinput
elements. Instead, I'd recommend using a.sr-only
class to visually hide the checkboxes and keep them accessible to screen readers. Here's a good article from the A11y Project about visually hiding content to learn more.
After looking at your code, here are a few recommendations:
- Now that optional chaining in JS is a thing, you don't need to use the
&&
operator so much. That means this line:filteredInvoices && filteredInvoices.length === 0
could become thisfilteredInvoices?.length === 0
. - You're using a
div
withspan
elements to display the invoice page's addresses. Instead, you could add more context in the HTML by using theaddress
element. You can read more about the address element on MDN here. - You could add the media query breakpoints to your theme. Seeing as they're used throughout the app, this would reduce duplication of values.
It's awesome to see you adding animations and extra details like the attribution overlay. Your attention to detail is incredible!
A couple of feature suggestions I'd love to see would be:
- Try making the form disappear if someone clicks away from it instead of always needing to click the buttons at the bottom.
- I know this wasn't in the design, but you could remove the "Mark as Paid" button from invoices that have a "Paid" status.
Overall, you've done an AMAZING job on this challenge! Especially considering you're still new to React and this was your first time using most of these packages.
Keep up the brilliant work! π
Marked as helpful
@ApplePieGiraffe
Posted
@mattstuddert
Thank you so much, Matt! π€© This helps a lot! π
I 100% agree with everything you said and I'll look into all of those points and try to learn from them! π