diff --git a/Part_7/bloglist-frontend/src/App.js b/Part_7/bloglist-frontend/src/App.js
index 232df7c..3a81949 100644
--- a/Part_7/bloglist-frontend/src/App.js
+++ b/Part_7/bloglist-frontend/src/App.js
@@ -1,5 +1,5 @@
import { useEffect, useContext } from 'react'
-import { Routes, Route } from 'react-router-dom'
+import { Routes, Route, Navigate } from 'react-router-dom'
import BlogForm from './components/BlogForm'
import NotifBox from './components/NotifBox'
import { useQuery } from 'react-query'
@@ -12,6 +12,7 @@ import Loading from './components/Loading'
import Error from './components/Error'
import Users from './components/Users'
import User from './components/User'
+import BlogView from './components/BlogView'
const App = () => {
const [LoggedUser, userDispatch] = useContext(UserContext)
@@ -58,6 +59,19 @@ const App = () => {
path="/"
element={}
/>
+
+ }
+ />
+ }
+ />
}
diff --git a/Part_7/bloglist-frontend/src/components/Blog.js b/Part_7/bloglist-frontend/src/components/Blog.js
index 0c23951..711c220 100644
--- a/Part_7/bloglist-frontend/src/components/Blog.js
+++ b/Part_7/bloglist-frontend/src/components/Blog.js
@@ -1,79 +1,12 @@
-import { useState } from 'react'
-import propTypes from 'prop-types'
-
-const Blog = ({ blog, user, updateBlog, deleteBlog }) => {
- const [blogObj, setBlogObj] = useState(blog)
- const [visible, setVisible] = useState(false)
-
- Blog.propTypes = {
- blog: propTypes.object.isRequired,
- user: propTypes.object.isRequired,
- }
-
- const showWhenVisible = { display: visible ? '' : 'none' }
- const buttonLabel = visible ? 'Hide' : 'Show'
-
- const likeBlog = event => {
- event.preventDefault()
-
- const updatedBlog = {
- ...blogObj,
- likes: blogObj.likes + 1,
- }
-
- updateBlog(updatedBlog)
- setBlogObj(updatedBlog)
- }
-
- const removeBlog = event => {
- event.preventDefault()
- deleteBlog(blogObj)
- }
+import { Link } from 'react-router-dom'
+const Blog = ({ blog }) => {
return (
- {blogObj.title} - {blogObj.author}
-
-
-
-
-
- Url: {blogObj.url}
-
-
-
- Likes: {blogObj.likes}
-
- {' '}
-
-
- User: {blogObj.user.name}
-
- {user.username.toString() ===
- blogObj.user.username.toString() ? (
-
-
-
- ) : null}
+
+
{blog.title} - {blog.author}
+
)
diff --git a/Part_7/bloglist-frontend/src/components/BlogList.js b/Part_7/bloglist-frontend/src/components/BlogList.js
index 6363678..49c816e 100644
--- a/Part_7/bloglist-frontend/src/components/BlogList.js
+++ b/Part_7/bloglist-frontend/src/components/BlogList.js
@@ -1,57 +1,6 @@
-import { useQueryClient, useMutation } from 'react-query'
-import { useUserValue } from '../utils/UserContext'
-import { putBlog, removeBlog } from '../utils/requests'
import Blog from './Blog'
-import { useNotification } from '../utils/NotifContext'
const BlogList = ({ blogs }) => {
- const user = useUserValue()
- const setNotif = useNotification()
- const queryClient = useQueryClient()
-
- const updateBlogMutation = useMutation(putBlog, {
- onSuccess: votedBlog => {
- const prevBlogs = queryClient.getQueryData('blogs')
- const updatedBlog = prevBlogs.find(b => b.id === votedBlog.id)
- updatedBlog.votes = votedBlog.likes
- queryClient.invalidateQueries('blogs', prevBlogs)
- },
- })
-
- const deleteBlogMutation = useMutation(removeBlog, {
- onSuccess: deletedBlog => {
- const prevBlogs = queryClient.getQueryData('blogs')
- const filteredBlogs = prevBlogs.filter(b => b.id !== deletedBlog.id)
- queryClient.invalidateQueries('blogs', filteredBlogs)
- },
- })
- const updateBlog = async blogObj => {
- try {
- updateBlogMutation.mutateAsync(blogObj)
- setNotif(`Liked '${blogObj.title}' by ${blogObj.author}`, 5000)
- } catch (err) {
- setNotif(`Error occured while updating '${blogObj.title}'`, 5000)
- console.error(err)
- }
- }
-
- const deleteBlog = async blogObj => {
- try {
- const confirmation = window.confirm(`Delete ${blogObj.title}?`)
-
- if (confirmation) {
- deleteBlogMutation.mutateAsync(blogObj)
- setNotif(
- `Deleted '${blogObj.title}' by ${blogObj.author}`,
- 5000
- )
- }
- setNotif('Deletion Cancelled', 5000)
- } catch (err) {
- setNotif(`Error occured while Deleting '${blogObj.title}'`, 5000)
- console.log(err)
- }
- }
return (
{blogs
@@ -60,9 +9,6 @@ const BlogList = ({ blogs }) => {
))}
diff --git a/Part_7/bloglist-frontend/src/components/BlogView.js b/Part_7/bloglist-frontend/src/components/BlogView.js
new file mode 100644
index 0000000..291fd97
--- /dev/null
+++ b/Part_7/bloglist-frontend/src/components/BlogView.js
@@ -0,0 +1,104 @@
+import { useNavigate, useParams } from 'react-router-dom'
+import { useUserValue } from '../utils/UserContext'
+import { useNotification } from '../utils/NotifContext'
+import { putBlog, removeBlog } from '../utils/requests'
+import { useQuery, useQueryClient, useMutation } from 'react-query'
+import Loading from './Loading'
+import Error from './Error'
+
+const BlogView = () => {
+ const { id } = useParams()
+ const navigate = useNavigate()
+ const result = useQuery('blogs')
+ const blogs = result.data
+
+ const blog = blogs !== undefined ? blogs.find(b => b.id === id) : null
+ const user = useUserValue()
+ const setNotif = useNotification()
+ const queryClient = useQueryClient()
+
+ const updateBlogMutation = useMutation(putBlog, {
+ onSuccess: votedBlog => {
+ const prevBlogs = queryClient.getQueryData('blogs')
+ const updatedBlog = prevBlogs.find(b => b.id === votedBlog.id)
+ updatedBlog.votes = votedBlog.likes
+ queryClient.invalidateQueries('blogs', prevBlogs)
+ },
+ })
+
+ const deleteBlogMutation = useMutation(removeBlog, {
+ onSuccess: deletedBlog => {
+ const prevBlogs = queryClient.getQueryData('blogs')
+ const filteredBlogs = prevBlogs.filter(b => b.id !== deletedBlog.id)
+ queryClient.invalidateQueries('blogs', filteredBlogs)
+ },
+ })
+
+ const updateBlog = async blogObj => {
+ try {
+ updateBlogMutation.mutateAsync(blogObj)
+ setNotif(`Liked '${blogObj.title}' by ${blogObj.author}`, 5000)
+ } catch (err) {
+ setNotif(`Error occured while updating '${blogObj.title}'`, 5000)
+ console.error(err)
+ }
+ }
+
+ const deleteBlog = async blogObj => {
+ try {
+ const confirmation = window.confirm(`Delete ${blogObj.title}?`)
+
+ if (confirmation) {
+ deleteBlogMutation.mutateAsync(blogObj)
+ setNotif(
+ `Deleted '${blogObj.title}' by ${blogObj.author}`,
+ 5000
+ )
+ }
+ setNotif('Deletion Cancelled', 5000)
+ } catch (err) {
+ setNotif(`Error occured while Deleting '${blogObj.title}'`, 5000)
+ console.log(err)
+ }
+ }
+
+ const likeBlog = () => {
+ const updatedBlog = {
+ ...blog,
+ likes: blog.likes + 1,
+ }
+
+ updateBlog(updatedBlog)
+ }
+
+ const delBlog = () => {
+ deleteBlog(blog)
+ navigate('/')
+ }
+
+ if (result.isLoading) return
+
+ if (result.isError) return
+
+ return (
+
+
{blog.title}
+
+ Author: {blog.author}
+
+
+ Link: {blog.url}
+
+
+ Has {blog.likes} Likes
+
+
+
Added by {blog.user.name}
+ {user.username === blog.user.username ? (
+
+ ) : null}
+
+ )
+}
+
+export default BlogView
diff --git a/Part_7/bloglist-frontend/src/components/Menu.js b/Part_7/bloglist-frontend/src/components/Menu.js
index ef9491d..35542f6 100644
--- a/Part_7/bloglist-frontend/src/components/Menu.js
+++ b/Part_7/bloglist-frontend/src/components/Menu.js
@@ -1,9 +1,9 @@
import { Link } from 'react-router-dom'
-import { useUserDispatch, useUserValue } from '../utils/UserContext'
+import UserContext from '../utils/UserContext'
+import { useContext } from 'react'
const Menu = () => {
- const user = useUserValue()
- const dispatch = useUserDispatch()
+ const [user, dispatch] = useContext(UserContext)
const style = {
paddingRight: 5,