diff --git a/islands/Routine.tsx b/islands/Routine.tsx
index b831018..e3985b1 100644
--- a/islands/Routine.tsx
+++ b/islands/Routine.tsx
@@ -55,38 +55,37 @@ export function Routine(
{taskGroups[currentPhase.value].map((
- { emoji, id, description, doneAt, index }: TaskWithIndex,
- ) => (
- - {
- tasks.value[index].doneAt = tasks.value[index].doneAt
- ? null
- : new Date()
- tasks.value = [...tasks.value]
- if (tasks.value[index].doneAt) {
- fetch('/api/tasks', {
- method: 'POST',
- headers: { 'content-type': 'application/json' },
- body: JSON.stringify({ id: id }),
- })
- excitement()
- } else {
- fetch('/api/tasks', {
- method: 'DELETE',
- headers: { 'content-type': 'application/json' },
- body: JSON.stringify({ id: id }),
- })
- }
- }}
- >
- {emoji ? `${emoji.trim()} ` : ''}
- {description.trim()}
-
- ))}
+ task: TaskWithIndex,
+ ) => {
+ const { emoji, description, doneAt, index } = task
+ return (
+ - {
+ tasks.value[index].doneAt = tasks.value[index].doneAt
+ ? null
+ : new Date()
+ tasks.value = [...tasks.value]
+ if (tasks.value[index].doneAt) {
+ excitement()
+ }
+ await (await fetch('/api/tasks', {
+ method: 'PUT',
+ body: JSON.stringify({
+ ...task,
+ done: !!tasks.value[index].doneAt,
+ }),
+ })).json()
+ }}
+ >
+ {emoji ? `${emoji.trim()} ` : ''}
+ {description.trim()}
+
+ )
+ })}
>
diff --git a/routes/api/tasks.ts b/routes/api/tasks.ts
index 7f0f9e3..b7e73c0 100644
--- a/routes/api/tasks.ts
+++ b/routes/api/tasks.ts
@@ -4,66 +4,37 @@ import { kv } from '@homeman/db.ts'
import { ulid } from 'https://deno.land/x/ulid@v0.3.0/mod.ts'
import { z } from 'https://deno.land/x/zod@v3.21.4/mod.ts'
-const TaskPayload = TaskModel.partial({ id: true })
+const TaskPayload = TaskModel.omit({ doneAt: true }).partial({
+ id: true,
+}).extend({
+ done: z.boolean().optional(),
+})
type TaskPayload = z.infer
async function createOrUpdate(task: TaskPayload) {
- if (!task.id || task.id === '') {
- const newTask: Task = TaskModel.parse({
- ...task,
- id: ulid(),
- })
- const result = await kv.set(['task', newTask.id], newTask)
- await kv.set(['last_task_updated'], newTask.id)
- return result
- } else {
- const newTask: Task = TaskModel.parse(task)
- const result = await kv.set(['task', task.id], newTask)
- await kv.set(['last_task_updated'], newTask.id)
- return result
+ const newTask: Task = TaskModel.parse({
+ ...task,
+ doneAt: task.done ? new Date() : null,
+ })
+ if (!newTask.id || newTask.id === '') {
+ newTask.id = ulid()
}
+ const result = await kv.set(['task', newTask.id], newTask)
+ await kv.set(['last_task_updated'], newTask.id)
+ return result
}
export const handler: Handlers = {
async POST(req, _ctx) {
- if (req.headers.get('content-type')?.includes('json')) {
- const result = await createOrUpdate(
- TaskPayload.parse(await req.json()),
- )
- return new Response(JSON.stringify(result))
- } else {
- const form = await req.formData()
- const id = form.get('id')?.toString() || undefined
-
- const doneAt = form.get('doneAt')
- console.log('task POST doneAt:', doneAt)
-
- const task = TaskPayload.parse({
- id: id,
- emoji: form.get('emoji')?.toString() || null,
- doneAt: form.get('doneAt')?.toString() || null,
- description: form.get('description')?.toString(),
- phase: form.get('phase')?.toString() || null,
- })
-
- if (!id) {
- delete task.id
- }
-
- await createOrUpdate(task)
-
- const url = new URL(req.url)
- url.pathname = '/'
- return Response.redirect(url, 303)
- }
+ const result = await createOrUpdate(
+ TaskPayload.parse(await req.json()),
+ )
+ return new Response(JSON.stringify(result))
},
async PUT(req, _ctx) {
- if (req.headers.get('content-type')?.includes('json')) {
- const result = await createOrUpdate(
- TaskPayload.parse(await req.json()),
- )
- return new Response(JSON.stringify(result))
- }
+ const t = TaskPayload.parse(await req.json())
+ const result = await createOrUpdate(t)
+ return new Response(JSON.stringify(result))
},
async DELETE(req, _ctx) {
// task: form or query params or json