Skip to content

Commit 3b21270

Browse files
committedNov 26, 2020
changed layout and updated gif
1 parent c010a34 commit 3b21270

File tree

10 files changed

+381
-184
lines changed

10 files changed

+381
-184
lines changed
 

‎package-lock.json

+184
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json

+7-5
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,21 @@
77
"@syncstate/history": "^0.6.0",
88
"@syncstate/react": "^0.6.0",
99
"@syncstate/remote-client": "^0.6.0",
10+
"@syncstate/remote-server": "^0.6.0",
1011
"@testing-library/jest-dom": "^5.11.4",
1112
"@testing-library/react": "^11.1.0",
1213
"@testing-library/user-event": "^12.1.10",
14+
"bootstrap": "^4.5.3",
15+
"express": "^4.17.1",
16+
"nodemon": "^2.0.6",
1317
"react": "^17.0.1",
18+
"react-bootstrap": "^1.4.0",
1419
"react-dom": "^17.0.1",
1520
"react-scripts": "4.0.0",
21+
"socket.io": "^2.3.0",
1622
"socket.io-client": "^2.3.1",
1723
"uuidv4": "^6.2.4",
18-
"web-vitals": "^0.2.4",
19-
"@syncstate/remote-server": "^0.6.0",
20-
"express": "^4.17.1",
21-
"nodemon": "^2.0.6",
22-
"socket.io": "^2.3.0"
24+
"web-vitals": "^0.2.4"
2325
},
2426
"scripts": {
2527
"start": "react-scripts start",

‎public/images/Todo.gif

7.33 MB
Loading

‎public/index.html

+7-4
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,14 @@
2626
-->
2727
<link
2828
rel="stylesheet"
29-
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
29+
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
30+
/>
31+
<link
32+
rel="stylesheet"
33+
href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css"
34+
integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2"
35+
crossorigin="anonymous"
3036
/>
31-
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
32-
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
33-
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
3437
<title>React App</title>
3538
</head>
3639
<body>

‎src/App.css

+30-25
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,43 @@
1+
body {
2+
background-color: #6200ea;
3+
}
14
.App {
25
text-align: center;
36
}
47

5-
.App-logo {
6-
height: 40vmin;
7-
pointer-events: none;
8+
.checkbox {
9+
margin-left: -25px;
810
}
9-
10-
@media (prefers-reduced-motion: no-preference) {
11-
.App-logo {
12-
animation: App-logo-spin infinite 20s linear;
13-
}
11+
.caption {
12+
width: 300px;
1413
}
15-
16-
.App-header {
17-
background-color: #282c34;
18-
min-height: 100vh;
19-
display: flex;
20-
flex-direction: column;
21-
align-items: center;
22-
justify-content: center;
23-
font-size: calc(10px + 2vmin);
24-
color: white;
14+
.addText {
15+
width: 350px;
2516
}
2617

27-
.App-link {
28-
color: #61dafb;
18+
@media (max-width: 375px) {
19+
.checkbox {
20+
margin-left: -35px;
21+
}
22+
.caption {
23+
width: 280px;
24+
}
25+
26+
.addText {
27+
width: 330px;
28+
}
2929
}
3030

31-
@keyframes App-logo-spin {
32-
from {
33-
transform: rotate(0deg);
31+
@media (max-width: 320px) {
32+
.caption {
33+
width: 180px;
3434
}
35-
to {
36-
transform: rotate(360deg);
35+
36+
.addText {
37+
width: 230px;
3738
}
3839
}
40+
41+
todoTitle {
42+
width: "89%";
43+
}

‎src/App.js

+34-26
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import React, { useState } from "react";
1+
import React from "react";
22
import "./App.css";
3-
import Todo from "./Todo";
3+
import Todo from "./components/Todo";
4+
import AddTodo from "./components/AddTodo";
45
import { useDoc } from "@syncstate/react";
6+
57
function App() {
68
const todoPath = "/todos";
79
const [todos, setTodos] = useDoc(todoPath);
8-
const [input, setInput] = useState("");
910

1011
const keyGenerator = () => "_" + Math.random().toString(36).substr(2, 9);
1112
const addTodo = (todoItem) => {
@@ -20,31 +21,38 @@ function App() {
2021
});
2122
};
2223

23-
const todoList = todos.map((todo, index) => {
24-
return <Todo key={index} todoPath={todoPath + "/" + index} />;
24+
const todoList = todos.map((todoItem, index) => {
25+
return (
26+
<li key={todoItem.index} className="list-group-item">
27+
<Todo todo={todoItem} todoPath={todoPath + "/" + index} />
28+
</li>
29+
);
2530
});
31+
2632
return (
27-
<div className="main-app">
28-
<div className="todo-app">
29-
<h1>Multi User Todo</h1>
30-
<br></br>
31-
<form
32-
onSubmit={(e) => {
33-
e.preventDefault();
34-
addTodo(input);
35-
setInput("");
36-
}}
37-
>
38-
<input
39-
type="text"
40-
placeholder="What's on your mind?"
41-
className="input-todo"
42-
onChange={(e) => {
43-
setInput(e.target.value);
44-
}}
45-
></input>
46-
</form>
47-
{todoList}
33+
<div className="container mt-5">
34+
<h2 className="text-center text-white">
35+
Multi User Todo Using SyncState
36+
</h2>
37+
<div className="row justify-content-center mt-5">
38+
<div className="col-md-8">
39+
<div className="card-hover-shadow-2x mb-3 card">
40+
<div className="card-header-tab card-header">
41+
<div className="card-header-title font-size-lg text-capitalize font-weight-normal">
42+
<i className="fa fa-tasks"></i>&nbsp;Task Lists
43+
</div>
44+
</div>
45+
<div
46+
className="overflow-auto"
47+
style={{ height: "auto", maxHeight: "300px" }}
48+
>
49+
<div className="position-static">
50+
<ul className=" list-group list-group-flush">{todoList}</ul>
51+
</div>
52+
</div>
53+
<AddTodo addTodo={addTodo} />
54+
</div>
55+
</div>
4856
</div>
4957
</div>
5058
);

‎src/Todo.js

-53
This file was deleted.

‎src/components/AddTodo.js

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import React, { useState } from "react";
2+
3+
function AddTodo({ addTodo }) {
4+
const [input, setInput] = useState("");
5+
6+
return (
7+
<div
8+
className="d-block text-right card-footer d-flex"
9+
style={{ padding: "0.75rem" }}
10+
>
11+
<div className=" position-relative col " style={{ paddingLeft: "13px" }}>
12+
<input
13+
type="text"
14+
className="form-control input-todo" //addText
15+
value={input}
16+
onChange={(e) => {
17+
setInput(e.target.value);
18+
}}
19+
onKeyPress={(event) => {
20+
if (event.which === 13 || event.keyCode === 13) {
21+
addTodo(input);
22+
setInput("");
23+
}
24+
}}
25+
placeholder="Enter new todo"
26+
/>
27+
28+
<i
29+
className="fa fa-close"
30+
style={{
31+
position: "absolute",
32+
top: "25%",
33+
right: "25px",
34+
}}
35+
onClick={() => setInput("")}
36+
></i>
37+
</div>
38+
<div className="ml-auto">
39+
<button
40+
className="btn btn-primary"
41+
onClick={(e) => {
42+
e.preventDefault();
43+
addTodo(input);
44+
setInput("");
45+
}}
46+
>
47+
Add Task
48+
</button>
49+
</div>
50+
</div>
51+
);
52+
}
53+
54+
export default AddTodo;

‎src/components/Todo.js

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import React from "react";
2+
import { useDoc } from "@syncstate/react";
3+
4+
function Todo({ todoPath }) {
5+
const [todos, setTodos] = useDoc("/todos", Infinity);
6+
const [todoItem, setTodoItem] = useDoc(todoPath);
7+
8+
const deleteTodo = (id) => {
9+
let newTodos = todos.filter((todo) => {
10+
return todo.id !== id;
11+
});
12+
setTodos(newTodos);
13+
};
14+
const toggleTodo = (completed) => {
15+
setTodoItem((todoItem) => {
16+
todoItem.completed = completed;
17+
});
18+
};
19+
20+
const getTxtStyle = () => {
21+
return {
22+
textDecoration: todoItem.completed ? "line-through" : "none",
23+
marginLeft: "10px",
24+
};
25+
};
26+
27+
return (
28+
<div>
29+
<div className="d-flex align-content-center">
30+
<div
31+
className="custom-checkbox custom-control d-flex align-items-center"
32+
style={{ marginBottom: "2px" }}
33+
>
34+
<input
35+
type="checkbox"
36+
className="form-check-input"
37+
checked={todoItem.completed}
38+
onChange={(e) => {
39+
toggleTodo(e.target.checked);
40+
}}
41+
/>
42+
</div>
43+
44+
<div
45+
className="d-flex align-items-center todoTitle"
46+
style={getTxtStyle()}
47+
>
48+
<div style={{ width: "100%" }}>{todoItem.caption} </div>
49+
</div>
50+
<div className="ml-auto d-flex align-items-center">
51+
<button
52+
className="border-0 btn-transition btn btn-outline-danger"
53+
onClick={() => {
54+
deleteTodo(todoItem.id);
55+
}}
56+
>
57+
<i className="fa fa-trash"></i>
58+
</button>
59+
</div>
60+
</div>
61+
</div>
62+
);
63+
}
64+
65+
export default Todo;

‎src/index.css

-71
Original file line numberDiff line numberDiff line change
@@ -1,71 +0,0 @@
1-
body {
2-
margin: 0;
3-
padding: 0;
4-
color: #4d4d4d;
5-
box-sizing: border-box;
6-
font-size: 1.5rem;
7-
8-
background-color: white;
9-
}
10-
.main-app {
11-
display: flex;
12-
justify-content: center;
13-
align-items: center;
14-
}
15-
.todo-app {
16-
width: 50%;
17-
text-align: center;
18-
margin-top: 50px;
19-
}
20-
input[type="text"] {
21-
width: 100%;
22-
height: 3rem;
23-
text-align: center;
24-
color: #4d4d4d;
25-
border: none;
26-
font-weight: 100;
27-
28-
font-size: 1.5rem;
29-
border-radius: 15px;
30-
border: 1px solid grey;
31-
}
32-
input[type="text"]:focus {
33-
outline: none;
34-
}
35-
36-
.todo-list-item {
37-
display: flex;
38-
width: 100%;
39-
justify-content: space-between;
40-
margin-top: 1rem;
41-
font-weight: 100;
42-
padding: 0.5rem;
43-
background-color: #f5f5f5;
44-
border-bottom: 1px solid #cc9a9a;
45-
}
46-
47-
input[type="checkbox"] {
48-
width: 1.5em;
49-
height: 1.5em;
50-
background-color: white;
51-
border-radius: 50%;
52-
vertical-align: middle;
53-
border: 1px solid #ddd;
54-
-webkit-appearance: none;
55-
outline: none;
56-
cursor: pointer;
57-
}
58-
[type="checkbox"]:checked {
59-
background-color: #cc9a9a;
60-
}
61-
[type="checkbox"]:checked + div {
62-
text-decoration: line-through black;
63-
opacity: 0.5;
64-
}
65-
span {
66-
opacity: 0.7;
67-
cursor: pointer;
68-
}
69-
span:hover {
70-
transform: scale(1.3);
71-
}

0 commit comments

Comments
 (0)
Please sign in to comment.