homeman-deno/islands/TodoList.tsx
2024-01-11 18:57:29 -06:00

75 lines
1.9 KiB
TypeScript

import { Todo, UserWithTodos } from '@homeman/models.ts'
import { JSX } from 'preact'
import { Button } from '@homeman/components/Button.tsx'
import { Avatar } from '@homeman/components/Avatar.tsx'
export interface Props {
user: UserWithTodos
onNewButtonClicked: JSX.MouseEventHandler<HTMLButtonElement>
}
export function TodoList(
{ onNewButtonClicked, user: { avatarUrl, assignedTodos, name, color } }:
Props,
) {
const todoItem = (
{ id, doneAt, className, description, hideDone }:
& Pick<Todo, 'description' | 'id' | 'doneAt'>
& {
className?: string
hideDone?: boolean
},
) => (
<li
style={`border-color: #${color}`}
class={`${className || ''} ${
hideDone ? '' : 'border-l-4'
} p-4 rounded drop-shadow-lg bg-white dark:bg-stone-900 flex flex-col gap-2`}
>
{JSON.stringify(doneAt)}
<span class='text-xl'>{description}</span>
{(hideDone || doneAt != null) ? '' : (
<Button
onClick={async () => {
await fetch('/api/todo/done', {
method: 'POST',
body: JSON.stringify({ id }),
})
// TODO: remove the todoitem?
// TODO: confetti
}}
>
Done
</Button>
)}
</li>
)
return (
<div class='p-2 w-1/4 min-w-[15rem] relative flex flex-col grow-0'>
<Avatar
className='mb-2'
src={avatarUrl != null ? avatarUrl : 'https://placehold.co/512x512'}
title={`${name}'s avatar`}
/>
<span style={`color: #${color};`} class='font-semibold text-center'>
{name}
</span>
<button
class='mt-4 mb-4 text-left w-full px-2 py-1 rounded-lg border-[1px] text-stone-500 border-stone-500 opacity-50 hover:opacity-100'
onClick={onNewButtonClicked}
>
+ New
</button>
<ul class='flex flex-col gap-y-4'>
{assignedTodos.length < 1
? todoItem({
description: 'All clear! 🎉',
className: 'text-center',
hideDone: true,
})
: assignedTodos.map(todoItem)}
</ul>
</div>
)
}