Skip to content

Commit 5404969

Browse files
committed
Merge branch 'dev' of https://github.com/CodebilityDev/codebility-plus into task-#CBP-57
2 parents 6f83f4a + b5ef898 commit 5404969

7 files changed

Lines changed: 931 additions & 247 deletions

File tree

‎apps/codebility/app/(marketing)/profiles/_components/CodevContainer.tsx‎

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
"use client";
2-
32
import { fadeInOutDownToUp } from "@/components/FramerAnimation/Framer";
43
import H2 from "@/components/shared/home/H2";
54
import Heading3 from "@/components/shared/home/Heading3";
65
import IntroText from "@/components/shared/home/IntroText";
7-
import { Codev } from "@/types/home/codev";
86
import { motion } from "framer-motion";
97

108
export default function CodevContainer() {
@@ -24,15 +22,17 @@ export default function CodevContainer() {
2422
whileInView="visible"
2523
className="relative z-10 mx-auto max-w-[700px] rounded-2xl border border-white/10 bg-white/5 p-6 text-center shadow-xl backdrop-blur-sm"
2624
>
27-
<Heading3 className="mb-4 text-white">
28-
Meet Our Skilled Developer Network
29-
</Heading3>
30-
<IntroText className="text-gray-200">
31-
Discover our carefully vetted CoDevs ready to join your team. Each
32-
developer brings proven expertise, strong communication skills, and a
33-
passion for delivering exceptional results on your projects.
34-
</IntroText>
25+
<div className="mb-4 text-white">
26+
<Heading3>Meet Our Skilled Team Network</Heading3>
27+
</div>
28+
<div className="text-gray-200">
29+
<IntroText>
30+
Discover our carefully vetted professionals, ready to join your team
31+
and deliver exceptional results. Every member brings proven expertise,
32+
strong communication, and a passion for getting things done right.
33+
</IntroText>
34+
</div>
3535
</motion.div>
3636
</div>
3737
);
38-
}
38+
}

‎apps/codebility/app/globals.css‎

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,11 @@
103103
--card-foreground: 240 10% 3.9%;
104104
--popover: 0 0% 100%;
105105
--popover-foreground: 240 10% 3.9%;
106-
--primary: 2, 255, 226, 100%;
107-
--primary-foreground: 355.7 100% 97.3%;
106+
107+
/* ✅ Fix primary - use proper HSL. Based on your teal/cyan brand color */
108+
--primary: 174 100% 50%; /* was: 2, 255, 226, 100% (broken RGBA) */
109+
--primary-foreground: 174 100% 10%;
110+
108111
--secondary: 240 4.8% 95.9%;
109112
--secondary-foreground: 240 5.9% 10%;
110113
--muted: 240 4.8% 95.9%;
@@ -115,19 +118,25 @@
115118
--destructive-foreground: 0 0% 98%;
116119
--border: 240 5.9% 90%;
117120
--input: 240 5.9% 90%;
118-
--ring: 142.1 76.2% 36.3%;
121+
--ring: 174 100% 36%;
119122
--radius: 0.5rem;
120-
--text-color-1: var(--primary);
123+
124+
/* Custom text colors - keep as is, these are fine */
121125
--text-color-2: 234, 84%, 68%;
122126
--text-color-3: 285, 99%, 51%;
123127
--text-color-4: 266, 100%, 64%;
128+
129+
/* ✅ Add these missing light-mode specific vars */
130+
--kanban-column-title: 240 10% 10%; /* dark text for column headers */
131+
--kanban-column-bg: 240 5% 96%; /* light gray column background */
132+
--sidebar-icon: 240 10% 25%; /* visible dark icons in light mode */
133+
--drag-handle: 240 5% 60%; /* drag grip icon */
134+
--card-shadow: 0 1px 3px rgba(0,0,0,0.1);
135+
124136
--muted-figma: 252, 252, 252, 100%;
125137
--card-clients: 246, 246, 246, 100%;
126-
127138
--violet-color: theme("colors.violet.500");
128-
129139
--teal-color: theme("colors.customTeal");
130-
131140
--blue-500: theme("colors.blue.500");
132141
--blue-100: theme("colors.blue.100");
133142
--white: theme("colors.white");
@@ -146,9 +155,11 @@
146155
--card-foreground: 0 0% 95%;
147156
--popover: 0 0% 9%;
148157
--popover-foreground: 0 0% 95%;
149-
--primary:
150-
2, 255, 226, 100%; /* Please check, not sure if this is for hsl or rgba */
151-
--primary-foreground: 144.9 80.4% 10%;
158+
159+
/* ✅ Same fix for dark mode primary */
160+
--primary: 174 100% 50%;
161+
--primary-foreground: 174 100% 10%;
162+
152163
--secondary: 240 3.7% 15.9%;
153164
--secondary-foreground: 0 0% 98%;
154165
--muted: 0 0% 15%;
@@ -159,11 +170,18 @@
159170
--destructive-foreground: 0 85.7% 97.3%;
160171
--border: 240 3.7% 15.9%;
161172
--input: 240 3.7% 15.9%;
162-
--ring: 142.4 71.8% 29.2%;
163-
--text-color-1: var(--primary);
173+
--ring: 174 71.8% 29.2%;
174+
164175
--text-color-2: 234, 84%, 68%;
165176
--text-color-3: 285, 99%, 51%;
166177
--text-color-4: 266, 100%, 64%;
178+
179+
/* ✅ Dark mode counterparts */
180+
--kanban-column-title: 0 0% 95%;
181+
--kanban-column-bg: 240 3.7% 12%;
182+
--sidebar-icon: 0 0% 90%;
183+
--drag-handle: 0 0% 60%;
184+
167185
--muted-figma: 24, 24, 24, 25%;
168186
--card-clients: 19, 19, 19, 100%;
169187

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

Lines changed: 22 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { useUserStore } from "@/store/codev-store";
1010
import { KanbanBoardType, KanbanColumnType } from "@/types/home/codev";
1111
import { useQuery } from "@tanstack/react-query";
1212
import toast from "react-hot-toast";
13+
import { Archive } from "lucide-react";
1314

1415
import { Button } from "@codevs/ui/button";
1516

@@ -27,47 +28,29 @@ interface KanbanBoardProps {
2728
projectId: string;
2829
}
2930

30-
/**
31-
* Enhanced KanbanBoard component with three-level breadcrumb navigation
32-
* and draft task card counter badge
33-
*
34-
* Features:
35-
* - Three-level breadcrumb navigation
36-
* - Draft task counter badge (CBP-16)
37-
* - Archive toggle
38-
* - Task filtering by user
39-
* - Responsive design
40-
*
41-
* Follows KISS, YAGNI, DRY, and SOLID principles
42-
*/
4331
function KanbanBoard({ boardData, projectId }: KanbanBoardProps) {
4432
const user = useUserStore((state) => state.user);
4533

46-
// Sync the Kanban task modal with the URL ?taskId param
4734
useKanbanTaskUrlModal(boardData);
4835

49-
// User permissions - simple boolean checks following YAGNI principle
5036
const canAddColumn = user?.role_id === 1 || user?.role_id === 5;
5137
const canAddMember = canAddColumn;
5238

53-
// Component state - minimal and focused
5439
const [activeFilter, setActiveFilter] = useState<string | null>(null);
5540
const [showArchive, setShowArchive] = useState(false);
5641
const [draftCount, setDraftCount] = useState<number>(0);
5742

58-
// Fetch project members using React Query for caching and optimization
5943
const { data: allMembers = [], isLoading: isMembersLoading } = useQuery({
6044
queryKey: ["members", projectId],
6145
queryFn: async () => {
6246
const result = await getMembers(projectId);
6347
return result.data || [];
6448
},
6549
enabled: !!projectId,
66-
staleTime: 5 * 60 * 1000, // 5 minutes cache
50+
staleTime: 5 * 60 * 1000,
6751
refetchOnWindowFocus: false,
6852
});
6953

70-
// Transform members data using useMemo for performance optimization
7154
const members = useMemo(
7255
() =>
7356
allMembers.map((user) => ({
@@ -79,32 +62,24 @@ function KanbanBoard({ boardData, projectId }: KanbanBoardProps) {
7962
[allMembers, activeFilter],
8063
);
8164

82-
// Load draft count when component mounts or user/project changes
8365
useEffect(() => {
8466
if (user?.id && projectId) {
8567
loadDraftCount();
8668
}
8769
}, [user?.id, projectId]);
8870

89-
/**
90-
* Fetch the number of draft task cards for the current user
91-
* Updates the draftCount state for badge display
92-
*/
9371
const loadDraftCount = async () => {
9472
if (!user?.id || !projectId) return;
95-
9673
const result = await getDraftCount(projectId, user.id);
9774
if (result.success && result.count !== undefined) {
9875
setDraftCount(result.count);
9976
}
10077
};
10178

102-
// Filter handler using useCallback to prevent unnecessary re-renders
10379
const handleFilterClick = useCallback((userId: string) => {
10480
setActiveFilter((prev) => (prev === userId ? null : userId));
10581
}, []);
10682

107-
// Early return for missing data - fail fast principle
10883
if (!boardData) {
10984
return (
11085
<div className="text-center text-red-500">Board data not found.</div>
@@ -120,12 +95,11 @@ function KanbanBoard({ boardData, projectId }: KanbanBoardProps) {
12095
className="flex flex-row items-center gap-3 text-sm"
12196
aria-label="Breadcrumb"
12297
>
123-
{/* Level 1: Kanban Board Overview */}
12498
<Link
12599
href={pathsConfig.app.kanban}
126100
className="group transition-colors duration-200"
127101
>
128-
<span className="group-hover:text-customBlue-600 dark:group-hover:text-customBlue-400 text-gray-500 dark:text-gray-400">
102+
<span className="text-gray-500 group-hover:text-customBlue-600 dark:text-gray-400 dark:group-hover:text-customBlue-400">
129103
📋 Kanban Board
130104
</span>
131105
</Link>
@@ -135,12 +109,11 @@ function KanbanBoard({ boardData, projectId }: KanbanBoardProps) {
135109
aria-hidden="true"
136110
/>
137111

138-
{/* Level 2: Project Sprint */}
139112
<Link
140113
href={`${pathsConfig.app.kanban}/${projectId}`}
141114
className="group transition-colors duration-200"
142115
>
143-
<span className="group-hover:text-customBlue-600 dark:group-hover:text-customBlue-400 text-gray-500 dark:text-gray-400">
116+
<span className="text-gray-500 group-hover:text-customBlue-600 dark:text-gray-400 dark:group-hover:text-customBlue-400">
144117
Kanban Sprint
145118
</span>
146119
</Link>
@@ -150,9 +123,8 @@ function KanbanBoard({ boardData, projectId }: KanbanBoardProps) {
150123
aria-hidden="true"
151124
/>
152125

153-
{/* Level 3: Current Board Name */}
154126
<span
155-
className="to-customBlue-600 bg-gradient-to-r from-purple-600 bg-clip-text font-semibold text-gray-900 text-transparent dark:text-white"
127+
className="bg-gradient-to-r from-purple-600 to-customBlue-600 bg-clip-text font-semibold text-transparent"
156128
aria-current="page"
157129
>
158130
{boardData.name}
@@ -168,7 +140,7 @@ function KanbanBoard({ boardData, projectId }: KanbanBoardProps) {
168140
</span>
169141
</div>
170142
<div>
171-
<h1 className="to-customBlue-600 bg-gradient-to-r from-purple-600 bg-clip-text text-2xl font-bold text-transparent drop-shadow-sm md:text-3xl">
143+
<h1 className="bg-gradient-to-r from-purple-600 to-customBlue-600 bg-clip-text text-2xl font-bold text-transparent drop-shadow-sm md:text-3xl">
172144
{boardData.name}
173145
</h1>
174146
<p className="text-sm font-medium text-gray-600 dark:text-gray-400">
@@ -178,19 +150,23 @@ function KanbanBoard({ boardData, projectId }: KanbanBoardProps) {
178150
</div>
179151

180152
{/* Desktop Layout: Search Left, Controls Right */}
181-
<div className="flex flex-col gap-6 lg:flex-row lg:gap-8 lg:items-start">
153+
<div className="flex flex-col gap-6 lg:flex-row lg:items-start lg:gap-8">
182154
{/* Left: Search Input */}
183155
<div className="flex-1">
184-
<div className="focus-within:ring-customBlue-500 focus-within:border-customBlue-300 flex w-full items-center gap-3 rounded-xl border border-white/20 bg-white/10 p-3 shadow-lg backdrop-blur-sm transition-all duration-300 focus-within:shadow-xl focus-within:ring-2 hover:bg-white/20 dark:border-white/10 dark:bg-white/5">
156+
<div className="focus-within:ring-customBlue-500 focus-within:border-customBlue-300 flex w-full items-center gap-3 rounded-xl border p-3 shadow-lg backdrop-blur-sm transition-all duration-300 focus-within:shadow-xl focus-within:ring-2
157+
border-gray-200 bg-white hover:bg-gray-50
158+
dark:border-white/10 dark:bg-white/5 dark:hover:bg-white/10">
185159
<label htmlFor="kanbanSearch" className="sr-only">
186160
Search tasks
187161
</label>
188162
<IconSearch
189-
className="text-gray-300 transition-colors duration-200 dark:text-gray-400"
163+
className="text-gray-400 transition-colors duration-200 dark:text-gray-400"
190164
aria-hidden="true"
191165
/>
192166
<KanbanBoardsSearch
193-
className="w-full bg-transparent font-medium text-white placeholder-gray-300 outline-none dark:text-white dark:placeholder-gray-400"
167+
className="w-full bg-transparent font-medium outline-none
168+
text-gray-800 placeholder-gray-400
169+
dark:text-white dark:placeholder-gray-400"
194170
placeholder="🔍 Search tasks..."
195171
id="kanbanSearch"
196172
/>
@@ -206,18 +182,18 @@ function KanbanBoard({ boardData, projectId }: KanbanBoardProps) {
206182
)}
207183
{canAddMember && <KanbanAddMembersButton />}
208184

209-
{/* Archive Toggle Button */}
185+
{/* Archive Toggle Button - FIXED for light mode */}
210186
<Button
211187
onClick={() => setShowArchive(!showArchive)}
212188
variant={showArchive ? "default" : "outline"}
213189
className={`flex transform items-center gap-2 whitespace-nowrap px-3 py-2 text-sm transition-all duration-300 hover:scale-105 ${
214190
showArchive
215191
? "bg-customBlue-600 hover:bg-customBlue-700 shadow-customBlue-500/30 text-white shadow-lg"
216-
: "border-white/30 text-white hover:border-white/50 hover:bg-white/20 dark:border-white/20 dark:text-gray-300 dark:hover:bg-white/10 backdrop-blur-sm"
192+
: "border-gray-300 bg-white text-gray-700 hover:border-gray-400 hover:bg-gray-100 dark:border-white/20 dark:bg-transparent dark:text-gray-300 dark:hover:bg-white/10 backdrop-blur-sm"
217193
}`}
218194
aria-pressed={showArchive}
219195
>
220-
<IconArchive className="h-4 w-4" aria-hidden="true" />
196+
<Archive className="h-4 w-4 text-gray-600 dark:text-gray-300" aria-hidden="true" />
221197
<span className="hidden lg:inline">
222198
{showArchive ? "Hide Archive" : "Show Archive"}
223199
</span>
@@ -226,7 +202,7 @@ function KanbanBoard({ boardData, projectId }: KanbanBoardProps) {
226202
</span>
227203
</Button>
228204

229-
{/* Draft Badge Button - CBP-16 */}
205+
{/* Draft Badge Button - FIXED for light mode */}
230206
{draftCount > 0 && (
231207
<Button
232208
onClick={() => {
@@ -236,13 +212,15 @@ function KanbanBoard({ boardData, projectId }: KanbanBoardProps) {
236212
});
237213
}}
238214
variant="outline"
239-
className="relative flex transform items-center gap-2 whitespace-nowrap px-3 py-2 text-sm transition-all duration-300 hover:scale-105 border-white/30 text-white hover:border-white/50 hover:bg-white/20 dark:border-white/20 dark:text-gray-300 dark:hover:bg-white/10 backdrop-blur-sm"
215+
className="relative flex transform items-center gap-2 whitespace-nowrap px-3 py-2 text-sm transition-all duration-300 hover:scale-105
216+
border-gray-300 bg-white text-gray-700 hover:border-gray-400 hover:bg-gray-100
217+
dark:border-white/20 dark:bg-transparent dark:text-gray-300 dark:hover:bg-white/10 backdrop-blur-sm"
240218
aria-label={`You have ${draftCount} draft${draftCount > 1 ? 's' : ''}`}
241219
title="View your saved drafts"
242220
>
243221
<span className="text-lg" aria-hidden="true">📝</span>
244222
<span className="hidden lg:inline">Drafts</span>
245-
<span className="absolute -right-1 -top-1 flex h-5 w-5 items-center justify-center rounded-full bg-blue-500 text-xs text-white font-semibold shadow-lg">
223+
<span className="absolute -right-1 -top-1 flex h-5 w-5 items-center justify-center rounded-full bg-blue-500 text-xs font-semibold text-white shadow-lg">
246224
{draftCount}
247225
</span>
248226
</Button>
@@ -263,7 +241,6 @@ function KanbanBoard({ boardData, projectId }: KanbanBoardProps) {
263241
{/* Main Content Area */}
264242
<main className="flex-1">
265243
{boardData.kanban_columns.length === 0 ? (
266-
// Empty State
267244
<div className="flex flex-1 items-center justify-center">
268245
<div className="py-20 text-center">
269246
<div
@@ -287,7 +264,6 @@ function KanbanBoard({ boardData, projectId }: KanbanBoardProps) {
287264
</div>
288265
</div>
289266
) : (
290-
// Kanban Board Content
291267
<div className="flex h-full flex-1 overflow-hidden rounded-xl bg-transparent backdrop-blur-sm transition-all duration-300">
292268
{!showArchive ? (
293269
<KanbanBoardColumnContainer
@@ -304,7 +280,6 @@ function KanbanBoard({ boardData, projectId }: KanbanBoardProps) {
304280
</div>
305281
</div>
306282

307-
{/* Modal Container */}
308283
{canAddColumn && <KanbanColumnAddModal />}
309284
</div>
310285
);

0 commit comments

Comments
 (0)