blog base functions added
This commit is contained in:
parent
b225deace1
commit
30f0c0ae55
|
@ -1,13 +1,66 @@
|
||||||
import React from 'react';
|
import React, {useState, useEffect, useCallback} from 'react';
|
||||||
import Display from './Display';
|
import Display from './Display';
|
||||||
|
import Loader from './Loader';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {jsx} The homepage component
|
* @return {jsx} The homepage component
|
||||||
*/
|
*/
|
||||||
export default function Blog() {
|
export default function Blog() {
|
||||||
|
const [articles, setArticles]: any = useState([]);
|
||||||
|
const [page, setPage] = useState(0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if you've reach the bottom of an HTMLElement
|
||||||
|
* @param {HTMLElement} element the element to check
|
||||||
|
* @return {boolean} true if reached else false
|
||||||
|
*/
|
||||||
|
function isBottom(element: HTMLElement) {
|
||||||
|
return element.getBoundingClientRect().bottom <= window.innerHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
const trackScrolling = useCallback(() => {
|
||||||
|
const element = document.getElementById('root')!;
|
||||||
|
if (isBottom(element)) {
|
||||||
|
setPage(page + 1);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const tmpArticles = articles;
|
||||||
|
tmpArticles.push(<Loader />);
|
||||||
|
setArticles(tmpArticles);
|
||||||
|
axios.get('/api/articles/' + page).then((res) => {
|
||||||
|
tmpArticles.pop();
|
||||||
|
for (let i = 0; i < res.data.length; i++) {
|
||||||
|
tmpArticles.push(<h1>{res.data[i].title}</h1>);
|
||||||
|
for (let j = 0; j < res.data[i].tags.length; j++) {
|
||||||
|
tmpArticles.push(<small>{res.data[i].tags[j].name}</small>);
|
||||||
|
}
|
||||||
|
tmpArticles.push(<small>
|
||||||
|
{new Date(res.data[i].createdAt).toLocaleDateString()}
|
||||||
|
</small>);
|
||||||
|
tmpArticles.push(<div>{res.data[i].sanitizedHtml}</div>);
|
||||||
|
}
|
||||||
|
console.log('test');
|
||||||
|
setArticles([...tmpArticles]);
|
||||||
|
console.log(articles);
|
||||||
|
});
|
||||||
|
}, [page]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
window.addEventListener('scroll', trackScrolling);
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener('scroll', trackScrolling);
|
||||||
|
};
|
||||||
|
}, [trackScrolling]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Display text='Blog' />
|
<Display text='Carnet de voyage' />
|
||||||
|
<div className='container'>
|
||||||
|
{articles}
|
||||||
|
</div>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import express, {RequestHandler} from 'express';
|
import express from 'express';
|
||||||
import sequelize from './../dbobject';
|
|
||||||
|
|
||||||
import Article, {articleI} from './../models/article';
|
import Article from './../models/article';
|
||||||
import Tag from './../models/tag';
|
import Tag from './../models/tag';
|
||||||
|
|
||||||
import {authorize} from './../auth';
|
import {authorize} from './../auth';
|
||||||
|
@ -10,21 +9,34 @@ import {authorize} from './../auth';
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
/* eslint-enable */
|
/* eslint-enable */
|
||||||
|
|
||||||
/* eslint-disable */
|
|
||||||
declare global {
|
|
||||||
namespace Express {
|
|
||||||
interface Request {
|
|
||||||
article: articleI;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* eslint-enable */
|
|
||||||
|
|
||||||
router.delete('/signout', async (_req, res) => {
|
router.delete('/signout', async (_req, res) => {
|
||||||
res.cookie('accessToken', '', {expires: new Date()});
|
res.cookie('accessToken', '', {expires: new Date()});
|
||||||
res.sendStatus(204);
|
res.sendStatus(204);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
router.get('/articles/:page', async (req, res) => {
|
||||||
|
console.log(parseInt(req.params.page));
|
||||||
|
const articles = await Article.findAll({
|
||||||
|
attributes: [
|
||||||
|
'title',
|
||||||
|
'createdAt',
|
||||||
|
'sanitizedHtml',
|
||||||
|
],
|
||||||
|
include: [{
|
||||||
|
model: Tag,
|
||||||
|
attributes: [
|
||||||
|
'name',
|
||||||
|
],
|
||||||
|
}],
|
||||||
|
order: [
|
||||||
|
['createdAt', 'DESC'],
|
||||||
|
],
|
||||||
|
limit: 10,
|
||||||
|
offset: parseInt(req.params.page) * 10,
|
||||||
|
});
|
||||||
|
res.send(articles);
|
||||||
|
});
|
||||||
|
|
||||||
router.get('/articletable', authorize, async (_req, res) => {
|
router.get('/articletable', authorize, async (_req, res) => {
|
||||||
const articles = await Article.findAll({
|
const articles = await Article.findAll({
|
||||||
attributes: [
|
attributes: [
|
||||||
|
@ -36,70 +48,4 @@ router.get('/articletable', authorize, async (_req, res) => {
|
||||||
res.send(articles);
|
res.send(articles);
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get('/new', authorize, (_req, res) => {
|
|
||||||
res.render('admin/new', {article: Article.build(), tags: []});
|
|
||||||
});
|
|
||||||
|
|
||||||
router.get('/edit/:id', authorize, async (req, res) => {
|
|
||||||
const article = await Article.findByPk(req.params.id,
|
|
||||||
{rejectOnEmpty: true});
|
|
||||||
const tags = await Tag.findAll({
|
|
||||||
where: {articleId: article.id},
|
|
||||||
attributes: [
|
|
||||||
'name',
|
|
||||||
],
|
|
||||||
});
|
|
||||||
res.render('admin/edit', {article, tags});
|
|
||||||
});
|
|
||||||
|
|
||||||
router.post('/', authorize, async (req, _res, next) => {
|
|
||||||
req.article = Article.build();
|
|
||||||
next();
|
|
||||||
}, saveArticleAndRedirect('new'));
|
|
||||||
|
|
||||||
router.put('/:id', authorize, async (req, _res, next) => {
|
|
||||||
req.article = await Article.findByPk(req.params.id, {rejectOnEmpty: true});
|
|
||||||
next();
|
|
||||||
}, saveArticleAndRedirect('edit'));
|
|
||||||
|
|
||||||
router.delete('/:id', authorize, async (req, _res) => {
|
|
||||||
await Article.destroy({where: {id: req.params.id}, cascade: true});
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} path Path of redirection
|
|
||||||
* @return {RequestHandler} middleware
|
|
||||||
*/
|
|
||||||
function saveArticleAndRedirect(path: string): RequestHandler {
|
|
||||||
return async (req, res) => {
|
|
||||||
let article: any = req.article;
|
|
||||||
article.title = req.body.title;
|
|
||||||
article.description = req.body.description;
|
|
||||||
article.markdown = req.body.markdown;
|
|
||||||
try {
|
|
||||||
await sequelize.transaction(async (t) => {
|
|
||||||
let tagCount = 0;
|
|
||||||
while (req.body.articletags[tagCount] != '') {
|
|
||||||
tagCount++;
|
|
||||||
}
|
|
||||||
Tag.destroy({where: {articleId: article.id},
|
|
||||||
transaction: t});
|
|
||||||
article = await article.save();
|
|
||||||
for (let i = 0; i < tagCount; i++) {
|
|
||||||
await article.createTag({
|
|
||||||
articleId: article.id,
|
|
||||||
main: (i == 0) ? true : false,
|
|
||||||
name: req.body.articletags[i],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
res.redirect(`/blog/post/${article.slug}`);
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e);
|
|
||||||
req.flash('error', 'The operation has failed, please try again');
|
|
||||||
res.render(`admin/${path}`, {article: article});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
|
Loading…
Reference in New Issue