Skip to content

Commit

Permalink
solution2
Browse files Browse the repository at this point in the history
  • Loading branch information
Shevchuchka committed Nov 2, 2024
1 parent c1b9036 commit ff27209
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 109 deletions.
2 changes: 0 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ export const App: React.FC = () => {
return (
<div className="todoapp">
<TodosProvider>
<h1 className="todoapp__title">todos</h1>

<Content />
</TodosProvider>
</div>
Expand Down
30 changes: 16 additions & 14 deletions src/components/Content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { TodosContext } from '../context/TodosContex';
export const Content: React.FC = () => {
const { todos, setTodos } = useContext(TodosContext);

const [focused, setFocused] = useState(true);
const [visibleTodos, setVisibleTodos] = useState(todos);

useEffect(() => {
Expand All @@ -27,18 +26,21 @@ export const Content: React.FC = () => {
}, [todos]);

return (
<div className="todoapp__content">
<Header focused={focused} setFocused={setFocused} />

<TodoList visibleTodos={visibleTodos} setFocused={setFocused} />

{todos.length > 0 && (
<Footer
visibleTodos={visibleTodos}
setVisibleTodos={setVisibleTodos}
setFocused={setFocused}
/>
)}
</div>
<>
<h1 className="todoapp__title">todos</h1>

<div className="todoapp__content">
<Header />

<TodoList visibleTodos={visibleTodos} />

{todos.length > 0 && (
<Footer
visibleTodos={visibleTodos}
setVisibleTodos={setVisibleTodos}
/>
)}
</div>
</>
);
};
14 changes: 2 additions & 12 deletions src/components/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,9 @@ import { Todo } from '../types/Todo';
type Props = {
visibleTodos: Todo[];
setVisibleTodos: (vilteredTodos: Todo[]) => void;
setFocused: (value: boolean) => void;
};

export const Footer: React.FC<Props> = ({
visibleTodos,
setVisibleTodos,
setFocused,
}) => {
export const Footer: React.FC<Props> = ({ visibleTodos, setVisibleTodos }) => {
const { todos, setTodos } = useContext(TodosContext);

const [selectedFilter, setSelectedFilter] = useState<Filter>(Filter.All);
Expand Down Expand Up @@ -54,12 +49,7 @@ export const Footer: React.FC<Props> = ({
};

const clearFunction = () => {
const completedTodos = todos
.filter(todo => todo.completed)
.map(todo => todo.id);

setTodos(todos.filter(todo => !completedTodos.includes(todo.id)));
setFocused(true);
setTodos(todos.filter(t => !t.completed));
};

const setFilter = (filter: Filter) => {
Expand Down
58 changes: 17 additions & 41 deletions src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,66 +1,46 @@
import React, {
useCallback,
useContext,
useEffect,
useRef,
useState,
} from 'react';
import React, { useContext, useEffect, useRef, useState } from 'react';
import { TodosContext } from '../context/TodosContex';
import classNames from 'classnames';
import { Todo } from '../types/Todo';

type Props = {
focused: boolean;
setFocused: (value: boolean) => void;
};

export const Header: React.FC<Props> = ({ focused, setFocused }) => {
export const Header: React.FC = () => {
const { todos, setTodos } = useContext(TodosContext);

const [title, setTitle] = useState('');

const inputRef = useRef<HTMLInputElement>(null);

useEffect(() => {
if (inputRef.current && focused) {
if (inputRef.current) {
inputRef.current.focus();
}
}, [focused]);
}, [todos]);

const checkActiveTodos = useCallback((): boolean => {
const checkActiveTodos = (): boolean => {
if (todos.length > 0) {
return todos.every(todo => todo.completed);
}

return false;
}, [todos]);

const onInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
event.preventDefault();
setTitle(event.target.value);
};

const addTodo = (todoTitle: string) => {
const newTodo: Todo = {
id: +new Date(),
title: todoTitle,
completed: false,
};

setTodos([...todos, newTodo]);
};

const onSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();

const normalizedTitle = title.trim();

if (normalizedTitle.length > 0) {
addTodo(normalizedTitle);
setTitle('');
} else {
if (!normalizedTitle) {
return;
}

const newTodo: Todo = {
id: +new Date(),
title: normalizedTitle,
completed: false,
};

setTodos([...todos, newTodo]);
setTitle('');
};

const toggleAll = () => {
Expand All @@ -72,7 +52,6 @@ export const Header: React.FC<Props> = ({ focused, setFocused }) => {
}));

setTodos(toggledTodos);
setFocused(true);
};

return (
Expand All @@ -88,15 +67,12 @@ export const Header: React.FC<Props> = ({ focused, setFocused }) => {
/>
)}

<form
onSubmit={event => onSubmit(event)}
onBlur={() => setFocused(false)}
>
<form onSubmit={event => onSubmit(event)}>
<input
data-cy="NewTodoField"
ref={inputRef}
value={title}
onChange={event => onInputChange(event)}
onChange={event => setTitle(event.target.value)}
type="text"
className="todoapp__new-todo"
placeholder="What needs to be done?"
Expand Down
47 changes: 10 additions & 37 deletions src/components/TodoItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,18 @@ import { TodosContext } from '../context/TodosContex';

type Props = {
todo: Todo;
setFocused: (value: boolean) => void;
};

export const TodoItem: React.FC<Props> = ({ todo, setFocused }) => {
export const TodoItem: React.FC<Props> = ({ todo }) => {
const { todos, setTodos } = useContext(TodosContext);

const [onEdit, setOnEdit] = useState(false);
const [title, setTitle] = useState(todo.title);

const todoInputRef = useRef<HTMLInputElement>(null);
const normalizedTitle = title.trim();

useEffect(() => {
if (onEdit && todoInputRef.current) {
if (todoInputRef.current) {
todoInputRef.current.focus();
}
}, [onEdit]);
Expand All @@ -32,32 +30,12 @@ export const TodoItem: React.FC<Props> = ({ todo, setFocused }) => {
}
};

const onInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
event.preventDefault();

setTitle(event.target.value);
};

const updateTodo = (updatedTodo: Todo) => {
const newTodos = [...todos];

const index = todos.findIndex(
currentTodo => currentTodo.id === updatedTodo.id,
);

newTodos.splice(index, 1, updatedTodo);

setFocused(true);
setTodos(newTodos);
};

const deleteTodo = () => {
setTodos(todos.filter(currentTodo => currentTodo.id !== todo.id));
setTodos(todos.map(t => (t.id === updatedTodo.id ? updatedTodo : t)));
};

const onDelete = () => {
deleteTodo();
setFocused(true);
setTodos(todos.filter(currentTodo => currentTodo.id !== todo.id));
};

const statusChange = () => {
Expand All @@ -66,22 +44,17 @@ export const TodoItem: React.FC<Props> = ({ todo, setFocused }) => {

const onSubmit = (event?: React.FormEvent<HTMLFormElement>) => {
event?.preventDefault();
setOnEdit(false);

if (normalizedTitle.length === 0) {
deleteTodo();

return;
}
const normalizedTitle = title.trim();

if (normalizedTitle === todo.title) {
setTitle(normalizedTitle);
setOnEdit(false);
if (!normalizedTitle) {
onDelete();

return;
}

updateTodo({ ...todo, title: title });
setOnEdit(false);
updateTodo({ ...todo, title: normalizedTitle });
};

return (
Expand Down Expand Up @@ -122,7 +95,7 @@ export const TodoItem: React.FC<Props> = ({ todo, setFocused }) => {
ref={todoInputRef}
value={title}
onChange={event => {
onInputChange(event);
setTitle(event.target.value);
}}
onBlur={() => onSubmit()}
onKeyUp={event => handleKeyUp(event)}
Expand Down
5 changes: 2 additions & 3 deletions src/components/TodoList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@ import { Todo } from '../types/Todo';

type Props = {
visibleTodos: Todo[];
setFocused: (value: boolean) => void;
};

export const TodoList: React.FC<Props> = ({ visibleTodos, setFocused }) => {
export const TodoList: React.FC<Props> = ({ visibleTodos }) => {
return (
<section className="todoapp__main" data-cy="TodoList">
{visibleTodos.map(todo => (
<TodoItem todo={todo} key={todo.id} setFocused={setFocused} />
<TodoItem todo={todo} key={todo.id} />
))}
</section>
);
Expand Down
4 changes: 4 additions & 0 deletions src/styles/todoapp.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
* {
box-sizing: border-box;
}

.todoapp {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 24px;
Expand Down

0 comments on commit ff27209

Please sign in to comment.