128 lines
4.4 KiB
JavaScript
128 lines
4.4 KiB
JavaScript
import { useState } from 'react';
|
|
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
|
import { useParams, useNavigate } from 'react-router-dom';
|
|
import { apiUrl, fetchPage, fetchPageAtEdit, postPage, deletePage } from '../apiTools.jsx';
|
|
import { useFixLinks } from '../clientStuff.jsx';
|
|
import { useLoggedIn } from '../AuthProvider.jsx';
|
|
import Sidebar from './Sidebar.jsx';
|
|
import CommandEntry from './CommandEntry.jsx';
|
|
|
|
import './Pages.css';
|
|
|
|
function PageWithSidebar({ editing }) {
|
|
const queryClient = useQueryClient();
|
|
const navigate = useNavigate();
|
|
const { pagenumber, editid } = useParams();
|
|
const loggedIn = useLoggedIn();
|
|
const noLoad = useFixLinks();
|
|
const [command, setCommand] = useState("");
|
|
|
|
const fetchQuery = useQuery({ // fetch the currrent values
|
|
queryKey: ['page', pagenumber, editid],
|
|
queryFn: () => editid ? fetchPageAtEdit(pagenumber, editid) : fetchPage(pagenumber)
|
|
})
|
|
|
|
const postMutation = useMutation({ // for changing the value when we're done with it
|
|
mutationFn: ({id, title, description}) => postPage({id, title, description}),
|
|
onSettled: async (data, error, variables) => {
|
|
// Invalidate and refetch
|
|
await queryClient.invalidateQueries({ queryKey: ['page', variables.id, undefined] })
|
|
},
|
|
});
|
|
|
|
const deleteMutation = useMutation({ // for changing the value when we're done with it
|
|
mutationFn: (id) => deletePage(id),
|
|
onSettled: async (data, error, variables) => {
|
|
// Invalidate and refetch
|
|
await queryClient.invalidateQueries({ queryKey: ['pages'] })
|
|
},
|
|
});
|
|
|
|
const readyToShow = !(fetchQuery.error || fetchQuery.isPending);
|
|
|
|
let {id, title, description, html, time, author} = fetchQuery.data || {};
|
|
if (!title) title = "[no title]";
|
|
if (!html) html = "[body missing]";
|
|
if (!description) description = "[body missing]";
|
|
|
|
function submitChanges(e) {
|
|
const newTitle = document.querySelector('span').innerHTML;
|
|
const newText = document.querySelector('pre').innerHTML;
|
|
postMutation.mutate({
|
|
id: pagenumber,
|
|
title: newTitle,
|
|
description: newText
|
|
});
|
|
navigate(`/${pagenumber}`, {replace: true})
|
|
}
|
|
|
|
function submitDelete(e) {
|
|
e.preventDefault();
|
|
deleteMutation.mutate(pagenumber);
|
|
navigate(`/`);
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<div className="main-column">
|
|
<header>
|
|
<h1>
|
|
<a href="/" {...noLoad}>🌳</a>
|
|
{pagenumber}.
|
|
<span
|
|
contentEditable={editing}
|
|
dangerouslySetInnerHTML={{__html: readyToShow ? title : "..." }} />
|
|
</h1>
|
|
{readyToShow && editid && `saved at ${time} by user #${author}`}
|
|
<hr/>
|
|
</header>
|
|
<section className="page-contents">
|
|
{ readyToShow ?
|
|
(
|
|
editing ?
|
|
<pre
|
|
contentEditable="true"
|
|
dangerouslySetInnerHTML={{__html: description}} />
|
|
:
|
|
<div
|
|
dangerouslySetInnerHTML={{__html: html}}
|
|
{...noLoad} />
|
|
)
|
|
:
|
|
"..."
|
|
}
|
|
</section>
|
|
<button
|
|
onClick={() => navigate(`/${pagenumber}/history`)}>
|
|
History
|
|
</button>
|
|
{editing && (
|
|
<button
|
|
disabled={postMutation.isPending}
|
|
onClick={submitChanges}>
|
|
{postMutation.isPending ? "Updating..." : "Update"}
|
|
</button>)}
|
|
{!editing && !editid && (
|
|
<button
|
|
disabled={!loggedIn}
|
|
onClick={() => navigate(`/${pagenumber}/edit`)}>
|
|
Edit Page
|
|
</button>)}
|
|
{loggedIn && (
|
|
<button
|
|
disabled={deleteMutation.isPending}
|
|
onClick={submitDelete}>
|
|
{deleteMutation.isPending ? "Deleting..." : "Delete this page and entire edit history (no backsies)"}
|
|
</button>)}
|
|
</div>
|
|
<Sidebar pagenumber={pagenumber} hidden="true" sendWord={(word) => setCommand((command + " " + word).trim())}>
|
|
{!editing && <li><button onClick={() => navigate(`/${pagenumber}/edit`)}>edit</button></li>}
|
|
{editing && <li><button disabled={postMutation.isPending} onClick={submitChanges}>save</button></li>}
|
|
{editing && <li><button onClick={() => navigate(`/${pagenumber}`)}>return</button></li>}
|
|
</Sidebar>
|
|
<CommandEntry command={command} onChange={(e) => setCommand(e.target.value)}/>
|
|
</>
|
|
);
|
|
}
|
|
|
|
export default PageWithSidebar; |