Add progress loading on homepage roadmaps

pull/4053/head
Kamran Ahmed 1 year ago
parent 3cf3786476
commit 08e52a3d18
  1. 4
      src/components/FeaturedItems/FeaturedItem.astro
  2. 20
      src/components/Navigation/Navigation.astro
  3. 2
      src/layouts/BaseLayout.astro
  4. 57
      src/lib/home-progress.ts
  5. 2
      src/pages/404.astro
  6. 27
      src/pages/index.astro

@ -13,14 +13,14 @@ const { isUpcoming = false, isNew = false, text, url } = Astro.props;
<a <a
class:list={[ class:list={[
'group border border-slate-800 bg-slate-900 p-2.5 sm:p-3.5 block no-underline rounded-lg relative text-slate-400 font-regular text-md hover:border-slate-600 hover:text-slate-100', 'group border border-slate-800 bg-slate-900 p-2.5 sm:p-3.5 block no-underline rounded-lg relative text-slate-400 font-regular text-md hover:border-slate-600 hover:text-slate-100 overflow-hidden',
{ {
'opacity-50': isUpcoming, 'opacity-50': isUpcoming,
}, },
]} ]}
href={url} href={url}
> >
<span class='text-slate-400'> <span class='text-slate-400 relative z-20'>
{text} {text}
</span> </span>

@ -5,7 +5,11 @@ import AccountDropdown from './AccountDropdown.astro';
<div class='bg-slate-900 py-5 text-white sm:py-8'> <div class='bg-slate-900 py-5 text-white sm:py-8'>
<nav class='container flex items-center justify-between'> <nav class='container flex items-center justify-between'>
<a class='flex items-center text-lg font-medium text-white' href='/' aria-label="roadmap.sh"> <a
class='flex items-center text-lg font-medium text-white'
href='/'
aria-label='roadmap.sh'
>
<Icon icon='logo' /> <Icon icon='logo' />
</a> </a>
@ -26,9 +30,12 @@ import AccountDropdown from './AccountDropdown.astro';
<a href='/videos' class='text-gray-400 hover:text-white'>Videos</a> <a href='/videos' class='text-gray-400 hover:text-white'>Videos</a>
</li> </li>
<li> <li>
<kbd data-command-menu class="hidden sm:flex items-center text-gray-400 border border-gray-800 rounded-md px-2.5 py-1 text-sm hover:bg-gray-800 hover:cursor-pointer"> <kbd
<Icon icon='search' class='h-3 w-3 mr-2' /> data-command-menu
<kbd class='font-sans mr-1'>⌘</kbd><kbd class='font-sans'>K</kbd> class='hidden items-center rounded-md border border-gray-800 px-2.5 py-1 text-sm text-gray-400 hover:cursor-pointer hover:bg-gray-800 sm:flex'
>
<Icon icon='search' class='mr-2 h-3 w-3' />
<kbd class='mr-1 font-sans'>⌘</kbd><kbd class='font-sans'>K</kbd>
</kbd> </kbd>
</li> </li>
</ul> </ul>
@ -97,10 +104,7 @@ import AccountDropdown from './AccountDropdown.astro';
<!-- Links for logged in users --> <!-- Links for logged in users -->
<li data-auth-required class='hidden'> <li data-auth-required class='hidden'>
<a <a href='/account' class='text-xl hover:text-blue-300 md:text-lg'>
href='/account'
class='text-xl hover:text-blue-300 md:text-lg'
>
Account Account
</a> </a>
</li> </li>

@ -149,8 +149,8 @@ const gaPageIdentifier = Astro.url.pathname
</slot> </slot>
<Authenticator /> <Authenticator />
<PageProgress initialMessage={initialLoadingMessage} client:idle />
<CommandMenu client:idle /> <CommandMenu client:idle />
<PageProgress initialMessage={initialLoadingMessage} client:idle />
<PageSponsor <PageSponsor
gaPageIdentifier={briefTitle || gaPageIdentifier} gaPageIdentifier={briefTitle || gaPageIdentifier}
client:load client:load

@ -0,0 +1,57 @@
import { httpGet } from './http';
import { isLoggedIn } from './jwt';
type UserProgressResponse = {
resourceId: string;
resourceType: 'roadmap' | 'best-practice';
done: number;
learning: number;
skipped: number;
total: number;
updatedAt: Date;
}[];
async function renderProgress() {
if (!isLoggedIn()) {
return;
}
const { response: progressList, error } = await httpGet<UserProgressResponse>(
`${import.meta.env.PUBLIC_API_URL}/v1-get-user-all-progress`
);
if (error || !progressList) {
return;
}
progressList.forEach((progress) => {
const href =
progress.resourceType === 'best-practice'
? `/best-practices/${progress.resourceId}`
: `/${progress.resourceId}`;
const element = document.querySelector(`a[href="${href}"]`);
if (!element) {
return;
}
const totalDone = progress.done + progress.skipped;
const percentageDone = (totalDone / progress.total) * 100;
const progressBar = document.createElement('div');
progressBar.style.backgroundColor = 'rgb(23 42 58)';
progressBar.style.position = 'absolute';
progressBar.style.width = `${percentageDone}%`;
progressBar.style.height = '100%';
progressBar.style.bottom = '0';
progressBar.style.left = '0';
progressBar.style.top = '0';
progressBar.style.zIndex = '1';
element.appendChild(progressBar);
});
}
// on DOM load
window.addEventListener('DOMContentLoaded', () => {
window.setTimeout(renderProgress, 0);
});

@ -8,7 +8,7 @@ const legacyRoadmapUrls = [...roadmapIds.map((id) => `/${id}/`), '/roadmaps/'];
--- ---
<BaseLayout title='Page not found' permalink={'/404'} noIndex={true}> <BaseLayout title='Page not found' permalink={'/404'} noIndex={true}>
<!-- Legacy roadmp pages handling --> <!-- Legacy roadmap pages handling -->
<script slot='after-header' define:vars={{ legacyRoadmapUrls }}> <script slot='after-header' define:vars={{ legacyRoadmapUrls }}>
// If it's a roadmap page and it ends with a slash // If it's a roadmap page and it ends with a slash
// redirect to the same page without the slash // redirect to the same page without the slash

@ -23,20 +23,24 @@ const videos = await getAllVideos();
> >
<div class='bg-gradient-to-b from-slate-900 to-black'> <div class='bg-gradient-to-b from-slate-900 to-black'>
<div class='border-b border-b-[#1e293c]'> <div class='border-b border-b-[#1e293c]'>
<div class='container text-left sm:text-center py-6 pb-14 sm:py-20 px-6 sm:px-0'> <div
class='container px-6 py-6 pb-14 text-left sm:px-0 sm:py-20 sm:text-center'
>
<h1 <h1
class='text-2xl sm:text-5xl mb-2 sm:mb-4 font-bold bg-gradient-to-b from-amber-50 to-purple-500 text-transparent bg-clip-text' class='mb-2 bg-gradient-to-b from-amber-50 to-purple-500 bg-clip-text text-2xl font-bold text-transparent sm:mb-4 sm:text-5xl'
> >
Developer Roadmaps Developer Roadmaps
</h1> </h1>
<p class='hidden sm:block text-gray-400 text-lg px-4'> <p class='hidden px-4 text-lg text-gray-400 sm:block'>
<span class='font-medium text-gray-400'>roadmap.sh</span> is a community effort to create roadmaps, guides and <span class='font-medium text-gray-400'>roadmap.sh</span> is a community
other educational content to help guide developers in picking up the path and guide their learnings. effort to create roadmaps, guides and other educational content to help
guide developers in picking up the path and guide their learnings.
</p> </p>
<p class='block sm:hidden text-gray-400 text-md px-0'> <p class='text-md block px-0 text-gray-400 sm:hidden'>
Community created roadmaps, guides and articles to help developers grow in their career. Community created roadmaps, guides and articles to help developers
grow in their career.
</p> </p>
</div> </div>
</div> </div>
@ -54,7 +58,10 @@ const videos = await getAllVideos();
<FeaturedItems <FeaturedItems
heading='Skill based Roadmaps' heading='Skill based Roadmaps'
featuredItems={skillRoadmaps.map((roadmapItem) => ({ featuredItems={skillRoadmaps.map((roadmapItem) => ({
text: roadmapItem.frontmatter.briefTitle === 'Go' ? 'Go Roadmap' : roadmapItem.frontmatter.briefTitle, text:
roadmapItem.frontmatter.briefTitle === 'Go'
? 'Go Roadmap'
: roadmapItem.frontmatter.briefTitle,
url: `/${roadmapItem.id}`, url: `/${roadmapItem.id}`,
isNew: roadmapItem.frontmatter.isNew, isNew: roadmapItem.frontmatter.isNew,
isUpcoming: roadmapItem.frontmatter.isUpcoming, isUpcoming: roadmapItem.frontmatter.isUpcoming,
@ -71,9 +78,11 @@ const videos = await getAllVideos();
}))} }))}
/> />
<div class='grid grid-cols-1 gap-7 sm:gap-16 bg-gray-50 py-7 sm:py-16'> <div class='grid grid-cols-1 gap-7 bg-gray-50 py-7 sm:gap-16 sm:py-16'>
<FeaturedGuides heading='Guides' guides={guides.slice(0, 7)} /> <FeaturedGuides heading='Guides' guides={guides.slice(0, 7)} />
<FeaturedVideos heading='Videos' videos={videos.slice(0, 7)} /> <FeaturedVideos heading='Videos' videos={videos.slice(0, 7)} />
</div> </div>
</div> </div>
<script src='../lib/home-progress.ts'></script>
</BaseLayout> </BaseLayout>

Loading…
Cancel
Save