75 lines
1.9 KiB
TypeScript
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>
|
|
)
|
|
}
|