Add todo demo of sql on server.
This commit is contained in:
parent
7c683d9d6f
commit
85e07e993b
File diff suppressed because it is too large
Load Diff
|
@ -40,6 +40,10 @@
|
||||||
"vite": "^5.0.3",
|
"vite": "^5.0.3",
|
||||||
"fast-glob": "^3.3.2",
|
"fast-glob": "^3.3.2",
|
||||||
"openai": "^4.74.0",
|
"openai": "^4.74.0",
|
||||||
"ollama": "^0.5.10"
|
"ollama": "^0.5.10",
|
||||||
|
"zod": "^3.23.8",
|
||||||
|
"@libsql/client": "^0.4.0-pre.5",
|
||||||
|
"drizzle-orm": "^0.29.2",
|
||||||
|
"sveltekit-superforms": "^2.15.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { invalidate } from '$app/navigation';
|
||||||
|
import { todosTable } from '$lib/db/schema';
|
||||||
|
import type { deleteSchema, toggleSchema } from '$lib/zod';
|
||||||
|
import { superForm, type Infer, type SuperValidated } from 'sveltekit-superforms';
|
||||||
|
|
||||||
|
export let todo: typeof todosTable.$inferSelect;
|
||||||
|
export let toggleFormData: SuperValidated<Infer<typeof toggleSchema>>;
|
||||||
|
export let deleteFormData: SuperValidated<Infer<typeof deleteSchema>>;
|
||||||
|
|
||||||
|
const { enhance: toggleEnhance } = superForm(toggleFormData, {
|
||||||
|
onSubmit: ({ formData }) => {
|
||||||
|
formData.set('id', todo.id.toString());
|
||||||
|
formData.set('state', String(todo.completed));
|
||||||
|
},
|
||||||
|
invalidateAll: true
|
||||||
|
});
|
||||||
|
|
||||||
|
const { enhance: deleteEnhance } = superForm(deleteFormData, {
|
||||||
|
onSubmit: ({ formData }) => {
|
||||||
|
formData.set('id', todo.id.toString());
|
||||||
|
},
|
||||||
|
invalidateAll: true
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<li class="flex card justify-between p-4 items-center">
|
||||||
|
<div class="flex gap-4">
|
||||||
|
<button class="btn" form="toggleForm">
|
||||||
|
<i class={`${todo.completed ? 'fa-solid' : 'fa-regular'} fa-circle-check text-2xl`}></i>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div class={`my-auto`}>
|
||||||
|
<h2 class={`h2 ${todo.completed && 'line-through'}`}>{todo.title}</h2>
|
||||||
|
<p class="text-lg">{todo.content}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button class="btn" form="deleteForm"><i class="fa-solid fa-trash text-xl"></i></button>
|
||||||
|
</li>
|
||||||
|
<form class="hidden" action="?/toggle" method="post" use:toggleEnhance id="toggleForm"></form>
|
||||||
|
<form class="hidden" action="?/delete" method="post" use:deleteEnhance id="deleteForm"></form>
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { drizzle } from 'drizzle-orm/libsql';
|
||||||
|
import { createClient } from '@libsql/client';
|
||||||
|
|
||||||
|
const client = createClient({ url: 'file:local.db' });
|
||||||
|
export const db = drizzle(client);
|
|
@ -0,0 +1,8 @@
|
||||||
|
import { sqliteTable, integer, primaryKey, text } from 'drizzle-orm/sqlite-core';
|
||||||
|
|
||||||
|
export const todosTable = sqliteTable('todos', {
|
||||||
|
id: integer('id').primaryKey(),
|
||||||
|
title: text('title').notNull(),
|
||||||
|
content: text('content'),
|
||||||
|
completed: integer('completed', { mode: 'boolean' }).default(false)
|
||||||
|
});
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
export const createSchema = z.object({
|
||||||
|
title: z.string(),
|
||||||
|
content: z.string()
|
||||||
|
});
|
||||||
|
|
||||||
|
export const toggleSchema = z.object({
|
||||||
|
id: z.number(),
|
||||||
|
state: z.boolean()
|
||||||
|
});
|
||||||
|
|
||||||
|
export const deleteSchema = z.object({
|
||||||
|
id: z.number()
|
||||||
|
});
|
|
@ -0,0 +1,64 @@
|
||||||
|
import { db } from '$lib/db/db';
|
||||||
|
import { todosTable } from '$lib/db/schema';
|
||||||
|
// import { desc, eq } from 'drizzle-orm';
|
||||||
|
import type { Actions, PageServerLoad } from './$types';
|
||||||
|
import { fail, superValidate } from 'sveltekit-superforms';
|
||||||
|
import { zod } from 'sveltekit-superforms/adapters';
|
||||||
|
import { createSchema, deleteSchema } from '$lib/zod';
|
||||||
|
|
||||||
|
// export const load: PageServerLoad = async ({ depends }) => {
|
||||||
|
// depends('query:todos');
|
||||||
|
// // const todos = await db.select().from(todosTable).orderBy(desc(todosTable.id));
|
||||||
|
|
||||||
|
// const createForm = await superValidate(zod(createSchema));
|
||||||
|
// // const toggleForm = await superValidate(zod(toggleSchema));
|
||||||
|
// const deleteForm = await superValidate(zod(deleteSchema));
|
||||||
|
|
||||||
|
// return {
|
||||||
|
// todos,
|
||||||
|
// createForm,
|
||||||
|
// // toggleForm,
|
||||||
|
// deleteForm
|
||||||
|
// };
|
||||||
|
// };
|
||||||
|
|
||||||
|
export const actions = {
|
||||||
|
create: async ({ request }) => {
|
||||||
|
const form = await superValidate(request, zod(createSchema));
|
||||||
|
|
||||||
|
if (!form.valid) {
|
||||||
|
return fail(400, { form });
|
||||||
|
}
|
||||||
|
|
||||||
|
await db.insert(todosTable).values({
|
||||||
|
title: form.data.title,
|
||||||
|
content: form.data.content
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// toggle: async ({ request }) => {
|
||||||
|
// const form = await superValidate(request, zod(toggleSchema));
|
||||||
|
|
||||||
|
// if (!form.valid) {
|
||||||
|
// return fail(400, { form });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// await db
|
||||||
|
// .update(todosTable)
|
||||||
|
// .set({
|
||||||
|
// completed: !form.data.state
|
||||||
|
// })
|
||||||
|
// .where(eq(todosTable.id, form.data.id));
|
||||||
|
|
||||||
|
// return { form };
|
||||||
|
// },
|
||||||
|
delete: async ({ request }) => {
|
||||||
|
const form = await superValidate(request, zod(toggleSchema));
|
||||||
|
|
||||||
|
if (!form.valid) {
|
||||||
|
return fail(400, { form });
|
||||||
|
}
|
||||||
|
|
||||||
|
await db.delete(todosTable).where(eq(todosTable.id, form.data.id));
|
||||||
|
return { form };
|
||||||
|
}
|
||||||
|
} satisfies Actions;
|
Loading…
Reference in New Issue