Update stack message

pull/7102/head
Kamran Ahmed 2 months ago
parent 298b137a7d
commit bbcd7e18e5
  1. 4
      src/components/Dashboard/DashboardBookmarkCard.tsx
  2. 32
      src/components/Dashboard/EmptyStackMessage.tsx
  3. 218
      src/components/Dashboard/ProgressStack.tsx

@ -27,9 +27,9 @@ export function DashboardBookmarkCard(props: DashboardBookmarkCardProps) {
<a
href={url}
key={resourceId}
className="group relative flex w-full items-center gap-2 text-left text-sm hover:text-black hover:underline"
className="group relative flex flex-row items-center gap-2 rounded-md border border-gray-300 bg-white px-1.5 py-2 text-left text-sm transition-all hover:border-gray-400"
>
<Bookmark className="size-4 fill-current text-gray-400" />
<Bookmark className="size-4 fill-current text-gray-300" />
<h4 className="truncate font-medium text-gray-900">{resourceTitle}</h4>
</a>
);

@ -0,0 +1,32 @@
type EmptyStackMessageProps = {
number: number;
title: string;
description: string;
buttonText: string;
buttonLink: string;
};
export function EmptyStackMessage(props: EmptyStackMessageProps) {
const { number, title, description, buttonText, buttonLink } = props;
return (
<div className="absolute inset-0 flex items-center justify-center rounded-md bg-black/50">
<div className="flex max-w-[200px] flex-col items-center justify-center rounded-md bg-white p-4 shadow-sm">
<span className="flex h-8 w-8 items-center justify-center rounded-full bg-gray-300 text-white">
{number}
</span>
<div className="my-3 text-center">
<h3 className="text-sm font-medium text-black">{title}</h3>
<p className="text-center text-xs text-gray-500">{description}</p>
</div>
<a
href={buttonLink}
className="rounded-md bg-black px-3 py-1 text-xs text-white transition-transform hover:scale-105 hover:bg-gray-900"
>
{buttonText}
</a>
</div>
</div>
);
}

@ -14,6 +14,7 @@ import { cn } from '../../lib/classname';
import { DashboardProgressCard } from './DashboardProgressCard';
import { useStore } from '@nanostores/react';
import { $accountStreak, type StreakResponse } from '../../stores/streak';
import { EmptyStackMessage } from './EmptyStackMessage.tsx';
type ProgressStackProps = {
progresses: UserProgress[];
@ -26,8 +27,8 @@ type ProgressStackProps = {
};
const MAX_PROGRESS_TO_SHOW = 5;
const MAX_BOOKMARKS_TO_SHOW = 5;
const MAX_PROJECTS_TO_SHOW = 8;
const MAX_BOOKMARKS_TO_SHOW = 8;
type ProgressLaneProps = {
title: string;
@ -74,7 +75,7 @@ function ProgressLane(props: ProgressLaneProps) {
{linkText && linkHref && (
<a
href={linkHref}
className="flex items-center gap-1 text-xs text-gray-500"
className="flex items-center gap-1 text-xs text-gray-500 hover:text-black"
>
<ArrowUpRight size={12} />
{linkText}
@ -83,7 +84,7 @@ function ProgressLane(props: ProgressLaneProps) {
</div>
)}
<div className="mt-4 flex flex-grow flex-col gap-2">
<div className="mt-4 flex flex-grow flex-col gap-1.5">
{isLoading && (
<>
{Array.from({ length: loadingSkeletonCount }).map((_, index) => (
@ -166,98 +167,139 @@ export function ProgressStack(props: ProgressStackProps) {
</div>
<div className="mt-2 grid min-h-[330px] grid-cols-1 gap-2 sm:grid-cols-2 md:grid-cols-3">
<ProgressLane
title={'Your Progress'}
isLoading={isLoading}
loadingSkeletonCount={5}
isEmpty={userProgressesToShow.length === 0}
emptyMessage={'Update your Progress'}
emptyIcon={Map}
emptyLinkText={'Explore Roadmaps'}
>
{userProgressesToShow.length > 0 && (
<>
{userProgressesToShow.map((progress) => {
return (
<DashboardProgressCard
key={progress.resourceId}
progress={progress}
/>
);
})}
</>
)}
{userProgresses.length > MAX_PROGRESS_TO_SHOW && (
<ShowAllButton
showAll={showAllProgresses}
setShowAll={setShowAllProgresses}
count={userProgresses.length}
maxCount={MAX_PROGRESS_TO_SHOW}
className="mb-0.5 mt-3"
<div className="relative">
{!isLoading && bookmarksToShow.length === 0 && (
<EmptyStackMessage
number={1}
title={'Bookmark Roadmaps'}
description={'Bookmark some roadmaps to access them quickly'}
buttonText={'Explore Roadmaps'}
buttonLink={'/roadmaps'}
/>
)}
</ProgressLane>
<ProgressLane
title={'Projects'}
isLoading={isLoading}
loadingSkeletonClassName={'h-5'}
loadingSkeletonCount={8}
isEmpty={projectsToShow.length === 0}
emptyMessage={'No projects started'}
emptyIcon={FolderKanban}
emptyLinkText={'Explore Projects'}
emptyLinkHref={'/projects'}
>
{projectsToShow.map((project) => {
return (
<DashboardProjectCard key={project.projectId} project={project} />
);
})}
{projects.length > MAX_PROJECTS_TO_SHOW && (
<ShowAllButton
showAll={showAllProjects}
setShowAll={setShowAllProjects}
count={projects.length}
maxCount={MAX_PROJECTS_TO_SHOW}
className="mb-0.5 mt-3"
<ProgressLane
title={'Bookmarks'}
isLoading={isLoading}
loadingSkeletonCount={5}
linkHref={'/roadmaps'}
linkText={'Roadmaps'}
isEmpty={bookmarksToShow.length === 0}
emptyIcon={Bookmark}
emptyMessage={'No bookmarks to show'}
emptyLinkHref={'/roadmaps'}
emptyLinkText={'Explore Roadmaps'}
>
{bookmarksToShow.map((progress) => {
return (
<DashboardBookmarkCard
key={progress.resourceId}
bookmark={progress}
/>
);
})}
{bookmarkedProgresses.length > MAX_BOOKMARKS_TO_SHOW && (
<ShowAllButton
showAll={showAllBookmarks}
setShowAll={setShowAllBookmarks}
count={bookmarkedProgresses.length}
maxCount={MAX_BOOKMARKS_TO_SHOW}
className="mb-0.5 mt-3"
/>
)}
</ProgressLane>
</div>
<div className="relative">
{!isLoading && userProgressesToShow.length === 0 && (
<EmptyStackMessage
number={2}
title={'Track Progress'}
description={'Pick your first roadmap and start learning'}
buttonText={'Explore roadmaps'}
buttonLink={'/roadmaps'}
/>
)}
</ProgressLane>
<ProgressLane
title={'Progress'}
linkHref={'/roadmaps'}
linkText={'Roadmaps'}
isLoading={isLoading}
loadingSkeletonCount={5}
isEmpty={userProgressesToShow.length === 0}
emptyMessage={'Update your Progress'}
emptyIcon={Map}
emptyLinkText={'Explore Roadmaps'}
>
{userProgressesToShow.length > 0 && (
<>
{userProgressesToShow.map((progress) => {
return (
<DashboardProgressCard
key={progress.resourceId}
progress={progress}
/>
);
})}
</>
)}
<ProgressLane
title={'Bookmarks'}
isLoading={isLoading}
loadingSkeletonClassName={'h-5'}
loadingSkeletonCount={8}
linkHref={'/roadmaps'}
linkText={'Explore'}
isEmpty={bookmarksToShow.length === 0}
emptyIcon={Bookmark}
emptyMessage={'No bookmarks to show'}
emptyLinkHref={'/roadmaps'}
emptyLinkText={'Explore Roadmaps'}
>
{bookmarksToShow.map((progress) => {
return (
<DashboardBookmarkCard
key={progress.resourceId}
bookmark={progress}
{userProgresses.length > MAX_PROGRESS_TO_SHOW && (
<ShowAllButton
showAll={showAllProgresses}
setShowAll={setShowAllProgresses}
count={userProgresses.length}
maxCount={MAX_PROGRESS_TO_SHOW}
className="mb-0.5 mt-3"
/>
);
})}
{bookmarkedProgresses.length > MAX_BOOKMARKS_TO_SHOW && (
<ShowAllButton
showAll={showAllBookmarks}
setShowAll={setShowAllBookmarks}
count={bookmarkedProgresses.length}
maxCount={MAX_BOOKMARKS_TO_SHOW}
className="mb-0.5 mt-3"
/>
)}
</ProgressLane>
)}
</ProgressLane>
</div>
<div className="relative">
<ProgressLane
title={'Projects'}
linkHref={'/projects'}
linkText={'Projects'}
isLoading={isLoading}
loadingSkeletonClassName={'h-5'}
loadingSkeletonCount={8}
isEmpty={projectsToShow.length === 0}
emptyMessage={'No projects started'}
emptyIcon={FolderKanban}
emptyLinkText={'Explore Projects'}
emptyLinkHref={'/projects'}
>
{!isLoading && projectsToShow.length === 0 && (
<EmptyStackMessage
number={3}
title={'Build your first project'}
description={'Pick a project to practice and start building'}
buttonText={'Explore Projects'}
buttonLink={'/projects'}
/>
)}
{projectsToShow.map((project) => {
return (
<DashboardProjectCard
key={project.projectId}
project={project}
/>
);
})}
{projects.length > MAX_PROJECTS_TO_SHOW && (
<ShowAllButton
showAll={showAllProjects}
setShowAll={setShowAllProjects}
count={projects.length}
maxCount={MAX_PROJECTS_TO_SHOW}
className="mb-0.5 mt-3"
/>
)}
</ProgressLane>
</div>
</div>
</>
);

Loading…
Cancel
Save