Added project
After Width: | Height: | Size: 3.8 KiB |
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"name": "my-website",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@testing-library/jest-dom": "^5.14.1",
|
||||
"@testing-library/react": "^11.2.7",
|
||||
"@testing-library/user-event": "^12.8.3",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-scripts": "4.0.3",
|
||||
"web-vitals": "^1.1.2"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "BROWSER=none react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 17 KiB |
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta name="description" content="Personal website from Alexander Roese" />
|
||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||
<title>Alexander Röse</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
After Width: | Height: | Size: 34 KiB |
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"short_name": "My website",
|
||||
"name": "Alexander Röse",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
},
|
||||
{
|
||||
"src": "logo192.png",
|
||||
"type": "image/png",
|
||||
"sizes": "192x192"
|
||||
},
|
||||
{
|
||||
"src": "logo512.png",
|
||||
"type": "image/png",
|
||||
"sizes": "512x512"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
# https://www.robotstxt.org/robotstxt.html
|
||||
User-agent: *
|
||||
Disallow:
|
|
@ -0,0 +1,399 @@
|
|||
#root {
|
||||
background-image: url("img/background.jpg");
|
||||
height: 100vh;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
/*
|
||||
nav
|
||||
*/
|
||||
|
||||
.nav {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.nav li {
|
||||
float: left;
|
||||
display: block;
|
||||
text-align: center;
|
||||
padding: 14px 16px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.nav li a {
|
||||
display: block;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
margin: 0 20px 0 20px;
|
||||
}
|
||||
|
||||
.nav li a.active {
|
||||
background-color: #04aa6d;
|
||||
}
|
||||
|
||||
.nav li.right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.nav .icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/*
|
||||
mobile
|
||||
*/
|
||||
|
||||
@media screen and (max-width: 940px) {
|
||||
#modal-projects {
|
||||
width: 70vw !important;
|
||||
}
|
||||
|
||||
#modal-contact {
|
||||
width: 70vw !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
.nav .icon {
|
||||
float: right;
|
||||
font-weight: bold;
|
||||
font-size: 24px;
|
||||
display: block;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.nav li {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.nav-mobile ul,
|
||||
.nav-mobile li {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/*ul.nav li.right,
|
||||
ul.nav li {
|
||||
float: none;
|
||||
} */
|
||||
|
||||
/*
|
||||
page: home
|
||||
*/
|
||||
|
||||
#modal-home {
|
||||
width: 80vw;
|
||||
}
|
||||
|
||||
#modal-home h1 {
|
||||
font-size: 10vw;
|
||||
}
|
||||
|
||||
#modal-home p {
|
||||
font-size: 5vw;
|
||||
}
|
||||
|
||||
/*
|
||||
page: projects
|
||||
*/
|
||||
|
||||
#modal-projects h2 {
|
||||
font-size: 9vw;
|
||||
}
|
||||
|
||||
#modal-projects p {
|
||||
font-size: 5vw;
|
||||
}
|
||||
|
||||
#modal-projects table th,
|
||||
#modal-projects table td {
|
||||
font-size: 4vw;
|
||||
}
|
||||
|
||||
/*
|
||||
page: contact
|
||||
*/
|
||||
|
||||
#modal-contact {
|
||||
width: 80vw;
|
||||
}
|
||||
|
||||
#modal-contact h1 {
|
||||
font-size: 10vw;
|
||||
}
|
||||
|
||||
#modal-contact label,
|
||||
#modal-contact button {
|
||||
font-size: 5vw !important;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-mobile {
|
||||
height: 0;
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
z-index: 1;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-color: rgba(0, 0, 0, 0.9);
|
||||
overflow-x: hidden;
|
||||
transition: 0.4s;
|
||||
}
|
||||
|
||||
.nav-mobile button {
|
||||
position: absolute;
|
||||
right: 30px;
|
||||
top: 8px;
|
||||
font-size: 34px;
|
||||
border: 0;
|
||||
color: #fff;
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.nav-mobile.open {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.nav-mobile ul a {
|
||||
display: block;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
margin: 20px 0 20px 0;
|
||||
}
|
||||
|
||||
.nav-mobile ul {
|
||||
position: relative;
|
||||
top: 25%;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin-top: 30px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.nav-mobile div {
|
||||
padding: 20px 45% 0 45%;
|
||||
}
|
||||
|
||||
.nav-mobile div li {
|
||||
margin-bottom: 10px;
|
||||
cursor: pointer;
|
||||
transition: transform 0.1s;
|
||||
}
|
||||
|
||||
.nav-mobile div a {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.nav-mobile div li {
|
||||
margin: 10px 0 10px 0;
|
||||
}
|
||||
|
||||
.nav-mobile div li:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.nav-mobile img {
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.nav-mobile hr {
|
||||
margin: 0 7px 0 7px;
|
||||
border: 1px solid #4d4d4d;
|
||||
}
|
||||
|
||||
/*
|
||||
sidebar
|
||||
*/
|
||||
|
||||
.sidebar {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 10px;
|
||||
transform: translate(-50%, -50%);
|
||||
border-radius: 10px;
|
||||
background-color: rgba(34, 34, 34, 0.9);
|
||||
box-shadow: 0 10px 10px #000;
|
||||
}
|
||||
|
||||
.sidebar hr {
|
||||
margin: 0 2px 0 7px;
|
||||
border: 1px solid #4d4d4d;
|
||||
}
|
||||
|
||||
.sidebar img {
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.sidebar ul {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.sidebar li {
|
||||
margin: 10px;
|
||||
cursor: pointer;
|
||||
transition: transform 0.1s;
|
||||
}
|
||||
|
||||
.sidebar li:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
/*
|
||||
modal defaults
|
||||
*/
|
||||
|
||||
.modal {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
font-size: 32px;
|
||||
color: #fff;
|
||||
background-color: rgba(34, 34, 34, 0.9);
|
||||
box-shadow: 0 10px 10px #000;
|
||||
}
|
||||
|
||||
.modal h1,
|
||||
.modal h2 {
|
||||
margin-top: 10px;
|
||||
letter-spacing: 3.6px;
|
||||
}
|
||||
|
||||
/*
|
||||
page: home
|
||||
*/
|
||||
|
||||
#modal-home p {
|
||||
color: rgba(252, 252, 252, 0.705);
|
||||
}
|
||||
|
||||
/*
|
||||
page: projects
|
||||
*/
|
||||
|
||||
#modal-projects {
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
#modal-projects h2 {
|
||||
text-align: center;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
#modal-projects p {
|
||||
text-align: center;
|
||||
color: rgba(252, 252, 252, 0.705);
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
#modal-projects th {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#modal-projects div {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
#modal-projects table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 26px;
|
||||
}
|
||||
|
||||
#modal-projects th {
|
||||
border-bottom: 4px solid #4d4d4d;
|
||||
border-right: 3px solid #4d4d4d;
|
||||
}
|
||||
|
||||
#modal-projects th:last-child {
|
||||
border-right: 0;
|
||||
}
|
||||
|
||||
#modal-projects td {
|
||||
border-top: 3px solid #4d4d4d;
|
||||
border-right: 3px solid #4d4d4d;
|
||||
}
|
||||
|
||||
#modal-projects td:last-child {
|
||||
border-right: 0;
|
||||
}
|
||||
|
||||
#modal-projects a {
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/*
|
||||
page: contact
|
||||
*/
|
||||
|
||||
#modal-contact {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#modal-contact h2 {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#modal-contact p {
|
||||
color: rgba(252, 252, 252, 0.705);
|
||||
}
|
||||
|
||||
#modal-contact a {
|
||||
color: #00acd3;
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/*
|
||||
#modal-contact input,
|
||||
#modal-contact textarea {
|
||||
width: 100%;
|
||||
padding: 12px 20px;
|
||||
margin: 8px 0;
|
||||
display: inline-block;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
box-sizing: border-box;
|
||||
border: none;
|
||||
transition: 0.1s;
|
||||
outline: none;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
#modal-contact textarea {
|
||||
resize: vertical;
|
||||
min-height: 6em;
|
||||
max-height: 12em;
|
||||
}
|
||||
|
||||
#modal-contact input:hover,
|
||||
#modal-contact textarea:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
#modal-contact button {
|
||||
width: 100%;
|
||||
background-color: #00acd3;
|
||||
font-size: 32px;
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
border-radius: 5px;
|
||||
border: none;
|
||||
letter-spacing: 3.6px;
|
||||
padding: 5px;
|
||||
cursor: pointer;
|
||||
transition: 0.1s;
|
||||
}
|
||||
|
||||
#modal-contact button:hover {
|
||||
background-color: rgba(0, 174, 212, 0.9);
|
||||
}
|
||||
*/
|
|
@ -0,0 +1,49 @@
|
|||
import "./App.css";
|
||||
import React, { Suspense, lazy } from "react";
|
||||
import {
|
||||
BrowserRouter as Router,
|
||||
Redirect,
|
||||
Route,
|
||||
Switch,
|
||||
} from "react-router-dom";
|
||||
import { LanguageProvider } from "./component/Language/LanguageProvider";
|
||||
import NavbarComponent, { navOnload, navOnresize } from "./component/Navbar";
|
||||
import SidebarComponent, {
|
||||
sidebarOnload,
|
||||
sidebarOnresize,
|
||||
} from "./component/Sidebar";
|
||||
|
||||
const Home = lazy(() => import("./routes/Home"));
|
||||
const Projects = lazy(() => import("./routes/Projects"));
|
||||
const Contact = lazy(() => import("./routes/Contact"));
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<Router>
|
||||
<LanguageProvider>
|
||||
<NavbarComponent />
|
||||
<SidebarComponent />
|
||||
|
||||
<Suspense fallback={<div></div>}>
|
||||
<Switch>
|
||||
<Route exact path="/" component={Home} />
|
||||
<Route path="/projects" component={Projects} />
|
||||
<Route path="/contact" component={Contact} />
|
||||
|
||||
<Redirect to="/" />
|
||||
</Switch>
|
||||
</Suspense>
|
||||
</LanguageProvider>
|
||||
</Router>
|
||||
);
|
||||
}
|
||||
|
||||
window.onload = () => {
|
||||
navOnload();
|
||||
sidebarOnload();
|
||||
};
|
||||
|
||||
window.onresize = () => {
|
||||
navOnresize();
|
||||
sidebarOnresize();
|
||||
};
|
|
@ -0,0 +1,94 @@
|
|||
import React from "react";
|
||||
|
||||
export const languages = {
|
||||
german: {
|
||||
nav: {
|
||||
projects: "Projekte",
|
||||
contact: "Kontakt",
|
||||
},
|
||||
pages: {
|
||||
home: {
|
||||
text: "Selbstlernender Entwickler durch Recherche & Entwicklung",
|
||||
},
|
||||
projects: {
|
||||
title: "Meine Projekte",
|
||||
description:
|
||||
"Auflistung von Projekten die ich umgesetzt habe oder an denen ich zur Zeit arbeite",
|
||||
tableTh: {
|
||||
description: "Beschreibung",
|
||||
language: "Sprachen",
|
||||
date: "Zeitraum",
|
||||
},
|
||||
},
|
||||
contact: {
|
||||
title: "Sende mir eine Email",
|
||||
text: "Sie können mich unter folgender Email kontaktieren",
|
||||
},
|
||||
},
|
||||
},
|
||||
english: {
|
||||
nav: {
|
||||
projects: "Projects",
|
||||
contact: "Contact",
|
||||
},
|
||||
pages: {
|
||||
home: {
|
||||
text: "Self-learning developer through research & development",
|
||||
},
|
||||
projects: {
|
||||
title: "My projects",
|
||||
description:
|
||||
"Listing of projects I have implemented or am currently working on",
|
||||
tableTh: {
|
||||
description: "Description",
|
||||
language: "Language",
|
||||
date: "Date",
|
||||
},
|
||||
},
|
||||
contact: {
|
||||
title: "Send me an email",
|
||||
text: "You can contact me at the following email",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
name: {
|
||||
placeholder: "Ihr Name",
|
||||
},
|
||||
email: {
|
||||
placeholder: "Ihre Email",
|
||||
},
|
||||
subject: {
|
||||
text: "Betreff",
|
||||
placeholder: "Ihr Betreff",
|
||||
},
|
||||
message: {
|
||||
text: "Nachricht",
|
||||
placeholder: "Ihre Nachricht",
|
||||
},
|
||||
submit: "Abschicken",
|
||||
|
||||
|
||||
name: {
|
||||
placeholder: "Your name",
|
||||
},
|
||||
email: {
|
||||
placeholder: "Your email",
|
||||
},
|
||||
subject: {
|
||||
text: "Subject",
|
||||
placeholder: "Your subject",
|
||||
},
|
||||
message: {
|
||||
text: "Message",
|
||||
placeholder: "Your message",
|
||||
},
|
||||
submit: "Send",
|
||||
*/
|
||||
|
||||
export const LanguageContext = React.createContext({
|
||||
language: languages.english,
|
||||
changeLanguage: () => {},
|
||||
});
|
|
@ -0,0 +1,30 @@
|
|||
import React from "react";
|
||||
import { LanguageContext, languages } from "./LanguageContext";
|
||||
|
||||
export class LanguageProvider extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = { language: languages.german };
|
||||
this.changeLanguage = this.changeLanguage.bind(this);
|
||||
}
|
||||
|
||||
changeLanguage = (language) => {
|
||||
this.setState({
|
||||
language: language === "en" ? languages.english : languages.german,
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<LanguageContext.Provider
|
||||
value={{
|
||||
language: this.state.language,
|
||||
changeLanguage: this.changeLanguage,
|
||||
}}
|
||||
>
|
||||
{this.props.children}
|
||||
</LanguageContext.Provider>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,145 @@
|
|||
import React from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { LanguageContext } from "./Language/LanguageContext";
|
||||
import { SidebarElements } from "./Sidebar";
|
||||
|
||||
export default function NavbarComponent() {
|
||||
return (
|
||||
<LanguageContext.Consumer>
|
||||
{({ changeLanguage, language }) => (
|
||||
<>
|
||||
<ul className="nav">
|
||||
<NavElements language={language} />
|
||||
|
||||
<li className="icon" onClick={() => openNavMobile()}>
|
||||
☰
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div className="nav-mobile">
|
||||
<button onClick={() => closeNavMobile()}>×</button>
|
||||
|
||||
<ul>
|
||||
<NavElements language={language} mobile={true} />
|
||||
|
||||
<div>
|
||||
<SidebarElements changeLanguage={changeLanguage} />
|
||||
</div>
|
||||
</ul>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</LanguageContext.Consumer>
|
||||
);
|
||||
}
|
||||
|
||||
function NavElements(props) {
|
||||
return (
|
||||
<>
|
||||
<li>
|
||||
<Link
|
||||
to="/"
|
||||
onClick={() => {
|
||||
fontWeightEffect(0);
|
||||
if (props.mobile) {
|
||||
closeNavMobile();
|
||||
}
|
||||
}}
|
||||
>
|
||||
Alexander Röse
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link
|
||||
to="/projects"
|
||||
onClick={() => {
|
||||
fontWeightEffect(1);
|
||||
if (props.mobile) {
|
||||
closeNavMobile();
|
||||
}
|
||||
}}
|
||||
>
|
||||
{props.language.nav.projects}
|
||||
</Link>
|
||||
</li>
|
||||
<li className="right">
|
||||
<Link
|
||||
to="/contact"
|
||||
onClick={() => {
|
||||
fontWeightEffect(2);
|
||||
if (props.mobile) {
|
||||
closeNavMobile();
|
||||
}
|
||||
}}
|
||||
>
|
||||
{props.language.nav.contact}
|
||||
</Link>
|
||||
</li>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export function navOnresize() {
|
||||
const navMobile = document.querySelector(".nav-mobile");
|
||||
|
||||
if (window.screen.width > 600 && navMobile.classList.contains("open")) {
|
||||
navMobile.classList.remove("open");
|
||||
|
||||
document
|
||||
.querySelector(".nav .icon")
|
||||
.setAttribute("style", "visibility: visible;");
|
||||
}
|
||||
}
|
||||
|
||||
function openNavMobile() {
|
||||
document
|
||||
.querySelector(".nav .icon")
|
||||
.setAttribute("style", "visibility: hidden;");
|
||||
|
||||
document.querySelector(".nav-mobile").classList.add("open");
|
||||
}
|
||||
|
||||
function closeNavMobile() {
|
||||
document
|
||||
.querySelector(".nav .icon")
|
||||
.setAttribute("style", "visibility: visible;");
|
||||
|
||||
document.querySelector(".nav-mobile").classList.remove("open");
|
||||
}
|
||||
|
||||
export function navOnload() {
|
||||
switch (window.location.pathname) {
|
||||
case "/projects":
|
||||
fontWeightEffect(1);
|
||||
break;
|
||||
case "/contact":
|
||||
fontWeightEffect(2);
|
||||
break;
|
||||
default:
|
||||
fontWeightEffect(0);
|
||||
}
|
||||
}
|
||||
|
||||
function fontWeightEffect(number) {
|
||||
// navbar
|
||||
const navLi = document.querySelectorAll(".nav li a");
|
||||
|
||||
for (let i = 0; i < navLi.length; i++) {
|
||||
if (i !== number) {
|
||||
navLi[i].setAttribute("style", "font-weight: normal;");
|
||||
}
|
||||
}
|
||||
|
||||
navLi[number].setAttribute("style", "font-weight: bold;");
|
||||
|
||||
// overlay
|
||||
const navMobileLi = document.querySelectorAll(".nav-mobile li a");
|
||||
|
||||
for (let i = 0; i < navMobileLi.length; i++) {
|
||||
if (i !== number) {
|
||||
navMobileLi[i].setAttribute("style", "font-weight: normal;");
|
||||
}
|
||||
}
|
||||
|
||||
navMobileLi[number].setAttribute("style", "font-weight: bold;");
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
import React from "react";
|
||||
import { LanguageContext } from "./Language/LanguageContext";
|
||||
|
||||
import gitea from "../img/gitea.png";
|
||||
import github from "../img/github.png";
|
||||
import discord from "../img/discord.png";
|
||||
import germanyFlag from "../img/germany.png";
|
||||
import englandFlag from "../img/england.png";
|
||||
|
||||
export default class Sidebar extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<LanguageContext.Consumer>
|
||||
{({ changeLanguage }) => (
|
||||
<div className="sidebar">
|
||||
<ul>
|
||||
<SidebarElements changeLanguage={changeLanguage} />
|
||||
</ul>
|
||||
</div>
|
||||
)}
|
||||
</LanguageContext.Consumer>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function SidebarElements(props) {
|
||||
return (
|
||||
<>
|
||||
<li>
|
||||
<a href="https://git.umbach.dev/Alex" target="_blank" rel="noreferrer">
|
||||
<img src={gitea} alt="gitea" />
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://github.com/RuisPipe" target="_blank" rel="noreferrer">
|
||||
<img src={github} alt="github" />
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://discordapp.com/users/444509946902609941"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<img src={discord} alt="discord" />
|
||||
</a>
|
||||
</li>
|
||||
<hr />
|
||||
<li onClick={() => props.changeLanguage("de")}>
|
||||
<img src={germanyFlag} alt="germany" />
|
||||
</li>
|
||||
<li onClick={() => props.changeLanguage("en")}>
|
||||
<img src={englandFlag} alt="england" />
|
||||
</li>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export function sidebarOnresize() {
|
||||
sidebarVisibility();
|
||||
}
|
||||
|
||||
export function sidebarOnload() {
|
||||
sidebarVisibility();
|
||||
}
|
||||
|
||||
function sidebarVisibility() {
|
||||
let sidebar = document.querySelector(".sidebar");
|
||||
|
||||
window.screen.width > 600
|
||||
? sidebar.setAttribute("style", "visibility: visible;")
|
||||
: sidebar.setAttribute("style", "visibility: hidden;");
|
||||
}
|
After Width: | Height: | Size: 324 KiB |
After Width: | Height: | Size: 57 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 739 B |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 8.6 KiB |
|
@ -0,0 +1,14 @@
|
|||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
|
||||
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
|
||||
monospace;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import "./index.css";
|
||||
import App from "./App";
|
||||
|
||||
ReactDOM.render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
</React.StrictMode>,
|
||||
document.getElementById("root")
|
||||
);
|
|
@ -0,0 +1,53 @@
|
|||
import React from "react";
|
||||
import { LanguageContext } from "../component/Language/LanguageContext";
|
||||
|
||||
export default function Contact() {
|
||||
return (
|
||||
<LanguageContext.Consumer>
|
||||
{({ language }) => (
|
||||
<div id="modal-contact" className="modal">
|
||||
<h2>{language.pages.contact.title}</h2>
|
||||
<p>{language.pages.contact.text}</p>
|
||||
<a href="mailto:alexander@roese.dev">alexander@roese.dev</a>
|
||||
</div>
|
||||
)}
|
||||
</LanguageContext.Consumer>
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
<form>
|
||||
<label>Name</label>
|
||||
<input
|
||||
type="text"
|
||||
name="name"
|
||||
placeholder={language.pages.contact.name.placeholder}
|
||||
required
|
||||
/>
|
||||
|
||||
<label>Email</label>
|
||||
<input
|
||||
type="email"
|
||||
name="email"
|
||||
placeholder={language.pages.contact.email.placeholder}
|
||||
required
|
||||
/>
|
||||
|
||||
<label>{language.pages.contact.subject.text}</label>
|
||||
<input
|
||||
type="text"
|
||||
name="subject"
|
||||
placeholder={language.pages.contact.subject.placeholder}
|
||||
required
|
||||
/>
|
||||
|
||||
<label>{language.pages.contact.message.text}</label>
|
||||
<textarea
|
||||
name="message"
|
||||
placeholder={language.pages.contact.message.placeholder}
|
||||
required
|
||||
/>
|
||||
|
||||
<button type="submit">{language.pages.contact.submit}</button>
|
||||
</form>
|
||||
*/
|
|
@ -0,0 +1,13 @@
|
|||
import React from "react";
|
||||
import { LanguageContext } from "../component/Language/LanguageContext";
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<div id="modal-home" className="modal">
|
||||
<h1>Alexander Röse</h1>
|
||||
<LanguageContext.Consumer>
|
||||
{({ language }) => <p>{language.pages.home.text}</p>}
|
||||
</LanguageContext.Consumer>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
import React from "react";
|
||||
import {
|
||||
LanguageContext,
|
||||
languages,
|
||||
} from "../component/Language/LanguageContext";
|
||||
|
||||
const list = {
|
||||
german: [
|
||||
{
|
||||
name: "Privat",
|
||||
description: "Privates Projekt",
|
||||
language: "GoLang",
|
||||
date: "05/2021 - jetzt",
|
||||
},
|
||||
{
|
||||
link: "https://gitea.roese.dev/Alex/personal-website",
|
||||
name: "Diese Webseite",
|
||||
description: "Privates Projekt",
|
||||
language: "React.js, JavaScript, CSS, HTML, GoLang",
|
||||
date: "07/2021",
|
||||
},
|
||||
{
|
||||
link: "https://github.com/RuisPipe/PasswordManager",
|
||||
name: "Password Manager",
|
||||
description: "Eigener Passwortmanager",
|
||||
language: "JavaScript, CSS, HTML, Node.JS",
|
||||
date: "03/2020 - 12/2020",
|
||||
},
|
||||
],
|
||||
english: [
|
||||
{
|
||||
name: "Private",
|
||||
description: "Private project",
|
||||
language: "GoLang",
|
||||
date: "05/2021 - now",
|
||||
},
|
||||
{
|
||||
link: "https://gitea.roese.dev/Alex/personal-website",
|
||||
name: "This website",
|
||||
description: "Private project",
|
||||
language: "React.js, JavaScript, CSS, HTML, GoLang",
|
||||
date: "07/2021",
|
||||
},
|
||||
{
|
||||
link: "https://github.com/RuisPipe/PasswordManager",
|
||||
name: "Password Manager",
|
||||
description: "Self-hosted encrypted password manager",
|
||||
language: "JavaScript, CSS, HTML, Node.JS",
|
||||
date: "03/2020 - 12/2020",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
function RenderProjects(props) {
|
||||
if (props.language === languages.german) {
|
||||
return list.german.map((project, index) => (
|
||||
<tr key={"a" + index}>
|
||||
<td key={"b" + index}>
|
||||
<a href={project.link}>{project.name}</a>
|
||||
</td>
|
||||
<td key={"c" + index}>{project.description}</td>
|
||||
<td key={"d" + index}>{project.language}</td>
|
||||
<td key={"e" + index}>{project.date}</td>
|
||||
</tr>
|
||||
));
|
||||
}
|
||||
|
||||
return list.english.map((project, index) => (
|
||||
<tr key={"a" + index}>
|
||||
<td key={"b" + index}>
|
||||
{project.link === undefined ? (
|
||||
project.name
|
||||
) : (
|
||||
<a href={project.link}>{project.name}</a>
|
||||
)}
|
||||
</td>
|
||||
<td key={"c" + index}>{project.description}</td>
|
||||
<td key={"d" + index}>{project.language}</td>
|
||||
<td key={"e" + index}>{project.date}</td>
|
||||
</tr>
|
||||
));
|
||||
}
|
||||
|
||||
export default function Projects() {
|
||||
return (
|
||||
<LanguageContext.Consumer>
|
||||
{({ language }) => (
|
||||
<div id="modal-projects" className="modal">
|
||||
<h2>{language.pages.projects.title}</h2>
|
||||
<p>{language.pages.projects.description}</p>
|
||||
|
||||
<div>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>{language.pages.projects.tableTh.description}</th>
|
||||
<th>{language.pages.projects.tableTh.language}</th>
|
||||
<th>{language.pages.projects.tableTh.date}</th>
|
||||
</tr>
|
||||
|
||||
<RenderProjects language={language} />
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</LanguageContext.Consumer>
|
||||
);
|
||||
}
|