2024-08-01 18:09:35 +02:00
|
|
|
<script lang="ts">
|
|
|
|
|
import WebsiteEditor from "$lib/components/WebsiteEditor.svelte";
|
|
|
|
|
import { page } from "$app/stores";
|
|
|
|
|
import { enhance } from "$app/forms";
|
2024-08-02 15:33:18 +02:00
|
|
|
import Modal from "$lib/components/Modal.svelte";
|
2024-08-02 16:36:21 +02:00
|
|
|
import SuccessOrError from "$lib/components/SuccessOrError.svelte";
|
2024-09-07 14:28:23 +02:00
|
|
|
import LoadingSpinner from "$lib/components/LoadingSpinner.svelte";
|
2024-08-05 14:38:44 +02:00
|
|
|
import type { ActionData, PageServerData } from "./$types";
|
2024-09-27 16:59:29 +02:00
|
|
|
import { enhanceForm } from "$lib/utils";
|
|
|
|
|
import { sending } from "$lib/runes.svelte";
|
|
|
|
|
import { previewContent } from "$lib/runes.svelte";
|
2024-08-01 18:09:35 +02:00
|
|
|
|
2024-08-20 19:17:05 +02:00
|
|
|
const { data, form }: { data: PageServerData; form: ActionData } = $props();
|
2024-09-07 14:28:23 +02:00
|
|
|
|
2024-09-27 16:59:29 +02:00
|
|
|
previewContent.value = data.home.main_content;
|
2024-08-01 18:09:35 +02:00
|
|
|
</script>
|
|
|
|
|
|
2024-08-02 16:36:21 +02:00
|
|
|
<SuccessOrError success={form?.success} message={form?.message} />
|
2024-08-01 18:09:35 +02:00
|
|
|
|
2024-09-27 16:59:29 +02:00
|
|
|
{#if sending.value}
|
2024-09-07 14:28:23 +02:00
|
|
|
<LoadingSpinner />
|
|
|
|
|
{/if}
|
|
|
|
|
|
2024-08-01 18:09:35 +02:00
|
|
|
<WebsiteEditor
|
|
|
|
|
id={data.website.id}
|
2024-08-27 16:39:29 +02:00
|
|
|
contentType={data.website.content_type}
|
2024-08-01 18:09:35 +02:00
|
|
|
title={data.website.title}
|
|
|
|
|
>
|
2024-08-24 21:43:15 +02:00
|
|
|
<section id="create-article">
|
|
|
|
|
<h2>
|
|
|
|
|
<a href="#create-article">Create article</a>
|
|
|
|
|
</h2>
|
2024-08-01 18:09:35 +02:00
|
|
|
|
2024-10-30 21:33:44 +01:00
|
|
|
<div class="multi-wrapper">
|
|
|
|
|
<Modal id="create-article" text="Create article">
|
|
|
|
|
<h3>Create article</h3>
|
|
|
|
|
<form
|
|
|
|
|
method="POST"
|
|
|
|
|
action="?/createArticle"
|
|
|
|
|
use:enhance={enhanceForm({ closeModal: true })}
|
|
|
|
|
>
|
|
|
|
|
<label>
|
|
|
|
|
Title:
|
|
|
|
|
<input type="text" name="title" pattern="\S(.*\S)?" maxlength="100" required />
|
|
|
|
|
</label>
|
|
|
|
|
<button type="submit" disabled={data.permissionLevel === 10}>Create article</button>
|
|
|
|
|
</form>
|
|
|
|
|
</Modal>
|
|
|
|
|
<Modal id="import-articles" text="Import articles">
|
|
|
|
|
<h3>Import articles</h3>
|
|
|
|
|
<form
|
|
|
|
|
method="POST"
|
|
|
|
|
action="?/importArticles"
|
|
|
|
|
enctype="multipart/form-data"
|
|
|
|
|
use:enhance={enhanceForm({ closeModal: true })}
|
|
|
|
|
>
|
|
|
|
|
<label>
|
|
|
|
|
Markdown files:
|
|
|
|
|
<input type="file" name="import-articles" accept=".md" multiple required />
|
|
|
|
|
</label>
|
|
|
|
|
<button type="submit" disabled={data.permissionLevel === 10}>Import articles</button>
|
|
|
|
|
</form>
|
|
|
|
|
</Modal>
|
|
|
|
|
</div>
|
2024-08-01 18:09:35 +02:00
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
{#if data.totalArticleCount > 0}
|
2024-08-24 21:43:15 +02:00
|
|
|
<section id="all-articles">
|
|
|
|
|
<h2>
|
|
|
|
|
<a href="#all-articles">All articles</a>
|
|
|
|
|
</h2>
|
2024-08-01 18:09:35 +02:00
|
|
|
|
2024-10-30 21:33:44 +01:00
|
|
|
<a
|
|
|
|
|
class="export-anchor"
|
|
|
|
|
href={`${data.API_BASE_PREFIX}/rpc/export_articles_zip?website_id=${data.website.id}`}
|
|
|
|
|
>Export articles</a
|
|
|
|
|
>
|
2024-08-15 18:45:47 +02:00
|
|
|
<details>
|
2024-08-29 12:05:02 +02:00
|
|
|
<summary>Search & Filter</summary>
|
2024-08-15 18:45:47 +02:00
|
|
|
<form method="GET">
|
|
|
|
|
<label>
|
|
|
|
|
Search:
|
2024-10-19 17:55:02 +02:00
|
|
|
<input type="text" name="query" value={$page.url.searchParams.get("query")} />
|
2024-08-15 18:45:47 +02:00
|
|
|
</label>
|
|
|
|
|
<label>
|
|
|
|
|
Filter:
|
2024-10-19 17:55:02 +02:00
|
|
|
<select name="filter">
|
|
|
|
|
<option value="all" selected={"all" === $page.url.searchParams.get("filter")}
|
2024-09-01 16:51:21 +02:00
|
|
|
>Show all</option
|
|
|
|
|
>
|
|
|
|
|
<option
|
|
|
|
|
value="creations"
|
2024-10-19 17:55:02 +02:00
|
|
|
selected={"creations" === $page.url.searchParams.get("filter")}
|
2024-09-01 16:51:21 +02:00
|
|
|
>Created by you</option
|
|
|
|
|
>
|
2024-10-19 17:55:02 +02:00
|
|
|
<option value="shared" selected={"shared" === $page.url.searchParams.get("filter")}
|
2024-09-01 16:51:21 +02:00
|
|
|
>Created by others</option
|
|
|
|
|
>
|
2024-08-15 18:45:47 +02:00
|
|
|
</select>
|
|
|
|
|
</label>
|
2024-10-25 19:23:38 +02:00
|
|
|
<button type="submit">Apply</button>
|
2024-08-15 18:45:47 +02:00
|
|
|
</form>
|
|
|
|
|
</details>
|
|
|
|
|
|
2024-08-23 18:43:52 +02:00
|
|
|
<ul class="unpadded">
|
2024-10-19 17:55:02 +02:00
|
|
|
{#each data.articles as { id, user_id, title, article_weight, docs_category } (id)}
|
2024-08-15 18:45:47 +02:00
|
|
|
<li class="article-card">
|
|
|
|
|
<p>
|
2024-08-29 20:09:37 +02:00
|
|
|
<strong>{title} {article_weight ? `(${article_weight})` : ""}</strong>
|
2024-08-28 19:39:22 +02:00
|
|
|
{#if docs_category?.category_name}
|
|
|
|
|
<br />
|
|
|
|
|
<small>
|
|
|
|
|
<svg
|
|
|
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
|
|
|
viewBox="0 0 16 16"
|
|
|
|
|
fill="currentColor"
|
|
|
|
|
width="16"
|
|
|
|
|
height="16"
|
|
|
|
|
>
|
|
|
|
|
<path
|
|
|
|
|
fill-rule="evenodd"
|
|
|
|
|
d="M4.5 2A2.5 2.5 0 0 0 2 4.5v2.879a2.5 2.5 0 0 0 .732 1.767l4.5 4.5a2.5 2.5 0 0 0 3.536 0l2.878-2.878a2.5 2.5 0 0 0 0-3.536l-4.5-4.5A2.5 2.5 0 0 0 7.38 2H4.5ZM5 6a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z"
|
|
|
|
|
clip-rule="evenodd"
|
|
|
|
|
></path>
|
|
|
|
|
</svg>
|
|
|
|
|
|
|
|
|
|
{docs_category.category_name}
|
|
|
|
|
</small>
|
|
|
|
|
{/if}
|
2024-08-15 18:45:47 +02:00
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<div class="article-card__actions">
|
|
|
|
|
<a href="/website/{data.website.id}/articles/{id}">Edit</a>
|
|
|
|
|
<Modal id="delete-article-{id}" text="Delete">
|
|
|
|
|
<h4>Delete article</h4>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
<strong>Caution!</strong>
|
|
|
|
|
Deleting this article will irretrievably erase all data.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<form
|
|
|
|
|
method="POST"
|
|
|
|
|
action="?/deleteArticle"
|
2024-09-27 16:59:29 +02:00
|
|
|
use:enhance={enhanceForm({ closeModal: true })}
|
2024-08-15 18:45:47 +02:00
|
|
|
>
|
|
|
|
|
<input type="hidden" name="id" value={id} />
|
|
|
|
|
|
2024-10-19 17:55:02 +02:00
|
|
|
<button
|
|
|
|
|
type="submit"
|
|
|
|
|
disabled={data.permissionLevel === 10 ||
|
|
|
|
|
(data.permissionLevel === 20 && user_id !== data.user.id)}
|
|
|
|
|
>Delete article</button
|
|
|
|
|
>
|
2024-08-15 18:45:47 +02:00
|
|
|
</form>
|
|
|
|
|
</Modal>
|
|
|
|
|
</div>
|
|
|
|
|
</li>
|
|
|
|
|
{/each}
|
|
|
|
|
</ul>
|
2024-08-01 18:09:35 +02:00
|
|
|
</section>
|
|
|
|
|
{/if}
|
|
|
|
|
</WebsiteEditor>
|
2024-08-02 15:33:18 +02:00
|
|
|
|
|
|
|
|
<style>
|
|
|
|
|
.article-card {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
2024-08-15 16:26:32 +02:00
|
|
|
column-gap: var(--space-s);
|
|
|
|
|
row-gap: var(--space-2xs);
|
2024-08-02 15:33:18 +02:00
|
|
|
flex-wrap: wrap;
|
|
|
|
|
justify-content: space-between;
|
2024-08-15 18:45:47 +02:00
|
|
|
margin-block-start: var(--space-xs);
|
2024-08-02 15:33:18 +02:00
|
|
|
}
|
|
|
|
|
|
2024-08-15 16:26:32 +02:00
|
|
|
.article-card + .article-card {
|
2024-08-15 18:45:47 +02:00
|
|
|
padding-block-start: var(--space-xs);
|
2024-08-15 16:26:32 +02:00
|
|
|
border-block-start: var(--border-primary);
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-02 15:33:18 +02:00
|
|
|
.article-card__actions {
|
|
|
|
|
display: flex;
|
2024-08-15 16:26:32 +02:00
|
|
|
gap: var(--space-s);
|
2024-08-02 15:33:18 +02:00
|
|
|
align-items: center;
|
|
|
|
|
}
|
2024-10-30 21:33:44 +01:00
|
|
|
|
|
|
|
|
.multi-wrapper {
|
|
|
|
|
display: flex;
|
|
|
|
|
gap: var(--space-s);
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
align-items: start;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.export-anchor {
|
|
|
|
|
max-inline-size: fit-content;
|
|
|
|
|
}
|
2024-08-02 15:33:18 +02:00
|
|
|
</style>
|