Skip to content

Commit

Permalink
getting all posts in frontend
Browse files Browse the repository at this point in the history
  • Loading branch information
JaberHPranto committed Sep 16, 2021
1 parent 526ecc3 commit 89f5c02
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 56 deletions.
35 changes: 24 additions & 11 deletions client/src/components/Blog/Blog.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
import React from 'react'
import React, { useEffect } from 'react'
import { Button, Col, Row } from 'react-bootstrap'
import { useDispatch, useSelector } from 'react-redux'
import { useHistory } from 'react-router-dom'
import { fetchBlogs } from '../../redux/actions/blogActions'
import '../../styles/blog.css'
import Loader from '../Ecommerce/Loader'
import BlogCard from './BlogCard'
import { blogCategories, blogTags } from './BlogSeedData'

function Blog() {
const num = [1, 2, 3, 4, 5]

const history = useHistory()
const dispatch = useDispatch()

const blogList = useSelector(state => state.blogList)
const { loading, blogs} = blogList

useEffect(() => {
dispatch(fetchBlogs())
}, [dispatch])

function handleCreateBlog(){
history.push("/newblog")
Expand Down Expand Up @@ -44,15 +55,17 @@ function Blog() {
</div>
</div>
</Col>
<Col md={10} xs={12}>
<Row>
{num.map(n => (
<Col key={n} xs={12} md={6} lg={4} xl={4} className='blog-card'>
<BlogCard />
</Col>
))}
</Row>
</Col>
{loading ? <Loader /> : (
<Col md={10} xs={12}>
<Row>
{blogs && blogs.map((blog,index) => (
<Col key={index} xs={12} md={6} lg={4} xl={4} className='blog-card'>
<BlogCard blog={blog}/>
</Col>
))}
</Row>
</Col>
)}
</Row>
</div>
</>
Expand Down
21 changes: 13 additions & 8 deletions client/src/components/Blog/BlogCard.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,31 @@
import React from 'react'
import { Badge, Button, Card } from 'react-bootstrap'
import { Link, useHistory } from 'react-router-dom'
import "../../styles/blog.css"

function BlogCard() {
const tags = ['plant','indoor','gardening']
function BlogCard({ blog }) {
const history = useHistory()
const handleViewBlog = (id) => {
history.push(`/blog/${id}`)
}
return (
<div>
<Card style={{ width: '24rem', minWidth: '18rem' }}>
<Link to={`/blog/${blog._id}`}>
<Card.Img style={{ padding: '0.7rem' }} variant="top" src="https://images.unsplash.com/photo-1520121401995-928cd50d4e27?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=750&q=80" />

</Link>
<Card.Body>
<Card.Title className="blog-card-title">How to plant</Card.Title>
{tags.map((tag,index) => (
<Card.Title className="blog-card-title">{blog.title}</Card.Title>
{blog.tags.map((tag,index) => (
<Badge key={index} className="blog-card-badge">{tag}</Badge>
))}
<Card.Text className="blog-card-desc">
Some quick example text to build on the card title and make up the bulk of
the card's content
Lorem ipsum, dolor sit amet consectetur adipisicing elit. A provident sint ipsam voluptate inventore deleniti, hic eligendi perspiciatis cum, rerum, facere sequi perferendis. Et temporibus, laboriosam velit quae quas non?
{blog.description}
</Card.Text>

<div style={{ display: 'flex', justifyContent:'space-between'}}>
<Button className="bg-col-primary">Read More &nbsp; <i className="fa fa-chevron-right"></i> </Button>
<Button className="bg-col-primary" onClick={()=>handleViewBlog(blog._id)} >Read More &nbsp; <i className="fa fa-chevron-right"></i> </Button>
<div className='blog-card-icons'>
<i className="far fa-thumbs-up blog-card-like" aria-hidden="true"></i>
<i className="far fa-bookmark blog-card-bookmark" aria-hidden="true"></i>
Expand Down
69 changes: 41 additions & 28 deletions client/src/components/Blog/BlogDetails.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,50 @@
import React from 'react'
import React, { useEffect } from 'react'
import { Badge, Container } from 'react-bootstrap'
import { useDispatch, useSelector } from 'react-redux'
import { fetchBlogById } from '../../redux/actions/blogActions'
import '../../styles/blog.css'
import Loader from '../Ecommerce/Loader'
import Message from '../Ecommerce/Message'

function BlogDetails() {
const tags = ['plant','indoor','gardening']
function BlogDetails({match}) {
const dispatch = useDispatch()
const blogDetails = useSelector(state => state.blogDetails)
const { loading, blog, error } = blogDetails
useEffect(() => {
dispatch(fetchBlogById(match.params.id))
}, [dispatch,match])

return (
<Container className='blog-det-container'>
<img className="blog-det-image"
src="https://images.unsplash.com/photo-1441974231531-c6227db76b6e?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80"
alt="blog hero"
/>
<h1 className='blog-det-title'>A Plant’s Journey Home </h1>
<div className='blog-det-info'>
<p>By <span className='info-span'>Jaber Hossain Pranto</span></p>
<p>Published in <span className='info-span'>Plant</span></p>
<p>19 September,2021</p>
</div>
<div className='blog-det-desc'>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Iure vel officiis ipsum placeat itaque neque dolorem modi perspiciatis dolor distinctio veritatis sapiente, minima corrupti dolores necessitatibus suscipit accusantium dignissimos culpa cumque.
It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters.
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Iure vel officiis ipsum placeat itaque neque dolorem modi perspiciatis dolor distinctio veritatis sapiente, minima corrupti dolores necessitatibus suscipit accusantium dignissimos culpa cumque.
It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters.
{loading ? <Loader /> : error ? <Message variant="alert">{error}</Message> : blog && (
<>
<img className="blog-det-image"
src="https://images.unsplash.com/photo-1441974231531-c6227db76b6e?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80"
alt="blog hero"
/>

<h1 className='blog-det-title'>{blog.title}</h1>
<div className='blog-det-info'>
<p>By <span className='info-span'>Jaber Hossain Pranto</span></p>
<p>Published in <span className='info-span'>{blog.category}</span></p>
<p>{blog.createdAt && blog.createdAt.substr(0,10)}</p>
</div>
<div className='blog-det-desc'>
{blog.description}
</div>
<div className="blog-det-tags">
{blog.tags && blog.tags.map((tag, index) => (
<Badge key={index} className="blog-card-badge blog-det-badge">{tag}</Badge>
))}
</div>
<div className='blog-card-icons blog-det-icons'>
<i className="far fa-thumbs-up blog-det-like" aria-hidden="true"><span>&nbsp;5</span></i>
<i className="far fa-comments blog-det-comments" aria-hidden="true"><span>&nbsp;4</span></i>
</div>
</>

</div>
<div className="blog-det-tags">
{tags.map((tag, index) => (
<Badge key={index} className="blog-card-badge blog-det-badge">{tag}</Badge>
))}
</div>
<div className='blog-card-icons blog-det-icons'>
<i className="far fa-thumbs-up blog-det-like" aria-hidden="true"><span>&nbsp;5</span></i>
<i className="far fa-comments blog-det-comments" aria-hidden="true"><span>&nbsp;4</span></i>
</div>
)}


</Container>
)
Expand Down
5 changes: 5 additions & 0 deletions client/src/constants/blogConstant.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,9 @@ export const BLOG_FETCH_REQUEST = "BLOG_FETCH_REQUEST"
export const BLOG_FETCH_SUCCESS = "BLOG_FETCH_SUCCESS"
export const BLOG_FETCH_FAIL = "BLOG_FETCH_FAIL"

export const BLOG_DETAILS_REQUEST = "BLOG_DETAILS_REQUEST"
export const BLOG_DETAILS_SUCCESS = "BLOG_DETAILS_SUCCESS"
export const BLOG_DETAILS_FAIL = "BLOG_DETAILS_FAIL"


export const BLOG_CREATE = "BLOG_CREATE"
25 changes: 23 additions & 2 deletions client/src/redux/actions/blogActions.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import axios from "axios"
import { BLOG_FETCH_FAIL, BLOG_FETCH_REQUEST, BLOG_FETCH_SUCCESS } from "../../constants/blogConstant"
import { BLOG_DETAILS_REQUEST, BLOG_DETAILS_SUCCESS, BLOG_FETCH_FAIL, BLOG_FETCH_REQUEST, BLOG_FETCH_SUCCESS } from "../../constants/blogConstant"
import { PRODUCT_DETAILS_FAIL } from "../../constants/productConstants"

// @ GET blogs
export const fetchBlogs = () => async (dispatch) => {
try {
Expand All @@ -19,6 +21,25 @@ export const fetchBlogs = () => async (dispatch) => {
payload: error.response && error.response.data.message ? error.response.data.message : error.message
})
}
}

// Get a blog by id
export const fetchBlogById = (id) => async (dispatch) => {
try {
dispatch({ type: BLOG_DETAILS_REQUEST })

const { data } = await axios.get(`/api/blogs/${id}`)
dispatch({
type: BLOG_DETAILS_SUCCESS,
payload: data
})

} catch (error) {
console.log(error);
dispatch({
type: PRODUCT_DETAILS_FAIL,
payload: error.response && error.response.data.message ? error.response.data.message : error.message
})
}


}
18 changes: 17 additions & 1 deletion client/src/redux/reducers/blogReducers.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { BLOG_FETCH_FAIL, BLOG_FETCH_REQUEST, BLOG_FETCH_SUCCESS } from "../../constants/blogConstant"
import { BLOG_DETAILS_FAIL, BLOG_DETAILS_REQUEST, BLOG_DETAILS_SUCCESS, BLOG_FETCH_FAIL, BLOG_FETCH_REQUEST, BLOG_FETCH_SUCCESS } from "../../constants/blogConstant"

export const blogListReducer = ( blogs=[], action) => {
switch (action.type) {
Expand All @@ -14,4 +14,20 @@ export const blogListReducer = ( blogs=[], action) => {
default:
return blogs
}
}

export const blogDetailsReducer = (state = { blog: {comments:[]} }, action) => {
switch (action.type) {
case BLOG_DETAILS_REQUEST:
return { loading: true, ...state }

case BLOG_DETAILS_SUCCESS:
return { loading: false, blog: action.payload }

case BLOG_DETAILS_FAIL:
return { loading: false, error: action.payload }

default:
return state
}
}
7 changes: 3 additions & 4 deletions client/src/store.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { applyMiddleware, combineReducers, createStore } from "redux";
import { composeWithDevTools } from "redux-devtools-extension";
import thunk from "redux-thunk";
import {
blogListReducer
} from "./redux/reducers/blogReducers";
import { blogDetailsReducer, blogListReducer } from "./redux/reducers/blogReducers";
import { cartReducer } from "./redux/reducers/cartReducers";
import {
orderCreateReducer, orderListReducer
Expand Down Expand Up @@ -35,7 +33,8 @@ const reducer = combineReducers({
cart: cartReducer,
orderCreate: orderCreateReducer,
orderList: orderListReducer,
blogList:blogListReducer
blogList: blogListReducer,
blogDetails: blogDetailsReducer
});

const cartItemsFromStorage = localStorage.getItem("cartItems")
Expand Down
11 changes: 11 additions & 0 deletions server/controller/blogController.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,14 @@ export const postBlogs = async (req, res) => {
})
}
}

// get a blog by id
export const getBlogById = async (req, res) => {
try {
const blog = await BlogPost.findById(req.params.id)
res.status(200).json(blog)

} catch (err) {
res.status(404).json({ message: "No blog found" })
}
}
5 changes: 3 additions & 2 deletions server/routes/blogRoute.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import express from 'express'
import { getBlogs, postBlogs } from '../controller/blogController.js'
import { getBlogById, getBlogs, postBlogs } from '../controller/blogController.js'
import { isLoggedIn } from '../middlewares/authMiddleware.js'
const router = express.Router()

router.get("/", getBlogs)
router.post("/",isLoggedIn,postBlogs)
router.post("/", isLoggedIn, postBlogs)
router.get("/:id",getBlogById)


export default router

0 comments on commit 89f5c02

Please sign in to comment.