b097d58f13
Manual task input box in TaskList component. Tasks persisted to Honcho as JSON preference on every mutation. Tasks loaded from Honcho on identify (session reconnect).
80 lines
2.6 KiB
TypeScript
80 lines
2.6 KiB
TypeScript
import { useState } from 'react';
|
|
import { Task } from '../hooks/useConversation';
|
|
|
|
interface Props {
|
|
tasks: Task[];
|
|
addTask: (text: string) => void;
|
|
}
|
|
|
|
export default function TaskList({ tasks, addTask }: Props) {
|
|
const [input, setInput] = useState('');
|
|
const pending = tasks.filter((t) => !t.completed);
|
|
const done = tasks.filter((t) => t.completed);
|
|
|
|
const handleSubmit = (e: React.FormEvent) => {
|
|
e.preventDefault();
|
|
if (!input.trim()) return;
|
|
addTask(input.trim());
|
|
setInput('');
|
|
};
|
|
|
|
return (
|
|
<div className="p-3">
|
|
<h3 className="text-sm font-bold text-kira-plum mb-2 flex items-center gap-2">
|
|
<span>✅</span> Tasks
|
|
{pending.length > 0 && (
|
|
<span className="text-xs font-normal bg-kira-pink/30 text-kira-plum px-1.5 py-0.5 rounded-full">
|
|
{pending.length}
|
|
</span>
|
|
)}
|
|
</h3>
|
|
|
|
<form onSubmit={handleSubmit} className="flex gap-1.5 mb-2">
|
|
<input
|
|
type="text"
|
|
value={input}
|
|
onChange={(e) => setInput(e.target.value)}
|
|
placeholder="add a task..."
|
|
className="flex-1 bg-white/30 border border-kira-pink/20 rounded-lg px-2 py-1 text-xs text-kira-plum placeholder:text-kira-plum/30 focus:outline-none focus:border-kira-pink/50"
|
|
/>
|
|
<button
|
|
type="submit"
|
|
className="bg-kira-pink/30 hover:bg-kira-pink/50 text-kira-plum text-xs px-2 py-1 rounded-lg transition-colors"
|
|
>
|
|
+
|
|
</button>
|
|
</form>
|
|
|
|
{tasks.length === 0 && (
|
|
<div className="text-xs text-kira-plum/30 text-center py-2">
|
|
tell Kira or type a task above!
|
|
</div>
|
|
)}
|
|
|
|
{pending.length > 0 && (
|
|
<ul className="space-y-1.5 mb-2">
|
|
{pending.map((t) => (
|
|
<li key={t.id} className="flex items-start gap-2 text-sm text-kira-plum">
|
|
<span className="mt-0.5 shrink-0 w-4 h-4 rounded-full border-2 border-kira-pink/40" />
|
|
<span className="leading-snug">{t.text}</span>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
)}
|
|
|
|
{done.length > 0 && (
|
|
<ul className="space-y-1">
|
|
{done.map((t) => (
|
|
<li key={t.id} className="flex items-start gap-2 text-sm text-kira-plum/40 line-through">
|
|
<span className="mt-0.5 shrink-0 w-4 h-4 rounded-full bg-kira-mint flex items-center justify-center">
|
|
<span className="text-[8px] text-white">✓</span>
|
|
</span>
|
|
<span className="leading-snug">{t.text}</span>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|