Skip to content

Commit

Permalink
Refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
andersholt committed May 4, 2022
1 parent 19e7fec commit 2b3af50
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 145 deletions.
44 changes: 22 additions & 22 deletions client/src/hooks/global.jsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
import {useEffect, useState} from "react";
import { useEffect, useState } from "react";

export async function fetchJSON(url) {
const res = await fetch(url);
if (!res.ok) {
throw new Error(`Failed ${res.status}`);
}
return await res.json();
export async function fetchJSON(url, options = { method: "GET" }) {
const res = await fetch(url, options);

if (!res.ok) {
throw new Error(`Failed ${res.status}`);
}
return await res.json();
}

export function useLoader(loadingFn) {
const [loading, setLoading] = useState(true);
const [data, setData] = useState();
const [error, setError] = useState();
const [loading, setLoading] = useState(true);
const [data, setData] = useState();
const [error, setError] = useState();

async function load() {
try {
setLoading(true);
setData(await loadingFn());
} catch (error) {
setError(error);
} finally {
setLoading(false);
}
async function load() {
try {
setLoading(true);
setData(await loadingFn());
} catch (error) {
setError(error);
} finally {
setLoading(false);
}
}

useEffect(() => load(), []);
return {loading, data, error};
useEffect(() => load(), []);
return { loading, data, error };
}
4 changes: 4 additions & 0 deletions client/src/lib/getHumanDate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export function getHumanDate(timestamp) {
const humanDate = new Date(parseInt(timestamp)).toLocaleString();
return humanDate;
}
1 change: 0 additions & 1 deletion client/src/pages/frontpage/frontpage.css
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
}

.article-list .article-cards {
max-width: 100vw;
display: flex;
flex-wrap: wrap-reverse;
justify-content: center;
Expand Down
157 changes: 62 additions & 95 deletions client/src/pages/frontpage/frontpage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,22 @@ import { ProfileContext } from "../../hooks/loginProvider";
import { Navbar } from "../../components/navbar/navbar";
import "./frontpage.css";
import { fetchJSON, useLoader } from "../../hooks/global";
const ws = new WebSocket(window.location.origin.replace(/^http/, "ws"));
import LoadingAnimation from "../loadingpage/LoadingPage";
import { getHumanDate } from "../../lib/getHumanDate";

async function deleteArticle(title, ws) {
let deleteTitle = { remove: { title: title } };
ws.send(JSON.stringify(deleteTitle));
await fetchJSON("/api/articles/select/?title=" + title, {
method: "delete",
});
}

function ArticlesList({ setSelectedArticle, selectedArticle }) {
const { userinfo } = useContext(ProfileContext);

const [search, setSearch] = useState("");
const [data, setData] = useState([]);
const ws = new WebSocket(window.location.origin.replace(/^http/, "ws"));

useEffect(() => {
ws.onmessage = (event) => {
Expand All @@ -27,21 +36,13 @@ function ArticlesList({ setSelectedArticle, selectedArticle }) {
setData((oldState) => [...oldState, newData]);
}
};

ws.onclose = () => {
setTimeout(() => connect(), 1000);
};
}, [data]);

useEffect(() => {
if (search === "") {
fetchJSON("/api/articles/all").then((jsonData) => {
setData(jsonData);
});
} else {
fetchJSON(`/api/articles/search/?title=${search}`).then((jsonData) => {
setData(jsonData.articles);
});
}
}, [search]);

Expand All @@ -50,13 +51,11 @@ function ArticlesList({ setSelectedArticle, selectedArticle }) {
setData(jsonData);
});
});

async function handleSearch(event) {
setSearch(event);
}

if (loading) {
return <div>Loading...</div>;
return <LoadingAnimation />;
}
if (error) {
return <div>{error.toString()}</div>;
Expand Down Expand Up @@ -93,9 +92,6 @@ function ArticlesList({ setSelectedArticle, selectedArticle }) {
onClick={() => selectArticle(article.title)}
>
<h2>{article.title}</h2>
<p>Published on {getHumanDate(article.date)}</p>
<p>Written by {article.author}</p>
<p>Topics: {article.topic}</p>
</div>
))}
</div>
Expand All @@ -104,11 +100,6 @@ function ArticlesList({ setSelectedArticle, selectedArticle }) {
);
}

function getHumanDate(timestamp) {
const humanDate = new Date(parseInt(timestamp)).toLocaleString();
return humanDate;
}

function ArticleRead({ data, setSelectedArticle }) {
const article = data;

Expand All @@ -117,33 +108,31 @@ function ArticleRead({ data, setSelectedArticle }) {
}

return (
<>
<>
<h1>{article.title}</h1>
<p>Created: {getHumanDate(article.date)}</p>
<p>Author: {article.author}</p>
<p>Topics: {article.topic}</p>
<article>{article.articleText}</article>
<button id={"leaveArticle"} onClick={leaveArticle}>
Leave article
</button>
</>
</>
<main>
<h1>{article.title}</h1>
<p>Created: {getHumanDate(article.date)}</p>
<p>Author: {article.author}</p>
<p>Topics: {article.topic}</p>
<article>{article.articleText}</article>
<button id={"leaveArticle"} onClick={leaveArticle}>
Leave article
</button>
</main>
);
}

function ArticleReadWrite({ data }) {
const article = data;
console.log(data);
const { userinfo } = useContext(ProfileContext);
const ws = new WebSocket(window.location.origin.replace(/^http/, "ws"));

const [title, setTitle] = useState(article.title);
const [topic, setTopic] = useState(article.topic);
const [articleText, setArticleText] = useState(article.articleText);

async function updateArticle(event) {
event.preventDefault();
await fetch("/api/articles/select/?originalTitle=" + article.title, {
await fetchJSON("/api/articles/select/?originalTitle=" + article.title, {
method: "put",
body: new URLSearchParams({
title,
Expand All @@ -155,26 +144,8 @@ function ArticleReadWrite({ data }) {
});
}

async function deleteArticle() {
const deleteVar = {
title,
topic: topic,
articleText,
author: userinfo.name,
date: Date.now(),
updated: Date.now(),
};

let deleteTitle = { remove: { title: article.title } };
ws.send(JSON.stringify(deleteTitle));

await fetch("/api/articles/select/?title=" + article.title, {
method: "delete",
});
}

return (
<>
<main>
<form onSubmit={updateArticle}>
<h2>Edit mode</h2>
<label>Title</label>
Expand All @@ -200,27 +171,34 @@ function ArticleReadWrite({ data }) {
<br />
<button formAction={"submit"}>Publish article</button>
</form>
<button onClick={deleteArticle}>Delete this article</button>
</>
<button
onClick={() => {
deleteArticle(article.title, ws);
}}
>
Delete this article
</button>
</main>
);
}

function Article({ mode, selectedArticle, setSelectedArticle }) {
export function FrontPage() {
const [editMode, setEditMode] = useState(false);
const [selectedArticle, setSelectedArticle] = useState("");
const { userinfo } = useContext(ProfileContext);
const [data, setData] = useState();
const ws = new WebSocket(window.location.origin.replace(/^http/, "ws"));

useEffect(() => {
ws.onmessage = (event) => {
const newData = JSON.parse(event.data);

if (newData.title === selectedArticle) {
setData(newData);
}
};
ws.onmessage = (event) => {
const newData = JSON.parse(event.data);
if (newData.title === selectedArticle) {
setData(newData);
}
};

ws.onclose = () => {
setTimeout(() => connect(), 1000);
};
}, [data]);
ws.onclose = () => {
setTimeout(() => connect(), 1000);
};

useEffect(() => {
if (selectedArticle !== "") {
Expand All @@ -233,27 +211,6 @@ function Article({ mode, selectedArticle, setSelectedArticle }) {
);
}
}, [selectedArticle]);

return (
<main>
{mode === false && data !== undefined && selectedArticle !== "" && (
<>
<ArticleRead data={data} setSelectedArticle={setSelectedArticle} />
</>
)}
{mode === true && data !== undefined && selectedArticle !== "" && (
<>
<ArticleReadWrite data={data} />
</>
)}
</main>
);
}

export function FrontPage() {
const [editMode, setEditMode] = useState(false);
const [selectedArticle, setSelectedArticle] = useState("");
const { userinfo } = useContext(ProfileContext);
return (
<div>
{!userinfo && (
Expand All @@ -272,11 +229,21 @@ export function FrontPage() {
selectedArticle={selectedArticle}
setSelectedArticle={setSelectedArticle}
/>
<Article
mode={editMode}
selectedArticle={selectedArticle}
setSelectedArticle={setSelectedArticle}
/>
{editMode === false &&
data !== undefined &&
selectedArticle !== "" && (
<>
<ArticleRead
data={data}
setSelectedArticle={setSelectedArticle}
/>
</>
)}
{editMode === true && data !== undefined && selectedArticle !== "" && (
<>
<ArticleReadWrite data={data} />
</>
)}
</div>
</>
)}
Expand Down
27 changes: 0 additions & 27 deletions server/articlesApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,33 +33,6 @@ export function articlesApi(mongoDatabase) {
res.sendStatus(204);
});

router.get("/search/*", async (req, res) => {
const title = req.query.title;

const articles = await mongoDatabase
.collection("articles")
.find({
title: new RegExp(title, "i"),
})
.sort({
date: 1,
})
.map(({ title, date, author, topic, updated }) => ({
title,
date,
author,
topic,
updated,
}))
//.limit(50)
.toArray();
if (!articles) {
res.status(404).json({ errors });
return;
}
res.json({ articles });
});

router.get("/select/*", async (req, res) => {
const title = req.query.title;
console.log(title);
Expand Down

0 comments on commit 2b3af50

Please sign in to comment.