Files
web2.0-frontend/src/pages/admin/feed/index.tsx
T
2024-02-28 18:12:37 +02:00

115 lines
3.3 KiB
TypeScript

import React, { useState, useEffect } from "react";
import { NextPage } from "next";
import useSWR from "swr";
import { formatRelative, formatISO } from "date-fns";
import { toast } from "react-toastify";
import styled from "styled-components";
import AdminListCommon from "@views/admin/AdminListCommon";
import { Button, Link } from "@components/index";
import AddLink from "@components/AddLink";
import Post from "@models/Feed";
import PostApi from "@api/feedApi";
import { fetcher, APIPath, API } from "@api/backend";
import { SelectWrapper, StyledSelect } from "@components/Select";
const URL = "/admin/feed";
const StyledButton = styled(Button) <{ $colorOverride: "red" }>`
background-color: ${(p) => p.$colorOverride};
border-radius: 8px;
color: white;
font-size: 13px;
font-weight: bold;
`;
const confirmDelete = async (post: Post) => {
if (window.confirm(`Delete: ${post.id}: ${post.title_fi}/${post.title_en}; Are you sure?`) === true) {
try {
await PostApi.deletePost(post.id);
toast.success("Post removed successfully 😎");
window.location.reload(); // TODO: Fetch/update post list, so user sees the signup in the list
} catch (err) {
toast.error("Uh oh! Something went wrong! Try again later. 😟");
}
}
};
const Renderer: React.FC = () => {
const api: API = { path: APIPath.FEED, authenticated: true };
const { data: feed, error } = useSWR<Post[]>(api, fetcher);
const [order, setOrder] = useState<string>("descending");
const feedSort = (a, b) => {
let result = 0;
if (order === "descending") {
result = new Date(b.publish_time).getTime() - new Date(a.publish_time).getTime();
} else if (order === "ascending") {
result = new Date(a.publish_time).getTime() - new Date(b.publish_time).getTime();
}
return result;
};
useEffect(() => {
}, [order, feed]);
if (error) {
console.error(error);
return (
<div>
Failed loading feed
</div>
);
}
if (!feed?.length) {
return (
<div>No posts.</div>
);
}
return (
<div>
<SelectWrapper>
Order:
<StyledSelect name="" onChange={(e) => setOrder(e.target.value)}>
<option value="descending">Descending</option>
<option value="ascending">Ascending</option>
</StyledSelect>
</SelectWrapper>
<table>
<thead>
<tr>
<th>Title</th>
<th>Description</th>
<th>Publish time</th>
</tr>
</thead>
<tbody>
{feed.sort(feedSort).map((post) => (
<tr key={post.id}>
<td><Link to={`${URL}/${post.id}`}>{post.title_fi}</Link></td>
<td>{post.description_fi}</td>
<td>{formatISO(new Date(post.publish_time), { representation: "date" })}</td>
<td>
<StyledButton $colorOverride="red" buttonStyle="filled" onClick={() => confirmDelete(post)}>
Delete
</StyledButton>
</td>
</tr>
))}
</tbody>
</table>
</div>
);
};
const AdminFeedPage: NextPage = () => (
<AdminListCommon>
<h1>Feed</h1>
<AddLink text="Create news post" to={`${URL}/create`} />
<Renderer />
</AdminListCommon>
);
export default AdminFeedPage;