save floors to db

This commit is contained in:
David Senoner 2025-05-18 17:21:58 +02:00
parent 4b9620be7f
commit b0ffcb838f
6 changed files with 83 additions and 57 deletions

View file

@ -14,3 +14,8 @@ export const sessions = pgTable("sessions", {
.references(() => users.id), .references(() => users.id),
expiresAt: timestamp({ withTimezone: true, mode: "date" }).notNull(), expiresAt: timestamp({ withTimezone: true, mode: "date" }).notNull(),
}); });
export const floors = pgTable("floors", {
floor: integer().primaryKey(),
url: text().notNull(),
});

View file

@ -1,8 +1,12 @@
import { db } from "$lib/server/db";
import * as table from "$lib/server/db/schema";
import { redirect } from "@sveltejs/kit"; import { redirect } from "@sveltejs/kit";
export const load = async (event) => { export const load = async (event) => {
if (!event.locals.user) { if (!event.locals.user) {
return redirect(302, "/login"); return redirect(302, "/login");
} }
return { user: event.locals.user }; const floors = await db.select().from(table.floors).orderBy(table.floors.floor);
return { user: event.locals.user, floors: floors };
}; };

View file

@ -3,21 +3,12 @@
import * as Sidebar from "$lib/components/ui/sidebar/index.js"; import * as Sidebar from "$lib/components/ui/sidebar/index.js";
import { ChevronUp } from "lucide-svelte"; import { ChevronUp } from "lucide-svelte";
import House from "lucide-svelte/icons/house"; import House from "lucide-svelte/icons/house";
import Settings from "lucide-svelte/icons/settings"; import User from "lucide-svelte/icons/user";
import "../../app.css"; import "../../app.css";
import { sidebarItems } from "@/stores/sidebarStore.ts"; import DropdownMenuItem from "$lib/components/ui/dropdown-menu/dropdown-menu-item.svelte";
import { Button } from "bits-ui";
let { children, data } = $props(); let { children, data } = $props();
const items = [
{
number: 1,
url: "/",
icon: House,
},
];
sidebarItems.set(items);
function getFloorName(n) { function getFloorName(n) {
switch (n) { switch (n) {
case 1: case 1:
@ -30,6 +21,7 @@
return n + "th floor"; return n + "th floor";
} }
} }
console.log(data.floors);
</script> </script>
<Sidebar.Provider> <Sidebar.Provider>
@ -39,13 +31,13 @@
<Sidebar.GroupLabel>Floors</Sidebar.GroupLabel> <Sidebar.GroupLabel>Floors</Sidebar.GroupLabel>
<Sidebar.GroupContent> <Sidebar.GroupContent>
<Sidebar.Menu> <Sidebar.Menu>
{#each $sidebarItems as item (item.number)} {#each data.floors as item (item.floor)}
<Sidebar.MenuItem> <Sidebar.MenuItem>
<Sidebar.MenuButton> <Sidebar.MenuButton>
{#snippet child({ props })} {#snippet child({ props })}
<a href={item.url} {...props}> <a href={item.url} {...props}>
<item.icon /> <House />
<span>{getFloorName(item.number)}</span> <span>{getFloorName(item.floor)}</span>
</a> </a>
{/snippet} {/snippet}
</Sidebar.MenuButton> </Sidebar.MenuButton>
@ -54,22 +46,6 @@
</Sidebar.Menu> </Sidebar.Menu>
</Sidebar.GroupContent> </Sidebar.GroupContent>
</Sidebar.Group> </Sidebar.Group>
<Sidebar.Group>
<Sidebar.GroupContent>
<Sidebar.Menu>
<Sidebar.MenuItem>
<Sidebar.MenuButton>
{#snippet child({ props })}
<a href="/settings" {...props}>
<Settings />
<span>Settings</span>
</a>
{/snippet}
</Sidebar.MenuButton>
</Sidebar.MenuItem>
</Sidebar.Menu>
</Sidebar.GroupContent>
</Sidebar.Group>
</Sidebar.Content> </Sidebar.Content>
<Sidebar.Footer> <Sidebar.Footer>
<Sidebar.Menu> <Sidebar.Menu>
@ -81,20 +57,24 @@
{...props} {...props}
class="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground" class="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
> >
<User />
{data.user.username} {data.user.username}
<ChevronUp class="ml-auto" /> <ChevronUp class="ml-auto" />
</Sidebar.MenuButton> </Sidebar.MenuButton>
{/snippet} {/snippet}
</DropdownMenu.Trigger> </DropdownMenu.Trigger>
<DropdownMenu.Content side="top" class="w-[--bits-dropdown-menu-anchor-width]"> <DropdownMenu.Content side="top" class="w-[--bits-dropdown-menu-anchor-width]">
<a href="/settings">
<DropdownMenu.Item class="cursor-pointer">Settings</DropdownMenu.Item>
</a>
<a href="/logout"> <a href="/logout">
<DropdownMenu.Item class="cursor-pointer">Sign out</DropdownMenu.Item> <DropdownMenu.Item class="cursor-pointer">Log out</DropdownMenu.Item>
</a> </a>
</DropdownMenu.Content> </DropdownMenu.Content>
</DropdownMenu.Root> </DropdownMenu.Root>
</Sidebar.MenuItem> </Sidebar.MenuItem>
</Sidebar.Menu></Sidebar.Footer </Sidebar.Menu>
> </Sidebar.Footer>
</Sidebar.Root> </Sidebar.Root>
<main> <main>
<Sidebar.Trigger /> <Sidebar.Trigger />

View file

@ -0,0 +1,41 @@
import { db } from "$lib/server/db";
import * as table from "$lib/server/db/schema";
import { fail } from "@sveltejs/kit";
import { eq } from "drizzle-orm";
export const load = async (event) => {
const floors = await db.select().from(table.floors).orderBy(table.floors.floor);
return { floors: floors };
};
export const actions = {
newfloor: async (event) => {
const formData = await event.request.formData();
const newFloorNumber = await formData.get("number");
const n = Number(newFloorNumber);
if (isNaN(n)) return fail(400, { message: "Invalid number!" });
const exists = await db
.select({ floor: table.floors.floor })
.from(table.floors)
.where(eq(table.floors.floor, n))
.execute();
console.log(n);
console.log(exists);
if (exists.length == 1) return fail(400, { message: "Floor " + n + " already exists!" });
await db.insert(table.floors).values({ floor: n, url: "/" });
},
rmfloor: async (event) => {
const formData = await event.request.formData();
const rmFloorNumber = await formData.get("number");
const n = Number(rmFloorNumber);
if (isNaN(n)) return fail(400, { message: "Invalid number!" });
const floors = await db.select().from(table.floors);
if (floors.length == 1) return fail(400, { message: "Cannot delete last floor!" });
await db.delete(table.floors).where(eq(table.floors.floor, n));
},
};

View file

@ -1,23 +1,22 @@
<script> <script>
import { sidebarItems } from "@/stores/sidebarStore.ts"; import { enhance } from "$app/forms";
import House from "lucide-svelte/icons/house"; import Button from "$lib/components/ui/button/button.svelte";
import { get } from "svelte/store"; import Input from "$lib/components/ui/input/input.svelte";
import Label from "$lib/components/ui/label/label.svelte";
let i = 2; const { form } = $props();
function a() {
const result = {
number: i++,
url: "/",
icon: House,
};
sidebarItems.update((item) => {
item.push(result);
return item;
});
console.log(get(sidebarItems));
}
</script> </script>
<button on:click={a}>a</button> <form method="post" action="?/newfloor" use:enhance>
<div class="form-group">
<Label for="number">Floor number</Label>
<Input id="number" name="number" />
</div>
<div class="button-group">
<Button type="submit">Add floor</Button>
<Button type="submit" formaction="?/rmfloor" variant="secondary">Delete floor</Button>
</div>
</form>
{#if form?.message}
<p class="error-message">{form.message}</p>
{/if}

View file

@ -1,3 +0,0 @@
import { writable } from "svelte/store"
export const sidebarItems = writable([]);