Skip to content

feat(react): dynamic-list-of-posts#1465

Open
xapg6acc wants to merge 1 commit into
mate-academy:masterfrom
xapg6acc:master
Open

feat(react): dynamic-list-of-posts#1465
xapg6acc wants to merge 1 commit into
mate-academy:masterfrom
xapg6acc:master

Conversation

@xapg6acc

@xapg6acc xapg6acc commented Jul 5, 2026

Copy link
Copy Markdown

@mateacademy-ai-mentor mateacademy-ai-mentor left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Review Summary

Your solution is approved because all core functional requirements are met: users and posts load correctly, the sidebar opens and shows post details immediately, comments are fetched with proper loading/error/empty states, and the comment form behaves as specified (validation with trimming, error handling on submit, keeping name/email, clearing body, and optimistic deletion). There are no issues that would block task completion or break the main flows.

The main issues left are non-blocking checklist mismatches: UserSelector uses document.addEventListener('click', ...) for outside-click handling (violating the "don’t interact with the DOM directly" guideline [CHECKLIST ITEM #2]), and components rely only on TypeScript types without propTypes for object props [CHECKLIST ITEM #3]. You also have some lingering ESLint-disable comments and unused imports that could be cleaned up, and your error handling for comment add/delete relies on .catch without surfacing retry options, even though the description suggests optional retry handling.

Going forward, I recommend refactoring the outside-click behavior to a React-based approach (e.g., a higher-level click handler or an outside-click hook), adding propTypes definitions for components receiving objects, and introducing some visible error state for failed createComment/deleteComment calls so users can retry when needed. Despite these improvements being possible, your current implementation is functionally solid and aligns well with the task, so you can confidently move on while keeping these refinements in mind for future iterations.


✨ Please rate this review in the Platform's notification center1. I will be grateful for your feedback! ✨

Footnotes

  1. Rate AI review example

Comment thread src/App.tsx
>
Something went wrong!
</div>
setPostsLoading(true);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

You’re calling setPostsLoading, setPostsError, setPosts, and setSelectedPost sequentially in the same effect. While this works, checklist item #8 recommends not using setState several times in one function for clarity; consider consolidating related state changes or using a single state object if appropriate.

Comment thread src/App.tsx

<div className="notification is-warning" data-cy="NoPostsYet">
No posts yet
getUserPosts(selectedUser.id)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The promise chain here handles errors via .catch, but checklist item #9 suggests using try {..} catch for error handling. Not mandatory, but you might refactor to async/await with try/catch for clearer error handling semantics.

Comment thread src/App.tsx
Comment on lines +29 to +33
if (!selectedUser) {
return;
}

<div
className="notification is-danger"
data-cy="PostsLoadingError"
>
Something went wrong!
</div>
setPostsLoading(true);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Your validation trims name, email, and body before checking emptiness, which correctly satisfies checklist item #1 (prevent adding entries with spaces only). If you want to align with the optional recommendation in checklist item #8, you could reduce the number of setState calls here by grouping them, but it’s not required.

Comment thread src/App.tsx
selectedUser && !postsLoading && !postsError && posts.length > 0;

return (
<main className="section">

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The submission handler doesn’t use try/catch; instead, it relies on .then/.finally. Checklist item #9 recommends try {..} catch for error handling (optional). To allow user retries and show add-error feedback (optional requirement in the description), consider capturing and surfacing errors from createComment.

Comment thread src/App.tsx
Comment on lines +34 to +36
setPostsError(false);
setPosts([]);
setSelectedPost(null);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

You optimistically remove the comment and then call deleteComment. This matches the requirement to delete immediately for UX, but you don’t handle deletion errors (the description’s optional "Handle Add and Delete errors so the user can retry"). Consider adding error handling so a failed delete can be retried or rolled back.

Comment on lines +50 to +57
createComment(commentData)
.then(newComment => {
onAddComment(newComment);
setBody('');
})
.finally(() => {
setIsSubmitting(false);
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

In handleSubmit, you handle errors via promise chaining but do not expose any retry mechanism or user-visible error state for failed createComment calls, while the description mentions handling Add/Delete errors so the user can retry; consider tracking an error state and rendering a notification or retry UI.

Comment on lines +34 to +37
setHasEmailError(emailError);
setHasBodyError(bodyError);

if (nameError || emailError || bodyError) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

You optimistically delete comments and call deleteComment(commentId) but do not handle a failed delete or allow retry, whereas the description suggests handling Add/Delete errors so the user can retry; consider adding error state and UI to inform the user and possibly restore the comment on failure.

Comment on lines +24 to +27

const trimmedName = name.trim();
const trimmedEmail = email.trim();
const trimmedBody = body.trim();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Checklist item recommends using try {..} catch for error handling; here you rely solely on .catch in chained promises for loading comments—while functionally sufficient, you might consider async/await with try/catch for clearer error handling, especially if you extend this logic.


import { Comment } from '../types/Comment';
import { Post } from '../types/Post';
import { deleteComment, getPostComments } from '../api';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

There is an unused import User here that is never referenced in this file. This goes against checklist guidance about keeping code clean and can be safely removed.

Comment on lines +20 to +30
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (
dropdownRef.current &&
!dropdownRef.current.contains(event.target as Node)
) {
setIsOpen(false);
}
};

document.addEventListener('click', handleClickOutside);

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 direct use of document.addEventListener('click', ...) to handle outside clicks violates checklist item: "don't interact with DOM directly, use React as much as possible". Consider a React-based approach (e.g., handling clicks via a higher-level component or using a library/outside-click hook) instead of attaching a global document listener manually.

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