Created
November 20, 2019 09:40
-
-
Save erwanriou/49cc72692058b1492c556d57bb4e2611 to your computer and use it in GitHub Desktop.
Redux flow for a blog
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import axios from "axios" | |
import { | |
GET_ERRORS, | |
ARTICLE_RESET_STATE, | |
ARTICLE_FETCH, | |
ARTICLES_FETCH, | |
ARTICLES_LIKE, | |
ARTICLE_LIKE | |
} from "../types" | |
import { loading, clearLoading } from "./loadingActions" | |
export const fetchAllPublicArticles = ( | |
category, | |
countryCode, | |
query | |
) => async dispatch => { | |
dispatch(loading()) | |
try { | |
// DEFINE QUERY | |
const config = { | |
params: { | |
countryCode, | |
title: query | |
} | |
} | |
// CALL API | |
const res = await axios.get(`/api/global/article/${category}`, config) | |
dispatch({ | |
type: ARTICLES_FETCH, | |
payload: res.data | |
}) | |
} catch (e) { | |
dispatch({ | |
type: GET_ERRORS, | |
payload: e.response.data | |
}) | |
} | |
dispatch(clearLoading()) | |
} | |
// FETCH ONE ARTICLE | |
export const fetchAllPublicArticle = ( | |
category, | |
url, | |
countryCode, | |
history | |
) => async dispatch => { | |
dispatch(loading()) | |
try { | |
// DEFINE QUERY | |
const config = { | |
params: { | |
countryCode | |
} | |
} | |
// CALL API | |
const res = await axios.get( | |
`/api/global/article/${category}/${url}`, | |
config | |
) | |
dispatch({ | |
type: ARTICLE_FETCH, | |
payload: res.data | |
}) | |
} catch (e) { | |
dispatch({ | |
type: GET_ERRORS, | |
payload: e.response.data | |
}) | |
history.push("/not-found") | |
} | |
dispatch(clearLoading()) | |
} | |
// LIKE OR UNLIKE ARTICLES | |
export const likeArticle = (id, url) => async dispatch => { | |
dispatch(loading()) | |
try { | |
const res = await axios.post(`/api/global/article/favorite/${id}`) | |
window.location.pathname.includes(url) | |
? dispatch({ | |
type: ARTICLE_LIKE, | |
payload: res.data | |
}) | |
: dispatch({ | |
type: ARTICLES_LIKE, | |
payload: res.data, | |
id | |
}) | |
} catch (e) { | |
dispatch({ | |
type: GET_ERRORS, | |
payload: e.response.data | |
}) | |
} | |
dispatch(clearLoading()) | |
} | |
export const cleanArticleState = () => async dispatch => { | |
dispatch({ | |
type: ARTICLE_RESET_STATE | |
}) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const express = require("express") | |
const mongoose = require("mongoose") | |
const passport = require("passport") | |
const apicache = require("apicache") | |
const { getCode } = require("country-list") | |
// IMPORT MIDDLEWARE AND MODELS | |
const Article = require("../../../models/Article") | |
const cache = apicache.middleware | |
// IMPORT VALIDATION | |
const isEmpty = require("../../../validation/is-empty") | |
const router = express.Router() | |
// @route GET api/global/article/post | |
// @desc Get all approved publications | |
// @access Public | |
router.get("/post", cache("1 hour"), async (req, res) => { | |
try { | |
let articleQuery | |
isEmpty(req.query.title) | |
? (articleQuery = "") | |
: (articleQuery = req.query.title | |
.toLowerCase() | |
.split("%20") | |
.join(" ")) | |
const articles = await Article.find({ | |
isActivated: true, | |
category: "POST", | |
country: { $in: [req.query.countryCode] }, | |
title: { | |
$regex: new RegExp(articleQuery, "i") | |
} | |
}) | |
res.status(200).json(articles) | |
} catch (err) { | |
res.status(400).json(err) | |
} | |
}) | |
// @route GET api/global/article/post | |
// @desc Get all approved publications | |
// @access Public | |
router.get("/post/:url", cache("1 hour"), async (req, res) => { | |
try { | |
const errors = {} | |
const url = req.params.url.toLowerCase() | |
const article = await Article.findOne({ | |
url: req.params.url, | |
isActivated: true, | |
country: { $in: [req.query.countryCode] }, | |
category: "POST" | |
}) | |
if (!article) { | |
errors.noprofile = "There is no Article existing" | |
return res.status(404).json(errors) | |
} | |
res.status(200).json(article) | |
} catch (err) { | |
res.status(400).json(err) | |
} | |
}) | |
// @route GET api/global/article/post | |
// @desc Get all approved partners | |
// @access Public | |
router.get("/partner", async (req, res) => { | |
try { | |
let articleQuery | |
isEmpty(req.query.title) | |
? (articleQuery = "") | |
: (articleQuery = req.query.title | |
.toLowerCase() | |
.split("%20") | |
.join(" ")) | |
const articles = await Article.find({ | |
isActivated: true, | |
category: "PARTNER", | |
country: { $in: [req.query.countryCode] }, | |
title: { | |
$regex: new RegExp(articleQuery, "i") | |
} | |
}) | |
res.status(200).json(articles) | |
} catch (err) { | |
res.status(400).json(err) | |
} | |
}) | |
// @route POST api/global/article/favorite/:id | |
// @desc Like or Unlike article | |
// @access Private | |
router.post( | |
"/favorite/:id", | |
passport.authenticate("jwt", { session: false }), | |
async (req, res) => { | |
try { | |
const article = await Article.findById(req.params.id) | |
const indexOfUser = article.favorite.findIndex( | |
favorite => favorite.user.toString() === req.user.id | |
) | |
indexOfUser === -1 | |
? article.favorite.unshift({ user: req.user.id }) | |
: article.favorite.splice(indexOfUser, 1) | |
await article.save() | |
return res.status(200).json(article.favorite) | |
} catch (err) { | |
res.status(400).json(err) | |
} | |
} | |
) | |
module.exports = router |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { | |
LOADING_DATA, | |
CLEAR_LOADING_DATA, | |
ARTICLE_RESET_STATE, | |
ARTICLE_FETCH, | |
ARTICLES_FETCH, | |
ARTICLE_NEW, | |
ARTICLES_LIKE, | |
ARTICLE_LIKE, | |
ARTICLE_IMAGE_UPLOAD, | |
ARTICLE_ACTIVATE, | |
ARTICLE_UPDATE_STATUS | |
} from "../actions/types" | |
const initialState = { | |
articles: [], | |
article: {}, | |
drafts: [], | |
total: "", | |
loading: false | |
} | |
export default function articleReducer(state = initialState, action) { | |
switch (action.type) { | |
case LOADING_DATA: | |
return { | |
...state, | |
loading: true | |
} | |
case ARTICLES_FETCH: | |
return { | |
...state, | |
articles: action.payload, | |
loading: false | |
} | |
case ARTICLE_FETCH: | |
return { | |
...state, | |
article: action.payload, | |
loading: false | |
} | |
case ARTICLE_NEW: | |
return { | |
...state, | |
articles: [...state.articles, action.payload], | |
loading: false | |
} | |
case ARTICLE_ACTIVATE: | |
return { | |
...state, | |
articles: [ | |
...state.articles.map(article => { | |
if (article._id === action.id) { | |
return { | |
...article, | |
isActivated: action.payload | |
} | |
} else { | |
return article | |
} | |
}) | |
], | |
loading: false | |
} | |
case ARTICLE_UPDATE_STATUS: | |
return { | |
...state, | |
articles: [ | |
...state.articles.map(article => { | |
if (article._id === action.id) { | |
return { | |
...article, | |
category: action.payload | |
} | |
} else { | |
return article | |
} | |
}) | |
], | |
loading: false | |
} | |
case ARTICLE_IMAGE_UPLOAD: | |
const image = { url: action.payload.key } | |
return { | |
...state, | |
drafts: [...state.drafts, image], | |
loading: false | |
} | |
case ARTICLES_LIKE: | |
return { | |
...state, | |
articles: [ | |
...state.articles.map(article => { | |
if (article._id === action.id) { | |
return { | |
...article, | |
favorite: action.payload | |
} | |
} else { | |
return article | |
} | |
}) | |
], | |
loading: false | |
} | |
case ARTICLE_LIKE: | |
return { | |
...state, | |
article: { | |
...state.article, | |
favorite: action.payload | |
} | |
} | |
case CLEAR_LOADING_DATA: | |
return { | |
...state, | |
loading: false | |
} | |
case ARTICLE_RESET_STATE: | |
return { | |
...state, | |
articles: [] | |
} | |
default: | |
return state | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment