Hero roadmap section updates

pull/4559/head
Kamran Ahmed 1 year ago
parent e5e0a7c8c5
commit 7ec5e30b51
  1. 7
      src/components/CustomRoadmap/CreateRoadmap/CreateRoadmapButton.tsx
  2. 25
      src/components/HeroSection/FavoriteRoadmaps.tsx
  3. 103
      src/components/HeroSection/HeroRoadmaps.tsx

@ -12,10 +12,12 @@ import { useState } from 'react';
type CreateRoadmapButtonProps = { type CreateRoadmapButtonProps = {
className?: string; className?: string;
type?: AllowedCustomRoadmapType; type?: AllowedCustomRoadmapType;
text?: string;
teamId?: string;
}; };
export function CreateRoadmapButton(props: CreateRoadmapButtonProps) { export function CreateRoadmapButton(props: CreateRoadmapButtonProps) {
const { className, type } = props; const { teamId, className, type, text = 'Create your own Roadmap' } = props;
const [isCreatingRoadmap, setIsCreatingRoadmap] = useState(false); const [isCreatingRoadmap, setIsCreatingRoadmap] = useState(false);
@ -31,6 +33,7 @@ export function CreateRoadmapButton(props: CreateRoadmapButtonProps) {
<> <>
{isCreatingRoadmap && ( {isCreatingRoadmap && (
<CreateRoadmapModal <CreateRoadmapModal
teamId={teamId}
type={type} type={type}
onClose={() => { onClose={() => {
setIsCreatingRoadmap(false); setIsCreatingRoadmap(false);
@ -46,7 +49,7 @@ export function CreateRoadmapButton(props: CreateRoadmapButtonProps) {
onClick={toggleCreateRoadmapHandler} onClick={toggleCreateRoadmapHandler}
> >
<Plus size={16} /> <Plus size={16} />
Create your own Roadmap {text}
</button> </button>
</> </>
); );

@ -1,8 +1,9 @@
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { EmptyProgress } from './EmptyProgress'; import { EmptyProgress } from './EmptyProgress';
import { httpGet } from '../../lib/http'; import { httpGet } from '../../lib/http';
import { HeroRoadmaps } from './HeroRoadmaps'; import { HeroRoadmaps, type HeroTeamRoadmaps } from './HeroRoadmaps';
import { isLoggedIn } from '../../lib/jwt'; import { isLoggedIn } from '../../lib/jwt';
import type { AllowedMemberRoles } from '../ShareOptions/ShareTeamMemberList.tsx';
export type UserProgressResponse = { export type UserProgressResponse = {
resourceId: string; resourceId: string;
@ -15,6 +16,11 @@ export type UserProgressResponse = {
total: number; total: number;
updatedAt: Date; updatedAt: Date;
isCustomResource: boolean; isCustomResource: boolean;
team?: {
name: string;
id: string;
role: AllowedMemberRoles;
};
}[]; }[];
function renderProgress(progressList: UserProgressResponse) { function renderProgress(progressList: UserProgressResponse) {
@ -114,8 +120,22 @@ export function FavoriteRoadmaps() {
} }
const hasProgress = progress?.length > 0; const hasProgress = progress?.length > 0;
const customRoadmaps = progress?.filter((p) => p.isCustomResource); const customRoadmaps = progress?.filter(
(p) => p.isCustomResource && !p.team?.name
);
const defaultRoadmaps = progress?.filter((p) => !p.isCustomResource); const defaultRoadmaps = progress?.filter((p) => !p.isCustomResource);
const teamRoadmaps: HeroTeamRoadmaps = progress
?.filter((p) => p.isCustomResource && p.team?.name)
.reduce((acc: HeroTeamRoadmaps, curr) => {
const currTeam = curr.team!;
if (!acc[currTeam.name]) {
acc[currTeam.name] = [];
}
acc[currTeam.name].push(curr);
return acc;
}, {});
return ( return (
<div <div
@ -130,6 +150,7 @@ export function FavoriteRoadmaps() {
{!isLoading && progress?.length == 0 && <EmptyProgress />} {!isLoading && progress?.length == 0 && <EmptyProgress />}
{hasProgress && ( {hasProgress && (
<HeroRoadmaps <HeroRoadmaps
teamRoadmaps={teamRoadmaps}
customRoadmaps={customRoadmaps} customRoadmaps={customRoadmaps}
progress={defaultRoadmaps} progress={defaultRoadmaps}
isLoading={isLoading} isLoading={isLoading}

@ -3,10 +3,10 @@ import { CheckIcon } from '../ReactIcons/CheckIcon';
import { MarkFavorite } from '../FeaturedItems/MarkFavorite'; import { MarkFavorite } from '../FeaturedItems/MarkFavorite';
import { Spinner } from '../ReactIcons/Spinner'; import { Spinner } from '../ReactIcons/Spinner';
import type { ResourceType } from '../../lib/resource-progress'; import type { ResourceType } from '../../lib/resource-progress';
import { MapIcon } from 'lucide-react'; import { MapIcon, Users2 } from 'lucide-react';
import { CreateRoadmapButton } from '../CustomRoadmap/CreateRoadmap/CreateRoadmapButton'; import { CreateRoadmapButton } from '../CustomRoadmap/CreateRoadmap/CreateRoadmapButton';
import { CreateRoadmapModal } from '../CustomRoadmap/CreateRoadmap/CreateRoadmapModal'; import { CreateRoadmapModal } from '../CustomRoadmap/CreateRoadmap/CreateRoadmapModal';
import { useState } from 'react'; import { type ReactNode, useState } from 'react';
import { TeamAnnouncement } from '../TeamAnnouncement'; import { TeamAnnouncement } from '../TeamAnnouncement';
type ProgressRoadmapProps = { type ProgressRoadmapProps = {
@ -56,7 +56,7 @@ function HeroRoadmap(props: ProgressRoadmapProps) {
type ProgressTitleProps = { type ProgressTitleProps = {
icon: any; icon: any;
isLoading?: boolean; isLoading?: boolean;
title: string; title: string | ReactNode;
}; };
export function HeroTitle(props: ProgressTitleProps) { export function HeroTitle(props: ProgressTitleProps) {
@ -74,25 +74,39 @@ export function HeroTitle(props: ProgressTitleProps) {
</p> </p>
); );
} }
export type HeroTeamRoadmaps = Record<string, UserProgressResponse>;
type ProgressListProps = { type ProgressListProps = {
progress: UserProgressResponse; progress: UserProgressResponse;
customRoadmaps: UserProgressResponse; customRoadmaps: UserProgressResponse;
teamRoadmaps?: HeroTeamRoadmaps;
isLoading?: boolean; isLoading?: boolean;
}; };
export function HeroRoadmaps(props: ProgressListProps) { export function HeroRoadmaps(props: ProgressListProps) {
const { progress, isLoading = false, customRoadmaps } = props; const {
teamRoadmaps = {},
progress,
isLoading = false,
customRoadmaps,
} = props;
const [isCreatingRoadmap, setIsCreatingRoadmap] = useState(false); const [isCreatingRoadmap, setIsCreatingRoadmap] = useState(false);
const [creatingRoadmapTeamId, setCreatingRoadmapTeamId] = useState<string>();
return ( return (
<div className="relative pb-12 pt-4 sm:pt-7"> <div className="relative pb-12 pt-4 sm:pt-7">
<p className="mb-7 text-sm mt-2"> <p className="mb-7 mt-2 text-sm">
<TeamAnnouncement /> <TeamAnnouncement />
</p> </p>
{isCreatingRoadmap && ( {isCreatingRoadmap && (
<CreateRoadmapModal onClose={() => setIsCreatingRoadmap(false)} /> <CreateRoadmapModal
teamId={creatingRoadmapTeamId}
onClose={() => {
setIsCreatingRoadmap(false);
setCreatingRoadmapTeamId(undefined);
}}
/>
)} )}
{ {
<HeroTitle <HeroTitle
@ -168,6 +182,83 @@ export function HeroRoadmaps(props: ProgressListProps) {
</div> </div>
)} )}
</div> </div>
{Object.keys(teamRoadmaps).map((teamName) => {
const currentTeam: UserProgressResponse[0]['team'] =
teamRoadmaps?.[teamName]?.[0]?.team;
const roadmapsList = teamRoadmaps[teamName].filter(
(roadmap) => !!roadmap.resourceTitle
);
const canManageTeam = ['admin', 'manager'].includes(currentTeam?.role!);
return (
<div className="mt-5">
{
<HeroTitle
icon={<Users2 className="mr-1.5 h-[14px] w-[14px]" />}
title={
<>
Team{' '}
<a
className="mx-1 font-medium underline underline-offset-2 transition-colors hover:text-gray-300"
href={`/team/progress?t=${currentTeam?.id}`}
>
{teamName}
</a>
Roadmaps
</>
}
/>
}
{roadmapsList.length === 0 && (
<p className="rounded-md border border-dashed border-gray-800 p-2 text-sm text-gray-600">
Team does not have any roadmaps yet.{' '}
{canManageTeam && (
<button
className="text-gray-500 underline underline-offset-2 hover:text-gray-400"
onClick={() => {
setCreatingRoadmapTeamId(currentTeam?.id);
setIsCreatingRoadmap(true);
}}
>
Create one!
</button>
)}
</p>
)}
{roadmapsList.length > 0 && (
<div className="grid grid-cols-1 gap-2 sm:grid-cols-2 md:grid-cols-3">
{roadmapsList.map((customRoadmap) => {
return (
<HeroRoadmap
key={customRoadmap.resourceId}
resourceId={customRoadmap.resourceId}
resourceType={'roadmap'}
resourceTitle={customRoadmap.resourceTitle}
percentageDone={
((customRoadmap.skipped + customRoadmap.done) /
customRoadmap.total) *
100
}
url={`/r?id=${customRoadmap.resourceId}`}
allowFavorite={false}
/>
);
})}
{canManageTeam && (
<CreateRoadmapButton
teamId={currentTeam?.id}
text="Create Team Roadmap"
/>
)}
</div>
)}
</div>
);
})}
</div> </div>
); );
} }

Loading…
Cancel
Save