Skip to content

Commit

Permalink
Todo App with registration
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergey-Kovyazin committed Sep 13, 2023
1 parent 12f7c54 commit ddba80e
Show file tree
Hide file tree
Showing 30 changed files with 1,372 additions and 110 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,4 @@ Implement a simple [TODO app](http://todomvc.com/examples/vanillajs/) working as
- 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 `<your_account>` with your Github username in the [DEMO LINK](https://<your_account>.github.io/react_todo-app/) and add it to the PR description.
- Replace `<your_account>` with your Github username in the [DEMO LINK](https://Sergey-Kovyazin.github.io/react_todo-app/) and add it to the PR description.
40 changes: 25 additions & 15 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
"author": "Mate Academy",
"license": "GPL-3.0",
"dependencies": {
"@fortawesome/fontawesome-free": "^6.4.0",
"bulma": "^0.9.4",
"classnames": "^2.3.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
126 changes: 40 additions & 86 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,93 +1,47 @@
/* eslint-disable jsx-a11y/control-has-associated-label */
import React from 'react';
import { useState, useCallback } from 'react';
import { User } from './types/User';
import { UserWarning } from './UserWarning';
import { Registration } from './components/Registration/Registration';
import { useLocalStorage } from './hooks/useLocalStorage';
import { TodoApp } from './components/TodoApp/TodoApp';

export const App: React.FC = () => {
return (
<div className="todoapp">
<header className="header">
<h1>todos</h1>

<form>
<input
type="text"
data-cy="createTodo"
className="new-todo"
placeholder="What needs to be done?"
/>
</form>
</header>

<section className="main">
<input
type="checkbox"
id="toggle-all"
className="toggle-all"
data-cy="toggleAll"
/>
<label htmlFor="toggle-all">Mark all as complete</label>

<ul className="todo-list" data-cy="todoList">
<li>
<div className="view">
<input type="checkbox" className="toggle" id="toggle-view" />
<label htmlFor="toggle-view">asdfghj</label>
<button type="button" className="destroy" data-cy="deleteTodo" />
</div>
<input type="text" className="edit" />
</li>

<li className="completed">
<div className="view">
<input type="checkbox" className="toggle" id="toggle-completed" />
<label htmlFor="toggle-completed">qwertyuio</label>
<button type="button" className="destroy" data-cy="deleteTodo" />
</div>
<input type="text" className="edit" />
</li>
const USER_ID = 10326;

<li className="editing">
<div className="view">
<input type="checkbox" className="toggle" id="toggle-editing" />
<label htmlFor="toggle-editing">zxcvbnm</label>
<button type="button" className="destroy" data-cy="deleteTodo" />
</div>
<input type="text" className="edit" />
</li>

<li>
<div className="view">
<input type="checkbox" className="toggle" id="toggle-view2" />
<label htmlFor="toggle-view2">1234567890</label>
<button type="button" className="destroy" data-cy="deleteTodo" />
</div>
<input type="text" className="edit" />
</li>
</ul>
</section>

<footer className="footer">
<span className="todo-count" data-cy="todosCounter">
3 items left
</span>

<ul className="filters">
<li>
<a href="#/" className="selected">All</a>
</li>
export const App: React.FC = () => {
const [
currentUser,
setCurrentUser,
] = useLocalStorage<User | null>('user', null);

<li>
<a href="#/active">Active</a>
</li>
const [errorType, setErrorType] = useState<string | null>(null);
const setError = useCallback((typeOfError: string | null) => {
setErrorType(typeOfError);
setTimeout(() => setErrorType(null), 3000);
}, [errorType]);

<li>
<a href="#/completed">Completed</a>
</li>
</ul>
if (!USER_ID) {
return <UserWarning />;
}

<button type="button" className="clear-completed">
Clear completed
</button>
</footer>
</div>
return (
<>
{currentUser
? (
<TodoApp
currentUser={currentUser}
setErrorType={setErrorType}
errorType={errorType}
setError={setError}
/>
)
: (
<Registration
setCurrentUser={setCurrentUser}
setErrorType={setErrorType}
errorType={errorType}
setError={setError}
/>
)}
</>
);
};
22 changes: 22 additions & 0 deletions src/UserWarning.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react';

export const UserWarning: React.FC = () => (
<section className="section">
<p className="box is-size-3">
Please get your
{' '}
<b> userId </b>
{' '}
<a href="https://mate-academy.github.io/react_student-registration">
here
</a>
{' '}
and save it in the app
{' '}
<pre>const USER_ID = ...</pre>

All requests to the API must be sent with this
<b> userId.</b>
</p>
</section>
);
26 changes: 26 additions & 0 deletions src/api/todos.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Todo } from '../types/Todo';
import { client } from '../utils/fetchClient';

export const getTodos = (userId: number) => {
return client.get<Todo[]>(`/todos?userId=${userId}`);
};

export const addTodo = (userId: number, title: string) => {
return client.post<Todo>('/todos', {
id: 0,
userId,
title,
completed: false,
});
};

export const updateTodo = (
todoId: number,
data: {},
) => {
return client.patch<Todo>(`/todos/${todoId}`, data);
};

export const deleteTodo = (todoId: number) => {
return client.delete(`/todos/${todoId}`);
};
10 changes: 10 additions & 0 deletions src/api/users.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { User } from '../types/User';
import { client } from '../utils/fetchClient';

export const createUser = (user: Omit<User, 'id'>) => {
return client.post<User>('/users', user);
};

export const getUser = (email: string) => {
return client.get<User[]>(`/users?email=${email}`);
};
32 changes: 32 additions & 0 deletions src/components/Error/Error.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/* eslint-disable jsx-a11y/control-has-associated-label */
import React from 'react';
import classNames from 'classnames';

type Props = {
setErrorType: React.Dispatch<React.SetStateAction<string | null>>
errorMessage: string | null,
};

export const Error: React.FC<Props> = ({
setErrorType,
errorMessage,
}) => (
<>
{errorMessage && (
<div className={classNames(
'notification', 'is-danger', 'is-light', 'has-text-weight-normal', {
hidden: !errorMessage,
},
)}
>
<button
type="button"
className="delete"
onClick={() => setErrorType(null)}
/>

{errorMessage}
</div>
)}
</>
);
Loading

0 comments on commit ddba80e

Please sign in to comment.