Skip to content

Commit 6091099

Browse files
authored
Merge pull request #380 from CodebilityDev/miguel/fix-kanban-loading-and-params
Miguel/fix kanban loading and params
2 parents 3209a74 + 2ca5031 commit 6091099

2 files changed

Lines changed: 72 additions & 50 deletions

File tree

‎apps/codebility/app/home/kanban/[projectId]/[id]/loading.tsx‎

Lines changed: 53 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
21
import { Card, CardContent } from "@/components/ui/card";
2+
import { IconSearch } from "@/public/assets/svgs";
3+
import { Plus, Users } from "lucide-react";
4+
35
import { Button } from "@codevs/ui/button";
46
import { CardHeader } from "@codevs/ui/card";
57
import { Input } from "@codevs/ui/input";
68
import { Skeleton } from "@codevs/ui/skeleton";
7-
import { IconSearch } from "@/public/assets/svgs";
8-
import { Plus, Users } from "lucide-react"
99

1010
export default function KanbanLoadingSkeleton() {
1111
return (
@@ -32,9 +32,9 @@ export default function KanbanLoadingSkeleton() {
3232
<div className="flex items-center">
3333
<div className="flex space-x-2">
3434
{Array.from({ length: 6 }).map((_, i) => (
35-
<Skeleton
36-
key={i}
37-
className="h-8 w-8 rounded-full bg-gray-700 dark:bg-gray-300"
35+
<Skeleton
36+
key={i}
37+
className="h-8 w-8 rounded-full bg-gray-700 dark:bg-gray-300"
3838
style={{ zIndex: 6 - i }}
3939
/>
4040
))}
@@ -51,13 +51,19 @@ export default function KanbanLoadingSkeleton() {
5151

5252
{/* Action buttons */}
5353
<div className="flex items-center justify-center gap-2 md:justify-start">
54-
<Button disabled className="flex w-max items-center gap-2 text-sm md:text-base">
55-
<Plus className="w-4 h-4" />
54+
<Button
55+
disabled
56+
className="flex w-max items-center gap-2 text-sm md:text-base"
57+
>
58+
<Plus className="h-4 w-4" />
5659
Add column
5760
</Button>
5861

59-
<Button disabled className="flex w-max items-center gap-2 text-sm md:text-base">
60-
<Plus className="w-4 h-4" />
62+
<Button
63+
disabled
64+
className="flex w-max items-center gap-2 text-sm md:text-base"
65+
>
66+
<Plus className="h-4 w-4" />
6167
Add Members
6268
</Button>
6369
</div>
@@ -67,7 +73,7 @@ export default function KanbanLoadingSkeleton() {
6773
{/* Kanban Columns */}
6874
<div className="text-dark100_light900 flex h-full">
6975
<div className="overflow-x-auto overflow-y-hidden">
70-
<div className="flex flex-wrap min-h-[calc(100vh-12rem)] w-full gap-4 p-2 md:p-4">
76+
<div className="flex min-h-[calc(100vh-12rem)] w-full flex-wrap gap-4 p-2 md:p-4">
7177
{/* Column 1 */}
7278
<KanbanColumnSkeleton title="Todo" cardCount={3} />
7379

@@ -85,20 +91,28 @@ export default function KanbanLoadingSkeleton() {
8591
</div>
8692
</div>
8793
</div>
88-
)
94+
);
8995
}
9096

91-
function KanbanColumnSkeleton({ title, cardCount }: { title: string; cardCount: number }) {
97+
function KanbanColumnSkeleton({
98+
title,
99+
cardCount,
100+
}: {
101+
title: string;
102+
cardCount: number;
103+
}) {
92104
return (
93-
<div className="
105+
<div
106+
className="
94107
relative flex h-full
95108
w-[calc(100vw-2rem)] min-w-[280px]
96109
flex-col overflow-hidden
97110
rounded-md border-2 border-zinc-200
98-
md:w-[350px] md:min-w-[350px]
99-
lg:w-[400px] lg:min-w-[400px]
100-
bg-[#FCFCFC] dark:border-zinc-700 dark:bg-[#2C303A]
101-
">
111+
bg-[#FCFCFC] dark:border-zinc-700
112+
dark:bg-[#2C303A] md:w-[350px]
113+
md:min-w-[350px] lg:w-[400px] lg:min-w-[400px]
114+
"
115+
>
102116
{/* Column Header */}
103117
<div className="flex items-center justify-between p-2 font-bold dark:bg-[#1E1F26] md:p-3">
104118
<div className="flex items-center gap-2 text-gray-800 dark:text-gray-200 md:gap-3">
@@ -120,33 +134,35 @@ function KanbanColumnSkeleton({ title, cardCount }: { title: string; cardCount:
120134
))}
121135

122136
{/* Add card button skeleton */}
123-
<div className="flex items-center gap-2 p-3 text-gray-500 hover:text-gray-300 cursor-pointer">
124-
<Plus className="w-4 h-4" />
137+
<div className="flex cursor-pointer items-center gap-2 p-3 text-gray-500 hover:text-gray-300">
138+
<Plus className="h-4 w-4" />
125139
<span className="text-sm">Add a card</span>
126140
</div>
127141
</div>
128142
</div>
129143
</div>
130-
)
144+
);
131145
}
132146

133147
function KanbanCardSkeleton() {
134148
return (
135-
<div className="
136-
group relative cursor-pointer overflow-hidden
137-
rounded-lg border border-gray-200 bg-white p-3 shadow-sm
138-
transition-all duration-200 ease-in-out
139-
hover:shadow-lg hover:ring-2 hover:ring-customBlue-200 hover:ring-offset-2
149+
<div
150+
className="
151+
hover:ring-customBlue-200 group relative cursor-pointer
152+
overflow-hidden rounded-lg border border-gray-200 bg-white p-3
153+
shadow-sm transition-all duration-200
154+
ease-in-out hover:shadow-lg hover:ring-2 hover:ring-offset-2
140155
dark:border-gray-700 dark:bg-[#1E1F26]
141156
md:p-4
142-
">
157+
"
158+
>
143159
{/* Priority Indicator Bar */}
144-
<div className="absolute top-0 left-0 w-1 h-full rounded-l-lg bg-orange-500" />
160+
<div className="absolute left-0 top-0 h-full w-1 rounded-l-lg bg-orange-500" />
145161

146162
{/* Task Header */}
147-
<div className="flex items-center justify-between mb-3">
163+
<div className="mb-3 flex items-center justify-between">
148164
<Skeleton className="h-5 w-3/4 bg-gray-300 dark:bg-gray-600" />
149-
165+
150166
{/* Primary Avatar */}
151167
<div className="flex h-6 w-6 items-center justify-center overflow-hidden rounded-full border-2 border-white shadow-md dark:border-gray-800 md:h-8 md:w-8">
152168
<Skeleton className="h-full w-full rounded-full bg-gray-300 dark:bg-gray-600" />
@@ -157,7 +173,9 @@ function KanbanCardSkeleton() {
157173
{/* Priority and Status */}
158174
<div className="flex items-center justify-between text-xs md:text-sm">
159175
<div className="flex items-center gap-1">
160-
<span className="capitalize text-gray-600 dark:text-gray-400">Medium</span>
176+
<span className="capitalize text-gray-600 dark:text-gray-400">
177+
Medium
178+
</span>
161179
<Skeleton className="h-3 w-3 bg-gray-300 dark:bg-gray-600 md:h-4 md:w-4" />
162180
</div>
163181
</div>
@@ -170,13 +188,13 @@ function KanbanCardSkeleton() {
170188
{/* Sidekick avatars */}
171189
<div className="flex -space-x-1.5 pt-1 md:-space-x-2 md:pt-2">
172190
{Array.from({ length: 3 }).map((_, i) => (
173-
<Skeleton
174-
key={i}
175-
className="h-5 w-5 rounded-full border-2 border-white bg-gray-300 dark:border-gray-800 dark:bg-gray-600 md:h-7 md:w-7"
191+
<Skeleton
192+
key={i}
193+
className="h-5 w-5 rounded-full border-2 border-white bg-gray-300 dark:border-gray-800 dark:bg-gray-600 md:h-7 md:w-7"
176194
/>
177195
))}
178196
</div>
179197
</div>
180198
</div>
181-
)
199+
);
182200
}

‎apps/codebility/app/home/kanban/[projectId]/[id]/page.tsx‎

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
"use client";
22

3-
import { useEffect, useMemo, useState } from "react";
3+
import { use, useEffect, useMemo, useState } from "react";
44
import { useKanbanStore } from "@/store/kanban-store";
55
import { KanbanBoardType, KanbanColumnType, Task } from "@/types/home/codev";
66

77
import KanbanBoard from "./_components/KanbanBoard";
8+
import KanbanLoadingSkeleton from "./loading";
89

910
interface KanbanBoardPageProps {
10-
params: { id: string; projectId: string };
11-
searchParams?: { query?: string };
11+
params: Promise<{ id: string; projectId: string }>;
12+
searchParams?: Promise<{ query?: string }>;
1213
}
1314

1415
// Mapping functions to convert raw data into our expected types.
@@ -46,24 +47,29 @@ const mapColumn = (column: any): KanbanColumnType => ({
4647
: [],
4748
});
4849

49-
export default function KanbanBoardPage({
50-
params,
51-
searchParams,
52-
}: KanbanBoardPageProps) {
50+
export default function KanbanBoardPage(props: KanbanBoardPageProps) {
5351
const { boardData, fetchBoardData, setBoardId } = useKanbanStore();
5452
const [loading, setLoading] = useState(true);
5553

54+
// ✅ unwrap params and searchParams
55+
const { id, projectId } = use(props.params);
56+
const searchParams = props.searchParams ? use(props.searchParams) : {};
5657
const query = searchParams?.query?.toLowerCase() || "";
5758

5859
useEffect(() => {
5960
const loadData = async () => {
6061
setLoading(true);
61-
await setBoardId(params.id);
62-
await fetchBoardData();
63-
setLoading(false);
62+
try {
63+
setBoardId(id);
64+
await fetchBoardData();
65+
} catch (err) {
66+
console.error("Failed to load board data:", err);
67+
} finally {
68+
setLoading(false);
69+
}
6470
};
6571
loadData();
66-
}, [params.id, fetchBoardData]);
72+
}, [id, fetchBoardData, setBoardId]);
6773

6874
const processedBoardData = useMemo(() => {
6975
if (!boardData) return null;
@@ -96,14 +102,12 @@ export default function KanbanBoardPage({
96102
}, [boardData, query]);
97103

98104
if (loading) {
99-
return <div>Loading board...</div>;
105+
return <KanbanLoadingSkeleton />;
100106
}
101107

102108
if (!processedBoardData) {
103109
return <div>Board not found</div>;
104110
}
105111

106-
return (
107-
<KanbanBoard projectId={params.projectId} boardData={processedBoardData} />
108-
);
112+
return <KanbanBoard projectId={projectId} boardData={processedBoardData} />;
109113
}

0 commit comments

Comments
 (0)