From af926002e92aaa9e99a9a4734e00f7ec80b315b1 Mon Sep 17 00:00:00 2001 From: Kamran Ahmed Date: Wed, 14 Jun 2023 13:12:52 +0100 Subject: [PATCH] feat: show user's progress on homepage (#4058) * Add custom client:authenticated directive * Update 100-installing-a-local-cluster.md fixed typo for ubuntu in 100-installing-a-local-cluster.md * Animate progress on the homescreen * Show progress on homepage * Update progress list UI * Remove sponsor call from non-required pages * Resolve merge conflicts * Change height of hero container --------- Co-authored-by: kanhaya kumar yadav --- astro.config.mjs | 17 +++ package.json | 6 +- pnpm-lock.yaml | 85 +++++++------- src/components/Activity/EmptyActivity.tsx | 4 +- src/components/HeroSection/CheckIcon.tsx | 20 ++++ src/components/HeroSection/EmptyProgress.tsx | 23 ++++ .../HeroSection/FavoriteRoadmaps.tsx | 105 ++++++++++++++++++ src/components/HeroSection/HeroSection.astro | 28 +++++ src/components/HeroSection/ProgressList.tsx | 46 ++++++++ src/components/PageSponsor.tsx | 12 ++ .../cpp/content/115-compilers/100-stages.md | 10 +- src/directives/client-authenticated.mjs | 9 ++ src/lib/home-progress.ts | 48 -------- src/pages/index.astro | 28 +---- 14 files changed, 316 insertions(+), 125 deletions(-) create mode 100644 src/components/HeroSection/CheckIcon.tsx create mode 100644 src/components/HeroSection/EmptyProgress.tsx create mode 100644 src/components/HeroSection/FavoriteRoadmaps.tsx create mode 100644 src/components/HeroSection/HeroSection.astro create mode 100644 src/components/HeroSection/ProgressList.tsx create mode 100644 src/directives/client-authenticated.mjs delete mode 100644 src/lib/home-progress.ts diff --git a/astro.config.mjs b/astro.config.mjs index e6f458986..e0b09712c 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -5,6 +5,7 @@ import tailwind from '@astrojs/tailwind'; import compress from 'astro-compress'; import { defineConfig } from 'astro/config'; import rehypeExternalLinks from 'rehype-external-links'; +import { fileURLToPath } from 'node:url'; import { serializeSitemap, shouldIndexPage } from './sitemap.mjs'; // https://astro.build/config @@ -45,6 +46,22 @@ export default defineConfig({ format: 'file', }, integrations: [ + { + name: 'client-authenticated', + hooks: { + 'astro:config:setup'(options) { + options.addClientDirective({ + name: 'authenticated', + entrypoint: fileURLToPath( + new URL( + './src/directives/client-authenticated.mjs', + import.meta.url + ) + ), + }); + }, + }, + }, tailwind({ config: { applyBaseStyles: false, diff --git a/package.json b/package.json index c6c0d5401..4791a9261 100644 --- a/package.json +++ b/package.json @@ -26,8 +26,8 @@ "@astrojs/tailwind": "^3.1.3", "@fingerprintjs/fingerprintjs": "^3.4.1", "@nanostores/preact": "^0.5.0", - "astro": "^2.5.7", - "astro-compress": "^1.1.46", + "astro": "^2.6.3", + "astro-compress": "^1.1.47", "jose": "^4.14.4", "js-cookie": "^3.0.5", "nanostores": "^0.9.1", @@ -39,7 +39,7 @@ "tailwindcss": "^3.3.2" }, "devDependencies": { - "@playwright/test": "^1.34.3", + "@playwright/test": "^1.35.0", "@tailwindcss/typography": "^0.5.9", "@types/js-cookie": "^3.0.3", "csv-parser": "^3.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 973b61e89..cd6929b1e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,11 +6,11 @@ specifiers: '@astrojs/tailwind': ^3.1.3 '@fingerprintjs/fingerprintjs': ^3.4.1 '@nanostores/preact': ^0.5.0 - '@playwright/test': ^1.34.3 + '@playwright/test': ^1.35.0 '@tailwindcss/typography': ^0.5.9 '@types/js-cookie': ^3.0.3 - astro: ^2.5.7 - astro-compress: ^1.1.46 + astro: ^2.6.3 + astro-compress: ^1.1.47 csv-parser: ^3.0.0 gh-pages: ^5.0.0 jose: ^4.14.4 @@ -32,11 +32,11 @@ specifiers: dependencies: '@astrojs/preact': 2.2.1_preact@10.15.1 '@astrojs/sitemap': 1.3.3 - '@astrojs/tailwind': 3.1.3_cyxi2rbbvaq22julk2hkhgjf7u + '@astrojs/tailwind': 3.1.3_v3vh2dd4sag23uewccz5c4ppyu '@fingerprintjs/fingerprintjs': 3.4.1 '@nanostores/preact': 0.5.0_m2wbkjxz7237icvaxqi7ignbgm - astro: 2.5.7 - astro-compress: 1.1.46 + astro: 2.6.3 + astro-compress: 1.1.47 jose: 4.14.4 js-cookie: 3.0.5 nanostores: 0.9.1 @@ -48,7 +48,7 @@ dependencies: tailwindcss: 3.3.2 devDependencies: - '@playwright/test': 1.34.3 + '@playwright/test': 1.35.0 '@tailwindcss/typography': 0.5.9_tailwindcss@3.3.2 '@types/js-cookie': 3.0.3 csv-parser: 3.0.0 @@ -74,13 +74,13 @@ packages: '@jridgewell/trace-mapping': 0.3.18 dev: false - /@astrojs/compiler/1.4.2: - resolution: {integrity: sha512-xoRp7JpiMZPK/beUcZEM5kM44Z/h20wwwQcl54duPqQMyySG9vZ5xMM6dYiQmn7b3XzpZs0cT6TRDoJJ5gwHAQ==} - dev: false - /@astrojs/compiler/1.5.0: resolution: {integrity: sha512-k04X/7nlMklU0HQUScxbCTf5n8/Vr+0U0bawb9QWulWxd6qJf3FmBrNATgTYiltjB4pc5HBqmmttAfFi7m4lLg==} + /@astrojs/internal-helpers/0.1.0: + resolution: {integrity: sha512-OSwvoFkTqVowiyP+codQeQZWoq/HOwY32x17NxDglWoCx2sdyXzplDZoVV4/3odmSEY6/A+48WMl5qkjmP1CXw==} + dev: false + /@astrojs/language-server/1.0.0: resolution: {integrity: sha512-oEw7AwJmzjgy6HC9f5IdrphZ1GVgfV/+7xQuyf52cpTiRWd/tJISK3MsKP0cDkVlfodmNABNFnAaAWuLZEiiiA==} hasBin: true @@ -101,13 +101,13 @@ packages: vscode-uri: 3.0.7 dev: false - /@astrojs/markdown-remark/2.2.1_astro@2.5.7: + /@astrojs/markdown-remark/2.2.1_astro@2.6.3: resolution: {integrity: sha512-VF0HRv4GpC1XEMLnsKf6jth7JSmlt9qpqP0josQgA2eSpCIAC/Et+y94mgdBIZVBYH/yFnMoIxgKVe93xfO2GA==} peerDependencies: astro: ^2.5.0 dependencies: '@astrojs/prism': 2.1.2 - astro: 2.5.7 + astro: 2.6.3 github-slugger: 1.5.0 import-meta-resolve: 2.2.2 rehype-raw: 6.1.1 @@ -154,14 +154,14 @@ packages: zod: 3.21.4 dev: false - /@astrojs/tailwind/3.1.3_cyxi2rbbvaq22julk2hkhgjf7u: + /@astrojs/tailwind/3.1.3_v3vh2dd4sag23uewccz5c4ppyu: resolution: {integrity: sha512-10S1omrv5K5HRVAZ0fBgN5vQykn2HRL332LAVFyBASMn1Ff6gDfSK+CPUeUu94eZUOEaPnECLK8EHAqZ8iY9CA==} peerDependencies: astro: ^2.5.0 tailwindcss: ^3.0.24 dependencies: '@proload/core': 0.3.3 - astro: 2.5.7 + astro: 2.6.3 autoprefixer: 10.4.14_postcss@8.4.23 postcss: 8.4.23 postcss-load-config: 4.0.1_postcss@8.4.23 @@ -968,13 +968,13 @@ packages: tslib: 2.5.0 dev: false - /@playwright/test/1.34.3: - resolution: {integrity: sha512-zPLef6w9P6T/iT6XDYG3mvGOqOyb6eHaV9XtkunYs0+OzxBtrPAAaHotc0X+PJ00WPPnLfFBTl7mf45Mn8DBmw==} - engines: {node: '>=14'} + /@playwright/test/1.35.0: + resolution: {integrity: sha512-6qXdd5edCBynOwsz1YcNfgX8tNWeuS9fxy5o59D0rvHXxRtjXRebB4gE4vFVfEMXl/z8zTnAzfOs7aQDEs8G4Q==} + engines: {node: '>=16'} hasBin: true dependencies: '@types/node': 18.16.3 - playwright-core: 1.34.3 + playwright-core: 1.35.0 optionalDependencies: fsevents: 2.3.2 dev: true @@ -1330,21 +1330,21 @@ packages: engines: {node: '>=0.10.0'} dev: true - /astro-compress/1.1.46: - resolution: {integrity: sha512-5PiZsCOlYO04jATC/XlpdMT6869QLsbpSNoihutUxkdWpDpoXwNMyxxXsL7QljdXHyFg6XmTDpxOODxvqerVWA==} + /astro-compress/1.1.47: + resolution: {integrity: sha512-UBhhDfZffcPVdDFA4v42G68BdcNL6ZlYoXZdHTappiLWDvZPlhRmK6iuwya3SAGl4La4kqKCfNSqwKbG3agdBQ==} dependencies: '@types/csso': 5.0.0 '@types/html-minifier-terser': 7.0.0 csso: 5.0.5 - files-pipe: 0.0.6 + files-pipe: 0.0.7 html-minifier-terser: 7.2.0 sharp: 0.32.1 svgo: 3.0.2 - terser: 5.17.6 + terser: 5.17.7 dev: false - /astro/2.5.7: - resolution: {integrity: sha512-qYKMIN4tXAOAsm10vU4f+Q7LfC05JmEbQiJmSBqIEhp+wnQcEUFkGLrHMSsps3oBzMtjErUdDDW5tGJcn5eVlA==} + /astro/2.6.3: + resolution: {integrity: sha512-gJoBX+t11qAeYDjterGEaQZx7qqlGOigWhE0zkcEBv4zy7l4IpKx6nGGUNzD/l8x6WomZxkdZROsOsiEaWSJmQ==} engines: {node: '>=16.12.0', npm: '>=6.14.0'} hasBin: true peerDependencies: @@ -1353,17 +1353,18 @@ packages: sharp: optional: true dependencies: - '@astrojs/compiler': 1.4.2 + '@astrojs/compiler': 1.5.0 + '@astrojs/internal-helpers': 0.1.0 '@astrojs/language-server': 1.0.0 - '@astrojs/markdown-remark': 2.2.1_astro@2.5.7 + '@astrojs/markdown-remark': 2.2.1_astro@2.6.3 '@astrojs/telemetry': 2.1.1 '@astrojs/webapi': 2.2.0 '@babel/core': 7.22.1 - '@babel/generator': 7.21.5 - '@babel/parser': 7.21.5 + '@babel/generator': 7.22.3 + '@babel/parser': 7.22.4 '@babel/plugin-transform-react-jsx': 7.21.5_@babel+core@7.22.1 - '@babel/traverse': 7.21.5 - '@babel/types': 7.21.5 + '@babel/traverse': 7.22.4 + '@babel/types': 7.22.4 '@types/babel__core': 7.20.0 '@types/yargs-parser': 21.0.0 acorn: 8.8.2 @@ -1374,7 +1375,7 @@ packages: cookie: 0.5.0 debug: 4.3.4 deepmerge-ts: 4.3.0 - devalue: 4.3.0 + devalue: 4.3.2 diff: 5.1.0 es-module-lexer: 1.2.1 esbuild: 0.17.18 @@ -2056,8 +2057,8 @@ packages: engines: {node: '>=8'} dev: false - /devalue/4.3.0: - resolution: {integrity: sha512-n94yQo4LI3w7erwf84mhRUkUJfhLoCZiLyoOZ/QFsDbcWNZePrLwbQpvZBUG2TNxwV3VjCKPxkiiQA6pe3TrTA==} + /devalue/4.3.2: + resolution: {integrity: sha512-KqFl6pOgOW+Y6wJgu80rHpo2/3H07vr8ntR9rkkFIRETewbf5GaYYcakYfiKz89K+sLsuPkQIZaXDMjUObZwWg==} dev: false /didyoumean/1.2.2: @@ -2316,8 +2317,8 @@ packages: trim-repeated: 1.0.0 dev: true - /files-pipe/0.0.6: - resolution: {integrity: sha512-izHIHcqKEM0V2nw3FvzAqL0nx3IiZ2RC7k4eczIhlJ4X5JWJsxVl4c6b+Uid3zvNd6RiPxjFerbFcodFXMPHBw==} + /files-pipe/0.0.7: + resolution: {integrity: sha512-BkXQoAEo1X3RqmEucIBLL1ddc/LM3lqsf5ipIf/bRrUTn3SQZWhThgpIl1/ma2VNesB2hBoY+CB0rrZ3b1tQhA==} dependencies: deepmerge-ts: 5.1.0 fast-glob: 3.2.12 @@ -2790,7 +2791,7 @@ packages: entities: 4.5.0 param-case: 3.0.4 relateurl: 0.2.7 - terser: 5.17.6 + terser: 5.17.7 dev: false /html-void-elements/2.0.1: @@ -4446,9 +4447,9 @@ packages: find-up: 3.0.0 dev: false - /playwright-core/1.34.3: - resolution: {integrity: sha512-2pWd6G7OHKemc5x1r1rp8aQcpvDh7goMBZlJv6Co5vCNLVcQJdhxRL09SGaY6HcyHH9aT4tiynZabMofVasBYw==} - engines: {node: '>=14'} + /playwright-core/1.35.0: + resolution: {integrity: sha512-muMXyPmIx/2DPrCHOD1H1ePT01o7OdKxKj2ebmCAYvqhUy+Y1bpal7B0rdoxros7YrXI294JT/DWw2LqyiqTPA==} + engines: {node: '>=16'} hasBin: true dev: true @@ -5486,8 +5487,8 @@ packages: yallist: 4.0.0 dev: false - /terser/5.17.6: - resolution: {integrity: sha512-V8QHcs8YuyLkLHsJO5ucyff1ykrLVsR4dNnS//L5Y3NiSXpbK1J+WMVUs67eI0KTxs9JtHhgEQpXQVHlHI92DQ==} + /terser/5.17.7: + resolution: {integrity: sha512-/bi0Zm2C6VAexlGgLlVxA0P2lru/sdLyfCVaRMfKVo9nWxbmz7f/sD8VPybPeSUJaJcwmCJis9pBIhcVcG1QcQ==} engines: {node: '>=10'} hasBin: true dependencies: 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 roadmaps

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..b90c3f1b4 --- /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 show up here.', + } = props; + + return ( +
+

+ + Start learning .. +

+

{message}

+
+ ); +} diff --git a/src/components/HeroSection/FavoriteRoadmaps.tsx b/src/components/HeroSection/FavoriteRoadmaps.tsx new file mode 100644 index 000000000..e87d4bf83 --- /dev/null +++ b/src/components/HeroSection/FavoriteRoadmaps.tsx @@ -0,0 +1,105 @@ +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 | null = + element.querySelector('[data-progress]'); + if (progressBar) { + progressBar.style.width = `${percentageDone}%`; + } + }); +} + +export function FavoriteRoadmaps() { + const [isPreparing, setIsPreparing] = useState(true); + const [isLoading, setIsLoading] = useState(false); + const [progress, setProgress] = useState([]); + const [containerOpacity, setContainerOpacity] = useState(0); + + function showProgressContainer() { + const heroEl = document.getElementById('hero-text')!; + 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; + } + + const hasProgress = progress.length > 0; + + return ( +
+
+ {!isLoading && progress.length == 0 && } + {isLoading && } + {!isLoading && progress.length > 0 && ( + + )} +
+
+ ); +} diff --git a/src/components/HeroSection/HeroSection.astro b/src/components/HeroSection/HeroSection.astro new file mode 100644 index 000000000..fe12d5878 --- /dev/null +++ b/src/components/HeroSection/HeroSection.astro @@ -0,0 +1,28 @@ +--- +import { FavoriteRoadmaps } from './FavoriteRoadmaps'; +--- + +
+
+

+ Developer Roadmaps +

+ + + +

+ Community created roadmaps, guides and articles to help developers grow in + their career. +

+
+ +
diff --git a/src/components/HeroSection/ProgressList.tsx b/src/components/HeroSection/ProgressList.tsx new file mode 100644 index 000000000..6b7ad471b --- /dev/null +++ b/src/components/HeroSection/ProgressList.tsx @@ -0,0 +1,46 @@ +import type { UserProgressResponse } from './FavoriteRoadmaps'; +import { CheckIcon } from './CheckIcon'; + +type ProgressListProps = { + progress: UserProgressResponse; +}; + +export function ProgressList(props: ProgressListProps) { + const { progress } = props; + + return ( +
+

+ + Your progress and favorite roadmaps. + Your progress and favorite roadmaps. +

+ +
+ {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/components/PageSponsor.tsx b/src/components/PageSponsor.tsx index f77f64251..9b09a1b3c 100644 --- a/src/components/PageSponsor.tsx +++ b/src/components/PageSponsor.tsx @@ -29,6 +29,18 @@ export function PageSponsor(props: PageSponsorProps) { const [sponsor, setSponsor] = useState(); const loadSponsor = async () => { + const currentPath = window.location.pathname; + if ( + currentPath === '/' || + currentPath === '/best-practices' || + currentPath === '/roadmaps' || + currentPath.startsWith('/guides') || + currentPath.startsWith('/videos') || + currentPath.startsWith('/account') + ) { + return; + } + const { response, error } = await httpGet( `${import.meta.env.PUBLIC_API_URL}/v1-get-sponsor`, { 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/directives/client-authenticated.mjs b/src/directives/client-authenticated.mjs new file mode 100644 index 000000000..f76d42f64 --- /dev/null +++ b/src/directives/client-authenticated.mjs @@ -0,0 +1,9 @@ +export default async (load, opts) => { + const isAuthenticated = document.cookie.toString().indexOf('__roadmapsh_jt__') !== -1; + if (isAuthenticated) { + console.log("loading"); + + const hydrate = await load(); + await hydrate(); + } +}; 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 3eefd7bbe..846d5384b 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,7 +1,8 @@ --- +import FeaturedVideos from '../components/FeaturedVideos.astro'; import FeaturedGuides from '../components/FeaturedGuides.astro'; import FeaturedItems from '../components/FeaturedItems/FeaturedItems.astro'; -import FeaturedVideos from '../components/FeaturedVideos.astro'; +import HeroSection from '../components/HeroSection/HeroSection.astro'; import BaseLayout from '../layouts/BaseLayout.astro'; import { getAllBestPractices } from '../lib/best-pratice'; import { getAllGuides } from '../lib/guide'; @@ -22,28 +23,7 @@ const videos = await getAllVideos(); permalink={'/'} >
-
-
-

- Developer Roadmaps -

- - - -

- Community created roadmaps, guides and articles to help developers - grow in their career. -

-
-
+
- -