Add progress loading on roadmap pages

feat/linkedin
Kamran Ahmed 1 year ago
parent 943bf41dc5
commit 49cff0c22c
  1. 2
      .gitignore
  2. 31
      src/components/RoadmapHint.astro
  3. 2
      src/components/TopicDetail/TopicProgressButton.tsx
  4. 57
      src/lib/resource-progress.ts
  5. 18
      src/styles/global.css

2
.gitignore vendored

@ -1,3 +1,5 @@
.idea
# build output # build output
dist/ dist/
.output/ .output/

@ -1,4 +1,6 @@
--- ---
import { ClearProgress } from './Activity/ClearProgress';
import AstroIcon from './AstroIcon.astro';
import Icon from './AstroIcon.astro'; import Icon from './AstroIcon.astro';
export interface Props { export interface Props {
@ -42,30 +44,25 @@ const roadmapTitle =
} }
<!-- Desktop: Roadmap Resources - Alert --> <!-- Desktop: Roadmap Resources - Alert -->
<div <div id="progress-nums-container"
class:list={[ class:list={[
'hidden sm:flex justify-between px-2 bg-white items-center', 'hidden sm:flex justify-between px-2 bg-white items-center py-1.5 relative striped-loader bg-white',
{ {
'rounded-bl-md rounded-br-md': hasTNSBanner, 'rounded-bl-md rounded-br-md': hasTNSBanner,
'rounded-md': !hasTNSBanner, 'rounded-md': !hasTNSBanner,
}, },
]} ]}
> >
<p class='text-sm'> <p class='text-sm flex opacity-0 transition-opacity duration-300' id="progress-nums">
<span <span class="font-medium py-0.5 rounded-sm text-xs uppercase bg-yellow-200 px-1 text-yellow-900 mr-2.5">
class='mr-0.5 rounded-sm bg-yellow-200 px-1 py-0.5 text-xs font-medium uppercase text-yellow-900' <span class="progress-percentage">0</span>% Done
>New</span </span>
>
Track your progress and learn by clicking roadmap items.
</p>
<a <span><span class="progress-done">0</span> completed</span><span class="mx-1.5 text-gray-400">&middot;</span>
href={`/${roadmapId}/topics`} <span><span class="progress-learning">0</span> learning</span><span class="mx-1.5 text-gray-400">&middot;</span>
class='inline-flex items-center justify-center rounded-md px-1 py-1.5 text-sm font-medium text-gray-500 hover:text-black' <span><span class="progress-skipped">0</span> skipped</span><span class="mx-1.5 text-gray-400">&middot;</span>
> <span><span class="progress-total">0</span> Total</span>
<Icon icon='search' /> </p>
<span class='ml-2'>Search Topics</span>
</a>
</div> </div>
<!-- Mobile - Roadmap resources alert --> <!-- Mobile - Roadmap resources alert -->
@ -74,4 +71,4 @@ const roadmapTitle =
> >
Track your progress and learn about the topics by clicking the roadmap items. Track your progress and learn about the topics by clicking the roadmap items.
</p> </p>
</div> </div>

@ -8,6 +8,7 @@ import {
ResourceProgressType, ResourceProgressType,
ResourceType, ResourceType,
getTopicStatus, getTopicStatus,
refreshProgressCounters,
renderTopicProgress, renderTopicProgress,
updateResourceProgress, updateResourceProgress,
} from '../../lib/resource-progress'; } from '../../lib/resource-progress';
@ -135,6 +136,7 @@ export function TopicProgressButton(props: TopicProgressButtonProps) {
setProgress(progress); setProgress(progress);
onClose(); onClose();
renderTopicProgress(topicId, progress); renderTopicProgress(topicId, progress);
refreshProgressCounters();
}) })
.catch((err) => { .catch((err) => {
alert(err.message); alert(err.message);

@ -223,4 +223,61 @@ export async function renderResourceProgress(
skipped.forEach((topicId) => { skipped.forEach((topicId) => {
renderTopicProgress(topicId, 'skipped'); renderTopicProgress(topicId, 'skipped');
}); });
refreshProgressCounters();
}
export function refreshProgressCounters() {
const progressNumsContainer = document.getElementById('progress-nums-container');
const progressNums = document.getElementById('progress-nums');
if (!progressNumsContainer || !progressNums) {
return;
}
const totalClickable = document.querySelectorAll('.clickable-group').length;
const externalLinks = document.querySelectorAll(
'[data-group-id^="ext_link:"]'
).length;
const roadmapSwitchers = document.querySelectorAll(
'[data-group-id^="json:"]'
).length;
const totalItems = totalClickable - externalLinks - roadmapSwitchers;
const totalDone = document.querySelectorAll('.clickable-group.done').length;
const totalLearning = document.querySelectorAll(
'.clickable-group.learning'
).length;
const totalSkipped = document.querySelectorAll(
'.clickable-group.skipped'
).length;
const doneCountEl = document.querySelector('.progress-done');
if (doneCountEl) {
doneCountEl.innerHTML = `${totalDone}`;
}
const learningCountEl = document.querySelector('.progress-learning');
if (learningCountEl) {
learningCountEl.innerHTML = `${totalLearning}`;
}
const skippedCountEl = document.querySelector('.progress-skipped');
if (skippedCountEl) {
skippedCountEl.innerHTML = `${totalSkipped}`;
}
const totalCountEl = document.querySelector('.progress-total');
if (totalCountEl) {
totalCountEl.innerHTML = `${totalItems}`;
}
const progressPercentage = Math.round(((totalDone + totalSkipped) / totalItems) * 100);
const progressPercentageEl = document.querySelector('.progress-percentage');
if (progressPercentageEl) {
progressPercentageEl.innerHTML = `${progressPercentage}`;
}
progressNumsContainer.classList.remove('striped-loader')
progressNums.classList.remove('opacity-0');
progressNums.classList.remove('opacity-100');
} }

@ -63,3 +63,21 @@ a > code:before {
) )
hsla(203, 11%, 95%, 0.4); hsla(203, 11%, 95%, 0.4);
} }
.striped-loader {
background-image: repeating-linear-gradient(
-45deg,
transparent,
transparent 5px,
hsla(0, 0%, 0%, 0.025) 5px,
hsla(0, 0%, 0%, 0.025) 10px
);
background-size: 200% 200%;
animation: barberpole 15s linear infinite;
}
@keyframes barberpole {
100% {
background-position: 100% 100%;
}
}
Loading…
Cancel
Save