feat: add task comments feature with CRUD operations
- Introduced a new `task_comments` table in the database schema. - Implemented task comments API endpoints for listing, creating, and deleting comments. - Enhanced the task detail dialog to display comments and allow users to add new comments. - Updated task row component to handle click events for viewing task details. - Added a theme provider to manage light/dark mode across the application. - Refactored Milkdown editor to use Crepe for improved markdown editing experience. - Updated global styles to accommodate new editor and theme changes. - Enhanced task filtering and sorting functionality in the tasks page.
This commit is contained in:
@@ -23,6 +23,7 @@ import {
|
||||
import { Empty, EmptyHeader, EmptyMedia, EmptyTitle, EmptyDescription } from '@/components/ui/empty';
|
||||
import { NewTaskDialog } from '@/components/tasks/NewTaskDialog';
|
||||
import { EditTaskDialog } from '@/components/tasks/EditTaskDialog';
|
||||
import { TaskDetailDialog } from '@/components/tasks/TaskDetailDialog';
|
||||
import { TaskRow, type TaskItem } from '@/components/tasks/TaskRow';
|
||||
|
||||
export const Route = createFileRoute('/tasks')({
|
||||
@@ -42,9 +43,10 @@ function TasksPage() {
|
||||
const [search, setSearch] = useState('');
|
||||
const [debouncedSearch, setDebouncedSearch] = useState('');
|
||||
const [statusFilter, setStatusFilter] = useState<StatusFilter>('all');
|
||||
const [orderBy, setOrderBy] = useState<OrderBy>('createdAt');
|
||||
const [orderBy, setOrderBy] = useState<OrderBy>('dueDate');
|
||||
const [dialogOpen, setDialogOpen] = useState(false);
|
||||
const [editTask, setEditTask] = useState<TaskItem | null>(null);
|
||||
const [viewTask, setViewTask] = useState<TaskItem | null>(null);
|
||||
|
||||
const debounceTimer = useMemo(() => ({ id: null as ReturnType<typeof setTimeout> | null }), []);
|
||||
|
||||
@@ -127,7 +129,7 @@ function TasksPage() {
|
||||
<ItemDescription>To Do</ItemDescription>
|
||||
</ItemContent>
|
||||
</Item>
|
||||
<Item variant="muted" className="bg-sky-50">
|
||||
<Item variant="muted" className="bg-sky-50 dark:bg-sky-950/30">
|
||||
<ItemMedia variant="icon">
|
||||
<Loader2 />
|
||||
</ItemMedia>
|
||||
@@ -136,7 +138,7 @@ function TasksPage() {
|
||||
<ItemDescription>In Progress</ItemDescription>
|
||||
</ItemContent>
|
||||
</Item>
|
||||
<Item variant="muted" className="bg-green-50">
|
||||
<Item variant="muted" className="bg-green-50 dark:bg-green-950/30">
|
||||
<ItemMedia variant="icon">
|
||||
<CheckCircle2 />
|
||||
</ItemMedia>
|
||||
@@ -211,6 +213,7 @@ function TasksPage() {
|
||||
onToggle={handleCheckboxToggle}
|
||||
onEdit={setEditTask}
|
||||
onDelete={(id) => deleteTask.mutate({ id })}
|
||||
onClick={setViewTask}
|
||||
/>
|
||||
))
|
||||
)}
|
||||
@@ -222,6 +225,13 @@ function TasksPage() {
|
||||
open={!!editTask}
|
||||
onOpenChange={(open: boolean) => { if (!open) setEditTask(null); }}
|
||||
/>
|
||||
<TaskDetailDialog
|
||||
task={viewTask}
|
||||
open={!!viewTask}
|
||||
onOpenChange={(open) => { if (!open) setViewTask(null); }}
|
||||
onEdit={(task) => { setViewTask(null); setEditTask(task); }}
|
||||
onDelete={(id) => { deleteTask.mutate({ id }); setViewTask(null); }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user