diff --git a/apps/hackathon/src/app/teams/browse/page.tsx b/apps/hackathon/src/app/teams/browse/page.tsx
index 08382cc..d8ed113 100644
--- a/apps/hackathon/src/app/teams/browse/page.tsx
+++ b/apps/hackathon/src/app/teams/browse/page.tsx
@@ -17,6 +17,17 @@ import { Icon } from '@iconify/react';
const DEFAULT_PER_PAGE = 12;
const PER_PAGE_OPTIONS = [6, 12, 24, 48];
+// Member filter options
+const MEMBER_FILTER_OPTIONS = [
+ { label: 'All Teams', value: '', minMembers: undefined, maxMembers: undefined },
+ { label: 'Looking for Members (1-4)', value: 'looking', minMembers: 1, maxMembers: 4 },
+ { label: '1 Member', value: '1', minMembers: 1, maxMembers: 1 },
+ { label: '2 Members', value: '2', minMembers: 2, maxMembers: 2 },
+ { label: '3 Members', value: '3', minMembers: 3, maxMembers: 3 },
+ { label: '4 Members', value: '4', minMembers: 4, maxMembers: 4 },
+ { label: '5 Members (Full)', value: '5', minMembers: 5, maxMembers: 5 },
+];
+
// Skeleton card component for loading state
const TeamCardSkeleton: FC = () => (
@@ -54,10 +65,12 @@ const BrowseTeamsPage: FC = (): ReactElement => {
);
const initialSearch = searchParams.get('search') || '';
const initialCity = searchParams.get('city') || '';
+ const initialMembers = searchParams.get('members') || '';
const [searchTerm, setSearchTerm] = useState(initialSearch);
const [debouncedSearch, setDebouncedSearch] = useState(initialSearch);
const [selectedCity, setSelectedCity] = useState(initialCity);
+ const [selectedMembers, setSelectedMembers] = useState(initialMembers);
const [selectedTeamId, setSelectedTeamId] = useState
(null);
const [showJoinModal, setShowJoinModal] = useState(false);
const [currentPage, setCurrentPage] = useState(
@@ -74,6 +87,7 @@ const BrowseTeamsPage: FC = (): ReactElement => {
per_page?: number;
search?: string;
city?: string;
+ members?: string;
}) => {
const newParams = new URLSearchParams(searchParams);
@@ -109,6 +123,14 @@ const BrowseTeamsPage: FC = (): ReactElement => {
}
}
+ if (params.members !== undefined) {
+ if (params.members === '') {
+ newParams.delete('members');
+ } else {
+ newParams.set('members', params.members);
+ }
+ }
+
setSearchParams(newParams, { replace: true });
},
[searchParams, setSearchParams]
@@ -134,6 +156,11 @@ const BrowseTeamsPage: FC = (): ReactElement => {
}
}, [selectedCity]);
+ // Get member filter values
+ const memberFilter = MEMBER_FILTER_OPTIONS.find(
+ (opt) => opt.value === selectedMembers
+ );
+
const {
data: teamsData,
isLoading,
@@ -144,6 +171,8 @@ const BrowseTeamsPage: FC = (): ReactElement => {
search: debouncedSearch,
city: selectedCity || undefined,
visibility: ETeamVisibility.PUBLIC,
+ minMembers: memberFilter?.minMembers,
+ maxMembers: memberFilter?.maxMembers,
});
const { data: myTeamsData } = useMyTeams();
@@ -243,7 +272,7 @@ const BrowseTeamsPage: FC = (): ReactElement => {
{/* Filters */}
-
+
+
+
+
+
diff --git a/libs/service/src/hooks/teams/index.ts b/libs/service/src/hooks/teams/index.ts
index e9b2257..b0cf0f3 100644
--- a/libs/service/src/hooks/teams/index.ts
+++ b/libs/service/src/hooks/teams/index.ts
@@ -125,6 +125,8 @@ export const useTeams = (params?: {
city?: string;
visibility?: string;
search?: string;
+ minMembers?: number;
+ maxMembers?: number;
}) => {
return useQuery({
queryKey: teamKeys.list(params),
@@ -135,6 +137,8 @@ export const useTeams = (params?: {
if (params?.search) queryParams.append('search', params.search);
if (params?.city) queryParams.append('city', params.city);
if (params?.visibility) queryParams.append('visibility', params.visibility);
+ if (params?.minMembers) queryParams.append('min_members', String(params.minMembers));
+ if (params?.maxMembers) queryParams.append('max_members', String(params.maxMembers));
const response = await hackathonApi.get
>(
`/teams/browse${queryParams.toString() ? `?${queryParams.toString()}` : ''}`