2023-02-12 10:16:13 +00:00
|
|
|
<script lang="ts">
|
|
|
|
|
import { format as formatDate } from "date-fns";
|
2023-02-12 22:13:29 +00:00
|
|
|
import { BlogPost } from "$lib/blog/BlogPost.js";
|
2025-01-04 15:35:07 +00:00
|
|
|
let title = $state("");
|
|
|
|
|
let author = $state("Thomas Wilson");
|
2023-02-12 22:13:29 +00:00
|
|
|
let date = new Date();
|
2025-01-04 15:35:07 +00:00
|
|
|
let content = $state("");
|
|
|
|
|
let slug = $state("");
|
2023-02-12 22:13:29 +00:00
|
|
|
let blogPost: BlogPost | null = null;
|
2023-02-12 10:16:13 +00:00
|
|
|
|
2023-02-12 22:13:29 +00:00
|
|
|
function slugifyString(originalString: string): string {
|
|
|
|
|
return originalString
|
|
|
|
|
.toLowerCase()
|
|
|
|
|
.replaceAll(/ /g, "-")
|
|
|
|
|
.replaceAll(/[^a-zA-Z0-9-]+/g, "")
|
|
|
|
|
.replaceAll(/-+/g, "-");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function handleTitleChange() {
|
|
|
|
|
const dateAsString = formatDate(date, "yyyy-MM-dd");
|
|
|
|
|
const slugifiedTitle = slugifyString(title);
|
|
|
|
|
slug = `${dateAsString}-${slugifiedTitle}`;
|
|
|
|
|
}
|
2023-02-12 10:16:13 +00:00
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<section class="new-blog-post">
|
2023-09-08 21:31:00 +00:00
|
|
|
<a href="/blog">Back to Blog</a>
|
2023-02-12 10:16:13 +00:00
|
|
|
<h1>New Blog Post</h1>
|
2025-01-09 14:08:29 +00:00
|
|
|
<form method="POST" action="/blog">
|
2023-02-12 22:13:29 +00:00
|
|
|
<div class="field">
|
|
|
|
|
<label class="field__label" for="title">Title</label>
|
|
|
|
|
<input
|
|
|
|
|
type="text"
|
|
|
|
|
id="title"
|
2025-01-09 14:08:29 +00:00
|
|
|
name="title"
|
2023-02-12 22:13:29 +00:00
|
|
|
required
|
2024-08-26 09:57:05 +00:00
|
|
|
bind:value={title}
|
2025-01-04 15:35:07 +00:00
|
|
|
onchange={handleTitleChange}
|
2023-02-12 22:13:29 +00:00
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="field">
|
|
|
|
|
<label class="field__label" for="author">Author</label>
|
2025-01-09 14:08:29 +00:00
|
|
|
<input
|
|
|
|
|
type="text"
|
|
|
|
|
name="author"
|
|
|
|
|
id="author"
|
|
|
|
|
required
|
|
|
|
|
bind:value={author}
|
|
|
|
|
/>
|
2023-02-12 22:13:29 +00:00
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="field">
|
|
|
|
|
<label class="field__label" for="slug">Slug</label>
|
2025-01-09 14:08:29 +00:00
|
|
|
<input type="text" name="slug" id="slug" required bind:value={slug} />
|
2023-02-12 22:13:29 +00:00
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="field">
|
|
|
|
|
<label class="field__label" for="content">Content</label>
|
2025-01-09 14:08:29 +00:00
|
|
|
<textarea
|
|
|
|
|
name="content"
|
|
|
|
|
id="content"
|
|
|
|
|
rows="10"
|
|
|
|
|
cols="50"
|
|
|
|
|
bind:value={content}
|
|
|
|
|
></textarea>
|
2023-02-12 22:13:29 +00:00
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="submit">
|
2025-01-09 14:08:29 +00:00
|
|
|
<button type="submit" class="create-button">Publish</button>
|
2023-02-12 22:13:29 +00:00
|
|
|
</div>
|
|
|
|
|
</form>
|
2023-02-12 10:16:13 +00:00
|
|
|
</section>
|
|
|
|
|
|
2023-02-12 22:13:29 +00:00
|
|
|
{#if blogPost}
|
|
|
|
|
<section class="preview">
|
|
|
|
|
<h2>Preview</h2>
|
|
|
|
|
<article>
|
|
|
|
|
{@html blogPost.html}
|
|
|
|
|
</article>
|
|
|
|
|
</section>
|
|
|
|
|
{/if}
|
|
|
|
|
|
2023-02-12 10:16:13 +00:00
|
|
|
<style>
|
|
|
|
|
section {
|
|
|
|
|
--gap: 8px;
|
|
|
|
|
--padding: 8px;
|
|
|
|
|
--padding-md: 16px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.new-blog-post {
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: 100%;
|
|
|
|
|
grid-template-rows: min-content min-content min-content 1fr;
|
|
|
|
|
gap: var(--gap);
|
|
|
|
|
place-items: center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.field {
|
|
|
|
|
width: 100%;
|
|
|
|
|
max-width: 600px;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.field__label {
|
|
|
|
|
font-family: var(--font-family-title);
|
|
|
|
|
font-size: 1.15rem;
|
|
|
|
|
color: var(--grey-600);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.create-button {
|
|
|
|
|
background-color: var(--brand-orange);
|
|
|
|
|
color: var(--white);
|
|
|
|
|
border: none;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
padding: var(--padding) var(--padding-md);
|
|
|
|
|
font-family: var(--font-family-title);
|
|
|
|
|
font-size: 1.15rem;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
}
|
2023-02-12 22:13:29 +00:00
|
|
|
|
|
|
|
|
.preview {
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: 100%;
|
|
|
|
|
grid-template-rows: min-content 1fr;
|
|
|
|
|
gap: var(--gap);
|
|
|
|
|
place-items: center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.preview article {
|
|
|
|
|
width: 100%;
|
|
|
|
|
max-width: 65ch;
|
|
|
|
|
}
|
2023-02-12 10:16:13 +00:00
|
|
|
</style>
|