Added project

master
RuisPipe 2021-07-05 16:34:18 +02:00
commit 8f199075e6
26 changed files with 17391 additions and 0 deletions

3
README.md Normal file
View File

@ -0,0 +1,3 @@
# My Website
[Alexander Röse](https://roese.dev)

BIN
favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

16313
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

39
package.json Normal file
View File

@ -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"
]
}
}

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

17
public/index.html Normal file
View File

@ -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>

BIN
public/logo192.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

25
public/manifest.json Normal file
View File

@ -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"
}

3
public/robots.txt Normal file
View File

@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

399
src/App.css Normal file
View File

@ -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);
}
*/

49
src/App.js Normal file
View File

@ -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();
};

View File

@ -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: () => {},
});

View File

@ -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>
);
}
}

145
src/component/Navbar.js Normal file
View File

@ -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()}>
&#9776;
</li>
</ul>
<div className="nav-mobile">
<button onClick={() => closeNavMobile()}>&times;</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;");
}

73
src/component/Sidebar.js Normal file
View File

@ -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;");
}

BIN
src/img/background.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 KiB

BIN
src/img/discord.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

BIN
src/img/england.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
src/img/germany.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 739 B

BIN
src/img/gitea.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
src/img/github.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

14
src/index.css Normal file
View File

@ -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;
}

11
src/index.js Normal file
View File

@ -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")
);

53
src/routes/Contact.js Normal file
View File

@ -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>
*/

13
src/routes/Home.js Normal file
View File

@ -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>
);
}

110
src/routes/Projects.js Normal file
View File

@ -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>
);
}