part 12 done

This commit is contained in:
QkoSad
2024-09-30 15:32:50 +03:00
parent 0a7a469d56
commit 33a5afd017
426 changed files with 46304 additions and 5 deletions
@@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
@@ -0,0 +1,15 @@
# React application
This application is created from create-react-app.
Install dependencies with `npm install`
You can run the application in development mode with `npm start`
You can build static files for production release with `npm run build`
You can run tests with `npm run test`
## Environment variables
Use REACT_APP_BACKEND_URL to set where the backend for this application is.
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,39 @@
{
"name": "todo-frontend",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.3.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

@@ -0,0 +1,25 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
@@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:
@@ -0,0 +1,38 @@
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@@ -0,0 +1,12 @@
import './App.css';
import TodoView from './Todos/TodoView'
function App() {
return (
<div className="App">
<TodoView />
</div>
);
}
export default App;
@@ -0,0 +1,23 @@
import React, { useState } from 'react'
const TodoForm = ({ createTodo }) => {
const [text, setText] = useState('')
const onChange = ({ target }) => {
setText(target.value)
}
const handleSubmit = (e) => {
e.preventDefault()
createTodo({ text })
}
return (
<form onSubmit={handleSubmit}>
<input type="text" name="text" value={text} onChange={onChange} />
<button type="submit"> Submit </button>
</form>
)
}
export default TodoForm
@@ -0,0 +1,49 @@
import React from 'react'
const TodoList = ({ todos, deleteTodo, completeTodo }) => {
const onClickDelete = (todo) => () => {
deleteTodo(todo)
}
const onClickComplete = (todo) => () => {
completeTodo(todo)
}
return (
<>
{todos.map(todo => {
const doneInfo = (
<>
<span>This todo is done</span>
<span>
<button onClick={onClickDelete(todo)}> Delete </button>
</span>
</>
)
const notDoneInfo = (
<>
<span>
This todo is not done
</span>
<span>
<button onClick={onClickDelete(todo)}> Delete </button>
<button onClick={onClickComplete(todo)}> Set as done </button>
</span>
</>
)
return (
<div style={{ display: 'flex', justifyContent: 'space-between', maxWidth: '70%', margin: 'auto' }}>
<span>
{todo.text}
</span>
{todo.done ? doneInfo : notDoneInfo}
</div>
)
}).reduce((acc, cur) => [...acc, <hr />, cur], [])}
</>
)
}
export default TodoList
@@ -0,0 +1,46 @@
import React, { useEffect, useState } from 'react'
import axios from '../util/apiClient'
import List from './List'
import Form from './Form'
const TodoView = () => {
const [todos, setTodos] = useState([])
const refreshTodos = async () => {
const { data } = await axios.get('/todos')
setTodos(data)
}
useEffect(() => {
refreshTodos()
}, [])
const createTodo = async (todo) => {
const { data } = await axios.post('/todos', todo)
setTodos([...todos, data])
}
const deleteTodo = async (todo) => {
await axios.delete(`/todos/${todo._id}`)
refreshTodos()
}
const completeTodo = async (todo) => {
await axios.put(`/todos/${todo._id}`, {
text: todo.text,
done: true
})
refreshTodos()
}
return (
<>
<h1>Todos</h1>
<Form createTodo={createTodo} />
<List todos={todos} deleteTodo={deleteTodo} completeTodo={completeTodo} />
</>
)
}
export default TodoView
@@ -0,0 +1,13 @@
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}
@@ -0,0 +1,8 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
ReactDOM.createRoot(document.getElementById('root')).render(
<App />
);
@@ -0,0 +1,5 @@
// jest-dom adds custom jest matchers for asserting on DOM nodes.
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom';
@@ -0,0 +1,7 @@
import axios from 'axios'
const apiClient = axios.create({
baseURL: process.env.REACT_APP_BACKEND_URL,
})
export default apiClient