mirror of
https://github.com/kamranahmedse/developer-roadmap.git
synced 2025-08-11 03:34:00 +02:00
Add progress loading on roadmap pages
This commit is contained in:
2
.gitignore
vendored
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">·</span>
|
||||||
href={`/${roadmapId}/topics`}
|
<span><span class="progress-learning">0</span> learning</span><span class="mx-1.5 text-gray-400">·</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">·</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%;
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user