userData: User | null
@@ -128,7 +139,7 @@ export function Admin({ users, todos }: Props) {
- {assignedTodos.length < 1
+ {inProgressTodos.length < 1
? todoItem({
+ id: '',
+ doneAt: null,
description: 'All clear! 🎉',
className: 'text-center',
- hideDone: true,
+ virtual: true,
})
- : assignedTodos.map(todoItem)}
+ : inProgressTodos.map(todoItem)}
+ {doneTodos.length > 0
+ ? (
+
+ +{doneTodos.length} completed todos
+
+
+ {doneTodos.map(todoItem)}
+
+
+
+ )
+ : ''}
)
}
diff --git a/models.ts b/models.ts
index 0204955..b095e11 100644
--- a/models.ts
+++ b/models.ts
@@ -1,8 +1,11 @@
import { z } from 'https://deno.land/x/zod@v3.21.4/mod.ts'
-import { createPentagon } from 'https://deno.land/x/pentagon@v0.1.5/mod.ts'
+import {
+ createPentagon,
+ TableDefinition,
+} from 'https://deno.land/x/pentagon@v0.1.5/mod.ts'
// import { ulid } from 'https://deno.land/x/ulid@v0.3.0/mod.ts'
-const kv = await Deno.openKv('homeman.db')
+export const kv = await Deno.openKv('homeman.db')
// const todos = kv.list({ prefix: ['todos'] })
// const deleteme = []
@@ -41,7 +44,7 @@ const Todo = z.object({
export const TodoModel = Todo
export type Todo = z.infer
-export const db = createPentagon(kv, {
+export const schema: Record = {
users: {
schema: User,
relations: {
@@ -54,7 +57,9 @@ export const db = createPentagon(kv, {
assignee: ['users', User, 'assigneeUserId', 'id'],
},
},
-})
+}
+
+export const db = createPentagon(kv, schema)
// const daddy: User = {
// id: ulid(),
diff --git a/routes/_app.tsx b/routes/_app.tsx
index b41a3ec..bedd5e4 100644
--- a/routes/_app.tsx
+++ b/routes/_app.tsx
@@ -1,5 +1,5 @@
import { type PageProps } from '$fresh/server.ts'
-import { Nav } from '@homeman/components/Nav.tsx'
+import { Nav } from '@homeman/islands/Nav.tsx'
export default function App({ Component }: PageProps) {
return (
diff --git a/routes/admin.tsx b/routes/admin.tsx
index 30ea3a3..c2387ff 100644
--- a/routes/admin.tsx
+++ b/routes/admin.tsx
@@ -4,7 +4,9 @@ import { Admin, Props } from '@homeman/islands/Admin.tsx'
export const handler: Handlers = {
async GET(_req, ctx) {
- const users = await db.users.findMany({})
+ const users = Object.fromEntries((await db.users.findMany({})).map(
+ (u) => [u.id, u],
+ ))
const todos = await db.todos.findMany({})
return ctx.render({ users, todos })
},
diff --git a/routes/api/todo.ts b/routes/api/todo.ts
index c8e52ef..55a9710 100644
--- a/routes/api/todo.ts
+++ b/routes/api/todo.ts
@@ -60,6 +60,7 @@ export const handler: Handlers = {
} else {
data = { id: new URL(req.url).searchParams.get('id') }
}
+ console.log('delete todo data:', data)
const todoData = TodoModel.pick({ id: true }).parse(data)
const result = await db.todos.delete({ where: todoData })
return new Response(JSON.stringify(result))
diff --git a/routes/api/todo/done.ts b/routes/api/todo/done.ts
index f0c200e..45df6c7 100644
--- a/routes/api/todo/done.ts
+++ b/routes/api/todo/done.ts
@@ -3,12 +3,23 @@ import { db, TodoModel } from '@homeman/models.ts'
const Model = TodoModel.pick({ id: true })
+async function markDone(id: string) {
+ const todo = await db.todos.findFirst({ where: { id } })
+ todo.doneAt = new Date()
+ return await db.todos.update({ where: { id }, data: todo })
+}
+
+async function markNotDone(id: string) {
+ return await db.todos.update({ where: { id }, data: { doneAt: null } })
+}
+
export const handler: Handlers = {
- async POST(req, _ctx) {
+ async PUT(req, _ctx) {
const { id } = Model.parse(await req.json())
- const todo = await db.todos.findFirst({ where: { id } })
- todo.doneAt = new Date()
- const newTodo = await db.todos.update({ where: { id }, data: todo })
- return new Response(JSON.stringify(newTodo))
+ return new Response(JSON.stringify(await markDone(id)))
+ },
+ async DELETE(req, _ctx) {
+ const { id } = Model.parse(await req.json())
+ return new Response(JSON.stringify(await markNotDone(id)))
},
}
diff --git a/routes/index.tsx b/routes/index.tsx
index c69798b..ade88c6 100644
--- a/routes/index.tsx
+++ b/routes/index.tsx
@@ -1,12 +1,23 @@
import { Handlers, PageProps } from '$fresh/server.ts'
-import { db, Todo, UserWithTodos } from '@homeman/models.ts'
+import { db, kv, schema, Todo, UserWithTodos } from '@homeman/models.ts'
import Dashboard from '@homeman/islands/Dashboard.tsx'
+import { useSignal } from '@preact/signals'
+import { useEffect } from 'preact/hooks'
interface Data {
users: Record
unassignedTodos: Todo[]
}
+const allTableNames = Object.keys(schema).map((s) => [s])
+async function watcher() {
+ console.log('watching:', allTableNames)
+ for await (const entry of kv.watch(allTableNames)) {
+ console.log('entry:', entry)
+ }
+}
+watcher()
+
export const handler: Handlers = {
async GET(_req, ctx) {
const users = Object.fromEntries(
@@ -22,5 +33,16 @@ export const handler: Handlers = {
}
export default function Home({ data }: PageProps) {
- return
+ const rdata = useSignal(data)
+ useEffect(() => {
+ async function watcher() {
+ console.log('watcher watching...')
+ for await (const entry of kv.watch(allTableNames)) {
+ console.log('entry:', entry)
+ }
+ }
+ watcher().catch(console.error)
+ }, [rdata])
+ console.log('Home rendered')
+ return
}
|