@portosaur/theme 0.1.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +10 -3
- package/src/plugins/theme.mjs +2 -0
- package/theme/DocCategoryGeneratedIndexPage/index.jsx +4 -10
- package/theme/MDXComponents.jsx +1 -1
- package/theme/Root.jsx +1 -1
- package/theme/components/AboutSection/index.jsx +89 -249
- package/theme/components/ContactSection/index.jsx +72 -153
- package/theme/components/ExperienceSection/index.jsx +35 -106
- package/theme/components/HeroSection/index.jsx +64 -186
- package/theme/components/NavArrow/index.jsx +38 -55
- package/theme/components/NoteIndex/index.jsx +50 -116
- package/theme/components/Preview/components/FeedbackStates.jsx +45 -190
- package/theme/components/Preview/components/FileTabs.jsx +17 -24
- package/theme/components/Preview/components/PreviewContent.jsx +37 -62
- package/theme/components/Preview/components/PreviewHeader.jsx +146 -380
- package/theme/components/Preview/components/Triggers/Pv.jsx +50 -78
- package/theme/components/Preview/components/Triggers/SrcPv.jsx +16 -47
- package/theme/components/Preview/components/Triggers/index.jsx +2 -2
- package/theme/components/Preview/components/ViewerWindow.jsx +160 -268
- package/theme/components/Preview/index.jsx +3 -3
- package/theme/components/Preview/renderers/CodeRenderer.jsx +81 -109
- package/theme/components/Preview/renderers/ImageRenderer.jsx +30 -67
- package/theme/components/Preview/renderers/PdfRenderer.jsx +31 -52
- package/theme/components/Preview/renderers/WebRenderer.jsx +18 -32
- package/theme/components/Preview/state/index.jsx +46 -30
- package/theme/components/ProjectsSection/index.jsx +278 -573
- package/theme/components/SocialLinks/index.jsx +43 -55
- package/theme/components/Tooltip/index.jsx +28 -39
- package/theme/pages/index.jsx +23 -87
- package/theme/pages/notes.jsx +26 -104
- package/theme/pages/tasks.jsx +220 -903
|
@@ -4,6 +4,8 @@ import { FaQuestionCircle } from "react-icons/fa";
|
|
|
4
4
|
import useScrollReveal from "../../hooks/useScrollReveal";
|
|
5
5
|
import useBrokenLinks from "@docusaurus/useBrokenLinks";
|
|
6
6
|
import styles from "./styles.module.css";
|
|
7
|
+
|
|
8
|
+
// Sort so email links appear first in the contact grid
|
|
7
9
|
const sortEmail = (links) => {
|
|
8
10
|
return [...links].sort((a, b) => {
|
|
9
11
|
const isEmailA =
|
|
@@ -19,170 +21,87 @@ const sortEmail = (links) => {
|
|
|
19
21
|
return 0;
|
|
20
22
|
});
|
|
21
23
|
};
|
|
24
|
+
|
|
22
25
|
export default function ContactSection({ id, className }) {
|
|
23
26
|
const { siteConfig } = useDocusaurusContext();
|
|
24
27
|
const brokenLinks = useBrokenLinks();
|
|
28
|
+
|
|
25
29
|
if (id) {
|
|
26
30
|
brokenLinks.collectAnchor(id);
|
|
27
31
|
}
|
|
32
|
+
|
|
28
33
|
const { customFields } = siteConfig;
|
|
29
|
-
const socialLinksConfig = customFields.
|
|
30
|
-
|
|
34
|
+
const socialLinksConfig = customFields.socialSection || {};
|
|
35
|
+
|
|
36
|
+
if (socialLinksConfig.enable === false) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
|
|
31
40
|
let socialLinks = socialLinksConfig.links || [];
|
|
32
41
|
const displayHeading = socialLinksConfig.heading;
|
|
33
42
|
const displaySubheading = socialLinksConfig.subheading;
|
|
34
43
|
const [sectionRef, isVisible] = useScrollReveal();
|
|
44
|
+
|
|
35
45
|
socialLinks = sortEmail(socialLinks);
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
id
|
|
40
|
-
ref
|
|
41
|
-
className
|
|
42
|
-
role
|
|
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
|
-
social.name ||
|
|
97
|
-
""
|
|
98
|
-
).toLowerCase();
|
|
99
|
-
const iconData = iconMap[iconKey] || {};
|
|
100
|
-
const name = social.name;
|
|
101
|
-
const Icon = iconData.icon || FaQuestionCircle;
|
|
102
|
-
const iconColor =
|
|
103
|
-
iconData.color || "var(--ifm-color-primary)";
|
|
104
|
-
const desc = social.desc || `Connect with me on ${name}`;
|
|
105
|
-
const url = social.url;
|
|
106
|
-
return jsxDEV_7x81h0kn(
|
|
107
|
-
"a",
|
|
108
|
-
{
|
|
109
|
-
href: url,
|
|
110
|
-
target: "_blank",
|
|
111
|
-
rel: "noopener noreferrer",
|
|
112
|
-
className: styles.socialCard,
|
|
113
|
-
style: {
|
|
114
|
-
"--card-index": index,
|
|
115
|
-
"--icon-hover-color": iconColor,
|
|
116
|
-
},
|
|
117
|
-
"aria-label": `Connect with me on ${name}: ${desc}`,
|
|
118
|
-
role: "listitem",
|
|
119
|
-
children: [
|
|
120
|
-
Icon &&
|
|
121
|
-
jsxDEV_7x81h0kn(
|
|
122
|
-
"div",
|
|
123
|
-
{
|
|
124
|
-
className: styles.socialIcon,
|
|
125
|
-
children: jsxDEV_7x81h0kn(
|
|
126
|
-
Icon,
|
|
127
|
-
{ "aria-hidden": "true" },
|
|
128
|
-
undefined,
|
|
129
|
-
false,
|
|
130
|
-
undefined,
|
|
131
|
-
this,
|
|
132
|
-
),
|
|
133
|
-
},
|
|
134
|
-
undefined,
|
|
135
|
-
false,
|
|
136
|
-
undefined,
|
|
137
|
-
this,
|
|
138
|
-
),
|
|
139
|
-
jsxDEV_7x81h0kn(
|
|
140
|
-
"h3",
|
|
141
|
-
{ className: styles.socialTitle, children: name },
|
|
142
|
-
undefined,
|
|
143
|
-
false,
|
|
144
|
-
undefined,
|
|
145
|
-
this,
|
|
146
|
-
),
|
|
147
|
-
jsxDEV_7x81h0kn(
|
|
148
|
-
"p",
|
|
149
|
-
{ className: styles.socialDesc, children: desc },
|
|
150
|
-
undefined,
|
|
151
|
-
false,
|
|
152
|
-
undefined,
|
|
153
|
-
this,
|
|
154
|
-
),
|
|
155
|
-
],
|
|
156
|
-
},
|
|
157
|
-
name,
|
|
158
|
-
true,
|
|
159
|
-
undefined,
|
|
160
|
-
this,
|
|
161
|
-
);
|
|
162
|
-
}),
|
|
163
|
-
},
|
|
164
|
-
undefined,
|
|
165
|
-
false,
|
|
166
|
-
undefined,
|
|
167
|
-
this,
|
|
168
|
-
),
|
|
169
|
-
},
|
|
170
|
-
undefined,
|
|
171
|
-
false,
|
|
172
|
-
undefined,
|
|
173
|
-
this,
|
|
174
|
-
),
|
|
175
|
-
],
|
|
176
|
-
},
|
|
177
|
-
undefined,
|
|
178
|
-
true,
|
|
179
|
-
undefined,
|
|
180
|
-
this,
|
|
181
|
-
),
|
|
182
|
-
},
|
|
183
|
-
undefined,
|
|
184
|
-
false,
|
|
185
|
-
undefined,
|
|
186
|
-
this,
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<div
|
|
49
|
+
id={id}
|
|
50
|
+
ref={sectionRef}
|
|
51
|
+
className={`${styles.contactSection} ${isVisible ? "is-visible" : ""} ${className || ""}`}
|
|
52
|
+
role="region"
|
|
53
|
+
aria-label="Contact section"
|
|
54
|
+
>
|
|
55
|
+
<div className={styles.contactContainer}>
|
|
56
|
+
{/* Heading */}
|
|
57
|
+
<div className={styles.contactHeader}>
|
|
58
|
+
<h2 className={styles.contactTitle}>{displayHeading}</h2>
|
|
59
|
+
<p className={styles.contactSubtitle}>{displaySubheading}</p>
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
{/* Social cards grid */}
|
|
63
|
+
<div className={styles.gridWrapper}>
|
|
64
|
+
<div
|
|
65
|
+
className={styles.socialGrid}
|
|
66
|
+
role="list"
|
|
67
|
+
aria-label="Social media and contact links"
|
|
68
|
+
>
|
|
69
|
+
{socialLinks.map((social, index) => {
|
|
70
|
+
const iconKey = (social.icon || social.name || "").toLowerCase();
|
|
71
|
+
const iconData = iconMap[iconKey] || {};
|
|
72
|
+
const name = social.name;
|
|
73
|
+
const Icon = iconData.icon || FaQuestionCircle;
|
|
74
|
+
const iconColor = iconData.color || "var(--ifm-color-primary)";
|
|
75
|
+
const desc = social.desc || `Connect with me on ${name}`;
|
|
76
|
+
const url = social.url;
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<a
|
|
80
|
+
key={name}
|
|
81
|
+
href={url}
|
|
82
|
+
target="_blank"
|
|
83
|
+
rel="noopener noreferrer"
|
|
84
|
+
className={styles.socialCard}
|
|
85
|
+
style={{
|
|
86
|
+
"--card-index": index,
|
|
87
|
+
"--icon-hover-color": iconColor,
|
|
88
|
+
}}
|
|
89
|
+
aria-label={`Connect with me on ${name}: ${desc}`}
|
|
90
|
+
role="listitem"
|
|
91
|
+
>
|
|
92
|
+
{Icon && (
|
|
93
|
+
<div className={styles.socialIcon}>
|
|
94
|
+
<Icon aria-hidden="true" />
|
|
95
|
+
</div>
|
|
96
|
+
)}
|
|
97
|
+
<h3 className={styles.socialTitle}>{name}</h3>
|
|
98
|
+
<p className={styles.socialDesc}>{desc}</p>
|
|
99
|
+
</a>
|
|
100
|
+
);
|
|
101
|
+
})}
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
</div>
|
|
187
106
|
);
|
|
188
107
|
}
|
|
@@ -1,119 +1,48 @@
|
|
|
1
1
|
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
|
|
2
2
|
import useBrokenLinks from "@docusaurus/useBrokenLinks";
|
|
3
3
|
import styles from "./styles.module.css";
|
|
4
|
+
|
|
4
5
|
export default function ExperienceSection({ id, className }) {
|
|
5
6
|
const { siteConfig } = useDocusaurusContext();
|
|
6
7
|
const brokenLinks = useBrokenLinks();
|
|
8
|
+
|
|
7
9
|
if (id) {
|
|
8
10
|
brokenLinks.collectAnchor(id);
|
|
9
11
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
|
|
13
|
+
const experience = siteConfig.customFields?.experienceSection || {};
|
|
14
|
+
|
|
15
|
+
if (experience.enable === false) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
|
|
12
19
|
const displayHeading = experience.heading;
|
|
13
20
|
const displaySubheading = experience.subheading;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
id
|
|
18
|
-
className
|
|
19
|
-
role
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
{
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
this,
|
|
41
|
-
),
|
|
42
|
-
jsxDEV_7x81h0kn(
|
|
43
|
-
"p",
|
|
44
|
-
{
|
|
45
|
-
className: styles.experienceSubtitle,
|
|
46
|
-
children: displaySubheading,
|
|
47
|
-
},
|
|
48
|
-
undefined,
|
|
49
|
-
false,
|
|
50
|
-
undefined,
|
|
51
|
-
this,
|
|
52
|
-
),
|
|
53
|
-
],
|
|
54
|
-
},
|
|
55
|
-
undefined,
|
|
56
|
-
true,
|
|
57
|
-
undefined,
|
|
58
|
-
this,
|
|
59
|
-
),
|
|
60
|
-
jsxDEV_7x81h0kn(
|
|
61
|
-
"div",
|
|
62
|
-
{
|
|
63
|
-
className: styles.noticeWrapper,
|
|
64
|
-
children: jsxDEV_7x81h0kn(
|
|
65
|
-
"div",
|
|
66
|
-
{
|
|
67
|
-
className: styles.noticeBox,
|
|
68
|
-
role: "status",
|
|
69
|
-
"aria-live": "polite",
|
|
70
|
-
children: [
|
|
71
|
-
jsxDEV_7x81h0kn(
|
|
72
|
-
"p",
|
|
73
|
-
{
|
|
74
|
-
className: styles.noticeText,
|
|
75
|
-
children: "Coming Soon!",
|
|
76
|
-
},
|
|
77
|
-
undefined,
|
|
78
|
-
false,
|
|
79
|
-
undefined,
|
|
80
|
-
this,
|
|
81
|
-
),
|
|
82
|
-
jsxDEV_7x81h0kn(
|
|
83
|
-
"p",
|
|
84
|
-
{
|
|
85
|
-
className: styles.noticeDesc,
|
|
86
|
-
children: "This section is under construction.",
|
|
87
|
-
},
|
|
88
|
-
undefined,
|
|
89
|
-
false,
|
|
90
|
-
undefined,
|
|
91
|
-
this,
|
|
92
|
-
),
|
|
93
|
-
],
|
|
94
|
-
},
|
|
95
|
-
undefined,
|
|
96
|
-
true,
|
|
97
|
-
undefined,
|
|
98
|
-
this,
|
|
99
|
-
),
|
|
100
|
-
},
|
|
101
|
-
undefined,
|
|
102
|
-
false,
|
|
103
|
-
undefined,
|
|
104
|
-
this,
|
|
105
|
-
),
|
|
106
|
-
],
|
|
107
|
-
},
|
|
108
|
-
undefined,
|
|
109
|
-
true,
|
|
110
|
-
undefined,
|
|
111
|
-
this,
|
|
112
|
-
),
|
|
113
|
-
},
|
|
114
|
-
undefined,
|
|
115
|
-
false,
|
|
116
|
-
undefined,
|
|
117
|
-
this,
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<div
|
|
24
|
+
id={id}
|
|
25
|
+
className={`${styles.experienceSection} ${className || ""}`}
|
|
26
|
+
role="region"
|
|
27
|
+
aria-label="Experience section"
|
|
28
|
+
>
|
|
29
|
+
<div className={styles.experienceContainer}>
|
|
30
|
+
{/* Heading */}
|
|
31
|
+
<div className={styles.experienceHeader}>
|
|
32
|
+
<h2 className={styles.experienceTitle}>{displayHeading}</h2>
|
|
33
|
+
<p className={styles.experienceSubtitle}>{displaySubheading}</p>
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
{/* Placeholder */}
|
|
37
|
+
<div className={styles.noticeWrapper}>
|
|
38
|
+
<div className={styles.noticeBox} role="status" aria-live="polite">
|
|
39
|
+
<p className={styles.noticeText}>Coming Soon!</p>
|
|
40
|
+
<p className={styles.noticeDesc}>
|
|
41
|
+
This section is under construction.
|
|
42
|
+
</p>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
118
47
|
);
|
|
119
48
|
}
|
|
@@ -1,198 +1,76 @@
|
|
|
1
1
|
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
|
|
2
2
|
import useBrokenLinks from "@docusaurus/useBrokenLinks";
|
|
3
|
-
import SocialLinks from "../SocialLinks/index.
|
|
3
|
+
import SocialLinks from "../SocialLinks/index.jsx";
|
|
4
4
|
import styles from "./styles.module.css";
|
|
5
|
+
|
|
5
6
|
export default function HeroSection({ id, className }) {
|
|
6
7
|
const { siteConfig } = useDocusaurusContext();
|
|
7
8
|
const brokenLinks = useBrokenLinks();
|
|
9
|
+
|
|
8
10
|
if (id) {
|
|
9
11
|
brokenLinks.collectAnchor(id);
|
|
10
12
|
}
|
|
13
|
+
|
|
11
14
|
const { customFields } = siteConfig;
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
const
|
|
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
|
-
{ className: styles.subtitle, children: subtitle },
|
|
73
|
-
undefined,
|
|
74
|
-
false,
|
|
75
|
-
undefined,
|
|
76
|
-
this,
|
|
77
|
-
),
|
|
78
|
-
jsxDEV_7x81h0kn(
|
|
79
|
-
"h2",
|
|
80
|
-
{
|
|
81
|
-
className: styles.profession,
|
|
82
|
-
children: profession,
|
|
83
|
-
},
|
|
84
|
-
undefined,
|
|
85
|
-
false,
|
|
86
|
-
undefined,
|
|
87
|
-
this,
|
|
88
|
-
),
|
|
89
|
-
jsxDEV_7x81h0kn(
|
|
90
|
-
"span",
|
|
91
|
-
{ className: styles.subtitle, children: "." },
|
|
92
|
-
undefined,
|
|
93
|
-
false,
|
|
94
|
-
undefined,
|
|
95
|
-
this,
|
|
96
|
-
),
|
|
97
|
-
],
|
|
98
|
-
},
|
|
99
|
-
undefined,
|
|
100
|
-
true,
|
|
101
|
-
undefined,
|
|
102
|
-
this,
|
|
103
|
-
),
|
|
104
|
-
jsxDEV_7x81h0kn(
|
|
105
|
-
"p",
|
|
106
|
-
{ className: styles.description, children: desc },
|
|
107
|
-
undefined,
|
|
108
|
-
false,
|
|
109
|
-
undefined,
|
|
110
|
-
this,
|
|
111
|
-
),
|
|
112
|
-
jsxDEV_7x81h0kn(
|
|
113
|
-
"div",
|
|
114
|
-
{
|
|
115
|
-
className: styles.actionRow,
|
|
116
|
-
children: [
|
|
117
|
-
jsxDEV_7x81h0kn(
|
|
118
|
-
"div",
|
|
119
|
-
{
|
|
120
|
-
className: styles.cta,
|
|
121
|
-
children: jsxDEV_7x81h0kn(
|
|
122
|
-
"a",
|
|
123
|
-
{
|
|
124
|
-
href: "#about",
|
|
125
|
-
className: styles.ctaButton,
|
|
126
|
-
"aria-label": "Learn more about me",
|
|
127
|
-
children: learnMoreButtonText,
|
|
128
|
-
},
|
|
129
|
-
undefined,
|
|
130
|
-
false,
|
|
131
|
-
undefined,
|
|
132
|
-
this,
|
|
133
|
-
),
|
|
134
|
-
},
|
|
135
|
-
undefined,
|
|
136
|
-
false,
|
|
137
|
-
undefined,
|
|
138
|
-
this,
|
|
139
|
-
),
|
|
140
|
-
jsxDEV_7x81h0kn(
|
|
141
|
-
SocialLinks,
|
|
142
|
-
{ links: customFields.heroSection.social },
|
|
143
|
-
undefined,
|
|
144
|
-
false,
|
|
145
|
-
undefined,
|
|
146
|
-
this,
|
|
147
|
-
),
|
|
148
|
-
],
|
|
149
|
-
},
|
|
150
|
-
undefined,
|
|
151
|
-
true,
|
|
152
|
-
undefined,
|
|
153
|
-
this,
|
|
154
|
-
),
|
|
155
|
-
],
|
|
156
|
-
},
|
|
157
|
-
undefined,
|
|
158
|
-
true,
|
|
159
|
-
undefined,
|
|
160
|
-
this,
|
|
161
|
-
),
|
|
162
|
-
jsxDEV_7x81h0kn(
|
|
163
|
-
"div",
|
|
164
|
-
{
|
|
165
|
-
className: styles.rightSection,
|
|
166
|
-
children: jsxDEV_7x81h0kn(
|
|
167
|
-
"img",
|
|
168
|
-
{
|
|
169
|
-
src: `${profilePic}`,
|
|
170
|
-
alt: "profile",
|
|
171
|
-
className: styles.profilePic,
|
|
172
|
-
loading: "lazy",
|
|
173
|
-
},
|
|
174
|
-
undefined,
|
|
175
|
-
false,
|
|
176
|
-
undefined,
|
|
177
|
-
this,
|
|
178
|
-
),
|
|
179
|
-
},
|
|
180
|
-
undefined,
|
|
181
|
-
false,
|
|
182
|
-
undefined,
|
|
183
|
-
this,
|
|
184
|
-
),
|
|
185
|
-
],
|
|
186
|
-
},
|
|
187
|
-
undefined,
|
|
188
|
-
true,
|
|
189
|
-
undefined,
|
|
190
|
-
this,
|
|
191
|
-
),
|
|
192
|
-
},
|
|
193
|
-
undefined,
|
|
194
|
-
false,
|
|
195
|
-
undefined,
|
|
196
|
-
this,
|
|
15
|
+
const { heroSection } = customFields;
|
|
16
|
+
|
|
17
|
+
const intro = heroSection.intro;
|
|
18
|
+
const title = heroSection.title;
|
|
19
|
+
const subtitle = heroSection.subtitle;
|
|
20
|
+
const profession = heroSection.profession;
|
|
21
|
+
const desc = heroSection.desc;
|
|
22
|
+
const profilePic = heroSection.profilePic;
|
|
23
|
+
const learnMoreButtonText = heroSection.learnMoreButtonTxt;
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<div
|
|
27
|
+
id={id}
|
|
28
|
+
className={`${styles.hero} ${className || ""}`}
|
|
29
|
+
role="region"
|
|
30
|
+
aria-label="Hero section"
|
|
31
|
+
>
|
|
32
|
+
<div className={styles.container}>
|
|
33
|
+
{/* Left: text content */}
|
|
34
|
+
<div className={styles.leftSection}>
|
|
35
|
+
<p className={styles.intro}>{intro}</p>
|
|
36
|
+
|
|
37
|
+
<h1 className={styles.title}>
|
|
38
|
+
{title}
|
|
39
|
+
<span className={styles.titleComma}>,</span>
|
|
40
|
+
</h1>
|
|
41
|
+
|
|
42
|
+
<div className={styles.subtitleWrapper}>
|
|
43
|
+
<span className={styles.subtitle}>{subtitle}</span>
|
|
44
|
+
<h2 className={styles.profession}>{profession}</h2>
|
|
45
|
+
<span className={styles.subtitle}>.</span>
|
|
46
|
+
</div>
|
|
47
|
+
|
|
48
|
+
<p className={styles.description}>{desc}</p>
|
|
49
|
+
|
|
50
|
+
<div className={styles.actionRow}>
|
|
51
|
+
<div className={styles.cta}>
|
|
52
|
+
<a
|
|
53
|
+
href="#about"
|
|
54
|
+
className={styles.ctaButton}
|
|
55
|
+
aria-label="Learn more about me"
|
|
56
|
+
>
|
|
57
|
+
{learnMoreButtonText}
|
|
58
|
+
</a>
|
|
59
|
+
</div>
|
|
60
|
+
<SocialLinks links={heroSection.social} />
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
|
|
64
|
+
{/* Right: profile picture */}
|
|
65
|
+
<div className={styles.rightSection}>
|
|
66
|
+
<img
|
|
67
|
+
src={`${profilePic}`}
|
|
68
|
+
alt="profile"
|
|
69
|
+
className={styles.profilePic}
|
|
70
|
+
loading="lazy"
|
|
71
|
+
/>
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
197
75
|
);
|
|
198
76
|
}
|