-
Notifications
You must be signed in to change notification settings - Fork 60
Julia D, recipe library #62
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
base: main
Are you sure you want to change the base?
Conversation
bjoernholmlund
left a comment
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.
Good job with the project! Clean and nice code, easy to follow along.
| <div class="filter filter-wrapper filter-random"> | ||
| <h3>Feeling adventurous?</h3> | ||
| <button id="btnRandom" class="btn">✨Get a random recipe✨</button> | ||
| </div> |
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 filter section feels inspiring: “Feeling adventurous?” with a ✨ button makes me want to click. Fun!
| ><img | ||
| class="card-img" | ||
| src="./Assets/focaccia.png" | ||
| alt="close-up photo of a focaccia with cherry tomatoes on it" |
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 alt text on the image is good: “close-up photo of a focaccia…” it helps both accessibility and SEO.
| <div class="card"> | ||
| <a | ||
| href="https://www.kingarthurbaking.com/blog/2025/01/03/recipe-of-the-year-focaccia" | ||
| target="_blank" |
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.
Link settings are careful: target="_blank" + rel="noopener noreferrer" safe and neat.
| @@ -0,0 +1,325 @@ | |||
| //Main DOM | |||
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 code feels well organized and easy to follow. I like how you've gathered all the DOM fetching at the top. It gives a good overview and makes it easy to understand what the page is made of.
| } | ||
|
|
||
| //Filters and sorting functions | ||
| function applyFiltersAndSorting() { |
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 functions follow a natural order. For example this one applyFiltersAndSorting() feels like a clear hub where filtering and sorting are gathered in a clear way.
| let showingFavourites = false; | ||
|
|
||
|
|
||
| //API |
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.
Keep them comments coming! 👍
| }); | ||
| } | ||
|
|
||
| function initTimeFilters() { |
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.
Clear logic for how the filter buttons work, easy to follow along with the flow.
JennieDalgren
left a comment
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.
Great job with this project!
You have structured your code well and it is easy to follow with only the short comments you have. The code follows a natural flow and you could almost read the project itself from reading only your code files.
Good implementation of requirements and several stretch goals!
Keep up the good work 🚀
| //Default states | ||
| let recipes = []; | ||
| let favourites = JSON.parse(localStorage.getItem("favourites")) || []; | ||
| let activeCuisines = []; | ||
| let activeTime = null; | ||
| let activeSort = null; | ||
| let showingFavourites = false; |
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.
⭐
| //Cache functions | ||
| function saveCache(data) { | ||
| localStorage.setItem("cachedRecipes", JSON.stringify(data)); | ||
| localStorage.setItem("cacheTime", Date.now()); | ||
| } | ||
|
|
||
| function getCache() { | ||
| const cached = localStorage.getItem("cachedRecipes"); | ||
| const time = localStorage.getItem("cacheTime"); | ||
| if (!cached || !time) return null; | ||
| const SIX_HOURS = 6 * 60 * 60 * 1000; | ||
| if (Date.now() - Number(time) > SIX_HOURS) return null; | ||
| return JSON.parse(cached); | ||
| } |
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.
great implementation
| cardsContainer.innerHTML = ` | ||
| <div class="empty-state"> | ||
| <h2>No recipes found</h2> | ||
| <img src="./Assets/404error.jpg" alt="No recipes found" class="empty-state-img" /> |
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.
hehehehe love that image
| function applyFiltersAndSorting() { | ||
| if (showingFavourites) return; | ||
|
|
||
| let filtered = [...recipes]; |
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.
spread operator! nice
| const loading = document.createElement("div"); | ||
| loading.textContent = "Loading recipes..."; | ||
| loading.style.textAlign = "center"; | ||
| cardsContainer.innerHTML = ""; | ||
| cardsContainer.appendChild(loading); | ||
|
|
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.
loading! nice
| function toggleFavourite(id) { | ||
| const recipe = recipes.find(r => r.id === id) || favourites.find(f => f.id === id); | ||
| if (!recipe) return; | ||
|
|
||
| const exists = favourites.some(f => f.id === id); | ||
| if (exists) { | ||
| favourites = favourites.filter(f => f.id !== id); | ||
| } else { | ||
| favourites.push(recipe); |
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.
nice feature!
| if (text.includes("30")) newTime = "30"; | ||
| else if (text.includes("45")) newTime = "45"; | ||
| else if (text.includes("1,5")) newTime = "90"; | ||
| else if (text.includes("3")) newTime = "180"; |
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 see what you want to do here. It is totally fine to do it like this! in the future you could think about building a small little helper function that only converts the time into minutes and returns that. That way it can be used throughout a project whenever you need to convert hours to minutes or similar.
| const otherButtons = [ | ||
| btnAll, btnAsian, btnFrench, btnMexican, btnItalian, | ||
| ...timeBtns, | ||
| sortShortest, sortLongest, | ||
| btnFavourites | ||
| ]; |
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.
smart to add the buttons in an array and then loop through them
| function attachUiEvents() { | ||
| initCuisineFilters(); | ||
| initTimeFilters(); | ||
| initSortingButtons(); | ||
| initRandomButton(); | ||
| initFavouritesButton(); | ||
| } | ||
|
|
||
|
|
||
| // Initial load | ||
| function init() { | ||
| attachUiEvents(); | ||
| btnAll.classList.add("active"); | ||
| fetchRecipes(); | ||
| } |
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.
good structure and naming
https://juls-recipe-library.netlify.app/