1
0
mirror of https://github.com/kamranahmedse/developer-roadmap.git synced 2025-09-25 16:39:02 +02:00

feat: add project status (#7252)

* feat: add project status

* Update project card and fix warnings

* Add loading indicator to project card

---------

Co-authored-by: Kamran Ahmed <kamranahmed.se@gmail.com>
This commit is contained in:
Arik Chakma
2024-10-01 19:27:39 +06:00
committed by GitHub
parent e3ca03e531
commit 52c1b20f56
2 changed files with 90 additions and 10 deletions

View File

@@ -1,7 +1,7 @@
import { ProjectCard } from './ProjectCard.tsx';
import { HeartHandshake, Trash2 } from 'lucide-react';
import { cn } from '../../lib/classname.ts';
import { useMemo, useState } from 'react';
import { useEffect, useMemo, useState } from 'react';
import {
projectDifficulties,
type ProjectDifficultyType,
@@ -12,6 +12,8 @@ import {
getUrlParams,
setUrlParams,
} from '../../lib/browser.ts';
import { httpPost } from '../../lib/http.ts';
import { isLoggedIn } from '../../lib/jwt.ts';
type DifficultyButtonProps = {
difficulty: ProjectDifficultyType;
@@ -38,6 +40,11 @@ function DifficultyButton(props: DifficultyButtonProps) {
);
}
export type ListProjectStatusesResponse = Record<
string,
'completed' | 'started'
>;
type ProjectsListProps = {
projects: ProjectFileType[];
userCounts: Record<string, number>;
@@ -50,6 +57,25 @@ export function ProjectsList(props: ProjectsListProps) {
const [difficulty, setDifficulty] = useState<
ProjectDifficultyType | undefined
>(urlDifficulty);
const [projectStatuses, setProjectStatuses] =
useState<ListProjectStatusesResponse>();
const loadProjectStatuses = async () => {
const projectIds = projects.map((project) => project.id);
const { response, error } = await httpPost(
`${import.meta.env.PUBLIC_API_URL}/v1-list-project-statuses`,
{
projectIds,
},
);
if (error || !response) {
console.error(error);
return;
}
setProjectStatuses(response);
};
const projectsByDifficulty: Map<ProjectDifficultyType, ProjectFileType[]> =
useMemo(() => {
@@ -72,12 +98,21 @@ export function ProjectsList(props: ProjectsListProps) {
? projectsByDifficulty.get(difficulty) || []
: projects;
useEffect(() => {
if (!isLoggedIn()) {
return;
}
loadProjectStatuses().finally();
}, []);
return (
<div className="flex flex-col">
<div className="my-2.5 flex items-center justify-between">
<div className="flex flex-wrap gap-1">
{projectDifficulties.map((projectDifficulty) => (
<DifficultyButton
key={projectDifficulty}
onClick={() => {
setDifficulty(projectDifficulty);
setUrlParams({ difficulty: projectDifficulty });
@@ -130,7 +165,18 @@ export function ProjectsList(props: ProjectsListProps) {
})
.map((matchingProject) => {
const count = userCounts[matchingProject?.id] || 0;
return <ProjectCard project={matchingProject} userCount={count} />;
return (
<ProjectCard
key={matchingProject.id}
project={matchingProject}
userCount={count}
status={
projectStatuses
? (projectStatuses?.[matchingProject.id] ?? 'none')
: undefined
}
/>
);
})}
</div>
</div>