diff --git a/app/(loggedInRoutes)/kanban/layout.tsx b/app/(loggedInRoutes)/kanban/layout.tsx
new file mode 100644
index 00000000..a113d3ad
--- /dev/null
+++ b/app/(loggedInRoutes)/kanban/layout.tsx
@@ -0,0 +1,25 @@
+import { TasksClient } from "@/app/_components/FeatureComponents/Checklists/TasksClient";
+import { getCategories } from "@/app/_server/actions/category";
+import { getCurrentUser } from "@/app/_server/actions/users";
+import { Modes } from "@/app/_types/enums";
+import { sanitizeUserForClient } from "@/app/_utils/user-sanitize-utils";
+
+export default async function KanbanLayout({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ const [checklistCategories, userRecord] = await Promise.all([
+ getCategories(Modes.CHECKLISTS),
+ getCurrentUser(),
+ ]);
+
+ const categories = checklistCategories.data || [];
+ const user = sanitizeUserForClient(userRecord);
+
+ return (
+
- {t('tryAdjustingFiltersChecklist')} + {t("tryAdjustingFiltersChecklist")}
${t( - "checklists.noDescription" - )}
`; - if (!item.description) return noDescText; - const unsanitized = unsanitizeDescription(item.description); - const withLineBreaks = unsanitized.replace(/\n/g, " \n"); - return convertMarkdownToHtml(withLineBreaks) || noDescText; - }, [item.description, t]); - - const findItemInChecklist = ( - checklist: Checklist, - itemId: string - ): Item | null => { - const searchItems = (items: Item[]): Item | null => { - for (const item of items) { - if (item.id === itemId) return item; - if (item.children) { - const found = searchItems(item.children); - if (found) return found; - } - } - return null; - }; - return searchItems(checklist.items); - }; - - const handleSave = async () => { - const sanitizedDescription = sanitizeDescription(editDescription.trim()); - const currentUnsanitized = unsanitizeDescription(item.description || ""); - - if ( - editText.trim() !== item.text || - editDescription.trim() !== currentUnsanitized - ) { - const formData = new FormData(); - formData.append("listId", checklistId); - formData.append("itemId", item.id); - formData.append("text", editText.trim()); - formData.append("description", sanitizedDescription); - formData.append("category", category); - - const result = await updateItem(checklist, formData); - if (result.success && result.data) { - onUpdate(result.data); - const updatedItem = findItemInChecklist(result.data, item.id); - if (updatedItem) { - setItem(updatedItem); - setEditText(updatedItem.text); - setEditDescription( - unsanitizeDescription(updatedItem.description || "") - ); - } - } - } - setIsEditing(false); - }; - - const handleAddSubtask = async () => { - if (!newSubtaskText.trim()) return; - - const formData = new FormData(); - formData.append("listId", checklistId); - formData.append("parentId", item.id); - formData.append("text", newSubtaskText.trim()); - formData.append("category", category); - - const result = await createSubItem(formData); - if (result.success && result.data) { - onUpdate(result.data); - const updatedItem = findItemInChecklist(result.data, item.id); - if (updatedItem) { - setItem(updatedItem); - } - setNewSubtaskText(""); - } - }; - - const handleAddNestedSubtask = async (parentId: string, text: string) => { - const formData = new FormData(); - formData.append("listId", checklistId); - formData.append("parentId", parentId); - formData.append("text", text); - formData.append("category", category); - - const result = await createSubItem(formData); - if (result.success && result.data) { - onUpdate(result.data); - const updatedItem = findItemInChecklist(result.data, item.id); - if (updatedItem) { - setItem(updatedItem); - } - } - }; - - const handleToggleSubtask = async (subtaskId: string, completed: boolean) => { - const formData = new FormData(); - formData.append("listId", checklistId); - formData.append("itemId", subtaskId); - formData.append("completed", completed.toString()); - formData.append("category", category); - - const result = await updateItem(checklist, formData); - if (result.success && result.data) { - onUpdate(result.data); - const updatedItem = findItemInChecklist(result.data, item.id); - if (updatedItem) { - setItem(updatedItem); - } - } - }; - - const handleEditSubtask = async (subtaskId: string, text: string) => { - const formData = new FormData(); - formData.append("listId", checklistId); - formData.append("itemId", subtaskId); - formData.append("text", text); - formData.append("category", category); - - const result = await updateItem(checklist, formData); - if (result.success && result.data) { - onUpdate(result.data); - const updatedItem = findItemInChecklist(result.data, item.id); - if (updatedItem) { - setItem(updatedItem); - } - } - }; - - const handleDeleteSubtask = async (subtaskId: string) => { - const formData = new FormData(); - formData.append("listId", checklistId); - formData.append("itemId", subtaskId); - formData.append("category", category); - - const result = await deleteItem(formData); - if (result.success && result.data) { - onUpdate(result.data); - const updatedItem = findItemInChecklist(result.data, item.id); - if (updatedItem) { - setItem(updatedItem); - } - } - }; - - const handleToggleAll = async (completed: boolean) => { - if (!item.children?.length) return; - - const findTargetItems = (items: Item[]): Item[] => { - const targets: Item[] = []; - - items.forEach((subtask) => { - const shouldToggle = completed ? !subtask.completed : subtask.completed; - if (shouldToggle) { - targets.push(subtask); - } - - if (subtask.children && subtask.children.length > 0) { - targets.push(...findTargetItems(subtask.children)); - } - }); - - return targets; - }; - - const targetItems = findTargetItems(item.children); - if (targetItems.length === 0) return; - - const formData = new FormData(); - formData.append("listId", checklistId); - formData.append("completed", String(completed)); - formData.append("itemIds", JSON.stringify(targetItems.map((t) => t.id))); - formData.append("category", category); - - const result = await bulkToggleItems(formData); - if (result.success && result.data) { - onUpdate(result.data); - const updatedItem = findItemInChecklist(result.data, item.id); - if (updatedItem) { - setItem(updatedItem); - } - } - }; - - const renderMetadata = () => { - const metadata = []; - - if (item.createdBy) { - metadata.push( - t("common.createdByOn", { - user: item.createdBy, - date: formatDateTimeString(item.createdAt!), - }) - ); - } - - if (item.lastModifiedBy) { - metadata.push( - t("common.lastModifiedByOn", { - user: item.lastModifiedBy, - date: formatDateTimeString(item.lastModifiedAt!), - }) - ); - } - - if (item.history?.length) { - metadata.push(t("common.statusChanges", { count: item.history.length })); - } - - return metadata.length ? ( -- • - {text} -
- ))} -