Skip to content

Conversation

melnikolaidis86
Copy link

This pull request adds a complete Cat Lovers web application built using modern React tooling and best practices. The project showcases several key frontend technologies and architectural patterns, including:

🔧 Tech Stack:

  • React (CRA)
  • Redux Toolkit for state management
  • React Router for routing
  • Context API and React Hooks for component logic and state sharing
  • Tailwind CSS for utility-first styling
  • BFF (Backend-for-Frontend) layer for data fetching abstraction

✨ Key Features:

  • Centralized state handling with Redux Toolkit
  • Component-level state and effects with React Hooks
  • Routing between multiple pages using React Router
  • Used Context api for alternative method of handling state
  • Clean UI styled with Tailwind CSS
  • Integration with a backend via BFF pattern

This PR includes all the initial implementation for the core UI, routing, state handling, and styling. It serves as the foundation for future feature additions and scalability improvements.


Please review and let me know if any changes are required. 😊

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Null Assertion Risks in User and Category Handling

Unsafe non-null assertions (!) are used on catId and userId. catId is an optional parameter, but catId! is used when adding a favourite without a null check. userId can be null from the user context, but userId! is used when fetching favourites without a null check. This can lead to runtime errors if these variables are undefined or null.

src/hooks/useFavourites.ts#L46-L49

} else {
await dispatch(addFavourite({ image_id: catId!, sub_id: userId })).unwrap();
}
dispatch(fetchFavourites(userId!));

Fix in CursorFix in Web


Bug: Null Country Code Causes TypeError

Potential TypeError when currentBreed.country_code.toUpperCase() is called. This occurs if currentBreed exists but currentBreed.country_code is null or undefined. The current currentBreed && ... check is insufficient as it only validates currentBreed. Use optional chaining: currentBreed?.country_code?.toUpperCase().

src/components/BreedDetailsModal.tsx#L8-L9

const { isModalOpen, currentBreed, currentBreedImages, handleClose } = useBreedDetails();
const Code = currentBreed && currentBreed.country_code.toUpperCase();

Fix in CursorFix in Web


Bug: Null Assertion Errors in User Functions

The handleRemove function uses an unsafe non-null assertion on userId!. This can cause a runtime error if userId is null or undefined, for instance, if the user context is not initialized. A similar issue exists in the toggleFavourite function.

src/hooks/useFavourites.ts#L58-L59

await dispatch(removeFavourite(favourite_id)).unwrap();
dispatch(fetchFavourites(userId!));

Fix in CursorFix in Web


Was this report helpful? Give feedback by reacting with 👍 or 👎

Copy link

@gpositive gpositive left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @melnikolaidis86 - Thanks a lot for your effort dude! :)

I've checked your assignment and I have some questions for you:

  • Noticed that the same favourites network requests are performed multiple times in some cases (ie: in the cats list page). Any idea on why this is happening and how could you prevent it?
  • Seems that you're using headlessui package to have a modal component ready for you. If you were to create one yourself, how would you approach it?
  • Are there any performance improvements that you've may thought on doing?
  • If you had some more time, what would you have done differently?

Again thanks for your submission and looking forward to your answers!

"name": "catlover",
"version": "0.1.0",
"private": true,
"dependencies": {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noticed that you don't have any devDependencies defined. Is this on purpose?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some devDependencies on package.json

"devDependencies": {
"@types/react-router-dom": "^5.3.3",
"autoprefixer": "^10.4.21",
"concurrently": "^9.2.0",
"cypress": "^14.5.2",
"postcss": "^8.5.6",
"tailwindcss": "^3.4.17"
}

However some of the them could have been moved to devDepenencies

"@testing-library/dom"
"@testing-library/jest-dom"
"@testing-library/react"
"@testing-library/user-event"
"@types/jest"
"@types/node"
"@types/react"
"@types/react-dom"
"react-scripts"
"typescript"
"web-vitals"

@@ -0,0 +1,2 @@
CAT_API_KEY=
MAX_FAVOURITES=10

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May you provide some more info about this env variable?
Why do we need a MAX_FAVOURITES variable in the server layer, in the app layer?
Also: What's the rational behind this decision?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason behind this is that there is a hard limit of 100 favorites when fetching favorites and if there are too many favorites I think I should have added pagination on this page too for better ux. However, on second thought I think it would be have been better if I had completely removed this env variable on server and added a hard limit of 100 in FE while checking if the added favorite exists on unique favorites list. Also I think it would have been better if I had added this list on local storage and invalidated when adding a new favorite.

@melnikolaidis86
Copy link
Author

Hey @melnikolaidis86 - Thanks a lot for your effort dude! :)

I've checked your assignment and I have some questions for you:

  • Noticed that the same favourites network requests are performed multiple times in some cases (ie: in the cats list page). Any idea on why this is happening and how could you prevent it?
  • Seems that you're using headlessui package to have a modal component ready for you. If you were to create one yourself, how would you approach it?
  • Are there any performance improvements that you've may thought on doing?
  • If you had some more time, what would you have done differently?

Again thanks for your submission and looking forward to your answers!

Hey @gpositive - it was a pleasure doing this assignment.

  • Indeed the request for fetching favorites is performed when fetching cat list in order to match if there are cats already in favorite list and display the proper icon, however this could be prevented by adding favorites to local storage and invalidate local storage when adding an new cat in list.
  • It would be very possible to create a custom modal instead of using headlessui. The basic structure would be to create a div for backdrop and a div for holding the modal information and passing children as content. The main props would be isOpen, onClose, title, children. The downside is that I had to add accessibility rules like closing on esc button, headless ui is more robust and handles all these rules on its own
  • Certainly, besides adding favorites in local storage I could use some caching like redis to fetch and save cat list in redis for instance.
  • I just saw that I didn't add the catsapi in .env and I keep copying in each request in BFF layer. Another thing it would be to completely remove the max favorites from both .env files and maybe add a hard limit of 100 favorites in FE as it's the max number of favorites you can fetch by default. Another thing would be to add React Helmet for some SEO purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants