From 6d84542380d8e29b7c85335a0d4909608eeb1fbb Mon Sep 17 00:00:00 2001 From: Anastasiia Karkachova Date: Tue, 24 Oct 2023 09:35:13 +0300 Subject: [PATCH] addtask solution --- README.md | 2 +- src/App.tsx | 142 ++++++++++++++++++++------- src/Types/Todo.ts | 9 ++ src/Types/User.ts | 6 ++ src/components/TodoInfo/TodoInfo.tsx | 27 ++++- src/components/TodoList/TodoList.tsx | 17 +++- src/components/UserInfo/UserInfo.tsx | 14 ++- 7 files changed, 177 insertions(+), 40 deletions(-) create mode 100644 src/Types/Todo.ts create mode 100644 src/Types/User.ts diff --git a/README.md b/README.md index f6e09d1094..2b1471865b 100644 --- a/README.md +++ b/README.md @@ -25,4 +25,4 @@ Implement the ability to add TODOs to the `TodoList` implemented in the **Static - Implement a solution following the [React task guideline](https://github.com/mate-academy/react_task-guideline#react-tasks-guideline). - Use the [React TypeScript cheat sheet](https://mate-academy.github.io/fe-program/js/extra/react-typescript). - Open one more terminal and run tests with `npm test` to ensure your solution is correct. -- Replace `` with your Github username in the [DEMO LINK](https://.github.io/react_add-todo-form/) and add it to the PR description. +- Replace `` with your Github username in the [DEMO LINK](https://dsfreedom.github.io/react_add-todo-form/) and add it to the PR description. diff --git a/src/App.tsx b/src/App.tsx index 9646bf5c6f..fce8511113 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,25 +1,123 @@ import './App.scss'; +import { useState } from 'react'; -// import usersFromServer from './api/users'; -// import todosFromServer from './api/todos'; +import usersFromServer from './api/users'; +import todosFromServer from './api/todos'; +import { TodoList } from './components/TodoList'; +import { Todo } from './Types/Todo'; + +function getUserById(userId: number) { + return usersFromServer.find(user => user.id === userId) || null; +} + +const preparedTodos: Todo[] = todosFromServer.map(todo => ({ + ...todo, + user: getUserById(todo.userId), +})); + +function getMaxId(recievedTodos: Todo[]) { + const maxId = Math.max( + ...recievedTodos.map(todo => todo.id), + ); + + return maxId + 1; +} export const App = () => { + const [title, setTitle] = useState(''); + const [userId, setUserId] = useState(0); + const [todos, setTodos] = useState(preparedTodos); + + const [hasTitleError, setHasTitleError] = useState(false); + const [selectedIdUserError, setSelectedIdUserError] = useState(false); + + function handleSubmit(event: React.ChangeEvent) { + event.preventDefault(); + + let hasErrors = false; + + if (!title) { + setHasTitleError(true); + hasErrors = true; + } else { + setHasTitleError(false); + } + + if (!userId) { + setSelectedIdUserError(true); + hasErrors = true; + } else { + setSelectedIdUserError(false); + } + + if (hasErrors) { + return; + } + + const newPost: Todo = { + id: getMaxId(todos), + title, + completed: false, + userId, + user: getUserById(userId), + }; + + setTodos(currentTodos => [...currentTodos, newPost]); + setTitle(''); + setUserId(0); + } + return (

Add todo form

-
+
- - Please enter a title + + { + setTitle(event.target.value); + setHasTitleError(false); + }} + /> + + {hasTitleError && ( + Please enter a title + )}
- { + setUserId(+event.target.value); + setSelectedIdUserError(false); + }} + > + {usersFromServer.map(user => ( + + ))} - Please choose a user + {selectedIdUserError && ( + Please choose a user + )}
-
- - - - - -
+
); }; diff --git a/src/Types/Todo.ts b/src/Types/Todo.ts new file mode 100644 index 0000000000..99f6f5f38d --- /dev/null +++ b/src/Types/Todo.ts @@ -0,0 +1,9 @@ +import { User } from './User'; + +export interface Todo { + id: number, + title: string, + completed: boolean, + userId: number, + user: User | null, +} diff --git a/src/Types/User.ts b/src/Types/User.ts new file mode 100644 index 0000000000..4d8e55bc27 --- /dev/null +++ b/src/Types/User.ts @@ -0,0 +1,6 @@ +export interface User { + id: number, + name: string, + username: string, + email: string, +} diff --git a/src/components/TodoInfo/TodoInfo.tsx b/src/components/TodoInfo/TodoInfo.tsx index d164511fa8..28df7c21ba 100644 --- a/src/components/TodoInfo/TodoInfo.tsx +++ b/src/components/TodoInfo/TodoInfo.tsx @@ -1 +1,26 @@ -export const TodoInfo = () => {}; +import classNames from 'classnames'; +import { Todo } from '../../Types/Todo'; +import { UserInfo } from '../UserInfo'; + +type Props = { + todo: Todo, +}; + +export const TodoInfo: React.FC = ({ todo }) => { + return ( + <> +
+

+ {todo.title} +

+ + +
+ + ); +}; diff --git a/src/components/TodoList/TodoList.tsx b/src/components/TodoList/TodoList.tsx index c12fae07c0..470b7b7740 100644 --- a/src/components/TodoList/TodoList.tsx +++ b/src/components/TodoList/TodoList.tsx @@ -1 +1,16 @@ -export const TodoList = () => {}; +import { Todo } from '../../Types/Todo'; +import { TodoInfo } from '../TodoInfo'; + +type Props = { + todos: Todo[]; +}; + +export const TodoList: React.FC = ({ todos }) => { + return ( +
+ {todos.map(todo => ( + + ))} +
+ ); +}; diff --git a/src/components/UserInfo/UserInfo.tsx b/src/components/UserInfo/UserInfo.tsx index f7bf0410ec..d05599597a 100644 --- a/src/components/UserInfo/UserInfo.tsx +++ b/src/components/UserInfo/UserInfo.tsx @@ -1 +1,13 @@ -export const UserInfo = () => {}; +import { User } from '../../Types/User'; + +type Props = { + user: User | null, +}; + +export const UserInfo: React.FC = ({ user }) => { + return ( + + {user?.name} + + ); +};