Skip to content

Commit c39e5d1

Browse files
Resolved search bar filter in the add new member.
1 parent a747848 commit c39e5d1

1 file changed

Lines changed: 95 additions & 81 deletions

File tree

‎apps/codebility/app/home/my-team/AddMembersModal.tsx‎

Lines changed: 95 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -299,14 +299,12 @@ const AddMembersModal = ({
299299
const teamLeadData = teamLead.data;
300300
const currentMembers = members.data ?? [];
301301

302-
const [supabase, setSupabase] = useState<any>(null);
303-
304-
useEffect(() => {
302+
const supabase = useMemo(() => {
305303
try {
306-
const supabaseClient = createClientClientComponent();
307-
setSupabase(supabaseClient);
304+
return createClientClientComponent();
308305
} catch (error) {
309306
console.error('Failed to initialize Supabase client:', error);
307+
return null;
310308
}
311309
}, []);
312310

@@ -319,26 +317,42 @@ const AddMembersModal = ({
319317
const [isLoadingMembers, setIsLoadingMembers] = useState(false);
320318
const [loadError, setLoadError] = useState<string | null>(null);
321319

322-
// ✅ NEW: Direct fetch function that includes ALL internal statuses including INTERN
320+
// ✅ FIXED: Paginated fetch to bypass Supabase's 1000-row default limit
323321
const fetchAllCodevs = useCallback(async (): Promise<Codev[]> => {
324322
if (!supabase) {
325323
console.error('Supabase client not available');
326324
return [];
327325
}
328326

329327
try {
330-
const { data, error } = await supabase
331-
.from('codev')
332-
.select('*')
333-
.in('internal_status', ['GRADUATED', 'INTERN', 'MENTOR', 'TRAINING', 'ADMIN', 'ONBOARDING'])
334-
.order('first_name', { ascending: true });
335-
336-
if (error) {
337-
console.error('Error fetching codevs:', error);
338-
throw error;
328+
const PAGE_SIZE = 1000;
329+
let allData: Codev[] = [];
330+
let from = 0;
331+
332+
while (true) {
333+
const { data, error } = await supabase
334+
.from('codev')
335+
.select('*')
336+
.in('internal_status', ['GRADUATED', 'INTERN', 'MENTOR', 'TRAINING', 'ADMIN', 'ONBOARDING'])
337+
.order('first_name', { ascending: true })
338+
.range(from, from + PAGE_SIZE - 1);
339+
340+
if (error) {
341+
console.error('Error fetching codevs page:', error);
342+
throw error;
343+
}
344+
345+
if (!data || data.length === 0) break;
346+
347+
allData = [...allData, ...data];
348+
349+
// If we got fewer rows than PAGE_SIZE, we've reached the last page
350+
if (data.length < PAGE_SIZE) break;
351+
352+
from += PAGE_SIZE;
339353
}
340354

341-
return data || [];
355+
return allData;
342356
} catch (error) {
343357
console.error('Failed to fetch codevs directly:', error);
344358
throw error;
@@ -433,7 +447,7 @@ const AddMembersModal = ({
433447
}
434448
}, [getCompleteCodevProfileSafe, openProfileModal]);
435449

436-
// ✅ FIXED: Load available members using direct fetch that includes INTERNS
450+
// ✅ Load available members
437451
useEffect(() => {
438452
let isMounted = true;
439453
let timeoutId: NodeJS.Timeout;
@@ -445,14 +459,12 @@ const AddMembersModal = ({
445459
setLoadError(null);
446460

447461
try {
448-
// Set up timeout
449462
timeoutId = setTimeout(() => {
450463
if (isMounted) {
451464
throw new Error('Loading timeout');
452465
}
453466
}, 30000);
454467

455-
// ✅ Use direct fetch instead of getProjectCodevs()
456468
const users = await fetchAllCodevs();
457469

458470
clearTimeout(timeoutId);
@@ -560,7 +572,7 @@ const AddMembersModal = ({
560572
}
561573
}, [isOpen]);
562574

563-
// ✅ FIXED: Submit handler with username and username_updated_at
575+
// ✅ Submit handler
564576
const handleSubmit = async () => {
565577
if (!teamLeadData) {
566578
toast.error('Team leader not found');
@@ -699,74 +711,76 @@ const AddMembersModal = ({
699711
</Button>
700712
</div>
701713
) : filteredUsers.length > 0 ? (
702-
filteredUsers.slice(0, 50).map((user) => (
703-
<div
704-
key={user.id}
705-
onClick={() => toggleMember(user)}
706-
className={`flex items-center gap-2 sm:gap-3 p-2 sm:p-3 rounded-lg cursor-pointer transition-all duration-200 ${
707-
isSelected(user.id)
708-
? 'bg-customBlue-600/30 ring-2 ring-customBlue-500'
709-
: 'hover:bg-gray-700/30'
710-
}`}
711-
>
712-
<div className="flex-shrink-0">
713-
<div
714-
className={`relative rounded-full overflow-hidden ring-2 transition-all duration-200 cursor-pointer hover:ring-customBlue-300 ${
715-
isSelected(user.id)
716-
? 'ring-customBlue-500'
717-
: 'ring-customBlue-400'
718-
}`}
719-
style={{ width: 40, height: 40 }}
720-
onClick={(e) => {
721-
e.stopPropagation();
722-
handleProfileClick(user);
723-
}}
724-
title="Click to view profile"
725-
>
726-
<img
727-
src={
728-
user.image_url ||
729-
"https://codebility-cdn.pages.dev/assets/images/default-avatar-200x200.jpg"
730-
}
731-
alt={`${user.first_name} ${user.last_name}`}
732-
className="w-full h-full object-cover"
733-
onError={(e) => {
734-
const target = e.target as HTMLImageElement;
735-
target.src = "https://codebility-cdn.pages.dev/assets/images/default-avatar-200x200.jpg";
714+
filteredUsers
715+
.slice(0, searchQuery ? filteredUsers.length : 50)
716+
.map((user) => (
717+
<div
718+
key={user.id}
719+
onClick={() => toggleMember(user)}
720+
className={`flex items-center gap-2 sm:gap-3 p-2 sm:p-3 rounded-lg cursor-pointer transition-all duration-200 ${
721+
isSelected(user.id)
722+
? 'bg-customBlue-600/30 ring-2 ring-customBlue-500'
723+
: 'hover:bg-gray-700/30'
724+
}`}
725+
>
726+
<div className="flex-shrink-0">
727+
<div
728+
className={`relative rounded-full overflow-hidden ring-2 transition-all duration-200 cursor-pointer hover:ring-customBlue-300 ${
729+
isSelected(user.id)
730+
? 'ring-customBlue-500'
731+
: 'ring-customBlue-400'
732+
}`}
733+
style={{ width: 40, height: 40 }}
734+
onClick={(e) => {
735+
e.stopPropagation();
736+
handleProfileClick(user);
736737
}}
737-
/>
738+
title="Click to view profile"
739+
>
740+
<img
741+
src={
742+
user.image_url ||
743+
"https://codebility-cdn.pages.dev/assets/images/default-avatar-200x200.jpg"
744+
}
745+
alt={`${user.first_name} ${user.last_name}`}
746+
className="w-full h-full object-cover"
747+
onError={(e) => {
748+
const target = e.target as HTMLImageElement;
749+
target.src = "https://codebility-cdn.pages.dev/assets/images/default-avatar-200x200.jpg";
750+
}}
751+
/>
752+
</div>
738753
</div>
739-
</div>
740-
741-
<div className="flex-1 min-w-0">
742-
<div className="text-white font-semibold text-sm sm:text-base truncate">
743-
{user.first_name} {user.last_name}
744-
{isCurrentMember(user.id) && (
745-
<span className="ml-2 text-xs text-green-400 font-normal">(Current)</span>
754+
755+
<div className="flex-1 min-w-0">
756+
<div className="text-white font-semibold text-sm sm:text-base truncate">
757+
{user.first_name} {user.last_name}
758+
{isCurrentMember(user.id) && (
759+
<span className="ml-2 text-xs text-green-400 font-normal">(Current)</span>
760+
)}
761+
</div>
762+
{user.display_position && (
763+
<div className="text-gray-300 text-xs sm:text-sm truncate">
764+
{user.display_position}
765+
</div>
746766
)}
747767
</div>
748-
{user.display_position && (
749-
<div className="text-gray-300 text-xs sm:text-sm truncate">
750-
{user.display_position}
768+
769+
<div className="flex-shrink-0">
770+
<div className={`w-5 h-5 sm:w-6 sm:h-6 rounded border-2 flex items-center justify-center transition-all duration-200 ${
771+
isSelected(user.id)
772+
? 'bg-white border-white'
773+
: 'bg-transparent border-gray-400'
774+
}`}>
775+
{isSelected(user.id) && (
776+
<svg className="w-4 h-4 text-black font-bold" fill="none" viewBox="0 0 24 24" stroke="currentColor">
777+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={3} d="M5 13l4 4L19 7" />
778+
</svg>
779+
)}
751780
</div>
752-
)}
753-
</div>
754-
755-
<div className="flex-shrink-0">
756-
<div className={`w-5 h-5 sm:w-6 sm:h-6 rounded border-2 flex items-center justify-center transition-all duration-200 ${
757-
isSelected(user.id)
758-
? 'bg-white border-white'
759-
: 'bg-transparent border-gray-400'
760-
}`}>
761-
{isSelected(user.id) && (
762-
<svg className="w-4 h-4 text-black font-bold" fill="none" viewBox="0 0 24 24" stroke="currentColor">
763-
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={3} d="M5 13l4 4L19 7" />
764-
</svg>
765-
)}
766781
</div>
767782
</div>
768-
</div>
769-
))
783+
))
770784
) : (
771785
<div className="text-center py-8 text-gray-400">
772786
<Users className="h-12 w-12 mx-auto mb-3 opacity-50" />

0 commit comments

Comments
 (0)