From 5377d8d38f751a7cbca5efca91cc8f48808a4972 Mon Sep 17 00:00:00 2001 From: Yannick Lescure Date: Mon, 18 Apr 2022 16:52:40 -0400 Subject: [PATCH] add delete article + fix tags update --- client/src/components/Stories/Select.js | 126 ++++++++++++++++--- client/src/components/Trending.js | 2 - client/src/components/buttons/UpdateStory.js | 4 +- server/handlers.js | 76 ++++++----- server/index.js | 2 +- 5 files changed, 158 insertions(+), 52 deletions(-) diff --git a/client/src/components/Stories/Select.js b/client/src/components/Stories/Select.js index 7e28c91..1e423d7 100644 --- a/client/src/components/Stories/Select.js +++ b/client/src/components/Stories/Select.js @@ -1,10 +1,16 @@ -import { useContext } from "react"; +import { useContext, useState } from "react"; +import { useNavigate } from "react-router-dom"; import styled from "styled-components"; import { COLORS, MIN_CHAR } from "../../constants"; import { StoryContext } from "../../contexts/StoryContext"; import { capitalizeStr } from "../../helpers"; +import Loading from "../Loading"; const Select = ({ from = undefined, article = undefined }) => { + const navigate = useNavigate(); + const [showDeleteBtns, setShowDeleteBtns] = useState(false); + const [loading, setLoading] = useState(false); + const { state: { story }, actions: { initialStory, readyToPublish, updateStory, readyToUpdate }, @@ -43,31 +49,123 @@ const Select = ({ from = undefined, article = undefined }) => { }, ]; + const handleClick = () => { + setShowDeleteBtns(!showDeleteBtns); + } + + const handleDelete = () => { + setLoading(true); + fetch(`/api/stories/${article.user.username}/${article.slug}?_id=${article.user._id}&delete=true`, { + method: "PUT", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(article), + }) + .then((res) => res.json()) + .then((json) => { + console.log(json); + if (json.status === 200) { + initialStory(); + // receivedUserFromServer({ user: json.data }); + // Go to new story page + navigate(`/${article.user.username}/articles`); + } + else { + // setErrorMessage(json.message); + // setValid(false); + // setDisabled(true); + // logoutUser(); + } + }) + .catch((err) => { + console.error(err); + // errorFromServerUser({ message: "An unknown error has occurred" }); + }); + } + + if (loading) return + return ( -
Visibility
- - {options.map((option) => ( - {option.label} - ))} - + + Are you sure ? + Yes + No + + Delete article + +
Visibility
+ + {options.map((option) => ( + {option.label} + ))} + +
) } +const Question = styled.div` + display: ${({show}) => show ? 'flex' : 'none'}; + align-items: center; + gap: 12px; +`; +const ReqDiv = styled.div` + font-size: 16px; +`; +const YesDiv = styled.button` + background-color: ${COLORS.success}; + outline: none; + padding: 4px; + width: 48px; + border: none; + border-radius: 4px; + font-size: 16px; + color: ${COLORS.light}; + cursor: pointer; +`; +const NoDiv = styled.button` + background-color: ${COLORS.danger}; + outline: none; + padding: 4px; + width: 48px; + border: none; + border-radius: 4px; + font-size: 16px; + color: ${COLORS.light}; + cursor: pointer; +`; const Wrapper = styled.div` display: flex; - justify-content: flex-end; + justify-content: space-between; + align-items: center; +`; +const Container = styled.div` + display: flex; align-items: center; font-weight: bold; gap: 12px; `; +const Trash = styled.button` + display: ${({show}) => show ? 'none' : 'flex'}; + background: none; + outline: none; + padding: 0; + border: none; + font-size: 16px; + color: ${COLORS.danger}; + cursor: pointer; +`; const StyledSelect = styled.select` padding: 2px 4px; font-size: 16px; diff --git a/client/src/components/Trending.js b/client/src/components/Trending.js index 29b7721..8761c75 100644 --- a/client/src/components/Trending.js +++ b/client/src/components/Trending.js @@ -9,7 +9,6 @@ import { TrendingContext } from "../contexts/TrendingContext"; const Trending = () => { const [loading, setLoading] = useState(true); - const [data, setData] = useState([]); const [tags, setTags] = useState([]); const { @@ -30,7 +29,6 @@ const Trending = () => { .then((response) => { // console.log(response.data); receivedTrendingFromServer({ trending: response.data }); - setData(response.data); setLoading(false); const cleanTags = []; response.data.forEach(item => { diff --git a/client/src/components/buttons/UpdateStory.js b/client/src/components/buttons/UpdateStory.js index c3d57f7..6dda4dc 100644 --- a/client/src/components/buttons/UpdateStory.js +++ b/client/src/components/buttons/UpdateStory.js @@ -26,7 +26,7 @@ const UpdateStory = () => { }, [status]); const handleUpdateStory = () => { - // console.log(story); + console.log(story); setReady(false); sendingStoryToServer(); setLoading(true); @@ -44,7 +44,7 @@ const UpdateStory = () => { initialStory(); // receivedUserFromServer({ user: json.data }); // Go to new story page - navigate(`/${json.data.user.username}/${json.data.slug}`); + navigate(`/${user.username}/${story.slug}`); } else { // setErrorMessage(json.message); diff --git a/server/handlers.js b/server/handlers.js index 2dea28b..1bb3bdb 100644 --- a/server/handlers.js +++ b/server/handlers.js @@ -269,46 +269,55 @@ const createStory = async (req, res) => { }; const updateStory = async (req, res) => { + console.log(req.params); + console.log(req.query); + const client = new MongoClient(MONGO_URI, option); const { _id, title, content, user, imageSrc, visibility, slug } = req.body; + try { await client.connect(); const db = client.db(DB_NAME); const story = await db.collection("stories").findOne({ _id }); - console.log(story); + // console.log(story); if (story) { - // const updatedStory = { - // ...story, - // title, - // content, - // user, - // imageSrc, - // visibility, - // slug, - // updatedAt: new Date().getTime() - // }; - // Rather than sending the full object, I just send the updated data. - const updatedStory = {}; - if (story.slug !== slug) updatedStory.slug = slug; - if (story.title !== title) updatedStory.title = title; - if (story.content !== content) updatedStory.content = content; - if (story.userId !== user._id) updatedStory.userId = user._id; - if (story.imageSrc !== imageSrc) updatedStory.imageSrc = imageSrc; - if (story.visibility !== visibility) updatedStory.visibility = visibility; - if (story.username !== user.username) updatedStory.username = user.username; + let updatedStory = { + ...story, + title, + content, + imageSrc, + visibility, + slug, + updatedAt: new Date().getTime(), + }; + + if (req.query.delete === 'true') { + updatedStory = { + ...updatedStory, + deleted: true + } + + } + updatedStory.tags = []; if (req.body.tags) { - if (req.body.tags.includes(',')) { - updatedStory.tags = req.body.tags.split(',').map(el => el.trim()).filter(el => el !== ''); + console.log(req.body.tags); + if (typeof req.body.tags === 'string') { + if (req.body.tags.includes(',')) { + updatedStory.tags = req.body.tags.split(',').map(el => el.trim()).filter(el => el !== ''); + } + else { + updatedStory.tags = [req.body.tags]; + } } else { - updatedStory.tags = [req.body.tags]; + updatedStory.tags = req.body.tags; } } - updatedStory.updatedAt = new Date().getTime(); - console.log(updatedStory); + + // console.log(updatedStory); const result = await db.collection("stories").updateOne( { _id }, @@ -316,14 +325,15 @@ const updateStory = async (req, res) => { $set: updatedStory, } ); - console.log(result); - result - ? res.status(200).json({ - status: 200, - data: req.body, - message: "Story updated", - }) - : res.status(409).json({ status: 409, message: "ERROR" }); + // console.log(result); + + if (result) { + if (updatedStory.deleted) res.status(200).json({ status: 200, message: "Story deleted" }); + else res.status(200).json({ status: 200, data: req.body, message: "Story updated" }); + } + else { + res.status(409).json({ status: 409, message: "ERROR" }); + } } else { res.status(404).json({ status: 404, message: "Item not found" }); diff --git a/server/index.js b/server/index.js index 1df3d31..54f0ad0 100644 --- a/server/index.js +++ b/server/index.js @@ -74,7 +74,7 @@ app.post("/api/signup", createUser) if (process.env.NODE_ENV === 'production') { // Serve any static files app.use(express.static(path.resolve(__dirname, '../client/build'))); - + // Handle React routing, return all requests to React app app.get('*', function(req, res) { res.sendFile(path.resolve(__dirname, '../client/build', 'index.html'));