save floors to db
This commit is contained in:
parent
4b9620be7f
commit
b0ffcb838f
6 changed files with 83 additions and 57 deletions
|
@ -14,3 +14,8 @@ export const sessions = pgTable("sessions", {
|
|||
.references(() => users.id),
|
||||
expiresAt: timestamp({ withTimezone: true, mode: "date" }).notNull(),
|
||||
});
|
||||
|
||||
export const floors = pgTable("floors", {
|
||||
floor: integer().primaryKey(),
|
||||
url: text().notNull(),
|
||||
});
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
import { db } from "$lib/server/db";
|
||||
import * as table from "$lib/server/db/schema";
|
||||
import { redirect } from "@sveltejs/kit";
|
||||
|
||||
export const load = async (event) => {
|
||||
if (!event.locals.user) {
|
||||
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 };
|
||||
};
|
||||
|
|
|
@ -3,21 +3,12 @@
|
|||
import * as Sidebar from "$lib/components/ui/sidebar/index.js";
|
||||
import { ChevronUp } from "lucide-svelte";
|
||||
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 { 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();
|
||||
|
||||
const items = [
|
||||
{
|
||||
number: 1,
|
||||
url: "/",
|
||||
icon: House,
|
||||
},
|
||||
];
|
||||
|
||||
sidebarItems.set(items);
|
||||
|
||||
function getFloorName(n) {
|
||||
switch (n) {
|
||||
case 1:
|
||||
|
@ -30,6 +21,7 @@
|
|||
return n + "th floor";
|
||||
}
|
||||
}
|
||||
console.log(data.floors);
|
||||
</script>
|
||||
|
||||
<Sidebar.Provider>
|
||||
|
@ -39,13 +31,13 @@
|
|||
<Sidebar.GroupLabel>Floors</Sidebar.GroupLabel>
|
||||
<Sidebar.GroupContent>
|
||||
<Sidebar.Menu>
|
||||
{#each $sidebarItems as item (item.number)}
|
||||
{#each data.floors as item (item.floor)}
|
||||
<Sidebar.MenuItem>
|
||||
<Sidebar.MenuButton>
|
||||
{#snippet child({ props })}
|
||||
<a href={item.url} {...props}>
|
||||
<item.icon />
|
||||
<span>{getFloorName(item.number)}</span>
|
||||
<House />
|
||||
<span>{getFloorName(item.floor)}</span>
|
||||
</a>
|
||||
{/snippet}
|
||||
</Sidebar.MenuButton>
|
||||
|
@ -54,22 +46,6 @@
|
|||
</Sidebar.Menu>
|
||||
</Sidebar.GroupContent>
|
||||
</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.Footer>
|
||||
<Sidebar.Menu>
|
||||
|
@ -81,20 +57,24 @@
|
|||
{...props}
|
||||
class="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
|
||||
>
|
||||
<User />
|
||||
{data.user.username}
|
||||
<ChevronUp class="ml-auto" />
|
||||
</Sidebar.MenuButton>
|
||||
{/snippet}
|
||||
</DropdownMenu.Trigger>
|
||||
<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">
|
||||
<DropdownMenu.Item class="cursor-pointer">Sign out</DropdownMenu.Item>
|
||||
<DropdownMenu.Item class="cursor-pointer">Log out</DropdownMenu.Item>
|
||||
</a>
|
||||
</DropdownMenu.Content>
|
||||
</DropdownMenu.Root>
|
||||
</Sidebar.MenuItem>
|
||||
</Sidebar.Menu></Sidebar.Footer
|
||||
>
|
||||
</Sidebar.Menu>
|
||||
</Sidebar.Footer>
|
||||
</Sidebar.Root>
|
||||
<main>
|
||||
<Sidebar.Trigger />
|
||||
|
|
41
src/routes/(app)/settings/+page.server.js
Normal file
41
src/routes/(app)/settings/+page.server.js
Normal 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));
|
||||
},
|
||||
};
|
|
@ -1,23 +1,22 @@
|
|||
<script>
|
||||
import { sidebarItems } from "@/stores/sidebarStore.ts";
|
||||
import House from "lucide-svelte/icons/house";
|
||||
import { get } from "svelte/store";
|
||||
import { enhance } from "$app/forms";
|
||||
import Button from "$lib/components/ui/button/button.svelte";
|
||||
import Input from "$lib/components/ui/input/input.svelte";
|
||||
import Label from "$lib/components/ui/label/label.svelte";
|
||||
|
||||
let i = 2;
|
||||
|
||||
function a() {
|
||||
const result = {
|
||||
number: i++,
|
||||
url: "/",
|
||||
icon: House,
|
||||
};
|
||||
|
||||
sidebarItems.update((item) => {
|
||||
item.push(result);
|
||||
return item;
|
||||
});
|
||||
console.log(get(sidebarItems));
|
||||
}
|
||||
const { form } = $props();
|
||||
</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}
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
import { writable } from "svelte/store"
|
||||
|
||||
export const sidebarItems = writable([]);
|
Loading…
Add table
Add a link
Reference in a new issue