diff --git a/src/App.tsx b/src/App.tsx index a9a9bb4c53..62053aad05 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,27 +1,113 @@ +import React, { useState } from 'react'; + import './App.scss'; -// 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'; +import { User } from './types/User'; + +const getNewTodoId = (todo: Todo[]) => { + const maxId = Math.max(...todo.map(todoMax => todoMax.id)); + + return maxId + 1; +}; + +const getUserById = (userId: number): User => { + return usersFromServer.find(user => user.id === userId) as User; +}; + +const initialTodos = todosFromServer.map(todo => ({ + ...todo, + user: getUserById(todo.userId), +})); + +export const App: React.FC = () => { + const [todos, setTodos] = useState(initialTodos); + const [title, setTitle] = useState(''); + const [userId, setUserId] = useState(0); + const [hasTitleError, setTitleError] = useState(false); + const [hasUserIdError, setUserIdError] = useState(false); + + const handlUserSelect = (event: React.ChangeEvent) => { + setUserId(Number(event.currentTarget.value)); + setUserIdError(false); + }; + + const handleTitleChange = (e: React.ChangeEvent) => { + const regExp = /[^a-zA-ZА-ЩЬЮЯҐЄІЇа-щьюяґєі0-9\s]/g; + const value = e.currentTarget.value.replace(regExp, ''); + + setTitle(value); + setTitleError(false); + }; + + const handleFormSubmit = (e: React.FormEvent) => { + e.preventDefault(); + + setTitleError(!title); + setUserIdError(!userId); + + if (title && userId) { + setTitle(''); + setUserId(0); + + const newTodo = { + id: getNewTodoId(todos), + title, + completed: false, + userId, + user: getUserById(userId), + }; + + setTodos(currentTodos => [...currentTodos, newTodo]); + } + }; -export const App = () => { return (

Add todo form

-
+
- - Please enter a title + + {hasTitleError && Please enter a title}
- + - Please choose a user + {hasUserIdError && ( + Please choose a user + )}
-
- - - - - -
+
); }; diff --git a/src/components/TodoInfo/TodoInfo.tsx b/src/components/TodoInfo/TodoInfo.tsx index d164511fa8..4f33554db9 100644 --- a/src/components/TodoInfo/TodoInfo.tsx +++ b/src/components/TodoInfo/TodoInfo.tsx @@ -1 +1,17 @@ -export const TodoInfo = () => {}; +import { Todo } from '../../types/Todo'; +import { UserInfo } from '../UserInfo'; + +type Props = { + todo: Todo; +}; + +export const TodoInfo: React.FC = ({ todo }) => ( +
+

{todo.title}

+ + +
+); diff --git a/src/components/TodoList/TodoList.tsx b/src/components/TodoList/TodoList.tsx index c12fae07c0..e3492bb0f4 100644 --- a/src/components/TodoList/TodoList.tsx +++ b/src/components/TodoList/TodoList.tsx @@ -1 +1,14 @@ -export const TodoList = () => {}; +import { Todo } from '../../types/Todo'; +import { TodoInfo } from '../TodoInfo'; + +type Props = { + todos: Todo[]; +}; + +export const TodoList: React.FC = ({ todos }) => ( +
+ {todos.map(todo => ( + + ))} +
+); diff --git a/src/components/UserInfo/UserInfo.tsx b/src/components/UserInfo/UserInfo.tsx index f7bf0410ec..1fbca4e1d8 100644 --- a/src/components/UserInfo/UserInfo.tsx +++ b/src/components/UserInfo/UserInfo.tsx @@ -1 +1,12 @@ -export const UserInfo = () => {}; +import React from 'react'; +import { User } from '../../types/User'; + +type Props = { + user: User; +}; + +export const UserInfo: React.FC = ({ user }) => ( + + {user.name} + +); diff --git a/src/types/Todo.ts b/src/types/Todo.ts new file mode 100644 index 0000000000..ec8b562a81 --- /dev/null +++ b/src/types/Todo.ts @@ -0,0 +1,9 @@ +import { User } from './User'; + +export type Todo = { + id: number; + title: string; + completed: boolean; + userId: number; + user: User; +}; diff --git a/src/types/User.ts b/src/types/User.ts new file mode 100644 index 0000000000..f74409b994 --- /dev/null +++ b/src/types/User.ts @@ -0,0 +1,6 @@ +export type User = { + id: number; + name: string; + username: string; + email: string; +};