feat: initial uploads and single study space view

Co-Authored-By: Alex Ling <al443@ic.ac.uk>
This commit is contained in:
2025-06-04 18:10:45 +01:00
parent b02f2b2303
commit 40435df5e2
16 changed files with 486 additions and 86 deletions

View File

@@ -0,0 +1,118 @@
<script lang="ts">
import Text from "$lib/components/inputs/Text.svelte";
import Textarea from "$lib/components/inputs/Textarea.svelte";
import Navbar from "$lib/components/Navbar.svelte";
import crossUrl from "$lib/assets/cross.svg";
import Button from "$lib/components/Button.svelte";
import Image from "$lib/components/inputs/Image.svelte";
import type { Table } from "$lib";
import { goto, invalidate } from "$app/navigation";
const { data } = $props();
const { supabase } = $derived(data);
let spaceImg = $state<FileList>();
let studySpaceData = $state<Omit<Table<"study_spaces">, "id" | "created_at" | "updated_at">>({
description: "",
building_address: "",
location: ""
});
async function uploadStudySpace() {
const imageFile = spaceImg?.[0];
if (!imageFile) return alert("Please select an image file.");
const { data: studySpaceInsert, error: studySpaceError } = await supabase
.from("study_spaces")
.insert(studySpaceData)
.select()
.single();
if (studySpaceError)
return alert(`Error uploading study space: ${studySpaceError.message}`);
const { data: imgUpload, error: imageError } = await supabase.storage
.from("files_bucket")
.upload(`public/${studySpaceInsert.id}-${imageFile.name}`, imageFile, {
contentType: imageFile.type
});
if (imageError) return alert(`Error uploading image: ${imageError.message}`);
const { error: imageInsertError } = await supabase
.from("study_space_images")
.insert({
study_space_id: studySpaceInsert.id,
image_path: imgUpload.path
})
.select()
.single();
if (imageInsertError) return alert(`Error creating image: ${imageInsertError.message}`);
alert("Thank you for your contribution!");
// Redirect to the new study space page
await goto(`/space/${studySpaceInsert.id}`, {
invalidate: ["db:study_spaces"]
});
}
</script>
<Navbar>
<a href="/">
<img src={crossUrl} alt="close" />
</a>
</Navbar>
<form
onsubmit={async (event) => {
event.preventDefault();
await uploadStudySpace();
}}
>
<Image name="study-space-image" minHeight="16rem" bind:files={spaceImg} />
<label for="location">Enter the name:</label>
<Text name="location" bind:value={studySpaceData.location} placeholder="Room 123, Floor 1" />
<label for="description">Add a description:</label>
<Textarea
name="description"
bind:value={studySpaceData.description}
placeholder="A quiet, but small study space..."
rows={5}
/>
<label for="address">Add an address:</label>
<Text
name="address"
bind:value={studySpaceData.building_address}
placeholder="180 Queen's Gate, London, SW7 5HF"
/>
<div class="submit">
<Button type="submit">Share this study space!</Button>
</div>
</form>
<style>
form {
display: flex;
flex-direction: column;
padding: 1.5rem;
gap: 0.5rem;
max-width: 32rem;
margin: 0 auto;
}
label {
color: #ffffff;
margin-top: 0.5rem;
}
.submit {
position: sticky;
display: flex;
flex-direction: column;
margin-top: 0.5rem;
bottom: 0;
margin-left: -0.5rem;
width: calc(100% + 1rem);
}
</style>