-
-
Notifications
You must be signed in to change notification settings - Fork 94
/
Copy pathContent.tsx
121 lines (109 loc) · 2.95 KB
/
Content.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import React, { useEffect, useState } from "react";
import ReactMarkdown from "react-markdown";
import rehypeRaw from "rehype-raw";
import rehypeHighlight from "rehype-highlight";
import { useNavigate } from "react-router-dom";
import {
ContentContainer,
NavigationButtons,
NavigationButton,
} from "../styles/components/Content";
import {
LoadingOutlined,
LeftOutlined,
RightOutlined,
} from "@ant-design/icons";
import { Spin } from "antd";
import fetchContent from "../utils/fetchContent";
import { steps } from "../constants/learningSteps/steps";
import { LearnContentProps } from "../types/components/Content.types";
// markdown syntax highlighting theme
import "highlight.js/styles/github.css";
const LearnContent: React.FC<LearnContentProps> = ({ file }) => {
const [content, setContent] = useState<string | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const navigate = useNavigate();
useEffect(() => {
const loadContent = async (): Promise<void> => {
try {
setLoading(true);
const content = await fetchContent(file);
setContent(content);
setError(null);
} catch (err: unknown) {
setError("Failed to load content");
} finally {
setLoading(false);
}
};
void loadContent();
}, [file]);
const currentIndex = steps.findIndex((step) =>
step.link.includes(file.split(".")[0])
);
const handlePrevious = () => {
if (currentIndex > 0) {
navigate(steps[currentIndex - 1].link);
}
};
const handleNext = () => {
if (currentIndex < steps.length - 1) {
navigate(steps[currentIndex + 1].link);
}
};
if (loading) {
return (
<div
style={{
flex: 1,
display: "flex",
justifyContent: "center",
alignItems: "center",
}}
>
<Spin
indicator={
<LoadingOutlined style={{ fontSize: 42, color: "#19c6c7" }} spin />
}
/>
</div>
);
}
if (error) {
return <div>Error: {error}</div>;
}
return (
<ContentContainer>
{content && (
<ReactMarkdown
rehypePlugins={[rehypeRaw, rehypeHighlight]}
components={{
img: ({ ...props }) => (
<div className="image-container">
<img {...props} alt={props.alt || ""} />
</div>
),
}}
>
{content}
</ReactMarkdown>
)}
<NavigationButtons>
<NavigationButton
onClick={handlePrevious}
disabled={currentIndex === 0}
>
<LeftOutlined /> Previous
</NavigationButton>
<NavigationButton
onClick={handleNext}
disabled={currentIndex === steps.length - 1}
>
Next <RightOutlined />
</NavigationButton>
</NavigationButtons>
</ContentContainer>
);
};
export default LearnContent;