Skip to content

Commit 4d82f9e

Browse files
committed
feat: introduce intro to ethereum track
1 parent 962781d commit 4d82f9e

File tree

7 files changed

+745
-4
lines changed

7 files changed

+745
-4
lines changed

src/contexts/AppContext.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
import { type Project, type Fundamental } from "@/interfaces";
1+
import { type Project, type Fundamental, type EthIntro } from "@/interfaces";
22
import { createContext, useContext } from "react";
33

44
interface IAppContext {
55
completedQuizzesIds: string[];
66
projects: Project[];
77
fundamentals: Fundamental[];
8+
ethIntro: EthIntro[];
89
allLessonsData: any[];
910
refetchCompletedQuizzesAll?: () => Promise<any>;
1011
}
@@ -13,6 +14,7 @@ export const AppContext = createContext<IAppContext>({
1314
completedQuizzesIds: [],
1415
projects: [],
1516
fundamentals: [],
17+
ethIntro: [],
1618
allLessonsData: [],
1719
refetchCompletedQuizzesAll: () => Promise.resolve(),
1820
});

src/contexts/AppContextProvider.tsx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { AppContext } from "./AppContext";
88
import {
99
type Project,
1010
type Fundamental,
11+
type EthIntro,
1112
type IFormatedLessons,
1213
} from "@/interfaces";
1314
import { useSession } from "next-auth/react";
@@ -21,6 +22,7 @@ interface IProps {
2122
export function AppContextProvider({ children }: IProps) {
2223
const [fundamentals, setFundamentals] = useState<Fundamental[]>([]);
2324
const [projects, setProjects] = useState<Project[]>([]);
25+
const [ethIntro, setEthIntro] = useState<EthIntro[]>([]);
2426
const [completedQuizzesIds, setCompletedQuizzesIds] = useState<string[]>([]);
2527
const [sessionDataUser, setSessionDataUser] = useState<any>(null);
2628

@@ -86,6 +88,7 @@ export function AppContextProvider({ children }: IProps) {
8688

8789
setFundamentals(lessonsFormatResult.fundamentals);
8890
setProjects(lessonsFormatResult.projects);
91+
setEthIntro(lessonsFormatResult.ethIntro);
8992
};
9093

9194
useEffect(() => {
@@ -97,6 +100,31 @@ export function AppContextProvider({ children }: IProps) {
97100
refetchOnWindowFocus: false,
98101
});
99102

103+
useEffect(() => {
104+
if (allLessonsData && ethIntro && completedQuizzesIds.length !== 0) {
105+
const lessonsWithCompleteStatus = ethIntro.map((lesson) => {
106+
const currentLessonId = allLessonsData.find(
107+
(lessonData) =>
108+
lessonData.projectLessonNumber?.toString() ===
109+
lesson.slug.toString(), // DEV_NOTE: forcing .toString() to avoid type errors
110+
)?.id;
111+
112+
const completed = currentLessonId
113+
? completedQuizzesIds.includes(currentLessonId)
114+
: false; // DEV_NOTE: if the lesson is not found, it is not completed
115+
return { ...lesson, completed };
116+
});
117+
118+
setEthIntro(lessonsWithCompleteStatus);
119+
} else if (allLessonsData && ethIntro && completedQuizzesIds.length === 0) {
120+
const lessonsWithCompleteStatus = ethIntro.map((lesson) => {
121+
return { ...lesson, completed: false };
122+
});
123+
setEthIntro(lessonsWithCompleteStatus);
124+
}
125+
// eslint-disable-next-line react-hooks/exhaustive-deps
126+
}, [completedQuizzesIds]);
127+
100128
useEffect(() => {
101129
if (allLessonsData && projects && completedQuizzesIds.length !== 0) {
102130
const projectsWithCompleteStatus = projects.map((lesson) => {
@@ -157,6 +185,7 @@ export function AppContextProvider({ children }: IProps) {
157185
completedQuizzesIds,
158186
projects,
159187
fundamentals,
188+
ethIntro,
160189
allLessonsData: allLessonsData || [],
161190
refetchCompletedQuizzesAll,
162191
}}

src/interfaces/index.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export interface Lessons {
1515
export interface IFormatedLessons {
1616
projects: Project[];
1717
fundamentals: Fundamental[];
18+
ethIntro: EthIntro[];
1819
}
1920

2021
export interface Fundamental {
@@ -43,6 +44,13 @@ export interface Project {
4344
completed?: boolean;
4445
}
4546

47+
export interface EthIntro {
48+
path: string;
49+
frontMatter: ProjectFrontMatter;
50+
slug: string;
51+
completed?: boolean;
52+
}
53+
4654
export interface ProjectFrontMatter {
4755
title: string;
4856
description: string;

src/pages/getting-started.tsx

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import type { Lessons, Lesson } from "@/interfaces";
2424
import { useAppContext } from "@/contexts/AppContext";
2525

2626
const GettingStartedPage: NextPageWithLayout<Lessons> = () => {
27-
const { projects, fundamentals } = useAppContext();
27+
const { ethIntro, projects, fundamentals } = useAppContext();
2828
const [isMobile] = useMediaQuery("(max-width: 768px)", {
2929
ssr: true,
3030
fallback: true, // return false on the server, and re-evaluate on the client side
@@ -76,7 +76,55 @@ const GettingStartedPage: NextPageWithLayout<Lessons> = () => {
7676
</Heading>
7777
<UnorderedList listStyleType="none" textAlign="center" as="div">
7878
<Heading size="md" color="yellow.300">
79-
{`PROJECTS`}
79+
{`INTRO TO ETHEREUM`}
80+
</Heading>
81+
<>
82+
{ethIntro.map((lesson: Lesson, idx: number) => (
83+
<ListItem key={idx} my="2" py="2" maxW="40vw" margin="0 auto">
84+
<Link
85+
as={NextLink}
86+
href={`/lessons/${lesson.path}/${lesson.slug}`}
87+
passHref
88+
>
89+
<Button
90+
height="auto"
91+
style={{
92+
whiteSpace: "normal",
93+
wordWrap: "break-word",
94+
padding: "0.5rem",
95+
width: "100%",
96+
fontSize: "xl",
97+
}}
98+
>
99+
<Flex direction={!isMobile ? "row" : "column"}>
100+
<Box>{lesson.frontMatter.title}</Box>
101+
<Box>
102+
{lesson &&
103+
lesson.completed &&
104+
lesson.completed === true ? (
105+
<>
106+
<Badge
107+
ml="1"
108+
alignItems={"flex-end"}
109+
colorScheme="green"
110+
position={!isMobile ? "absolute" : "relative"}
111+
right={3}
112+
>
113+
Completed
114+
</Badge>
115+
</>
116+
) : null}
117+
</Box>
118+
</Flex>
119+
</Button>
120+
</Link>
121+
</ListItem>
122+
))}
123+
</>
124+
</UnorderedList>
125+
<UnorderedList listStyleType="none" textAlign="center" as="div">
126+
<Heading size="md" color="yellow.300">
127+
{`PROJECT: BUILD AN NFT COLLECTION`}
80128
</Heading>
81129
<>
82130
{projects.map((lesson: Lesson, idx: number) => (

0 commit comments

Comments
 (0)