Tasks work

This commit is contained in:
Daniel Flanagan 2024-01-21 20:10:46 -06:00
parent 6529cb3810
commit 2aaeb1ac7f
Signed by: lytedev
GPG key ID: 5B2020A0F9921EF4
2 changed files with 52 additions and 82 deletions

View file

@ -55,38 +55,37 @@ export function Routine(
<main class='flex flex-col overflow-x-scroll'> <main class='flex flex-col overflow-x-scroll'>
<ul> <ul>
{taskGroups[currentPhase.value].map(( {taskGroups[currentPhase.value].map((
{ emoji, id, description, doneAt, index }: TaskWithIndex, task: TaskWithIndex,
) => ( ) => {
const { emoji, description, doneAt, index } = task
return (
<li <li
role='button' role='button'
class={`text-lg cursor-pointer p-4 hover:bg-gray-500/20 ${ class={`text-lg cursor-pointer p-4 hover:bg-gray-500/20 ${
doneAt ? 'line-through opacity-30 hover:bg-gray-500' : '' doneAt ? 'line-through opacity-30 hover:bg-gray-500' : ''
}`} }`}
onClick={() => { onClick={async () => {
tasks.value[index].doneAt = tasks.value[index].doneAt tasks.value[index].doneAt = tasks.value[index].doneAt
? null ? null
: new Date() : new Date()
tasks.value = [...tasks.value] tasks.value = [...tasks.value]
if (tasks.value[index].doneAt) { if (tasks.value[index].doneAt) {
fetch('/api/tasks', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ id: id }),
})
excitement() excitement()
} else {
fetch('/api/tasks', {
method: 'DELETE',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ id: id }),
})
} }
await (await fetch('/api/tasks', {
method: 'PUT',
body: JSON.stringify({
...task,
done: !!tasks.value[index].doneAt,
}),
})).json()
}} }}
> >
{emoji ? `${emoji.trim()} ` : ''} {emoji ? `${emoji.trim()} ` : ''}
{description.trim()} {description.trim()}
</li> </li>
))} )
})}
</ul> </ul>
</main> </main>
</> </>

View file

@ -4,66 +4,37 @@ import { kv } from '@homeman/db.ts'
import { ulid } from 'https://deno.land/x/ulid@v0.3.0/mod.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' 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<typeof TaskPayload> type TaskPayload = z.infer<typeof TaskPayload>
async function createOrUpdate(task: TaskPayload) { async function createOrUpdate(task: TaskPayload) {
if (!task.id || task.id === '') {
const newTask: Task = TaskModel.parse({ const newTask: Task = TaskModel.parse({
...task, ...task,
id: ulid(), doneAt: task.done ? new Date() : null,
}) })
if (!newTask.id || newTask.id === '') {
newTask.id = ulid()
}
const result = await kv.set(['task', newTask.id], newTask) const result = await kv.set(['task', newTask.id], newTask)
await kv.set(['last_task_updated'], newTask.id) await kv.set(['last_task_updated'], newTask.id)
return result 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
}
} }
export const handler: Handlers<Task | null> = { export const handler: Handlers<Task | null> = {
async POST(req, _ctx) { async POST(req, _ctx) {
if (req.headers.get('content-type')?.includes('json')) {
const result = await createOrUpdate( const result = await createOrUpdate(
TaskPayload.parse(await req.json()), TaskPayload.parse(await req.json()),
) )
return new Response(JSON.stringify(result)) 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)
}
}, },
async PUT(req, _ctx) { async PUT(req, _ctx) {
if (req.headers.get('content-type')?.includes('json')) { const t = TaskPayload.parse(await req.json())
const result = await createOrUpdate( const result = await createOrUpdate(t)
TaskPayload.parse(await req.json()),
)
return new Response(JSON.stringify(result)) return new Response(JSON.stringify(result))
}
}, },
async DELETE(req, _ctx) { async DELETE(req, _ctx) {
// task: form or query params or json // task: form or query params or json