Compare commits

...

591 Commits

Author SHA1 Message Date
Kamran Ahmed
fd6888a61d Add progress loading on roadmap pages 2023-06-17 05:28:46 +01:00
Umair Khan
6c9ba75906 Fix KodeKloud spelling (#4066)
* Update devops.json 

kodekloud spelling correction

* Update src/data/roadmaps/devops/devops.json

---------

Co-authored-by: Kamran Ahmed <kamranahmed.se@gmail.com>
2023-06-15 22:17:53 +01:00
Kamran Ahmed
70976ee42a Add roadcard as protected route 2023-06-15 14:51:52 +01:00
roadmap bot
5848698abf chore: add resource under python:python-advanced-topics:lambdas 2023-06-15 02:27:28 +01:00
roadmap bot
29dd1eb21f chore: add resource under python:python-advanced-topics:decorators 2023-06-15 02:27:17 +01:00
roadmap bot
ebe6d3c6e4 chore: add resource under system-design:latency-vs-throughput 2023-06-15 02:27:06 +01:00
roadmap bot
425bfea265 chore: add resource under system-design:performance-vs-scalability 2023-06-15 02:26:57 +01:00
roadmap bot
c58efe8d00 chore: add resource under python:python-advanced-topics:oop:classes 2023-06-15 02:26:39 +01:00
Kamran Ahmed
955d04e532 UI changes on road cards 2023-06-14 20:58:15 +01:00
Kamran Ahmed
0031a9c6ba Remove preact-compat 2023-06-14 20:42:32 +01:00
Kamran Ahmed
8fb778337d Add support for roadcards 2023-06-14 20:42:07 +01:00
Kamran Ahmed
a48d39a863 Update animation of progress switcher 2023-06-14 15:02:53 +01:00
Kamran Ahmed
36b2a8f2d7 Progress container update 2023-06-14 14:46:10 +01:00
Kamran Ahmed
00e9d44ba9 Remove client:only from favorite roadmaps 2023-06-14 13:54:54 +01:00
Kamran Ahmed
62b068a94a Fix jitter on homepage 2023-06-14 13:51:29 +01:00
Kamran Ahmed
af926002e9 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 <kanhaya.workspace@gmail.com>
2023-06-14 13:12:52 +01:00
roadmap bot
0612f9c44f chore: add resource under docker:introduction:what-are-containers 2023-06-14 03:47:19 +01:00
roadmap bot
fbf545c2ed chore: add resource under cyber-security:security-skills-and-knowledge:common-distros-for-hacking:parrot-os 2023-06-14 03:47:04 +01:00
roadmap bot
c7ef97cb4f chore: add resource under react:rendering:refs 2023-06-14 03:46:43 +01:00
roadmap bot
564f48540e chore: add resource under react:rendering:render-props 2023-06-14 03:46:29 +01:00
roadmap bot
52e729d212 chore: add resource under prompt-engineering:prompting-introduction 2023-06-14 03:45:32 +01:00
roadmap bot
bdfa7606dd chore: add resource under devops:live-in-terminal:scripting:powershell 2023-06-14 03:45:21 +01:00
roadmap bot
056e0e8e3a chore: add resource under react:rendering:lists-and-keys 2023-06-14 03:45:11 +01:00
roadmap bot
879ba258b2 chore: add resource under cyber-security:basic-it-skills:connection-types:wifi 2023-06-14 03:44:40 +01:00
Kamran Ahmed
3d62d2689f Animate progress on the homescreen 2023-06-14 02:09:09 +01:00
Arik Chakma
ac892d2868 Merge pull request #4047 from kanhayaKy/patch-1
fix: ubuntu type
2023-06-13 17:57:19 +06:00
roadmap bot
19bde7bb2f chore: add resource under cyber-security:security-skills-and-knowledge:forensics 2023-06-13 11:38:12 +01:00
roadmap bot
419b1872b8 chore: add resource under javascript:javascript-asynchronous-javascript:callbacks 2023-06-13 11:37:50 +01:00
roadmap bot
bbeb4ee279 chore: add resource under devops:live-in-terminal:scripting:bash-scripting 2023-06-13 11:37:42 +01:00
roadmap bot
f2ca7d9140 chore: add resource under backend:relational-databases:mysql 2023-06-13 11:37:12 +01:00
roadmap bot
70b95c6ad1 chore: add resource under javascript:javascript-asynchronous-javascript:callbacks:callback-hell 2023-06-13 11:36:49 +01:00
roadmap bot
5a3f621093 chore: add resource under javascript:javascript-loops-iterations:break-continue:labeled-statements 2023-06-13 11:36:41 +01:00
roadmap bot
631eb380fc chore: add resource under cpp:pointers-and-references:smart-pointers:weak-ptr 2023-06-13 11:36:31 +01:00
roadmap bot
cb9778ba15 chore: add resource under cyber-security:basic-it-skills:os-independent-troubleshooting 2023-06-13 11:36:20 +01:00
roadmap bot
38106a8199 chore: add resource under typescript:typescript-types:type-assertions:as-type 2023-06-13 11:35:46 +01:00
roadmap bot
226e94857b chore: add resource under aspnet-core:basics-of-csharp:csharp 2023-06-13 11:35:31 +01:00
roadmap bot
f94c701657 chore: add resource under computer-science:pick-a-language:c-plus-plus 2023-06-13 11:35:17 +01:00
roadmap bot
259109cc38 chore: add resource under cyber-security:basic-it-skills 2023-06-13 11:35:04 +01:00
kanhaya kumar yadav
e120df30e3 Update 100-installing-a-local-cluster.md
fixed typo for ubuntu in 100-installing-a-local-cluster.md
2023-06-13 11:46:55 +05:30
Kamran Ahmed
43f351a943 Add progress loading on homepage roadmaps 2023-06-13 03:19:59 +01:00
roadmap bot
502b8e20d5 chore: add resource under computer-science:common-algorithms:graph-algorithms:breadth-first-search 2023-06-11 18:44:23 +01:00
roadmap bot
ff5858f965 chore: add resource under flutter:widgets:inherited-widgets 2023-06-11 18:43:59 +01:00
roadmap bot
8b8ef52d98 chore: add resource under python:python-basics 2023-06-11 18:43:37 +01:00
roadmap bot
7032bc0726 chore: add resource under backend:repo-hosting-services:github 2023-06-11 18:43:29 +01:00
roadmap bot
ba65dec596 chore: add resource under cpp:libraries:poco 2023-06-11 18:42:48 +01:00
roadmap bot
78cf88fbd9 chore: add resource under flutter:design-principles:design-patterns 2023-06-11 02:10:16 +01:00
roadmap bot
93e16d899a chore: add resource under devops:artifcats:nexus 2023-06-11 02:09:49 +01:00
roadmap bot
14060bda94 chore: add resource under javascript:javascript-control-flow:exception-handling:throw-statement 2023-06-11 02:08:21 +01:00
Kamran Ahmed
45b729d708 Update the schema updated date 2023-06-10 20:28:13 +01:00
roadmap bot
9023ea6298 chore: add resource under angular:typescript-basics:union-types 2023-06-10 14:06:00 +01:00
Kamran Ahmed
d29176cf98 Add links to beginner versions 2023-06-10 11:40:24 +01:00
Kamran Ahmed
55989d8480 Add updated devops roadmap pdf 2023-06-10 04:03:38 +01:00
Kamran Ahmed
9c936974c7 Add devops beginner roadmap 2023-06-10 04:02:51 +01:00
Kamran Ahmed
311b4683d0 Rewrite devops roadmap 2023-06-10 04:02:48 +01:00
roadmap bot
bf61697154 chore: add resource under react:hooks:common-hooks 2023-06-09 21:01:31 +01:00
roadmap bot
52818f1e34 chore: add resource under blockchain:blockchain-basics 2023-06-09 21:01:17 +01:00
roadmap bot
174ea05a92 chore: add resource under devops:infrastructure-as-code:kubernetes 2023-06-09 20:59:40 +01:00
roadmap bot
dcb4e06fea chore: add resource under cyber-security:security-skills-and-knowledge:blue-team-read-team-purple-team 2023-06-09 01:53:31 +01:00
roadmap bot
62eb6a4a01 chore: add resource under postgresql-dba:introduction:what-are-relational-databases 2023-06-09 01:53:04 +01:00
roadmap bot
f643f3bd9a chore: add resource under kubernetes:running-applications:deployments 2023-06-09 01:52:10 +01:00
roadmap bot
972370e0e6 chore: add resource under angular:typescript-basics:type-guard 2023-06-09 01:52:01 +01:00
roadmap bot
a6feb72339 chore: add resource under cyber-security:basic-it-skills:connection-types:nfc 2023-06-09 01:51:47 +01:00
roadmap bot
c751706631 chore: add resource under cpp:functions:lambda 2023-06-09 01:51:32 +01:00
roadmap bot
8900324234 chore: add resource under frontend:css:responsive-design-and-media-queries 2023-06-09 01:51:04 +01:00
roadmap bot
f1b880d898 chore: add resource under java:java-advanced-topics:memory-management 2023-06-09 01:50:50 +01:00
roadmap bot
9a285d7470 chore: add resource under cpp:setting-up:code-editors 2023-06-09 01:50:36 +01:00
roadmap bot
15259560e0 chore: add resource under javascript:javascript-control-flow:exception-handling 2023-06-09 01:50:19 +01:00
roadmap bot
d8afa166aa chore: add resource under python:python-basics:variables-and-datatypes 2023-06-08 14:34:57 +01:00
roadmap bot
d39791257e chore: add resource under cpp:introduction:what-is-cpp 2023-06-07 14:48:42 +01:00
Kamran Ahmed
06b7005782 chore: add resource under cyber-security:security-skills-and-knowledge:attack-types:phishing-vishing-whaling-smishing 2023-06-07 11:24:23 +01:00
Kamran Ahmed
bc6c933440 chore: add resource under cyber-security:security-skills-and-knowledge:cryptography 2023-06-07 11:24:05 +01:00
Kamran Ahmed
b965a89db3 chore: add resource under java:java-advanced-topics:garbage-collection 2023-06-07 11:23:32 +01:00
Kamran Ahmed
9b82e327e2 chore: add resource under backend:learn-a-language:java 2023-06-07 11:23:01 +01:00
Kamran Ahmed
5808125d92 chore: add resource under computer-science:pick-a-language:c-plus-plus 2023-06-07 11:22:38 +01:00
Kamran Ahmed
f49fe258aa chore: add resource under cyber-security:basic-it-skills:connection-types:nfc 2023-06-07 11:22:05 +01:00
Kamran Ahmed
08df9e8c33 chore: add resource under cyber-security:extras:certifications:beginner-certifications:comptia-aplus 2023-06-07 11:21:46 +01:00
Kamran Ahmed
56e388edd8 chore: add resource under backend:apis:authentication:openid 2023-06-07 11:21:08 +01:00
Kamran Ahmed
ded75c7af1 chore: add resource under golang:go-basics:structs 2023-06-07 11:20:44 +01:00
Kamran Ahmed
557c426078 Update apollo workshop image 2023-06-07 11:19:42 +01:00
Kamran Ahmed
d61a83a0a3 chore: add resource under flutter:design-principles:solid-principles 2023-06-06 14:19:46 +01:00
Kamran Ahmed
7500c6c1cb chore: add resource under backend:internet:what-is-http 2023-06-06 14:19:16 +01:00
Kamran Ahmed
b51076dd0a chore: add resource under cpp:introduction 2023-06-06 14:18:56 +01:00
Kamran Ahmed
8010bfc832 Add kodecloud link 2023-06-06 14:17:21 +01:00
Kamran Ahmed
0f80f26d17 Update link-groups 2023-06-06 11:02:08 +01:00
thesmallrock
40d25c43f4 Fixing "new and delete operators" titles. (#3994) 2023-06-06 09:32:02 +01:00
Kamran Ahmed
686a7382ab chore: add resource under cyber-security:basic-it-skills:basics-of-computer-networking 2023-06-06 09:11:42 +01:00
Kamran Ahmed
88401bd7b1 chore: add resource under mongodb:datatypes:date 2023-06-06 09:11:12 +01:00
Kamran Ahmed
1d97467c05 chore: add resource under software-design-architecture:architectural-styles 2023-06-06 09:10:43 +01:00
Kamran Ahmed
2388fa148b Update apollo workshop 2023-06-05 23:40:10 +01:00
Kamran Ahmed
d574fccbc8 Add apollo asset 2023-06-05 23:21:04 +01:00
Kamran Ahmed
89cc55a1eb chore: add resource under flutter:state-management:change-notifier 2023-06-05 21:18:29 +01:00
Kamran Ahmed
8c75354235 chore: add resource under flutter:state-management:value-notifier 2023-06-05 21:18:22 +01:00
Kamran Ahmed
9eb9dc8cd8 chore: add resource under nodejs:nodejs-command-line-apps:taking-input 2023-06-05 21:18:07 +01:00
Kamran Ahmed
afa28bddd3 chore: add resource under python:python-advanced-topics:lambdas 2023-06-05 21:17:32 +01:00
Kamran Ahmed
5cf0e76765 chore: add resource under react:components:props-vs-state 2023-06-05 21:16:59 +01:00
Kamran Ahmed
16b3f8ff49 chore: add resource under system-design:application-layer:microservices 2023-06-05 21:16:12 +01:00
Kamran Ahmed
d2055e0f6d chore: add resource under react:components:conditional-rendering 2023-06-05 21:15:43 +01:00
Kamran Ahmed
4010157baf chore: add resource under ux-design:human-decision-making:frameworks:bj-frogg-behavior-model 2023-06-05 21:15:08 +01:00
Kamran Ahmed
75c7e83264 chore: add resource under backend:os-general-knowledge:terminal-usage 2023-06-05 21:14:28 +01:00
Kamran Ahmed
8ca22e0dcc chore: add resource under python:python-testing:pytest 2023-06-05 21:13:27 +01:00
Kamran Ahmed
2b8d1f470c chore: add resource under backend:version-control-systems:git 2023-06-05 21:13:15 +01:00
Kamran Ahmed
c4d9651e95 chore: add resource under react:components 2023-06-05 21:12:13 +01:00
Kamran Ahmed
813c0ebd93 chore: add resource under backend:relational-databases:mysql 2023-06-05 21:11:38 +01:00
Kamran Ahmed
e376942c8d chore: add resource under devops:infrastructure-as-code:gitops:argo-cd 2023-06-05 21:02:21 +01:00
Kamran Ahmed
6d91c11856 chore: add resource link to ux-design >> human-decision-making:frameworks:stephen-wendell-create-action-funnel 2023-06-05 21:00:49 +01:00
Kamran Ahmed
1d47b1fb7b chore: add resource link to cpp >> introduction:what-is-cpp 2023-06-05 20:47:54 +01:00
Kamran Ahmed
54a9e586bf chore: add resource link to frontend >> progressive-web-apps:lighthouse 2023-06-05 20:46:58 +01:00
Kamran Ahmed
b58c2a1356 Fix roadmap json 2023-06-05 20:38:54 +01:00
Kamran Ahmed
dec5e58063 Refactor roadmap and best practice rendering engine 2023-06-05 19:55:58 +01:00
Kamran Ahmed
b0a4130229 Update code review pyramid 2023-06-04 23:00:35 +01:00
Kamran Ahmed
a06e992b8a Update reference link for code review pyramid 2023-06-03 21:31:37 +01:00
Kamran Ahmed
6e1072bea9 Add code review pyramid 2023-06-03 21:17:55 +01:00
Kamran Ahmed
1f9eb18bfb Add update file URL in the topic file 2023-06-02 22:45:37 +01:00
Kamran Ahmed
603bd2b107 Update contribution copy 2023-06-02 21:34:30 +01:00
Kamran Ahmed
0163d9e4f9 Update copy on contribution 2023-06-02 21:33:30 +01:00
Kamran Ahmed
910579f463 Update isNew badges 2023-06-02 21:31:27 +01:00
Kamran Ahmed
d6a28a312a Add contribution functionality 2023-06-02 21:23:26 +01:00
Kamran Ahmed
267a4a7be5 Update cpp roadmap dates 2023-06-01 17:01:39 +01:00
Kamran Ahmed
59111a1a90 Add link to C++ roadmap 2023-06-01 03:59:22 +01:00
Kamran Ahmed
9f5d1aef74 Add content to C++ roadmap 2023-06-01 03:42:42 +01:00
Kamran Ahmed
36eed57ec2 Add content to C++ roadmap 2023-06-01 03:33:27 +01:00
Kamran Ahmed
cc054bb24b Add content to C++ roadmap 2023-06-01 03:18:40 +01:00
Kamran Ahmed
056256015d Add C++ roadmap 2023-06-01 02:55:26 +01:00
Arik Chakma
dd5f3795ec fix: login link (#3985) 2023-05-31 10:00:19 +01:00
Kamran Ahmed
8c29d43bef fix: page loading message does not persist 2023-05-30 19:48:40 +01:00
Kamran Ahmed
aa32258aa1 Refactor page progress implementation 2023-05-30 18:52:41 +01:00
Kamran Ahmed
d2394aca77 Downgrade nanostores 2023-05-30 18:40:58 +01:00
Kamran Ahmed
6804535fe4 chore: update dependencies 2023-05-30 18:27:08 +01:00
github-actions[bot]
3852e7d96f chore: update dependencies to latest (#3973)
Co-authored-by: kamranahmedse <kamranahmedse@users.noreply.github.com>
2023-05-30 17:41:57 +01:00
Kamran Ahmed
eb852caee8 Update link to improve guide 2023-05-30 14:50:37 +01:00
유성현
1414693e33 fix minor typos (#3974)
* 📝 fix : typos

* Update 101-anti-corruption-layer.md

---------

Co-authored-by: Arik Chakma <arikchangma@gmail.com>
2023-05-30 14:32:15 +01:00
Kamran Ahmed
fbdb7e77c3 Fix: active sidebar missing border 2023-05-27 03:04:35 +01:00
Kamran Ahmed
c72658938f Add icons in the mobile sidebar menu 2023-05-26 17:31:10 +01:00
Kamran Ahmed
718c582a8c Update account sidebar 2023-05-26 17:11:59 +01:00
Kamran Ahmed
12f385dffd Show the recently updated item on top 2023-05-26 15:38:04 +01:00
Kamran Ahmed
35f500d218 Show most recently tracked items on top 2023-05-26 03:43:50 +01:00
Kamran Ahmed
44949709d1 Add activity page 2023-05-26 03:16:25 +01:00
Kamran Ahmed
476557db80 Add activity dashboard 2023-05-25 16:37:33 +01:00
Kamran Ahmed
f7625a8250 Add basic UI for activity dashboard 2023-05-24 19:25:35 +01:00
Kamran Ahmed
c06c236da5 Refactor account pages 2023-05-24 15:18:29 +01:00
Kamran Ahmed
24c262282e External redirect tracking from roadmap.sh 2023-05-22 19:59:38 +01:00
Kamran Ahmed
876330522d Add devops by nana link 2023-05-22 19:59:38 +01:00
Sean Kelly
f1c771e95c Fix typo in content (#3959) 2023-05-22 18:08:55 +01:00
Kamran Ahmed
d3668b25e9 Add kbd around cmd+k 2023-05-22 11:06:26 +01:00
Kamran Ahmed
b0493c370c Add prompt engineering roadmap 2023-05-21 13:00:45 +01:00
Arik Chakma
e67caa0ffe chore: firefox input outline (#3951) 2023-05-21 12:56:34 +01:00
Arik Chakma
82a44ddfef fix: user gets logged out on browser quit (#3947) 2023-05-21 12:55:02 +01:00
Arik Chakma
205fe6cc23 fix: firefox bug (#3948) 2023-05-21 12:27:38 +01:00
Kamran Ahmed
591cac8bfa Add content for reliability 2023-05-21 03:39:19 +01:00
Kamran Ahmed
42debdeab0 Add content for real world under prompting techniques 2023-05-21 03:22:20 +01:00
Kamran Ahmed
0555452bf2 Load pages on render 2023-05-21 02:17:31 +01:00
Kamran Ahmed
cc7f9d94bb Clear text on command menu close 2023-05-20 23:47:54 +01:00
Kamran Ahmed
51d986b86f Add support for CMD + K search (#3944)
* Add command k input

* On Enter open the page

* chore: backend fix

* Refactor pages and add retrieval

* Group separation, no result handling and filtering

* Fix responsiveness of command menu

* Activate on CMD+K and focus

* Add icons to menu

* Add page filtering

* Add search icon in navigation

---------

Co-authored-by: Arik Chakma <arikchangma@gmail.com>
2023-05-20 23:20:11 +01:00
Kamran Ahmed
83057d65cd Update content for prompt engineering 2023-05-20 12:15:37 +01:00
Kamran Ahmed
b886f20570 Add pdf for prompt engineering 2023-05-20 05:13:38 +01:00
Kamran Ahmed
dacd2d898b Add prompt enginering roadmap 2023-05-20 05:12:33 +01:00
Kamran Ahmed
a2490efa80 Add content dirs for prompt engineering 2023-05-20 02:37:57 +01:00
Kamran Ahmed
e087b79ade Add prompt engineering roadmap 2023-05-20 02:10:20 +01:00
Kamran Ahmed
10b1a8cb07 Add guide about resources for llms 2023-05-19 16:06:59 +01:00
Kamran Ahmed
f2c06462fa Add assets for ambassador and GraphQL 2023-05-19 01:05:36 +01:00
Kamran Ahmed
ad7ba44a2e Add pages JSON 2023-05-18 20:03:46 +01:00
Kamran Ahmed
7a72c96e79 Remove categroy field injection 2023-05-18 19:36:39 +01:00
Kamran Ahmed
d955044a3b Add category levels to pages 2023-05-18 18:03:08 +01:00
Kamran Ahmed
b86fafd538 Update roadmap note 2023-05-18 16:23:12 +01:00
Abilio Castro
c52a4e6638 Adding link to Spring Boot roadmap from Java roadmap (#3935)
* Adding link to Spring Boot roadmap from Java roadmap

* Adding link to Spring Boot roadmap from Java roadmap

---------

Co-authored-by: Abilio Silva <asilva@descartes.com>
2023-05-18 15:47:11 +01:00
Kamran Ahmed
9d66da6bf9 Add store link in footer 2023-05-18 12:57:20 +01:00
Kamran Ahmed
4b76d0b7aa Rearrange visual 2023-05-16 16:35:18 +01:00
Kamran Ahmed
626026eebc Add guide about LLMs 2023-05-16 16:35:18 +01:00
Kamran Ahmed
fdd12acb8e Add link to full stack roadmap 2023-05-15 19:51:14 +01:00
Kamran Ahmed
02015826ff Update related roadmaps 2023-05-15 14:51:45 +01:00
Kamran Ahmed
5d07ce32d8 Change color for skipped 2023-05-14 14:57:51 +01:00
Mohammad Ostadi
3967b16d25 Fix wrong backend and devops links (#3919) 2023-05-14 13:09:38 +01:00
Kamran Ahmed
f325183691 Add keydowns in updating progerss 2023-05-14 03:31:00 +01:00
Kamran Ahmed
a029850531 Change color of skipped 2023-05-14 03:12:28 +01:00
Kamran Ahmed
d3d2ae5889 Refactor update topic progress functionality 2023-05-14 03:05:54 +01:00
Kamran Ahmed
4a049b2a7a Skip colors 2023-05-14 02:53:07 +01:00
Kamran Ahmed
fd349f2da8 Allow skipping 2023-05-14 02:41:04 +01:00
Kamran Ahmed
f338bd5ecb Refactor progress button 2023-05-13 12:44:14 +01:00
Kamran Ahmed
a3470cd844 Fix flickering issue on the profile pages 2023-05-12 22:38:14 +01:00
Kamran Ahmed
f4635d794f Refactor buttons 2023-05-12 17:26:37 +01:00
Kamran Ahmed
426fe44dc8 Add content for full stack roadmap 2023-05-12 14:14:45 +01:00
Kamran Ahmed
4ed39cec1a Update monitoring 2023-05-12 13:07:46 +01:00
Kamran Ahmed
b1f0844546 Add github action sample 2023-05-12 12:57:35 +01:00
Kamran Ahmed
88aa7e4024 Add fullstack roadmap 2023-05-12 12:51:34 +01:00
Kamran Ahmed
471f6348f1 Add isNew flag to fullstack roadmap 2023-05-12 12:51:34 +01:00
Kamran Ahmed
9dfb70c941 Add fullstack roadmap 2023-05-12 12:51:34 +01:00
Zai Santillan
6fa7e0d1c0 Update twitter username (#3907) 2023-05-11 03:41:20 +01:00
Kamran Ahmed
5ccfa654ec Add support for custom labels in ga 2023-05-10 01:18:23 +01:00
Kamran Ahmed
1c67068eab Update twitter username 2023-05-09 15:39:50 +01:00
Kamran Ahmed
f5ff2a0823 Add contribution url to topic detail popup 2023-05-09 15:28:16 +01:00
Aman Tank
58503f67f3 Fix #3882, resolves #3874 (#3882)
* F[ixed] Link in Content Delivery Networks #3881

* [Fixed] Typo #3881

* Delete package-lock.json

---------

Co-authored-by: Aman Tank <132202130+amanntank@users.noreply.github.com>
2023-05-09 15:24:21 +01:00
Kamran Ahmed
5dd0479caf Add feature image 2023-05-09 11:47:07 +01:00
Kamran Ahmed
7441f1a203 Refactor avatar implementation 2023-05-09 03:36:29 +01:00
Arik Chakma
4d3ebb0ac6 chore: placeholder image 2023-05-09 03:36:29 +01:00
Arik Chakma
47d5716238 feat: upload profile picture 2023-05-09 03:36:29 +01:00
Kamran Ahmed
94d888a61e Add avatar url config 2023-05-09 03:35:45 +01:00
bany
ddd43a1514 Add missing file android.pdf (#3899) 2023-05-09 02:22:52 +01:00
Kamran Ahmed
2cf94f981b Resource progress functionality 2023-05-09 02:14:27 +01:00
Kamran Ahmed
f1973f63c2 Rename "Mark as Done" and "Mark as Pending" 2023-05-09 01:53:18 +01:00
Arik Chakma
dfb67e17d5 chore: in progress design 2023-05-09 06:21:39 +06:00
Arik Chakma
48239772f6 fix: removing classes 2023-05-09 06:04:47 +06:00
Arik Chakma
1cea9d0e13 chore: added pending state for topics 2023-05-09 06:02:41 +06:00
Kamran Ahmed
6591c36ef4 Add visit tracker to roadmap 2023-05-08 23:06:09 +01:00
Kamran Ahmed
41de9c47b0 Add partner images 2023-05-08 22:48:45 +01:00
Kamran Ahmed
0ba1a8a1d1 Rearrange scripts 2023-05-08 22:16:27 +01:00
Kamran Ahmed
6fcb153244 Fix invalid markdown language warnings 2023-05-08 21:12:34 +01:00
Kamran Ahmed
7a8d97b1cd Refactor analytics 2023-05-08 21:06:33 +01:00
Kamran Ahmed
9e37076d0d Add preconnect for ga and api 2023-05-08 20:59:57 +01:00
Kamran Ahmed
f8e5661353 Refactor perf issues 2023-05-08 20:54:56 +01:00
Kamran Ahmed
4d4cda6cac Fix accessibility issues 2023-05-08 20:37:26 +01:00
Arik Chakma
8b528f39f2 fix: broken link (#3897) 2023-05-08 16:58:35 +01:00
Kamran Ahmed
e1a04b4a20 Update username 2023-05-08 14:36:21 +01:00
Kamran Ahmed
f0e8ffe565 Fix spelling mistake 2023-05-06 16:42:12 +01:00
Kamran Ahmed
f9c1e64235 Add docker roadmap to readme 2023-05-06 01:44:25 +01:00
Kamran Ahmed
0174c9156b Fix formatting issue 2023-05-05 22:51:38 +01:00
Kamran Ahmed
2ee81e6ff3 Add docker roadmap 2023-05-05 22:49:57 +01:00
Kamran Ahmed
42ab5a3e9e Add docker roadmpa 2023-05-05 22:49:57 +01:00
Kamran Ahmed
e9fa663410 Notify icon 2023-05-05 12:16:07 +01:00
Kamran Ahmed
2d17a267be Refactor upcoming form 2023-05-04 18:18:44 +01:00
Arik Chakma
40371cdded fix: notify for upcoming page (#3887)
* chore: upcoming login

* fix: subscribed button
2023-05-04 18:09:32 +01:00
Arik Chakma
6bb315a2fc fix: featured items heading position (#3837) 2023-05-03 14:48:21 +01:00
Kamran Ahmed
fc2c9a1439 Remove sponsors and relevant codebase 2023-05-03 12:50:15 +01:00
Kamran Ahmed
b50935ecd6 Remove delay for sponsors 2023-05-03 04:09:09 +01:00
Kamran Ahmed
9b73d60c5d Add support for multiple ads 2023-05-03 03:14:04 +01:00
Kamran Ahmed
504ee8cf5e Add support for multiple ads 2023-05-02 20:48:01 +01:00
Kamran Ahmed
057bbddd9f Add support for multiple ads 2023-05-02 20:48:01 +01:00
Joshua
4063979c2a Fix typo (#3797) 2023-05-02 20:34:17 +01:00
Rita Bradley
da391fe9ed Fix typos (#3795)
* Fix typos

- Add 's' to reason
- Change "it's" to is
- Remove unnecessary hyphen

* Fix typos

- change 'remove' to 'removing'
- change comma to semicolon

* Fix typos

- change "don't" to "doesn't"
- add "is" before "relied upon"
2023-05-02 20:33:33 +01:00
Kamran Ahmed
953ca9257c Fix typo on homepage 2023-05-01 17:02:16 +01:00
Kamran Ahmed
396bedd319 Update sponsor banners 2023-05-01 16:50:59 +01:00
The New Stack
e05269f117 Add TypeScript installation guide (#3791)
* Added 1 TNS Article

* Update src/data/roadmaps/typescript/content/100-typescript/102-install-configure/index.md

---------

Co-authored-by: Kamran Ahmed <kamranahmed.se@gmail.com>
2023-04-27 13:58:30 +01:00
Kamran Ahmed
77c7ca8835 Update badges 2023-04-27 12:41:08 +01:00
Kamran Ahmed
e877f5c610 Add code review best practices 2023-04-27 12:39:16 +01:00
Kamran Ahmed
42e1a79697 Update code review pdf 2023-04-26 21:12:09 +01:00
Kamran Ahmed
ce32cdc8a4 Update code review texts 2023-04-26 20:54:29 +01:00
Kamran Ahmed
e2a0bd23c0 Add best practice content 2023-04-26 17:44:02 +01:00
Kamran Ahmed
98f0ebde8b Add code-review best practices 2023-04-26 17:17:39 +01:00
Kamran Ahmed
bc018f8b39 Add code review best practices 2023-04-26 15:57:32 +01:00
Kamran Ahmed
03bd478aaa Add data aggregation command 2023-04-26 13:47:19 +01:00
Kamran Ahmed
67a8582c22 Fix overlapping login and videos 2023-04-24 18:07:51 +01:00
Kamran Ahmed
7533575df9 Update PgQ (#3856) 2023-04-24 15:29:21 +01:00
Kamran Ahmed
34fcd74d93 Update ad text 2023-04-21 20:27:52 +01:00
Kamran Ahmed
1558feb734 Update liblab link 2023-04-21 19:48:38 +01:00
Kamran Ahmed
bc4d9f9e2f Add postgresql dba pdf 2023-04-19 22:11:00 +01:00
Kamran Ahmed
4142c7b51e Compress postgresql json 2023-04-19 21:55:56 +01:00
Kamran Ahmed
e36a749223 Update postgresql roadmap 2023-04-19 21:55:22 +01:00
Kamran Ahmed
e69d9b4238 Add PEV2 2023-04-19 15:28:14 +01:00
Kamran Ahmed
3132a39816 Fix sponsor opener 2023-04-19 00:57:41 +01:00
Kamran Ahmed
03f9fa51ff Update roadmap node 2023-04-18 14:36:54 +01:00
Kamran Ahmed
e2062aefe9 Update postgresql roadmap 2023-04-18 14:24:58 +01:00
Kamran Ahmed
855ba7bbfb Add postgresql roadmap 2023-04-18 14:24:58 +01:00
Kamran Ahmed
ad71b6398d Fix styling issue 2023-04-18 14:24:57 +01:00
Kamran Ahmed
0ea0629104 Add postgresql-dba content 2023-04-18 14:24:57 +01:00
Kamran Ahmed
8b2f12fcdd Improve the content writing performance 2023-04-18 14:24:57 +01:00
Kamran Ahmed
e66bff74bf Add postgresql-dba content 2023-04-18 14:24:57 +01:00
github-actions[bot]
58ea34bb49 chore: update sponsors (#3821)
Co-authored-by: kamranahmedse <kamranahmedse@users.noreply.github.com>
2023-04-17 15:01:32 +01:00
Kamran Ahmed
275c2c3c88 Add noindex pages 2023-04-17 00:57:20 +01:00
Kamran Ahmed
f13c29adad Enable github auth 2023-04-14 21:17:49 +01:00
Kamran Ahmed
ec9f836a1f Fix check icon 2023-04-14 20:56:24 +01:00
Kamran Ahmed
589d157be5 Disable github login for now 2023-04-14 20:16:38 +01:00
Kamran Ahmed
a2719bc771 feat: user accounts functionality (#3813)
* feat: integrate astro

* chore: login popup design

* chore: data-popup changed

* refactor: github and google button

* chore: signup page

* chore: login popup design

* chore: signup page design

* chore: auth divider

* feat: integrate astro

* chore: login popup design

* chore: data-popup changed

* refactor: github and google button

* chore: signup page

* chore: login popup design

* chore: signup page design

* chore: auth divider

* chore: login feature

* chore: login error message

* chore: added name in token decode return

* chore: use auth hook

* chore: logout vs login

* chore: download button link

* chore: account dropdown

* fix: dropdown z index

* chore: profile page

* Add missing content for backend roadmap

* Remove unused styles

* Add login with google

* chore: google login implementation

* chore: profile guard clause

* fix: button size

* chore: preact to astro components

* chore: preact to astro comp

* chore: github astro component

* chore: google login error handling

* chore: github login error handling

* chore: change password page

* chore: rename profile to password

* fix: change password rename

* chore: update profile page

* chore: setting sidebar

* fix: setting dropdown design

* chore: required indicator

* chore: change password form

* chore: update profile form

* chore: mobile navigation

* fix: form data empty error

* chore: email login and signup components

* chore: forgot password page

* chore: reset password page

* chore: verify account page

* chore: resend verification email

* fix: types in spinner

* chore: forgot password functionality

* fix: class -> className

* chore: reset password page

* chore: reset password functionality

* chore: login page

* fix: spacing for login and signup page

* refactor: email login form

* chore: astro spinner

* chore: pre-fill user data

* chore: dummy placeholder

* chore: forgot password link add

* fix: replaced constants

* chore: forgot password link

* chore: change password for social provider

* chore: internal pages guard

* chore: internal paths

* refactor: change password errors

* refactor: update profile errors

* chore: mark as done overlay

* fix: uncontrolled to controlled form

* fix: de-structure error

* chore: error messages

* fix: 401 error code redirect to login page

* chore: loading spinner accessibilities

* fix: remove spinner

* chore: keep spinner after success to redirect

* chore: keep the spinner

* style: resend email underline

* chore: chevron down account

* chore: roadmap pdf link download

* chore: roadmap pdf link download

* chore: best practices buttons

* fix: verify account text

* fix: topic overlay hide

* chore: base verify design

* chore: email verify page

* fix: div tag missing

* Formatting

* Refactor top navigation

* Prettier

* Update dependencies

* Refactor top navigation

* Refactor login button

* Remove captcha and add google scripts

* Refactor email sign up form

* Resend verfication email functionality

* Refactor verification pending page

* Add verify account functionality

* Update signup text

* Add login page

* Add login button in top nav

* Email login form

* Handle authenticatoin

* Show hide auth elements change

* Add ease-in on the guest elements

* Refactor logic for download and subscribe popups

* Add forgot password

* Rename fetch lib

* Add authentication popup

* Refactor logic for mark done and pending

* Handle logout

* Add route protection

* Popup opener to close the overlay

* Remember page when logging in

* Add reset password page

* Change placement of constant

* Update profile page

* Add update password form

* Update password page

* Update profile page

* Update design

* chore: toggle mark resource done api

* chore: toggle topic done

* chore: get user resource progress api

* fix: best practice topic toggle

* chore: fetch progress

* fix: query selector for topics

* Keep track of the old page before social login

* Update public api url

* Add user progress tracking

* Update topic done functionality

* Add progress loader

* Add page wide spinner

* Add spinner on setting pages

* Add fingerprint to user requests

* Use http wrapper instead of fetch

* Update fingerprint

* Minor improvements

---------

Co-authored-by: Arik Chakma <arikchangma@gmail.com>
2023-04-14 19:22:52 +01:00
Umair Raza
c5645299aa Issues: Text not showing up properly #3796 (#3802) 2023-04-12 12:09:25 +01:00
Kamran Ahmed
6aac3f296c Remove youtube banner from top 2023-04-08 13:57:32 +01:00
Haseeb Ansari
137635f11a fix: wrong MAN explanation (#3771)
Co-authored-by: haseeb.ansari <haseeb.ansari@qordata.com>
2023-04-07 18:55:53 +01:00
karthikeyantc
8487d2f443 Updated the Route Guard for Angular (#3731)
* Update 104-guards.md

Added the link for resolve route guard

* Update 103-router-events.md

Added the documentation for Router events.

---------

Co-authored-by: Kamran Ahmed <kamranahmed.se@gmail.com>
2023-04-05 17:35:19 +01:00
github-actions[bot]
a7bee1fea7 chore: update dependencies to latest (#3744)
Co-authored-by: kamranahmedse <kamranahmedse@users.noreply.github.com>
2023-04-05 17:34:13 +01:00
CMarghin
43292de507 Fix typo, replace Interface with Inference (#3750) 2023-04-05 17:32:51 +01:00
Sanjay Singha
bee30defb5 Add content for FVM (#3759)
* Adding content for FVM

* Update src/data/roadmaps/flutter/content/101-setup-development-environment/102-fvm.md

---------

Co-authored-by: Kamran Ahmed <kamranahmed.se@gmail.com>
2023-04-05 17:32:20 +01:00
Pedro Macedo
52649a2d3c Change react docs link (#3742) 2023-04-05 17:31:04 +01:00
Salah Eddine Mebkhouti
be47ac6573 Update invalid link (#3752)
Co-authored-by: AIpills <x9one@pop-os.localdomain>
2023-04-04 14:09:15 +01:00
Arik Chakma
24ce27090e Fix guide type (#3754) 2023-04-04 14:08:50 +01:00
Ehren Nwokocha
8dd0225720 Fix minor typo (#3756)
I replaced and with it in the Javascript versioning paragraph
2023-04-04 14:08:30 +01:00
Kamran Ahmed
9893e9f0a3 Add singlestore links 2023-04-03 22:33:03 +01:00
Kamran Ahmed
caf1cd0269 Minor update 2023-04-03 21:37:13 +01:00
Kamran Ahmed
d21c1f6d0d Add sponsors 2023-04-03 19:15:10 +01:00
Kamran Ahmed
9d38cf7650 Add liblab content 2023-04-03 15:26:15 +01:00
Kamran Ahmed
d232d3bbd0 Update sponsors 2023-04-01 01:37:24 +01:00
Dimension
366d893df9 Fix invalid link (#3734)
Co-authored-by: Hitesh <hitesh.g@smarter.codes>
2023-03-30 18:20:01 +01:00
Kamran Ahmed
ff27561765 Remove unused styles 2023-03-30 18:17:27 +01:00
Kamran Ahmed
133642e05f Add missing content for backend roadmap 2023-03-30 16:34:39 +01:00
Kamran Ahmed
7434ff71eb Run prettier 2023-03-30 01:23:01 +01:00
Arik Chakma
d081ecf5b3 tooling: prettier for astro and tailwind (#3732)
* tooling: prettier for astro and tailwind

Prettier configuration for Astro component's formatting and Tailwind CSS class sorting.

* fix: single quote for props
2023-03-30 01:10:47 +01:00
Kamran Ahmed
d8a039690b Add a button to join on discord 2023-03-28 17:53:48 +01:00
Rahul Saw
56f0df549d Removed a link (#3697)
I think there is no need to use one more link for the exact same example.
The link that I have removed, redirects the user to the old react documentation which is already listed in this md file as "Reusing Logic with Custom Hooks".
2023-03-28 17:07:43 +01:00
Kamran Ahmed
b042161e29 Broken style of code 2023-03-28 17:04:21 +01:00
Kamran Ahmed
db273210fd Fix broken build 2023-03-28 15:47:14 +01:00
Kamran Ahmed
9370e262c0 Add content for mongodb-aggreagtion 2023-03-28 15:35:11 +01:00
Kamran Ahmed
e0f9bc8456 Add mongodb content 2023-03-28 14:05:57 +01:00
Kamran Ahmed
af211ab129 Add related roadmaps 2023-03-27 23:12:06 +01:00
Kamran Ahmed
eab1fb31b2 Fix typo 2023-03-27 21:25:50 +01:00
Kamran Ahmed
c36fd71ec1 Add content for cyber-security roadmap 2023-03-27 21:20:39 +01:00
Kamran Ahmed
7d0e35d7ae Update wireframing tools 2023-03-27 14:40:35 +01:00
Kamran Ahmed
59d881a77b Update ux design roadmap description 2023-03-27 13:43:27 +01:00
Kamran Ahmed
b57e3ecc75 Add content for UX Design Roadmap 2023-03-27 13:26:14 +01:00
Kamran Ahmed
cd5c0c10a2 Add content to UX Design Roadmap 2023-03-27 12:49:19 +01:00
Kamran Ahmed
10a5e4c0ae Add content to UX Design Roadmap 2023-03-27 12:41:38 +01:00
Kamran Ahmed
432983631d Add content to UX Design Roadmap 2023-03-27 12:39:02 +01:00
Kamran Ahmed
29189062b9 Add content to UX Design Roadmap 2023-03-27 06:04:38 +01:00
Kamran Ahmed
84138d5049 Update prompt 2023-03-27 04:38:47 +01:00
Kamran Ahmed
c28ac4b078 Add content writing command 2023-03-27 04:11:34 +01:00
Kamran Ahmed
66bdbd7458 Automate the title creation in new roadmap content 2023-03-27 03:44:54 +01:00
Kamran Ahmed
907f820778 Rename roadmap/best-practice content to dirs 2023-03-27 03:08:19 +01:00
Kamran Ahmed
ec0a8a99ef Add content to UX roadmap 2023-03-27 03:04:34 +01:00
Kamran Ahmed
a7a342c8e7 Add link to UX Design Roadmap 2023-03-26 22:03:50 +01:00
Kamran Ahmed
e0e26580fa Add UX design roadmap pdf 2023-03-26 21:45:49 +01:00
Kamran Ahmed
f9d96d415f Add ux-design roadmap 2023-03-26 21:45:49 +01:00
github-actions[bot]
e1c22932be chore: update dependencies to latest (#3720)
Co-authored-by: kamranahmedse <kamranahmedse@users.noreply.github.com>
2023-03-26 00:14:53 +00:00
Chandresh Patidar
9dae1b3595 Update 114-never.md (#3716)
Replace a deprecated link with new link for `never` type documentation
2023-03-25 15:40:07 +00:00
Kamran Ahmed
cdb642c8d4 Update newsletter 2023-03-25 04:10:40 +00:00
Arik Chakma
71b43af862 fix: upcoming button overlap (#3713)
* docs: new resources for jsx and functional components

* fix: upcoming button overlap
2023-03-24 15:08:17 +00:00
github-actions[bot]
69dccb3fcc chore: update dependencies to latest (#3677)
Co-authored-by: kamranahmedse <kamranahmedse@users.noreply.github.com>
2023-03-21 23:45:15 +00:00
Akshay Jagiasi
ca6ddb4654 How Bitcoin Blockchain actually work video added (#3684)
* How Bitcoin Blockchain actually work video added

* Delete package-lock.json
2023-03-21 23:44:28 +00:00
Ivan Kibala
0ac6fc70ff Fix typo (#3686)
Fix typo
2023-03-21 23:42:54 +00:00
Sandro Fiorio de S. Júnior
5ddb021898 Add content to QA roadmap (#3688)
Co-authored-by: Sandro Fiorio <sandrofioriojr@gmail.com>
2023-03-21 23:42:38 +00:00
Julio Martins
d227603a59 feat: added description and content at FastAPI on Python Roadmap (#3678) 2023-03-20 19:41:49 +00:00
Yerkebulan
e0d70950ac Fix ORM title (#3682)
Update title. Orms to ORMs
2023-03-20 19:39:28 +00:00
Kamran Ahmed
148bfd8736 Add guide on jump servers 2023-03-20 19:37:31 +00:00
Kamran Ahmed
648985cefc Update font and page size for guide page 2023-03-20 18:13:13 +00:00
Kamran Ahmed
9321ac6aa1 Add guide on jump servers 2023-03-20 17:46:22 +00:00
Kamran Ahmed
170ab3a6cf Update git resources 2023-03-20 17:46:22 +00:00
Shreyas Karanam
708fa31998 Fix typo in FAQ (#3658)
Removed multiple AWS listings
2023-03-18 21:41:47 +00:00
Aroyan
f83a1a6c3b Update links to the latest React documentation (#3675)
* feat: add Set JavaScript content

* refactor: update links to the latest react documentation

This commit updates all links that referred to outdated(legacy) React documentation to the latest version
2023-03-18 20:39:05 +00:00
Lane Wagner
dc1d7ef226 Add the complete Docker course by Boot.dev to back-end and devops roadmaps (#3676) 2023-03-18 20:38:12 +00:00
Aroyan
808bd40cce fix: update react docs to new url (#3656)
* feat: add Set JavaScript content

* fix: update react docs and remove beta docs

* update react docs url
2023-03-17 11:15:36 +00:00
Kamran Ahmed
45ce59b10d Add guide for semantic HTML 2023-03-17 02:47:27 +00:00
wagslane
e3f41ec0e3 add updated HTTP networking course 2023-03-16 20:33:55 +00:00
Kamran Ahmed
4f821d0f1d Add PDF and image for MongoDB roadmap 2023-03-16 20:32:14 +00:00
kamranahmedse
ec1283a5dc chore: update sponsors 2023-03-16 20:27:49 +00:00
Kamran Ahmed
4da909d358 Add MongoDB roadmap link 2023-03-16 20:27:19 +00:00
Kamran Ahmed
0beb9ad239 Add MongoDB roadmap 2023-03-16 20:23:47 +00:00
Kamran Ahmed
c6213dde92 Update guides 2023-03-16 18:36:05 +00:00
Kamran Ahmed
3d655965f6 Add event tracking for done/pending 2023-03-16 02:09:26 +00:00
Kamran Ahmed
c5c2ee3b2c Update events 2023-03-16 01:54:41 +00:00
Kamran Ahmed
cad0813eb6 Add event for roadmap switch 2023-03-16 01:05:11 +00:00
Kamran Ahmed
f9c1e6e0a2 Add event tracking for topic load 2023-03-16 00:58:10 +00:00
Kamran Ahmed
d3578756d4 Add event tracking for topic load 2023-03-16 00:53:02 +00:00
Kamran Ahmed
5fe506324a Add article for secrets management 2023-03-15 23:05:33 +00:00
Kamran Ahmed
bc007dcc9b Add article for DevOps language 2023-03-15 23:04:22 +00:00
Arthur Henrique
42a5d5bba6 feat: Include atlassian tutorials in git section (#3557)
Atlassian's Git Tutorials come across the beginning up to advanced tips on git usage, a great place to dive into its understanding
2023-03-14 08:56:02 +00:00
The New Stack
f908c5371d Added TNS K8s Overview Page (#3558) 2023-03-14 08:53:46 +00:00
The New Stack
78964b9f65 Added TNS K8s Primer Article (#3559) 2023-03-14 08:53:25 +00:00
The New Stack
9f11de60ed Added TNS K8s Explainer YouTube Video (#3560) 2023-03-14 08:53:09 +00:00
The New Stack
4ba28b702b Added 2 TNS K8s Alternative Resources (#3561) 2023-03-14 08:52:39 +00:00
The New Stack
45c6fc873f Added TNS K8s Deployment Tutorial (#3562) 2023-03-14 08:52:15 +00:00
The New Stack
23b7c21502 Added TNS Article for Cluster Deployment on Ubuntu (#3564) 2023-03-14 08:52:01 +00:00
The New Stack
d474d07ebb Added 2 TNS Articles on K8s Managed Services (#3563) 2023-03-14 08:47:09 +00:00
The New Stack
7d08572d78 Added 2 TNS Articles Covering K8s Pods (#3565) 2023-03-14 08:46:28 +00:00
The New Stack
17fc85f893 Added TNS Article for K8s Sets (#3566) 2023-03-14 08:45:56 +00:00
github-actions[bot]
5ccba8d7c0 chore: update dependencies to latest (#3576)
Co-authored-by: kamranahmedse <kamranahmedse@users.noreply.github.com>
2023-03-14 08:45:14 +00:00
Alex Ivanovs
fefbb4f833 Updating resources for React Router (#3586)
I'm adding a link to a React Router cheatsheet/reference covering examples of various routes, including core components and routers introduced in v6.4.
2023-03-14 08:42:26 +00:00
The New Stack
bcbc9c9d54 Added TNS Article for Building Stateful K8s Applications (#3587) 2023-03-14 08:40:47 +00:00
The New Stack
73d1d0e389 Added TNS Article About K8s as Universal Schedular (#3588) 2023-03-14 08:40:25 +00:00
The New Stack
14856560c3 Added TNS Article on K8s Ingress for Beginners (#3589) 2023-03-14 08:39:56 +00:00
The New Stack
b097395c07 Added TNS Article on Ingress Controllers for K8s (#3590) 2023-03-14 08:39:29 +00:00
The New Stack
929be729e5 Added TNS Article on K8s Networking (#3591) 2023-03-14 08:39:07 +00:00
The New Stack
1eb8fab15e Added TNS Article on CRD and ConfigMaps (#3592) 2023-03-14 08:38:49 +00:00
The New Stack
51233c8011 Added TNS Article on Secrets Management (#3593) 2023-03-14 08:38:26 +00:00
The New Stack
0081e9059c Added 2 TNS Articles on Resource Types, Requests, Limits (#3594) 2023-03-14 08:38:02 +00:00
The New Stack
4e66148777 Added TNS Article on Namespaces (#3595) 2023-03-14 08:37:48 +00:00
The New Stack
18e430be0b Added TNS Article on Choosing Monitoring Tools (#3596) 2023-03-14 08:37:22 +00:00
The New Stack
e39d0d93e0 Added 5 TNS Articles on K8s Access Control (#3605) 2023-03-14 08:37:05 +00:00
The New Stack
9260dc36b5 Added 3 TNS Articles on K8s Network Security (#3606) 2023-03-14 08:36:16 +00:00
The New Stack
f5f846ed73 Added 2 TNS Articles on Container and Pod Security (#3607) 2023-03-14 08:35:55 +00:00
The New Stack
7518d60013 Added 2 TNS Articles on K8s Security Scanning (#3608) 2023-03-14 08:35:31 +00:00
Kamran Ahmed
59d9674d75 Add guide about SSL certificates 2023-03-13 21:49:49 +00:00
Kota Hayashi
16fb03086e Add riverpod desc (#3599)
* Add riverpod desc

* Update src/data/roadmaps/flutter/content/111-state-management/102-riverpod.md

---------

Co-authored-by: Kamran Ahmed <kamranahmed.se@gmail.com>
2023-03-13 20:37:19 +00:00
Kamran Ahmed
c0f46c5eed Add support for ads on best-practices 2023-03-13 18:04:20 +00:00
Kamran Ahmed
b5b8b92791 Update sponsors workflow 2023-03-13 18:02:15 +00:00
kamranahmedse
8f90dac32e chore: update sponsors 2023-03-13 17:44:48 +00:00
Kamran Ahmed
e9f3a616d1 Add FAQs for DevOps 2023-03-10 01:05:41 +00:00
Kamran Ahmed
c28ed87247 Compress json 2023-03-09 17:07:04 +00:00
Kamran Ahmed
53fb6313db Add link to AWS best practices 2023-03-09 17:05:42 +00:00
Kamran Ahmed
cc933b238d Add best practices for AWS 2023-03-09 16:54:50 +00:00
github-actions[bot]
48fba932b4 chore: update dependencies to latest (#3530)
Co-authored-by: kamranahmedse <kamranahmedse@users.noreply.github.com>
2023-03-06 18:20:40 +00:00
Kamran Ahmed
9961259ffb Fix typo 2023-03-04 23:58:23 +00:00
Kamran Ahmed
cab2054c1d Add related roadmaps to each roadmap page 2023-03-04 23:55:14 +00:00
Kamran Ahmed
d34affb420 Add related roadmaps to each roadmap page 2023-03-04 23:51:40 +00:00
Kamran Ahmed
ee4f0980bc Link to best practices from roadmaps 2023-03-04 18:43:28 +00:00
Kamran Ahmed
37fdd010a8 Add Cyber Security roadmap 2023-03-04 18:28:18 +00:00
Kamran Ahmed
aa04c51a12 Add PDF url 2023-03-04 18:27:35 +00:00
Kamran Ahmed
7993f12d12 Add content for certs and ctfs 2023-03-04 18:27:03 +00:00
Kamran Ahmed
1a3265295c Add directories for content 2023-03-04 18:27:02 +00:00
Kamran Ahmed
238245431b Add cyber-security roadmap 2023-03-04 18:27:02 +00:00
rakibulhaq
48c04055d5 Fix - Typo in 3rd line of migration strategies (#3522)
Solves the issue #3520
2023-03-03 09:00:15 +00:00
Kamran Ahmed
596b8f56ac Update frontend beginner roadmap 2023-03-02 23:34:53 +00:00
Kamran Ahmed
45267693e2 Addevent on switch 2023-03-02 22:13:25 +00:00
Kamran Ahmed
f932df8627 Use query parameters for roadmap switching 2023-03-02 22:05:58 +00:00
Kamran Ahmed
8dcf4b00c4 Refactor frontend roadmap for beginners 2023-03-02 21:58:14 +00:00
Kamran Ahmed
cb32a9610d Add beginner version of frontend roadmap 2023-03-02 19:19:34 +00:00
Kamran Ahmed
01c090f62d Update renderer 2023-03-02 15:41:49 +00:00
Kamran Ahmed
60b1edcab9 Update event labels for sponsor links 2023-03-01 23:04:32 +00:00
Kamran Ahmed
d08887060f Update sponsor workflow title 2023-03-01 02:39:52 +00:00
Kamran Ahmed
24a6c4930e Update sponsors workflow 2023-03-01 02:31:18 +00:00
Kamran Ahmed
e57b889f73 Add script to update sponsors 2023-03-01 02:28:46 +00:00
Kamran Ahmed
c5d14d2543 Update dependencies 2023-03-01 02:22:49 +00:00
Kamran Ahmed
4f0b08ea93 Add sponsor action 2023-03-01 02:19:56 +00:00
github-actions[bot]
47e2dbdd12 chore: update dependencies to latest (#3445)
Co-authored-by: kamranahmedse <kamranahmedse@users.noreply.github.com>
2023-03-01 01:27:31 +00:00
Kamran Ahmed
f1ad70acd9 Update backend, js and python 2023-03-01 00:40:28 +00:00
Kamran Ahmed
ac230bbf29 Add sponsor links on the roadmaps 2023-03-01 00:40:28 +00:00
prchann
d0861711ac Fix a link issue in markdown (#3508) 2023-02-28 19:20:46 +00:00
Amin Rezaei
74b2dda7f7 Fix heading for content file (#3509)
Removed unnecessary heading <code> tag.
2023-02-28 19:17:36 +00:00
Kamran Ahmed
2b49fa3182 Add responsive widgets 2023-02-28 19:16:46 +00:00
Kamran Ahmed
e2a8240e35 Add FVM 2023-02-28 19:12:05 +00:00
Kamran Ahmed
a7f45c0af1 Fix some flutter nodes not clickable 2023-02-28 17:31:39 +00:00
Kamran Ahmed
77a6270bd7 Update flutter roadmap 2023-02-28 17:29:47 +00:00
Kamran Ahmed
64d3ad662c Add riverpod and remove getx 2023-02-28 17:18:41 +00:00
Kamran Ahmed
c8b8e12b64 Add guide for database setup 2023-02-27 10:56:39 +00:00
Tobias Uhmann
8f94a5887e Update 101-jdbc-template.md (#3478)
Clarify in the first sentence that "the JDBC core package" is about Spring
2023-02-25 18:49:54 +00:00
Aroyan
00b6217e63 feat: add urql content (#3483) 2023-02-25 18:49:33 +00:00
João
1a0d7463eb Add Interactive Git Branching Guide by pcottle (#3486)
Github repo of added resource: https://github.com/pcottle/learnGitBranching
2023-02-25 18:49:20 +00:00
Olusola Amoo
983ee44632 fix(blockchain-content): Fix typo in roadmaps > blockchain > security > tools content (#3489) 2023-02-25 18:49:03 +00:00
Olusola Amoo
f393cb186e fix(blockchain-content): fix typo in blockchain solidity content (#3490) 2023-02-25 18:48:45 +00:00
devwithsmf
70edfb0ac2 Adding content to Kubernetes Roadmap (#3477)
* Update 100-kubernetes-overview.md

* Update 101-why-kubernetes.md

* Update 102-key-concepts-terminologies.md

* Update 103-kubernetes-alternatives.md

* Update index.md

* Update 100-installing-a-local-cluster.md

* Update 101-why-kubernetes.md

* Update 102-key-concepts-terminologies.md

* Update 103-kubernetes-alternatives.md

* Update index.md

* Update 100-installing-a-local-cluster.md

* Update 101-choosing-a-managed-provider.md

* Update 102-deploying-your-first-application.md

* Update index.md

* Update 100-pods.md

* Update 101-replicasets.md

* Update 103-statefulsets.md

* Update 103-statefulsets.md

* Update 104-jobs.md

* Update index.md

* Update 100-networking-and-pod-to-pod-communication.md

* Update 101-load-balancing.md

* Update 102-external-access-to-services.md

* Update index.md

* Update 100-config-maps.md

* Update 101-secrets.md

* Update index.md

* Update 100-setting-resource-requests-and-limits.md

* Update 101-assigning-quotas-to-namespaces.md

* Update 102-monitoring-and-optimizing-resource-usage.md

* Update 102-monitoring-and-optimizing-resource-usage.md

* Update index.md

* Update 100-role-based-acccess-control.md

* Update 101-network-security.md

* Update 102-container-and-pod-security.md

* Update 103-security-scanners.md

* Update index.md

* Update 100-logs.md

* Update 101-metrics.md

* Update 102-traces.md

* Update 103-resource-health.md

* Update 104-observability-engines.md

* Update index.md

* Update 100-horizontal-pod-autoscaler.md

* Update 101-vertical-pod-autoscaler.md

* Update 102-cluster-autoscaling.md

* Update index.md

* Update 100-scheduling-basics.md

* Update 101-taints-and-tolerations.md

* Update 102-topology-spread-constraints.md

* Update 103-pod-priorities.md

* Update 104-evictions.md

* Update index.md

* Update 100-csi-drivers.md

* Update 101-stateful-applications.md

* Update index.md

* Update 100-ci-cd-integration.md

* Update 101-gitops.md

* Update 102-helm-charts.md

* Update 103-canary-deployments.md

* Update 104-blue-green-deployments.md

* Update 105-rolling-updates-rollbacks.md

* Update index.md

* Update 100-custom-controllers.md

* Update 101-custom-schedulers-extenders.md

* Update 102-custom-resource-definitions.md

* Update 103-kubernetes-extensions-and-apis.md

* Update 104-own-cluster.md

* Update 105-control-plane-installation.md

* Update 106-managing-worker-nodes.md

* Update 107-multi-cluster-management.md

* Update index.md

* Update index.md
2023-02-25 18:46:21 +00:00
Bernd Hobbie
ed07d34d64 Move 'exclude' option in tsconfig.json out of 'compilerOptions (#3479) 2023-02-25 18:44:43 +00:00
Appasaheb Nage
831521ae10 Update tsconfig (#3496) 2023-02-25 18:44:12 +00:00
Kamran Ahmed
e29289f0dc Add API Security PDF 2023-02-22 09:48:13 +00:00
Kamran Ahmed
0fd3eb0cc6 Add link to API Security Best Practices 2023-02-21 19:41:54 +00:00
Kamran Ahmed
f58a77010b Add content for API security best practices 2023-02-21 19:37:35 +00:00
Kamran Ahmed
6303e31c0e Add content for API security best practices 2023-02-21 19:22:15 +00:00
Kamran Ahmed
dfc2d39427 Add content to API security best practices 2023-02-21 15:48:03 +00:00
Kamran Ahmed
5e75026424 Add content to API security best practices 2023-02-21 15:39:34 +00:00
Kamran Ahmed
7a4c077a90 Add content for API security best practices 2023-02-21 15:16:15 +00:00
Kamran Ahmed
e45c49a404 Fix broken build 2023-02-21 12:44:44 +00:00
Kamran Ahmed
b6a0255f12 Change location for data files 2023-02-21 12:25:58 +00:00
Kamran Ahmed
b741a0e1ee Add support for link-groups 2023-02-20 16:59:02 +00:00
Kamran Ahmed
8200993af4 Update subscription 2023-02-14 14:07:49 +00:00
Kamran Ahmed
5c1d803892 Fix mistake in constructor overloading 2023-02-13 14:19:30 +00:00
Natan Yellin
dcf0f94af9 Update 101-containers.md (#3440) 2023-02-10 21:03:58 +00:00
Artem Gontar
4ad8886aa0 fix: broken link to Circuit Breaker AWS WAF (#3304) 2023-02-10 18:39:44 +00:00
Lucas Soares
a1143cd6cb Add content to Node.js roadmap (#3305) 2023-02-10 18:38:06 +00:00
mohd-e-mustafa
f130c706da Add filtering content (#3355)
* Updated 100-filtering.md added content

* Update content

---------

Co-authored-by: Kamran Ahmed <kamranahmed.se@gmail.com>
2023-02-10 18:31:23 +00:00
mohd-e-mustafa
8068face54 Add rate-limiting content (#3364)
* Update 101-rate-limiting.md

* Update src/roadmaps/angular/content/101-rxjs-basics/104-operators/101-rate-limiting.md

---------

Co-authored-by: Kamran Ahmed <kamranahmed.se@gmail.com>
2023-02-10 18:27:15 +00:00
Benson Arafat
39866117a6 Update Nuxt resources (#3365)
The current version of nuxt is v3.
Update source to v3
2023-02-10 18:25:32 +00:00
mohd-e-mustafa
df7aa17f86 Add content for RxJS transformation (#3369) 2023-02-10 18:22:45 +00:00
payal pagariya
ee6572660b Add resources for data structures (#3374)
Added resources related to stack, queue and recursion all implemented in JavaScript
2023-02-10 18:20:56 +00:00
Jorge Martin
9875a2d6f7 Fix spelling mistake (#3378) 2023-02-10 18:15:45 +00:00
Nikita Monastyrskiy
5b180e2597 Add content to globby (#3432) 2023-02-10 18:10:39 +00:00
Nikita Monastyrskiy
6f05972493 Add content to fs-extra (#3433) 2023-02-10 18:10:15 +00:00
Felipe Riveras
4bd182e4d0 Add MDN resources for hosting (#3436)
this articles explain very good the term and explain with clarity
2023-02-10 18:08:30 +00:00
Israni, Murli
68d319cacb Fix spelling mistake (#3439) 2023-02-10 18:08:00 +00:00
Mohammad Morakabati
3e76df8d2a Add gRPC resources (#3429) 2023-02-10 18:07:37 +00:00
Kamran Ahmed
9d69477947 Fix broken URLs 2023-02-10 17:55:18 +00:00
Kamran Ahmed
e0ead47fb1 Add kubernetes roadmap 2023-02-10 15:49:39 +00:00
Kamran Ahmed
253c88542f Upgrade dependencies 2023-02-10 15:49:39 +00:00
andran777
5bca9834fb Update Spring Boot scope content (#3398) 2023-02-08 17:42:45 +00:00
Jesse Chang
dde6e3d3df Remove beego link (#3403)
* Update 100-beego.md

New official documentation website.

* Update src/roadmaps/golang/content/104-go-web-frameworks/100-beego.md

---------

Co-authored-by: Kamran Ahmed <kamranahmed.se@gmail.com>
2023-02-08 16:12:05 +00:00
Khushi Kothari
6fe8fee25f Add MDN link to Asynchronous JavaScript (#3404)
* Update index.md

* Update src/roadmaps/javascript/content/112-javascript-asynchronous-javascript/index.md

---------

Co-authored-by: Kamran Ahmed <kamranahmed.se@gmail.com>
2023-02-08 16:09:55 +00:00
Hans Elde
f3622a1b1c Fix the availability numbers (#3410)
* Update 102-availability-in-numbers.md

Updated downtime #s using https://uptime.is/

* Update src/roadmaps/system-design/content/105-availability-patterns/102-availability-in-numbers.md

* Update src/roadmaps/system-design/content/105-availability-patterns/102-availability-in-numbers.md

---------

Co-authored-by: Kamran Ahmed <kamranahmed.se@gmail.com>
2023-02-08 16:00:25 +00:00
Muhammad Kamal Fergany
a92bda38f4 Fix a typo in 103-load-balancer.md (#3414) 2023-02-08 15:58:18 +00:00
Kamran Ahmed
b194d167be Make youtube banner non-sticky 2023-02-08 12:29:30 +00:00
Kamran Ahmed
ec04b582a6 Add note for feedback 2023-02-08 12:22:09 +00:00
Kamran Ahmed
f55159a12b Update title for kubernetes page 2023-02-08 11:19:58 +00:00
Kamran Ahmed
938c7796d1 Update title for best practices pages 2023-02-08 11:19:58 +00:00
Paul Reichetanz
e04bd9db05 Fix typos in frontend/123-bonus-content.md (#3423) 2023-02-08 11:00:30 +00:00
Kamran Ahmed
7c837d14da Add link to Kubernetes roadmap 2023-02-07 20:59:11 +00:00
Kamran Ahmed
cc05587d9e Add kubernetes roadmap 2023-02-07 20:49:14 +00:00
Kamran Ahmed
2172014d6e Add dimensions 2023-02-07 20:21:03 +00:00
Kamran Ahmed
98d43e76b7 Add kubernetes roadmap 2023-02-07 20:19:39 +00:00
Kamran Ahmed
7665970813 Add kubecampus snippet 2023-02-06 21:55:55 +00:00
Kamran Ahmed
d96e5890b9 Add content to TypeScript roadmap 2023-02-06 21:26:56 +00:00
Kamran Ahmed
659bd93094 Add content to TypeScript roadmap 2023-02-06 21:26:56 +00:00
syedmouaazfarrukh
a4dddfb19b Adding content to 101-typescript-types 2023-02-06 21:26:56 +00:00
syedmouaazfarrukh
12a4be2227 Adding content to 104-undefined 2023-02-06 21:26:56 +00:00
syedmouaazfarrukh
9edcb35acb Adding content to 115-type-assertions 2023-02-06 21:26:56 +00:00
syedmouaazfarrukh
1df4e4b836 Adding content to 111-utility-types 2023-02-06 21:26:56 +00:00
syedmouaazfarrukh
49e78cf1c0 102-type-inference, 103-type-compatibility, 110-decorators 2023-02-06 21:26:56 +00:00
syedmouaazfarrukh
a4a29b4efa 114-ecosystem 2023-02-06 21:26:56 +00:00
syedmouaazfarrukh
3e49e7f91d 113-modules 2023-02-06 21:26:56 +00:00
syedmouaazfarrukh
7627bc73b5 112-advanced-types 2023-02-06 21:26:56 +00:00
syedmouaazfarrukh
26eaa40dc1 Adding content to 109-generics 2023-02-06 21:26:56 +00:00
syedmouaazfarrukh
45a0b53d5f Adding content to 108-classes 2023-02-06 21:26:56 +00:00
syedmouaazfarrukh
7bac3c3444 Adding content to 107-interfaces 2023-02-06 21:26:56 +00:00
syedmouaazfarrukh
62905bda7a Adding content to 106-functions 2023-02-06 21:26:56 +00:00
syedmouaazfarrukh
179bf366cc Adding content to 104-combining-types 2023-02-06 21:26:56 +00:00
syedmouaazfarrukh
59d47c5b1e Adding content to 100-typescript 2023-02-06 21:26:56 +00:00
syedmouaazfarrukh
d23ea8e577 Adding content to 103-running-typescript 2023-02-06 21:26:56 +00:00
syedmouaazfarrukh
07f001f8be Adding content to 102-install-configure 2023-02-06 21:26:56 +00:00
Kamran Ahmed
754a91acef Fix invalid link 2023-02-06 15:09:55 +00:00
Kamran Ahmed
16c550211b Fix invalid link 2023-02-06 15:08:33 +00:00
Kamran Ahmed
a56710c43d Remove ambassador and tigera links 2023-02-02 00:11:20 +04:00
CodeGuage
00f94e031e Add link to switch in JS Roadmap (#3380) 2023-01-31 20:56:37 +04:00
Tianzhou (天舟)
d1556c85df docs: add PostGIS and Bytebase to the postgresql-dba roadmap. (#3390) 2023-01-31 20:55:55 +04:00
tim-laue
1885d6d304 Fix broken link (#3381)
Fixed broken link
2023-01-31 20:55:13 +04:00
Zanin Andrea
3b8c8316b3 Add HTTPs content (#3384)
I have added a brief explanation of how the HTTPS protocol works and a new resource to learn more
2023-01-31 20:54:30 +04:00
mohd-e-mustafa
034fd16a1f Add combination content in RxJS (#3385) 2023-01-31 20:53:24 +04:00
Diego Kfuri
aa9bf2f263 fix typo in system designs roadmap (#3395) 2023-01-31 20:52:12 +04:00
syedmouaazfarrukh
6a5df98f4f Add content to flutter roadmap (#3389)
* Adding content to 100-dart-basics

* Adding content to 102-setup-development-environment

* Adding content to 102-styled-widgets

* Adding content to 102-widgets

* Adding content to 103-working-with-assets

* Adding content to 105-repo-hosting-services

* Adding content to 106-design-principles

* Adding content to 107-package-manager

* Adding content to 108-working-with-apis

* Adding content to 102-firebase

* Adding content to 109-storage

* Adding content to 114-reactive programming

* Adding content to 115-dev-tools

* Adding content to 116-flutter-internals

* Adding content to 117-ci-cd

* Adding content to 118-analytics

* Adding content to 119-deployment

* Adding content to 110-advanced-dart

* Adding content to 111-state-management

* Adding content to 112-animations

* Adding content to 113-testing

* Adding content to 102-flutter-bloc, 101-flutter-outline

* Update src/roadmaps/flutter/content/100-dart-basics/104-operators.md

* Update src/roadmaps/flutter/content/101-setup-development-environment/101-ides/index.md

---------

Co-authored-by: Kamran Ahmed <kamranahmed.se@gmail.com>
2023-01-31 20:49:28 +04:00
Kamran Ahmed
ea02c8835a Add typescript roadmap reference in frontend roadmap 2023-01-31 14:23:18 +04:00
Kamran Ahmed
e13733a503 Add link to TypeScript roadmap 2023-01-31 04:28:24 +04:00
Kamran Ahmed
6f0ad58764 Add TypeScript roadmap (#3391)
* Add typescript roadmap

* Add typescript content

* Add typescript roadmap
2023-01-31 04:05:46 +04:00
Kamran Ahmed
f68c303ffa Fix canonicals on best-practices topic page 2023-01-31 01:19:54 +04:00
Kamran Ahmed
b2c79ff395 Fix canonicals on topic pages 2023-01-31 01:15:13 +04:00
Kamran Ahmed
ff16ea542f Add content to Frontend Best Practices (#3358)
* Add content to Frontend Best Practices

* Add content to frontend performance best practices
2023-01-26 19:55:36 +04:00
payal pagariya
e3adcdaba4 Add resource for algorithsm (#3360)
Added dynamic programming resource having JavaScript code implementation
2023-01-26 00:58:00 +04:00
Saad Shafiq
6783d7ea44 Fixed a typo in python roadmap note 2023-01-25 15:06:20 +04:00
Kamran Ahmed
f06dfce7fb Add best practices to sitemap 2023-01-25 02:53:34 +04:00
Kamran Ahmed
3df8db5fa5 Compress blockchain roadmap 2023-01-25 02:20:10 +04:00
Krish Chopra
5c92cdedd8 Update - content for rxdart under flutter roadmap (#3352)
* Update 100-rxdart.md

* added links to 100-rxdart.md

* Update src/roadmaps/flutter/content/114-reactive-programming/100-rxdart.md

Co-authored-by: Kamran Ahmed <kamranahmed.se@gmail.com>
2023-01-25 01:58:17 +04:00
Kamran Ahmed
07b6d067c4 Styling for the topic page 2023-01-25 01:55:54 +04:00
Kamran Ahmed
a7f9e7d735 Add pdfs for best practices 2023-01-25 01:55:54 +04:00
Kamran Ahmed
3521525611 Implement the state loading in checklists 2023-01-25 01:55:54 +04:00
Kamran Ahmed
43260ff14f Disable user selection on the rectangles 2023-01-25 01:55:54 +04:00
Kamran Ahmed
102ccc6a6b External links 2023-01-25 01:55:54 +04:00
Kamran Ahmed
415dc2d8e8 Handle mark done/pending functionality in best practices 2023-01-25 01:55:54 +04:00
Kamran Ahmed
e0e6168cfe Remove sorting information from best practices content 2023-01-25 01:55:54 +04:00
Kamran Ahmed
dd7c0ec003 Add forntend performance content 2023-01-25 01:55:54 +04:00
Kamran Ahmed
190c75cebe Toipc pages rendering 2023-01-25 01:55:54 +04:00
Kamran Ahmed
813a3d9b2b Rearrange best practices pages 2023-01-25 01:55:54 +04:00
Kamran Ahmed
c2dda3bc35 Implement best-practice click handling 2023-01-25 01:55:54 +04:00
Kamran Ahmed
4711ab9a6f Handle rendering of the roadmap topics 2023-01-25 01:55:54 +04:00
Kamran Ahmed
5f2836a148 Make topic overlay renderer agnostic 2023-01-25 01:55:54 +04:00
Kamran Ahmed
badb2c029d Refactor the topic loading 2023-01-25 01:55:54 +04:00
Kamran Ahmed
8a24b3e695 Refactor sharer icons 2023-01-25 01:55:54 +04:00
Kamran Ahmed
8b3f8ee6b8 Refactor share icons 2023-01-25 01:55:54 +04:00
Kamran Ahmed
f9db9bee95 Add rendering of best practices 2023-01-25 01:55:54 +04:00
Kamran Ahmed
e8d2bd00c6 Refactor roadmap topic path 2023-01-25 01:55:54 +04:00
Kamran Ahmed
f4e505113c Add rendering for best practices lists 2023-01-25 01:55:54 +04:00
Kamran Ahmed
f675f08d83 Refactor roadmaps 2023-01-25 01:55:54 +04:00
Kamran Ahmed
a12ec64af5 Refactor markdown content 2023-01-25 01:55:54 +04:00
Kamran Ahmed
24512374e8 Update best practices 2023-01-25 01:55:54 +04:00
Kamran Ahmed
359f5d6a4d Add best practices page 2023-01-25 01:55:54 +04:00
Kamran Ahmed
c7302d7484 Rearrange pdfs and images 2023-01-25 01:55:54 +04:00
syedmouaazfarrukh
6ab477df8d Add content to graphql (#3329)
* Adding content to 100-graphql-introduction

* Adding content to 101-graphql-queries

* Adding content to 102-mutations

* Adding content to 103-subscriptions

* Adding content to 108-frontend-implementation

* Adding content to 104-schema

* Adding content to 101-resolvers

* Adding content to 105-execution

* Adding content to 109-backend-implementations

* Adding content to 100-graphql-over-http

* Adding content to 101-graphql-over-websockets

* Adding content to 102-graphql-over-sse

* Adding content to 106-serving-over-internet

* Adding content to 104-validation, 107-pagination

* Adding content to graphql
2023-01-25 01:52:56 +04:00
Kamran Ahmed
961d00e70e Add system design roadmap link 2023-01-23 17:42:19 +04:00
syedmouaazfarrukh
c1a53cf3cc Add content to software-design-architecture (#3343)
* Adding content to 100-clean-code-principles

* Adding content to 101-programming-paradigms

* Adding content to 103-software-design-principles

* Adding content to 104-design-patterns

* Adding content to 105-architectural-principles

* Adding content to 100-primary-principles

* Adding content to 101-paradigm-features

* Adding content to 102-object-oriented-programming

* Adding content to 106-architectural-styles

* Adding content to 107-architectural-patterns

* Adding content to 108-enterprise-patterns

* Adding content to 108-enterprise-patterns

* Update src/roadmaps/software-design-architecture/content/100-clean-code-principles/101-be-consistent.md

* Update src/roadmaps/software-design-architecture/content/100-clean-code-principles/102-meaningful-names.md

* Update src/roadmaps/software-design-architecture/content/100-clean-code-principles/103-indentation-and-code-style.md

* Update src/roadmaps/software-design-architecture/content/100-clean-code-principles/104-keep-it-small.md

* Update src/roadmaps/software-design-architecture/content/100-clean-code-principles/105-pure-functions.md

* Update src/roadmaps/software-design-architecture/content/102-object-oriented-programming/101-paradigm-features/102-scope-visibility.md

* Update src/roadmaps/software-design-architecture/content/102-object-oriented-programming/101-paradigm-features/index.md

* Update src/roadmaps/software-design-architecture/content/102-object-oriented-programming/102-model-driven-design/100-domain-models.md

* Update src/roadmaps/software-design-architecture/content/103-software-design-principles/104-solid.md

* Update src/roadmaps/software-design-architecture/content/104-design-patterns/100-gof-design-patterns.md

* Update src/roadmaps/software-design-architecture/content/100-clean-code-principles/109-use-correct-constructs.md

* Update src/roadmaps/software-design-architecture/content/100-clean-code-principles/110-keep-tests-independent.md

* Update src/roadmaps/software-design-architecture/content/100-clean-code-principles/110-keep-tests-independent.md

* Update src/roadmaps/software-design-architecture/content/100-clean-code-principles/110-keep-tests-independent.md

* Update src/roadmaps/software-design-architecture/content/100-clean-code-principles/111-use-meaningful-names.md

* Update src/roadmaps/software-design-architecture/content/100-clean-code-principles/114-avoid-hasty-abstractions.md

* Update src/roadmaps/software-design-architecture/content/100-clean-code-principles/114-avoid-hasty-abstractions.md

* Update src/roadmaps/software-design-architecture/content/100-clean-code-principles/index.md

* Update src/roadmaps/software-design-architecture/content/102-object-oriented-programming/101-paradigm-features/101-concrete-classes.md

Co-authored-by: Kamran Ahmed <kamranahmed.se@gmail.com>
2023-01-23 03:29:01 +04:00
github-actions[bot]
1f485c21f7 chore: update dependencies to latest (#3344)
Co-authored-by: kamranahmedse <kamranahmedse@users.noreply.github.com>
2023-01-23 02:48:35 +04:00
Amrou Bellalouna
e886d0bacb Fix typo in "avaiability" (#3346) 2023-01-23 02:47:26 +04:00
Kamran Ahmed
8a07f2f685 Add slack integration for aws-costs 2023-01-22 18:28:00 +04:00
Kamran Ahmed
19ad916334 Update action file 2023-01-22 17:11:50 +04:00
Kamran Ahmed
b30016b6f4 Add github action 2023-01-22 17:09:29 +04:00
Kamran Ahmed
57395f769a Make software design and architecture roadmap interacxtive 2023-01-21 18:11:51 +04:00
Kamran Ahmed
b91c11b273 Fix broken links 2023-01-21 03:50:39 +04:00
Kamran Ahmed
c026f9c928 Fix broken links 2023-01-21 01:10:57 +04:00
Kamran Ahmed
aee51ee43e Handle legacy roadmap urls 2023-01-20 21:13:38 +04:00
Kamran Ahmed
3b12130579 Handle legacy roadmap urls 2023-01-20 20:57:58 +04:00
Kamran Ahmed
3dd9429338 Handle legacy roadmap urls 2023-01-20 20:48:14 +04:00
Kamran Ahmed
0af54cd906 Fix broken URLs 2023-01-20 20:33:31 +04:00
Kamran Ahmed
750e6e5a36 Remove trailing slashes from the roadmap pages 2023-01-20 20:13:19 +04:00
Kamran Ahmed
5b93bc42db Remove trailing slashes from the website URLs 2023-01-20 20:10:21 +04:00
Kamran Ahmed
8b32a3a831 Rename featured roadmap item 2023-01-20 17:03:52 +04:00
Kamran Ahmed
a28204c908 Remove lastmod from sitemap 2023-01-20 16:47:58 +04:00
Benson Arafat
4aca07e3d4 Update Broken Link (#3308)
Update Callback broken link
2023-01-20 00:27:03 +04:00
Kamran Ahmed
5c2562dadb Add content to cloud design patterns 2023-01-19 22:10:12 +04:00
Kamran Ahmed
e934dc60f4 Add content for reliability patterns 2023-01-19 20:50:14 +04:00
Kamran Ahmed
ad4f35764d Add content to cloud design patterns 2023-01-19 20:46:19 +04:00
Kamran Ahmed
a715a85b46 Add disclaimer above cloud design patterns 2023-01-19 20:26:24 +04:00
Kamran Ahmed
f16a207e7c Add content for monitoring 2023-01-19 20:02:21 +04:00
Kamran Ahmed
6582d65935 Add content for performance antipatterns 2023-01-19 19:48:02 +04:00
Kamran Ahmed
ab36350cdc Add communication protocols 2023-01-19 19:25:22 +04:00
Kamran Ahmed
3b05a615d8 Add content to asynchronism 2023-01-19 19:04:58 +04:00
Kamran Ahmed
9a2bc75646 Add caching strategies 2023-01-19 18:54:30 +04:00
Kamran Ahmed
d283ce7c67 Add right click to mark as done/pending 2023-01-19 18:35:08 +04:00
Kamran Ahmed
59ed243fa7 Add content to system design roadmap 2023-01-19 17:58:10 +04:00
Kamran Ahmed
ca35551e4f Add content for consistency and background jobs 2023-01-19 17:16:26 +04:00
Kamran Ahmed
cab06b46da Add content to system design roadmap 2023-01-19 16:45:34 +04:00
Kamran Ahmed
f5e980d8ec Add functionality to add note to the roadmaps 2023-01-19 15:05:25 +04:00
Kamran Ahmed
6187b1dc52 Update isNew tags 2023-01-19 14:16:03 +04:00
syedmouaazfarrukh
a3b8b5653a Add content to system-design (#3323) 2023-01-19 14:10:10 +04:00
Kamran Ahmed
8f8e2f41d8 Rearrange JSON files 2023-01-18 19:47:47 +04:00
Kamran Ahmed
89a436a5b7 Add content for making API calls using http moduel 2023-01-18 17:00:04 +04:00
Zied Chekir
231e295f01 Add resource links to blockchain roadmap (#3317)
I would suggest those articles since it is an advanced subject. the first one explains the math behind zk-rollups and the second one is Vitalik ( Founder of Ethereum) explaining how snarks work.
2023-01-18 16:56:03 +04:00
Kamran Ahmed
64e20e9fc1 Add links to roadmaps from FAQs on the frontend roadmap 2023-01-18 16:19:21 +04:00
Kamran Ahmed
621f841fbf Add a guide about consistency patterns 2023-01-18 02:46:59 +04:00
Kamran Ahmed
c61afb15bc Add content in consistency patterns 2023-01-18 02:35:24 +04:00
RaifAR
595f3680be fix: typo in the word development (#3320)
Co-authored-by: Raif Abdul Razak <raif@Raifs-MacBook-Air.local>
2023-01-17 22:57:02 +04:00
Kamran Ahmed
ee65c56bf3 Add content to availability vs consistency 2023-01-17 20:25:06 +04:00
Kamran Ahmed
a2c339f2d5 Add system design roadmap content 2023-01-17 18:49:53 +04:00
Kamran Ahmed
a3031a2371 Add system design roadmap 2023-01-17 18:06:43 +04:00
Kamran Ahmed
952169ec8e Add AWS guide link 2023-01-16 19:53:25 +04:00
Kamran Ahmed
fbd82ce215 Remove pluralsight links 2023-01-15 15:37:16 +04:00
Kamran Ahmed
35f61e876e Fix broken URL 2023-01-15 15:36:19 +04:00
syedmouaazfarrukh
bb9878fdb7 Add content to aspnet-core roadmap (#3294)
* Initial commit

* Initial commit

* Initial commit

* Initial commit

* Initial commit

* Initial commit

* Initial commit

* Initial commit

* Initital commit

* Initial commit

* Initial commit

* Committing 107-databases

* Content added in aspnet-core/content/108-log-frameworks

* Content added in aspnet-core/content/109-api-clients

* Content added in aspnet-core/content/110-real-time-communication

* Content added in aspnet-core/content/111-object-mapping

* Content added in aspnet-core/content/112-task-scheduling

* Fix Eager Loading heading

* Fix lazy loading heading

* Update src/roadmaps/aspnet-core/content/104-orm/103-nhibernate.md

* Update src/roadmaps/aspnet-core/content/100-basics-of-csharp/101-dotnet.md

* Update src/roadmaps/aspnet-core/content/103-basics-of-aspnet-core/101-rest.md

* Update src/roadmaps/aspnet-core/content/109-api-clients/102-graphql/100-graphql-dotnet.md

* Update src/roadmaps/aspnet-core/content/103-basics-of-aspnet-core/index.md

* Update src/roadmaps/aspnet-core/content/104-orm/100-entity-framework-core/102-change-tracker-api.md

* Update src/roadmaps/aspnet-core/content/104-orm/102-repodb.md

* Update src/roadmaps/aspnet-core/content/104-orm/102-repodb.md

* Update src/roadmaps/aspnet-core/content/105-dependency-injection/102-life-cycles/index.md

* Update src/roadmaps/aspnet-core/content/105-dependency-injection/index.md

* Update src/roadmaps/aspnet-core/content/109-api-clients/102-graphql/100-graphql-dotnet.md

* Update src/roadmaps/aspnet-core/content/109-api-clients/102-graphql/index.md

* Update src/roadmaps/aspnet-core/content/110-real-time-communication/101-singlar-core.md

* Update src/roadmaps/aspnet-core/content/111-object-mapping/100-atuo-mapper.md

* Update src/roadmaps/aspnet-core/content/107-databases/100-search-engines/100-elasticsearch.md

* Update src/roadmaps/aspnet-core/content/107-databases/102-relational/101-postgresql.md

* Update src/roadmaps/aspnet-core/content/107-databases/102-relational/103-mysql.md

* Update src/roadmaps/aspnet-core/content/107-databases/103-nosql/101-mongodb.md

* Update src/roadmaps/aspnet-core/content/108-log-frameworks/101-nlog.md

* Update src/roadmaps/aspnet-core/content/108-log-frameworks/100-serilog.md

* Update src/roadmaps/aspnet-core/content/108-log-frameworks/102-log-management-system/100-elk-stack.md

* Update src/roadmaps/aspnet-core/content/108-log-frameworks/102-log-management-system/104-elmah.md

* Update src/roadmaps/aspnet-core/content/108-log-frameworks/index.md

* Update src/roadmaps/aspnet-core/content/109-api-clients/100-rest/101-odata.md

* Update src/roadmaps/aspnet-core/content/109-api-clients/100-rest/index.md

* Update src/roadmaps/aspnet-core/content/109-api-clients/102-graphql/100-graphql-dotnet.md

* Update src/roadmaps/aspnet-core/content/109-api-clients/101-grpc.md

* Adding content to 115-ci-cd

* Adding content to 116-client-side-libraries

* Adding content to 117-template-engines

* Adding content to 118-good-to-know-libraries

* Adding content to 113-testing

* Adding content to 114-microservices

Co-authored-by: Kamran Ahmed <kamranahmed.se@gmail.com>
2023-01-15 15:35:54 +04:00
Kamran Ahmed
ee843cc9e2 Add tests for roadmaps, guides and videos 2023-01-15 15:26:58 +04:00
Kamran Ahmed
cbd79ef299 Add tests for roadmap pages and homepage 2023-01-15 15:23:27 +04:00
Kamran Ahmed
af9e266190 Update dependencies 2023-01-15 15:01:34 +04:00
Kamran Ahmed
0cbd401071 Remove critters 2023-01-15 14:32:37 +04:00
kamranahmedse
0929d40bd0 chore: update dependencies to latest 2023-01-15 14:32:12 +04:00
Kamran Ahmed
927aa0a066 Update twitter URL 2023-01-14 18:14:01 +04:00
Kamran Ahmed
85eff7f894 Fix invalid faq schema 2023-01-14 12:11:16 +04:00
Kamran Ahmed
11695f4b05 Add json-ld schema to all roadmaps 2023-01-14 01:20:57 +04:00
Kamran Ahmed
aebee9b3a3 Add json-ld schema to the backend roadmap and refactor 2023-01-14 00:58:45 +04:00
Kamran Ahmed
6b52baf093 Add json-ld schema to the roadmap pages 2023-01-14 00:32:14 +04:00
Kamran Ahmed
6922fd826f Remove prism file 2023-01-13 15:48:26 +04:00
Kamran Ahmed
ec29e1836e Update configuration for colors 2023-01-13 14:49:59 +04:00
Kamran Ahmed
dca9eb32cd Remove prism file 2023-01-13 14:45:44 +04:00
Kamran Ahmed
4b681c6317 Add json-ld schema to frontend/backend roadmaps 2023-01-13 12:37:45 +04:00
Kamran Ahmed
9c24ff23e3 Guide code not showing proper bg 2023-01-12 19:12:26 +04:00
Kamran Ahmed
cdc87a99e1 Add ambassador eBook link 2023-01-12 18:48:11 +04:00
Kamran Ahmed
ea16e99598 Add ambassador eBook link 2023-01-12 18:46:49 +04:00
Kamran Ahmed
ba86e8a6b1 Update content headings 2023-01-12 14:41:54 +04:00
syedmouaazfarrukh
5f23d4c7eb Add content to Spring Boot roadmap (#3285)
* Initial commit

* Update content files

Co-authored-by: Kamran Ahmed <kamranahmed.se@gmail.com>
2023-01-12 14:38:50 +04:00
5099 changed files with 102079 additions and 12425 deletions

2
.env.example Normal file
View File

@@ -0,0 +1,2 @@
PUBLIC_API_URL=http://api.roadmap.sh
PUBLIC_AVATAR_BASE_URL=https://dodrc8eu8m09s.cloudfront.net/avatars

21
.github/workflows/aws-costs.yml vendored Normal file
View File

@@ -0,0 +1,21 @@
name: Sends Daily AWS Costs to Slack
on:
# Allow manual Run
workflow_dispatch:
# Run at 7:00 UTC every day
schedule:
- cron: "0 7 * * *"
jobs:
aws_costs:
runs-on: ubuntu-latest
steps:
- name: Get Costs
env:
AWS_KEY: ${{ secrets.COST_AWS_ACCESS_KEY }}
AWS_SECRET: ${{ secrets.COST_AWS_SECRET_KEY }}
AWS_REGION: ${{ secrets.COST_AWS_REGION }}
SLACK_CHANNEL: ${{ secrets.SLACK_COST_CHANNEL }}
SLACK_TOKEN: ${{ secrets.SLACK_TOKEN }}
run: |
npm install -g aws-cost-cli
aws-cost -k $AWS_KEY -s $AWS_SECRET -r $AWS_REGION -S $SLACK_TOKEN -C $SLACK_CHANNEL

View File

@@ -3,6 +3,8 @@ on:
push:
branches: [ master ]
env:
PUBLIC_API_URL: "https://api.roadmap.sh"
PUBLIC_AVATAR_BASE_URL: "https://dodrc8eu8m09s.cloudfront.net/avatars"
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PAT: ${{ secrets.PAT }}
CI: true

9
.gitignore vendored
View File

@@ -1,3 +1,5 @@
.idea
# build output
dist/
.output/
@@ -5,7 +7,7 @@ dist/
# dependencies
node_modules/
bin/developer-roadmap
scripts/developer-roadmap
# logs
npm-debug.log*
@@ -20,3 +22,8 @@ pnpm-debug.log*
# macOS-specific files
.DS_Store
/test-results/
/playwright-report/
/playwright/.cache/
tests-examples
*.csv

7
.prettierignore Normal file
View File

@@ -0,0 +1,7 @@
app-dist
dist
.idea
.github
public
node_modules
pnpm-lock.yaml

18
.prettierrc.cjs Normal file
View File

@@ -0,0 +1,18 @@
module.exports = {
semi: true,
singleQuote: true,
overrides: [
{
files: '*.astro',
options: {
parser: 'astro',
singleQuote: true,
jsxSingleQuote: true,
},
},
],
plugins: [
require.resolve('prettier-plugin-astro'),
require('prettier-plugin-tailwindcss'),
],
};

6
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,6 @@
{
"prettier.documentSelectors": ["**/*.astro"],
"[astro]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}

View File

@@ -1,24 +1,67 @@
// https://astro.build/config
import preact from '@astrojs/preact';
import sitemap from '@astrojs/sitemap';
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
export default defineConfig({
site: 'https://roadmap.sh',
site: 'https://roadmap.sh/',
markdown: {
shikiConfig: {
theme: 'dracula',
},
rehypePlugins: [
[
rehypeExternalLinks,
{
target: '_blank',
rel: function (element) {
const href = element.properties.href;
const whiteListedStarts = [
'/',
'#',
'mailto:',
'https://github.com/kamranahmedse',
'https://thenewstack.io',
'https://cs.fyi',
'https://roadmap.sh',
];
if (whiteListedStarts.some((start) => href.startsWith(start))) {
return [];
}
return 'noopener noreferrer nofollow';
},
},
],
],
},
build: {
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,
@@ -32,5 +75,6 @@ export default defineConfig({
css: false,
js: false,
}),
preact(),
],
});

View File

@@ -1,14 +0,0 @@
const fs = require('node:fs');
const path = require('node:path');
const jsonsDir = path.join(process.cwd(), 'public/jsons');
const jsonFiles = fs.readdirSync(jsonsDir);
jsonFiles.forEach((jsonFileName) => {
console.log(`Compressing ${jsonFileName}...`);
const jsonFilePath = path.join(jsonsDir, jsonFileName);
const json = require(jsonFilePath);
fs.writeFileSync(jsonFilePath, JSON.stringify(json));
});

View File

@@ -1,163 +0,0 @@
const fs = require('fs');
const path = require('path');
const CONTENT_DIR = path.join(__dirname, '../content');
// Directory containing the roadmaps
const ROADMAP_CONTENT_DIR = path.join(__dirname, '../src/roadmaps');
const roadmapId = process.argv[2];
const allowedRoadmapIds = fs.readdirSync(ROADMAP_CONTENT_DIR);
if (!roadmapId) {
console.error('roadmapId is required');
process.exit(1);
}
if (!allowedRoadmapIds.includes(roadmapId)) {
console.error(`Invalid roadmap key ${roadmapId}`);
console.error(`Allowed keys are ${allowedRoadmapIds.join(', ')}`);
process.exit(1);
}
// Directory holding the roadmap content files
const roadmapDirName = fs
.readdirSync(ROADMAP_CONTENT_DIR)
.find((dirName) => dirName.replace(/\d+-/, '') === roadmapId);
if (!roadmapDirName) {
console.error('Roadmap directory not found');
process.exit(1);
}
const roadmapDirPath = path.join(ROADMAP_CONTENT_DIR, roadmapDirName);
const roadmapContentDirPath = path.join(
ROADMAP_CONTENT_DIR,
roadmapDirName,
'content'
);
// If roadmap content already exists do not proceed as it would override the files
if (fs.existsSync(roadmapContentDirPath)) {
console.error(`Roadmap content already exists @ ${roadmapContentDirPath}`);
process.exit(1);
}
function prepareDirTree(control, dirTree, dirSortOrders) {
// Directories are only created for groups
if (control.typeID !== '__group__') {
return;
}
// e.g. 104-testing-your-apps:other-options
const controlName = control?.properties?.controlName || '';
// e.g. 104
const sortOrder = controlName.match(/^\d+/)?.[0];
// No directory for a group without control name
if (!controlName || !sortOrder) {
return;
}
// e.g. testing-your-apps:other-options
const controlNameWithoutSortOrder = controlName.replace(/^\d+-/, '');
// e.g. ['testing-your-apps', 'other-options']
const dirParts = controlNameWithoutSortOrder.split(':');
// Nest the dir path in the dirTree
let currDirTree = dirTree;
dirParts.forEach((dirPart) => {
currDirTree[dirPart] = currDirTree[dirPart] || {};
currDirTree = currDirTree[dirPart];
});
dirSortOrders[controlNameWithoutSortOrder] = Number(sortOrder);
const childrenControls = control.children.controls.control;
// No more children
if (childrenControls.length) {
childrenControls.forEach((childControl) => {
prepareDirTree(childControl, dirTree, dirSortOrders);
});
}
return { dirTree, dirSortOrders };
}
const roadmap = require(path.join(__dirname, `../public/jsons/${roadmapId}`));
const controls = roadmap.mockup.controls.control;
// Prepare the dir tree that we will be creating and also calculate the sort orders
const dirTree = {};
const dirSortOrders = {};
controls.forEach((control) => {
prepareDirTree(control, dirTree, dirSortOrders);
});
/**
* @param parentDir Parent directory in which directory is to be created
* @param dirTree Nested dir tree to be created
* @param sortOrders Mapping from groupName to sort order
* @param filePaths The mapping from groupName to file path
*/
function createDirTree(parentDir, dirTree, sortOrders, filePaths = {}) {
const childrenDirNames = Object.keys(dirTree);
const hasChildren = childrenDirNames.length !== 0;
// @todo write test for this, yolo for now
const groupName = parentDir
.replace(roadmapContentDirPath, '') // Remove base dir path
.replace(/(^\/)|(\/$)/g, '') // Remove trailing slashes
.replace(/(^\d+?-)/g, '') // Remove sorting information
.replaceAll('/', ':') // Replace slashes with `:`
.replace(/:\d+-/, ':');
const humanizedGroupName = groupName
.split(':')
.pop()
?.replaceAll('-', ' ')
.replace(/^\w/, ($0) => $0.toUpperCase());
const sortOrder = sortOrders[groupName] || '';
// Attach sorting information to dirname
// e.g. /roadmaps/100-frontend/content/internet
// ———> /roadmaps/100-frontend/content/103-internet
if (sortOrder) {
parentDir = parentDir.replace(/(.+?)([^\/]+)?$/, `$1${sortOrder}-$2`);
}
// If no children, create a file for this under the parent directory
if (!hasChildren) {
let fileName = `${parentDir}.md`;
fs.writeFileSync(fileName, `# ${humanizedGroupName}`);
filePaths[groupName || 'home'] = fileName.replace(CONTENT_DIR, '');
return filePaths;
}
// There *are* children, so create the parent as a directory
// and create `index.md` as the content file for this
fs.mkdirSync(parentDir);
let readmeFilePath = path.join(parentDir, 'index.md');
fs.writeFileSync(readmeFilePath, `# ${humanizedGroupName}`);
filePaths[groupName || 'home'] = readmeFilePath.replace(CONTENT_DIR, '');
// For each of the directory names, create a
// directory inside the given directory
childrenDirNames.forEach((dirName) => {
createDirTree(
path.join(parentDir, dirName),
dirTree[dirName],
dirSortOrders,
filePaths
);
});
return filePaths;
}
// Create directories and get back the paths for created directories
createDirTree(roadmapContentDirPath, dirTree, dirSortOrders);
console.log('Created roadmap content directory structure');

View File

@@ -14,21 +14,21 @@ appearance, race, religion, or sexual identity and orientation.
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
- The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
- Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities

View File

@@ -3,10 +3,10 @@
First of all thank you for considering to contribute. Please look at the details below:
- [Contribution](#contribution)
- [New Roadmaps](#new-roadmaps)
- [Existing Roadmaps](#existing-roadmaps)
- [Adding Content](#adding-content)
- [Guidelines](#guidelines)
- [New Roadmaps](#new-roadmaps)
- [Existing Roadmaps](#existing-roadmaps)
- [Adding Content](#adding-content)
- [Guidelines](#guidelines)
## New Roadmaps
@@ -23,7 +23,7 @@ For the existing roadmaps, please follow the details listed for the nature of co
## Adding Content
Find [the content directory inside the relevant roadmap](https://github.com/kamranahmedse/roadmap-astro/tree/master/src/roadmaps). Please keep the following guidelines in mind when submitting content:
Find [the content directory inside the relevant roadmap](https://github.com/kamranahmedse/developer-roadmap/tree/master/src/data/roadmaps). Please keep the following guidelines in mind when submitting content:
- Content must be in English.
- Put a brief description about the topic on top of the file and the a list of links below with each link having title of the URL.

View File

@@ -8,30 +8,47 @@
"start": "astro dev",
"build": "astro build",
"preview": "astro preview",
"format": "prettier --write .",
"astro": "astro",
"deploy": "NODE_DEBUG=gh-pages gh-pages -d dist -t",
"compress:jsons": "node bin/compress-jsons.cjs",
"compress:jsons": "node scripts/compress-jsons.cjs",
"upgrade": "ncu -u",
"roadmap-links": "node bin/roadmap-links.cjs",
"roadmap-content": "node bin/roadmap-content.cjs"
"roadmap-links": "node scripts/roadmap-links.cjs",
"roadmap-dirs": "node scripts/roadmap-dirs.cjs",
"roadmap-content": "node scripts/roadmap-content.cjs",
"best-practice-dirs": "node scripts/best-practice-dirs.cjs",
"best-practice-content": "node scripts/best-practice-content.cjs",
"test:e2e": "playwright test"
},
"dependencies": {
"@astrojs/sitemap": "^1.0.0",
"@astrojs/tailwind": "^2.1.3",
"astro": "^1.8.0",
"astro-compress": "^1.1.24",
"astro-critters": "^1.1.24",
"node-html-parser": "^6.1.4",
"npm-check-updates": "^16.6.2",
"rehype-external-links": "^2.0.1",
"roadmap-renderer": "^1.0.1",
"tailwindcss": "^3.2.4"
"@astrojs/preact": "^2.2.1",
"@astrojs/sitemap": "^1.3.3",
"@astrojs/tailwind": "^3.1.3",
"@fingerprintjs/fingerprintjs": "^3.4.1",
"@nanostores/preact": "^0.5.0",
"astro": "^2.6.3",
"astro-compress": "^1.1.47",
"jose": "^4.14.4",
"js-cookie": "^3.0.5",
"nanostores": "^0.9.1",
"node-html-parser": "^6.1.5",
"npm-check-updates": "^16.10.12",
"preact": "^10.15.1",
"rehype-external-links": "^2.1.0",
"roadmap-renderer": "^1.0.6",
"tailwindcss": "^3.3.2"
},
"devDependencies": {
"@tailwindcss/typography": "^0.5.8",
"gh-pages": "^4.0.0",
"json-to-pretty-yaml": "^1.2.2",
"prettier": "^2.8.1",
"prettier-plugin-astro": "^0.7.0"
"@playwright/test": "^1.35.0",
"@tailwindcss/typography": "^0.5.9",
"@types/js-cookie": "^3.0.3",
"csv-parser": "^3.0.0",
"gh-pages": "^5.0.0",
"js-yaml": "^4.1.0",
"markdown-it": "^13.0.1",
"openai": "^3.2.1",
"prettier": "^2.8.8",
"prettier-plugin-astro": "^0.10.0",
"prettier-plugin-tailwindcss": "^0.3.0"
}
}

108
playwright.config.ts Normal file
View File

@@ -0,0 +1,108 @@
import type { PlaywrightTestConfig } from '@playwright/test';
import { devices } from '@playwright/test';
/**
* Read environment variables from file.
* https://github.com/motdotla/dotenv
*/
// require('dotenv').config();
/**
* See https://playwright.dev/docs/test-configuration.
*/
const config: PlaywrightTestConfig = {
testDir: './tests',
/* Maximum time one test can run for. */
timeout: 30 * 1000,
expect: {
/**
* Maximum time expect() should wait for the condition to be met.
* For example in `await expect(locator).toHaveText();`
*/
timeout: 5000,
},
/* Run tests in files in parallel */
fullyParallel: true,
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
/* Retry on CI only */
retries: process.env.CI ? 2 : 0,
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: 'html',
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
actionTimeout: 0,
/* Base URL to use in actions like `await page.goto('/')`. */
baseURL: 'http://localhost:3000',
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: 'on-first-retry',
},
/* Configure projects for major browsers */
projects: [
{
name: 'chromium',
use: {
...devices['Desktop Chrome'],
},
},
// {
// name: 'firefox',
// use: {
// ...devices['Desktop Firefox'],
// },
// },
// {
// name: 'webkit',
// use: {
// ...devices['Desktop Safari'],
// },
// },
/* Test against mobile viewports. */
// {
// name: 'Mobile Chrome',
// use: {
// ...devices['Pixel 5'],
// },
// },
// {
// name: 'Mobile Safari',
// use: {
// ...devices['iPhone 12'],
// },
// },
/* Test against branded browsers. */
// {
// name: 'Microsoft Edge',
// use: {
// channel: 'msedge',
// },
// },
// {
// name: 'Google Chrome',
// use: {
// channel: 'chrome',
// },
// },
],
/* Folder for test artifacts such as screenshots, videos, traces, etc. */
// outputDir: 'test-results/',
/* Run your local dev server before starting the tests */
webServer: {
command: 'npm run dev',
url: 'http://localhost:3000',
reuseExistingServer: !process.env.CI,
},
};
export default config;

3888
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 505 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 469 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 KiB

View File

@@ -1,13 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 36 36">
<path fill="#000" d="M22.25 4h-8.5a1 1 0 0 0-.96.73l-5.54 19.4a.5.5 0 0 0 .62.62l5.05-1.44a2 2 0 0 0 1.38-1.4l3.22-11.66a.5.5 0 0 1 .96 0l3.22 11.67a2 2 0 0 0 1.38 1.39l5.05 1.44a.5.5 0 0 0 .62-.62l-5.54-19.4a1 1 0 0 0-.96-.73Z"/>
<path fill="url(#gradient)" d="M18 28a7.63 7.63 0 0 1-5-2c-1.4 2.1-.35 4.35.6 5.55.14.17.41.07.47-.15.44-1.8 2.93-1.22 2.93.6 0 2.28.87 3.4 1.72 3.81.34.16.59-.2.49-.56-.31-1.05-.29-2.46 1.29-3.25 3-1.5 3.17-4.83 2.5-6-.67.67-2.6 2-5 2Z"/>
<defs>
<linearGradient id="gradient" x1="16" x2="16" y1="32" y2="24" gradientUnits="userSpaceOnUse">
<stop stop-color="#000"/>
<stop offset="1" stop-color="#000" stop-opacity="0"/>
</linearGradient>
</defs>
<style>
@media (prefers-color-scheme:dark){:root{filter:invert(100%)}}
</style>
</svg>

Before

Width:  |  Height:  |  Size: 873 B

BIN
public/guides/llms.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 691 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 832 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
public/roadmaps/cpp.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 773 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

BIN
public/roadmaps/docker.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 542 KiB

BIN
public/roadmaps/mongodb.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 544 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 KiB

View File

@@ -4,16 +4,16 @@
<p align="center">Community driven roadmaps, articles and resources for developers<p>
<p align="center">
<a href="https://roadmap.sh/roadmaps">
<img src="https://img.shields.io/badge/-Roadmaps%20-0a0a0a.svg?style=flat&colorA=0a0a0a" alt="roadmaps" />
<img src="https://img.shields.io/badge/%E2%9C%A8-Roadmaps%20-0a0a0a.svg?style=flat&colorA=0a0a0a" alt="roadmaps" />
</a>
<a href="https://roadmap.sh/best-practices">
<img src="https://img.shields.io/badge/%E2%9C%A8-Best%20Practices-0a0a0a.svg?style=flat&colorA=0a0a0a" alt="best practices" />
</a>
<a href="https://youtube.com/theroadmap?sub_confirmation=1">
<img src="https://img.shields.io/badge/-Videos-0a0a0a.svg?style=flat&colorA=0a0a0a" alt="videos" />
</a>
<a href="https://github.com/kamranahmedse/developer-roadmap/tree/0471d44c8fae58b6a36a7c57bba12253916d0249/translations">
<img src="https://img.shields.io/badge/-Translations-0a0a0a.svg?style=flat&colorA=0a0a0a" alt="videos" />
<img src="https://img.shields.io/badge/%E2%9C%A8-Videos-0a0a0a.svg?style=flat&colorA=0a0a0a" alt="videos" />
</a>
<a href="https://www.youtube.com/channel/UCA0H2KIWgWTwpTFjSxp0now?sub_confirmation=1">
<img src="https://img.shields.io/badge/%E2%9D%A4-YouTube%20Channel-0a0a0a.svg?style=flat&colorA=0a0a0a" alt="roadmaps" />
<img src="https://img.shields.io/badge/%E2%9C%A8-YouTube%20Channel-0a0a0a.svg?style=flat&colorA=0a0a0a" alt="roadmaps" />
</a>
</p>
</p>
@@ -30,14 +30,17 @@ Roadmaps are now interactive, you can click the nodes to read more about the top
Here is the list of available roadmaps with more being actively worked upon.
- [Frontend Roadmap](https://roadmap.sh/frontend)
- [Frontend Roadmap](https://roadmap.sh/frontend) / [Frontend Beginner Roadmap](https://roadmap.sh/frontend?r=frontend-beginner)
- [Backend Roadmap](https://roadmap.sh/backend)
- [DevOps Roadmap](https://roadmap.sh/devops)
- [DevOps Roadmap](https://roadmap.sh/devops) / [DevOps Beginner Roadmap](https://roadmap.sh/devops?r=devops-beginner)
- [Full Stack Roadmap](https://roadmap.sh/full-stack)
- [Computer Science Roadmap](https://roadmap.sh/computer-science)
- [QA Roadmap](https://roadmap.sh/qa)
- [Software Architect Roadmap](https://roadmap.sh/software-architect)
- [Software Design and Architecture Roadmap](https://roadmap.sh/software-design-architecture)
- [JavaScript Roadmap](https://roadmap.sh/javascript)
- [TypeScript Roadmap](https://roadmap.sh/typescript)
- [C++ Roadmap](https://roadmap.sh/cpp)
- [React Roadmap](https://roadmap.sh/react)
- [Vue Roadmap](https://roadmap.sh/vue)
- [Angular Roadmap](https://roadmap.sh/angular)
@@ -53,6 +56,20 @@ Here is the list of available roadmaps with more being actively worked upon.
- [DBA Roadmap](https://roadmap.sh/postgresql-dba)
- [Blockchain Roadmap](https://roadmap.sh/blockchain)
- [ASP.NET Core Roadmap](https://roadmap.sh/aspnet-core)
- [System Design Roadmap](https://roadmap.sh/system-design)
- [Kubernetes Roadmap](https://roadmap.sh/kubernetes)
- [Cyber Security Roadmap](https://roadmap.sh/cyber-security)
- [MongoDB Roadmap](https://roadmap.sh/mongodb)
- [UX Design Roadmap](https://roadmap.sh/ux-design)
- [Docker Roadmap](https://roadmap.sh/docker)
- [Prompt Engineering Roadmap](https://roadmap.sh/prompt-engineering)
We have also added a new form of visual content covering best practices:
- [Code Review Best Practices](https://roadmap.sh/best-practices/code-review)
- [Frontend Performance Best Practices](https://roadmap.sh/best-practices/frontend-performance)
- [API Security Best Practices](https://roadmap.sh/best-practices/api-security)
- [AWS Best Practices](https://roadmap.sh/best-practices/aws)
![](https://i.imgur.com/waxVImv.png)

View File

@@ -0,0 +1,173 @@
const fs = require('fs');
const path = require('path');
const OPEN_AI_API_KEY = process.env.OPEN_AI_API_KEY;
const ALL_BEST_PRACTICES_DIR = path.join(
__dirname,
'../src/data/best-practices'
);
const BEST_PRACTICE_JSON_DIR = path.join(
__dirname,
'../public/jsons/best-practices'
);
const bestPracticeId = process.argv[2];
const bestPracticeTitle = bestPracticeId.replace(/-/g, ' ');
const allowedBestPracticeIds = fs.readdirSync(ALL_BEST_PRACTICES_DIR);
if (!bestPracticeId) {
console.error('bestPracticeId is required');
process.exit(1);
}
if (!allowedBestPracticeIds.includes(bestPracticeId)) {
console.error(`Invalid bestPractice key ${bestPracticeId}`);
console.error(`Allowed keys are ${allowedBestPracticeIds.join(', ')}`);
process.exit(1);
}
const BEST_PRACTICE_CONTENT_DIR = path.join(
ALL_BEST_PRACTICES_DIR,
bestPracticeId,
'content'
);
const { Configuration, OpenAIApi } = require('openai');
const configuration = new Configuration({
apiKey: OPEN_AI_API_KEY,
});
const openai = new OpenAIApi(configuration);
function getFilesInFolder(folderPath, fileList = {}) {
const files = fs.readdirSync(folderPath);
files.forEach((file) => {
const filePath = path.join(folderPath, file);
const stats = fs.statSync(filePath);
if (stats.isDirectory()) {
getFilesInFolder(filePath, fileList);
} else if (stats.isFile()) {
const fileUrl = filePath
.replace(BEST_PRACTICE_CONTENT_DIR, '') // Remove the content folder
.replace(/\/\d+-/g, '/') // Remove ordering info `/101-ecosystem`
.replace(/\/index\.md$/, '') // Make the `/index.md` to become the parent folder only
.replace(/\.md$/, ''); // Remove `.md` from the end of file
fileList[fileUrl] = filePath;
}
});
return fileList;
}
function writeTopicContent(topicTitle) {
let prompt = `I am reading a guide that has best practices about "${bestPracticeTitle}". I want to know more about "${topicTitle}". Write me a brief introductory paragraph about this and some tips on how I make sure of this? Behave as if you are the author of the guide.`;
console.log(`Generating '${topicTitle}'...`);
return new Promise((resolve, reject) => {
openai
.createChatCompletion({
model: 'gpt-4',
messages: [
{
role: 'user',
content: prompt,
},
],
})
.then((response) => {
const article = response.data.choices[0].message.content;
resolve(article);
})
.catch((err) => {
reject(err);
});
});
}
async function writeFileForGroup(group, topicUrlToPathMapping) {
const topicId = group?.properties?.controlName;
const topicTitle = group?.children?.controls?.control?.find(
(control) => control?.typeID === 'Label'
)?.properties?.text;
const currTopicUrl = `/${topicId}`;
if (currTopicUrl.startsWith('/check:')) {
return;
}
const contentFilePath = topicUrlToPathMapping[currTopicUrl];
if (!contentFilePath) {
console.log(`Missing file for: ${currTopicUrl}`);
process.exit(0);
return;
}
const currentFileContent = fs.readFileSync(contentFilePath, 'utf8');
const isFileEmpty = currentFileContent.replace(/^#.+/, ``).trim() === '';
if (!isFileEmpty) {
console.log(`Ignoring ${topicId}. Not empty.`);
return;
}
let newFileContent = `# ${topicTitle}`;
if (!OPEN_AI_API_KEY) {
console.log(`Writing ${topicId}..`);
fs.writeFileSync(contentFilePath, newFileContent, 'utf8');
return;
}
const topicContent = await writeTopicContent(topicTitle);
newFileContent += `\n\n${topicContent}`;
console.log(`Writing ${topicId}..`);
fs.writeFileSync(contentFilePath, newFileContent, 'utf8');
// console.log(currentFileContent);
// console.log(currTopicUrl);
// console.log(topicTitle);
// console.log(topicUrlToPathMapping[currTopicUrl]);
}
async function run() {
const topicUrlToPathMapping = getFilesInFolder(BEST_PRACTICE_CONTENT_DIR);
const bestPracticeJson = require(path.join(
BEST_PRACTICE_JSON_DIR,
`${bestPracticeId}.json`
));
const groups = bestPracticeJson?.mockup?.controls?.control?.filter(
(control) =>
control.typeID === '__group__' &&
!control.properties?.controlName?.startsWith('ext_link')
);
if (!OPEN_AI_API_KEY) {
console.log('----------------------------------------');
console.log('OPEN_AI_API_KEY not found. Skipping openai api calls...');
console.log('----------------------------------------');
}
const writePromises = [];
for (let group of groups) {
writePromises.push(writeFileForGroup(group, topicUrlToPathMapping));
}
console.log('Waiting for all files to be written...');
await Promise.all(writePromises);
}
run()
.then(() => {
console.log('Done');
})
.catch((err) => {
console.error(err);
process.exit(1);
});

View File

@@ -0,0 +1,155 @@
const fs = require('fs');
const path = require('path');
const CONTENT_DIR = path.join(__dirname, '../content');
// Directory containing the best-practices
const BEST_PRACTICE_CONTENT_DIR = path.join(
__dirname,
'../src/data/best-practices'
);
const bestPracticeId = process.argv[2];
const allowedBestPracticeId = fs.readdirSync(BEST_PRACTICE_CONTENT_DIR);
if (!bestPracticeId) {
console.error('bestPractice is required');
process.exit(1);
}
if (!allowedBestPracticeId.includes(bestPracticeId)) {
console.error(`Invalid best practice key ${bestPracticeId}`);
console.error(`Allowed keys are ${allowedBestPracticeId.join(', ')}`);
process.exit(1);
}
// Directory holding the best parctice content files
const bestPracticeDirName = fs
.readdirSync(BEST_PRACTICE_CONTENT_DIR)
.find((dirName) => dirName.replace(/\d+-/, '') === bestPracticeId);
if (!bestPracticeDirName) {
console.error('Best practice directory not found');
process.exit(1);
}
const bestPracticeDirPath = path.join(
BEST_PRACTICE_CONTENT_DIR,
bestPracticeDirName
);
const bestPracticeContentDirPath = path.join(
BEST_PRACTICE_CONTENT_DIR,
bestPracticeDirName,
'content'
);
// If best practice content already exists do not proceed as it would override the files
if (fs.existsSync(bestPracticeContentDirPath)) {
console.error(
`Best Practice content already exists @ ${bestPracticeContentDirPath}`
);
process.exit(1);
}
function prepareDirTree(control, dirTree) {
// Directories are only created for groups
if (control.typeID !== '__group__') {
return;
}
// e.g. 104-testing-your-apps:other-options
const controlName = control?.properties?.controlName || '';
// No directory for a group without control name
if (
!controlName ||
controlName.startsWith('check:') ||
controlName.startsWith('ext_link:')
) {
return;
}
// e.g. ['testing-your-apps', 'other-options']
const dirParts = controlName.split(':');
// Nest the dir path in the dirTree
let currDirTree = dirTree;
dirParts.forEach((dirPart) => {
currDirTree[dirPart] = currDirTree[dirPart] || {};
currDirTree = currDirTree[dirPart];
});
const childrenControls = control.children.controls.control;
// No more children
if (childrenControls.length) {
childrenControls.forEach((childControl) => {
prepareDirTree(childControl, dirTree);
});
}
return { dirTree };
}
const bestPractice = require(path.join(
__dirname,
`../public/jsons/best-practices/${bestPracticeId}`
));
const controls = bestPractice.mockup.controls.control;
// Prepare the dir tree that we will be creating
const dirTree = {};
controls.forEach((control) => {
prepareDirTree(control, dirTree);
});
/**
* @param parentDir Parent directory in which directory is to be created
* @param dirTree Nested dir tree to be created
* @param filePaths The mapping from groupName to file path
*/
function createDirTree(parentDir, dirTree, filePaths = {}) {
const childrenDirNames = Object.keys(dirTree);
const hasChildren = childrenDirNames.length !== 0;
// @todo write test for this, yolo for now
const groupName = parentDir
.replace(bestPracticeContentDirPath, '') // Remove base dir path
.replace(/(^\/)|(\/$)/g, '') // Remove trailing slashes
.replaceAll('/', ':') // Replace slashes with `:`
.replace(/:\d+-/, ':');
const humanizedGroupName = groupName
.split(':')
.pop()
?.replaceAll('-', ' ')
.replace(/^\w/, ($0) => $0.toUpperCase());
// If no children, create a file for this under the parent directory
if (!hasChildren) {
let fileName = `${parentDir}.md`;
fs.writeFileSync(fileName, `# ${humanizedGroupName}`);
filePaths[groupName || 'home'] = fileName.replace(CONTENT_DIR, '');
return filePaths;
}
// There *are* children, so create the parent as a directory
// and create `index.md` as the content file for this
fs.mkdirSync(parentDir);
let readmeFilePath = path.join(parentDir, 'index.md');
fs.writeFileSync(readmeFilePath, `# ${humanizedGroupName}`);
filePaths[groupName || 'home'] = readmeFilePath.replace(CONTENT_DIR, '');
// For each of the directory names, create a
// directory inside the given directory
childrenDirNames.forEach((dirName) => {
createDirTree(path.join(parentDir, dirName), dirTree[dirName], filePaths);
});
return filePaths;
}
// Create directories and get back the paths for created directories
createDirTree(bestPracticeContentDirPath, dirTree);
console.log('Created best practice content directory structure');

129
scripts/page-data-agg.cjs Normal file
View File

@@ -0,0 +1,129 @@
const csv = require('csv-parser');
const fs = require('fs');
const path = require('path');
const csvFilePath = path.join(__dirname, '../data.csv');
const results = {};
const pageSummary = {};
fs.createReadStream(csvFilePath)
.pipe(
csv({
separator: ',',
mapHeaders: ({ header, index }) =>
header.toLowerCase().replace(/ /g, '_'),
mapValues: ({ header, index, value }) => {
if (header === 'page') {
return (
value
.replace(/"/g, '')
.replace(/'/g, '')
.replace(/`/g, '')
.replace(/\?r=/g, '#r#')
.replace(/\?.+?$/g, '')
.replace(/#r#/g, '?r=')
.replace(/\/$/g, '') || '/'
);
}
if (header !== 'month_of_year') {
return parseInt(value, 10);
}
return value;
},
})
)
.on('data', (data) => {
const { page, month_of_year, unique_pageviews, users } = data;
const pageData = results[page] || {};
const existingPageMonthData = pageData[month_of_year] || {};
const existingViews = existingPageMonthData.views || 0;
const existingUsers = existingPageMonthData.users || 0;
const newViews = existingViews + unique_pageviews;
const newUsers = existingUsers + users;
pageData[month_of_year] = {
views: newViews,
users: newUsers,
};
results[page] = pageData;
pageSummary[page] = pageSummary[page] || { views: 0, users: 0 };
pageSummary[page].views += unique_pageviews;
pageSummary[page].users += users;
})
.on('end', () => {
const csvHeader = [
'Page',
'Jan 2022',
'Feb 2022',
'Mar 2022',
'Apr 2022',
'May 2022',
'Jun 2022',
'Jul 2022',
'Aug 2022',
'Sep 2022',
'Oct 2022',
'Nov 2022',
'Dec 2022',
'Jan 2023',
'Feb 2023',
'Mar 2023',
'Apr 2023',
'May 2023',
'Jun 2023',
'Jul 2023',
'Aug 2023',
'Sep 2023',
'Oct 2023',
'Nov 2023',
'Dec 2023',
];
const csvRows = Object.keys(pageSummary)
.filter(pageUrl => pageSummary[pageUrl].views > 10)
.filter(pageUrl => !['/upcoming', '/pdfs', '/signup', '/login', '/@'].includes(pageUrl))
.sort((pageA, pageB) => {
const aViews = pageSummary[pageA].views;
const bViews = pageSummary[pageB].views;
return bViews - aViews;
})
.map((pageUrl) => {
const rawPageResult = results[pageUrl];
const pageResultCsvRow = [];
csvHeader.forEach((csvHeaderItem) => {
if (csvHeaderItem === 'Page') {
pageResultCsvRow.push(pageUrl);
return;
}
const csvHeaderItemAlt = csvHeaderItem
.replace(/ /g, '_')
.toLowerCase();
const result = rawPageResult[csvHeaderItem || csvHeaderItemAlt] || {};
const views = result.views || 0;
const users = result.users || 0;
pageResultCsvRow.push(users);
});
return pageResultCsvRow;
});
const finalCsvRows = [csvHeader, ...csvRows];
const csvRowStrings = finalCsvRows.map((row) => {
return row.join(',');
});
const csvString = csvRowStrings.join('\n');
fs.writeFileSync(path.join(__dirname, '../data-agg.csv'), csvString);
});

37
scripts/readme.md Normal file
View File

@@ -0,0 +1,37 @@
## CLI Tools
> A bunch of CLI scripts to make the development easier
## `roadmap-links.cjs`
Generates a list of all the resources links in any roadmap file.
## `compress-jsons.cjs`
Compresses all the JSON files in the `public/jsons` folder
## `update-sponsors.cjs`
Updates the sponsor ads on each roadmap page with the latest sponsor information in the Excel sheet.
## `roadmap-content.cjs`
Currently, for any new roadmaps that we add, we do create the interactive roadmap but we end up leaving the content empty in the roadmap till we get time to fill it up manually.
This script populates all the content files with some minimal content from OpenAI so that the users visiting the website have something to read in the interactive roadmap till we get time to fill it up manually.
## `roadmap-dirs.cjs`
This command is used to create the content folders and files for the interactivity of the roadmap. You can use the below command to generate the roadmap skeletons inside a roadmap directory:
```bash
npm run roadmap-dirs [frontend|backend|devops|...]
```
For the content skeleton to be generated, we should have proper grouping, and the group names in the project files. You can follow the steps listed below in order to add the meta information to the roadmap.
- Remove all the groups from the roadmaps through the project editor. Select all and press `cmd+shift+g`
- Identify the boxes that should be clickable and group them together with `cmd+shift+g`
- Assign the name to the groups.
- Group names have the format of `[sort]-[slug]` e.g. `100-internet`. Each group name should start with a number starting from 100 which helps with sorting of the directories and the files. Groups at the same level have the sequential sorting information.
- Each groups children have a separate group and have the name similar to `[sort]-[parent-slug]:[child-slug]` where sort refers to the sorting of the `child-slug` and not the parent. Also parent-slug does not need to have the sorting information as a part of slug e.g. if parent was `100-internet` the children would be `100-internet:how-does-the-internet-work`, `101-internet:what-is-http`, `102-internet:browsers`.

174
scripts/roadmap-content.cjs Normal file
View File

@@ -0,0 +1,174 @@
const fs = require('fs');
const path = require('path');
const OPEN_AI_API_KEY = process.env.OPEN_AI_API_KEY;
const ALL_ROADMAPS_DIR = path.join(__dirname, '../src/data/roadmaps');
const roadmapId = process.argv[2];
const allowedRoadmapIds = fs.readdirSync(ALL_ROADMAPS_DIR);
if (!roadmapId) {
console.error('roadmapId is required');
process.exit(1);
}
if (!allowedRoadmapIds.includes(roadmapId)) {
console.error(`Invalid roadmap key ${roadmapId}`);
console.error(`Allowed keys are ${allowedRoadmapIds.join(', ')}`);
process.exit(1);
}
const ROADMAP_CONTENT_DIR = path.join(ALL_ROADMAPS_DIR, roadmapId, 'content');
const { Configuration, OpenAIApi } = require('openai');
const configuration = new Configuration({
apiKey: OPEN_AI_API_KEY,
});
const openai = new OpenAIApi(configuration);
function getFilesInFolder(folderPath, fileList = {}) {
const files = fs.readdirSync(folderPath);
files.forEach((file) => {
const filePath = path.join(folderPath, file);
const stats = fs.statSync(filePath);
if (stats.isDirectory()) {
getFilesInFolder(filePath, fileList);
} else if (stats.isFile()) {
const fileUrl = filePath
.replace(ROADMAP_CONTENT_DIR, '') // Remove the content folder
.replace(/\/\d+-/g, '/') // Remove ordering info `/101-ecosystem`
.replace(/\/index\.md$/, '') // Make the `/index.md` to become the parent folder only
.replace(/\.md$/, ''); // Remove `.md` from the end of file
fileList[fileUrl] = filePath;
}
});
return fileList;
}
function writeTopicContent(currTopicUrl) {
const [parentTopic, childTopic] = currTopicUrl
.replace(/^\d+-/g, '/')
.replace(/:/g, '/')
.replace(/^\//, '')
.split('/')
.slice(-2)
.map((topic) => topic.replace(/-/g, ' '));
const roadmapTitle = roadmapId.replace(/-/g, ' ');
let prompt = `I am reading a guide about "${roadmapTitle}". I am on the topic "${parentTopic}". I want to know more about "${childTopic}". Write me with a brief summary of that. Content should be in markdown. I already know the benefits of each so do not add benefits in the output. Also include the code examples if applicable to this topic.`;
if (!childTopic) {
prompt = `I am reading a guide about "${roadmapTitle}". I am on the topic "${parentTopic}". I want to know more about "${parentTopic}". Write me with a brief summary of that. Content should be in markdown. I already know the benefits of each so do not add benefits in the output. Also include the code examples if applicable to this topic.`;
}
console.log(`Generating '${childTopic || parentTopic}'...`);
return new Promise((resolve, reject) => {
openai
.createChatCompletion({
model: 'gpt-4',
messages: [
{
role: 'user',
content: prompt,
},
],
})
.then((response) => {
const article = response.data.choices[0].message.content;
resolve(article);
})
.catch((err) => {
reject(err);
});
});
}
async function writeFileForGroup(group, topicUrlToPathMapping) {
const topicId = group?.properties?.controlName;
const topicTitle = group?.children?.controls?.control?.find(
(control) => control?.typeID === 'Label'
)?.properties?.text;
const currTopicUrl = topicId?.replace(/^\d+-/g, '/')?.replace(/:/g, '/');
if (!currTopicUrl) {
return;
}
const contentFilePath = topicUrlToPathMapping[currTopicUrl];
if (!contentFilePath) {
console.log(`Missing file for: ${currTopicUrl}`);
return;
}
const currentFileContent = fs.readFileSync(contentFilePath, 'utf8');
const isFileEmpty = currentFileContent.replace(/^#.+/, ``).trim() === '';
if (!isFileEmpty) {
console.log(`Ignoring ${topicId}. Not empty.`);
return;
}
let newFileContent = `# ${topicTitle}`;
if (!OPEN_AI_API_KEY) {
console.log(`Writing ${topicId}..`);
fs.writeFileSync(contentFilePath, newFileContent, 'utf8');
return;
}
const topicContent = await writeTopicContent(currTopicUrl);
newFileContent += `\n\n${topicContent}`;
console.log(`Writing ${topicId}..`);
fs.writeFileSync(contentFilePath, newFileContent, 'utf8');
// console.log(currentFileContent);
// console.log(currTopicUrl);
// console.log(topicTitle);
// console.log(topicUrlToPathMapping[currTopicUrl]);
}
async function run() {
const topicUrlToPathMapping = getFilesInFolder(ROADMAP_CONTENT_DIR);
const roadmapJson = require(path.join(
ALL_ROADMAPS_DIR,
`${roadmapId}/${roadmapId}`
));
const groups = roadmapJson?.mockup?.controls?.control?.filter(
(control) =>
control.typeID === '__group__' &&
!control.properties?.controlName?.startsWith('ext_link')
);
if (!OPEN_AI_API_KEY) {
console.log('----------------------------------------');
console.log('OPEN_AI_API_KEY not found. Skipping openai api calls...');
console.log('----------------------------------------');
}
const writePromises = [];
for (let group of groups) {
writePromises.push(writeFileForGroup(group, topicUrlToPathMapping));
}
console.log('Waiting for all files to be written...');
await Promise.all(writePromises);
}
run()
.then(() => {
console.log('Done');
})
.catch((err) => {
console.error(err);
process.exit(1);
});

167
scripts/roadmap-dirs.cjs Normal file
View File

@@ -0,0 +1,167 @@
const fs = require('fs');
const path = require('path');
const CONTENT_DIR = path.join(__dirname, '../content');
// Directory containing the roadmaps
const ROADMAP_CONTENT_DIR = path.join(__dirname, '../src/data/roadmaps');
const roadmapId = process.argv[2];
const allowedRoadmapIds = fs.readdirSync(ROADMAP_CONTENT_DIR);
if (!roadmapId) {
console.error('roadmapId is required');
process.exit(1);
}
if (!allowedRoadmapIds.includes(roadmapId)) {
console.error(`Invalid roadmap key ${roadmapId}`);
console.error(`Allowed keys are ${allowedRoadmapIds.join(', ')}`);
process.exit(1);
}
// Directory holding the roadmap content files
const roadmapDirName = fs
.readdirSync(ROADMAP_CONTENT_DIR)
.find((dirName) => dirName.replace(/\d+-/, '') === roadmapId);
if (!roadmapDirName) {
console.error('Roadmap directory not found');
process.exit(1);
}
const roadmapDirPath = path.join(ROADMAP_CONTENT_DIR, roadmapDirName);
const roadmapContentDirPath = path.join(
ROADMAP_CONTENT_DIR,
roadmapDirName,
'content'
);
// If roadmap content already exists do not proceed as it would override the files
if (fs.existsSync(roadmapContentDirPath)) {
console.error(`Roadmap content already exists @ ${roadmapContentDirPath}`);
process.exit(1);
}
function prepareDirTree(control, dirTree, dirSortOrders) {
// Directories are only created for groups
if (control.typeID !== '__group__') {
return;
}
// e.g. 104-testing-your-apps:other-options
const controlName = control?.properties?.controlName || '';
// e.g. 104
const sortOrder = controlName.match(/^\d+/)?.[0];
// No directory for a group without control name
if (!controlName || !sortOrder) {
return;
}
// e.g. testing-your-apps:other-options
const controlNameWithoutSortOrder = controlName.replace(/^\d+-/, '');
// e.g. ['testing-your-apps', 'other-options']
const dirParts = controlNameWithoutSortOrder.split(':');
// Nest the dir path in the dirTree
let currDirTree = dirTree;
dirParts.forEach((dirPart) => {
currDirTree[dirPart] = currDirTree[dirPart] || {};
currDirTree = currDirTree[dirPart];
});
dirSortOrders[controlNameWithoutSortOrder] = Number(sortOrder);
const childrenControls = control.children.controls.control;
// No more children
if (childrenControls.length) {
childrenControls.forEach((childControl) => {
prepareDirTree(childControl, dirTree, dirSortOrders);
});
}
return { dirTree, dirSortOrders };
}
const roadmap = require(path.join(
__dirname,
`../src/data/roadmaps/${roadmapId}/${roadmapId}`
));
const controls = roadmap.mockup.controls.control;
// Prepare the dir tree that we will be creating and also calculate the sort orders
const dirTree = {};
const dirSortOrders = {};
controls.forEach((control) => {
prepareDirTree(control, dirTree, dirSortOrders);
});
/**
* @param parentDir Parent directory in which directory is to be created
* @param dirTree Nested dir tree to be created
* @param sortOrders Mapping from groupName to sort order
* @param filePaths The mapping from groupName to file path
*/
function createDirTree(parentDir, dirTree, sortOrders, filePaths = {}) {
const childrenDirNames = Object.keys(dirTree);
const hasChildren = childrenDirNames.length !== 0;
// @todo write test for this, yolo for now
const groupName = parentDir
.replace(roadmapContentDirPath, '') // Remove base dir path
.replace(/(^\/)|(\/$)/g, '') // Remove trailing slashes
.replace(/(^\d+?-)/g, '') // Remove sorting information
.replaceAll('/', ':') // Replace slashes with `:`
.replace(/:\d+-/, ':');
const humanizedGroupName = groupName
.split(':')
.pop()
?.replaceAll('-', ' ')
.replace(/^\w/, ($0) => $0.toUpperCase());
const sortOrder = sortOrders[groupName] || '';
// Attach sorting information to dirname
// e.g. /roadmaps/100-frontend/content/internet
// ———> /roadmaps/100-frontend/content/103-internet
if (sortOrder) {
parentDir = parentDir.replace(/(.+?)([^\/]+)?$/, `$1${sortOrder}-$2`);
}
// If no children, create a file for this under the parent directory
if (!hasChildren) {
let fileName = `${parentDir}.md`;
fs.writeFileSync(fileName, `# ${humanizedGroupName}`);
filePaths[groupName || 'home'] = fileName.replace(CONTENT_DIR, '');
return filePaths;
}
// There *are* children, so create the parent as a directory
// and create `index.md` as the content file for this
fs.mkdirSync(parentDir);
let readmeFilePath = path.join(parentDir, 'index.md');
fs.writeFileSync(readmeFilePath, `# ${humanizedGroupName}`);
filePaths[groupName || 'home'] = readmeFilePath.replace(CONTENT_DIR, '');
// For each of the directory names, create a
// directory inside the given directory
childrenDirNames.forEach((dirName) => {
createDirTree(
path.join(parentDir, dirName),
dirTree[dirName],
dirSortOrders,
filePaths
);
});
return filePaths;
}
// Create directories and get back the paths for created directories
createDirTree(roadmapContentDirPath, dirTree, dirSortOrders);
console.log('Created roadmap content directory structure');

View File

@@ -6,7 +6,7 @@ if (!roadmapId) {
console.error('Error: roadmapId is required');
}
const fullPath = path.join(__dirname, `../src/roadmaps/${roadmapId}`);
const fullPath = path.join(__dirname, `../src/data/roadmaps/${roadmapId}`);
if (!fs.existsSync(fullPath)) {
console.error(`Error: path not found: ${fullPath}!`);
process.exit(1);

167
scripts/update-sponsors.cjs Normal file
View File

@@ -0,0 +1,167 @@
const path = require('path');
const fs = require('fs');
const yaml = require('js-yaml');
const apiKey = process.env.SPONSOR_SHEET_API_KEY;
const sheetId = process.env.SPONSOR_SHEET_ID;
if (!apiKey || !sheetId) {
console.error('Missing API key or sheet ID');
process.exit(1);
}
const sheetRange = 'A3:I1001';
const sheetUrl = `https://sheets.googleapis.com/v4/spreadsheets/${sheetId}/values/${sheetRange}?key=${apiKey}`;
function removeAllSponsors(baseContentDir) {
console.log('------------------------');
console.log('Removing sponsors from: ', baseContentDir);
console.log('------------------------');
const dataDirPath = path.join(__dirname, '../src/data');
const contentDirPath = path.join(dataDirPath, baseContentDir);
const contentDir = fs.readdirSync(contentDirPath);
contentDir.forEach((content) => {
console.log('Removing sponsors from: ', content);
const pageFilePath = path.join(contentDirPath, content, `${content}.md`);
const pageFileContent = fs.readFileSync(pageFilePath, 'utf8');
const frontMatterRegex = /---\n([\s\S]*?)\n---/;
const existingFrontmatter = pageFileContent.match(frontMatterRegex)[1];
const contentWithoutFrontmatter = pageFileContent
.replace(frontMatterRegex, ``)
.trim();
let frontmatterObj = yaml.load(existingFrontmatter);
delete frontmatterObj.sponsors;
const newFrontmatter = yaml.dump(frontmatterObj, {
lineWidth: 10000,
forceQuotes: true,
quotingType: "'",
});
const newContent = `---\n${newFrontmatter}---\n${contentWithoutFrontmatter}`;
fs.writeFileSync(pageFilePath, newContent, 'utf8');
});
}
function addPageSponsor({
pageUrl,
company,
redirectUrl,
imageUrl,
adTitle,
adDescription,
}) {
const urlPart = pageUrl
.replace('https://roadmap.sh/', '')
.replace(/\?.+?$/, '');
const parentDir = urlPart.startsWith('best-practices/')
? 'best-practices'
: 'roadmaps';
const pageId = urlPart.replace(`${parentDir}/`, '');
const pageFilePath = path.join(
__dirname,
`../src/data/${parentDir}`,
`${pageId}/${pageId}.md`
);
if (!fs.existsSync(pageFilePath)) {
console.error(`Page file not found: ${pageFilePath}`);
process.exit(1);
}
console.log(`Updating page: ${urlPart}`);
const pageFileContent = fs.readFileSync(pageFilePath, 'utf8');
const frontMatterRegex = /---\n([\s\S]*?)\n---/;
const existingFrontmatter = pageFileContent.match(frontMatterRegex)[1];
const contentWithoutFrontmatter = pageFileContent
.replace(frontMatterRegex, ``)
.trim();
let frontmatterObj = yaml.load(existingFrontmatter);
const sponsors = frontmatterObj.sponsors || [];
const frontmatterValues = Object.entries(frontmatterObj);
const roadmapLabel = frontmatterObj.briefTitle;
sponsors.push({
url: redirectUrl,
title: adTitle,
imageUrl,
description: adDescription,
page: roadmapLabel,
company,
});
// Insert sponsor data at 10 index i.e. after
// roadmap dimensions in the frontmatter
frontmatterValues.splice(10, 0, ['sponsors', sponsors]);
frontmatterObj = Object.fromEntries(frontmatterValues);
const newFrontmatter = yaml.dump(frontmatterObj, {
lineWidth: 10000,
forceQuotes: true,
quotingType: "'",
});
const newContent = `---\n${newFrontmatter}---\n\n${contentWithoutFrontmatter}`;
fs.writeFileSync(pageFilePath, newContent, 'utf8');
}
// Remove sponsors from all roadmaps
removeAllSponsors('roadmaps');
removeAllSponsors('best-practices');
console.log('------------------------');
console.log('Adding sponsors');
console.log('------------------------');
fetch(sheetUrl)
.then((res) => res.json())
.then((rawData) => {
const rows = rawData.values;
rows.map((row) => {
// prettier-ignore
const [
pageUrl,
company,
redirectUrl,
imageUrl,
adTitle,
adDescription,
startDate,
endDate,
isActive,
] = row;
const isConfiguredActive = isActive?.toLowerCase() === 'yes';
const currentDate = new Date();
const isDateInRange =
currentDate >= new Date(startDate) && currentDate <= new Date(endDate);
if (!isConfiguredActive || !isDateInRange) {
return;
}
addPageSponsor({
pageUrl,
company,
redirectUrl,
imageUrl,
adTitle,
adDescription,
startDate,
endDate,
isActive,
});
});
});

View File

@@ -2,26 +2,38 @@ import path from 'node:path';
import fs from 'node:fs/promises';
async function getRoadmapIds() {
return fs.readdir(path.join(process.cwd(), 'src/roadmaps'));
return fs.readdir(path.join(process.cwd(), 'src/data/roadmaps'));
}
export function shouldIndexPage(page) {
async function getBestPracticesIds() {
return fs.readdir(path.join(process.cwd(), 'src/data/best-practices'));
}
export function shouldIndexPage(pageUrl) {
return ![
'https://roadmap.sh/404/',
'https://roadmap.sh/terms/',
'https://roadmap.sh/privacy/',
'https://roadmap.sh/pdfs/',
].includes(page);
'https://roadmap.sh/404',
'https://roadmap.sh/terms',
'https://roadmap.sh/privacy',
'https://roadmap.sh/pdfs',
'https://roadmap.sh/g',
].includes(pageUrl);
}
export async function serializeSitemap(item) {
const highPriorityPages = [
'https://roadmap.sh/',
'https://roadmap.sh/about/',
'https://roadmap.sh/roadmaps/',
'https://roadmap.sh/guides/',
'https://roadmap.sh/videos/',
...(await getRoadmapIds()).map((id) => `https://roadmap.sh/${id}/`),
'https://roadmap.sh',
'https://roadmap.sh/about',
'https://roadmap.sh/roadmaps',
'https://roadmap.sh/best-practices',
'https://roadmap.sh/guides',
'https://roadmap.sh/videos',
...(await getRoadmapIds()).flatMap((id) => [
`https://roadmap.sh/${id}`,
`https://roadmap.sh/${id}/topics`,
]),
...(await getBestPracticesIds()).map(
(id) => `https://roadmap.sh/best-practices/${id}`
),
];
// Roadmaps and other high priority pages
@@ -32,22 +44,20 @@ export async function serializeSitemap(item) {
// @ts-ignore
changefreq: 'monthly',
priority: 1,
lastmod: new Date().toISOString(),
};
}
}
// Guide and video pages
if (
item.url.startsWith('https://roadmap.sh/guides/') ||
item.url.startsWith('https://roadmap.sh/videos/')
item.url.startsWith('https://roadmap.sh/guides') ||
item.url.startsWith('https://roadmap.sh/videos')
) {
return {
...item,
// @ts-ignore
changefreq: 'monthly',
priority: 0.9,
lastmod: new Date().toISOString(),
};
}

View File

@@ -0,0 +1,153 @@
---
import AstroIcon from './AstroIcon.astro';
const { activePageId, activePageTitle } = Astro.props;
export interface Props {
activePageId: string;
activePageTitle: string;
}
const sidebarLinks = [
{
href: '/account',
title: 'Activity',
id: 'activity',
isNew: false,
icon: {
glyph: 'analytics',
classes: 'h-3 w-4',
},
},
{
href: '/account/road-card',
title: 'Card',
id: 'road-card',
isNew: true,
icon: {
glyph: 'badge',
classes: 'h-4 w-4',
},
},
{
href: '/account/update-profile',
title: 'Profile',
id: 'profile',
isNew: false,
icon: {
glyph: 'user',
classes: 'h-4 w-4',
},
},
{
href: '/account/update-password',
title: 'Security',
id: 'change-password',
isNew: false,
icon: {
glyph: 'security',
classes: 'h-4 w-4',
},
},
];
---
<div class='relative mb-5 block border-b p-4 shadow-inner md:hidden'>
<button
class='flex h-10 w-full items-center justify-between rounded-md border bg-white px-2 text-center text-sm font-medium text-gray-900'
id='settings-menu'
>
{activePageTitle}
<AstroIcon icon='dropdown' />
</button>
<ul
id='settings-menu-dropdown'
class='absolute left-0 right-0 z-10 mt-1 hidden space-y-1.5 bg-white p-2 shadow-lg'
>
{
sidebarLinks.map((sidebarLink) => {
const isActive = activePageId === sidebarLink.id;
return (
<li>
<a
href={sidebarLink.href}
class={`flex w-full items-center rounded px-3 py-1.5 text-sm text-slate-900 hover:bg-slate-200 ${
isActive ? 'bg-slate-100' : ''
}`}
>
<AstroIcon
icon={sidebarLink.icon.glyph}
class={`${sidebarLink.icon.classes} mr-2`}
/>
{sidebarLink.title}
</a>
</li>
);
})
}
</ul>
</div>
<div class='container flex min-h-screen items-stretch'>
<!-- Start Desktop Sidebar -->
<aside class='hidden w-44 shrink-0 border-r border-slate-200 py-10 md:block'>
<nav>
<ul class='space-y-1'>
{
sidebarLinks.map((sidebarLink) => {
const isActive = activePageId === sidebarLink.id;
return (
<li>
<a
href={sidebarLink.href}
class={`font-regular flex w-full items-center border-r-2 px-2 py-1.5 text-sm ${
isActive
? 'border-r-black bg-gray-100 text-black'
: 'border-r-transparent text-gray-500 hover:border-r-gray-300'
}`}
>
<span class='flex flex-grow items-center'>
<AstroIcon
icon={sidebarLink.icon.glyph}
class={`${sidebarLink.icon.classes} mr-2`}
/>
{sidebarLink.title}
</span>
{sidebarLink.isNew && !isActive && (
<span class='relative mr-1 flex items-center'>
<span class='relative rounded-full bg-gray-200 p-1 text-xs' />
<span class='absolute bottom-0 left-0 right-0 top-0 animate-ping rounded-full bg-gray-400 p-1 text-xs' />
</span>
)}
</a>
</li>
);
})
}
</ul>
</nav>
</aside>
<!-- /End Desktop Sidebar -->
<div class='grow px-0 py-0 md:px-10 md:py-10'>
<slot />
</div>
</div>
<script>
const menuButton = document.getElementById('settings-menu');
const menuDropdown = document.getElementById('settings-menu-dropdown');
menuButton?.addEventListener('click', () => {
menuDropdown?.classList.toggle('hidden');
});
document.addEventListener('click', (e) => {
if (!menuButton?.contains(e.target as Node)) {
menuDropdown?.classList.add('hidden');
}
});
</script>

View File

@@ -0,0 +1,56 @@
type ActivityCountersType = {
done: {
today: number;
total: number;
};
learning: {
today: number;
total: number;
};
streak: {
count: number;
};
};
type ActivityCounterType = {
text: string;
count: string;
};
function ActivityCounter(props: ActivityCounterType) {
const { text, count } = props;
return (
<div class="relative flex flex-1 flex-row-reverse sm:flex-col px-0 sm:px-4 py-2 sm:py-4 text-center sm:pt-10 items-center gap-2 sm:gap-0 justify-end">
<h2 class="text-base sm:text-5xl font-bold">
{count}
</h2>
<p class="mt-0 sm:mt-2 text-sm text-gray-400">{text}</p>
</div>
);
}
export function ActivityCounters(props: ActivityCountersType) {
const { done, learning, streak } = props;
return (
<div class="mx-0 -mt-5 sm:-mx-10 md:-mt-10">
<div class="flex flex-col sm:flex-row gap-0 sm:gap-2 divide-y sm:divide-y-0 divide-x-0 sm:divide-x border-b">
<ActivityCounter
text={'Topics Completed'}
count={`${done?.total || 0}`}
/>
<ActivityCounter
text={'Currently Learning'}
count={`${learning?.total || 0}`}
/>
<ActivityCounter
text={'Visit Streak'}
count={`${streak?.count || 0}d`}
/>
</div>
</div>
);
}

View File

@@ -0,0 +1,161 @@
import { useEffect, useState } from 'preact/hooks';
import { httpGet } from '../../lib/http';
import { ActivityCounters } from './ActivityCounters';
import { ResourceProgress } from './ResourceProgress';
import { pageProgressMessage } from '../../stores/page';
import { EmptyActivity } from './EmptyActivity';
type ActivityResponse = {
done: {
today: number;
total: number;
};
learning: {
today: number;
total: number;
roadmaps: {
title: string;
id: string;
learning: number;
done: number;
total: number;
skipped: number;
updatedAt: string;
}[];
bestPractices: {
title: string;
id: string;
learning: number;
done: number;
skipped: number;
total: number;
updatedAt: string;
}[];
};
streak: {
count: number;
firstVisitAt: Date | null;
lastVisitAt: Date | null;
};
activity: {
type: 'done' | 'learning' | 'pending' | 'skipped';
createdAt: Date;
metadata: {
resourceId?: string;
resourceType?: 'roadmap' | 'best-practice';
topicId?: string;
topicLabel?: string;
resourceTitle?: string;
};
}[];
};
export function ActivityPage() {
const [activity, setActivity] = useState<ActivityResponse>();
const [isLoading, setIsLoading] = useState(true);
async function loadActivity() {
const { error, response } = await httpGet<ActivityResponse>(
`${import.meta.env.PUBLIC_API_URL}/v1-get-user-stats`
);
if (!response || error) {
console.error('Error loading activity');
console.error(error);
return;
}
setActivity(response);
}
useEffect(() => {
loadActivity().finally(() => {
pageProgressMessage.set('');
setIsLoading(false);
});
}, []);
const learningRoadmaps = activity?.learning.roadmaps || [];
const learningBestPractices = activity?.learning.bestPractices || [];
if (isLoading) {
return null;
}
return (
<>
<ActivityCounters
done={activity?.done || { today: 0, total: 0 }}
learning={activity?.learning || { today: 0, total: 0 }}
streak={activity?.streak || { count: 0 }}
/>
<div class="mx-0 px-0 py-5 md:-mx-10 md:px-8 md:py-8">
{learningRoadmaps.length === 0 &&
learningBestPractices.length === 0 && <EmptyActivity />}
{(learningRoadmaps.length > 0 || learningBestPractices.length > 0) && (
<>
<h2 class="mb-3 text-xs uppercase text-gray-400">
Continue Following
</h2>
<div class="flex flex-col gap-3">
{learningRoadmaps
.sort((a, b) => {
const updatedAtA = new Date(a.updatedAt);
const updatedAtB = new Date(b.updatedAt);
return updatedAtB.getTime() - updatedAtA.getTime();
})
.map((roadmap) => (
<ResourceProgress
doneCount={roadmap.done || 0}
learningCount={roadmap.learning || 0}
totalCount={roadmap.total || 0}
skippedCount={roadmap.skipped || 0}
resourceId={roadmap.id}
resourceType={'roadmap'}
updatedAt={roadmap.updatedAt}
title={roadmap.title}
onCleared={() => {
pageProgressMessage.set('Updating activity');
loadActivity().finally(() => {
pageProgressMessage.set('');
});
}}
/>
))}
{learningBestPractices
.sort((a, b) => {
const updatedAtA = new Date(a.updatedAt);
const updatedAtB = new Date(b.updatedAt);
return updatedAtB.getTime() - updatedAtA.getTime();
})
.map((bestPractice) => (
<ResourceProgress
doneCount={bestPractice.done || 0}
totalCount={bestPractice.total || 0}
learningCount={bestPractice.learning || 0}
resourceId={bestPractice.id}
skippedCount={bestPractice.skipped || 0}
resourceType={'best-practice'}
title={bestPractice.title}
updatedAt={bestPractice.updatedAt}
onCleared={() => {
pageProgressMessage.set('Updating activity');
loadActivity().finally(() => {
pageProgressMessage.set('');
});
}}
/>
))}
</div>
</>
)}
</div>
</>
);
}

View File

@@ -0,0 +1,27 @@
import RoadmapIcon from '../../icons/roadmap.svg';
export function EmptyActivity() {
return (
<div class="rounded-md">
<div class="flex flex-col items-center p-7 text-center">
<img
alt="no roadmaps"
src={RoadmapIcon}
class="mb-2 w-[60px] h-[60px] sm:h-[120px] sm:w-[120px] opacity-10"
/>
<h2 class="text-lg sm:text-xl font-bold">No Progress</h2>
<p className="my-1 sm:my-2 max-w-[400px] text-gray-500 text-sm sm:text-base">
Progress will appear here as you start tracking your{' '}
<a href="/roadmaps" class="mt-4 text-blue-500 hover:underline">
Roadmaps
</a>{' '}
or{' '}
<a href="/best-practices" class="mt-4 text-blue-500 hover:underline">
Best Practices
</a>{' '}
progress.
</p>
</div>
</div>
);
}

View File

@@ -0,0 +1,139 @@
import { useState } from 'preact/hooks';
import { httpPost } from '../../lib/http';
import { getRelativeTimeString } from '../../lib/date';
type ResourceProgressType = {
resourceType: 'roadmap' | 'best-practice';
resourceId: string;
title: string;
updatedAt: string;
totalCount: number;
doneCount: number;
learningCount: number;
skippedCount: number;
onCleared: () => void;
};
export function ResourceProgress(props: ResourceProgressType) {
const [isClearing, setIsClearing] = useState(false);
const [isConfirming, setIsConfirming] = useState(false);
const {
updatedAt,
resourceType,
resourceId,
title,
totalCount,
learningCount,
doneCount,
skippedCount,
onCleared,
} = props;
async function clearProgress() {
setIsClearing(true);
const { error, response } = await httpPost(
`${import.meta.env.PUBLIC_API_URL}/v1-clear-resource-progress`,
{
resourceId,
resourceType,
}
);
if (error || !response) {
alert('Error clearing progress. Please try again.');
console.error(error);
setIsClearing(false);
return;
}
localStorage.removeItem(`${resourceType}-${resourceId}-progress`);
console.log(`${resourceType}-${resourceId}-progress`);
setIsClearing(false);
setIsConfirming(false);
onCleared();
}
const url =
resourceType === 'roadmap'
? `/${resourceId}`
: `/best-practices/${resourceId}`;
const totalMarked = doneCount + skippedCount;
const progressPercentage = Math.round((totalMarked / totalCount) * 100);
return (
<div>
<a
href={url}
className="group relative flex cursor-pointer items-center rounded-t-md border p-3 text-gray-600 hover:border-gray-300 hover:text-black"
>
<span
className={`absolute left-0 top-0 block h-full cursor-pointer rounded-tl-md bg-black/5 group-hover:bg-black/10`}
style={{
width: `${progressPercentage}%`,
}}
></span>
<span className="relative flex-1 cursor-pointer truncate">
{title}
</span>
<span className="ml-1 cursor-pointer text-sm text-gray-400">
{getRelativeTimeString(updatedAt)}
</span>
</a>
<p className="sm:space-between flex flex-row items-start rounded-b-md border border-t-0 px-2 py-2 text-xs text-gray-500">
<span className="hidden flex-1 gap-1 sm:flex">
{doneCount > 0 && (
<>
<span>{doneCount} done</span> &bull;
</>
)}
{learningCount > 0 && (
<>
<span>{learningCount} in progress</span> &bull;
</>
)}
{skippedCount > 0 && (
<>
<span>{skippedCount} skipped</span> &bull;
</>
)}
<span>{totalCount} total</span>
</span>
{!isConfirming && (
<button
className="text-red-500 hover:text-red-800"
onClick={() => setIsConfirming(true)}
disabled={isClearing}
>
{!isClearing && (
<>
Clear Progress <span>&times;</span>
</>
)}
{isClearing && 'Processing...'}
</button>
)}
{isConfirming && (
<span>
Are you sure?{' '}
<button
onClick={clearProgress}
className="ml-1 mr-1 text-red-500 underline hover:text-red-800"
>
Yes
</button>{' '}
<button
onClick={() => setIsConfirming(false)}
className="text-red-500 underline hover:text-red-800"
>
No
</button>
</span>
)}
</p>
</div>
);
}

View File

@@ -1,41 +1,17 @@
---
---
<script src='./analytics.js'></script>
<script src='./analytics.ts'></script>
<script async src='https://www.googletagmanager.com/gtag/js?id=UA-139582634-1'
></script>
<script is:inline>
// @ts-nocheck
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', 'UA-139582634-1');
document.addEventListener('click', (e) => {
let trackEl = e.target;
if (!trackEl.getAttribute('ga-category')) {
trackEl = trackEl.closest('[ga-category]');
}
if (!trackEl) {
return;
}
const category = trackEl.getAttribute('ga-category');
const action = trackEl.getAttribute('ga-action');
const label = trackEl.getAttribute('ga-label');
if (!category) {
return;
}
window.fireEvent({
category,
action,
label,
});
});
</script>

Some files were not shown because too many files have changed in this diff Show More