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. 18
      src/components/Dashboard/DashboardPage.tsx
  5. 14
      src/components/Dashboard/LoadingProgress.tsx
  6. 64
      src/components/Dashboard/PersonalDashboard.tsx

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

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

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

@ -46,6 +46,16 @@ export function DashboardPage(props: DashboardPageProps) {
isActive={!selectedTeamId} isActive={!selectedTeamId}
onClick={() => setSelectedTeamId(undefined)} onClick={() => setSelectedTeamId(undefined)}
/> />
{isLoading && (
<>
<DashboardTabLoading />
<DashboardTabLoading />
<DashboardTabLoading />
</>
)}
{!isLoading && (
<>
{teamList.map((team) => ( {teamList.map((team) => (
<DashboardTab <DashboardTab
key={team._id} key={team._id}
@ -60,9 +70,17 @@ export function DashboardPage(props: DashboardPageProps) {
href="/team/new" href="/team/new"
className="border-black bg-black text-white" className="border-black bg-black text-white"
/> />
</>
)}
</div> </div>
{!selectedTeamId && <PersonalDashboard />} {!selectedTeamId && <PersonalDashboard />}
</div> </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 { UserProgress } from '../TeamProgress/TeamProgressPage';
import type { ProjectStatusDocument } from '../Projects/ListProjectSolutions'; import type { ProjectStatusDocument } from '../Projects/ListProjectSolutions';
import { ResourceProgress } from '../Activity/ResourceProgress'; 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 = { type UserDashboardResponse = {
progresses: UserProgress[]; progresses: UserProgress[];
@ -12,13 +16,14 @@ type UserDashboardResponse = {
type PersonalDashboardProps = {}; type PersonalDashboardProps = {};
export function PersonalDashboard(props: PersonalDashboardProps) { export function PersonalDashboard(props: PersonalDashboardProps) {
const toast = useToast();
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
const [projectDetails, setProjectDetails] = useState<PageType[]>([]);
const [personalDashboardDetails, setPersonalDashboardDetails] = const [personalDashboardDetails, setPersonalDashboardDetails] =
useState<UserDashboardResponse>(); useState<UserDashboardResponse>();
async function loadProgress() { async function loadProgress() {
setIsLoading(true);
const { response: progressList, error } = const { response: progressList, error } =
await httpGet<UserDashboardResponse>( await httpGet<UserDashboardResponse>(
`${import.meta.env.PUBLIC_API_URL}/v1-user-dashboard`, `${import.meta.env.PUBLIC_API_URL}/v1-user-dashboard`,
@ -31,8 +36,26 @@ export function PersonalDashboard(props: PersonalDashboardProps) {
setPersonalDashboardDetails(progressList); 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(() => { useEffect(() => {
loadProgress().finally(() => setIsLoading(false)); Promise.allSettled([loadProgress(), loadAllProjectDetails()]).finally(() =>
setIsLoading(false),
);
}, []); }, []);
const learningRoadmaps = const learningRoadmaps =
@ -55,12 +78,26 @@ export function PersonalDashboard(props: PersonalDashboardProps) {
return updatedAtB.getTime() - updatedAtA.getTime(); 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 ( return (
<section className="mt-8"> <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 Progress and Bookmarks
</h2> </h2>
<div className="mt-3 grid grid-cols-1 gap-1.5 sm:grid-cols-3"> {isLoading && <LoadingProgress />}
{!isLoading && learningRoadmapsToShow.length > 0 && (
<div className="grid grid-cols-1 gap-1.5 sm:grid-cols-3">
{learningRoadmapsToShow.map((roadmap) => { {learningRoadmapsToShow.map((roadmap) => {
const learningCount = roadmap.learning || 0; const learningCount = roadmap.learning || 0;
const doneCount = roadmap.done || 0; const doneCount = roadmap.done || 0;
@ -86,6 +123,23 @@ export function PersonalDashboard(props: PersonalDashboardProps) {
); );
})} })}
</div> </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> </section>
); );
} }

Loading…
Cancel
Save