Skip to content

Commit 8078402

Browse files
committed
fix codev prioritization
1 parent 95e5300 commit 8078402

2 files changed

Lines changed: 204 additions & 11 deletions

File tree

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

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
11
// components/landing/LandingIntern-CodevPagination.tsx
2+
//
3+
// This component displays a paginated list of team members (Interns and Codevs)
4+
// with prioritization applied using the prioritizeCodevs utility function.
5+
// Team members are automatically sorted by:
6+
// 1. Total codev points (highest first)
7+
// 2. Level 2+ badges (prioritized)
8+
// 3. Number of valid badges
9+
// 4. Has profile image
10+
// 5. Has work experience
11+
// 6. Years of experience
212

313
"use client";
414

@@ -7,23 +17,46 @@ import { ChevronLeft, ChevronRight } from "lucide-react";
717
import { Button } from "@/components/ui/button";
818
import { cn } from "@/lib/utils";
919
import InternCards from "./LandingIntern-CodevCard";
20+
import { prioritizeCodevs } from "@/utils/codev-priority";
1021

1122
// Type definitions for the two roles from database
1223
type PersonRole = 'Intern' | 'Codev';
1324

1425
type TeamMember = {
26+
id: string;
1527
name: string;
1628
role: PersonRole; // Either Intern or Codev from roles table
1729
image?: string;
1830
display_position?: string;
31+
years_of_experience?: number;
32+
internal_status?: string;
33+
level?: Record<string, any>;
34+
codev_points?: Array<{
35+
id: string;
36+
codev_id?: string;
37+
skill_category_id?: string;
38+
points: number;
39+
}>;
40+
work_experience?: Array<any>;
1941
};
2042

2143
interface TeamMembersApiResponse {
22-
INTERNS: { // Keep as INTERNS to match current API response, you may modify later
44+
TEAM_MEMBERS: { // Changed from INTERNS to TEAM_MEMBERS to match new API
45+
id: string;
2346
name: string;
2447
role: string;
2548
image?: string;
26-
display_position?: string
49+
display_position?: string;
50+
years_of_experience?: number;
51+
internal_status?: string;
52+
level?: Record<string, any>;
53+
codev_points?: Array<{
54+
id: string;
55+
codev_id?: string;
56+
skill_category_id?: string;
57+
points: number;
58+
}>;
59+
work_experience?: Array<any>;
2760
}[];
2861
error?: string;
2962
}
@@ -57,25 +90,31 @@ export default function TeamMembersPagination() {
5790
setFetchError(null);
5891

5992
try {
60-
const response = await fetch("/api/all-active-interns-codev");
93+
const response = await fetch("/api/all-active-interns-codev-prioritized");
6194
if (!response.ok) {
6295
const errorText = await response.text();
6396
throw new Error(`Failed to fetch team members: ${response.status} ${errorText}`);
6497
}
6598

6699
const apiData = (await response.json()) as TeamMembersApiResponse;
67100

68-
if (!apiData || !Array.isArray(apiData.INTERNS)) {
69-
console.warn("Unexpected API response shape for /api/all-active-interns-codev:", apiData);
101+
if (!apiData || !Array.isArray(apiData.TEAM_MEMBERS)) {
102+
console.warn("Unexpected API response shape for /api/all-active-interns-codev-prioritized:", apiData);
70103
if (!isMounted) return;
71104
setAllTeamMembers([]);
72105
} else {
73106
// Map API response to TeamMember objects with proper role validation
74-
const mappedTeamMembers = apiData.INTERNS.map((member) => ({
107+
const mappedTeamMembers = apiData.TEAM_MEMBERS.map((member) => ({
108+
id: member.id,
75109
name: member.name,
76110
role: validateTeamRole(member.role), // Ensures only Intern or Codev roles
77111
image: member.image,
78112
display_position: member.display_position,
113+
years_of_experience: member.years_of_experience,
114+
internal_status: member.internal_status,
115+
level: member.level,
116+
codev_points: member.codev_points,
117+
work_experience: member.work_experience,
79118
}));
80119

81120
if (!isMounted) return;
@@ -135,12 +174,13 @@ export default function TeamMembersPagination() {
135174
goToNextPage();
136175
};
137176

138-
// Debug: Log the current pagination state
139-
console.log('Debug pagination state:', {
177+
// Debug: Log the current pagination state with prioritization info
178+
console.log('Debug pagination state (prioritized):', {
140179
currentPage,
141180
totalPages,
142181
isLoading,
143-
totalTeamMembers: allTeamMembers.length
182+
totalTeamMembers: allTeamMembers.length,
183+
teamMembersArePrioritized: true // Team members are now prioritized using codev-priority.ts
144184
});
145185

146186
// Button disabled states
@@ -158,10 +198,11 @@ export default function TeamMembersPagination() {
158198
const internMembers = allTeamMembers.filter(member => isInternRole(member.role));
159199
const codevMembers = allTeamMembers.filter(member => isCodevRole(member.role));
160200

161-
console.log('Team composition:', {
201+
console.log('Team composition (prioritized):', {
162202
totalInterns: internMembers.length,
163203
totalCodevs: codevMembers.length,
164-
totalMembers: allTeamMembers.length
204+
totalMembers: allTeamMembers.length,
205+
note: 'Team members are sorted by priority using codev-priority.ts utility'
165206
});
166207

167208
return (
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
// app/api/all-active-interns-codev-prioritized/route.ts
2+
import { NextResponse } from "next/server";
3+
import { createClientServerComponent } from "@/utils/supabase/server";
4+
import { Codev } from "@/types/home/codev";
5+
import { prioritizeCodevs } from "@/utils/codev-priority";
6+
7+
export async function GET() {
8+
try {
9+
const supabase = await createClientServerComponent();
10+
11+
// Fetch comprehensive codev data with all necessary fields for prioritization
12+
const { data, error } = await supabase
13+
.from("codev")
14+
.select(`
15+
id,
16+
first_name,
17+
last_name,
18+
email_address,
19+
phone_number,
20+
address,
21+
about,
22+
display_position,
23+
image_url,
24+
internal_status,
25+
availability_status,
26+
level,
27+
application_status,
28+
years_of_experience,
29+
role_id,
30+
created_at,
31+
updated_at,
32+
codev_points (
33+
id,
34+
codev_id,
35+
skill_category_id,
36+
points
37+
),
38+
work_experience (
39+
id,
40+
codev_id,
41+
position,
42+
description,
43+
date_from,
44+
date_to,
45+
company_name,
46+
location,
47+
is_present
48+
),
49+
project_members (
50+
id,
51+
project_id,
52+
role,
53+
joined_at,
54+
projects (
55+
id,
56+
name,
57+
description,
58+
status,
59+
start_date,
60+
end_date,
61+
github_link,
62+
main_image,
63+
website_url,
64+
figma_link,
65+
client_id,
66+
project_category_id,
67+
kanban_display,
68+
public_display
69+
)
70+
)
71+
`)
72+
.eq("availability_status", true)
73+
.in("role_id", [4, 10]); // Intern and Codev role IDs
74+
75+
if (error) {
76+
console.error("Supabase query error:", error);
77+
return NextResponse.json(
78+
{ TEAM_MEMBERS: [], error: error.message ?? "DB error" },
79+
{ status: 500 }
80+
);
81+
}
82+
83+
// Transform the data to match Codev interface
84+
const teamMembers: Codev[] = (data ?? []).map((row: any) => {
85+
// Transform project_members to projects format expected by Codev interface
86+
const projects = row.project_members?.map((pm: any) => ({
87+
...pm.projects,
88+
role: pm.role,
89+
joined_at: pm.joined_at,
90+
})) || [];
91+
92+
return {
93+
id: row.id,
94+
first_name: row.first_name,
95+
last_name: row.last_name,
96+
email_address: row.email_address,
97+
phone_number: row.phone_number,
98+
address: row.address,
99+
about: row.about,
100+
positions: [], // Empty array as this field isn't used in prioritization
101+
display_position: row.display_position,
102+
tech_stacks: [], // Empty array as this field isn't available
103+
image_url: row.image_url,
104+
internal_status: row.internal_status,
105+
availability_status: row.availability_status,
106+
level: row.level,
107+
application_status: row.application_status,
108+
work_experience: row.work_experience || [],
109+
created_at: row.created_at,
110+
updated_at: row.updated_at,
111+
years_of_experience: row.years_of_experience,
112+
role_id: row.role_id,
113+
codev_points: row.codev_points || [],
114+
projects: projects,
115+
project_members: row.project_members || [],
116+
} as Codev;
117+
});
118+
119+
// Apply prioritization using the prioritizeCodevs function
120+
const prioritizedTeamMembers = prioritizeCodevs(teamMembers, false);
121+
122+
// Transform back to the expected format for the component
123+
const TEAM_MEMBERS = prioritizedTeamMembers.map((codev) => {
124+
// Map role_id to role name (4 = Intern, 10 = Codev)
125+
const roleName = codev.role_id === 4 ? "Intern" : codev.role_id === 10 ? "Codev" : "Member";
126+
127+
return {
128+
id: codev.id,
129+
name: `${codev.first_name} ${codev.last_name}`.trim(),
130+
role: roleName,
131+
image: codev.image_url,
132+
display_position: codev.display_position,
133+
// Include additional useful fields for display
134+
years_of_experience: codev.years_of_experience,
135+
internal_status: codev.internal_status,
136+
level: codev.level,
137+
codev_points: codev.codev_points,
138+
work_experience: codev.work_experience,
139+
};
140+
});
141+
142+
console.log(`Prioritized ${TEAM_MEMBERS.length} team members`);
143+
144+
return NextResponse.json({ TEAM_MEMBERS });
145+
} catch (err) {
146+
console.error("Unexpected error in /api/all-active-interns-codev-prioritized:", err);
147+
return NextResponse.json(
148+
{ TEAM_MEMBERS: [], error: "Unexpected server error" },
149+
{ status: 500 }
150+
);
151+
}
152+
}

0 commit comments

Comments
 (0)