wip: project status

feat/dashboard
Arik Chakma 2 months ago
parent 9f1b6d107f
commit 850e8e1be7
  1. 1
      src/components/Activity/ActivityPage.tsx
  2. 7
      src/components/Activity/ProjectProgress.tsx
  3. 1
      src/components/Authenticator/authenticator.ts
  4. 46
      src/components/Dashboard/DashboardPage.tsx
  5. 14
      src/components/Dashboard/LoadingProgress.tsx
  6. 114
      src/components/Dashboard/PersonalDashboard.tsx

@ -88,7 +88,6 @@ export function ActivityPage() {
}
const allProjects = response.filter((page) => page.group === 'Projects');
console.log(allProjects);
setProjectDetails(allProjects);
}

@ -10,14 +10,17 @@ type ProjectProgressType = {
projectStatus: ProjectStatusDocument & {
title: string;
};
showActions?: boolean;
};
export function ProjectProgress(props: ProjectProgressType) {
const { projectStatus } = props;
const { projectStatus, showActions = true } = props;
const userId = getUser()?.id;
const shouldShowActions =
projectStatus.submittedAt && projectStatus.submittedAt !== null;
projectStatus.submittedAt &&
projectStatus.submittedAt !== null &&
showActions;
return (
<div className="relative">

@ -48,6 +48,7 @@ function handleGuest() {
'/team/members',
'/team/member',
'/team/settings',
'/dashboard',
];
showHideAuthElements('hide');

@ -46,23 +46,41 @@ export function DashboardPage(props: DashboardPageProps) {
isActive={!selectedTeamId}
onClick={() => setSelectedTeamId(undefined)}
/>
{teamList.map((team) => (
<DashboardTab
key={team._id}
label={team.name}
isActive={team._id === selectedTeamId}
onClick={() => setSelectedTeamId(team._id)}
/>
))}
<DashboardTab
label="+ Create Team"
isActive={false}
href="/team/new"
className="border-black bg-black text-white"
/>
{isLoading && (
<>
<DashboardTabLoading />
<DashboardTabLoading />
<DashboardTabLoading />
</>
)}
{!isLoading && (
<>
{teamList.map((team) => (
<DashboardTab
key={team._id}
label={team.name}
isActive={team._id === selectedTeamId}
onClick={() => setSelectedTeamId(team._id)}
/>
))}
<DashboardTab
label="+ Create Team"
isActive={false}
href="/team/new"
className="border-black bg-black text-white"
/>
</>
)}
</div>
{!selectedTeamId && <PersonalDashboard />}
</div>
);
}
function DashboardTabLoading() {
return (
<div className="h-7 w-20 animate-pulse rounded-md border bg-gray-100"></div>
);
}

@ -0,0 +1,14 @@
type LoadingProgressProps = {};
export function LoadingProgress(props: LoadingProgressProps) {
return (
<div className="grid grid-cols-1 gap-1.5 sm:grid-cols-3">
{Array.from({ length: 6 }).map((_, index) => (
<div
key={index}
className="h-[38px] w-full animate-pulse rounded-md border border-gray-300 bg-gray-100"
></div>
))}
</div>
);
}

@ -3,6 +3,10 @@ import { httpGet } from '../../lib/http';
import type { UserProgress } from '../TeamProgress/TeamProgressPage';
import type { ProjectStatusDocument } from '../Projects/ListProjectSolutions';
import { ResourceProgress } from '../Activity/ResourceProgress';
import { ProjectProgress } from '../Activity/ProjectProgress';
import type { PageType } from '../CommandMenu/CommandMenu';
import { useToast } from '../../hooks/use-toast';
import { LoadingProgress } from './LoadingProgress';
type UserDashboardResponse = {
progresses: UserProgress[];
@ -12,13 +16,14 @@ type UserDashboardResponse = {
type PersonalDashboardProps = {};
export function PersonalDashboard(props: PersonalDashboardProps) {
const toast = useToast();
const [isLoading, setIsLoading] = useState(true);
const [projectDetails, setProjectDetails] = useState<PageType[]>([]);
const [personalDashboardDetails, setPersonalDashboardDetails] =
useState<UserDashboardResponse>();
async function loadProgress() {
setIsLoading(true);
const { response: progressList, error } =
await httpGet<UserDashboardResponse>(
`${import.meta.env.PUBLIC_API_URL}/v1-user-dashboard`,
@ -31,8 +36,26 @@ export function PersonalDashboard(props: PersonalDashboardProps) {
setPersonalDashboardDetails(progressList);
}
async function loadAllProjectDetails() {
const { error, response } = await httpGet<PageType[]>(`/pages.json`);
if (error) {
toast.error(error.message || 'Something went wrong');
return;
}
if (!response) {
return [];
}
const allProjects = response.filter((page) => page.group === 'Projects');
setProjectDetails(allProjects);
}
useEffect(() => {
loadProgress().finally(() => setIsLoading(false));
Promise.allSettled([loadProgress(), loadAllProjectDetails()]).finally(() =>
setIsLoading(false),
);
}, []);
const learningRoadmaps =
@ -55,37 +78,68 @@ export function PersonalDashboard(props: PersonalDashboardProps) {
return updatedAtB.getTime() - updatedAtA.getTime();
});
const enrichedProjects =
personalDashboardDetails?.projects?.map((project) => {
const projectDetail = projectDetails.find(
(page) => page.id === project.projectId,
);
return {
...project,
title: projectDetail?.title || 'N/A',
};
}) || [];
return (
<section className="mt-8">
<h2 className="text-xs uppercase text-gray-400">
<h2 className="mb-3 text-xs uppercase text-gray-400">
Progress and Bookmarks
</h2>
<div className="mt-3 grid grid-cols-1 gap-1.5 sm:grid-cols-3">
{learningRoadmapsToShow.map((roadmap) => {
const learningCount = roadmap.learning || 0;
const doneCount = roadmap.done || 0;
const totalCount = roadmap.total || 0;
const skippedCount = roadmap.skipped || 0;
return (
<ResourceProgress
key={roadmap.resourceId}
isCustomResource={roadmap?.isCustomResource || false}
doneCount={doneCount > totalCount ? totalCount : doneCount}
learningCount={
learningCount > totalCount ? totalCount : learningCount
}
totalCount={totalCount}
skippedCount={skippedCount}
resourceId={roadmap.resourceId}
resourceType="roadmap"
updatedAt={roadmap.updatedAt}
title={roadmap.resourceTitle}
showActions={false}
/>
);
})}
</div>
{isLoading && <LoadingProgress />}
{!isLoading && learningRoadmapsToShow.length > 0 && (
<div className="grid grid-cols-1 gap-1.5 sm:grid-cols-3">
{learningRoadmapsToShow.map((roadmap) => {
const learningCount = roadmap.learning || 0;
const doneCount = roadmap.done || 0;
const totalCount = roadmap.total || 0;
const skippedCount = roadmap.skipped || 0;
return (
<ResourceProgress
key={roadmap.resourceId}
isCustomResource={roadmap?.isCustomResource || false}
doneCount={doneCount > totalCount ? totalCount : doneCount}
learningCount={
learningCount > totalCount ? totalCount : learningCount
}
totalCount={totalCount}
skippedCount={skippedCount}
resourceId={roadmap.resourceId}
resourceType="roadmap"
updatedAt={roadmap.updatedAt}
title={roadmap.resourceTitle}
showActions={false}
/>
);
})}
</div>
)}
<h2 className="mb-3 mt-6 text-xs uppercase text-gray-400">My Projects</h2>
{isLoading && <LoadingProgress />}
{!isLoading && enrichedProjects.length > 0 && (
<div className="grid grid-cols-1 gap-1.5 sm:grid-cols-3">
{enrichedProjects.map((project) => {
return (
<ProjectProgress
key={project.projectId}
projectStatus={project}
showActions={false}
/>
);
})}
</div>
)}
</section>
);
}

Loading…
Cancel
Save