Upload 7.3

This commit is contained in:
Andrew Trieu
2023-06-29 09:40:08 +03:00
parent f86409f665
commit f8e13d8099
11 changed files with 29664 additions and 0 deletions

23
part7/routed-anecdotes/.gitignore vendored Normal file
View File

@@ -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*

29310
part7/routed-anecdotes/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,39 @@
{
"name": "routed-anecdotes",
"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",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.14.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

View File

@@ -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

View File

@@ -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"
}

View File

@@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

View File

@@ -0,0 +1,211 @@
import { useState } from "react";
import { Route, Routes, Link, useMatch, useNavigate } from "react-router-dom";
const Menu = () => {
const padding = {
paddingRight: 5,
};
return (
<div>
<Link to="/anecdotes" style={padding}>
anecdotes
</Link>
<Link to="/create" style={padding}>
create new
</Link>
<Link to="/about" style={padding}>
about
</Link>
</div>
);
};
const Notification = ({ notification }) => {
const style = {
border: "solid",
padding: 10,
borderWidth: 1,
color: "green",
};
return <div style={style}>{notification}</div>;
};
const Anecdote = ({ anecdote }) => (
<div>
<h2>
{anecdote.content} by {anecdote.author}
</h2>
<p>has {anecdote.votes} votes</p>
<p>for more info see{anecdote.info}</p>
</div>
);
const AnecdoteList = ({ anecdotes }) => (
<div>
<h2>Anecdotes</h2>
<ul>
{anecdotes.map((anecdote) => (
<Link to={`/anecdotes/${anecdote.id}`}>
<li key={anecdote.id}>{anecdote.content}</li>
</Link>
))}
</ul>
</div>
);
const About = () => (
<div>
<h2>About anecdote app</h2>
<p>According to Wikipedia:</p>
<em>
An anecdote is a brief, revealing account of an individual person or an
incident. Occasionally humorous, anecdotes differ from jokes because their
primary purpose is not simply to provoke laughter but to reveal a truth
more general than the brief tale itself, such as to characterize a person
by delineating a specific quirk or trait, to communicate an abstract idea
about a person, place, or thing through the concrete details of a short
narrative. An anecdote is "a story with a point."
</em>
<p>
Software engineering is full of excellent anecdotes, at this app you can
find the best and add more.
</p>
</div>
);
const Footer = () => (
<div>
Anecdote app for <a href="https://fullstackopen.com/">Full Stack Open</a>.
See{" "}
<a href="https://github.com/fullstack-hy2020/routed-anecdotes/blob/master/src/App.js">
https://github.com/fullstack-hy2020/routed-anecdotes/blob/master/src/App.js
</a>{" "}
for the source code.
</div>
);
const CreateNew = (props) => {
const navigate = useNavigate();
const [content, setContent] = useState("");
const [author, setAuthor] = useState("");
const [info, setInfo] = useState("");
const handleSubmit = (e) => {
e.preventDefault();
props.addNew({
content,
author,
info,
votes: 0,
});
navigate("/");
};
return (
<div>
<h2>create a new anecdote</h2>
<form onSubmit={handleSubmit}>
<div>
content
<input
name="content"
value={content}
onChange={(e) => setContent(e.target.value)}
/>
</div>
<div>
author
<input
name="author"
value={author}
onChange={(e) => setAuthor(e.target.value)}
/>
</div>
<div>
url for more info
<input
name="info"
value={info}
onChange={(e) => setInfo(e.target.value)}
/>
</div>
<button>create</button>
</form>
</div>
);
};
const App = () => {
const [anecdotes, setAnecdotes] = useState([
{
content: "If it hurts, do it more often",
author: "Jez Humble",
info: "https://martinfowler.com/bliki/FrequencyReducesDifficulty.html",
votes: 0,
id: 1,
},
{
content: "Premature optimization is the root of all evil",
author: "Donald Knuth",
info: "http://wiki.c2.com/?PrematureOptimization",
votes: 0,
id: 2,
},
]);
const [notification, setNotification] = useState("");
const addNew = (anecdote) => {
anecdote.id = Math.round(Math.random() * 10000);
setAnecdotes(anecdotes.concat(anecdote));
setNotification(
`A new anecdote ${anecdote.content} has been created by ${anecdote.author}!`
);
setTimeout(() => {
setNotification("");
}, 5000);
};
const anecdoteById = (id) => anecdotes.find((a) => a.id === id);
const vote = (id) => {
const anecdote = anecdoteById(id);
const voted = {
...anecdote,
votes: anecdote.votes + 1,
};
setAnecdotes(anecdotes.map((a) => (a.id === id ? voted : a)));
};
const match = useMatch("/anecdotes/:id");
const anecdote = match
? anecdotes.find((a) => a.id === Number(match.params.id))
: null;
return (
<div>
<Menu />
{notification !== "" && <Notification notification={notification} />}
<Routes>
<Route
path="/anecdotes/:id"
element={<Anecdote anecdote={anecdote} />}
/>
<Route path="/" element={<AnecdoteList anecdotes={anecdotes} />} />
<Route
path="/anecdotes"
element={<AnecdoteList anecdotes={anecdotes} />}
/>
<Route path="/create" element={<CreateNew addNew={addNew} />} />
<Route path="/about" element={<About />} />
</Routes>
<Footer />
</div>
);
};
export default App;

View File

@@ -0,0 +1,10 @@
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { BrowserRouter as Router } from "react-router-dom";
ReactDOM.createRoot(document.getElementById("root")).render(
<Router>
<App />
</Router>
);