Skip to content

Conversation

Ouriel91
Copy link

No description provided.

<option value="Z-A">Z-A</option>
</select>
</div>
<div class="input-container">

Choose a reason for hiding this comment

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

Great layout modeling! well done!


* {
box-sizing: border-box;
margin: 0;
Copy link

@SergeiSafrigin SergeiSafrigin May 26, 2022

Choose a reason for hiding this comment

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

in general, it's usually a bad practice to use the wildcard selector *, as it applies to all elements, rather than inheriting the style from a parent element (it still could be html or body) which are much easier to override when needed.
You can read more on CSS precedence here - https://jenkov.com/tutorials/css/precedence.html

You also have this cool library that normalizes the base/default styles across different browsers - https://necolas.github.io/normalize.css/


body {
width: 100%;
height: 100vh;

Choose a reason for hiding this comment

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

in order for the viewport styles (vh/vw) to apply correctly you need to add this meta tag to the HTML header

You can read more on css viewport here https://www.educba.com/css-viewport/

.add-button {
width: 10%;
min-width: 35px;
height: 100%;

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 align the base style of different components such as "button", to avoid code duplication, improve maintainability & have a consistent UI across the app.
You can add a button class with that base style and apply it to all the buttons.

(same goes for input and other components)

transition: all 0.3s ease;
}

.add-button.active, .clear-all-button.active {

Choose a reason for hiding this comment

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

nice re-use!

position: relative;
background-image: url("https://www.itgovernance.eu/blog/de/wp-content/uploads/2017/04/list.jpg");
background-size: cover;
height: 40vh;

Choose a reason for hiding this comment

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

viewport styles are considered a bad practice when used on inner components as it ignores the 'box' it's inside of, and uses the whole viewport as a reference, making it hard to maintain and forces you to change its size anytime the parent UI changes.

top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
z-index: 100;

Choose a reason for hiding this comment

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

Much easier to achieve with flex-box and is considered a better practice in general - https://css-tricks.com/snippets/css/a-guide-to-flexbox/


.todo-list-container {
max-height: 250px;
overflow-y: auto;

Choose a reason for hiding this comment

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

like!

overflow-y: auto;
}

.todo-list-container li {

Choose a reason for hiding this comment

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

Using "li" here instead of a class makes it coupled to this specific solution. If you'll need to change li to a different element (ex: div) you'll have to make many changes in the code

position: absolute;
right: -40px;
top: 50%;
transform: translateY(-50%);
Copy link

@SergeiSafrigin SergeiSafrigin May 26, 2022

Choose a reason for hiding this comment

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

the positioning here is very hard to maintain, as every change of the width will require adjusting the position of all the elements, flex-box will help you here as well

const clearAllTodosButton = document.getElementById("clear-all-todos-button")
const sumTodos = document.getElementById("sum-todos")
const orderSelect = document.getElementById("order-select")
const enterTodos = document.getElementById("enter-todos")

Choose a reason for hiding this comment

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

having all the elements outside here requires all the dom elements exist when this file is loaded, which might not be the case in complex web apps that dynamically change the dom depending on the view


showTodos()

todoInput.onkeyup = (e) => {

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 addEventListener method to add dom events


todoInput.onkeyup = (e) => {
let enterValue = todoInput.value
if (enterValue.trim() !== ""){
Copy link

@SergeiSafrigin SergeiSafrigin May 26, 2022

Choose a reason for hiding this comment

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

well done with this extra validation!

addTodoButton.style.cursor = "pointer"
addTodoButton.style.opacity = 1

if(e.keyCode === 13){

Choose a reason for hiding this comment

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

try to avoid "magic numbers", creating a const for this value will improve readability, for example:

const ENTER_KEY = 13; // at the top of the file

if (e.keyCode === ENTER_KEY) {...}

}
}
else{
addTodoButton.classList.remove("active")
Copy link

@SergeiSafrigin SergeiSafrigin May 26, 2022

Choose a reason for hiding this comment

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

it's considered a good practice to hide the implementation of different actions to improve code readability, maintability & code-reuse, for example:

const isEmptyTodoValue = e.keyCode === ENTER_KEY;
if (isEmptyTodoValue) {
deactivateAddTaskBtn();
} else {
activateAddTaskBtn();
if (e.keyCode === ENTER_KEY) {
addTodo();
}
}

function addTodo(){
let enterValue = todoInput.value

if(enterValue.trim() === ""){

Choose a reason for hiding this comment

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

the second time you check this -> could be moved to a function

return
}

checkIfExistDataFromLS()

Choose a reason for hiding this comment

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

I wonder why we have this check here as well

todoList = []
}
else{
todoList = JSON.parse(dataFromLS)

Choose a reason for hiding this comment

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

it's a bad practice to update some global variable from within a function, better use return instead :)

}

checkIfExistDataFromLS()
pushEnteredDataToLS(enterValue)

Choose a reason for hiding this comment

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

Awesome! love it!!!

Choose a reason for hiding this comment

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

Small bug: the enterValue is not trimmed before it's added

}

function showTodos() {
checkIfExistDataFromLS()

Choose a reason for hiding this comment

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

why don't we do this only once when the app loads?


orderSelect.addEventListener('change', (e) => {
let dataFromLS = localStorage.getItem("new-todo")
todoList = JSON.parse(dataFromLS)

Choose a reason for hiding this comment

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

it's better to encapsulate all the local storage operations behind functions to avoid accessing it directly. Then you could also build wrappers that both fetch and save the todos, and handle that calls to the local storage functions when needed

Copy link

@SergeiSafrigin SergeiSafrigin left a comment

Choose a reason for hiding this comment

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

See comments

<span class="delete" onclick="deleteTodo(${index})";>
<i class="fas fa-trash"></i>
</span>
<span class="edit" onclick="editTodo(${index})";>

Choose a reason for hiding this comment

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

functions inside the html are considered a bad practice and can lead to many bugs, prefer using addEventListener

`
})

todoListElement.innerHTML = listItems

Choose a reason for hiding this comment

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

cool idea!!! but has some downsides as you can't access the elements while creating them before they enter the dom

}

function editTodo(index) {
let editedValue = prompt('Edit todo:', todoList[index])
Copy link

@SergeiSafrigin SergeiSafrigin May 26, 2022

Choose a reason for hiding this comment

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

BUG: if you cancel the edit, it will rename it to null

todoList = JSON.parse(dataFromLS)

if(e.target.value === "A-Z") {
todoList = todoList.sort()

Choose a reason for hiding this comment

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

the sort method mutates the original array, therefore it's better to copy it beforehand ex: [...todoList.sort()];

As mutating the state directly (and complex data structures in general) is considered a bad practice as other parts of the code might be using it, not expecting it to suddenly change.
Read more on pure functions and the immutability approach in coding https://css-tricks.com/understanding-immutability-in-javascript/

Copy link
Author

Choose a reason for hiding this comment

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

Hi @SergeiSafrigin i fixed all the comments that you gave to me it was very helpfull

@Ouriel91 Ouriel91 closed this May 31, 2022
@Ouriel91 Ouriel91 reopened this May 31, 2022
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.

2 participants