Skip to content

Develop#3573

Open
BiCoNn wants to merge 26 commits intomate-academy:developfrom
BiCoNn:develop
Open

Develop#3573
BiCoNn wants to merge 26 commits intomate-academy:developfrom
BiCoNn:develop

Conversation

@BiCoNn
Copy link

@BiCoNn BiCoNn commented Mar 9, 2026

No description provided.

Copy link

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

Choose a reason for hiding this comment

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

Review Summary

Great job implementing the core functionality! The app works well, and the tests you've written are comprehensive. However, some changes are needed to align with the project's architectural requirements before this can be approved.

The primary issue is the data flow. The App component should be the single source of truth and prepare all data for its children [CHECKLIST ITEM #5]. Currently, the TodoInfo component fetches the user list itself. To fix this, you should first update the ToDo type in src/types/ToDo.ts to include the user object. Then, in App.tsx, when creating a new todo, you should find the full selectedUser object and add it to the newTask before updating the state.

Additionally, the form in App.tsx is missing <label> elements for the input and select fields, which is an important accessibility requirement. Please also address the use of one-letter variable names in your find methods [CHECKLIST ITEM #1].

Addressing these points will bring the solution in line with all the project guidelines. Keep up the great work!


✨ 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

node-version: [20.x]

steps:
- uses: actions/checkout@v2

Choose a reason for hiding this comment

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

It's a good practice to use the latest versions of GitHub Actions. actions/checkout@v2 is outdated. Consider updating to a newer version like v4 for better performance and security.

const [titleError, setTitleError] = useState(false);

const handleChangeUser = (event: React.ChangeEvent<HTMLSelectElement>) => {
const user = users.find(u => u.username === event.target.value);

Choose a reason for hiding this comment

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

This violates checklist item #1: 'Don't use one-letter variable naming.' Please use a more descriptive name for the parameter in the find method, for example, user instead of u.

Comment on lines +35 to +40
if (!titleTask.trim()) {
setTitleError(true);
}

setTitle(titleTask);
setTitleError(false);

Choose a reason for hiding this comment

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

The logic here is a bit confusing. The error state is set to true inside the if block, but then it's immediately set back to false on the next line. This makes the if block redundant. According to the requirements, the error should be hidden on any change, so calling setTitleError(false) is sufficient here.

Comment on lines +60 to +65
const newTask: ToDo = {
id: maxId,
title: title,
completed: false,
userId: selectedUser!.id,
};

Choose a reason for hiding this comment

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

The new task object is missing the user property as required by the task description ("each TODO item must have... and a user object..."). Currently, the TodoInfo component has to import the entire list of users to find the correct one. This violates checklist item #5, which states that data should be prepared in the root component and passed down. You should add the selectedUser object to this newTask and adjust the initial todos state to also include the user object for each todo.

src/App.tsx Outdated
id: maxId,
title: title,
completed: false,
userId: selectedUser!.id,

Choose a reason for hiding this comment

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

While there's a check for selectedUser earlier in the function, using the non-null assertion operator (!) is generally considered a bad practice as it can hide potential bugs. Since you've already confirmed selectedUser is not null, you can safely access selectedUser.id without the assertion.

Comment on lines +92 to +96
<select
data-cy="userSelect"
value={selectedUser?.username ?? '0'}
onChange={handleChangeUser}
>

Choose a reason for hiding this comment

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

This select element is also missing an associated <label> element. All form controls should have labels for better accessibility.

export const TodoInfo = () => {};
import { UserInfo } from '../UserInfo';
import ToDo from '../../types/ToDo';
import users from '../../api/users';

Choose a reason for hiding this comment

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

This violates checklist item #5: 'Prepare data in one place (App component) and pass it to child components. Don't use import keyword in non-root components'. The TodoInfo component should receive a todo object that already includes the full user object, rather than looking it up here.

};

export const TodoInfo = ({ todo }: Props) => {
const taskUser = users.find(u => u.id === todo.userId);

Choose a reason for hiding this comment

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

This logic for finding the user belongs in the parent App component, as stated in checklist item #5. Furthermore, this violates checklist item #1: 'Don't use one-letter variable naming.' The parameter u should be renamed to something more descriptive, like user.

Comment on lines +14 to +25
{taskUser ? (
<article
data-id={todo.id}
className={`TodoInfo ${todo.completed ? 'TodoInfo--completed' : ''}`}
>
<h2 className="TodoInfo__title">{todo.title}</h2>

<UserInfo name={taskUser.name} email={taskUser.email} />
</article>
) : (
''
)}

Choose a reason for hiding this comment

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

This conditional rendering violates the principle described in checklist item #4. The parent component should be responsible for ensuring that TodoInfo receives a valid todo object with a user. This component should not have to handle the case where taskUser might not be found. The check for a valid user should happen before this component is rendered.

Comment on lines +3 to +8
type ToDo = {
id: number;
title: string;
completed: boolean;
userId: User['id'];
};

Choose a reason for hiding this comment

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

The task description explicitly requires each ToDo item to have a user object containing the user's details. This type is missing the user: User; property. Adding it is a crucial first step to align with the application's data structure and fix the architectural issue in TodoInfo.tsx.

Copy link

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

Choose a reason for hiding this comment

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

Review Summary

Great work on the form logic and state management. However, this submission requires changes because several critical requirements from the task description and previous feedback have not yet been met.

The most important issue is the application's data flow. The App component must be the single source of truth, but the TodoInfo component is currently fetching its own data by importing the users list. This violates a core architectural guideline [CHECKLIST ITEM #5].

To resolve this, you'll need to:

  1. Update the ToDo type in src/types/ToDo.ts to include the full user: User object.
  2. In App.tsx, when creating a new task, find the complete selectedUser object and add it to the newTask.
  3. Remove the data import and user-finding logic from TodoInfo.tsx so it only displays the data passed via props.

Additionally, please remember to add the required <label> elements to the form in App.tsx for accessibility.


✨ 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

const [titleError, setTitleError] = useState(false);

const handleChangeUser = (event: React.ChangeEvent<HTMLSelectElement>) => {
const user = users.find(u => u.username === event.target.value);

Choose a reason for hiding this comment

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

This violates checklist item #1: 'Don't use one-letter variable naming.' Please use a more descriptive variable name like user instead of u. This was also noted in the previous review and is important for code readability.

Comment on lines +32 to +41
const handleChangeTitle = (event: React.ChangeEvent<HTMLInputElement>) => {
const titleTask = event.target.value;

if (!titleTask.trim()) {
setTitleError(true);
}

setTitle(titleTask);
setTitleError(false);
};

Choose a reason for hiding this comment

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

This handler function works, but the logic is a bit confusing. The if block on lines 35-37 sets an error that is immediately cleared by setTitleError(false) on line 40. Since the requirement is to show errors only on submission and hide them on input change, you can simplify this function by removing lines 35-37.

Comment on lines +60 to +65
const newTask: ToDo = {
id: maxId,
title: title,
completed: false,
userId: selectedUser!.id,
};

Choose a reason for hiding this comment

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

This is the central part that needs adjustment based on the previous review. The task requires each new todo to have a complete user object.

Currently, you're only adding userId. To fix this:

  1. First, update the ToDo type in src/types/ToDo.ts to include a user: User property.
  2. Then, here in App.tsx, add the selectedUser object to newTask: user: selectedUser.

This will make the App component the single source of truth and will allow you to remove the user lookup logic from the TodoInfo component, satisfying checklist item #5.

<h1>Add todo form</h1>

<form action="/api/users" method="POST">
<form action="/api/todos" method="POST" onSubmit={addTaskHandler}>

Choose a reason for hiding this comment

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

The form is missing its corresponding <label> elements for the input and select fields. This is an important accessibility requirement and was part of the feedback from the previous review. Please add labels for both form controls.

export const TodoInfo = () => {};
import { UserInfo } from '../UserInfo';
import ToDo from '../../types/ToDo';
import users from '../../api/users';

Choose a reason for hiding this comment

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

This violates checklist item #5. Non-root components like TodoInfo should not import data sources directly. All data should be prepared in the App component and passed down as props. This was a critical point in the previous review feedback and needs to be addressed.

};

export const TodoInfo = ({ todo }: Props) => {
const taskUser = users.find(u => u.id === todo.userId);

Choose a reason for hiding this comment

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

This logic for finding the user should be in the App component. The todo object passed to this component should already contain the complete user object. Additionally, this violates checklist item #1 by using the one-letter variable u.

Comment on lines +3 to +8
type ToDo = {
id: number;
title: string;
completed: boolean;
userId: User['id'];
};

Choose a reason for hiding this comment

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

This ToDo type is missing the required user object property. The task description and previous review feedback specified that each todo should contain the full user object. Please add user: User; to this type definition.

Copy link

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

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 because you've done an excellent job refactoring the application's architecture! The data flow is now much cleaner with App as the single source of truth, which was the main goal of this iteration.

While your work is approved, here are a few key areas to focus on for future tasks:

  • Type Safety: In src/types/ToDo.ts, the user property on the ToDo type should be required (user: User) instead of optional. Since your app logic always includes a user, making the type stricter prevents potential bugs.
  • Code Clarity: The if block within the handleChangeTitle function in src/App.tsx is redundant and can be safely removed to simplify the code.
  • Naming Conventions: Please avoid one-letter variable names like u. Using descriptive names like user makes the code much easier to read and maintain. [CHECKLIST ITEM #1]

Keep up the great work, you're making fantastic progress!


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

Footnotes

  1. Rate AI review example

- name: Upload tests report(cypress mochaawesome merged HTML report)
if: ${{ always() }}
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4

Choose a reason for hiding this comment

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

There seems to be a mismatch in the artifact path. According to cypress.config.ts, the test reports are generated in the raw_reports directory. However, this step attempts to upload from a reports directory (defined on line 29), which likely doesn't exist. Please update the path to match your Cypress configuration.

const [titleError, setTitleError] = useState(false);

const handleChangeUser = (event: React.ChangeEvent<HTMLSelectElement>) => {
const user = users.find(u => u.username === event.target.value);

Choose a reason for hiding this comment

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

This violates checklist item #1: "Don't use one-letter variable naming". Please rename u to a more descriptive name like user to improve code readability.

Comment on lines +39 to +41
if (!titleTask.trim()) {
setTitleError(true);
}

Choose a reason for hiding this comment

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

This if block is redundant. The call to setTitleError(true) on line 40 has no effect because setTitleError(false) is called unconditionally on line 44 right after it. You can safely remove this if statement, as the requirement is only to hide the error on change, which line 44 already accomplishes.

<h1>Add todo form</h1>

<form action="/api/users" method="POST">
<form action="/api/todos" method="POST" onSubmit={addTaskHandler}>

Choose a reason for hiding this comment

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

The action and method attributes are not necessary for a form handled entirely by React on the client side. The onSubmit handler in React (addTaskHandler) prevents the default browser form submission, so these attributes will never be used. You can remove them for cleaner code.

Comment on lines +87 to +93
<input
type="text"
data-cy="titleInput"
value={title}
onChange={handleChangeTitle}
placeholder="Enter title of task"
/>

Choose a reason for hiding this comment

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

To improve accessibility and provide a better user experience, it would be beneficial to add an id attribute to this input that matches the htmlFor in the associated <label>.

Comment on lines +99 to +103
<select
data-cy="userSelect"
value={selectedUser?.username ?? '0'}
onChange={handleChangeUser}
>

Choose a reason for hiding this comment

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

To improve accessibility, please add an id attribute to this <select> element that matches the htmlFor attribute of its corresponding <label>.

};

export const TodoInfo = ({ todo }: Props) => {
// const taskUser = users.find(u => u.id === todo.userId);

Choose a reason for hiding this comment

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

This line is no longer needed and can be removed. Great job on refactoring this component to rely on props instead of fetching its own data!

title: string;
completed: boolean;
userId: User['id'];
user?: User;

Choose a reason for hiding this comment

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

According to the task description, every todo item must have a user object. The logic in your App component also ensures this is always the case. To align the type with the requirements and the actual data structure, please make the user property non-optional by removing the ?.

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.

7 participants