-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProjects.tsx
More file actions
54 lines (47 loc) · 1.84 KB
/
Projects.tsx
File metadata and controls
54 lines (47 loc) · 1.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import * as React from "react";
import { ProjectData, ProjectsRequestTimeoutError, SERVER } from "./api";
export interface NameById {
[key: number]: string;
}
interface ProjectsProps {
selectedUser?: number;
nameById: NameById;
}
export default function Projects({ selectedUser, nameById }: ProjectsProps) {
const [projects, setProjects] = React.useState<ProjectData[] | null>(() => null);
const [hasMoreResults, setHasMoreResults] = React.useState<boolean>(false);
const fetchProjects = React.useCallback((startAfter?: ProjectData, overwrite = false) => {
SERVER.getProjects({ pageSize: 5, startAfter, userId: selectedUser?.toString() }).then((page) => {
if (overwrite) {
setProjects(_ => ([...(page.projects ?? [])]));
} else {
setProjects(projects => [...(projects ?? []), ...page.projects]);
}
setHasMoreResults(page.hasMoreResults);
}).catch((error) => {
if (error instanceof ProjectsRequestTimeoutError) {
alert(error.message);
return;
}
alert("Something went wrong...");
});
}, [selectedUser]);
const loadMore = React.useCallback(() => {
const start = projects?.length ? projects[projects.length - 1] : undefined;
fetchProjects(start);
}, [projects, fetchProjects])
React.useEffect(() => {
fetchProjects(undefined, true);
}, [selectedUser, fetchProjects]);
return (
<div className="projects">
{projects?.length === 0 && (<div>No projects found.</div>)}
{projects?.map(project => (
<div className="project" key={`project-${project.id}`}>
<div>(ID {project.id}) {project.title}</div><div>{nameById[project.creatorId]}</div>
</div>
))}
<button disabled={!hasMoreResults} onClick={loadMore}>{projects?.length ? `${projects.length} Project(s) Loaded - ` : ''}Load more</button>
</div>
);
}