Skip to content

Commit fb70162

Browse files
committed
first commit
1 parent 1dc0cc3 commit fb70162

File tree

5 files changed

+91
-33
lines changed

5 files changed

+91
-33
lines changed

package-lock.json

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"@types/node": "^12.12.32",
1111
"@types/react": "^16.9.27",
1212
"@types/react-dom": "^16.9.5",
13+
"bootswatch": "^4.4.1",
1314
"react": "^16.13.1",
1415
"react-dom": "^16.13.1",
1516
"react-scripts": "3.4.1",

src/App.tsx

Lines changed: 83 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,88 @@
1-
import React from 'react';
2-
import logo from './logo.svg';
3-
import './App.css';
1+
import React, { useState, useRef } from "react";
2+
import "./App.css";
3+
4+
type FormElemEvent = React.FormEvent<HTMLFormElement>;
5+
6+
interface ITask {
7+
name: string;
8+
done: boolean;
9+
}
10+
11+
function App(): JSX.Element {
12+
const [newTask, setNewTask] = useState<string>("");
13+
const [tasks, setTasks] = useState<ITask[]>([]);
14+
const taskInput = useRef<HTMLInputElement>(null);
15+
16+
const handleSubmit = (e: FormElemEvent): void => {
17+
e.preventDefault();
18+
addTask(newTask);
19+
setNewTask("");
20+
taskInput.current?.focus();
21+
};
22+
23+
const addTask = (name: string): void => {
24+
const newTasks: ITask[] = [...tasks, { name, done: false }];
25+
setTasks(newTasks);
26+
};
27+
28+
const toggleDoneTask = (i: number): void => {
29+
const newTasks: ITask[] = [...tasks];
30+
newTasks[i].done = !newTasks[i].done;
31+
setTasks(newTasks);
32+
};
33+
34+
const removeTask = (i: number): void => {
35+
const newTasks: ITask[] = [...tasks];
36+
newTasks.splice(i, 1);
37+
setTasks(newTasks);
38+
};
439

5-
function App() {
640
return (
7-
<div className="App">
8-
<header className="App-header">
9-
<img src={logo} className="App-logo" alt="logo" />
10-
<p>
11-
Edit <code>src/App.tsx</code> and save to reload.
12-
</p>
13-
<a
14-
className="App-link"
15-
href="https://reactjs.org"
16-
target="_blank"
17-
rel="noopener noreferrer"
18-
>
19-
Learn React
20-
</a>
21-
</header>
41+
<div className="container p-4">
42+
<div className="row">
43+
<div className="col-md-6 offset-md-3">
44+
<div className="card">
45+
<div className="card-header">
46+
<h1 className="text-center">Tasks ReactTs</h1>
47+
</div>
48+
<div className="card-body">
49+
<form onSubmit={handleSubmit}>
50+
<input
51+
type="text"
52+
value={newTask}
53+
onChange={e => setNewTask(e.target.value)}
54+
ref={taskInput}
55+
className="form-control"
56+
required
57+
autoFocus
58+
/>
59+
<button className="btn btn-success btn-block mt-2">Save</button>
60+
</form>
61+
{tasks.map((t: ITask, i: number) => (
62+
<div key={i} className="card card-body mt-2">
63+
<h2 style={{ textDecoration: t.done ? "line-through" : "" }}>
64+
{t.name}
65+
</h2>
66+
<div>
67+
<button
68+
onClick={() => toggleDoneTask(i)}
69+
className="btn btn-secondary"
70+
>
71+
{t.done ? "✓" : "✗"}
72+
</button>
73+
<button
74+
onClick={() => removeTask(i)}
75+
className="btn btn-danger"
76+
>
77+
🗑
78+
</button>
79+
</div>
80+
</div>
81+
))}
82+
</div>
83+
</div>
84+
</div>
85+
</div>
2286
</div>
2387
);
2488
}

src/index.css

Lines changed: 0 additions & 13 deletions
This file was deleted.

src/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import React from 'react';
22
import ReactDOM from 'react-dom';
3-
import './index.css';
43
import App from './App';
54
import * as serviceWorker from './serviceWorker';
65

6+
import "bootswatch/dist/lumen/bootstrap.min.css";
7+
78
ReactDOM.render(
89
<React.StrictMode>
910
<App />

0 commit comments

Comments
 (0)