Skip to content

Platform React App#30

Open
lkatmadas wants to merge 9 commits into
GlobalWebIndex:mainfrom
lkatmadas:feat/initial-commit
Open

Platform React App#30
lkatmadas wants to merge 9 commits into
GlobalWebIndex:mainfrom
lkatmadas:feat/initial-commit

Conversation

@lkatmadas
Copy link
Copy Markdown

No description provided.

@lkatmadas lkatmadas changed the title Initial commit Platform React App Jun 30, 2025
cursor[bot]

This comment was marked as outdated.

@lkatmadas lkatmadas force-pushed the feat/initial-commit branch from defd8ab to b19fdd3 Compare June 30, 2025 06:22
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.

@gpositive
Copy link
Copy Markdown

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

I've checked your assignment and I have a couple of questions for you:

  • I saw that you're using 2 different lock files in the project (ie: yarn.lock and package-lock.json). Could you share on why this is done?
  • We're getting this error in the console in the cats list component. Example here: Query data cannot be undefined. Please make sure to return a value other than undefined from your query function. Affected query key: ["cats","is-favourited","dn9"] Could we get more details about it?
  • If you had some more time, what would you have done differently?
  • Can you please respond to the comments I made across the whole project?

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This may not be needed I guess?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Oh my bad and no excuse here! Somehow missed this one and pushed it, sorry.

const [isModalDismissed, setIsModalDismissed] = useState(false)
const { data: fallbackCat = null, isLoading: isFetchingFallbackCat } = useCatImage(selectedCatId)

const debouncedHoverRef = useRef(
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Could you describe on why you've decided to use a ref to achieve this?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I used a ref to store the debounced hover handler so the function stays stable across renders and doesn’t get recreated on every update. This makes sure the debounce logic works as expected and helps avoid unnecessary API calls—for example, from handleCardHover. It also lets me clean up on unmount using .cancel(), which helps prevent any side effects after the component is removed.

Comment thread package.json
"lint:fix": "eslint . --fix",
"preview": "vite preview",
"test": "vitest",
"test:ui": "vitest --ui",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This doesn't seem to work for me. Wondering if it's needed? 🤔

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I added @vitest/ui intending to try out the UI interface, but ended up focusing more on the UI and accessibility work. It's an optional user interface for Vitest that I thought might be a good idea to have, but it is not currently used. Happy to remove it if needed.

@lkatmadas
Copy link
Copy Markdown
Author

Hello @gpositive,
Thank you for taking the time to review the PR and for your feedback.
I’ll go through your comments and follow up shortly.

@lkatmadas
Copy link
Copy Markdown
Author

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

I've checked your assignment and I have a couple of questions for you:

  • I saw that you're using 2 different lock files in the project (ie: yarn.lock and package-lock.json). Could you share on why this is done?
  • We're getting this error in the console in the cats list component. Example here: Query data cannot be undefined. Please make sure to return a value other than undefined from your query function. Affected query key: ["cats","is-favourited","dn9"] Could we get more details about it?
  • If you had some more time, what would you have done differently?
  • Can you please respond to the comments I made across the whole project?

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

- About the 2 different lock files:
You're right, and thanks for pointing this out. I accidentally committed the package-lock.json file. I had been switching between projects where we use npm, but this one uses yarn, so I shouldn't have included it. The project is set up to use yarn.lock, and yarn is what I used during development, so there's no actual dependency mismatch, just a leftover file I forgot to exclude.


- About "Query data cannot be undefined. Affected query key: ["cats","is-favourited","dn9"]
Last-minute changes are never a good idea.
Although enabled: !!imageId might skip query execution, React Query still sets up the queryKey and queryFn.
It happens because getFavouriteByImageId() is returning undefined, which React Query explicitly disallows unless we're using initialData or placeholderData.

We need to make sure the queryFn never returns undefined. Something like this will probably fix the issue:

export const useIsCatFavourited = (imageId?: string) => {
  return useQuery({
    queryKey: queryKeys.cats.isFavourited(imageId ?? 'noop'),
    queryFn: async () => {
      if (!imageId) return null
      const favourite = await getFavouriteByImageId(imageId)
      return favourite ?? null
    },
    enabled: !!imageId,
    retry: false,
  })
}

- If I had some more time, what would I have done differently?
I was able to spend about 5 days on this project, and I believe there’s always room for improvement. Here are a few areas I would focus on if I had more time:

General technical improvements:

  • Move static text into constants or a translation map to support future localization without modifying component code.
  • Extract static hex values into a shared colors.ts or theme config to promote consistency and simplify updates.
  • Add proper 404 and fallback error pages.
  • Ensure button components support a disabled state with visual clarity and accessibility.
  • Replace or adapt the GWI logo to work on dark backgrounds.
  • Review and potentially fine-tune React Query's default retry behavior (currently 3 retries) to avoid unnecessary load on predictable failures like 404s.
  • Improve error handling and user notifications:
    • Show specific feedback based on HTTP status codes (e.g., 401 Unauthorized, 404 Not Found).
    • Provide more actionable or contextual UI messages instead of generic alerts.

For UI/UX:

  • Modal layout: I'd look for a better layout solution, especially for the featured image. Since image aspect ratios vary (e.g., portrait vs. landscape), some images might get cropped in a way that hides important content. In this case, I might be able to improve the CardItem to use it in this case, too.
  • Clickable card: Either show a pointer cursor on hover or reconsider making the full card clickable, especially since it might conflict with hover actions as more features are added.
  • Avoid using SVGs with . Instead, import them as React components to allow styling, animations, etc.
  • Improve the "Favourite" button by using a heart icon, ideally with a simple animation for better visual feedback.

Testing:

  • Expand both unit and E2E test coverage, especially around API interactions, to catch the errors mentioned as well.

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.

2 participants