Skip to content

Commit b86d6a7

Browse files
Merge pull request #129 from kamranahmedse/master
Create a new pull request by comparing changes across two branches
2 parents 7f6e7c5 + 4e96a58 commit b86d6a7

File tree

76 files changed

+5193
-220
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+5193
-220
lines changed

.astro/settings.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"devToolbar": {
3+
"enabled": false
4+
}
5+
}

astro.config.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export default defineConfig({
2929
'mailto:',
3030
'https://github.com/kamranahmedse',
3131
'https://thenewstack.io',
32-
'https://cs.fyi',
32+
'https://kamranahmed.info',
3333
'https://roadmap.sh',
3434
];
3535
if (whiteListedStarts.some((start) => href.startsWith(start))) {
1.26 MB
Loading
305 KB
Loading
62.3 KB
Binary file not shown.

readme.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,9 @@ Here is the list of available roadmaps with more being actively worked upon.
7474

7575
There are also interactive best practices:
7676

77-
- [Code Review Best Practices](https://roadmap.sh/best-practices/code-review)
77+
- [Backend Performance Best Practices](https://roadmap.sh/best-practices/backend-performance)
7878
- [Frontend Performance Best Practices](https://roadmap.sh/best-practices/frontend-performance)
79+
- [Code Review Best Practices](https://roadmap.sh/best-practices/code-review)
7980
- [API Security Best Practices](https://roadmap.sh/best-practices/api-security)
8081
- [AWS Best Practices](https://roadmap.sh/best-practices/aws)
8182

scripts/best-practice-content.cjs

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,7 @@ const path = require('path');
44
const OPEN_AI_API_KEY = process.env.OPEN_AI_API_KEY;
55
const ALL_BEST_PRACTICES_DIR = path.join(
66
__dirname,
7-
'../src/data/best-practices'
8-
);
9-
const BEST_PRACTICE_JSON_DIR = path.join(
10-
__dirname,
11-
'../public/jsons/best-practices'
7+
'../src/data/best-practices',
128
);
139

1410
const bestPracticeId = process.argv[2];
@@ -29,15 +25,14 @@ if (!allowedBestPracticeIds.includes(bestPracticeId)) {
2925
const BEST_PRACTICE_CONTENT_DIR = path.join(
3026
ALL_BEST_PRACTICES_DIR,
3127
bestPracticeId,
32-
'content'
28+
'content',
3329
);
34-
const { Configuration, OpenAIApi } = require('openai');
35-
const configuration = new Configuration({
30+
const OpenAI = require('openai');
31+
32+
const openai = new OpenAI({
3633
apiKey: OPEN_AI_API_KEY,
3734
});
3835

39-
const openai = new OpenAIApi(configuration);
40-
4136
function getFilesInFolder(folderPath, fileList = {}) {
4237
const files = fs.readdirSync(folderPath);
4338

@@ -62,13 +57,19 @@ function getFilesInFolder(folderPath, fileList = {}) {
6257
}
6358

6459
function writeTopicContent(topicTitle) {
65-
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.`;
60+
let prompt = `I will give you a topic and you need to write a brief paragraph with examples (if possible) about why it is important for the "${bestPracticeTitle}". Just reply to the question without adding any other information about the prompt and use simple language. Also do not start your sentences with "XYZ is important because..". Your format should be as follows:
61+
62+
# (Put a heading for the topic)
63+
64+
(Write a brief paragraph about why it is important for the "${bestPracticeTitle})
65+
66+
First topic is: ${topicTitle}`;
6667

6768
console.log(`Generating '${topicTitle}'...`);
6869

6970
return new Promise((resolve, reject) => {
70-
openai
71-
.createChatCompletion({
71+
openai.chat.completions
72+
.create({
7273
model: 'gpt-4',
7374
messages: [
7475
{
@@ -78,7 +79,7 @@ function writeTopicContent(topicTitle) {
7879
],
7980
})
8081
.then((response) => {
81-
const article = response.data.choices[0].message.content;
82+
const article = response.choices[0].message.content;
8283

8384
resolve(article);
8485
})
@@ -90,9 +91,12 @@ function writeTopicContent(topicTitle) {
9091

9192
async function writeFileForGroup(group, topicUrlToPathMapping) {
9293
const topicId = group?.properties?.controlName;
93-
const topicTitle = group?.children?.controls?.control?.find(
94-
(control) => control?.typeID === 'Label'
95-
)?.properties?.text;
94+
const topicTitle = group?.children?.controls?.control
95+
?.filter((control) => control?.typeID === 'Label')
96+
.map((control) => control?.properties?.text)
97+
.join(' ')
98+
.toLowerCase();
99+
96100
const currTopicUrl = `/${topicId}`;
97101
if (currTopicUrl.startsWith('/check:')) {
98102
return;
@@ -102,7 +106,6 @@ async function writeFileForGroup(group, topicUrlToPathMapping) {
102106

103107
if (!contentFilePath) {
104108
console.log(`Missing file for: ${currTopicUrl}`);
105-
process.exit(0);
106109
return;
107110
}
108111

@@ -123,8 +126,13 @@ async function writeFileForGroup(group, topicUrlToPathMapping) {
123126
return;
124127
}
125128

129+
if (!topicTitle) {
130+
console.log(`Skipping ${topicId}. No title.`);
131+
return;
132+
}
133+
126134
const topicContent = await writeTopicContent(topicTitle);
127-
newFileContent += `\n\n${topicContent}`;
135+
newFileContent = `${topicContent}`;
128136

129137
console.log(`Writing ${topicId}..`);
130138
fs.writeFileSync(contentFilePath, newFileContent, 'utf8');
@@ -138,14 +146,14 @@ async function writeFileForGroup(group, topicUrlToPathMapping) {
138146
async function run() {
139147
const topicUrlToPathMapping = getFilesInFolder(BEST_PRACTICE_CONTENT_DIR);
140148

141-
const bestPracticeJson = require(path.join(
142-
BEST_PRACTICE_JSON_DIR,
143-
`${bestPracticeId}.json`
144-
));
149+
const bestPracticeJson = require(
150+
path.join(ALL_BEST_PRACTICES_DIR, `${bestPracticeId}/${bestPracticeId}`),
151+
);
152+
145153
const groups = bestPracticeJson?.mockup?.controls?.control?.filter(
146154
(control) =>
147155
control.typeID === '__group__' &&
148-
!control.properties?.controlName?.startsWith('ext_link')
156+
!control.properties?.controlName?.startsWith('ext_link'),
149157
);
150158

151159
if (!OPEN_AI_API_KEY) {

scripts/best-practice-dirs.cjs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const CONTENT_DIR = path.join(__dirname, '../content');
55
// Directory containing the best-practices
66
const BEST_PRACTICE_CONTENT_DIR = path.join(
77
__dirname,
8-
'../src/data/best-practices'
8+
'../src/data/best-practices',
99
);
1010
const bestPracticeId = process.argv[2];
1111

@@ -33,18 +33,18 @@ if (!bestPracticeDirName) {
3333

3434
const bestPracticeDirPath = path.join(
3535
BEST_PRACTICE_CONTENT_DIR,
36-
bestPracticeDirName
36+
bestPracticeDirName,
3737
);
3838
const bestPracticeContentDirPath = path.join(
3939
BEST_PRACTICE_CONTENT_DIR,
4040
bestPracticeDirName,
41-
'content'
41+
'content',
4242
);
4343

4444
// If best practice content already exists do not proceed as it would override the files
4545
if (fs.existsSync(bestPracticeContentDirPath)) {
4646
console.error(
47-
`Best Practice content already exists @ ${bestPracticeContentDirPath}`
47+
`Best Practice content already exists @ ${bestPracticeContentDirPath}`,
4848
);
4949
process.exit(1);
5050
}
@@ -88,10 +88,12 @@ function prepareDirTree(control, dirTree) {
8888
return { dirTree };
8989
}
9090

91-
const bestPractice = require(path.join(
92-
__dirname,
93-
`../public/jsons/best-practices/${bestPracticeId}`
94-
));
91+
const bestPractice = require(
92+
path.join(
93+
__dirname,
94+
`../src/data/best-practices/${bestPracticeId}/${bestPracticeId}`,
95+
),
96+
);
9597
const controls = bestPractice.mockup.controls.control;
9698

9799
// Prepare the dir tree that we will be creating

src/components/Activity/ActivityPage.tsx

Lines changed: 59 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ export function ActivityPage() {
5252

5353
async function loadActivity() {
5454
const { error, response } = await httpGet<ActivityResponse>(
55-
`${import.meta.env.PUBLIC_API_URL}/v1-get-user-stats`
55+
`${import.meta.env.PUBLIC_API_URL}/v1-get-user-stats`,
5656
);
5757

5858
if (!response || error) {
@@ -79,6 +79,25 @@ export function ActivityPage() {
7979
return null;
8080
}
8181

82+
const learningRoadmapsToShow = learningRoadmaps
83+
.sort((a, b) => {
84+
const updatedAtA = new Date(a.updatedAt);
85+
const updatedAtB = new Date(b.updatedAt);
86+
87+
return updatedAtB.getTime() - updatedAtA.getTime();
88+
})
89+
.filter((roadmap) => roadmap.learning > 0 || roadmap.done > 0);
90+
91+
const learningBestPracticesToShow = learningBestPractices
92+
.sort((a, b) => {
93+
const updatedAtA = new Date(a.updatedAt);
94+
const updatedAtB = new Date(b.updatedAt);
95+
96+
return updatedAtB.getTime() - updatedAtA.getTime();
97+
})
98+
.filter((bestPractice) => bestPractice.learning > 0 || bestPractice.done > 0);
99+
100+
82101
return (
83102
<>
84103
<ActivityCounters
@@ -88,10 +107,10 @@ export function ActivityPage() {
88107
/>
89108

90109
<div className="mx-0 px-0 py-5 md:-mx-10 md:px-8 md:py-8">
91-
{learningRoadmaps.length === 0 &&
92-
learningBestPractices.length === 0 && <EmptyActivity />}
110+
{learningRoadmapsToShow.length === 0 &&
111+
learningBestPracticesToShow.length === 0 && <EmptyActivity />}
93112

94-
{(learningRoadmaps.length > 0 || learningBestPractices.length > 0) && (
113+
{(learningRoadmapsToShow.length > 0 || learningBestPracticesToShow.length > 0) && (
95114
<>
96115
<h2 className="mb-3 text-xs uppercase text-gray-400">
97116
Continue Following
@@ -104,26 +123,38 @@ export function ActivityPage() {
104123

105124
return updatedAtB.getTime() - updatedAtA.getTime();
106125
})
107-
.map((roadmap) => (
108-
<ResourceProgress
109-
key={roadmap.id}
110-
isCustomResource={roadmap.isCustomResource}
111-
doneCount={roadmap.done || 0}
112-
learningCount={roadmap.learning || 0}
113-
totalCount={roadmap.total || 0}
114-
skippedCount={roadmap.skipped || 0}
115-
resourceId={roadmap.id}
116-
resourceType={'roadmap'}
117-
updatedAt={roadmap.updatedAt}
118-
title={roadmap.title}
119-
onCleared={() => {
120-
pageProgressMessage.set('Updating activity');
121-
loadActivity().finally(() => {
122-
pageProgressMessage.set('');
123-
});
124-
}}
125-
/>
126-
))}
126+
.filter((roadmap) => roadmap.learning > 0 || roadmap.done > 0)
127+
.map((roadmap) => {
128+
const learningCount = roadmap.learning || 0;
129+
const doneCount = roadmap.done || 0;
130+
const totalCount = roadmap.total || 0;
131+
const skippedCount = roadmap.skipped || 0;
132+
133+
return (
134+
<ResourceProgress
135+
key={roadmap.id}
136+
isCustomResource={roadmap.isCustomResource}
137+
doneCount={
138+
doneCount > totalCount ? totalCount : doneCount
139+
}
140+
learningCount={
141+
learningCount > totalCount ? totalCount : learningCount
142+
}
143+
totalCount={totalCount}
144+
skippedCount={skippedCount}
145+
resourceId={roadmap.id}
146+
resourceType={'roadmap'}
147+
updatedAt={roadmap.updatedAt}
148+
title={roadmap.title}
149+
onCleared={() => {
150+
pageProgressMessage.set('Updating activity');
151+
loadActivity().finally(() => {
152+
pageProgressMessage.set('');
153+
});
154+
}}
155+
/>
156+
);
157+
})}
127158

128159
{learningBestPractices
129160
.sort((a, b) => {
@@ -132,6 +163,10 @@ export function ActivityPage() {
132163

133164
return updatedAtB.getTime() - updatedAtA.getTime();
134165
})
166+
.filter(
167+
(bestPractice) =>
168+
bestPractice.learning > 0 || bestPractice.done > 0,
169+
)
135170
.map((bestPractice) => (
136171
<ResourceProgress
137172
isCustomResource={bestPractice.isCustomResource}

src/components/FeaturedItems/FeaturedItem.astro

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,11 @@ const {
4848
{
4949
isNew && (
5050
<span class='absolute bottom-1.5 right-2 flex items-center rounded-br rounded-tl text-xs font-medium text-purple-300'>
51-
<span class='flex h-2 w-2'>
51+
<span class='mr-1.5 flex h-2 w-2'>
5252
<span class='absolute inline-flex h-2 w-2 animate-ping rounded-full bg-purple-400 opacity-75' />
5353
<span class='relative inline-flex h-2 w-2 rounded-full bg-purple-500' />
5454
</span>
55+
New
5556
</span>
5657
)
5758
}

0 commit comments

Comments
 (0)