Custom roadmaps listing on homepage

pull/4446/head
Kamran Ahmed 1 year ago
parent 07b2cb0f9b
commit 1b74e86db7
  1. 2
      package.json
  2. 186
      pnpm-lock.yaml
  3. 4
      src/components/HeroSection/FavoriteRoadmaps.tsx
  4. 155
      src/components/HeroSection/HeroRoadmaps.tsx
  5. 61
      src/components/HeroSection/ProgressList.tsx
  6. 15
      src/components/Questions/QuestionCard.tsx
  7. 4
      src/components/Questions/QuestionsList.tsx
  8. 18
      src/components/Questions/QuestionsProgress.tsx

@ -42,7 +42,7 @@
"rehype-external-links": "^2.1.0",
"roadmap-renderer": "^1.0.6",
"slugify": "^1.6.6",
"tailwindcss": "^3.0.24"
"tailwindcss": "^3.3.3"
},
"devDependencies": {
"@playwright/test": "^1.35.1",

@ -13,7 +13,7 @@ dependencies:
version: 1.3.3
'@astrojs/tailwind':
specifier: ^5.0.0
version: 5.0.0(astro@3.0.5)(tailwindcss@3.0.24)
version: 5.0.0(astro@3.0.5)(tailwindcss@3.3.3)
'@fingerprintjs/fingerprintjs':
specifier: ^3.4.1
version: 3.4.1
@ -69,8 +69,8 @@ dependencies:
specifier: ^1.6.6
version: 1.6.6
tailwindcss:
specifier: ^3.0.24
version: 3.0.24(postcss@8.4.29)
specifier: ^3.3.3
version: 3.3.3
devDependencies:
'@playwright/test':
@ -78,7 +78,7 @@ devDependencies:
version: 1.35.1
'@tailwindcss/typography':
specifier: ^0.5.9
version: 0.5.9(tailwindcss@3.0.24)
version: 0.5.9(tailwindcss@3.3.3)
'@types/js-cookie':
specifier: ^3.0.3
version: 3.0.3
@ -109,6 +109,10 @@ devDependencies:
packages:
/@alloc/quick-lru@5.2.0:
resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
engines: {node: '>=10'}
/@ampproject/remapping@2.2.1:
resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==}
engines: {node: '>=6.0.0'}
@ -187,7 +191,7 @@ packages:
zod: 3.22.2
dev: false
/@astrojs/tailwind@5.0.0(astro@3.0.5)(tailwindcss@3.0.24):
/@astrojs/tailwind@5.0.0(astro@3.0.5)(tailwindcss@3.3.3):
resolution: {integrity: sha512-bMZZNNm/SW+ijUKMQDhdiuNWDdR3CubEKUHb2Ran4Arx1ikWn/kKIkFDXUV+MUnsLa7s19x9VMRlARRyKbqMkQ==}
peerDependencies:
astro: ^3.0.0
@ -197,7 +201,7 @@ packages:
autoprefixer: 10.4.15(postcss@8.4.29)
postcss: 8.4.29
postcss-load-config: 4.0.1(postcss@8.4.29)
tailwindcss: 3.0.24(postcss@8.4.29)
tailwindcss: 3.3.3
transitivePeerDependencies:
- ts-node
dev: false
@ -893,17 +897,14 @@ packages:
'@jridgewell/set-array': 1.1.2
'@jridgewell/sourcemap-codec': 1.4.15
'@jridgewell/trace-mapping': 0.3.19
dev: false
/@jridgewell/resolve-uri@3.1.1:
resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==}
engines: {node: '>=6.0.0'}
dev: false
/@jridgewell/set-array@1.1.2:
resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==}
engines: {node: '>=6.0.0'}
dev: false
/@jridgewell/source-map@0.3.5:
resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==}
@ -914,14 +915,12 @@ packages:
/@jridgewell/sourcemap-codec@1.4.15:
resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
dev: false
/@jridgewell/trace-mapping@0.3.19:
resolution: {integrity: sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==}
dependencies:
'@jridgewell/resolve-uri': 3.1.1
'@jridgewell/sourcemap-codec': 1.4.15
dev: false
/@nanostores/react@0.7.1(nanostores@0.9.2)(react@18.0.0):
resolution: {integrity: sha512-EXQg9N4MdI4eJQz/AZLIx3hxQ6BuBmV4Q55bCd5YCSgEOAW7tGTsIZxpRXxvxLXzflNvHTBvfrDNY38TlSVBkQ==}
@ -1093,7 +1092,7 @@ packages:
defer-to-connect: 2.0.1
dev: false
/@tailwindcss/typography@0.5.9(tailwindcss@3.0.24):
/@tailwindcss/typography@0.5.9(tailwindcss@3.3.3):
resolution: {integrity: sha512-t8Sg3DyynFysV9f4JDOVISGsjazNb48AeIYQwcL+Bsq5uf4RYL75C1giZ43KISjeDGBaTN3Kxh7Xj/vRSMJUUg==}
peerDependencies:
tailwindcss: '>=3.0.0 || insiders'
@ -1102,7 +1101,7 @@ packages:
lodash.isplainobject: 4.0.6
lodash.merge: 4.6.2
postcss-selector-parser: 6.0.10
tailwindcss: 3.0.24(postcss@8.4.29)
tailwindcss: 3.3.3
dev: true
/@tootallnate/once@2.0.0:
@ -1286,22 +1285,6 @@ packages:
resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==}
dev: false
/acorn-node@1.8.2:
resolution: {integrity: sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==}
dependencies:
acorn: 7.4.1
acorn-walk: 7.2.0
xtend: 4.0.2
/acorn-walk@7.2.0:
resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==}
engines: {node: '>=0.4.0'}
/acorn@7.4.1:
resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==}
engines: {node: '>=0.4.0'}
hasBin: true
/acorn@8.10.0:
resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==}
engines: {node: '>=0.4.0'}
@ -1371,6 +1354,9 @@ packages:
engines: {node: '>=12'}
dev: false
/any-promise@1.3.0:
resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
/anymatch@3.1.3:
resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
engines: {node: '>= 8'}
@ -1829,6 +1815,7 @@ packages:
/color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
dev: false
/color-string@1.9.1:
resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
@ -1869,6 +1856,10 @@ packages:
/commander@2.20.3:
resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
/commander@4.1.1:
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
engines: {node: '>= 6'}
/commander@7.2.0:
resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==}
engines: {node: '>= 10'}
@ -2027,9 +2018,6 @@ packages:
engines: {node: '>=10'}
dev: false
/defined@1.0.1:
resolution: {integrity: sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==}
/delayed-stream@1.0.0:
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
engines: {node: '>=0.4.0'}
@ -2049,15 +2037,6 @@ packages:
engines: {node: '>=8'}
dev: false
/detective@5.2.1:
resolution: {integrity: sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==}
engines: {node: '>=0.8.0'}
hasBin: true
dependencies:
acorn-node: 1.8.2
defined: 1.0.1
minimist: 1.2.8
/devalue@4.3.2:
resolution: {integrity: sha512-KqFl6pOgOW+Y6wJgu80rHpo2/3H07vr8ntR9rkkFIRETewbf5GaYYcakYfiKz89K+sLsuPkQIZaXDMjUObZwWg==}
dev: false
@ -2564,6 +2543,16 @@ packages:
path-scurry: 1.10.1
dev: false
/glob@7.1.6:
resolution: {integrity: sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==}
dependencies:
fs.realpath: 1.0.0
inflight: 1.0.6
inherits: 2.0.4
minimatch: 3.1.2
once: 1.4.0
path-is-absolute: 1.0.1
/glob@7.2.3:
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
dependencies:
@ -3038,6 +3027,10 @@ packages:
'@pkgjs/parseargs': 0.11.0
dev: false
/jiti@1.19.3:
resolution: {integrity: sha512-5eEbBDQT/jF1xg6l36P+mWGGoH9Spuy0PCdSr2dtWRDGC6ph/w9ZCL4lmESW8f8F7MwT3XKescfP0wnZWAKL9w==}
hasBin: true
/jju@1.4.0:
resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==}
dev: false
@ -3147,6 +3140,9 @@ packages:
resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==}
engines: {node: '>=10'}
/lines-and-columns@1.2.4:
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
/linkify-it@4.0.1:
resolution: {integrity: sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==}
dependencies:
@ -3862,6 +3858,13 @@ packages:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
dev: false
/mz@2.7.0:
resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
dependencies:
any-promise: 1.3.0
object-assign: 4.1.1
thenify-all: 1.6.0
/nanoid@3.3.6:
resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
@ -4095,7 +4098,6 @@ packages:
/object-assign@4.1.1:
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
engines: {node: '>=0.10.0'}
dev: true
/object-hash@3.0.0:
resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
@ -4311,7 +4313,6 @@ packages:
/pify@2.3.0:
resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
engines: {node: '>=0.10.0'}
dev: true
/pify@4.0.1:
resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==}
@ -4330,6 +4331,10 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
/pirates@4.0.6:
resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
engines: {node: '>= 6'}
/pkg-dir@4.2.0:
resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==}
engines: {node: '>=8'}
@ -4342,6 +4347,17 @@ packages:
hasBin: true
dev: true
/postcss-import@15.1.0(postcss@8.4.29):
resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==}
engines: {node: '>=14.0.0'}
peerDependencies:
postcss: ^8.0.0
dependencies:
postcss: 8.4.29
postcss-value-parser: 4.2.0
read-cache: 1.0.0
resolve: 1.22.4
/postcss-js@4.0.1(postcss@8.4.29):
resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==}
engines: {node: ^12 || ^14 || >= 16}
@ -4351,22 +4367,6 @@ packages:
camelcase-css: 2.0.1
postcss: 8.4.29
/postcss-load-config@3.1.4(postcss@8.4.29):
resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==}
engines: {node: '>= 10'}
peerDependencies:
postcss: '>=8.0.9'
ts-node: '>=9.0.0'
peerDependenciesMeta:
postcss:
optional: true
ts-node:
optional: true
dependencies:
lilconfig: 2.1.0
postcss: 8.4.29
yaml: 1.10.2
/postcss-load-config@4.0.1(postcss@8.4.29):
resolution: {integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==}
engines: {node: '>= 14'}
@ -4382,10 +4382,9 @@ packages:
lilconfig: 2.1.0
postcss: 8.4.29
yaml: 2.3.2
dev: false
/postcss-nested@5.0.6(postcss@8.4.29):
resolution: {integrity: sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA==}
/postcss-nested@6.0.1(postcss@8.4.29):
resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==}
engines: {node: '>=12.0'}
peerDependencies:
postcss: ^8.2.14
@ -4599,6 +4598,7 @@ packages:
/quick-lru@5.1.1:
resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==}
engines: {node: '>=10'}
dev: false
/rc-config-loader@4.1.3:
resolution: {integrity: sha512-kD7FqML7l800i6pS6pvLyIE2ncbk9Du8Q0gp/4hMPhJU6ZxApkoLcGD8ZeqgiAlfwZ6BlETq6qqe+12DUL207w==}
@ -4653,6 +4653,11 @@ packages:
loose-envify: 1.4.0
dev: false
/read-cache@1.0.0:
resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==}
dependencies:
pify: 2.3.0
/read-package-json-fast@3.0.2:
resolution: {integrity: sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
@ -5289,6 +5294,19 @@ packages:
escape-string-regexp: 1.0.5
dev: true
/sucrase@3.34.0:
resolution: {integrity: sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==}
engines: {node: '>=8'}
hasBin: true
dependencies:
'@jridgewell/gen-mapping': 0.3.3
commander: 4.1.1
glob: 7.1.6
lines-and-columns: 1.2.4
mz: 2.7.0
pirates: 4.0.6
ts-interface-checker: 0.1.13
/suf-log@2.5.3:
resolution: {integrity: sha512-KvC8OPjzdNOe+xQ4XWJV2whQA0aM1kGVczMQ8+dStAO6KfEB140JEVQ9dE76ONZ0/Ylf67ni4tILPJB41U0eow==}
dependencies:
@ -5319,34 +5337,33 @@ packages:
picocolors: 1.0.0
dev: false
/tailwindcss@3.0.24(postcss@8.4.29):
resolution: {integrity: sha512-H3uMmZNWzG6aqmg9q07ZIRNIawoiEcNFKDfL+YzOPuPsXuDXxJxB9icqzLgdzKNwjG3SAro2h9SYav8ewXNgig==}
engines: {node: '>=12.13.0'}
/tailwindcss@3.3.3:
resolution: {integrity: sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w==}
engines: {node: '>=14.0.0'}
hasBin: true
peerDependencies:
postcss: ^8.0.9
dependencies:
'@alloc/quick-lru': 5.2.0
arg: 5.0.2
chokidar: 3.5.3
color-name: 1.1.4
detective: 5.2.1
didyoumean: 1.2.2
dlv: 1.1.3
fast-glob: 3.3.1
glob-parent: 6.0.2
is-glob: 4.0.3
jiti: 1.19.3
lilconfig: 2.1.0
micromatch: 4.0.5
normalize-path: 3.0.0
object-hash: 3.0.0
picocolors: 1.0.0
postcss: 8.4.29
postcss-import: 15.1.0(postcss@8.4.29)
postcss-js: 4.0.1(postcss@8.4.29)
postcss-load-config: 3.1.4(postcss@8.4.29)
postcss-nested: 5.0.6(postcss@8.4.29)
postcss-load-config: 4.0.1(postcss@8.4.29)
postcss-nested: 6.0.1(postcss@8.4.29)
postcss-selector-parser: 6.0.13
postcss-value-parser: 4.2.0
quick-lru: 5.1.1
resolve: 1.22.4
sucrase: 3.34.0
transitivePeerDependencies:
- ts-node
@ -5409,6 +5426,17 @@ packages:
source-map-support: 0.5.21
dev: false
/thenify-all@1.6.0:
resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
engines: {node: '>=0.8'}
dependencies:
thenify: 3.3.1
/thenify@3.3.1:
resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
dependencies:
any-promise: 1.3.0
/to-fast-properties@2.0.0:
resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
engines: {node: '>=4'}
@ -5435,6 +5463,9 @@ packages:
resolution: {integrity: sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==}
dev: false
/ts-interface-checker@0.1.13:
resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
/tsconfig-resolver@3.0.1:
resolution: {integrity: sha512-ZHqlstlQF449v8glscGRXzL6l2dZvASPCdXJRWG4gHEZlUVx2Jtmr+a2zeVG4LCsKhDXKRj5R3h0C/98UcVAQg==}
dependencies:
@ -5829,10 +5860,6 @@ packages:
engines: {node: '>=12'}
dev: false
/xtend@4.0.2:
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
engines: {node: '>=0.4'}
/yallist@3.1.1:
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
dev: false
@ -5841,14 +5868,9 @@ packages:
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
dev: false
/yaml@1.10.2:
resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}
engines: {node: '>= 6'}
/yaml@2.3.2:
resolution: {integrity: sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg==}
engines: {node: '>= 14'}
dev: false
/yargs-parser@21.1.1:
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}

@ -1,7 +1,7 @@
import { useEffect, useState } from 'react';
import { EmptyProgress } from './EmptyProgress';
import { httpGet } from '../../lib/http';
import { ProgressList } from './ProgressList';
import { HeroRoadmaps } from './HeroRoadmaps.tsx';
import {isLoggedIn} from "../../lib/jwt";
export type UserProgressResponse = {
@ -122,7 +122,7 @@ export function FavoriteRoadmaps() {
<div className="container min-h-full">
{!isLoading && progress.length == 0 && <EmptyProgress />}
{progress.length > 0 && (
<ProgressList progress={progress} isLoading={isLoading} />
<HeroRoadmaps progress={progress} isLoading={isLoading} />
)}
</div>
</div>

@ -0,0 +1,155 @@
import type { UserProgressResponse } from './FavoriteRoadmaps';
import { CheckIcon } from '../ReactIcons/CheckIcon';
import { MarkFavorite } from '../FeaturedItems/MarkFavorite';
import { Spinner } from '../ReactIcons/Spinner';
import type { ResourceType } from '../../lib/resource-progress';
import { MapIcon } from 'lucide-react';
type ProgressRoadmapProps = {
url: string;
percentageDone: number;
allowFavorite?: boolean;
resourceId: string;
resourceType: ResourceType;
resourceTitle: string;
isFavorite?: boolean;
};
function HeroRoadmap(props: ProgressRoadmapProps) {
const {
url,
percentageDone,
resourceType,
resourceId,
resourceTitle,
isFavorite,
allowFavorite = true,
} = props;
return (
<a
href={url}
className="relative flex flex-col overflow-hidden rounded-md border border-slate-800 bg-slate-900 p-3 text-sm text-slate-400 hover:border-slate-600 hover:text-slate-300"
>
<span className="relative z-20">{resourceTitle}</span>
<span
className="absolute bottom-0 left-0 top-0 z-10 bg-[#172a3a]"
style={{ width: `${percentageDone}%` }}
></span>
{allowFavorite && (
<MarkFavorite
resourceId={resourceId}
resourceType={resourceType}
favorite={isFavorite}
/>
)}
</a>
);
}
type ProgressTitleProps = {
icon: any;
isLoading?: boolean;
title: string;
};
export function HeroTitle(props: ProgressTitleProps) {
const { isLoading = false, title, icon } = props;
return (
<p className="mb-4 flex items-center text-sm text-gray-400">
{!isLoading && icon}
{isLoading && (
<span className="mr-1.5">
<Spinner />
</span>
)}
{title}
</p>
);
}
type ProgressListProps = {
progress: UserProgressResponse;
showCustomRoadmaps?: boolean;
customRoadmaps: any[]; // @fixme implement this
isLoading?: boolean;
};
export function HeroRoadmaps(props: ProgressListProps) {
const {
progress,
isLoading = false,
customRoadmaps = [{} /* @fixme implement this */],
showCustomRoadmaps = false,
} = props;
return (
<div className="relative pb-12 pt-4 sm:pt-7">
{
<HeroTitle
icon={
(<CheckIcon additionalClasses="mr-1.5 h-[14px] w-[14px]" />) as any
}
isLoading={isLoading}
title="Your progress and favorite roadmaps."
/>
}
<div className="grid grid-cols-1 gap-2 sm:grid-cols-2 md:grid-cols-3">
{progress.map((resource) => (
<HeroRoadmap
key={resource.resourceId}
resourceId={resource.resourceId}
resourceType={resource.resourceType}
resourceTitle={resource.resourceTitle}
isFavorite={resource.isFavorite}
percentageDone={
((resource.skipped + resource.done) / resource.total) * 100
}
url={
resource.resourceType === 'roadmap'
? `/${resource.resourceId}`
: `/best-practices/${resource.resourceId}`
}
/>
))}
</div>
{showCustomRoadmaps && (
<div className="mt-5">
{
<HeroTitle
icon={<MapIcon className="mr-1.5 h-[14px] w-[14px]" />}
title="Your custom roadmaps"
/>
}
{customRoadmaps.length === 0 && (
<p className="rounded-md border border-dashed border-gray-800 p-2 text-sm text-gray-600">
You haven't created any custom roadmaps yet.{' '}
<button className="text-gray-500 underline underline-offset-2 hover:text-gray-400">
Create one!
</button>
</p>
)}
<div className="grid grid-cols-1 gap-2 sm:grid-cols-2 md:grid-cols-3">
{customRoadmaps.map((customRoadmap) => (
<HeroRoadmap
resourceId={'343434'}
resourceType={'roadmap'}
resourceTitle={'Frontend Roadmap Revised'}
percentageDone={50}
url={`/r?${'34343434'}`}
allowFavorite={false}
/>
))}
</div>
</div>
)}
</div>
);
}

@ -1,61 +0,0 @@
import type { UserProgressResponse } from './FavoriteRoadmaps';
import { CheckIcon } from '../ReactIcons/CheckIcon';
import { MarkFavorite } from '../FeaturedItems/MarkFavorite';
import { Spinner } from '../ReactIcons/Spinner';
type ProgressListProps = {
progress: UserProgressResponse;
isLoading?: boolean;
};
export function ProgressList(props: ProgressListProps) {
const { progress, isLoading = false } = props;
return (
<div className="relative pb-12 pt-4 sm:pt-7">
<p className="mb-4 flex items-center text-sm text-gray-400">
{!isLoading && (
<CheckIcon additionalClasses={'mr-1.5 w-[14px] h-[14px]'} />
)}
{isLoading && (
<span className="mr-1.5">
<Spinner />
</span>
)}
Your progress and favorite roadmaps.
</p>
<div className="grid grid-cols-1 gap-2 sm:grid-cols-2 md:grid-cols-3">
{progress.map((resource) => {
const url =
resource.resourceType === 'roadmap'
? `/${resource.resourceId}`
: `/best-practices/${resource.resourceId}`;
const percentageDone =
((resource.skipped + resource.done) / resource.total) * 100;
return (
<a
key={resource.resourceId}
href={url}
className="relative flex flex-col overflow-hidden rounded-md border border-slate-800 bg-slate-900 p-3 text-sm text-slate-400 hover:border-slate-600 hover:text-slate-300"
>
<span className="relative z-20">{resource.resourceTitle}</span>
<span
className="absolute bottom-0 left-0 top-0 z-10 bg-[#172a3a]"
style={{ width: `${percentageDone}%` }}
></span>
<MarkFavorite
resourceId={resource.resourceId}
resourceType={resource.resourceType}
favorite={resource.isFavorite}
/>
</a>
);
})}
</div>
</div>
);
}

@ -71,6 +71,21 @@ export function QuestionCard() {
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam
voluptatum, quod, quas, quia, voluptates voluptate quibusdam
voluptatibus quos quae quidem. Quisqu
<br />
<br />
Quisquam voluptatum, quod, quas, quia, voluptates voluptate
quibusdam voluptatibus quos quae quidem. Quisquam voluptatum, quod,
quas, quia, voluptates voluptate quibusdam voluptatibus quos quae
quidem. Quisquam voluptatum, quod, quas, quia, voluptates voluptate
quibusdam voluptatibus quos quae quidem.
<br />
<br />
Quisquam voluptatum, quod, quas, quia, voluptates voluptate
quibusdam voluptatibus quos quae quidem. Quisquam voluptatum, quod,
quas, quia, voluptates voluptate quibusdam voluptatibus quos quae
quidem. Quisquam voluptatum, quod, quas, quia, voluptates voluptate
quibusdam voluptatibus quos quae quidem.
</p>
</div>
<div className="mt-7 text-center">

@ -72,9 +72,7 @@ export function QuestionsList() {
<CheckCircle className="mr-1 h-4 text-current" />
Already Know that
</button>
<button
className="flex flex-1 items-center rounded-xl border border-gray-300 bg-white py-3 px-4 text-black transition-colors hover:border-black hover:bg-black hover:text-white"
>
<button className="flex flex-1 items-center rounded-xl border border-gray-300 bg-white py-3 px-4 text-black transition-colors hover:border-black hover:bg-black hover:text-white">
<Sparkles className="mr-1 h-4 text-current" />
Didn't Know that
</button>

@ -1,8 +1,15 @@
import {Check, CheckCircle, Lightbulb, PartyPopper, RotateCcw, Sparkles} from 'lucide-react';
import {
Check,
CheckCircle,
Lightbulb,
PartyPopper,
RotateCcw,
Sparkles,
} from 'lucide-react';
export function QuestionsProgress() {
return (
<div className="mb-5 rounded-lg border border-gray-300 bg-white p-6">
<div className="mb-5 rounded-lg border border-gray-300 bg-white p-6 overflow-hidden">
<div className="mb-3 flex items-center text-gray-600">
<div className="relative w-full flex-1 rounded-xl bg-gray-200 p-1">
<div className="absolute bottom-0 left-0 top-0 w-[30%] rounded-xl bg-slate-800"></div>
@ -32,6 +39,13 @@ export function QuestionsProgress() {
Reset Progress
</button>
</div>
<p className="-mx-6 mt-6 -mb-6 border-t bg-yellow-100 py-3 text-sm text-yellow-900">
You progress will not be saved. Please{' '}
<button className="underline-offset-3 font-medium underline">
login to save your progress.
</button>
</p>
</div>
);
}

Loading…
Cancel
Save