Added news editor

This commit is contained in:
2021-02-03 12:22:39 +11:00
parent 5a271fb127
commit 217bcf08a6
7 changed files with 671 additions and 69 deletions
+2
View File
@@ -4,6 +4,7 @@ import { useCookies } from 'react-cookie';
//import BannedEmails from '../panels/banned-emails';
import NewsPublisher from '../panels/news-publisher';
import NewsEditor from '../panels/news-editor';
const Admin = props => {
const [cookies, setCookie] = useCookies();
@@ -17,6 +18,7 @@ const Admin = props => {
<div className='page'>
<h1 className='centered'>Administration</h1>
<NewsPublisher uri={process.env.NEWS_URI} newsKey={process.env.NEWS_KEY} />
<NewsEditor uri={process.env.NEWS_URI} newsKey={process.env.NEWS_KEY} />
</div>
);
};
+110
View File
@@ -0,0 +1,110 @@
import React, { useState } from 'react';
import Select from 'react-dropdown-select';
//DOCS: props.uri is the address of a live news-server
//DOCS: props.newsKey is the key of the live news-server
const NewsEditor = props => {
let titleElement, authorElement, bodyElement;
const [articles, setArticles] = useState(null);
const [index, setIndex] = useState(null);
if (!articles) {
fetch(`${props.uri}/titles?limit=999`, { method: 'GET' })
.then(a => {
if (!a.ok) {
throw `Network error ${a.status}: ${a.statusText} ${a.url}`;
}
return a.json();
})
.then(a => setArticles(a))
.catch(e => console.error(e))
;
}
return (
<div>
<h2 className='centered'>News Editor</h2>
<div>
<label htmlFor='article'>Article: </label>
<Select
options={(articles || []).map(article => { return { label: article.title, value: article.index }; })}
onChange={values => setIndex(fetchSelection(values[0].value, titleElement, authorElement, bodyElement, props.uri))}
/>
</div>
<form onSubmit={async e => {
e.preventDefault();
await handleSubmit(index, titleElement.value, authorElement.value, bodyElement.value, props.uri, props.newsKey);
titleElement.value = authorElement.value = bodyElement.value = '';
}}>
<div>
<label htmlFor='title'>Title: </label>
<input type='text' name='title' ref={ e => titleElement = e } />
</div>
<div>
<label htmlFor='author'>Author: </label>
<input type='text' name='author' ref={ e => authorElement = e } />
</div>
<div>
<label htmlFor='body'>Body: </label>
<textarea name='body' rows='10' cols='150' ref={ e => bodyElement = e } />
</div>
<button type='submit'>Update</button>
</form>
</div>
);
};
const fetchSelection = (index, titleElement, authorElement, bodyElement, uri) => {
fetch(`${uri}/archive/${index}`, {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
})
.then(blob => blob.json())
.then(article => {
titleElement.value = article.title;
authorElement.value = article.author;
bodyElement.value = article.body;
})
.catch(e => console.error(e))
;
return index; //this is admittedly odd
};
const handleSubmit = async (index, title, author, body, uri, newsKey) => {
title = title.trim();
author = author.trim();
body = body.trim();
uri = uri.trim();
newsKey = newsKey.trim();
//fetch POST json data
const raw = await fetch(
`${uri}/${index}`,
{
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
body: JSON.stringify({ title: title, author: author, body: body, key: newsKey })
}
);
if (raw.ok) {
const result = await raw.json();
if (result.ok) {
alert(`Updated article index ${index}`);
} else {
alert(result.error);
}
} else {
alert(raw.statusText);
}
};
export default NewsEditor;
+2 -2
View File
@@ -20,7 +20,7 @@ const NewsFeed = props => {
return (
<div>
<h2 className='centered'>News Feed</h2>
<h1 className='centered'>News Feed</h1>
{(articles || []).map((article, index) => {
return (
<div key={index}>
@@ -31,7 +31,7 @@ const NewsFeed = props => {
<span>Last Updated {dateFormat(articles.updatedAt, 'fullDate')} ({`${article.edits} edit${article.edits > 1 ? 's': ''}`})</span> :
<span>Published {dateFormat(articles.createdAt, 'fullDate')}</span>
}</p>
<p>{article.body}</p>
<p style={{whiteSpace: 'pre-wrap'}}>{article.body}</p>
</div>
);
})}
@@ -1,5 +1,7 @@
import React from 'react';
//DOCS: props.uri is the address of a live news-server
//DOCS: props.newsKey is the key of the live news-server
const NewsPublisher = props => {
let titleElement, authorElement, bodyElement;