Skip to content

add task solution#1463

Open
ValentynaITCh wants to merge 4 commits into
mate-academy:masterfrom
ValentynaITCh:develop
Open

add task solution#1463
ValentynaITCh wants to merge 4 commits into
mate-academy:masterfrom
ValentynaITCh:develop

Conversation

@ValentynaITCh

Copy link
Copy Markdown

No description provided.

@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

I am requesting changes because there are still some critical requirement violations and at least one test-breaking behavior. Functionally, your app currently calls the posts API when no user is selected, which directly contradicts the test expectation that posts must only be requested after a user is chosen; update your useEffect so it only calls getUsersPosts when selectedUser (or selectedUserId) is present. Validation-wise, the new comment form treats whitespace-only input as valid (using !name, !email, !body without .trim()), which violates the checklist requirement to forbid empty (spaces-only) data [CHECKLIST ITEM #1]; use trimmed values both when setting errors and deciding to submit. In PostDetails/NewCommentForm, add-comment and delete-comment errors are either conflated with the main comments loading error or ignored entirely, so a failed add hides the list/form and a failed delete silently loses the comment; per the starred requirement “Handle Add and Delete errors so the user can retry”, you should introduce dedicated add/delete error state, wrap deletes in try/catch, and restore UI or show a retry option when failures occur. Also, No comments yet is shown whenever comments.length === 0, even during loading or on error; update the condition to !isLoading && !error && comments.length === 0 so it only appears once loading has succeeded. Once you address these points, your implementation will align well with the description and checklist, as most other structure and behavior (users/posts loading, sidebar behavior, loaders, and basic form UX) are already implemented correctly.


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

Important

Fix the issues, commit the changes, and then re-request my review using the Re-request review button2 in the Reviewers tab.

Tip

If you have any comments about this review, please leave a message in the Add a comment section below and mention me with the @mateacademy-ai-mentor tag3.
I will read your message during my next review of your pull request. Please do not reply directly to my comments, as that feature is not supported yet.

Caution

Do not close the pull request until the review is complete. Closing it early can lead to unexpected behavior and disrupt the review process.

Footnotes

  1. Rate AI review example

  2. Re-request AI review example

  3. Add AI review comments example

Comment thread src/App.tsx
Comment on lines +18 to +36
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(false);
const [selectedUser, setSelectedUser] = useState<User | null>(null);
const [users, setUsers] = useState<User[]>([]);
const [posts, setPosts] = useState<Post[]>([]);
const [selectedPost, setSelectedPost] = useState<Post | null>(null);

<div className="block" data-cy="MainContent">
<p data-cy="NoSelectedUser">No user selected</p>
const loadUserPosts = (userId: number) => {
setIsLoading(true);
setError(false);

<Loader />
getUsersPosts(userId)
.then(setPosts)
.catch(() => setError(true))
.finally(() => setIsLoading(false));
};

<div
className="notification is-danger"
data-cy="PostsLoadingError"
>
Something went wrong!
</div>
useEffect(() => {
setIsLoading(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.

Using a single isLoading state for both initial users loading and posts loading makes it impossible to distinguish between those two cases, so the posts loader (selectedUser && isLoading) and posts error message may be driven by users-loading state instead of posts-loading as required. Consider separate loading flags for users and posts to align with the requirement to show the <Loader> and error specifically for posts.

Comment thread src/App.tsx
</div>
export const App = () => {
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(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.

Similarly, the error flag is used only around getUsersPosts, but it is a generic name and could easily get mixed with other errors; the requirement explicitly mentions PostsLoadingError, so using a dedicated postsError state would avoid conflating error sources.

Comment thread src/App.tsx
Comment on lines +12 to +13
import { User } from './types/User';
import { getUsers } from './api/users';

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 optimistic delete here removes the comment from UI but never handles a failure of deleteComment, which violates the optional requirement: "(*) Handle Add and Delete errors so the user can retry". You should wrap the API call in try/catch and restore the comment or expose an error/retry path when deletion fails.

Comment thread src/components/NewCommentForm.tsx Outdated
Comment on lines +49 to +54
setErrors({
name: !name,
email: !email,
body: !body,
});
if (!name || !email || !body) {

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 validation only checks for empty strings, so values containing only spaces will pass (' ' is truthy). This violates checklist item: "make sure you can't add movie with empty data (with spaces only);". Use trimmed values, e.g. name.trim(), email.trim(), body.trim() when setting errors and deciding whether to submit.

Comment thread src/components/NewCommentForm.tsx Outdated
email: !email,
body: !body,
});
if (!name || !email || !body) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

For the same reason, this condition allows whitespace-only input to be treated as valid. Consider computing const trimmedName = name.trim() etc. and using those in both setErrors and this if guard.

Comment on lines +30 to +41
{posts.map(post => (
<tr key={post.id} data-cy="Post">
<td data-cy="PostId">{post.id}</td>

<td data-cy="PostTitle">{post.title}</td>

<td className="has-text-right is-vcentered">
<button
type="button"
data-cy="PostButton"
className={classNames('button is-link', {
'is-light': selectedPostId !== post.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.

Currently, any error in addComment sets the same error flag used for loading errors, which then hides the comments list and the form (due to !error conditions). This makes it hard for users to retry adding a comment. Consider a separate state for add/delete errors so that load errors (CommentsError) and operation errors are handled independently.

Comment on lines 52 to 54

<div className="dropdown-menu" id="dropdown-menu" role="menu">
<div className="dropdown-content">

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Similarly, the body field is only checked as !body, so a comment consisting only of spaces passes validation. Apply trimming here too so that whitespace-only comments are rejected.

Comment thread src/components/UserSelector.tsx Outdated
Comment on lines +59 to +60
onClick={() => onChange(user)}
className={classNames('dropdown-item', {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Since you accept raw name, email, and body here, and upstream validation doesn’t trim, onSubmit may receive whitespace-only values. Even if you trim in the form, it’s safer to treat trimmed values as the payload to avoid sending meaningless spaces to the API.

Comment on lines +45 to 47
<span>{value ? value.name : 'Choose a user'}</span>

<span className="icon is-small">

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

deleteTheComment performs an optimistic UI update but ignores errors from deleteComment. This conflicts with the requirement "(*) Handle Add and Delete errors so the user can retry". Consider wrapping the call in try/catch and restoring the comment state or exposing an error/retry mechanism when the API call fails.

Comment thread src/components/UserSelector.tsx Outdated
Comment on lines +30 to +41
<div
data-cy="UserSelector"
className={classNames('dropdown', { 'is-active': expanded })}
>
<div className="dropdown-trigger">
<button
type="button"
className="button"
aria-haspopup="true"
aria-controls="dropdown-menu"
onClick={e => {
e.stopPropagation();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

On add-comment error you set error to true, which then hides both comments and the form because rendering is guarded by !error. This prevents the user from seeing existing comments or retrying the add, conflicting with "(*) Handle Add and Delete errors so the user can retry". Use a separate piece of state for add errors instead of conflating it with the main loading error flag.

@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

I am requesting changes because there are still a couple of critical checklist violations that block full completion of the task. First, UserSelector (and related logic in App.tsx) attaches a document click listener directly, which violates the explicit requirement to avoid direct DOM interaction and rely on React event handling instead; this needs to be refactored so the dropdown closes via React-managed events (e.g., onBlur, wrapper onClick, or similar) rather than document.addEventListener [CHECKLIST ITEM #2]. Second, none of your components define propTypes for their props, even though the checklist explicitly requires describing objects in propTypes, so you should add appropriate propTypes for components like App, UserSelector, PostsList, PostDetails, and NewCommentForm, including object shapes where relevant [CHECKLIST ITEM #3].

There are also a couple of smaller logic issues worth fixing while you’re at it: the comments error notification currently uses a single CommentsError for both initial comments loading failures and add-comment failures, which makes it hard to distinguish what went wrong; separating these states or messages will better match the requirements and tests. Similarly, the App logic around showing No user selected when users loading fails should be adjusted so that this message still appears even if the users request fails, as the description and tests expect it to be visible alongside UserSelector. Overall, the functionality is very close and most requirements are met, so once you address the DOM interaction, add the missing propTypes, and tidy up the error/message conditions, your solution should fully comply with the task and checklist; you’ve done solid work so far, and these changes will complete it.


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

Important

Fix the issues, commit the changes, and then re-request my review using the Re-request review button2 in the Reviewers tab.

Tip

If you have any comments about this review, please leave a message in the Add a comment section below and mention me with the @mateacademy-ai-mentor tag3.
I will read your message during my next review of your pull request. Please do not reply directly to my comments, as that feature is not supported yet.

Caution

Do not close the pull request until the review is complete. Closing it early can lead to unexpected behavior and disrupt the review process.

Footnotes

  1. Rate AI review example

  2. Re-request AI review example

  3. Add AI review comments example

Comment thread src/App.tsx Outdated
Comment on lines +72 to +78
{!selectedUser && !isLoading && (
<p data-cy="NoSelectedUser">No user selected</p>
)}

{selectedUser && isLoading && <Loader />}

{error && (

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

When the users request fails, selectedUser is still null but isLoading becomes false and error remains true, so the No user selected paragraph will not render because of the !isLoading && !selectedUser condition combined with the separate error branch; the description requires that initially the App shows UserSelector and No user selected in the main content, and tests expect that message even on users-load failure, so you should ensure NoSelectedUser still shows (e.g., make the users-loading error independent of this message or add a dedicated users error state).

Comment thread src/App.tsx Outdated
Comment on lines 9 to 18
import { Loader } from './components/Loader';
import { useEffect, useState } from 'react';
import { User } from './types/User';
import { getUsers } from './api/users';
import { Post } from './types/Post';
import { getUsersPosts } from './api/userPosts';
import { PostsList } from './components/PostsList';

export const App = () => (
<main className="section">
<div className="container">
<div className="tile is-ancestor">
<div className="tile is-parent">
<div className="tile is-child box is-success">
<div className="block">
<UserSelector />
</div>
export const App = () => {

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 component adds and removes a click listener directly on document, which violates checklist item: - don't interact with DOM directly, use React as much as possible;; consider handling the dropdown closing purely through React state and event propagation on elements rather than manipulating document listeners yourself.

Comment thread src/App.tsx
Comment on lines +64 to +128
<UserSelector
users={users}
value={selectedUser}
onChange={setSelectedUser}
/>
</div>

<PostsList />
<div className="block" data-cy="MainContent">
{!selectedUser && !isLoading && (
<p data-cy="NoSelectedUser">No user selected</p>
)}

{selectedUser && isLoading && <Loader />}

{error && (
<div
className="notification is-danger"
data-cy="PostsLoadingError"
>
Something went wrong!
</div>
)}



{posts.length === 0 &&
selectedUser &&
!isLoading &&
!error && (
<div
className="notification is-warning"
data-cy="NoPostsYet"
>
No posts yet
</div>
)}

{posts.length > 0 && !isLoading && !error && (
<PostsList posts={posts} selectedPostId={selectedPost?.id}
onPostSelected={setSelectedPost}/>)}
</div>
</div>
</div>
</div>

<div
data-cy="Sidebar"
className={classNames(
'tile',
'is-parent',
'is-8-desktop',
'Sidebar',
'Sidebar--open',
)}
>
<div className="tile is-child box is-success ">
<PostDetails />
<div
data-cy="Sidebar"
className={classNames(
'tile',
'is-parent',
'is-8-desktop',
'Sidebar',
{
'Sidebar--open': selectedPost,
},
)}
>
<div className="tile is-child box is-success ">
{selectedPost && <PostDetails post={selectedPost} />}
</div>
</div>
</div>
</div>
</div>
</main>
);
</main>
);
};

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 checklist requires make sure you described objects in propTypes;, but none of your components (e.g., App, UserSelector, PostsList, PostDetails, NewCommentForm) define propTypes; you need to add appropriate propTypes descriptions for object props to satisfy that item.

Comment thread src/App.tsx
Comment on lines 29 to +40

<div
className="notification is-danger"
data-cy="PostsLoadingError"
>
Something went wrong!
</div>
getUsersPosts(userId)
.then(setPosts)
.catch(() => setError(true))
.finally(() => setIsLoading(false));
};

useEffect(() => {
setIsLoading(true);

<div className="notification is-warning" data-cy="NoPostsYet">
No posts yet
getUsers()
.then(setUsers)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Per the comment form requirements, CommentsError notification is meant for comments loading failures, and add-comment errors should allow retry without conflating with initial load errors; currently you show the same CommentsError when either error or addError is true ((error || addError)), which makes it impossible to distinguish a load failure from an add failure. Consider separate messages or data-cy hooks for loading vs adding errors so users can understand what went wrong and tests can target the correct state.

Comment thread src/App.tsx Outdated
Comment on lines 9 to 18
import { Loader } from './components/Loader';
import { useEffect, useState } from 'react';
import { User } from './types/User';
import { getUsers } from './api/users';
import { Post } from './types/Post';
import { getUsersPosts } from './api/userPosts';
import { PostsList } from './components/PostsList';

export const App = () => (
<main className="section">
<div className="container">
<div className="tile is-ancestor">
<div className="tile is-parent">
<div className="tile is-child box is-success">
<div className="block">
<UserSelector />
</div>
export const App = () => {

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 follow these naming conventions for methods recommends clear handleX style names for event handlers; here handleDocumentClick is a handler but the click listener is attached to document in useEffect rather than declared as a React event callback prop, which both conflicts with the DOM interaction guideline and makes handler naming less consistent with the rest of the app. Refactoring to React-driven handlers (onClick={handleToggle}, etc.) would align better with the conventions.

Comment thread src/api/postComments.ts
@@ -0,0 +1,14 @@
import { Comment } from '../types/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.

Checklist item "make sure you described objects in propTypes" also applies here: PostDetails receives a post prop but doesn’t define propTypes to describe its shape.

Comment thread src/api/postComments.ts
@@ -0,0 +1,14 @@
import { Comment } from '../types/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.

Checklist item "make sure you described objects in propTypes" applies to this component too: NewCommentForm has an onSubmit prop with a specific signature but no corresponding propTypes description.

Comment thread src/components/UserSelector.tsx Outdated
Comment on lines +13 to +22
useEffect(() => {
if (!expanded) {
return;
}

const handleDocumentClick = () => {
setExpanded(false);
};

document.addEventListener('click', handleDocumentClick);

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 violates checklist item "don't interact with DOM directly, use React as much as possible" because you are adding a global document click listener. Consider using React-controlled event handling (e.g., closing the dropdown via React onClick/onBlur on appropriate elements) instead of attaching listeners directly to document.

@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

I am approving your solution as an educational override so you can keep progressing while you refine these last details.

You’ve done a strong job on the core functionality: users and posts load correctly, the sidebar and comments flow work as described, you use fetchClient with the required delay, classnames for conditional styling, and your propTypes definitions with object shapes are solid. The main areas to improve are around state and error handling: several handlers and effects (especially in App.tsx, NewCommentForm, and parts of the comments logic) still call multiple setState functions in a single body, which goes against [CHECKLIST ITEM #9], and some async flows (users/posts loading and comments loading) still rely on .then/.catch instead of async/await with try {..} catch, as recommended in [CHECKLIST ITEM #10]. You also reuse a single error flag for both comments-loading and add-comment failures in PostDetails, which makes it hard for users to tell what went wrong; separating these into distinct error states/messages would better match the requirements. As you iterate, focus on consolidating related state into single updates (or a reducer), wrapping all async operations in try/catch, and distinguishing comments loading vs add-comment errors in the UI.

Overall, your solution is very close to fully polished; these remaining tweaks are great opportunities to deepen your understanding of React state management and robust error handling. Keep up the good work—your foundation here is strong and you’re clearly thinking carefully about both functionality and code quality.


✨ 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
Comment on lines +35 to +36
useEffect(() => {
setIsLoading(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.

This useEffect body calls setIsLoading twice (here and in loadUserPosts), which matches the checklist item * don't use setState several times in one function call (method) (it's better for clarity of the code); — consider consolidating related state updates so a single setState call handles both flags.

Comment thread src/App.tsx
Comment on lines +45 to +52
useEffect(() => {
setSelectedPost(null);
setPosts([]);

if (selectedUser) {
loadUserPosts(selectedUser.id);
} else {
setPosts([]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Within this useEffect, you call both setSelectedPost and setPosts (and another setPosts in the else branch). This violates checklist item * don't use setState several times in one function call (method) (it's better for clarity of the code); — try grouping dependent state updates into one setter or restructuring so you don’t call multiple setters in a single logical handler.

Comment on lines +23 to +34
const clearForms = () => {
setValues({
name: '',
email: '',
body: '',
});

setErrors({
name: false,
email: false,
body: 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.

clearForms calls both setValues and setErrors in one function body, which violates checklist item * don't use setState several times in one function call (method); consider restructuring state (e.g., combine values and errors or wrap this logic in a single state update) so you don’t call multiple setters per handler.

Comment on lines +37 to +43
const handleChange = (
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
) => {
const { name: field, value } = e.target;

setValues(current => ({ ...current, [field]: value }));
setErrors(current => ({ ...current, [field]: 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.

Similarly, handleChange calls both setValues and setErrors for every change. This matches the “Bad example” pattern from checklist item * don't use setState several times in one function call (method); try to unify these updates in a single state change or adjust your state shape to allow one setter.

Comment on lines +46 to +70
const handleSubmit = async (event: React.FormEvent) => {
event.preventDefault();

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

setErrors({
name: !trimmedName,
email: !trimmedEmail,
body: !trimmedBody,
});

if (!trimmedName || !trimmedEmail || !trimmedBody) {
return;
}

setSubmitting(true);
await onSubmit({
name: trimmedName,
email: trimmedEmail,
body: trimmedBody,
});
setSubmitting(false);
setValues(current => ({ ...current, body: '' }));

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 set submitting to true and then back to false in the same function, adding to multiple state updates in one handler along with setErrors and setValues. This again conflicts with checklist item about not using setState several times in one function call; refactoring to reduce the number of separate state updates would improve clarity and checklist compliance.

Comment on lines +25 to 32
}}
>
<div className="dropdown-trigger">
<button
type="button"
className="button"
aria-haspopup="true"
aria-controls="dropdown-menu"

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 posts-loading logic uses .catch(() => setError(true)) without try {..} catch, which violates checklist item * use try {..} catch for error handling. Refactor to async/await with try/catch so error handling is consistently implemented.

Comment on lines +23 to +35
setExpanded(false);
}
}}
>
<div className="dropdown-trigger">
<button
type="button"
className="button"
aria-haspopup="true"
aria-controls="dropdown-menu"
onClick={() => setExpanded(prev => !prev)}
>
<span>Choose a user</span>
<span>{value ? value.name : 'Choose a user'}</span>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

clearForms calls both setValues and setErrors in a single function body, directly matching the pattern the checklist warns about: * don't use setState several times in one function call (method); consider combining form values and errors into a single state or using one update function.

Comment on lines +46 to +70
<a
key={user.id}
href={`#user-${user.id}`}
onClick={() => {
onChange(user);
setExpanded(false);
}}
className={classNames('dropdown-item', {
'is-active': user.id === value?.id,
})}
>
{user.name}
</a>
))}
</div>
</div>
</div>
);
};
UserSelector.propTypes = {
users: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.number.isRequired,
name: PropTypes.string.isRequired,
username: PropTypes.string.isRequired,

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 call setErrors, setSubmitting(true), setSubmitting(false), and setValues in one function body; while functional, this pattern violates the checklist guidance against using setState several times in a single function. Consider simplifying the state transitions or grouping related updates.

Comment on lines +22 to 31
if (!dropdownRef.current?.contains(e.relatedTarget)) {
setExpanded(false);
}
}}
>
<div className="dropdown-trigger">
<button
type="button"
className="button"
aria-haspopup="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.

loadComments currently uses a .catch(() => setError(true)) chain, but checklist item * use try {..} catch for error handling expects you to handle async errors via try/catch. Refactor this to an async function with await getPostComments wrapped in try/catch to align with the checklist and match your add/delete patterns.

Comment on lines +73 to +77
}).isRequired,
).isRequired,

value: PropTypes.shape({
id: PropTypes.number.isRequired,

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 single error state is used both for initial comments loading errors and add-comment failures, but you only show one generic CommentsError notification. The requirements call for distinguishing these error cases; introduce separate flags/messages (e.g., commentsLoadError, addCommentError) so users can see whether loading or adding failed.

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