Add basic forms and routes

This commit is contained in:
Thilo Hohlt
2024-08-01 18:09:35 +02:00
parent d21e00a0c3
commit b0666f4a8c
20 changed files with 762 additions and 342 deletions

View File

@@ -0,0 +1,45 @@
<script lang="ts">
import type { Snippet } from "svelte";
const { id, title, children, previewContent } = $props<{
id: string;
title: string;
children: Snippet;
previewContent: string;
}>();
</script>
<div class="operations">
<h1>{title}</h1>
<div>
<a href="/website/{id}">Settings</a>
<a href="/website/{id}/articles">Articles</a>
</div>
{@render children()}
</div>
<div class="preview">
{@html previewContent}
</div>
<style>
.operations,
.preview {
padding: 1rem;
min-inline-size: 15rem;
block-size: 100%;
}
.operations {
inline-size: 50%;
border-inline-end: 0.0625rem solid hsl(0 0% 50%);
resize: horizontal;
overflow-y: auto;
}
.preview {
flex-grow: 1;
}
</style>

View File

@@ -0,0 +1,66 @@
import { randomUUID } from "node:crypto";
import { mkdir, writeFile } from "node:fs/promises";
import { extname, join, relative } from "node:path";
import { ALLOWED_MIME_TYPES } from "../utils";
export const handleFileUpload = async (
file: File,
contentId: string,
userId: string,
session_token: string | undefined,
customFetch: typeof fetch
) => {
if (file.size === 0) return undefined;
const MAX_FILE_SIZE = 1024 * 1024;
if (file.size > MAX_FILE_SIZE) {
return {
success: false,
message: `File size exceeds the maximum limit of ${MAX_FILE_SIZE / 1024 / 1024} MB.`
};
}
if (!ALLOWED_MIME_TYPES.includes(file.type)) {
return {
success: false,
message: "Invalid file type. JPEG, PNG, SVG and WEBP are allowed."
};
}
const buffer = Buffer.from(await file.arrayBuffer());
const uploadDir = join(process.cwd(), "static", "user-uploads", userId);
await mkdir(uploadDir, { recursive: true });
const fileId = randomUUID();
const fileExtension = extname(file.name);
const filepath = join(uploadDir, `${fileId}${fileExtension}`);
await writeFile(filepath, buffer);
const relativePath = relative(join(process.cwd(), "static"), filepath);
const res = await customFetch("http://localhost:3000/media", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${session_token}`,
Prefer: "return=representation",
Accept: "application/vnd.pgrst.object+json"
},
body: JSON.stringify({
website_id: contentId,
user_id: userId,
original_name: file.name,
file_system_path: relativePath
})
});
const response = await res.json();
if (!res.ok) {
return { success: false, message: response.message };
}
return { success: true, content: response.id };
};