+ {/* Header */}
+
+
+
+ {board.name}
+
+
+ {filteredTasks} of {totalTasks} tasks
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* Filters Panel */}
+ {showFilters && (
+
+
+ Filters will be implemented here
+
+
+ )}
+
+ {/* Board Content */}
+
+
+ {filteredBoard.columns.map((column) => (
+
+ {/* Column Header */}
+
+
+
+ {column.title}
+
+
+ {column.tasks.length}
+
+
+
+
+
+ {/* Column Tasks */}
+
+ {column.tasks.map((task) => (
+
handleTaskClick(task)}
+ >
+
+
+
+ {getTypeIcon(task.type)}
+
+
+ {task.priority.toUpperCase()}
+
+
+ {task.assignee_name && (
+
+ {task.assignee_name.charAt(0).toUpperCase()}
+
+ )}
+
+
+
+ {task.title}
+
+
+ {task.description && (
+
+ {task.description}
+
+ )}
+
+
+
+ {task.labels && task.labels.length > 0 && (
+
+ {task.labels.slice(0, 2).map((label, index) => (
+
+ {label}
+
+ ))}
+ {task.labels.length > 2 && (
+
+ +{task.labels.length - 2}
+
+ )}
+
+ )}
+
+
+ {task.story_points && (
+
+ {task.story_points}
+
+ )}
+
+
+ ))}
+
+
+ ))}
+
+
+
+ {/* TODO: Add modals when components are created */}
+ {showCreateModal && (
+
+
+
Create Task
+
+ Task creation modal will be implemented here
+
+
+
+
+
+
+ )}
+
+ {selectedTask && (
+
+
+
{selectedTask.title}
+
+ {selectedTask.description || "No description"}
+
+
+
+ Priority: {selectedTask.priority}
+
+
+ Type: {selectedTask.type}
+
+
+ Status: {selectedTask.status}
+
+
+ Assignee:{" "}
+ {selectedTask.assignee_name || "Unassigned"}
+
+
+
+
+
+
+
+ )}
+
+ );
+};
diff --git a/ui/src/pages/kanban.tsx b/ui/src/pages/kanban.tsx
new file mode 100644
index 0000000..c1745ac
--- /dev/null
+++ b/ui/src/pages/kanban.tsx
@@ -0,0 +1,330 @@
+import React, { useState, useEffect } from "react";
+import { useParams } from "react-router-dom";
+import { KanbanBoard } from "@ui/components/kanban/KanbanBoard";
+import { LoadingSpinner } from "@ui/components/LoadingSpinner";
+import { useTablosList } from "@ui/hooks/tablos";
+import {
+ KanbanBoard as KanbanBoardType,
+ KanbanTask,
+ KanbanColumn,
+ TaskStatus,
+} from "@ui/types/kanban.types";
+import {
+ Select,
+ SelectButton,
+ SelectPopover,
+ SelectListBox,
+ SelectListItem,
+} from "@ui/ui-library/select";
+
+// Mock data for demonstration
+const createMockKanbanBoard = (
+ tabloId: string,
+ tabloName: string
+): KanbanBoardType => {
+ const columns: KanbanColumn[] = [
+ {
+ id: "backlog",
+ title: "Backlog",
+ status: "backlog" as TaskStatus,
+ position: 0,
+ tasks: [
+ {
+ id: "1",
+ title: "Set up project structure",
+ description: "Create the initial project structure and configuration",
+ status: "backlog" as TaskStatus,
+ priority: "medium",
+ type: "task",
+ assignee_id: "user-1",
+ assignee_name: "John Doe",
+ reporter_id: "user-admin",
+ tablo_id: tabloId,
+ tablo_name: tabloName,
+ story_points: 3,
+ labels: ["setup", "infrastructure"],
+ created_at: new Date().toISOString(),
+ updated_at: new Date().toISOString(),
+ position: 0,
+ comments_count: 2,
+ attachments_count: 0,
+ },
+ {
+ id: "2",
+ title: "Design user interface mockups",
+ description:
+ "Create wireframes and mockups for the main user interface",
+ status: "backlog" as TaskStatus,
+ priority: "high",
+ type: "story",
+ assignee_id: "user-2",
+ assignee_name: "Jane Smith",
+ reporter_id: "user-admin",
+ tablo_id: tabloId,
+ tablo_name: tabloName,
+ story_points: 5,
+ labels: ["design", "ui", "mockups"],
+ created_at: new Date().toISOString(),
+ updated_at: new Date().toISOString(),
+ position: 1,
+ comments_count: 0,
+ attachments_count: 1,
+ },
+ ],
+ },
+ {
+ id: "todo",
+ title: "To Do",
+ status: "todo" as TaskStatus,
+ position: 1,
+ tasks: [
+ {
+ id: "3",
+ title: "Implement authentication system",
+ description: "Build login and registration functionality",
+ status: "todo" as TaskStatus,
+ priority: "highest",
+ type: "story",
+ assignee_id: "user-1",
+ assignee_name: "John Doe",
+ reporter_id: "user-admin",
+ tablo_id: tabloId,
+ tablo_name: tabloName,
+ story_points: 8,
+ labels: ["authentication", "security"],
+ created_at: new Date().toISOString(),
+ updated_at: new Date().toISOString(),
+ position: 0,
+ comments_count: 1,
+ attachments_count: 0,
+ },
+ ],
+ },
+ {
+ id: "in_progress",
+ title: "In Progress",
+ status: "in_progress" as TaskStatus,
+ position: 2,
+ tasks: [
+ {
+ id: "4",
+ title: "Fix critical bug in payment processing",
+ description:
+ "Users are unable to complete payments due to a validation error",
+ status: "in_progress" as TaskStatus,
+ priority: "highest",
+ type: "bug",
+ assignee_id: "user-2",
+ assignee_name: "Jane Smith",
+ reporter_id: "user-3",
+ tablo_id: tabloId,
+ tablo_name: tabloName,
+ story_points: 2,
+ labels: ["critical", "payment", "bugfix"],
+ due_date: new Date(Date.now() + 86400000).toISOString(), // Tomorrow
+ created_at: new Date().toISOString(),
+ updated_at: new Date().toISOString(),
+ position: 0,
+ comments_count: 5,
+ attachments_count: 2,
+ },
+ ],
+ },
+ {
+ id: "in_review",
+ title: "In Review",
+ status: "in_review" as TaskStatus,
+ position: 3,
+ tasks: [
+ {
+ id: "5",
+ title: "Add search functionality to dashboard",
+ description:
+ "Implement search and filter capabilities for the main dashboard",
+ status: "in_review" as TaskStatus,
+ priority: "medium",
+ type: "story",
+ assignee_id: "user-1",
+ assignee_name: "John Doe",
+ reporter_id: "user-admin",
+ tablo_id: tabloId,
+ tablo_name: tabloName,
+ story_points: 5,
+ labels: ["search", "dashboard", "enhancement"],
+ created_at: new Date().toISOString(),
+ updated_at: new Date().toISOString(),
+ position: 0,
+ comments_count: 3,
+ attachments_count: 0,
+ },
+ ],
+ },
+ {
+ id: "done",
+ title: "Done",
+ status: "done" as TaskStatus,
+ position: 4,
+ tasks: [
+ {
+ id: "6",
+ title: "Update project documentation",
+ description: "Update README and API documentation",
+ status: "done" as TaskStatus,
+ priority: "low",
+ type: "task",
+ assignee_id: "user-2",
+ assignee_name: "Jane Smith",
+ reporter_id: "user-admin",
+ tablo_id: tabloId,
+ tablo_name: tabloName,
+ story_points: 2,
+ labels: ["documentation"],
+ created_at: new Date().toISOString(),
+ updated_at: new Date().toISOString(),
+ position: 0,
+ comments_count: 1,
+ attachments_count: 0,
+ },
+ ],
+ },
+ ];
+
+ return {
+ id: "kanban-" + tabloId,
+ name: `${tabloName} Kanban Board`,
+ description: "Project task management board",
+ tablo_id: tabloId,
+ columns,
+ created_at: new Date().toISOString(),
+ updated_at: new Date().toISOString(),
+ };
+};
+
+export const KanbanPage: React.FC = () => {
+ const { tablo_id } = useParams();
+ const [selectedTabloId, setSelectedTabloId] = useState