This repository has been archived on 2025-12-11. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
fullstack-open/part7/routed-anecdotes/src/App.js
Andrew Trieu f8e13d8099 Upload 7.3
2023-06-29 09:40:08 +03:00

212 lines
5.3 KiB
JavaScript

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;