Skip to content

Commit dad1c11

Browse files
Add wysiwyg on blog
1 parent 9de6f8e commit dad1c11

File tree

9 files changed

+1162
-7
lines changed

9 files changed

+1162
-7
lines changed

client/src/Routes.js

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import Navbar from "./components/navbar/Navbar";
66
import Home from "./pages/home/Home.js";
77
import Tuto from "./pages/blog/Tuto";
88
import Blog from "./pages/blog/Blog";
9+
import ImgMediaCard from "./components/blog/Card";
10+
import PreviewBlog from "./components/blog/PreviewBlog";
911

1012

1113
function RoutesProvider() {
@@ -30,6 +32,8 @@ function RoutesProvider() {
3032
<Route path="/" element={<Home />} />
3133
<Route path="/tuto" element={<Tuto />} />
3234
<Route path="/blog" element={<Blog />} />
35+
<Route path="/blog/:id" element={<PreviewBlog />} />
36+
3337
</Route>
3438
</Routes>
3539
</BrowserRouter>

client/src/components/blog/Card.js

+54-3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import ThumbDownOffAltIcon from "@mui/icons-material/ThumbDownOffAlt";
1313
import { useEffect, useState } from "react";
1414
import axios from "axios";
1515
import Comment from "./Comment";
16+
import { useNavigate } from "react-router-dom";
17+
1618

1719
export default function ImgMediaCard({
1820
image,
@@ -22,7 +24,13 @@ export default function ImgMediaCard({
2224
dislike,
2325
id,
2426
type,
27+
28+
2529
}) {
30+
31+
32+
const navigate = useNavigate(); function handleClick() { navigate(`/blog/${id}`); }
33+
2634
// console.log(id);
2735

2836
// const [tuto, setTuto] = useState([]);
@@ -55,8 +63,8 @@ export default function ImgMediaCard({
5563
// alt="green iguana"
5664
height="10"
5765
image={image}
58-
// image="https://cdn.code.daypilot.org/image/big/7sca734yufgatkpbudmqro7tga/vue-resource-calendar-open-source.png"
59-
// sx={{maxHeight: 250}}
66+
// image="https://cdn.code.daypilot.org/image/big/7sca734yufgatkpbudmqro7tga/vue-resource-calendar-open-source.png"
67+
// sx={{maxHeight: 250}}
6068
/>
6169
<CardContent>
6270
<Typography gutterBottom variant="h5" component="div">
@@ -85,8 +93,51 @@ export default function ImgMediaCard({
8593
</Card>
8694
</Grid>
8795
) : (
88-
<h1>Blog</h1>
96+
<Grid item xs={2} sm={4} md={5}>
97+
<Card sx={{ maxWidth: 380, m: 2 }}>
98+
<CardMedia
99+
component="img"
100+
// alt="green iguana"
101+
height="10"
102+
image={image}
103+
// image="https://cdn.code.daypilot.org/image/big/7sca734yufgatkpbudmqro7tga/vue-resource-calendar-open-source.png"
104+
// sx={{maxHeight: 250}}
105+
/>
106+
<CardContent>
107+
<Typography gutterBottom variant="h5" component="div">
108+
{title}
109+
{/*yo*/}
110+
</Typography>
111+
<Typography variant="body2" color="text.secondary">
112+
{description}
113+
{/*sisi*/}
114+
</Typography>
115+
</CardContent>
116+
<CardActions>
117+
{like}
118+
<Checkbox
119+
icon={<ThumbUpOffAltIcon />}
120+
checkedIcon={<ThumbUpIcon />}
121+
/>
122+
{dislike}
123+
<Checkbox
124+
icon={<ThumbDownOffAltIcon />}
125+
checkedIcon={<ThumbDownAltIcon color={"error"} />}
126+
/>
127+
128+
<Button size="small">Commencer</Button>
129+
<Button size="small"
130+
131+
onClick={handleClick}
132+
133+
>Ouvrir</Button>
134+
135+
</CardActions>
136+
</Card>
137+
</Grid>
89138
)}
90139
</>
91140
);
92141
}
142+
143+

client/src/components/blog/NewBlog.js

+63-3
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,34 @@ import * as React from "react";
1717
import { useEffect, useState } from "react";
1818
import toast, { Toaster } from "react-hot-toast";
1919

20+
import { Editor } from "react-draft-wysiwyg";
21+
import { EditorState, convertToRaw } from "draft-js";
22+
import "react-draft-wysiwyg/dist/react-draft-wysiwyg.css";
23+
import draftToHtml from "draftjs-to-html";
24+
25+
2026
export default function SideBarModify({ open, toggleDrawerModify, deviceId }) {
2127
const [title, setTitle] = useState("");
2228
const [description, setDescription] = useState("");
2329
const [photo, setPhoto] = useState("");
2430
const [image, setImage] = useState("");
31+
const [editorState, setEditorState] = useState(EditorState.createEmpty());
32+
const [inputEditorState, setInputEditorState] = useState("");
33+
34+
35+
const handleEditorChange = (e) => {
36+
setEditorState(e);
37+
setInputEditorState(draftToHtml(convertToRaw(e.getCurrentContent())));
38+
39+
}
40+
41+
console.log(inputEditorState);
2542

2643
const newBlog = async (e) => {
2744
e.preventDefault();
2845

29-
if (!title || !description || !photo) {
46+
if (!title || !description || !photo || !editorState || !inputEditorState) {
47+
console.log(title, description, photo, editorState);
3048
toast.error("Veuillez remplir tous les champs");
3149
return;
3250
}
@@ -35,6 +53,10 @@ export default function SideBarModify({ open, toggleDrawerModify, deviceId }) {
3553
title,
3654
description,
3755
photo,
56+
editorState,
57+
inputEditorState
58+
59+
3860
};
3961
try {
4062
const response = await axios.post(
@@ -52,9 +74,10 @@ export default function SideBarModify({ open, toggleDrawerModify, deviceId }) {
5274

5375
const list = () => (
5476
<>
77+
5578
<Box
5679
sx={{
57-
width: 350,
80+
width: 1450,
5881
p: 2,
5982
justifyContent: "center",
6083
alignItems: "center",
@@ -63,14 +86,40 @@ export default function SideBarModify({ open, toggleDrawerModify, deviceId }) {
6386
}}
6487
role="presentation"
6588
>
89+
90+
6691
<Typography
6792
variant="h6"
6893
sx={{
6994
marginBottom: 4,
7095
}}
7196
>
7297
Ajout d'un nouveau blog
98+
99+
<div>
100+
<Editor
101+
102+
placeholder='Write your blog here...'
103+
104+
editorState={editorState}
105+
106+
toolbarClassName="toolbarClassName"
107+
wrapperClassName="wrapperClassName"
108+
editorClassName="editorClassName"
109+
onEditorStateChange={handleEditorChange}
110+
editorStyle={{ border: "1px solid black", minHeight: "180px", padding: "10px", borderRadius: "5px", boxShadow: "0 0 10px 0 rgba(0,0,0,0.2)" }}
111+
112+
/>
113+
114+
<textarea disabled value={
115+
draftToHtml(convertToRaw(editorState.getCurrentContent()))
116+
117+
}>
118+
119+
</textarea>
120+
</div>
73121
</Typography>
122+
74123
<IconButton
75124
sx={{
76125
position: "absolute",
@@ -83,7 +132,10 @@ export default function SideBarModify({ open, toggleDrawerModify, deviceId }) {
83132
>
84133
<CloseIcon />
85134
</IconButton>
135+
86136
<>
137+
138+
87139
<TextField
88140
sx={{ marginBottom: 2 }}
89141
id="outlined-search"
@@ -96,7 +148,9 @@ export default function SideBarModify({ open, toggleDrawerModify, deviceId }) {
96148
InputLabelProps={{ className: "inputLabel" }}
97149
InputProps={{ className: "input" }}
98150
/>
151+
99152
<TextField
153+
100154
sx={{ marginBottom: 2 }}
101155
id="outlined-search"
102156
type={"text"}
@@ -107,7 +161,9 @@ export default function SideBarModify({ open, toggleDrawerModify, deviceId }) {
107161
fullWidth
108162
InputLabelProps={{ className: "inputLabel" }}
109163
InputProps={{ className: "input" }}
110-
/>
164+
>
165+
166+
</TextField >
111167

112168
<TextField
113169
sx={{ marginBottom: 2 }}
@@ -140,6 +196,8 @@ export default function SideBarModify({ open, toggleDrawerModify, deviceId }) {
140196
image={photo ? photo : ""}
141197
alt=""
142198
/>
199+
200+
143201
</>
144202
)}
145203

@@ -174,3 +232,5 @@ export default function SideBarModify({ open, toggleDrawerModify, deviceId }) {
174232
</div>
175233
);
176234
}
235+
236+
+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import axios from 'axios';
2+
import React, { useEffect, useState } from 'react';
3+
import { useParams } from 'react-router-dom';
4+
5+
import { EditorState, ContentState } from 'draft-js';
6+
import htmlToDraft from 'html-to-draftjs';
7+
8+
9+
10+
11+
function PreviewBlog() {
12+
const [data, setData] = useState(null);
13+
const { id } = useParams();
14+
15+
16+
useEffect(() => {
17+
(async () => {
18+
19+
console.log(id);
20+
21+
await axios.get(`http://localhost:5050/blog_event/${id}`).then((res) => {
22+
setData(res.data);
23+
console.log(res.data);
24+
}).catch((err) => {
25+
console.log(err);
26+
});
27+
})();
28+
}, []);
29+
30+
31+
32+
return (
33+
<div>
34+
{data && (
35+
36+
//<h1>{data.inputEditorState}</h1>
37+
<div dangerouslySetInnerHTML={{ __html: data.inputEditorState }} />
38+
39+
)}
40+
</div>
41+
);
42+
43+
}
44+
45+
export default PreviewBlog;

client/src/components/blog/Quill.js

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import React, { useState } from 'react';
2+
import { useQuill } from 'react-quill';
3+
import 'quill/dist/quill.snow.css';
4+
5+
function Quill() {
6+
const { quill, quillRef } = useQuill();
7+
const [value, setValue] = useState();
8+
9+
10+
React.useEffect(() => {
11+
if (quill) {
12+
quill.on('text-change', () => {
13+
setValue(quillRef.current.firstChild.innerHTML);
14+
});
15+
}
16+
}, [quill]);
17+
18+
console.log(value, "this is the value");
19+
20+
21+
22+
return (
23+
<div>
24+
<div style={{ width: 500, height: 500 }}>
25+
<div ref={quillRef} />
26+
</div>
27+
</div>
28+
);
29+
}
30+
31+
32+
export default Quill;

0 commit comments

Comments
 (0)