Skip to content

Commit d4f174b

Browse files
committed
rename study plan to roadmap
1 parent bd34d64 commit d4f174b

File tree

19 files changed

+129
-66
lines changed

19 files changed

+129
-66
lines changed

.github/ISSUE_TEMPLATE/bug.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: Bug report
33
about: Create a report to help us improve
44
title: '[Bug]: ...'
55
labels: bug
6-
assignees: markmead
6+
assignees: jsartisan
77
---
88

99
**Describe the bug**

.github/ISSUE_TEMPLATE/feedback.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
---
2+
name: Feedback
3+
about: Provide feedback on the site
4+
title: '[Feedback]: ...'
5+
labels: feedback
6+
assignees: jsartisan
7+
---
8+
9+
### 💡 Site Feedback
10+
11+
**Your Feedback**
12+
Please provide your thoughts, ideas, or suggestions to improve the site.
13+
14+
**What did you like?**
15+
Tell us what you liked about the site!
16+
17+
**What could be improved?**
18+
Share any areas you think could be improved or enhanced.
19+
20+
**Additional context**
21+
Add any other comments or suggestions, such as features you'd like to see or changes that would improve the user experience.

packages/backend/src/db/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ export * from "./challenges";
22
export * from "./templates";
33
export * from "./locales";
44
export * from "./fs";
5-
export * from "./study-plans";
5+
export * from "./roadmaps";
66
export * from "./blogs";

packages/backend/src/db/study-plans.ts renamed to packages/backend/src/db/roadmaps.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
import fs from "fs";
22
import path from "path";
33
import YAML from "js-yaml";
4-
import { DEFAULT_LOCALE, STUDY_PLANS_ROOT, StudyPlan, StudyPlanInfo } from "@frontend-challenges/shared";
4+
import { DEFAULT_LOCALE, STUDY_PLANS_ROOT, Roadmap, RoadmapInfo } from "@frontend-challenges/shared";
55

66
import { getLocaleVariations } from "./locales";
77
import { getChallengeByPath } from "./challenges";
88

9-
export async function getStudyPlans(): Promise<StudyPlan[]> {
9+
export async function getRoadmaps(): Promise<Roadmap[]> {
1010
const folders = fs.readdirSync(STUDY_PLANS_ROOT);
1111

12-
const studyPlans = await Promise.all(folders.map(async (dir: string) => getStudyPlanByPath(dir)));
12+
const studyPlans = await Promise.all(folders.map(async (dir: string) => getRoadmapByPath(dir)));
1313

1414
return studyPlans;
1515
}
1616

17-
export async function getStudyPlanByPath(dir: string): Promise<StudyPlan> {
18-
const info = await getLocaleVariations(path.join(STUDY_PLANS_ROOT, dir, "info.yml"), [parseStudyPlan]);
17+
export async function getRoadmapByPath(dir: string): Promise<Roadmap> {
18+
const info = await getLocaleVariations(path.join(STUDY_PLANS_ROOT, dir, "info.yml"), [parseRoadmap]);
1919

2020
if (!info) {
21-
throw new Error(`Study plan not found: ${dir}`);
21+
throw new Error(`Roadmap not found: ${dir}`);
2222
}
2323

2424
const topics = await Promise.all(
@@ -39,7 +39,7 @@ export async function getStudyPlanByPath(dir: string): Promise<StudyPlan> {
3939
return { title: info[DEFAULT_LOCALE].title, topics, path: dir, info };
4040
}
4141

42-
export function parseStudyPlan(s: string): StudyPlanInfo {
42+
export function parseRoadmap(s: string): RoadmapInfo {
4343
const object = YAML.load(s) as any;
4444

4545
const arrayKeys = ["tags", "related"];

packages/shared/src/constants.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export const IS_WEBSITE_ROOT = ROOT_PATH.endsWith("website");
66

77
export const CONTENT_PATH = "./content";
88
export const CHALLENGES_ROOT = IS_WEBSITE_ROOT ? "../../challenges" : "./challenges";
9-
export const STUDY_PLANS_ROOT = IS_WEBSITE_ROOT ? "../../study-plans" : "./study-plans";
9+
export const STUDY_PLANS_ROOT = IS_WEBSITE_ROOT ? "../../roadmaps" : "./roadmaps";
1010

1111
export const REPO = "https://github.com/jsartisan/frontend-challenges";
1212
export const REPO_API = "https://api.github.com/repos/jsartisan/frontend-challenges";

packages/shared/src/types/index.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,17 +85,17 @@ export type Blog = {
8585

8686
export type Category = (typeof CATEGORIES)[number];
8787

88-
export type StudyPlan = {
88+
export type Roadmap = {
8989
title: string;
9090
path?: string;
9191
topics: {
9292
title: string;
9393
challenges: Challenge[];
9494
}[];
95-
info: Record<string, DeepPartial<StudyPlanInfo> | undefined>;
95+
info: Record<string, DeepPartial<RoadmapInfo> | undefined>;
9696
};
9797

98-
export type StudyPlanInfo = {
98+
export type RoadmapInfo = {
9999
title: string;
100100
description: string;
101101
topics: {

packages/website/app/challenges/[slug]/Question.tsx

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,15 @@ function QuestionChallenge(props: QuestionProps) {
4949
const { question, challenges } = props;
5050
const [template, setTemplate] = useState(Object.keys(question.templateFiles)[0] as SupportedTemplates);
5151
const savedChallengeFiles = useLocalStorageChallengeFiles(`/challenges/${question.path}-${template}`);
52+
const [files, setFiles] = useState({
53+
...TEMPLATES[template].files,
54+
...question.templateFiles[template],
55+
...savedChallengeFiles,
56+
});
5257

5358
return (
5459
<>
55-
<SandpackRoot
56-
files={{
57-
...TEMPLATES[template].files,
58-
...question.templateFiles[template],
59-
...savedChallengeFiles,
60-
}}
61-
>
60+
<SandpackRoot files={files}>
6261
<div className="flex h-full w-full flex-col gap-4 p-4">
6362
<div className="relative flex w-full justify-between">
6463
<Breadcrumb currentChallenge={question} challenges={challenges} />
@@ -99,6 +98,13 @@ function QuestionChallenge(props: QuestionProps) {
9998
exclude={["/package.json"]}
10099
className="min-h-0"
101100
template={template}
101+
onResetFiles={() => {
102+
setFiles({
103+
...TEMPLATES[template].files,
104+
...question.templateFiles[template],
105+
});
106+
localStorage.removeItem(`/challenges/${question.path}-${template}`);
107+
}}
102108
/>
103109
<Preview className="min-h-0" template={template} />
104110
<Console />

packages/website/app/play/client.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ export default function Client() {
103103
<CodeEditor
104104
path="/playground"
105105
template={template}
106-
resetFiles={() => {
106+
onResetFiles={() => {
107107
setFiles(TEMPLATES[template].files);
108108
localStorage.removeItem(`/playground-${template}`);
109109
}}

packages/website/app/study-plans/[slug]/page.tsx renamed to packages/website/app/roadmaps/[slug]/page.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,41 @@
11
import { Metadata } from "next";
22
import { DOMAIN } from "@frontend-challenges/shared";
3-
import { getStudyPlanByPath, getStudyPlans } from "@frontend-challenges/backend";
3+
import { getRoadmapByPath, getRoadmaps } from "@frontend-challenges/backend";
44

55
import Footer from "../../../components/layout/Footer";
66
import { Layout } from "../../../components/layout/Layout";
77
import { ChallengeList } from "../../../components/challenges/ChallengeList";
88

99
export async function generateMetadata(props: any): Promise<Metadata> {
10-
const question = await getStudyPlanByPath(props.params.slug);
10+
const question = await getRoadmapByPath(props.params.slug);
1111

1212
return {
13-
title: `${question.info?.en?.title} Study Plan | Frontend Challenges`,
13+
title: `${question.info?.en?.title} Roadmap | Frontend Challenges`,
1414
openGraph: {
15-
url: `${DOMAIN}/study-plans/${question.path}`,
15+
url: `${DOMAIN}/roadmaps/${question.path}`,
1616
images: "/og.png",
1717
},
1818
};
1919
}
2020

2121
export async function generateStaticParams() {
22-
const studyPlans = await getStudyPlans();
22+
const studyPlans = await getRoadmaps();
2323

2424
return studyPlans.map((studyPlan) => ({
2525
slug: studyPlan.path,
2626
}));
2727
}
2828

2929
export default async function Page(props: any) {
30-
const studyPlan = await getStudyPlanByPath(props.params.slug);
30+
const studyPlan = await getRoadmapByPath(props.params.slug);
3131

3232
return (
3333
<>
3434
<Layout className="pb-12 pt-8">
3535
<div className="text-3xl font-bold">{studyPlan.title}</div>
3636
<div className="w-full pb-6 pt-3 leading-relaxed text-gray-500 md:w-2/4">
37-
Study Plans are a collection of topics and challenges designed to help you learn a specific topic. It starts
38-
with the basics and progresses to more advanced topics.
37+
Roadmap are a collection of topics and challenges designed to help you learn a specific topic. It starts with
38+
the basics and progresses to more advanced topics.
3939
</div>
4040
<div className="flex flex-col gap-3">
4141
{studyPlan.topics.map((topic) => {
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { getRoadmaps } from "@frontend-challenges/backend";
2+
3+
import Footer from "../../components/layout/Footer";
4+
import { Layout } from "../../components/layout/Layout";
5+
import { RoadmapListItem } from "../../components/roadmaps/RoadmapListItem";
6+
7+
export default async function Page() {
8+
const roadmaps = await getRoadmaps();
9+
10+
return (
11+
<>
12+
<Layout className="pb-12 pt-8">
13+
<div className="text-3xl font-bold">Roadmaps</div>
14+
<div className="w-full pb-6 pt-3 leading-relaxed text-gray-500 md:w-3/4">
15+
Roadmaps are a collection of challenges and quizzes that are designed to help you learn a specific language,
16+
framework, or topic. Each Roadmaps is curated by the community and is designed to help you learn a specific
17+
topic from scratch.
18+
</div>
19+
{roadmaps.map((roadmap) => {
20+
return <RoadmapListItem studyPlan={roadmap} key={`roadmap-${roadmap.title}`} />;
21+
})}
22+
</Layout>
23+
24+
<Footer />
25+
</>
26+
);
27+
}

packages/website/app/study-plans/page.tsx

Lines changed: 0 additions & 27 deletions
This file was deleted.

packages/website/components/common/SubmissionNavigator.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
DropdownMenu,
77
DropdownMenuContent,
88
DropdownMenuItem,
9+
DropdownMenuSeparator,
910
DropdownMenuTrigger,
1011
} from "../../components/ui/dropdown-menu";
1112
import { Badge, Button, Icon } from "../ui";
@@ -44,6 +45,19 @@ export function SubmissionNavigator() {
4445
</div>
4546
</div>
4647
</DropdownMenuItem>
48+
<DropdownMenuSeparator />
49+
<DropdownMenuItem className="text-center">
50+
<a
51+
href="https://github.com/jsartisan/frontend-challenges/issues/new?assignees=jsartisan&labels=bug&projects=&template=bug.md&title=%5BBug%5D%3A+..."
52+
target="_blank"
53+
rel="noreferrer"
54+
aria-label="Report a bug"
55+
className="flex w-full items-center justify-center gap-2 text-center "
56+
>
57+
<Icon name="bug" size="sm" />
58+
Report a bug
59+
</a>
60+
</DropdownMenuItem>
4761
</DropdownMenuContent>
4862
</DropdownMenu>
4963
);

packages/website/components/editor/CodeEditor.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ type Props = {
2727
exclude?: string[];
2828
path?: string;
2929
template: SupportedTemplates;
30-
resetFiles?: () => void;
30+
onResetFiles?: () => void;
3131
};
3232

3333
export function CodeEditor(props: Props) {
34-
const { className, showTabs = true, exclude, path, template, onChange, resetFiles } = props;
34+
const { className, showTabs = true, exclude, path, template, onChange, onResetFiles } = props;
3535
const { sandpack } = useSandpack();
3636
const [loading, setLoading] = useState(true);
3737
const { setActiveFile, activeFile, files } = sandpack;
@@ -245,7 +245,7 @@ export function CodeEditor(props: Props) {
245245
</DropdownMenuTrigger>
246246
<DropdownMenuContent align="end">
247247
<DropdownMenuItem
248-
onClick={typeof resetFiles === "function" ? resetFiles : () => {}}
248+
onClick={typeof onResetFiles === "function" ? onResetFiles : () => {}}
249249
className="flex-col items-start"
250250
>
251251
<div>Reset Files</div>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import React, { ComponentProps } from "react";
2+
3+
export function BugIcon(props: ComponentProps<"svg">) {
4+
return (
5+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-0.75 -0.75 24 24" {...props}>
6+
<path
7+
fill="none"
8+
stroke="currentcolor"
9+
strokeLinecap="round"
10+
strokeLinejoin="round"
11+
strokeWidth="1.5"
12+
d="M3.516 13.404a7.734 7.734 0 1015.468 0 7.734 7.734 0 10-15.468 0zM4.367 9.889h13.766M11.25 9.889v11.25M4.024 10.642a4.898 4.898 0 00-2.618-.75M1.406 19.732a4.912 4.912 0 003.68-1.654M1.406 14.107h2.142M18.476 10.642a4.898 4.898 0 012.618-.75M21.094 19.732a4.912 4.912 0 01-3.68-1.654M21.094 14.107h-2.142M5.588 1.406c0 2.754.213 3.776 2.519 4.93M16.838 1.406c0 2.754-.214 3.776-2.52 4.93"
13+
></path>
14+
</svg>
15+
);
16+
}

packages/website/components/icons/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,4 @@ export { ChevronRightIcon } from "./ChevronRightIcon";
3535
export { VerticalDotsIcon } from "./VerticalDotsIcon";
3636
export { LinkedinIcon } from "./LinkedinIcon";
3737
export { XIcon } from "./XIcon";
38+
export { BugIcon } from "./BugIcon";

packages/website/components/layout/Header.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,14 @@ export async function Header(props: HeaderProps) {
4949
<Link href="/challenges" className="font-medium">
5050
Challenges
5151
</Link>
52-
<Link href="/study-plans" className="font-medium">
52+
<Link href="/roadmaps" className="font-medium">
5353
Roadmaps
5454
</Link>
5555
<Link href="/play" className="font-medium">
5656
Playground
5757
</Link>
5858
<Link
59-
href="https://frontend-challenges.canny.io/feature-requests"
59+
href="https://github.com/jsartisan/frontend-challenges/issues/new?assignees=jsartisan&labels=feedback&template=feedback.md&title=%5BFeedback%5D%3A+..."
6060
target="_blank"
6161
className="flex items-center gap-1 font-medium"
6262
>

packages/website/components/study-plans/StudyPlanListItem.tsx renamed to packages/website/components/roadmaps/RoadmapListItem.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { StudyPlan } from "@frontend-challenges/shared";
1+
import { Roadmap } from "@frontend-challenges/shared";
22

33
import { Card, Link } from "../ui";
44

5-
function StudyPlanListItem(props: { studyPlan: StudyPlan }) {
5+
function RoadmapListItem(props: { studyPlan: Roadmap }) {
66
const { studyPlan } = props;
77

88
return (
@@ -12,7 +12,7 @@ function StudyPlanListItem(props: { studyPlan: StudyPlan }) {
1212
<div className="flex items-center space-x-2">
1313
<Link
1414
className="text-base font-medium text-[var(--color-fg-accent)] hover:underline"
15-
href={`/study-plans/${studyPlan.path}`}
15+
href={`/roadmaps/${studyPlan.path}`}
1616
>
1717
{studyPlan.info.en?.title}
1818
</Link>
@@ -24,4 +24,4 @@ function StudyPlanListItem(props: { studyPlan: StudyPlan }) {
2424
);
2525
}
2626

27-
export { StudyPlanListItem };
27+
export { RoadmapListItem };

0 commit comments

Comments
 (0)