feat: add topics creation/adding

This commit is contained in:
2025-01-24 12:15:35 +01:00
parent f82b3373b4
commit e2d3e75311
2 changed files with 78 additions and 27 deletions

View File

@@ -1,10 +1,10 @@
import { db } from "$lib/db" import { db } from '$lib/db';
import { tasks, tasksToTopics } from "$lib/db/schema" import { tasks, tasksToTopics, topics } from '$lib/db/schema';
import { eq } from "drizzle-orm" import { eq, and } from 'drizzle-orm';
export const load = async ({ params }) => { export const load = async ({ params }) => {
return { return {
task: (await db.query.tasks.findFirst({ task: await db.query.tasks.findFirst({
with: { with: {
tasksToTopics: { tasksToTopics: {
with: { with: {
@@ -13,17 +13,50 @@ export const load = async ({ params }) => {
} }
}, },
where: eq(tasks.id, params.id) where: eq(tasks.id, params.id)
}),
})
),
topics: await db.query.topics.findMany() topics: await db.query.topics.findMany()
} };
} };
export const actions = { export const actions = {
addTopic: async ({ request, params }) => { createTopic: async ({ request, params }) => {
const data = await request.formData() const data = await request.formData();
const task = await db.insert(tasksToTopics).values({ taskId: params.id, topicId: data.get('topic-id') }).returning() const topic = await db
.insert(topics)
.values({ name: data.get('name') })
.returning();
const existing = await db.query.tasksToTopics.findFirst({
where: and(
eq(tasksToTopics.taskId, Number(params.id)),
eq(tasksToTopics.topicId, topic[0].id)
)
});
if (!existing) {
await db
.insert(tasksToTopics)
.values({ taskId: Number(params.id), topicId: topic[0].id })
.returning();
} }
} },
addTopic: async ({ request, params }) => {
const data = await request.formData();
const topicId = Number(data.get('topic-id'));
const existing = await db.query.tasksToTopics.findFirst({
where: and(eq(tasksToTopics.taskId, Number(params.id)), eq(tasksToTopics.topicId, topicId))
});
console.log(existing);
if (!existing) {
await db
.insert(tasksToTopics)
.values({ taskId: Number(params.id), topicId })
.returning();
}
}
};

View File

@@ -10,7 +10,9 @@
let open = $state(false); let open = $state(false);
let value = $state(''); let value = $state('');
let search = $state('');
let triggerRef = $state<HTMLButtonElement>(null!); let triggerRef = $state<HTMLButtonElement>(null!);
let addTopicForms = $state<HTMLFormElement[]>([]);
// We want to refocus the trigger button when the user selects // We want to refocus the trigger button when the user selects
// an item from the list so users can continue navigating the // an item from the list so users can continue navigating the
@@ -37,15 +39,30 @@
</Popover.Trigger> </Popover.Trigger>
<Popover.Content class="w-[200px] p-0"> <Popover.Content class="w-[200px] p-0">
<Command.Root> <Command.Root>
<Command.Input placeholder="Search topic..." /> <Command.Input bind:value={search} placeholder="Search topic..." />
<Command.List> <Command.List>
<Command.Empty>No topic found.</Command.Empty> <Command.Empty
>{#if search && !data.topics.filter((t) => t.name?.includes(search)).length}
<form method="post" action="?/createTopic">
<input type="hidden" name="name" value={search} />
<button class="px-4 py-2 rounded bg-secondary">Add Topic</button>
</form>
{:else}No topic found.
{/if}</Command.Empty
>
<Command.Group> <Command.Group>
{#each data.topics as topic} {#each data.topics.filter((t) => !search || t.name?.includes(search)) as topic}
<form
action="?/addTopic"
method="post"
bind:this={addTopicForms[topic.id]}
onsubmit={() => (value = topic.id.toString())}
>
<input type="hidden" name="topic-id" value={topic.id} />
<Command.Item <Command.Item
value={topic.id.toString()} value={topic.id.toString()}
onSelect={() => { onSelect={async () => {
value = topic.id.toString(); addTopicForms[topic.id].submit();
closeAndFocusTrigger(); closeAndFocusTrigger();
}} }}
> >
@@ -54,6 +71,7 @@
/> />
{topic.name} {topic.name}
</Command.Item> </Command.Item>
</form>
{/each} {/each}
</Command.Group> </Command.Group>
</Command.List> </Command.List>