1
0
Fork 0

Update projects and some improvements

This commit is contained in:
Moritz Ruth 2020-08-05 00:09:02 +02:00
parent 4158d6da05
commit 85dd304682
No known key found for this signature in database
GPG key ID: AFD57E23E753841B
14 changed files with 147 additions and 639 deletions

View file

@ -1,6 +1,6 @@
$background: white; $background: white;
$background-c: black; $background-c: black;
$pink: #BB2081; $pink: #bb2081;
$pink-c: white; $pink-c: white;
$blue: #14AAD8; $blue: #14AAD8;
$blue-c: white; $blue-c: white;

View file

@ -3,7 +3,6 @@
@use "./formatted"; @use "./formatted";
// General // General
html, body { html, body {
font-family: "Roboto Slab", sans-serif; font-family: "Roboto Slab", sans-serif;
font-size: 16px; font-size: 16px;
@ -18,8 +17,11 @@ html, body {
color: colors.$background-c; color: colors.$background-c;
} }
// Transitions ::selection {
background-color: rgba(229, 55, 162, 0.5);
}
// Transitions
.page-enter-active, .page-leave-active { .page-enter-active, .page-leave-active {
transition: 500ms ease opacity; transition: 500ms ease opacity;
} }
@ -33,7 +35,6 @@ html, body {
} }
// Other // Other
.content { .content {
@include content.content(); @include content.content();
} }

View file

@ -7,7 +7,7 @@
justify-content: flex-start; justify-content: flex-start;
align-items: center; align-items: center;
padding: 8px 15px; padding: 8px 12px 8px 20px;
border-radius: 4px; border-radius: 4px;
height: 30px; height: 30px;
@ -21,10 +21,8 @@
transition: 140ms ease background-color; transition: 140ms ease background-color;
&:hover, &:focus { &:hover, &:focus {
outline: none;
&:not(.my-button--disabled) { &:not(.my-button--disabled) {
background: transparentize(colors.$background-c, 0.9); background: transparentize(colors.$background-c, 0.94);
} }
} }
@ -96,6 +94,7 @@
text-transform: uppercase; text-transform: uppercase;
font-weight: bold; font-weight: bold;
font-size: 1.2rem; font-size: 1.2rem;
pointer-events: none;
} }
.my-button__prefix { .my-button__prefix {
@ -178,7 +177,7 @@
click: true, click: true,
400: true 400: true
}, },
value: "rgba(0, 0, 0, 0.5)" value: "rgba(0, 0, 0, 0.2)"
} }
], ],
attrs: { attrs: {

View file

@ -1,64 +0,0 @@
<template>
<footer class="my-footer">
<nuxt-link
v-for="item in $options.items"
:key="item.label"
class="my-footer__link"
:to="item.to"
@click.native.passive="open = false"
>
{{ item.label }}
</nuxt-link>
</footer>
</template>
<style lang="scss">
@use "~@/assets/styles/screenSize";
@use "~@/assets/styles/colors";
.my-footer {
display: flex;
justify-content: center;
align-items: center;
width: 100vw;
height: 100px;
opacity: 0.8;
transition: 200ms opacity linear;
&:hover {
opacity: 1;
}
}
.my-footer__link {
color: colors.$background-c;
text-decoration: none;
&:not(:last-child) {
margin-right: 20px;
}
}
@include screenSize.mobile {
.my-footer {
flex-direction: column;
margin-bottom: 10px;
}
.my-footer__link:not(:last-child) {
margin-right: 0;
margin-bottom: 10px;
}
}
</style>
<script>
import { footerItems } from "assets/js/footer-items"
export default {
name: "MyFooter",
items: footerItems
}
</script>

View file

@ -0,0 +1,18 @@
<style lang="scss">
</style>
<script>
export default {
name: "NavBarTitle",
mounted() {
this.$root.$emit("navbar-title", this.$slots.default[0].text)
},
beforeDestroy() {
this.$root.$emit("navbar-title", "")
},
render(createElement) {
return createElement("")
}
}
</script>

View file

@ -3,12 +3,9 @@
<div class="navigation-bar__placeholder"></div> <div class="navigation-bar__placeholder"></div>
<nav class="navigation-bar__content"> <nav class="navigation-bar__content">
<div class="navigation-bar__title-container"> <div class="navigation-bar__title-container">
<span <transition mode="out-in" name="fade">
class="navigation-bar__title" <span :key="title" class="navigation-bar__title">{{ title }}</span>
:class="{ 'navigation-bar__title--show': showTitle }" </transition>
>
{{ title }}
</span>
</div> </div>
<div class="navigation-bar__toggle" @click="open = !open"> <div class="navigation-bar__toggle" @click="open = !open">
<span></span> <span></span>
@ -22,11 +19,12 @@
class="navigation-bar__link" class="navigation-bar__link"
:exact="item.to === '/'" :exact="item.to === '/'"
:to="item.to" :to="item.to"
@click.native="open = false"
@mouseenter.native="e => handleLinkEvent(e, true)" @mouseenter.native="e => handleLinkEvent(e, true)"
@focus.native="e => handleLinkEvent(e, true)" @focus.native="e => handleLinkEvent(e, true)"
@mouseleave.native="e => handleLinkEvent(e, false)" @mouseleave.native="e => handleLinkEvent(e, false)"
@blur.native="e => handleLinkEvent(e, false)" @blur.native="e => handleLinkEvent(e, false)"
@keydown.enter.native="e => handleLinkEvent(e, false)"
@click.native="e => { open = false; handleLinkEvent(e, false) }"
> >
<span class="navigation-bar__link-text"> <span class="navigation-bar__link-text">
{{ item.label }} {{ item.label }}
@ -47,6 +45,14 @@
--navigation-bar-height: 80px; --navigation-bar-height: 80px;
} }
.fade-enter-active, .fade-leave-active {
transition: opacity 500ms;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
.navigation-bar__placeholder { .navigation-bar__placeholder {
height: var(--navigation-bar-height); height: var(--navigation-bar-height);
} }
@ -63,12 +69,10 @@
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
padding: 0 30px; padding: 0 30px 0 20px;
.navigation-bar--show-background & {
background: colors.$background; background: colors.$background;
} }
}
.navigation-bar__toggle { .navigation-bar__toggle {
position: relative; position: relative;
@ -102,20 +106,10 @@
} }
.navigation-bar__title { .navigation-bar__title {
font-size: 2rem; font-size: 1.8rem;
text-transform: uppercase; text-transform: uppercase;
font-weight: bold; font-weight: bold;
display: block; display: block;
opacity: 0;
transform: translateY(10px);
transition: 200ms ease;
transition-property: opacity, transform;
&.navigation-bar__title--show {
opacity: 1;
transform: translateY(0);
}
} }
.navigation-bar__links { .navigation-bar__links {
@ -245,7 +239,7 @@
} }
.navigation-bar__title { .navigation-bar__title {
font-size: 2.5rem; font-size: 2.2rem;
} }
.navigation-bar__toggle { .navigation-bar__toggle {
@ -291,40 +285,31 @@
export default { export default {
name: "NavigationBar", name: "NavigationBar",
props: {
backgroundAfterScroll: { type: Boolean },
title: { type: String, default: "" }
},
data: () => ({ data: () => ({
open: false, open: false,
scrollPosition: 0, hideActiveState: false,
hideActiveState: false title: ""
}), }),
computed: { computed: {
showTitle: vm => vm.scrollPosition > 60,
showBackground: vm => vm.backgroundAfterScroll ? vm.scrollPosition > 0 : true,
classes() { classes() {
const { open, showBackground, hideActiveState } = this const { open, hideActiveState } = this
return toModifierClasses("navigation-bar", { return toModifierClasses("navigation-bar", {
open, open,
showBackground,
hideActiveState hideActiveState
}) })
} }
}, },
mounted() { created() {
const scrollListener = () => { const handler = title => {
this.scrollPosition = window.scrollY this.title = title
} }
window.addEventListener("scroll", scrollListener, { passive: true }) this.$root.$on("navbar-title", handler)
this.$on("hook:beforeDestroy", () => { this.$on("hook:beforeDestroy", () => {
window.removeEventListener("scroll", scrollListener) this.$root.$off("navbar-title", handler)
}) })
scrollListener()
}, },
methods: { methods: {
handleLinkEvent(event, hideActiveStateNow) { handleLinkEvent(event, hideActiveStateNow) {

View file

@ -2,17 +2,15 @@
<div class="my-project"> <div class="my-project">
<div class="my-project__content"> <div class="my-project__content">
<h2 class="my-project__title"> <h2 class="my-project__title">
{{ title }} {{ project.emoji }} {{ project.title }}
</h2> </h2>
<span class="my-project__kind">{{ kind }}</span> <span class="my-project__type">{{ project.type }}</span>
<div class="my-project__description"> <div class="my-project__description" v-html="project.description"></div>
<slot/> <div v-if="project.links" class="my-project__links">
</div>
<div v-if="github || npm || url" class="my-project__links">
<MyButton <MyButton
v-if="url !== ''" v-if="project.links.open"
class="my-project__link" class="my-project__link"
:href="url" :href="project.links.open"
> >
<template v-slot:prefix> <template v-slot:prefix>
<PointerRightIcon class="my-project__link-icon"/> <PointerRightIcon class="my-project__link-icon"/>
@ -20,9 +18,9 @@
Open Open
</MyButton> </MyButton>
<MyButton <MyButton
v-if="github !== ''" v-if="project.links.github"
class="my-project__link" class="my-project__link"
:href="`https://github.com/${github}`" :href="`https://github.com/${project.links.github}`"
> >
<template v-slot:prefix> <template v-slot:prefix>
<GitHubIcon class="my-project__link-icon"/> <GitHubIcon class="my-project__link-icon"/>
@ -30,14 +28,14 @@
GitHub GitHub
</MyButton> </MyButton>
<MyButton <MyButton
v-if="npm !== ''" v-if="project.links.npm"
class="my-project__link" class="my-project__link"
:href="`https://npmjs.com/${npm}`" :href="`https://npmjs.com/${project.links.npm}`"
> >
<template v-slot:prefix> <template v-slot:prefix>
<NPMIcon class="my-project__link-icon"/> <NPMIcon class="my-project__link-icon my-project__link-icon--npm"/>
</template> </template>
NPM npm
</MyButton> </MyButton>
</div> </div>
</div> </div>
@ -70,7 +68,7 @@
font-size: 1.8rem; font-size: 1.8rem;
} }
.my-project__kind { .my-project__type {
display: block; display: block;
font-size: 1rem; font-size: 1rem;
@ -84,7 +82,7 @@
margin-top: 10px; margin-top: 10px;
display: grid; display: grid;
gap: 5px; gap: 2px;
grid-auto-flow: column; grid-auto-flow: column;
grid-auto-columns: min-content; grid-auto-columns: min-content;
grid-auto-rows: min-content; grid-auto-rows: min-content;
@ -99,6 +97,12 @@
height: 25px!important; height: 25px!important;
} }
.my-project__link-icon--npm {
height: 32px!important;
position: relative;
top: 1px;
}
@media (max-width: 500px) { @media (max-width: 500px) {
.my-project__links { .my-project__links {
grid-template-columns: 1fr; grid-template-columns: 1fr;
@ -117,25 +121,9 @@
name: "MyProject", name: "MyProject",
components: { MyButton, GitHubIcon, NPMIcon, PointerRightIcon }, components: { MyButton, GitHubIcon, NPMIcon, PointerRightIcon },
props: { props: {
title: { project: {
type: String, type: Object,
required: true required: true
},
kind: {
type: String,
required: true
},
npm: {
type: String,
default: ""
},
github: {
type: String,
default: ""
},
url: {
type: String,
default: ""
} }
} }
} }

View file

@ -1,7 +1,7 @@
<template> <template>
<div class="default-layout"> <div class="default-layout">
<NavigationBar/>
<nuxt/> <nuxt/>
<MyFooter/>
</div> </div>
</template> </template>
@ -14,10 +14,10 @@
</style> </style>
<script> <script>
import MyFooter from "@/components/MyFooter" import NavigationBar from "@/components/NavigationBar"
export default { export default {
name: "DefaultLayout", name: "DefaultLayout",
components: { MyFooter } components: { NavigationBar }
} }
</script> </script>

View file

@ -1,13 +0,0 @@
<template>
<nuxt/>
</template>
<style>
</style>
<script>
export default {
name: "EmptyLayout"
}
</script>

View file

@ -7,7 +7,7 @@ export default {
** Headers of the page ** Headers of the page
*/ */
head: { head: {
titleTemplate: `%s | ${manifest.name}`, titleTemplate: `%s ${manifest.name}`,
link: [ link: [
{ rel: "icon", type: "image/x-icon", href: "/favicon.ico" }, { rel: "icon", type: "image/x-icon", href: "/favicon.ico" },
{ rel: "stylesheet", href: "https://fonts.googleapis.com/css2?family=Roboto+Slab:wght@400;600&display=swap" } { rel: "stylesheet", href: "https://fonts.googleapis.com/css2?family=Roboto+Slab:wght@400;600&display=swap" }
@ -26,7 +26,9 @@ export default {
/* /*
** Plugins to load before mounting the App ** Plugins to load before mounting the App
*/ */
plugins: ["@/plugins/vue-ripple-directive"], plugins: [
"@/plugins/vue-ripple-directive"
],
/* /*
** Nuxt.js dev-modules ** Nuxt.js dev-modules
*/ */

View file

@ -1,6 +1,5 @@
<template> <template>
<div class="index-page"> <div class="index-page">
<NavigationBar background-after-scroll title="Start"/>
<canvas ref="canvas" class="index-page__background"/> <canvas ref="canvas" class="index-page__background"/>
<main class="index-page__content"> <main class="index-page__content">
<AnimatedLogo/> <AnimatedLogo/>
@ -12,8 +11,7 @@
><InstagramIcon class="index-page__social-icon"/></a> ><InstagramIcon class="index-page__social-icon"/></a>
<a <a
class="index-page__social" class="index-page__social"
href="httpsU href="https://twitter.com/moritz_ruth"
://twitter.com/moritz_ruth"
title="Twitter" title="Twitter"
><TwitterIcon class="index-page__social-icon"/></a> ><TwitterIcon class="index-page__social-icon"/></a>
<a <a
@ -32,17 +30,6 @@
><EmailIcon class="index-page__social-icon"/></a> ><EmailIcon class="index-page__social-icon"/></a>
</div> </div>
</main> </main>
<footer class="index-page__footer">
<nuxt-link
v-for="item in $options.footerItems"
:key="item.label"
class="index-page__footer-link"
:to="item.to"
@click.native.passive="() => { open = null }"
>
{{ item.label }}
</nuxt-link>
</footer>
</div> </div>
</template> </template>
@ -118,43 +105,11 @@
color: colors.$background-c; color: colors.$background-c;
height: 40px; height: 40px;
} }
.index-page__footer {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 20px;
opacity: 0.8;
transition: 200ms linear opacity;
&:hover {
opacity: 1;
}
.index-page__footer-link {
text-decoration: none;
color: colors.$background-c;
&:not(:last-child) {
margin-right: 20px;
}
}
}
@include screenSize.mobile {
.index-page__social-icon {
height: 30px;
}
}
</style> </style>
<script> <script>
import { ShapedCanvas } from "shaped.js" import { ShapedCanvas } from "shaped.js"
import AnimatedLogo from "@/components/AnimatedLogo" import AnimatedLogo from "@/components/AnimatedLogo"
import NavigationBar from "@/components/NavigationBar"
import { footerItems } from "assets/js/footer-items" import { footerItems } from "assets/js/footer-items"
import InstagramIcon from "@/assets/icons/instagram.svg" import InstagramIcon from "@/assets/icons/instagram.svg"
import TwitterIcon from "@/assets/icons/twitter.svg" import TwitterIcon from "@/assets/icons/twitter.svg"
@ -164,8 +119,7 @@
export default { export default {
name: "IndexPage", name: "IndexPage",
layout: "empty", components: { AnimatedLogo, InstagramIcon, TwitterIcon, NPMIcon, GitHubIcon, EmailIcon },
components: { NavigationBar, AnimatedLogo, InstagramIcon, TwitterIcon, NPMIcon, GitHubIcon, EmailIcon },
mounted() { mounted() {
const shaped = new ShapedCanvas(this.$refs.canvas, { const shaped = new ShapedCanvas(this.$refs.canvas, {
useWindowSize: true, useWindowSize: true,

View file

@ -1,79 +0,0 @@
<template>
<div class="legal-notice-page">
<NavigationBar title="Impressum"/>
<main class="content">
<h1 class="heading--1">
Impressum
</h1>
<h2 class="heading--3">
Diensteanbieter
</h2>
<p class="paragraph">
Moritz Ruth<br>
Zum Galgenberg 19<br>
66539 Neunkirchen<br>
Deutschland
</p>
<h2 class="heading--3">
Kontaktmöglichkeiten
</h2>
<p class="paragraph">
<b>Telefon</b>: +49 176 46146329
</p>
<p class="paragraph">
<b>E-Mail</b>: <a class="link" href="mailto:legal@moritz-ruth.de">legal@moritz-ruth.de</a>
</p>
<h2 class="heading--3">
Haftungs- und Urheberrechtshinweise
</h2>
<p class="paragraph">
<b>Haftungsausschluss</b>:
Die Inhalte dieses Onlineangebotes wurden sorgfältig und nach unserem aktuellen Kenntnisstand
erstellt, dienen jedoch nur der Information und entfalten keine rechtlich bindende Wirkung, sofern es sich nicht
um gesetzlich verpflichtende Informationen (z.B. das Impressum, die Datenschutzerklärung, AGB oder
Widerrufsbelehrungen für Verbraucher) handelt. Wir behalten uns vor, die Inhalte vollständig oder teilweise zu
ändern oder zu löschen, soweit vertragliche Verpflichtungen unberührt bleiben. Alle Angebote sind freibleibend
und unverbindlich.
</p>
<p class="paragraph">
<b>Links auf fremde Webseiten</b>:
Inhalte fremder Webseiten, auf die wir direkt oder indirekt verweisen, liegen
außerhalb unseres Verantwortungsbereiches und machen wir uns nicht zu Eigen. Für alle Inhalte und insbesondere
für Schäden, die aus der Nutzung der in den verlinkten Webseiten aufrufbaren Informationen entstehen, haftet
allein der Anbieter der verlinkten Webseiten.
</p>
<p class="paragraph">
<b>Urheberrechte und Markenrechte</b>:
Alle auf dieser Website dargestellten Inhalte, wie Texte, Fotografien, Grafiken,
Marken und Warenzeichen sind durch die jeweiligen Schutzrechte (Urheberrechte, Markenrechte) geschützt. Die
Verwendung, Vervielfältigung usw. unterliegen unseren Rechten oder den Rechten der jeweiligen Urheber bzw.
Rechteverwalter.
</p>
<p class="paragraph">
<b>Hinweise auf Rechtsverstöße</b>:
Sollten Sie innerhalb unseres Internetauftritts Rechtsverstöße bemerken, bitten wir
Sie uns auf diese hinzuweisen. Wir werden rechtswidrige Inhalte und Links nach Kenntnisnahme unverzüglich
entfernen.
</p>
<a
class="link"
href="https://datenschutz-generator.de/?l=de"
rel="noopener"
target="_blank"
>Erstellt mit kostenlosem Datenschutz-Generator.de von Dr. Thomas Schwenke</a>
</main>
</div>
</template>
<script>
import NavigationBar from "../components/NavigationBar"
export default {
name: "LegalNoticePage",
components: { NavigationBar },
head: () => ({
htmlAttrs: { lang: "de" },
title: "Legal notice"
})
}
</script>

View file

@ -1,298 +0,0 @@
<template>
<div class="privacy-policy-page">
<NavigationBar title="Datenschutz"/>
<div class="content formatted">
<h1>
Datenschutzerklärung
</h1>
<p>
Verantwortlicher im Sinne der Datenschutzgesetze, insbesondere der EU-Datenschutzgrundverordnung (DSGVO), ist:
</p>
<p>
Moritz Ruth<br>
Zum Galgenberg 19<br>
66539 Neunkirchen<br>
Deutschland
</p>
<h2>
Ihre Betroffenenrechte
</h2>
<p>
Unter den angegebenen Kontaktdaten unseres Datenschutzbeauftragten können Sie jederzeit folgende Rechte ausüben:
</p>
<ul>
<li>Auskunft über Ihre bei uns gespeicherten Daten und deren Verarbeitung (Art. 15 DSGVO),</li>
<li>Berichtigung unrichtiger personenbezogener Daten (Art. 16 DSGVO),</li>
<li>Löschung Ihrer bei uns gespeicherten Daten (Art. 17 DSGVO),</li>
<li>
Einschränkung der Datenverarbeitung, sofern wir Ihre Daten aufgrund gesetzlicher Pflichten noch nicht löschen
dürfen (Art. 18 DSGVO),
</li>
<li>Widerspruch gegen die Verarbeitung Ihrer Daten bei uns (Art. 21 DSGVO) und</li>
<li>
Datenübertragbarkeit, sofern Sie in die Datenverarbeitung eingewilligt haben oder einen Vertrag mit uns
abgeschlossen haben (Art. 20 DSGVO).
</li>
</ul>
<p>
Sofern Sie uns eine Einwilligung erteilt haben, können Sie diese jederzeit mit Wirkung für die Zukunft
widerrufen.
</p>
<p>
Sie können sich jederzeit mit einer Beschwerde an eine Aufsichtsbehörde wenden, z. B. an die zuständige
Aufsichtsbehörde des Bundeslands Ihres Wohnsitzes oder an die für uns als verantwortliche Stelle zuständige
Behörde.
</p>
<p>
Eine Liste der Aufsichtsbehörden (für den nichtöffentlichen Bereich) mit Anschrift finden Sie unter:
<ExternalLink href="https://www.bfdi.bund.de/DE/Infothek/Anschriften_Links/anschriften_links-node.html"/>.
</p>
<h2>
Erfassung allgemeiner Informationen beim Besuch unserer Website
</h2>
<h3>
Art und Zweck der Verarbeitung
</h3>
<p>
Wenn Sie auf unsere Website zugreifen, d.h., wenn Sie sich nicht registrieren oder anderweitig Informationen
übermitteln, werden automatisch Informationen allgemeiner Natur erfasst. Diese Informationen (Server-Logfiles)
beinhalten etwa die Art des Webbrowsers, das verwendete Betriebssystem, den Domainnamen Ihres
Internet-Service-Providers, Ihre IP-Adresse und ähnliches.
</p>
<p>
Sie werden insbesondere zu folgenden Zwecken verarbeitet
</p>
<ul>
<li>Sicherstellung eines problemlosen Verbindungsaufbaus der Website,</li>
<li>Sicherstellung einer reibungslosen Nutzung unserer Website,</li>
<li>Auswertung der Systemsicherheit und -stabilität sowie</li>
<li>zu weiteren administrativen Zwecken.</li>
</ul>
<p>
Wir verwenden Ihre Daten nicht, um Rückschlüsse auf Ihre Person zu ziehen. Informationen dieser Art werden von
uns ggfs. statistisch ausgewertet, um unseren Internetauftritt und die dahinterstehende Technik zu
optimieren.
</p>
<h3>
Rechtsgrundlage
</h3>
<p>
Die Verarbeitung erfolgt gemäß Art. 6 Abs. 1 lit. f DSGVO auf Basis unseres berechtigten Interesses an der
Verbesserung der Stabilität und Funktionalität unserer Website.
</p>
<h3>
Empfänger
</h3>
<p>
Empfänger der Daten sind ggf. technische Dienstleister, die für den Betrieb und die Wartung unserer Webseite als
Auftragsverarbeiter tätig werden.
</p>
<h3>
Speicherdauer
</h3>
<p>
Die Daten werden gelöscht, sobald diese für den Zweck der Erhebung nicht mehr erforderlich sind. Dies ist für
die Daten, die der Bereitstellung der Webseite dienen, grundsätzlich der Fall, wenn die jeweilige Sitzung
beendet ist.
</p>
<h3>
Bereitstellung vorgeschrieben oder erforderlich
</h3>
<p>
Die Bereitstellung der vorgenannten personenbezogenen Daten ist weder gesetzlich noch vertraglich
vorgeschrieben. Ohne die IP-Adresse ist jedoch der Dienst und die Funktionsfähigkeit unserer Website nicht
gewährleistet. Zudem können einzelne Dienste und Services nicht verfügbar oder eingeschränkt sein. Aus diesem
Grund ist ein Widerspruch ausgeschlossen.
</p>
<h2>
Verwendung von Scriptbibliotheken (Google Webfonts)
</h2>
<h3>
Art und Zweck der Verarbeitung
</h3>
<p>
Um unsere Inhalte browserübergreifend korrekt und grafisch ansprechend darzustellen, verwenden wir auf dieser
Website Google Web Fonts der Google LLC (1600 Amphitheatre Parkway, Mountain View, CA 94043, USA; nachfolgend
Google) zur Darstellung von Schriften.
</p>
<p>
Die Datenschutzrichtlinie des Bibliothekbetreibers Google finden Sie hier:
<ExternalLink href="https://www.google.com/policies/privacy/"/>
</p>
<h3>
Rechtsgrundlage
</h3>
<p>
Rechtsgrundlage für die Einbindung von Google Webfonts und dem damit verbundenen Datentransfer zu Google ist
Ihre Einwilligung (Art. 6 Abs. 1 lit. a DSGVO).
</p>
<h3>
Empfänger
</h3>
<p>
Der Aufruf von Scriptbibliotheken oder Schriftbibliotheken löst automatisch eine Verbindung zum Betreiber der
Bibliothek aus. Dabei ist es theoretisch möglich aktuell allerdings auch unklar ob und ggf. zu welchen Zwecken
dass der Betreiber in diesem Fall Google Daten erhebt.
</p>
<h3>
Speicherdauer
</h3>
<p>
Wir erheben keine personenbezogenen Daten, durch die Einbindung von Google Webfonts.
</p>
<p>
Weitere Informationen zu Google Web Fonts finden Sie unter
<ExternalLink href="https://developers.google.com/fonts/faq"/> und in der Datenschutzerklärung von Google:
<ExternalLink href="https://www.google.com/policies/privacy/"/>.
</p>
<h3>
Drittlandtransfer
</h3>
<p>
Google verarbeitet Ihre Daten in den USA und hat sich dem EU_US Privacy Shield unterworfen
<ExternalLink href="https://www.privacyshield.gov/EU-US-Framework"/>.
</p>
<h3>
Bereitstellung vorgeschrieben oder erforderlich
</h3>
<p>
Die Bereitstellung der personenbezogenen Daten ist weder gesetzlich, noch vertraglich vorgeschrieben. Allerdings
kann ggfs. die korrekte Darstellung der Inhalte durch Standardschriften nicht möglich sein.
</p>
<h3>
Widerruf der Einwilligung
</h3>
<p>
Zur Darstellung der Inhalte wird regelmäßig die Programmiersprache JavaScript verwendet. Sie können der
Datenverarbeitung daher widersprechen, indem Sie die Ausführung von JavaScript in Ihrem Browser deaktivieren
oder einen JavaScript-Blocker installieren. Bitte beachten Sie, dass es hierdurch zu Funktionseinschränkungen
auf der Website kommen kann.
</p>
<h2>
Eingebettete YouTube-Videos
</h2>
<h3>
Art und Zweck der Verarbeitung
</h3>
<p>
Auf einigen unserer Webseiten betten wir YouTube-Videos ein. Betreiber der entsprechenden Plugins ist die
YouTube, LLC, 901 Cherry Ave., San Bruno, CA 94066, USA (nachfolgend YouTube). Wenn Sie eine Seite mit dem
YouTube-Plugin besuchen, wird eine Verbindung zu Servern von YouTube hergestellt. Dabei wird YouTube mitgeteilt,
welche Seiten Sie besuchen. Wenn Sie in Ihrem YouTube-Account eingeloggt sind, kann YouTube Ihr Surfverhalten
Ihnen persönlich zuzuordnen. Dies verhindern Sie, indem Sie sich vorher aus Ihrem YouTube-Account ausloggen.
</p>
<p>
Wird ein YouTube-Video gestartet, setzt der Anbieter Cookies ein, die Hinweise über das Nutzerverhalten sammeln.
</p>
<p>
Weitere Informationen zu Zweck und Umfang der Datenerhebung und ihrer Verarbeitung durch YouTube erhalten Sie in
den Datenschutzerklärungen des Anbieters, Dort erhalten Sie auch weitere Informationen zu Ihren diesbezüglichen
Rechten und Einstellungsmöglichkeiten zum Schutze Ihrer Privatsphäre
(<ExternalLink href="https://policies.google.com/privacy"/>). Google verarbeitet Ihre Daten in den USA und hat
sich dem EU-US Privacy Shield unterworfen <ExternalLink href="https://www.privacyshield.gov/EU-US-Framework"/>.
</p>
<h3>
Rechtsgrundlage
</h3>
<p>
Rechtsgrundlage für die Einbindung von YouTube und dem damit verbundenen Datentransfer zu Google ist Ihre
Einwilligung (Art. 6 Abs. 1 lit. a DSGVO).
</p>
<h3>
Empfänger
</h3>
<p>
Der Aufruf von YouTube löst automatisch eine Verbindung zu Google aus.
</p>
<h3>
Speicherdauer und Widerruf der Einwilligung:
</h3>
<p>
Wer das Speichern von Cookies für das Google-Ad-Programm deaktiviert hat, wird auch beim Anschauen von
YouTube-Videos mit keinen solchen Cookies rechnen müssen. YouTube legt aber auch in anderen Cookies
nicht-personenbezogene Nutzungsinformationen ab. Möchten Sie dies verhindern, so müssen Sie das Speichern von
Cookies im Browser blockieren.
</p>
<p>
Weitere Informationen zum Datenschutz bei YouTube finden Sie in der Datenschutzerklärung des Anbieters unter:
<ExternalLink href="https://www.google.de/intl/de/policies/privacy/"/>
</p>
<h3>
Drittlandtransfer
</h3>
<p>
Google verarbeitet Ihre Daten in den USA und hat sich dem EU_US Privacy Shield unterworfen
<ExternalLink href="https://www.privacyshield.gov/EU-US-Framework"/>.
</p>
<h3>
Bereitstellung vorgeschrieben oder erforderlich
</h3>
<p>
Die Bereitstellung Ihrer personenbezogenen Daten erfolgt freiwillig, allein auf Basis Ihrer Einwilligung. Sofern
Sie den Zugriff unterbinden, kann es hierdurch zu Funktionseinschränkungen auf der Website kommen.
</p>
<h2>
SSL-Verschlüsselung
</h2>
<p>
Um die Sicherheit Ihrer Daten bei der Übertragung zu schützen, verwenden wir dem aktuellen Stand der Technik
entsprechende Verschlüsselungsverfahren (z. B. SSL) über HTTPS.
</p>
<h2>
Änderung unserer Datenschutzbestimmungen
</h2>
<p>
Wir behalten uns vor, diese Datenschutzerklärung anzupassen, damit sie stets den aktuellen rechtlichen
Anforderungen entspricht oder um Änderungen unserer Leistungen in der Datenschutzerklärung umzusetzen, z.B. bei
der Einführung neuer Services. Für Ihren erneuten Besuch gilt dann die neue Datenschutzerklärung.
</p>
<h2>
Fragen an den Datenschutzbeauftragten
</h2>
<p>
Wenn Sie Fragen zum Datenschutz haben, schreiben Sie uns bitte eine E-Mail oder wenden Sie sich direkt an die
für den Datenschutz verantwortliche Person:
</p>
<p>
Moritz Ruth<br>
Zum Galgenberg 19<br>
66539 Neunkirchen<br>
Deutschland
</p>
<p>
<b>Telefon</b>: +49 176 46146329
</p>
<p>
<b>E-Mail</b>: <a class="link" href="mailto:legal@moritz-ruth.de">legal@moritz-ruth.de</a>
</p>
<p>
Die Datenschutzerklärung wurde mithilfe der activeMind AG erstellt, den Experten für
<ExternalLink
href="https://www.activemind.de/datenschutz/datenschutzhinweis-generator/"
>
externe Datenschutzbeauftragte
</ExternalLink>.
</p>
</div>
</div>
</template>
<style scoped lang="scss">
.privacy-policy-page {
overflow-y: auto;
}
</style>
<script>
import ExternalLink from "@/components/ExternalLink"
import NavigationBar from "@/components/NavigationBar"
export default {
name: "PrivacyPolicyPage",
components: { NavigationBar, ExternalLink },
head: () => ({
htmlAttrs: { lang: "de" },
title: "Privacy Policy"
})
}
</script>

View file

@ -1,52 +1,13 @@
<template> <template>
<div class="projects-page"> <div class="projects-page">
<NavigationBar title="Projects"/> <NavBarTitle>Projects</NavBarTitle>
<main class="content"> <main class="content">
<h1 class="heading--1 projects-page__heading">
Projects
</h1>
<div class="projects-page__projects"> <div class="projects-page__projects">
<MyProject <MyProject
title="shaped.js" v-for="project in $options.projects"
kind="JavaScript Library" :key="project.title"
github="moritzruth/shaped.js" :project="project"
npm="shaped.js" />
>
Generate amazing animated backgrounds using only a canvas element.
<nuxt-link to="/" class="link">See it in action on the home page.</nuxt-link>
</MyProject>
<MyProject
title="Schweredruck-Simulation"
kind="Web App (german)"
github="moritzruth/schweredruck-simulation"
url="https://app.moritzruth.de/schweredruck-simulation/"
>
Calculate and visualize the hydrostatic pressure in different liquids.
</MyProject>
<MyProject
title="log-groups"
kind="Node.js Package"
github="moritzruth/log-groups"
npm="log-groups"
>
Print console log messages in groups.
</MyProject>
<MyProject
title="node-enttec-open-dmx-usb"
kind="Node.js Package"
github="moritzruth/node-enttec-open-dmx-usb"
npm="enttec-open-dmx-usb"
>
Use the Enttec Open DMX USB Interface with Node.js.
</MyProject>
<MyProject
title="eslint-config"
kind="ESLint Configuration"
github="moritzruth/eslint-config"
npm="@moritzruth/eslint-config"
>
My personal ESLint configuration.
</MyProject>
</div> </div>
</main> </main>
</div> </div>
@ -55,8 +16,9 @@
<style lang="scss"> <style lang="scss">
@use "~@/assets/styles/colors"; @use "~@/assets/styles/colors";
.projects-page__heading { .projects-page {
margin-top: 0; padding-top: 20px;
padding-bottom: 50px;
} }
.projects-page__projects { .projects-page__projects {
@ -67,12 +29,65 @@
</style> </style>
<script> <script>
import NavigationBar from "@/components/NavigationBar"
import MyProject from "@/components/pages/projects/MyProject" import MyProject from "@/components/pages/projects/MyProject"
import NavBarTitle from "~/components/NavBarTitle"
const projects = [
{
title: "log-groups",
type: "Node.js package",
emoji: "🍱",
description: "Log messages ... in groups.",
links: {
github: "moritzruth/log-groups",
npm: "log-groups"
}
},
{
title: "shaped.js",
type: "JavaScript package",
emoji: "🍭",
description: "Generate cool moving shapes using a canvas element. You can see it in action on the home page.",
links: {
github: "moritzruth/shaped.js",
npm: "shaped.js"
}
},
{
title: "node-enttec-open-dmx-usb",
type: "Node.js package",
emoji: "🔌",
description: "A Node.js library for interacting with the Enttec Open DMX USB Interface.",
links: {
github: "moritzruth/node-enttec-open-dmx-usb",
npm: "enttec-open-dmx-usb"
}
},
{
title: "eslint-config-awzzm",
type: "ESLint configurations",
emoji: "⚙️",
description: "ESLint configurations for JavaScript, TypeScript, Node.js, Vue.js and Nuxt.js.",
links: {
github: "moritzruth/eslint-config-awzzm",
npm: "eslint-config-awzzm"
}
},
{
title: "spigot-ttt",
type: "Spigot plugin",
emoji: "🔫",
description: "Trouble in Terrorist Town, ported to Minecraft as a Spigot plugin. I'll provide downloads soon.",
links: {
github: "moritzruth/spigot-ttt"
}
}
]
export default { export default {
name: "ProjectsPage", name: "ProjectsPage",
components: { MyProject, NavigationBar }, components: { NavBarTitle, MyProject },
head: () => ({ title: "Projects" }) head: () => ({ title: "Projects" }),
projects
} }
</script> </script>