Skip to content

Commit

Permalink
fix/performance-issues: updated listing pages to use front end cache …
Browse files Browse the repository at this point in the history
…& updated api urls
  • Loading branch information
yosuva-rajendran authored and madan-ideas2it committed Dec 3, 2024
1 parent 25a6539 commit 7164941
Show file tree
Hide file tree
Showing 26 changed files with 784 additions and 332 deletions.
Empty file added app/actions/members.actions.ts
Empty file.
24 changes: 24 additions & 0 deletions app/actions/projects.actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use server'
export const getAllProjects = async (queryParams: any, currentPage: number, limit = 0) => {
const requestOptions: RequestInit = { method: "GET", cache: 'force-cache', next: { tags: ['project-list']}};
const response = await fetch(
`${process.env.DIRECTORY_API_URL}/v1/projects?page=${currentPage}&limit=${limit}&${new URLSearchParams(queryParams)}`,
requestOptions
);
const result = await response.json();
if (!response?.ok) {
return { error: { statusText: response?.statusText } };
}
const formattedData = result?.projects?.map((project: any) => {
return {
id: project?.uid,
name: project?.name,
logo: project?.logo?.url,
description: project?.description,
maintainingTeam: project?.maintainingTeam,
lookingForFunding: project?.lookingForFunding,
tagline: project?.tagline,
};
});
return { data: { formattedData, totalProjects: result?.count } };
};
25 changes: 25 additions & 0 deletions app/actions/teams.actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"use server";

import { ITeamResponse } from "@/types/teams.types";
import { getHeader } from "@/utils/common.utils";

const teamsAPI = `${process.env.DIRECTORY_API_URL}/v1/teams`;

export const getTeamList = async (queryParams: any, currentPage = 1, limit = 50) => {
const requestOptions: RequestInit = { method: 'GET', headers: getHeader(''), cache: 'force-cache', next: { tags: ['team-list'] } };
const response = await fetch(`${teamsAPI}?page=${currentPage}&limit=${limit}&${new URLSearchParams(queryParams)}`, requestOptions);
const result = await response.json();
if (!response?.ok) {
return { isError: true };
}
const formattedData = result?.teams?.map((team: ITeamResponse) => {
return {
id: team?.uid,
name: team?.name,
logo: team?.logo?.url,
shortDescription: team?.shortDescription,
industryTags: team?.industryTags || [],
};
});
return { data: formattedData, totalItems: result?.count };
};
21 changes: 21 additions & 0 deletions app/api/revalidate/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { revalidateTag } from "next/cache";
import { NextRequest } from "next/server";

const BEARER_REGEX:any= /Bearer\s+(.+)/;

export async function POST(request: NextRequest) {
const body = await request.json();
const authToken = request.headers.get("Authorization");
const matcheResult = authToken?.match(BEARER_REGEX);
const token = matcheResult ? matcheResult[1] : null;
if (process.env.REVALIDATE_TOKEN !== token) {
return Response.json({ message: "UnAuthorized" }, { status: 401 });
}
if (!Array.isArray(body.tags)) {
return Response.json(null, { status: 400 });
}
body?.tags?.map((tag: string) => {
revalidateTag(tag);
});
return Response.json({ message: "Success" }, { status: 200 });
}
59 changes: 30 additions & 29 deletions app/members/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,24 @@ import { getCookiesFromHeaders } from '@/utils/next-helpers';
import styles from './page.module.css';
import { IMember, IMembersSearchParams } from '@/types/members.types';
import { IUserInfo } from '@/types/shared.types';
import { getMembersListOptions, getMembersOptionsFromQuery, parseMemberFilters } from '@/utils/member.utils';
import { getMemberRoles, getMembers, getMembersFilters } from '@/services/members.service';
import { getFormattedFilters, getMembersListOptions, getMembersOptionsFromQuery, getRoleTagsFromValues, parseMemberFilters } from '@/utils/member.utils';
import { getFilterValuesForQuery, getMemberListForQuery, getMemberRoles, getMembersFilters } from '@/services/members.service';
import Error from '@/components/core/error';
import MembersToolbar from '@/components/page/members/members-toolbar';
import FilterWrapper from '@/components/page/members/filter-wrapper';
import EmptyResult from '@/components/core/empty-result';
import MemberListWrapper from '@/components/page/members/member-list-wrapper';
import { Metadata } from 'next';
import { SOCIAL_IMAGE_URL } from '@/utils/constants';
import MemberInfiniteList from '@/components/page/members/member-infinite-list';

async function Page({ searchParams }: { searchParams: IMembersSearchParams }) {
const { refreshToken, userInfo, authToken } = getCookiesFromHeaders();
const { userInfo } = getCookiesFromHeaders();
const parsedUserDetails: IUserInfo = userInfo;

const { members, isError, filters, totalMembers = 0, isLoggedIn } = await getPageData(searchParams as IMembersSearchParams);

if (isError) {
if (isError || !members) {
return <Error />;
}

Expand All @@ -30,14 +31,14 @@ async function Page({ searchParams }: { searchParams: IMembersSearchParams }) {
</aside>
{/* Teams */}
<div className={styles.members__right}>
<div className={styles.members__right__content}>
<div className={styles.members__right__toolbar}>
<MembersToolbar searchParams={searchParams} totalTeams={members.length} userInfo={parsedUserDetails} />
</div>
<div className={styles.members__right__membersList} style={{ flex: 1 }}>
{members?.length > 0 && <MemberListWrapper isUserLoggedIn={isLoggedIn} members={members} totalMembers={totalMembers} userInfo={parsedUserDetails} searchParams={searchParams} />}
{members?.length === 0 && <EmptyResult />}
</div>
<div className={styles.members__right__content}>
<div className={styles.members__right__toolbar}>
<MembersToolbar searchParams={searchParams} totalTeams={totalMembers} userInfo={parsedUserDetails} />
</div>
<div className={styles.members__right__membersList} style={{ flex: 1 }}>
{members?.length > 0 && <MemberInfiniteList isUserLoggedIn={isLoggedIn} members={members} totalItems={totalMembers} userInfo={parsedUserDetails} searchParams={searchParams} />}
{members?.length === 0 && <EmptyResult />}
</div>
</div>
</div>
</section>
Expand All @@ -51,30 +52,30 @@ const getPageData = async (searchParams: IMembersSearchParams) => {
let filters: any;

try {
const { isLoggedIn } = getCookiesFromHeaders();

const optionsFromQuery = getMembersOptionsFromQuery(searchParams as IMembersSearchParams);
const listOptions = getMembersListOptions(optionsFromQuery);
const { isLoggedIn, authToken } = getCookiesFromHeaders();
const filtersFromQueryParams = getMembersOptionsFromQuery(searchParams as IMembersSearchParams);
const memberFilterQuery = getMembersListOptions(filtersFromQueryParams);

const [membersResosponse, membersFiltersResponse, roleValues] = await Promise.all([
getMembers(listOptions, '', 0, 0, isLoggedIn),
getMembersFilters(optionsFromQuery, isLoggedIn),
getMemberRoles(optionsFromQuery),
const [rawFilterValues, availableFilters, memberList, memberRoles] = await Promise.all([
getFilterValuesForQuery(null, authToken),
getFilterValuesForQuery(filtersFromQueryParams, authToken),
getMemberListForQuery(memberFilterQuery, 1, 6, authToken),
getMemberRoles(filtersFromQueryParams)
]);

const updatedFilters = parseMemberFilters(membersFiltersResponse, searchParams, isLoggedIn, roleValues);
filters = updatedFilters?.data?.formattedData;
if (membersResosponse?.error) {
isError = true;
return { isError, members, filters };
if(memberList?.isError || rawFilterValues?.isError || availableFilters?.isError || memberRoles?.isError){
return { isError: true, error: memberList?.error || rawFilterValues?.error || availableFilters?.error || memberRoles?.error };
}

members = membersResosponse?.data?.formattedData;
totalMembers = members?.length;

filters = getFormattedFilters(searchParams, rawFilterValues, availableFilters, isLoggedIn);
filters.memberRoles = getRoleTagsFromValues(memberRoles, searchParams.memberRoles);
members = memberList?.items;
totalMembers = memberList?.total;
return { isError, members, filters, totalMembers, isLoggedIn };
} catch (error) {
isError = true;
return { isError, members, filters };
console.error(error);
return { isError: true };
}
};

Expand Down
8 changes: 5 additions & 3 deletions app/projects/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import styles from './page.module.css';
import { getAllProjects } from '@/services/projects.service';
import { getCookiesFromHeaders } from '@/utils/next-helpers';
import { getProjectSelectOptions, getProjectsFiltersFromQuery } from '@/utils/projects.utils';
import ProjectsToolbar from '@/components/page/projects/project-toolbar';
Expand All @@ -8,9 +7,10 @@ import EmptyResult from '@/components/core/empty-result';
import ProjectlistWrapper from '@/components/page/projects/projectlist-wrapper';
import FilterWrapper from '@/components/page/projects/filter-wrapper';
import { getFocusAreas } from '@/services/common.service';
import { URL_QUERY_VALUE_SEPARATOR, SOCIAL_IMAGE_URL } from '@/utils/constants';
import { URL_QUERY_VALUE_SEPARATOR, SOCIAL_IMAGE_URL, ITEMS_PER_PAGE } from '@/utils/constants';
import { Metadata } from 'next';
import { getTeam, searchTeamsByName } from '@/services/teams.service';
import { getAllProjects } from '../actions/projects.actions';

export default async function Page({ searchParams }: any) {
const { projects, initialTeams, selectedTeam, isError, totalProjects, userInfo, focusAreas, isLoggedIn } = await getPageData(searchParams);
Expand Down Expand Up @@ -47,7 +47,9 @@ const getPageData = async (searchParams: any) => {
const { userInfo, isLoggedIn } = getCookiesFromHeaders();
const filterFromQuery = getProjectsFiltersFromQuery(searchParams);
const selectOpitons = getProjectSelectOptions(filterFromQuery);
const [projectsResponse, focusAreasResponse] = await Promise.all([getAllProjects(selectOpitons, 0, 0), getFocusAreas('Project', searchParams)]);
const [projectsResponse, focusAreasResponse] = await Promise.all([getAllProjects({...selectOpitons, isDeleted: false,
select: "uid,name,tagline,logo.url,description,lookingForFunding,maintainingTeam.name,maintainingTeam.logo.url"
}, 1, ITEMS_PER_PAGE), getFocusAreas('Project', searchParams)]);
if (projectsResponse?.error || focusAreasResponse?.error) {
isError = true;
return { isError };
Expand Down
48 changes: 24 additions & 24 deletions app/teams/page.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
import { getAllTeams, getTeamsFilters } from '@/services/teams.service';
import { IUserInfo } from '@/types/shared.types';
import { Metadata } from 'next';

import {getTeamListFilters } from '@/services/teams.service';
import { ITeamListOptions, ITeamsSearchParams } from '@/types/teams.types';
import { calculateTotalPages } from '@/utils/common.utils';
import { ITEMS_PER_PAGE, PAGE_ROUTES, SOCIAL_IMAGE_URL } from '@/utils/constants';
import { SOCIAL_IMAGE_URL } from '@/utils/constants';
import { getCookiesFromHeaders } from '@/utils/next-helpers';
import { getTeamsListOptions, getTeamsOptionsFromQuery } from '@/utils/team.utils';
import { Metadata } from 'next';
import { getTeamsListOptions, getTeamsOptionsFromQuery, processFilters } from '@/utils/team.utils';
import EmptyResult from '../../components/core/empty-result';
import Error from '../../components/core/error';
import { PaginationBox } from '../../components/core/pagination-box';
import FilterWrapper from '../../components/page/teams/filter-wrapper';
import TeamsList from '../../components/page/teams/team-list';
import TeamsToolbar from '../../components/page/teams/teams-toolbar';
import styles from './page.module.css';
import TeamListWrapper from '@/components/page/teams/teams-list-wrapper';
import TeamList from '@/components/page/teams/team-list';
import { getFocusAreas } from '@/services/common.service';
import { getTeamList } from '../actions/teams.actions';

async function Page({ searchParams }: { searchParams: ITeamsSearchParams }) {
const { userInfo } = getCookiesFromHeaders();

const { teams, filtersValues, isError, totalTeams, currentPage } = await getPageData(searchParams);

const totalPages = calculateTotalPages(totalTeams, ITEMS_PER_PAGE);
const { teams, filtersValues, isError, totalTeams } = await getPageData(searchParams);

if (isError) {
return <Error />;
Expand All @@ -39,7 +36,7 @@ async function Page({ searchParams }: { searchParams: ITeamsSearchParams }) {
<TeamsToolbar totalTeams={totalTeams} searchParams={searchParams} userInfo={userInfo} />
</div>
<div className={styles.team__right__teamslist}>
{teams?.length >= 0 && <TeamListWrapper teams={teams} totalTeams={totalTeams} searchParams={searchParams} userInfo={userInfo} />}
{teams?.length >= 0 && <TeamList teams={teams} totalTeams={totalTeams} searchParams={searchParams} userInfo={userInfo} />}
{teams?.length === 0 && <EmptyResult />}
</div>
</div>
Expand All @@ -55,27 +52,30 @@ const getPageData = async (searchParams: ITeamsSearchParams) => {
let isError = false;
let filtersValues;
let totalTeams = 0;
let currentPage = 1;
try {
const { authToken } = getCookiesFromHeaders();
const optionsFromQuery = getTeamsOptionsFromQuery(searchParams);
const listOptions: ITeamListOptions = getTeamsListOptions(optionsFromQuery);

currentPage = searchParams?.page ? Number(searchParams?.page) : 1;
const [teamsResponse, teamFiltersResponse] = await Promise.all([getAllTeams(authToken, listOptions, 0, 0), getTeamsFilters(optionsFromQuery, searchParams)]);
const [teamListResponse, teamListFiltersResponse, teamListFiltersForOptionsResponse, focusAreaResponse] = await Promise.all([
getTeamList(listOptions),
getTeamListFilters({}),
getTeamListFilters(listOptions),
getFocusAreas("Team",searchParams),
]);

if (teamsResponse?.error || teamFiltersResponse?.error) {
if (teamListResponse?.isError || teamListFiltersResponse?.isError || teamListFiltersForOptionsResponse?.isError || focusAreaResponse?.error) {
isError = true;
return { isError, filtersValues, totalTeams, currentPage };
return { isError };
}

teams = teamsResponse.data?.formattedData;
filtersValues = teamFiltersResponse?.data?.formattedFilters;
totalTeams = teamFiltersResponse?.data?.totalTeams;
return { teams, filtersValues, totalTeams, currentPage };
teams = teamListResponse.data;
totalTeams = teamListResponse?.totalItems;
filtersValues = processFilters(searchParams, teamListFiltersResponse?.data, teamListFiltersForOptionsResponse?.data, focusAreaResponse?.data);
return JSON.parse(JSON.stringify({ isError, filtersValues, totalTeams, teams }));
} catch (error: unknown) {
isError = true;
return { isError, filtersValues, totalTeams, currentPage };
console.error('Error in gettting teams page data', error);
return { isError };
}
};

Expand Down
Loading

0 comments on commit 7164941

Please sign in to comment.