completed content manager

This commit is contained in:
2024-09-17 00:39:39 +09:00
parent a7dc8d6c8f
commit 850ced37de
9 changed files with 1185 additions and 117 deletions

View File

@@ -1,20 +1,50 @@
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/htmx.org@2.0.1" integrity="sha384-QWGpdj554B4ETpJJC9z+ZHJcA/i59TyjxEPXiiUgN2WmTyV5OEZWCD6gQhgkdpB/" crossorigin="anonymous"></script>
<meta charset="UTF-8">
<title>Content Manager</title>
<script src="https://unpkg.com/htmx.org@2.0.2" integrity="sha384-Y7hw+L/jvKeWIRRkqWYfPcvVxHzVzn5REgzbawhxAuQGwX1XWe70vji+VSeHOThJ" crossorigin="anonymous"></script>
<style>
table, tr, td {
border: black solid 1px;
}
thead {
background-color: lightgray;
}
tbody {
background-color: beige;
}
</style>
</head>
<body>
<h1>Content Manager</h1>
<p>Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint cillum sint consectetur cupidatat.</p>
<h3>Manager for SERA-HP's databases.</h3>
<button hx-get="/api/hello"
hx-trigger="click"
hx-swap="afterend"
hx-target="#list"
>
Click Me!
</button>
<ul>
<li>
<a href="/new-news.html">New News</a>
</li>
</ul>
<ul id="list"></ul>
<button hx-get="/api/news-list" hx-trigger="click" hx-swap="innerHTML" hx-target="#entries">Refresh</button>
<table>
<thead>
<tr>
<td>ID</td>
<td>Date</td>
<td>Entry Type</td>
<td>Card Content</td>
<td>Actions</td>
</tr>
</thead>
<tbody id="entries" hx-confirm='Are you sure you want to delete this news?' hx-target="closest tr" hx-swap="outerHTML"></tbody>
</table>
<script>
htmx.ajax('GET', '/api/news-list', {target: '#entries', swap: 'innerHTML'});
</script>
</body>
</html>

View File

@@ -0,0 +1,79 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Content Manager - new news</title>
<script src="https://unpkg.com/htmx.org@2.0.2" integrity="sha384-Y7hw+L/jvKeWIRRkqWYfPcvVxHzVzn5REgzbawhxAuQGwX1XWe70vji+VSeHOThJ" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<style>
form fieldset {
display: grid;
grid-auto-flow: row;
}
#new-news {
display: grid;
grid-template-columns: 1fr 1fr;
}
#preview {
border: black solid 1px;
height: 100%;
}
</style>
</head>
<body>
<div id="new-news">
<div>
<h3>New News</h3>
<form id="create-entry" hx-post="/api/news" hx-swap="none">
<fieldset>
<legend>Create Entry</legend>
<label for="entryType">Entry Type:</label>
<div>
<input type="radio" id="entryType-article" name="entryType" value="0" checked>
<label for="entryType-article">Article</label>
<input type="radio" id="entryType-tweet" name="entryType" value="1">
<label for="entryType-tweet">Tweet</label>
</div>
<label for="cardContent">Card Content:</label>
<input type="text" id="cardContent" name="cardContent" required>
<label for="article">Content:</label>
<textarea id="article" name="article" rows="24" cols="80"></textarea>
<label for="linkPath">Link Path (Optional):</label>
<div style="display: inline-flex;">
<p>/news/</p>
<input style="height: 1em; margin: auto 0;" text id="linkPath" name="linkPath">
</div>
<label for="coverImagePath">Cover Image Path (Optional):</label>
<input type="text" id="coverImagePath" name="coverImagePath">
</fieldset>
<button id="submit-button" type="submit">Create Entry</button>
<a href="/index.html"><button role="none" type="button">Cancel</button></a>
</form>
</div>
<div>
<h3>Preview</h3>
<div id="preview"></div>
</div>
</div>
<script>
const markdownPreivew = document.getElementById('preview');
const articleEditor = document.getElementById('article');
const submitButton = document.getElementById('submit-button');
articleEditor.addEventListener('input', () => {
markdownPreivew.innerHTML = marked.parse(articleEditor.value);
});
submitButton.addEventListener('click', () => {
window.location.href = "/index.html";
});
</script>
</body>
</html>

View File

@@ -0,0 +1,106 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Content Manager - update news</title>
<script src="https://unpkg.com/htmx.org@2.0.2" integrity="sha384-Y7hw+L/jvKeWIRRkqWYfPcvVxHzVzn5REgzbawhxAuQGwX1XWe70vji+VSeHOThJ" crossorigin="anonymous"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<style>
form fieldset {
display: grid;
grid-auto-flow: row;
}
#new-news {
display: grid;
grid-template-columns: 1fr 1fr;
}
#preview {
border: black solid 1px;
height: 100%;
}
</style>
</head>
<body>
<div id="new-news">
<div>
<h3>New News</h3>
<form id="create-entry" hx-put="/api/news" hx-swap="none">
<fieldset>
<legend>Create Entry</legend>
<label for="entryType">Entry Type:</label>
<div>
<input type="radio" id="entry-type-article" name="entryType" value="0" checked>
<label for="entry-type-article">Article</label>
<input type="radio" id="entry-type-tweet" name="entryType" value="1">
<label for="entry-type-tweet">Tweet</label>
</div>
<label for="cardContent">Card Content:</label>
<input type="text" id="cardContent" name="cardContent" required>
<label for="article">Content:</label>
<textarea id="article" name="article" rows="24" cols="80"></textarea>
<label for="linkPath">Link Path (Optional):</label>
<div style="display: inline-flex;">
<p>/news/</p>
<input style="height: 1em; margin: auto 0;" text id="linkPath" name="linkPath">
</div>
<label for="coverImagePath">Cover Image Path (Optional):</label>
<input type="text" id="coverImagePath" name="coverImagePath">
<input type="hidden" name="target" id="targetValue" value="test" />
</fieldset>
<button id="submit-button" type="submit">Update Entry</button>
<a href="/index.html"><button role="none" type="button">Cancel</button></a>
</form>
</div>
<div>
<h3>Preview</h3>
<div id="preview"></div>
</div>
</div>
<script>
const markdownPreivew = document.getElementById('preview');
const articleEditor = document.getElementById('article');
const submitButton = document.getElementById('submit-button');
const cardContentInput = document.getElementById('cardContent');
const coverImagePathInput = document.getElementById('coverImagePath');
const linkPathInput = document.getElementById('linkPath');
const entryTypeArticleInput = document.getElementById('entry-type-article');
const entryTypeTweetInput = document.getElementById('entry-type-tweet');
const targetValueInput = document.getElementById('targetValue');
const urlParams = new URLSearchParams(window.location.search);
const targetEntry = urlParams.get('target');
axios.get('/api/news', {params: {target: targetEntry}})
.then((response) => {
targetValueInput.value = response.data.date;
cardContentInput.value = response.data.cardContent;
coverImagePathInput.value = response.data.coverImagePath;
linkPathInput.value = response.data.linkPath.split('/')[2];
articleEditor.value = response.data.article;
markdownPreivew.innerHTML = marked.parse(articleEditor.value);
if (response.data.entryType == 0) {
entryTypeArticleInput.checked = true;
} else if (response.data.entryType == 1) {
entryTypeTweetInput.checked = true;
}
})
.catch((err) => {console.error(err)});
articleEditor.addEventListener('input', () => {
markdownPreivew.innerHTML = marked.parse(articleEditor.value);
});
submitButton.addEventListener('click', () => {
window.location.href = "/index.html";
});
</script>
</body>
</html>