feat: walking skeleton - study space uploads

This commit is contained in:
2025-05-30 11:13:35 +01:00
parent 00944faf1e
commit d7db89e13c
12 changed files with 516 additions and 14 deletions

View File

@@ -1,2 +1,87 @@
<h1>Welcome to SvelteKit</h1>
<p>Visit <a href="https://svelte.dev/docs/kit">svelte.dev/docs/kit</a> to read the documentation</p>
<script lang="ts">
import SpaceCard from "$lib/components/SpaceCard.svelte";
import defaultImg from "$lib/assets/study_space.png";
import { createClient } from "@supabase/supabase-js";
import type { Database } from "$lib/database";
import { PUBLIC_SUPABASE_ANON_KEY, PUBLIC_SUPABASE_URL } from "$env/static/public";
import { invalidate } from "$app/navigation";
const supabase = createClient<Database>(PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY);
const { data } = $props();
const { studySpaces } = $derived(data);
let title = $state("");
let fileInput = $state<HTMLInputElement | null>(null);
async function uploadStudySpace() {
const imageFile = fileInput?.files?.[0];
const imageB64 = imageFile
? await new Promise<string>((resolve) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result as string);
reader.readAsDataURL(imageFile);
})
: null;
if (!imageB64 || !imageFile) {
alert("Please select an image file.");
return;
}
const res = await fetch("/api/study_spaces", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
title,
img: imageB64,
imgTitle: imageFile.name
})
});
if (res.ok) {
alert("Study space uploaded successfully!");
await invalidate("db:study_spaces");
} else {
alert("Failed to upload study space.");
}
}
</script>
<main>
{#each studySpaces as studySpace (studySpace.id)}
{@const imgUrl =
studySpace.study_space_images.length > 0
? supabase.storage
.from("files_bucket")
.getPublicUrl(studySpace.study_space_images[0].image_path).data.publicUrl
: defaultImg}
<SpaceCard alt="Photo of {studySpace.title}" imgSrc={imgUrl}>
{#snippet description()}
<p>{studySpace.title}</p>
{/snippet}
</SpaceCard>
{/each}
</main>
<form
onsubmit={(e) => {
e.preventDefault();
uploadStudySpace();
}}
>
<input type="text" name="title" bind:value={title} placeholder="Study Space Title" required />
<input type="file" name="image" accept=".png, image/png" required bind:this={fileInput} />
<button type="submit">Upload Study Space</button>
</form>
<style>
main {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
padding: 1rem;
width: min(600px, 100vw);
}
form {
max-width: 600px;
}
</style>