From 8c37a7308b58c4e472a958f6b895d14c4c29f54f Mon Sep 17 00:00:00 2001 From: Andrew Trieu Date: Tue, 20 Jun 2023 15:56:00 +0300 Subject: [PATCH] Upload 5.11 --- part5/bloglist-frontend/src/App.js | 26 +++++++++++++-- .../bloglist-frontend/src/components/Blog.js | 33 ++++++++++++++++--- .../src/components/Togglable.js | 2 +- part5/bloglist-frontend/src/services/blogs.js | 12 +++++-- 4 files changed, 63 insertions(+), 10 deletions(-) diff --git a/part5/bloglist-frontend/src/App.js b/part5/bloglist-frontend/src/App.js index de682e6..ddb26c4 100644 --- a/part5/bloglist-frontend/src/App.js +++ b/part5/bloglist-frontend/src/App.js @@ -72,7 +72,7 @@ const App = () => { } }; const newBlogRef = useRef(); - const handleNewBlog = async (newBlog) => { + const handleNewBlog = (newBlog) => { newBlogRef.current.toggleVisibility(); blogService .create(newBlog) @@ -89,6 +89,23 @@ const App = () => { }); }; + const handleRemoveBlog = (blog) => { + if (window.confirm(`Remove blog ${blog.title} by ${blog.author}?`)) { + blogService + .remove(blog.id) + .then(() => { + setBlogs(blogs.filter((b) => b.id !== blog.id)); + setNotification( + `Blog ${blog.title} by ${blog.author} removed`, + "success" + ); + }) + .catch((error) => { + setNotification("Failed to remove blog: " + error, "error"); + }); + } + }; + const loginForm = () => (
@@ -123,7 +140,12 @@ const App = () => {

All blogs

{blogs.map((blog) => ( - + ))}
); diff --git a/part5/bloglist-frontend/src/components/Blog.js b/part5/bloglist-frontend/src/components/Blog.js index a539016..3b5bd8a 100644 --- a/part5/bloglist-frontend/src/components/Blog.js +++ b/part5/bloglist-frontend/src/components/Blog.js @@ -1,6 +1,8 @@ +import { useState } from "react"; +import blogService from "../services/blogs"; import Togglable from "./Togglable"; -const Blog = ({ blog }) => { +const Blog = ({ blog, setNotification, removeBlog }) => { const blogStyle = { paddingTop: 10, paddingLeft: 2, @@ -8,15 +10,36 @@ const Blog = ({ blog }) => { borderWidth: 1, marginBottom: 5, }; + + const [likes, setLikes] = useState(blog.likes); + + const handleLike = (blog) => { + blog.likes = blog.likes + 1; + blogService + .update(blog.id, blog) + .then((returnedBlog) => { + setLikes(returnedBlog.likes); + setNotification(`You liked ${blog.title}`, "success"); + }) + .catch((error) => { + setNotification(`Like failed. Error: ${error}`, "error"); + }); + }; + return (
- {blog.title} - + {blog.title} +
    -
  • {blog.author}
  • -
  • {blog.url}
  • +
  • Author: {blog.author}
  • +
  • URL: {blog.url}
  • +
  • + {likes} likes  + +
+
diff --git a/part5/bloglist-frontend/src/components/Togglable.js b/part5/bloglist-frontend/src/components/Togglable.js index 84c0e0a..5052265 100644 --- a/part5/bloglist-frontend/src/components/Togglable.js +++ b/part5/bloglist-frontend/src/components/Togglable.js @@ -21,7 +21,7 @@ const Togglable = forwardRef((props, refs) => {
{props.children} - +
); diff --git a/part5/bloglist-frontend/src/services/blogs.js b/part5/bloglist-frontend/src/services/blogs.js index 1f70e29..c1c338f 100644 --- a/part5/bloglist-frontend/src/services/blogs.js +++ b/part5/bloglist-frontend/src/services/blogs.js @@ -23,8 +23,15 @@ const create = async (newObject) => { }; const update = async (id, newObject) => { - const request = axios.put(`${baseUrl} /${id}`, newObject); - const response = await request; + const response = await axios.put(`${baseUrl}/${id}`, newObject); + return response.data; +}; + +const remove = async (id) => { + const config = { + headers: { Authorization: token }, + }; + const response = await axios.delete(`${baseUrl}/${id}`, config); return response.data; }; @@ -33,6 +40,7 @@ const blogService = { getAll, create, update, + remove, }; export default blogService;