Skip to content

Commit 9758521

Browse files
authored
Merge pull request #467 from CodebilityDev/dev
latest update
2 parents fff2664 + f5bae68 commit 9758521

17 files changed

Lines changed: 1621 additions & 724 deletions

File tree

‎apps/codebility/app/(marketing)/_components/MarketingNavigation.tsx‎

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,16 @@ import {
3636
SheetTrigger,
3737
} from "@codevs/ui";
3838

39+
// Navigation items for top navbar and mobile drawer
3940
const NAV_ITEMS = [
4041
{ id: "1", title: "Our Services", path: "/services" },
4142
{ id: "2", title: "About Us", path: "/#whychooseus" },
4243
{ id: "3", title: "Book a Call", path: "/bookacall" },
43-
{ id: "4", title: "Hire a CoDevs", path: "/hire-a-codev" },
44+
{ id: "4", title: "Be a Codev", path: "/codevs" }, // ✅ ADDED: New link after Book a Call
45+
{ id: "5", title: "Hire a CoDevs", path: "/hire-a-codev" },
4446
] as const;
4547

48+
// Get menu items based on user application status
4649
const getMenuItems = (
4750
status: string,
4851
role_id: number,
@@ -271,7 +274,7 @@ const Navigation = () => {
271274

272275
async function fetchUser() {
273276
try {
274-
// FIXED: Use getUser() instead of getSession()
277+
// Use getUser() for proper auth check
275278
const { data: { user }, error: authError } = await supabase.auth.getUser();
276279

277280
if (authError) {
@@ -281,7 +284,6 @@ const Navigation = () => {
281284
}
282285

283286
if (!user) {
284-
// not logged in → silent
285287
setUserData(null);
286288
return;
287289
}
@@ -314,8 +316,8 @@ const Navigation = () => {
314316
const handleLogout = async () => {
315317
try {
316318
await signOut();
317-
setUserData(null); // Clear userData after logout
318-
setOpenSheet(false); // Close the mobile drawer (if open)
319+
setUserData(null);
320+
setOpenSheet(false);
319321
} catch (error) {
320322
console.error("Failed to log out:", error);
321323
}

‎apps/codebility/app/(marketing)/_components/MarketingSidenavMenu.tsx‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,20 @@ import { useEffect, useState } from "react";
44
import Link from "next/link";
55
import ScrollToHash from "@/app/(marketing)/_components/landing/LandingScrollToHash";
66

7+
// Navigation links for sidebar - displayed on left side of landing page
78
const links = [
89
{ href: "/services", label: "Our Services" },
910
{ href: "/#whychooseus", label: "About Us" },
1011
{ href: "/bookacall", label: "Book a Call" },
12+
{ href: "/codevs", label: "Be a Codev" }, // ✅ ADDED: New link after Book a Call
1113
{ href: "/hire-a-codev", label: "Hire Codevs" },
1214
{ href: "/careers", label: "Careers" },
1315
];
1416

1517
const SideNavMenu = () => {
1618
const [isScrolling, setIsScrolling] = useState(false);
1719

20+
// Handle scroll animation - shrink links when scrolling
1821
const handleNav = () => {
1922
if (window.scrollY >= 200) {
2023
setIsScrolling(true);
@@ -56,4 +59,4 @@ const SideNavMenu = () => {
5659
);
5760
};
5861

59-
export default SideNavMenu;
62+
export default SideNavMenu;

‎apps/codebility/app/(marketing)/_components/landing/LandingAdminCard.tsx‎

Lines changed: 74 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -8,81 +8,85 @@ import { useState } from "react";
88

99
// Utility function to capitalize the first letter of each word
1010
const capitalizeWords = (text: string) => {
11-
return text
12-
.split(" ")
13-
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
14-
.join(" ");
11+
return text
12+
.split(" ")
13+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
14+
.join(" ");
1515
};
1616

1717
const AdminCard = ({ admin }: { admin: Codev }) => {
18-
const [imageLoaded, setImageLoaded] = useState(false);
19-
const defaultImage = "/assets/svgs/icon-codebility-black.svg";
18+
const [imageLoaded, setImageLoaded] = useState(false);
19+
const defaultImage = "/assets/svgs/icon-codebility-black.svg";
2020

21-
return (
22-
<motion.div
23-
className="h-full"
24-
>
25-
<div className="flex h-full w-full flex-col gap-4 rounded-lg">
26-
<div className="relative h-[250px] w-full rounded-lg overflow-hidden bg-gray-100 dark:bg-gray-800">
27-
{/* Image */}
28-
<div className="relative w-full h-full">
29-
<Image
30-
alt={`${admin.first_name} Avatar`}
31-
src={admin.image_url || defaultImage}
32-
fill
33-
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
34-
priority
35-
className="rounded-lg object-cover"
36-
onLoad={() => setImageLoaded(true)}
37-
onError={(e) => {
38-
e.currentTarget.src = defaultImage;
39-
}}
40-
/>
41-
</div>
21+
// Line 18: Enhanced with onClick redirect and hover effects
22+
return (
23+
<motion.div
24+
className="h-full cursor-pointer"
25+
onClick={() => window.location.href = `https://www.codebility.tech/profiles/${admin.id}`}
26+
whileHover={{ scale: 1.02 }}
27+
transition={{ duration: 0.2 }}
28+
>
29+
<div className="flex h-full w-full flex-col gap-4 rounded-lg">
30+
<div className="relative h-[250px] w-full rounded-lg overflow-hidden bg-gray-100 dark:bg-gray-800">
31+
{/* Image */}
32+
<div className="relative w-full h-full">
33+
<Image
34+
alt={`${admin.first_name} Avatar`}
35+
src={admin.image_url || defaultImage}
36+
fill
37+
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
38+
priority
39+
className="rounded-lg object-cover"
40+
onLoad={() => setImageLoaded(true)}
41+
onError={(e) => {
42+
e.currentTarget.src = defaultImage;
43+
}}
44+
/>
45+
</div>
4246

43-
{/* Loading skeleton */}
44-
{!imageLoaded && (
45-
<motion.div
46-
className="absolute inset-0 bg-gradient-to-r from-gray-300 via-gray-200 to-gray-300 rounded-lg"
47-
animate={{
48-
backgroundPosition: ["200% 0", "-200% 0"],
49-
}}
50-
transition={{
51-
duration: 1.5,
52-
repeat: Infinity,
53-
ease: "linear",
54-
}}
55-
style={{
56-
backgroundSize: "200% 100%",
57-
}}
58-
/>
59-
)}
60-
</div>
47+
{/* Loading skeleton */}
48+
{!imageLoaded && (
49+
<motion.div
50+
className="absolute inset-0 bg-gradient-to-r from-gray-300 via-gray-200 to-gray-300 rounded-lg"
51+
animate={{
52+
backgroundPosition: ["200% 0", "-200% 0"],
53+
}}
54+
transition={{
55+
duration: 1.5,
56+
repeat: Infinity,
57+
ease: "linear",
58+
}}
59+
style={{
60+
backgroundSize: "200% 100%",
61+
}}
62+
/>
63+
)}
64+
</div>
6165

62-
{/* Text content */}
63-
<motion.div
64-
className="flex w-full flex-col gap-1"
65-
initial={{ opacity: 0, y: 10 }}
66-
animate={{ opacity: 1, y: 0 }}
67-
transition={{ duration: 0.5, delay: 0.2 }}
68-
>
69-
<p className="md:text-md text-sm text-white lg:text-lg font-medium">
70-
{capitalizeWords(admin.first_name)}{" "}
71-
{capitalizeWords(admin.last_name)}
72-
</p>
73-
<div className="min-h-[2.5rem]">
74-
{admin.display_position ? (
75-
<p className="text-gray-300 text-sm lg:text-base">
76-
{admin.display_position}
77-
</p>
78-
) : (
79-
<div className="text-sm lg:text-base">&nbsp;</div>
80-
)}
81-
</div>
82-
</motion.div>
83-
</div>
84-
</motion.div>
85-
);
66+
{/* Text content */}
67+
<motion.div
68+
className="flex w-full flex-col gap-1"
69+
initial={{ opacity: 0, y: 10 }}
70+
animate={{ opacity: 1, y: 0 }}
71+
transition={{ duration: 0.5, delay: 0.2 }}
72+
>
73+
<p className="md:text-md text-sm text-white lg:text-lg font-medium">
74+
{capitalizeWords(admin.first_name)}{" "}
75+
{capitalizeWords(admin.last_name)}
76+
</p>
77+
<div className="min-h-[2.5rem]">
78+
{admin.display_position ? (
79+
<p className="text-gray-300 text-sm lg:text-base">
80+
{admin.display_position}
81+
</p>
82+
) : (
83+
<div className="text-sm lg:text-base">&nbsp;</div>
84+
)}
85+
</div>
86+
</motion.div>
87+
</div>
88+
</motion.div>
89+
);
8690
};
8791

88-
export default AdminCard;
92+
export default AdminCard;

‎apps/codebility/app/(marketing)/_components/landing/LandingIntern-CodevCard.tsx‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { motion, useInView } from "framer-motion";
66
import { Card, CardContent } from "@/components/ui/card";
77

88
type Person = {
9+
id: string; // ✅ Added id field for navigation
910
name: string;
1011
role: 'Intern' | 'Codev'; // Only two possible roles from database
1112
image?: string; // image URL (optional)
@@ -231,6 +232,8 @@ export default function InternCards({ interns }: { interns: Person[] }) {
231232
}}
232233
whileTap={{ scale: 0.95 }}
233234
style={{ perspective: "1000px" }}
235+
onClick={() => window.location.href = `https://www.codebility.tech/profiles/${intern.id}`}
236+
className="cursor-pointer"
234237
>
235238
<motion.div
236239
className="h-full relative"

‎apps/codebility/app/(marketing)/_components/landing/LandingIntern-CodevPagination.tsx‎

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -155,56 +155,25 @@ export default function TeamMembersPagination() {
155155

156156
// Navigation functions
157157
const goToPreviousPage = () => {
158-
console.log('goToPreviousPage called, current page:', currentPage);
159158
setCurrentPage((prevPage) => Math.max(1, prevPage - 1));
160159
};
161-
160+
162161
const goToNextPage = () => {
163-
console.log('goToNextPage called, current page:', currentPage);
164162
setCurrentPage((prevPage) => Math.min(totalPages, prevPage + 1));
165163
};
166164

167165
const handlePreviousPageClick = () => {
168-
console.log('Previous page button clicked!');
169166
goToPreviousPage();
170167
};
171168

172169
const handleNextPageClick = () => {
173-
console.log('Next page button clicked!');
174170
goToNextPage();
175171
};
176172

177-
// Debug: Log the current pagination state with prioritization info
178-
console.log('Debug pagination state (prioritized):', {
179-
currentPage,
180-
totalPages,
181-
isLoading,
182-
totalTeamMembers: allTeamMembers.length,
183-
teamMembersArePrioritized: true // Team members are now prioritized using codev-priority.ts
184-
});
185-
186173
// Button disabled states
187174
const isPreviousPageDisabled = currentPage <= 1 || isLoading;
188175
const isNextPageDisabled = currentPage >= totalPages || isLoading;
189176

190-
console.log('Pagination button states:', {
191-
isPreviousPageDisabled,
192-
isNextPageDisabled,
193-
isFirstPage: currentPage <= 1,
194-
isLastPage: currentPage >= totalPages
195-
});
196-
197-
// Helper function to count each role type for debugging
198-
const internMembers = allTeamMembers.filter(member => isInternRole(member.role));
199-
const codevMembers = allTeamMembers.filter(member => isCodevRole(member.role));
200-
201-
console.log('Team composition (prioritized):', {
202-
totalInterns: internMembers.length,
203-
totalCodevs: codevMembers.length,
204-
totalMembers: allTeamMembers.length,
205-
note: 'Team members are sorted by priority using codev-priority.ts utility'
206-
});
207-
208177
return (
209178
<div className="w-full flex flex-col items-center gap-6">
210179
{/* Team Members Cards Container (Both Interns and Codevs) */}

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,13 +118,17 @@ const CodevCard = ({ codev, color }: Props) => {
118118
: {};
119119
}, [codev.level, codev.codev_points]);
120120

121+
// Line 119: Enhanced card wrapper with click redirect
121122
return (
122123
<div
123124
className="h-64"
124125
onMouseEnter={() => setHovered(true)}
125126
onMouseLeave={() => setHovered(false)}
126127
>
127-
<div className="group relative flex h-full w-full flex-col items-center justify-between rounded-lg border border-white/20 bg-white/10 p-4 shadow-2xl backdrop-blur-md transition-all duration-300 hover:bg-white/20 dark:border-white/10 dark:bg-white/5 dark:hover:bg-white/10">
128+
<div
129+
onClick={() => window.location.href = `https://www.codebility.tech/profiles/${codev.id}`}
130+
className="group relative flex h-full w-full flex-col items-center justify-between rounded-lg border border-white/20 bg-white/10 p-4 shadow-2xl backdrop-blur-md transition-all duration-300 cursor-pointer hover:bg-white/20 hover:scale-[1.02] dark:border-white/10 dark:bg-white/5 dark:hover:bg-white/10"
131+
>
128132
{/* Background decoration */}
129133
<div className="from-customBlue-50/30 dark:from-customBlue-950/10 absolute inset-0 bg-gradient-to-br to-purple-50/30 opacity-0 transition-opacity duration-300 group-hover:opacity-100 dark:to-purple-950/10" />
130134
<div className="absolute -right-4 -top-4 h-32 w-32 rounded-full bg-gradient-to-br from-yellow-400/10 to-orange-400/10 opacity-0 blur-2xl transition-opacity duration-500 group-hover:opacity-100" />
@@ -197,7 +201,8 @@ const CodevCard = ({ codev, color }: Props) => {
197201
<TooltipProvider>
198202
<Tooltip delayDuration={100}>
199203
<TooltipTrigger asChild>
200-
<Link href={`/profiles/${codev.id}`} target="_blank">
204+
{/* Line 217: Added stopPropagation to prevent card click when button is clicked */}
205+
<Link href={`/profiles/${codev.id}`} target="_blank" onClick={(e) => e.stopPropagation()}>
201206
<Button
202207
variant="outline"
203208
size="icon"
@@ -242,4 +247,4 @@ const CodevCard = ({ codev, color }: Props) => {
242247
);
243248
};
244249

245-
export default CodevCard;
250+
export default CodevCard;

0 commit comments

Comments
 (0)