diff --git a/api/core/_transformers.ts b/api/core/_transformers.ts index f3d713d..94b4089 100644 --- a/api/core/_transformers.ts +++ b/api/core/_transformers.ts @@ -1,4 +1,9 @@ -import { Issue, IssueDto } from "@/types/issue"; +import { + Issue, + IssueDto, + IssueQueryParams, + IssueQueryParamsDto, +} from "@/types/issue"; import { Project, ProjectDto } from "@/types/project"; import { Repository, RepositoryDto } from "@/types/repository"; @@ -39,3 +44,21 @@ export function dtoToProject(dto: ProjectDto): Project { technologies: dto.technologies ?? [], }; } + +export function issueQueryParamsToDto( + query: IssueQueryParams, + allLanguages: string[], +): IssueQueryParamsDto { + const technologies = query.technologies ?? []; + const languages = technologies.filter((tech) => allLanguages.includes(tech)); + const remainingTechnologies = technologies.filter( + (tech) => !allLanguages.includes(tech), + ); + + return { + ...query, + technologies: + remainingTechnologies.length > 0 ? remainingTechnologies : undefined, + languages: languages.length > 0 ? languages : undefined, + }; +} diff --git a/api/core/issues.ts b/api/core/issues.ts index b3655d7..41c0b8d 100644 --- a/api/core/issues.ts +++ b/api/core/issues.ts @@ -1,5 +1,10 @@ import { DEFAULT_QUERY } from "@/data/fetch"; -import { IssueQueryParams, IssueDto, Issue } from "@/types/issue"; +import { + IssueQueryParams, + IssueDto, + Issue, + IssueQueryParamsDto, +} from "@/types/issue"; import { PaginationQueryParams, PaginatedCustomResponse, @@ -7,17 +12,24 @@ import { } from "@/types/pagination"; import { prepareUrl } from "@/utils/url"; import { coreApiClient } from "./_client"; -import { dtoToIssue } from "./_transformers"; +import { dtoToIssue, issueQueryParamsToDto } from "./_transformers"; +import { getAllLanguages } from "./languages"; const ISSUES_PATH = "/issues"; export async function getIssues( query: IssueQueryParams & PaginationQueryParams = DEFAULT_QUERY, ): Promise> { - const url = prepareUrl(`${ISSUES_PATH}`, query); - // TODO: Small transformation needed to separate languages from technologies in query params + let queryDto: IssueQueryParamsDto = query; + if (query?.technologies?.length) { + const allLanguages = await getAllLanguages(); + queryDto = issueQueryParamsToDto(query, allLanguages); + } + + const url = prepareUrl(`${ISSUES_PATH}`, queryDto); const res = await coreApiClient.get>(url); + return { totalCount: res.total_count ?? 0, hasNextPage: res.has_next_page, diff --git a/app/page.tsx b/app/page.tsx index 07c3656..7e4cfdc 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -13,7 +13,10 @@ import { FiltersProvider } from "@/contexts/filters"; import { SITE_CONFIG } from "@/data/config"; import { getFilterOptions } from "@/lib/filters"; import { initFilters } from "@/utils/filters"; -import { DEFAULT_PAGE_SIZE, DEFAULT_PAGINATED_RESPONSE } from "@/data/fetch"; +import { + DEFAULT_HOMEPAGE_PAGE_SIZE, + DEFAULT_PAGINATED_RESPONSE, +} from "@/data/fetch"; import { FilterOptions } from "@/types/filters"; const EXPLORE_LABEL = "Explore Open Contributions"; @@ -27,7 +30,7 @@ export default async function Home() { const issues = await IssuesApi.getIssues({ offset: 0, - limit: DEFAULT_PAGE_SIZE, + limit: DEFAULT_HOMEPAGE_PAGE_SIZE, }).catch((error) => { console.error("Error fetching issues:", error); return DEFAULT_PAGINATED_RESPONSE; diff --git a/components/table/row.tsx b/components/table/row.tsx index 405f68b..28579e0 100644 --- a/components/table/row.tsx +++ b/components/table/row.tsx @@ -31,29 +31,34 @@ interface IProjectProps { slug: string; name: string; repository: Repository; + withProjectData?: boolean; } export const Project = ({ avatarSrc, slug, name, repository, -}: IProjectProps) => ( - - -
-

{name}

-

- {repository.name} -

-
-
-); + withProjectData, +}: IProjectProps) => { + if (!withProjectData) return
; + return ( + + +
+

{name}

+

+ {repository.name} +

+
+
+ ); +}; interface IAvatarProps { alt: string; @@ -83,21 +88,21 @@ interface IContentProps { title: string; projectName?: string; repositoryName: string; - url: string; isCertified: boolean; } export const Content = ({ title, projectName, repositoryName, - url, isCertified, }: IContentProps) => { return (
- +
{projectName ? ( `${projectName} / ${repositoryName}` @@ -109,9 +114,7 @@ export const Content = ({ )}
-
+

{title}

diff --git a/components/table/static-table.tsx b/components/table/static-table.tsx index be0c001..cdb0ec3 100644 --- a/components/table/static-table.tsx +++ b/components/table/static-table.tsx @@ -49,7 +49,7 @@ const StaticTable = ({ data, withProjectData = true }: IStaticTableProps) => { const isLaptop = useMediaQuery({ minWidth: 1024 }); // tailwind lg default: 1024px const [columns, setColumns] = useState([ - ...(withProjectData ? [{ name: "PROJECT", uid: "project" }] : []), + { name: "PROJECT", uid: "project" }, { name: "CONTENT", uid: "content" }, { name: "LABELS", uid: "labels" }, { name: "DATE", uid: "date" }, @@ -66,6 +66,7 @@ const StaticTable = ({ data, withProjectData = true }: IStaticTableProps) => { slug={project.slug} name={project.name} repository={repository} + withProjectData={withProjectData} /> ); } @@ -76,7 +77,6 @@ const StaticTable = ({ data, withProjectData = true }: IStaticTableProps) => { title={title} projectName={withProjectData ? project.name : undefined} repositoryName={repository?.name} - url={url} isCertified={isCertified} /> ); @@ -117,7 +117,7 @@ const StaticTable = ({ data, withProjectData = true }: IStaticTableProps) => { useEffect(() => { setColumns([ - ...(withProjectData ? [{ name: "PROJECT", uid: "project" }] : []), + { name: "PROJECT", uid: "project" }, { name: "CONTENT", uid: "content" }, ...(isLaptop ? [{ name: "LABELS", uid: "labels" }] : []), { name: "DATE", uid: "date" }, @@ -148,9 +148,12 @@ const StaticTable = ({ data, withProjectData = true }: IStaticTableProps) => { )} - + {(item) => { - const isHighlighted = item.isCertified && !filters[KUDOS_ISSUE_KEY]; + const isHighlighted = item.isCertified && !filters?.[KUDOS_ISSUE_KEY]; return ( = { @@ -12,7 +13,7 @@ export const DEFAULT_PAGINATED_RESPONSE: PaginatedCustomResponse = { export const DEFAULT_QUERY = { offset: 0, - limit: DEFAULT_BIG_PAGE_SIZE, + limit: DEFAULT_PAGE_SIZE, }; export const UNASSIGNED_CONTRIBUTION_FILTER = { diff --git a/hooks/useFilters.tsx b/hooks/useFilters.tsx index 3431d4d..4c7eb83 100644 --- a/hooks/useFilters.tsx +++ b/hooks/useFilters.tsx @@ -1,11 +1,6 @@ import { useCallback, useState } from "react"; import { useRouter } from "next/navigation"; -import { - FilterKeys, - IFilterOption, - FilterOptions, - Filters, -} from "@/types/filters"; +import { FilterKeys, FilterOptions, Filters } from "@/types/filters"; import { initFilters } from "@/utils/filters"; import { GOOD_FIRST_ISSUE_KEY, KUDOS_ISSUE_KEY } from "@/data/filters"; diff --git a/lib/filters.ts b/lib/filters.ts index d7912b4..eb55496 100644 --- a/lib/filters.ts +++ b/lib/filters.ts @@ -1,6 +1,6 @@ import LanguagesApi from "@/api/core/languages"; import ProjectsApi from "@/api/core/projects"; -import { DEFAULT_QUERY } from "@/data/fetch"; +import { DEFAULT_BIG_PAGE_SIZE } from "@/data/fetch"; import { FProjectTypes, FPurposes, @@ -42,7 +42,10 @@ export async function getFilterOptions(): Promise { const purposes = createFilterOptions(FPurposes, emojiMapForPurposes); const technologies = createFilterOptions( - [...languageValues, ...FTechnologies], + [ + ...languageValues.map((v) => v.toLocaleLowerCase().replaceAll('"', "")), + ...FTechnologies, + ], emojiMapForTechnologies, ); const stackLevels = createFilterOptions(FStackLevels, emojiMapForStackLevels); @@ -64,7 +67,8 @@ export function filtersToIssuesQuery( filters: Filters, ): IssueQueryParams & PaginationQueryParams { const query: IssueQueryParams & PaginationQueryParams = { - ...DEFAULT_QUERY, + offset: 0, + limit: DEFAULT_BIG_PAGE_SIZE, open: true, }; diff --git a/types/issue.ts b/types/issue.ts index 8266169..5b4aed2 100644 --- a/types/issue.ts +++ b/types/issue.ts @@ -39,3 +39,8 @@ export type IssueQueryParams = Partial<{ technologies: string[]; types: string[]; }>; + +export type IssueQueryParamsDto = IssueQueryParams & + Partial<{ + languages: string[]; + }>;