518 lines
13 KiB
JavaScript
518 lines
13 KiB
JavaScript
import * as React from "react"
|
|
import "../styles/general.scss"
|
|
import { content_pl } from "../content/kamil"
|
|
import { content_en } from "../content/kamil"
|
|
import { loadCaptchaEnginge, LoadCanvasTemplate, validateCaptcha } from 'react-simple-captcha'
|
|
|
|
const SimpleCaptchaWrapper = ({ onVerified, language }) => {
|
|
const [error, setError] = React.useState(null);
|
|
|
|
let content = {
|
|
"pl": {
|
|
"initial_information": "Wprowadź kod z obrazka aby wyświetlić informacje kontaktowe.",
|
|
"captcha_console_initialization": "Błąd inicjalizacji captcha:",
|
|
"captcha_ui_initialization": "Nie można załadować captcha",
|
|
"captcha_console_reload": "Błąd przeładowania captcha:",
|
|
"captcha_reload_button": "Odśwież kod",
|
|
"captcha": "Wprowadź kod z obrazka",
|
|
"button": "Potwierdź",
|
|
"error": "Nieprawidłowy kod. Spróbuj ponownie.",
|
|
},
|
|
"en": {
|
|
"initial_information": "Please enter the code from the image for display contact information.",
|
|
"captcha_console_initialization": "Captcha initialization error:",
|
|
"captcha_ui_initialization": "Cannot load captcha",
|
|
"captcha_console_reload": "Captcha reload error:",
|
|
"captcha_reload_button": "Reload code",
|
|
"captcha": "Enter the code from the image",
|
|
"button": "Confirm",
|
|
"error": "Invalid code. Try again.",
|
|
}
|
|
}
|
|
|
|
React.useEffect(() => {
|
|
try {
|
|
loadCaptchaEnginge(6, '#242424', '#a6a6a6');
|
|
} catch (err) {
|
|
console.error(content[language].captcha_console_initialization, err);
|
|
setError(content[language].captcha_ui_initialization);
|
|
}
|
|
}, []);
|
|
|
|
const handleSubmit = (e) => {
|
|
e.preventDefault();
|
|
const userCaptchaValue = document.getElementById('user_captcha_input').value;
|
|
|
|
if (validateCaptcha(userCaptchaValue)) {
|
|
onVerified(true);
|
|
setError(null);
|
|
} else {
|
|
setError(content[language].error);
|
|
document.getElementById('user_captcha_input').value = "";
|
|
// Przeładowanie captcha
|
|
try {
|
|
loadCaptchaEnginge(6, '#242424', '#a6a6a6');
|
|
} catch (err) {
|
|
console.error(content[language].captcha_console_reload, err);
|
|
}
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="captcha-container">
|
|
<div className="captcha-form">
|
|
<p>
|
|
{content[language].initial_information}
|
|
</p>
|
|
<LoadCanvasTemplate reloadText={content[language].captcha_reload_button} reloadColor="#a6a6a6" />
|
|
<form onSubmit={handleSubmit}>
|
|
<input
|
|
type="text"
|
|
placeholder={content[language].captcha}
|
|
id="user_captcha_input"
|
|
className="captcha-input"
|
|
/>
|
|
<button type="submit" className="captcha-button">
|
|
{content[language].button}
|
|
</button>
|
|
</form>
|
|
{error && (
|
|
<div className="error-message">
|
|
{error}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
const MiniWorkImage = ({ image }) => {
|
|
return (
|
|
<div
|
|
style={{
|
|
width: "40px",
|
|
height: "40px",
|
|
float: "left",
|
|
marginRight: "10px",
|
|
display: "flex",
|
|
justifyContent: "center",
|
|
alignItems: "center",
|
|
}}
|
|
>
|
|
<img
|
|
src={ image }
|
|
style={{
|
|
maxHeight: "100%",
|
|
maxWidth: "100%",
|
|
objectPosition: "center",
|
|
}}
|
|
/>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
|
|
const SegmentTitle = ({ segment }) => {
|
|
return (
|
|
<div
|
|
className="segment_general"
|
|
>
|
|
<div className="segment_title">
|
|
{ segment.title }
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
|
|
const SegmentListNormal = ({ segment, tabs }) => {
|
|
return (
|
|
<div
|
|
style={{
|
|
width: 100 - tabs * 5 + "%",
|
|
paddingLeft: tabs * 5 + "%",
|
|
}}
|
|
>
|
|
<div
|
|
className="segment_content_normal"
|
|
>
|
|
<ul>
|
|
<li>
|
|
{
|
|
segment.content.length > 0 ?
|
|
segment.title + ":"
|
|
:
|
|
segment.title + ","
|
|
}
|
|
</li>
|
|
{
|
|
segment.content.length > 0 ?
|
|
<ul>
|
|
{
|
|
segment.content.map(
|
|
(item, index) => {
|
|
return (
|
|
<li key={ index }>
|
|
{ item + "," }
|
|
</li>
|
|
)
|
|
}
|
|
)
|
|
}
|
|
</ul>
|
|
:
|
|
<></>
|
|
}
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
const SegmentListWork = ({ segment, tabs }) => {
|
|
return (
|
|
<div
|
|
style={{
|
|
width: 100 - tabs * 5 + "%",
|
|
}}
|
|
>
|
|
<div
|
|
style={{
|
|
borderLeft: segment.mainBorderColor === null ? "" : "3.5px dotted " + segment.mainBorderColor,
|
|
paddingLeft: tabs * 2.5 + "%",
|
|
marginLeft: tabs * 2.5 + "%",
|
|
marginTop: segment.firstElement === true ? "15px" : "",
|
|
marginBottom: segment.noElements === true ? "15px" : "",
|
|
}}
|
|
className="segment_content_work"
|
|
>
|
|
{
|
|
segment.image != "" ?
|
|
<MiniWorkImage
|
|
image={ segment.image }
|
|
/>
|
|
:
|
|
""
|
|
}
|
|
<div
|
|
className="segment_content_title"
|
|
>
|
|
{
|
|
segment.content.length > 0 ?
|
|
segment.title + ":"
|
|
:
|
|
segment.lastElement === true ?
|
|
segment.title + "."
|
|
:
|
|
segment.noElements === true ?
|
|
segment.title + ","
|
|
:
|
|
segment.title + ":"
|
|
}
|
|
</div>
|
|
{
|
|
segment.content.length > 0 ?
|
|
<ul
|
|
style={{
|
|
borderLeft: segment.branchBorderColor === null ? "" : "3.5px dotted " + segment.branchBorderColor,
|
|
marginBottom: segment.lastSubElement === true ? "30px" : "",
|
|
paddingBottom: segment.haveOneElement === true ? "30px" : "",
|
|
}}
|
|
>
|
|
{
|
|
segment.content.map(
|
|
(item, index) => {
|
|
return (
|
|
<li key={ index }>
|
|
{ item + "," }
|
|
</li>
|
|
)
|
|
}
|
|
)
|
|
}
|
|
</ul>
|
|
:
|
|
<></>
|
|
}
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
|
|
const SegmentCreateBranch = ({ segment, tabs }) => {
|
|
return (
|
|
<div
|
|
style={{
|
|
width: 100 - tabs * 5 + "%",
|
|
}}
|
|
>
|
|
<div
|
|
className="segment_content_work"
|
|
style={{
|
|
color: segment.branchBorderColor,
|
|
fontWeight: "bold",
|
|
marginLeft: tabs * 2.15 + "%",
|
|
marginTop: "-5px",
|
|
}}
|
|
>
|
|
x
|
|
</div>
|
|
<div
|
|
style={{
|
|
borderLeft: "3.5px dotted " + segment.mainBorderColor,
|
|
marginLeft: tabs * 2.5 + "%",
|
|
}}
|
|
className="segment_content_work"
|
|
>
|
|
<div
|
|
style={{
|
|
width: tabs * 2.5 + "%",
|
|
height: "20px",
|
|
marginLeft: "-3.5px",
|
|
borderRadius: "0 0 0 100%",
|
|
borderBottom: "3.5px dotted " + segment.branchBorderColor,
|
|
borderLeft: "3.5px dotted " + segment.branchBorderColor,
|
|
}}
|
|
>
|
|
</div>
|
|
<div
|
|
style={{
|
|
width: "18px",
|
|
height: "20px",
|
|
marginLeft: tabs * 2.5 + "%",
|
|
borderRadius: "0 100% 0 0",
|
|
borderTop: "3.5px dotted " + segment.branchBorderColor,
|
|
borderRight: "3.5px dotted " + segment.branchBorderColor,
|
|
}}
|
|
>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
|
|
const SegmentMergeBranch = ({ segment, tabs }) => {
|
|
return (
|
|
<div
|
|
style={{
|
|
width: 100 - tabs * 5 + "%",
|
|
}}
|
|
>
|
|
<div
|
|
style={{
|
|
borderLeft: "3.5px dotted " + segment.mainBorderColor,
|
|
marginLeft: tabs * 2.5 + "%",
|
|
}}
|
|
className="segment_content_work"
|
|
>
|
|
<div
|
|
style={{
|
|
width: "18px",
|
|
height: "20px",
|
|
marginLeft: tabs * 2.5 + "%",
|
|
borderRadius: "0 0 100% 0",
|
|
borderBottom: "3.5px dotted " + segment.branchBorderColor,
|
|
borderRight: "3.5px dotted " + segment.branchBorderColor,
|
|
}}
|
|
>
|
|
</div>
|
|
<div
|
|
style={{
|
|
width: tabs * 2.5 + "%",
|
|
height: "20px",
|
|
marginLeft: "-3.5px",
|
|
borderRadius: "100% 0 0 0",
|
|
borderTop: "3.5px dotted " + segment.branchBorderColor,
|
|
borderLeft: "3.5px dotted " + segment.branchBorderColor,
|
|
}}
|
|
>
|
|
</div>
|
|
</div>
|
|
<div
|
|
className="segment_content_work"
|
|
style={{
|
|
color: segment.branchBorderColor,
|
|
fontWeight: "bold",
|
|
marginLeft: tabs * 2.15 + "%",
|
|
marginTop: "-5px",
|
|
}}
|
|
>
|
|
x
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
|
|
const SegmentGeneral = ({ segment }) => {
|
|
const [isVerified, setIsVerified] = React.useState(false);
|
|
|
|
return (
|
|
<div className="segment_general">
|
|
<img
|
|
src={segment.image}
|
|
className="segment_image cover"
|
|
alt={segment.title}
|
|
/>
|
|
<div className="segment_title segment_title_image">
|
|
{segment.title}
|
|
</div>
|
|
{!isVerified ? (
|
|
<SimpleCaptchaWrapper
|
|
onVerified={setIsVerified}
|
|
language={segment.content_language}
|
|
/>
|
|
) : (
|
|
<div className="segment_content_image">
|
|
{typeof segment.content === "object" ? (
|
|
Object.keys(segment.content).map((key) => (
|
|
<React.Fragment key={`item_${key}`}>
|
|
<div className="segment_image_item">
|
|
{key + ": "}
|
|
</div>
|
|
<div className="segment_image_item subitem">
|
|
{segment.content[key].includes("git.") ? (
|
|
<a href={`https://${segment.content[key]}`}>
|
|
{segment.content[key]}
|
|
</a>
|
|
) : (
|
|
segment.content[key]
|
|
)}
|
|
</div>
|
|
</React.Fragment>
|
|
))
|
|
) : (
|
|
"lol"
|
|
)}
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
|
|
const SegmentRODO = ({ segment }) => {
|
|
return (
|
|
<div
|
|
className="segment_general"
|
|
>
|
|
<div className="segment_content_normal foot_content">
|
|
{ segment.content }
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
|
|
const Segment = ({ index, segment }) => {
|
|
const segment_index = "segment_" + index;
|
|
|
|
return (
|
|
<div
|
|
id={segment_index}
|
|
key={segment_index}
|
|
>
|
|
{
|
|
segment.type === "generalTitleSegment" ?
|
|
<SegmentGeneral
|
|
key={`general_${index}`}
|
|
segment={segment}
|
|
/>
|
|
:
|
|
segment.type === "titleSegment" ?
|
|
<SegmentTitle
|
|
key={`title_${index}`}
|
|
segment={segment}
|
|
/>
|
|
:
|
|
segment.type === "subSegment" ?
|
|
<SegmentListNormal
|
|
key={`normal_${index}`}
|
|
segment={segment}
|
|
tabs={segment.tabs}
|
|
/>
|
|
:
|
|
segment.type === "workSubSegment" ?
|
|
<SegmentListWork
|
|
key={`work_${index}`}
|
|
segment={segment}
|
|
tabs={segment.tabs}
|
|
/>
|
|
:
|
|
segment.type === "createBranchSegment" ?
|
|
<SegmentCreateBranch
|
|
key={`create_${index}`}
|
|
segment={segment}
|
|
tabs={segment.tabs}
|
|
/>
|
|
:
|
|
segment.type === "mergeBranchSegment" ?
|
|
<SegmentMergeBranch
|
|
key={`merge_${index}`}
|
|
segment={segment}
|
|
tabs={segment.tabs}
|
|
/>
|
|
:
|
|
segment.type === "RODOSegment" ?
|
|
<SegmentRODO
|
|
key={`rodo_${index}`}
|
|
segment={segment}
|
|
/>
|
|
:
|
|
null
|
|
}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
|
|
const IndexPage = () => {
|
|
let eng_ = "🇬🇧"
|
|
let pol_ = "🇵🇱"
|
|
|
|
const [content_swapper, set_content_swap] = React.useState(pol_);
|
|
const [content, set_content] = React.useState(content_en);
|
|
|
|
const swap_content = (event) => {
|
|
event.preventDefault()
|
|
if (content_swapper === eng_) {
|
|
set_content_swap(pol_)
|
|
set_content(content_en)
|
|
} else if (content_swapper === pol_) {
|
|
set_content_swap(eng_)
|
|
set_content(content_pl)
|
|
}
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<div className="global_segment">
|
|
<div className="title_bar">
|
|
Curriculum Vitae
|
|
</div>
|
|
<div className="language_bar">
|
|
<div onClick={e => swap_content(e)}>
|
|
{content_swapper}
|
|
</div>
|
|
</div>
|
|
{
|
|
content.map((value, index) => (
|
|
<Segment
|
|
key={`segment_${index}`}
|
|
index={index}
|
|
segment={value}
|
|
/>
|
|
))
|
|
}
|
|
</div>
|
|
<div className="foot">
|
|
|
|
</div>
|
|
</>
|
|
)
|
|
}
|
|
|
|
export default IndexPage
|