Hi @semperprimum!
First of all nice solution! Identical to the design!
Passing props down from Grid
to Card
would've been a hassle so I think managing the state for this challenge using the ContextAPI is good! and yours look good to me.
I just have a few suggestions regarding those ternary ladders inside the Card
component. While it does work it, it kind of makes it complex and less readable. One way you can do it efficiently is by using some helper functions and adding the logic for it there. Here's how I would do it:
- For the Icons instead of the ladder you can do something like an object which has keys and values as the Icon components like this:
const icons = {
Work: <IconWork />,
Play: <IconPlay />,
Study: <IconStudy />,
Exercise: <IconExercise />,
Social: <IconSocial />,
Self Care: <IconSelfCare />
};
and then in the return you can just do this:
<Banner className={`bg-accent-${item.title.toLowerCase().split(' ').join('-')}`}>
{icons[item.title]}
</Banner>
this way those 13 lines of code will just be 1! Since the JSON file has titles that are capitalized that's why in the icons object you must have to use capitalized words as keys so that they match and the icons get rendered. It will work like this -> The title from JSON matches the key from the icons object and the corresponding icon associated with the key will render out. This way you won't have to check for the titles using the ternary operator.
- For the time ladders you can make a helper function like
timeFrames
which takes in the type
state as a param from context and then return current and previous. (basically extracting that type ternary ladder from the time and last p element in the card element since you can see they are repeated) like this:
const timeframes = (type) => {
const current = item.timeframes[type].current;
const previous = item.timeframes[type].previous;
return { current, previous };
};
then destructure the object returned by the function while using type
from the context:
const { current, previous } = timeframes(type);
- Now
current
and previous
will hold the values for whatever type is there. So now you can use the current
like this:
<Time className="fs-600 fw-regular">
{current} hrs
</Time>
and for the previous
hours you can use it like this:
<p className="fw-semi-bold text-primary-200">
{type === 'daily' ? 'Yesterday' : type === 'weekly' ? 'Last Week' : 'Last Month'} - {previous} hrs
</p>
- You can probably cut down the text ternary ladder too but at this point I feel like this is enough hahahha!
- If you wanna still do it then you can do it the same way as we did for icons that is to make an object and then give key value pairs like
daily: 'Yesterday'
and so on and then the paragraph element can be rewritten like this:
<p className="fw-semi-bold text-primary-200">
{nameofobject[type]} - {previous} hrs
</p>
I don't know if my explanation is okay because I'm very bad at giving names to functions but hoping you at least get the idea of what I'm trying to say haha
Keep up the hard work!