diff --git a/src/components/Activity/EmptyActivity.tsx b/src/components/Activity/EmptyActivity.tsx
index a38fa7a15..dc8bbb4da 100644
--- a/src/components/Activity/EmptyActivity.tsx
+++ b/src/components/Activity/EmptyActivity.tsx
@@ -1,4 +1,4 @@
-import CheckIcon from '../../icons/roadmap.svg';
+import RoadmapIcon from '../../icons/roadmap.svg';
export function EmptyActivity() {
return (
@@ -6,7 +6,7 @@ export function EmptyActivity() {
No Progress
diff --git a/src/components/HeroSection/CheckIcon.tsx b/src/components/HeroSection/CheckIcon.tsx
new file mode 100644
index 000000000..de8eb4e15
--- /dev/null
+++ b/src/components/HeroSection/CheckIcon.tsx
@@ -0,0 +1,20 @@
+type CheckIconProps = {
+ additionalClasses?: string;
+};
+
+export function CheckIcon(props: CheckIconProps) {
+ const { additionalClasses = 'mr-2 top-[0.5px] w-[20px] h-[20px]' } = props;
+
+ return (
+
+ );
+}
diff --git a/src/components/HeroSection/EmptyProgress.tsx b/src/components/HeroSection/EmptyProgress.tsx
new file mode 100644
index 000000000..28dedcffc
--- /dev/null
+++ b/src/components/HeroSection/EmptyProgress.tsx
@@ -0,0 +1,23 @@
+import { CheckIcon } from './CheckIcon';
+
+type EmptyProgressProps = {
+ title?: string;
+ message?: string;
+};
+
+export function EmptyProgress(props: EmptyProgressProps) {
+ const {
+ title = 'Start learning ..',
+ message = 'Your progress and favorite roadmaps will appear here',
+ } = props;
+
+ return (
+
+
+
+ Start learning ..
+
+
{message}
+
+ );
+}
diff --git a/src/components/HeroSection/FavoriteRoadmaps.tsx b/src/components/HeroSection/FavoriteRoadmaps.tsx
index 9bf90032a..20b69a4af 100644
--- a/src/components/HeroSection/FavoriteRoadmaps.tsx
+++ b/src/components/HeroSection/FavoriteRoadmaps.tsx
@@ -1,20 +1,100 @@
import { useEffect, useState } from 'preact/hooks';
+import { EmptyProgress } from './EmptyProgress';
+import { httpGet } from '../../lib/http';
+import { ProgressList } from './ProgressList';
+
+export type UserProgressResponse = {
+ resourceId: string;
+ resourceType: 'roadmap' | 'best-practice';
+ resourceTitle: string;
+ done: number;
+ learning: number;
+ skipped: number;
+ total: number;
+ updatedAt: Date;
+}[];
+
+function renderProgress(progressList: UserProgressResponse) {
+ 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: HTMLElement = element.querySelector('[data-progress]')!;
+ progressBar.style.width = `${percentageDone}%`;
+ });
+}
export function FavoriteRoadmaps() {
const [isPreparing, setIsPreparing] = useState(true);
- useEffect(() => {
+ const [isLoading, setIsLoading] = useState(false);
+ const [progress, setProgress] = useState
([]);
+ const [containerOpacity, setContainerOpacity] = useState(0);
+
+ function showProgressContainer() {
const heroEl = document.getElementById('hero-text')!;
- heroEl.classList.add('opacity-0')
- setIsPreparing(false);
- });
+ if (!heroEl) {
+ return;
+ }
+
+ heroEl.classList.add('opacity-0');
+ setTimeout(() => {
+ heroEl.parentElement?.removeChild(heroEl);
+ setIsPreparing(false);
+
+ setTimeout(() => {
+ setContainerOpacity(100);
+ }, 50);
+ }, 300);
+ }
+
+ async function loadProgress() {
+ setIsLoading(true);
+ const { response: progressList, error } =
+ await httpGet(
+ `${import.meta.env.PUBLIC_API_URL}/v1-get-user-all-progress`
+ );
+
+ if (error || !progressList) {
+ return;
+ }
+
+ setProgress(progressList);
+ renderProgress(progressList);
+ }
+
+ useEffect(() => {
+ showProgressContainer();
+ loadProgress().finally(() => {
+ setIsLoading(false);
+ });
+ }, []);
if (isPreparing) {
return null;
}
- return null;
+ const hasProgress = progress.length > 0;
- // return (
- //
- // );
+ return (
+
+
+ {!isLoading && progress.length == 0 &&
}
+ {isLoading &&
}
+ {!isLoading && progress.length > 0 && (
+
+ )}
+
+
+ );
}
diff --git a/src/components/HeroSection/HeroSection.astro b/src/components/HeroSection/HeroSection.astro
index ea1aff881..2f1177541 100644
--- a/src/components/HeroSection/HeroSection.astro
+++ b/src/components/HeroSection/HeroSection.astro
@@ -2,7 +2,7 @@
import { FavoriteRoadmaps } from './FavoriteRoadmaps';
---
-
+
+
+
+ Your favorite roadmaps and tracked progress.
+
+
+
+ {progress.map((resource) => {
+ const url =
+ resource.resourceType === 'roadmap'
+ ? `/${resource.resourceId}`
+ : `/best-practices/${resource.resourceId}`;
+
+ const percentageDone =
+ ((resource.skipped + resource.done) / resource.total) * 100;
+
+ return (
+
+ {resource.resourceTitle}
+
+
+
+ );
+ })}
+
+
+ );
+}
diff --git a/src/data/roadmaps/cpp/content/115-compilers/100-stages.md b/src/data/roadmaps/cpp/content/115-compilers/100-stages.md
index 84c986f27..cbe299a67 100644
--- a/src/data/roadmaps/cpp/content/115-compilers/100-stages.md
+++ b/src/data/roadmaps/cpp/content/115-compilers/100-stages.md
@@ -39,10 +39,10 @@ The third stage is converting the compiler's intermediate representation into as
**Code Example (x86 Assembly):**
-```assembly
- mov eax, 10
- mov ebx, 20
- add eax, ebx
+```
+mov eax, 10
+mov ebx, 20
+add eax, ebx
```
## Linking
@@ -55,4 +55,4 @@ The final stage is the linking of the object code with the necessary libraries a
$ g++ main.o -o main -lm
```
-In summary, the compilation process in C++ involves four primary stages: preprocessing, compilation, assembly, and linking. Each stage plays a crucial role in transforming the source code into an executable program.
\ No newline at end of file
+In summary, the compilation process in C++ involves four primary stages: preprocessing, compilation, assembly, and linking. Each stage plays a crucial role in transforming the source code into an executable program.
diff --git a/src/lib/home-progress.ts b/src/lib/home-progress.ts
deleted file mode 100644
index 58ba52369..000000000
--- a/src/lib/home-progress.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-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
(
- `${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: HTMLElement = element.querySelector('[data-progress]')!;
- progressBar.style.width = `${percentageDone}%`;
- });
-}
-
-// on DOM load
-window.addEventListener('DOMContentLoaded', () => {
- window.setTimeout(renderProgress, 0);
-});
diff --git a/src/pages/index.astro b/src/pages/index.astro
index 5b54d8340..274221520 100644
--- a/src/pages/index.astro
+++ b/src/pages/index.astro
@@ -63,6 +63,4 @@ const videos = await getAllVideos();
-
-