Time It App Lets Go!
Tags: opensource, javascript, beginners, programming
Published: 2021-10-15 23:32:16

## Hey,

 It’s good to see you again!

This time I want to talk about my Second time collaborating on someone’s project. This time I was able to collaborate in the [Time It App](https://github.com/time-it-app/time-it-app). 
![TimeItAppLogo](https://github.com/time-it-app/time-it-app/blob/main/src/assets/images/logo.png?raw=true)

Time It app goal is to allow its users to record time and calculate the amount they should charge for it. It keeps the record of all the timed events you have and allow you to copy it to your clipboard.

--- 

## The Issue

[Issue #2]( https://github.com/time-it-app/time-it-app/issues/2) was the issue I decided to work on. Basically, my goal was to add a button loader for the Settings page buttons.
The project use React to build its components so, besides my React being rusted, it was really good to work with it again. 

--- 

## The Solution

First, I had to make a loader using CSS. I used [this](https://www.w3schools.com/howto/howto_css_loader.asp) as reference and ended up using this: 
```CSS

.loader {
    border: 10px solid #f3f3f3;
    border-radius: 50%;
    border-top: 10px solid #364f6b;
    width: 15px;
    height: 15px;
    -webkit-animation: spin 2s linear infinite; /* Safari */
    animation: spin 1.5s linear infinite;
    margin: auto;
  }

  /* Safari */
  @-webkit-keyframes spin {
    0% { -webkit-transform: rotate(0deg); }
    100% { -webkit-transform: rotate(360deg); }
  }
  
  @keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
  }
``` 

To make the Loaders work, I added a state for each, [L8]( https://github.com/time-it-app/time-it-app/blob/main/src/pages/Settings.js#L8) and [L9]( https://github.com/time-it-app/time-it-app/blob/main/src/pages/Settings.js#L9). 

```JavaScript
const [isLoadingDelete, setIsLoadingDelete] = useState(false);
const [isLoadingCopy, setIsLoadingCopy] = useState(false);
```

Because I had to make a loader appear for a process that is almost instantly, I thought it was a better idea to make a symbolic loader instead of one that would last until the process were being processed. 

So I decided to use [setTimeout()](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout) to make the loader appear for just a couple of seconds.

```JavaScript
 function clearLocalStorageData() {
        localStorage.clear();
        setIsLocalStorageEmpty(true);
        if(!isLocalStorageEmpty){ // This one!
         setTimeout(function(){ setIsLoadingDelete(false); }, 1500); // This one!
         setIsLoadingDelete(true); // This one!
        }
    }
```
and
```JavaScript
function localStorageTextToClipboard(text) {
        if (text != null) {
            let newText = text.toString();
            // formatting copied output
            newText = replaceAll(text, '[{', '');
            newText = replaceAll(newText, '}]', '');
            newText = replaceAll(newText, '{', '\n');
            newText = replaceAll(newText, '}', '');
            newText = replaceAll(newText, ',', '\n');
            const temp = document.createElement('textarea');
            document.body.appendChild(temp);
            temp.value = newText;
            temp.select();
            document.execCommand('copy');
            document.body.removeChild(temp);
            setTimeout(function(){ setIsLoadingCopy(false); }, 1500); // This one!
            setIsLoadingCopy(true); // This one!
        } 
    }
```

Then I just had to adjust the JSX to make it work:

```JSX
 {isLoadingDelete 
    ? <div className="loader" /> 
    : <button
     className={`${isLocalStorageEmpty
     ? 'GreyButtonBlueText'
     : 'PinkButtonYellowText'
  }`}
     onClick={clearLocalStorageData}
  >
   delete tasks
 </button>}
```
and
```JSX
 {isLoadingCopy 
   ? <div className="loader" /> 
   : <button
    className="PinkButtonYellowText"
     onClick={ () => 
     localStorageTextToClipboard(localStorage.getItem('tasks'))}
     >
      copy task data
   </button>}

```



I also happened to find a bug that made the onClick function to fire nonstop if a task could be copied to the clipboard, which I fixed while was solving the loader question.

```JSX
 //Before 
onClick={localStorageTextToClipboard(localStorage.getItem('tasks'))}

//Fixed
onClick={ () =>
  localStorageTextToClipboard(localStorage.getItem('tasks'))}
```

--- 


## The Result

Before: 
![Gif 1](https://media0.giphy.com/media/eJ6zS8jxnRRHpSyotj/giphy.gif?cid=790b7611c773037164fcf1b5f0dcf0e80ed20aefb1415762&rid=giphy.gif&ct=g)

After:
![Gif 2]( https://media4.giphy.com/media/ZLtQ0j6RyzrgtpW8aZ/giphy.gif?cid=790b761190141d0720562edb9df9e931499af8e50e2d8789&rid=giphy.gif&ct=g)

--- 

## Finally
This was a great project to contribute to, the people that I have interacted were polite and very welcoming which made me feel very comfortable.
Feels really good to be useful and capable to help other people.

I hope you have enjoyed reading this!
Thank you so much and see you again!