Added loader + Improvements.

This commit is contained in:
Daniel
2022-06-03 11:56:19 +04:30
parent 1d23855eac
commit c5104f432c
17 changed files with 298 additions and 28 deletions
+15 -2
View File
@@ -8,6 +8,8 @@ import Sort from './componets/Sort';
import sortList from './modules/sortList';
import filter from './modules/filterData';
import concatTags from './modules/concatTags';
import NoResults from './componets/NoResults';
import Loader from './componets/Loader';
function App() {
const [data, setData] = useState([]),
@@ -19,7 +21,12 @@ function App() {
[nameChecked, setNameChecked] = useState(true),
[descriptionChecked, setDescriptionChecked] = useState(true),
[tagsChecked, setTagsChecked] = useState(true),
[sortBy, setSortBy] = useState('Default');
[sortBy, setSortBy] = useState('Default'),
[loader, setLoader] = useState(false);
function SetLoader(x) {
setLoader(x)
}
function handleNameCheckbox() {
setNameChecked(!nameChecked);
@@ -66,6 +73,7 @@ function App() {
useEffect(() => {
fetchData();
// eslint-disable-next-line
}, [sortBy]);
useEffect(() => {
@@ -79,12 +87,14 @@ function App() {
<button className="btn" onClick={() => setNewBox(true)}>&#xf067;</button>
</div>
<p className="results">{numberOfResults > 0 ? numberOfResults + ' Bookmarks found' : 'No bookmarks found.'}</p>
<p className="results">{numberOfResults > 0 ? numberOfResults + ' Bookmarks found' : null}</p>
<button className='btn' onClick={() => setFilterBox(true)}>&#xf0b0;</button>
<button className='btn' onClick={() => setSortBox(true)}>&#xf0dc;</button>
<List data={filteredData} reFetch={fetchData} />
{numberOfResults === 0 ? <NoResults /> : null}
{sortBox ? <Sort
sortBy={sortByFunc}
onExit={exitSorting}
@@ -101,10 +111,13 @@ function App() {
/> : null}
{newBox ? <AddItem
SetLoader={SetLoader}
onExit={exitAdding}
reFetch={fetchData}
tags={() => concatTags(data)}
/> : null}
{loader ? <Loader /> : null}
</div>
);
}
+7 -2
View File
@@ -3,11 +3,16 @@ import '../styles/AddItem.css';
import TagSelection from './TagSelection';
import addItem from '../modules/addItem';
const AddItem = ({onExit, reFetch, tags}) => {
const AddItem = ({onExit, reFetch, tags, SetLoader}) => {
const [name, setName] = useState('');
const [link, setLink] = useState('');
const [tag, setTag] = useState([]);
function newItem() {
SetLoader(true)
addItem(name, link, tag, reFetch, onExit, SetLoader);
}
function SetName(e) {
setName(e.target.value);
}
@@ -39,7 +44,7 @@ const AddItem = ({onExit, reFetch, tags}) => {
<input onChange={SetLink} className="AddItem-input" type="search" placeholder="e.g. https://example.com/"/>
<h3>Tags:</h3>
<TagSelection setTags={SetTags} tags={tags} />
<button onClick={() => addItem(name, link, tag, reFetch, onExit)} className="upload-btn">Upload &#xf093;</button>
<button onClick={newItem} className="upload-btn">Upload &#xf093;</button>
</div>
</fieldset>
</>
+6 -5
View File
@@ -6,22 +6,23 @@ import deleteEntity from '../modules/deleteEntity';
const List = ({data, reFetch}) => {
return (
<div className="list">
{/* eslint-disable-next-line */}
{data.map((e, i) => {
try {
const url = new URL(e.link);
const favicon = 'http://www.google.com/s2/favicons?domain=' + url.hostname;
return <LazyLoad key={i} height={200} offset={200}>
return (<LazyLoad key={i} height={200} offset={200}>
<div className="list-row">
<div className="img-content-grp">
<img src={favicon} />
<img alt='' src={favicon} />
<div className="list-entity-content">
<div className='row-name'>
<span className="num">{i + 1}.</span> {e.name} <a target="_blank" href={e.link}>({url.hostname})</a>
<span className="num">{i + 1}.</span> {e.name} <a target="_blank" rel="noreferrer" href={e.link}>({url.hostname})</a>
</div>
<div>{e.title}</div>
<div className="tags">
{e.tag.map((e, i) => {
return <div key={i}>{e}</div>
return (<div key={i}>{e}</div>)
})}
</div>
</div>
@@ -31,7 +32,7 @@ const List = ({data, reFetch}) => {
<div className="delete" onClick={() => deleteEntity(e._id, reFetch)}>&#xf2ed;</div>
</div>
</div>
</LazyLoad>
</LazyLoad>)
} catch (e) {
console.log(e);
}
+13
View File
@@ -0,0 +1,13 @@
import '../styles/Loader.css';
import { InfinitySpin } from 'react-loader-spinner'
const Loader = () => {
return (
<div className='loader'>
<InfinitySpin color="white" />
</div>
)
}
export default Loader
+12
View File
@@ -0,0 +1,12 @@
import React from 'react'
const NoResults = () => {
return (
<div className='no-results'>
<h1>¯\_()_/¯</h1>
<p>Nothing found.</p>
</div>
)
}
export default NoResults;
+6 -2
View File
@@ -1,4 +1,3 @@
import { useState } from "react";
import CreatableSelect from "react-select/creatable";
const customStyles = {
@@ -7,6 +6,11 @@ const customStyles = {
color: '#a9a9a9',
}),
multiValueRemove: (provided) => ({
...provided,
color: 'gray',
}),
indicatorSeparator: (provided) => ({
...provided,
display: 'none',
@@ -17,7 +21,7 @@ const customStyles = {
border: 'solid',
borderWidth: '1px',
borderRadius: '0px',
borderColor: 'rgb(80, 80, 80)',
borderColor: 'rgb(141, 141, 141)',
opacity: '90%',
color: 'gray',
background: '#273949',
+2 -2
View File
@@ -7,9 +7,9 @@ const ViewArchived = ({ id }) => {
return (
<div className='view-archived'>
<a href={screenshotPath} target='_blank'>Screenshot</a>
<a href={screenshotPath} target='_blank' rel="noreferrer">Screenshot</a>
<hr className='seperator' />
<a href={pdfPath} target='_blank'>PDF</a>
<a href={pdfPath} target='_blank' rel="noreferrer">PDF</a>
</div>
)
}
+3 -3
View File
@@ -1,7 +1,7 @@
import config from '../config';
import { nanoid } from 'nanoid';
const addItem = async (name, link, tag, reFetch, onExit) => {
const addItem = async (name, link, tag, reFetch, onExit, SetLoader) => {
function isValidHttpUrl(string) {
let url;
@@ -30,9 +30,9 @@ const addItem = async (name, link, tag, reFetch, onExit) => {
}
})
.then(res => res.text())
.then(message => {console.log(message)})
.then(message => {SetLoader(false)})
.then(() => reFetch());
onExit();
} else if(name !== '' && link !== '' && tag !== '') {
alert('Please make sure the link is valid.\n\n(i.e. starts with "http"/"https")');
+3 -4
View File
@@ -17,11 +17,10 @@
box-shadow: rgba(0, 0, 0, 0.16) 0px 3px 6px, rgba(0, 0, 0, 0.23) 0px 3px 6px;
position: absolute;
z-index: 2;
top: 63px;
right: 20px;
top: 15%;
left: 20%;
right: 20%;
background-color: #1f2c38;
width: 50%;
max-width: 500px;
overflow-x: hidden;
overflow-y: auto;
}
+9
View File
@@ -59,3 +59,12 @@ textarea:focus, input:focus{
margin: 20px 20px 0px 30px;
display: inline-block;
}
.no-results {
text-align: center;
padding-top: 5%;
padding-bottom: 5%;
background-color:#273949;
box-shadow: rgba(0, 0, 0, 0.4) 0px 2px 4px, rgba(0, 0, 0, 0.3) 0px 7px 13px -3px, rgba(0, 0, 0, 0.2) 0px -3px 0px inset;
margin: 20px;
}
+3 -3
View File
@@ -20,10 +20,10 @@
box-shadow: rgba(0, 0, 0, 0.16) 0px 3px 6px, rgba(0, 0, 0, 0.23) 0px 3px 6px;
background-color: #273949;
padding: 5px;
top: 120px;
left: 195px;
top: 15%;
left: 30%;
right: 30%;
position: absolute;
margin-top: 4px;
-moz-user-select: none;
-webkit-user-select: none;
user-select: none;
+7
View File
@@ -0,0 +1,7 @@
.loader {
position: absolute;
bottom: 100px;
left: 30%;
right: 30%;
text-align: center;
}
+3 -3
View File
@@ -20,10 +20,10 @@
box-shadow: rgba(0, 0, 0, 0.16) 0px 3px 6px, rgba(0, 0, 0, 0.23) 0px 3px 6px;
background-color: #273949;
padding: 5px;
top: 120px;
left: 250px;
top: 15%;
left: 25%;
right: 25%;
position: absolute;
margin-top: 4px;
-moz-user-select: none;
-webkit-user-select: none;
user-select: none;
+1 -1
View File
@@ -9,5 +9,5 @@ body {
}
*::selection {
background-color: rgba(101, 142, 255, 0.335);
background-color: rgba(255, 255, 0, 0.25);
}