mirror of
https://github.com/Unkn0wnCat/KevinK.dev.js.git
synced 2025-06-18 18:42:05 +02:00
Rework homepage concept
This commit is contained in:
parent
07c240be4f
commit
b50b7d83c3
11 changed files with 548 additions and 222 deletions
|
@ -1,36 +1,45 @@
|
||||||
{
|
{
|
||||||
"siteDescription": "Hallo, ich bin Kevin Kandlbinder, ein Entwickler und Hobby-Fotograf aus Norddeutschland.",
|
"siteDescription": "Hallo, ich bin Kevin Kandlbinder, ein Entwickler und Hobby-Fotograf aus Norddeutschland.",
|
||||||
"imprint": "Impressum",
|
"imprint": "Impressum",
|
||||||
"datasec": "Datenschutz",
|
"datasec": "Datenschutz",
|
||||||
"disclaimer": "Disclaimer",
|
"disclaimer": "Disclaimer",
|
||||||
"projects": "Projekte",
|
"projects": "Projekte",
|
||||||
"project": "Projekt",
|
"project": "Projekt",
|
||||||
"social": "Soziales",
|
"social": "Soziales",
|
||||||
"homeHello": "Hallo, ich bin",
|
"homeHello": "Hallo, ich bin",
|
||||||
"homeMe": "Ich bin",
|
"homeMe": "Ich bin",
|
||||||
"homeWebDeveloper": "Web Developer",
|
"homeWebDeveloper": "Web Developer",
|
||||||
"homeMyLocation": "Quickborn, Schleswig-Holstein, Deutschland",
|
"homeMyLocation": "Quickborn, Schleswig-Holstein, Deutschland",
|
||||||
"donationCatchphrase": "Gefällt dir was du siehst? Spende doch etwas.",
|
"donationCatchphrase": "Gefällt dir was du siehst? Spende doch etwas.",
|
||||||
"homeImageCredit": "Portrait aufgenommen von Jannik Kiel",
|
"homeImageCredit": "Portrait aufgenommen von Jannik Kiel",
|
||||||
"de": "Deutsch",
|
"de": "Deutsch",
|
||||||
"en": "Englisch",
|
"en": "Englisch",
|
||||||
"projectAboutHeader": "Über {{projectName}}",
|
"projectAboutHeader": "Über {{projectName}}",
|
||||||
"projectViewGitHub": "Auf GitHub anschauen",
|
"projectViewGitHub": "Auf GitHub anschauen",
|
||||||
"projectViewWebsite": "Projekt-Website anschauen",
|
"projectViewWebsite": "Projekt-Website anschauen",
|
||||||
"projectsDescription": "Das ist woran ich grade arbeite oder woran ich gearbeitet habe.",
|
"projectsDescription": "Das ist woran ich grade arbeite oder woran ich gearbeitet habe.",
|
||||||
"projectView": "Anschauen",
|
"projectView": "Anschauen",
|
||||||
"socialDescriptionWithLink": "Finde mich auf anderen Plattformen oder <1>besuche meine Freunde</1>!",
|
"socialDescriptionWithLink": "Finde mich auf anderen Plattformen oder <1>besuche meine Freunde</1>!",
|
||||||
"socialDescription": "Finde mich auf anderen Plattformen!",
|
"socialDescription": "Finde mich auf anderen Plattformen!",
|
||||||
"friends": "Freunde",
|
"friends": "Freunde",
|
||||||
"friendsDescription": "In dieser Liste stehen Freunde von mir und meiner Seite. Schau doch bei ihnen mal rein, wenn du mehr interessante Projekte sehen willst.",
|
"friendsDescription": "In dieser Liste stehen Freunde von mir und meiner Seite. Schau doch bei ihnen mal rein, wenn du mehr interessante Projekte sehen willst.",
|
||||||
"donateThanksText": "Ich finde es schön, dass du meine Arbeit schön findest und das zeigst! Sende mir gerne eine E-Mail an <1>{{contactEmail}}</1> wenn du mit mir über irgendwas reden möchtest!",
|
"donateThanksText": "Ich finde es schön, dass du meine Arbeit schön findest und das zeigst! Sende mir gerne eine E-Mail an <1>{{contactEmail}}</1> wenn du mit mir über irgendwas reden möchtest!",
|
||||||
"donateThanks": "Danke für die Spende!",
|
"donateThanks": "Danke für die Spende!",
|
||||||
"donateDescription": "Hey! Es sieht so aus als würdest du über eine Spende nachdenken. Das ist nett! Wenn du ein bestimmtes Projekt unterstützen willst, schreibe deine Wünsche gerne in den Spendenkommentar.",
|
"donateDescription": "Hey! Es sieht so aus als würdest du über eine Spende nachdenken. Das ist nett! Wenn du ein bestimmtes Projekt unterstützen willst, schreibe deine Wünsche gerne in den Spendenkommentar.",
|
||||||
"donate": "Spenden",
|
"donate": "Spenden",
|
||||||
"featuredProjects": "Vorgestellte Projekte",
|
"featuredProjects": "Vorgestellte Projekte",
|
||||||
"seeMore": "Mehr Projekte erkunden",
|
"seeMore": "Mehr Projekte erkunden",
|
||||||
"donateGitHub": "Du kannst mich mit dem folgenden Button ganz einfach über GitHub Sponsors unterstützen!",
|
"donateGitHub": "Du kannst mich mit dem folgenden Button ganz einfach über GitHub Sponsors unterstützen!",
|
||||||
"donatePayPal": "Wenn du mich lieber über PayPal unterstützen willst ist hier der Button für dich:",
|
"donatePayPal": "Wenn du mich lieber über PayPal unterstützen willst ist hier der Button für dich:",
|
||||||
"sponsorGitHub": "Über GitHub unterstützen",
|
"sponsorGitHub": "Über GitHub unterstützen",
|
||||||
"mySkills": "Meine Fähigkeiten"
|
"mySkills": "Meine Fähigkeiten",
|
||||||
|
"about": "Über",
|
||||||
|
"explore": "Erkunde",
|
||||||
|
"myProjects": "meine Projekte",
|
||||||
|
"discover": "Entdecke",
|
||||||
|
"mySocials": "meine Accounts",
|
||||||
|
"learn": "Erfahre",
|
||||||
|
"moreAboutMe": "mehr über mich",
|
||||||
|
"home": "Home",
|
||||||
|
"menu": "Menü"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,36 +1,45 @@
|
||||||
{
|
{
|
||||||
"siteDescription": "Hello, I am Kevin Kandlbinder, a developer and hobby photographer from northern Germany.",
|
"siteDescription": "Hello, I am Kevin Kandlbinder, a developer and hobby photographer from northern Germany.",
|
||||||
"imprint": "Imprint",
|
"imprint": "Imprint",
|
||||||
"datasec": "Data Protection",
|
"datasec": "Data Protection",
|
||||||
"disclaimer": "Disclaimer",
|
"disclaimer": "Disclaimer",
|
||||||
"projects": "Projects",
|
"projects": "Projects",
|
||||||
"project": "Project",
|
"project": "Project",
|
||||||
"social": "Social",
|
"social": "Social",
|
||||||
"homeHello": "Hello, I am",
|
"homeHello": "Hello, I am",
|
||||||
"homeMe": "I am",
|
"homeMe": "I am",
|
||||||
"homeWebDeveloper": "a web developer",
|
"homeWebDeveloper": "a web developer",
|
||||||
"homeMyLocation": "Quickborn, Schleswig-Holstein, Germany",
|
"homeMyLocation": "Quickborn, Schleswig-Holstein, Germany",
|
||||||
"donationCatchphrase": "Like what you're seeing? Consider donating.",
|
"donationCatchphrase": "Like what you're seeing? Consider donating.",
|
||||||
"homeImageCredit": "Portrait taken by Jannik Kiel",
|
"homeImageCredit": "Portrait taken by Jannik Kiel",
|
||||||
"de": "German",
|
"de": "German",
|
||||||
"en": "English",
|
"en": "English",
|
||||||
"projectAboutHeader": "About {{projectName}}",
|
"projectAboutHeader": "About {{projectName}}",
|
||||||
"projectViewGitHub": "View on GitHub",
|
"projectViewGitHub": "View on GitHub",
|
||||||
"projectViewWebsite": "View Project-Website",
|
"projectViewWebsite": "View Project-Website",
|
||||||
"projectsDescription": "This is what I am working on or have worked on.",
|
"projectsDescription": "This is what I am working on or have worked on.",
|
||||||
"projectView": "View",
|
"projectView": "View",
|
||||||
"socialDescriptionWithLink": "Find me on other platforms or <1>visit my friends</1>!",
|
"socialDescriptionWithLink": "Find me on other platforms or <1>visit my friends</1>!",
|
||||||
"socialDescription": "Find me on other platforms!",
|
"socialDescription": "Find me on other platforms!",
|
||||||
"friends": "Friends",
|
"friends": "Friends",
|
||||||
"friendsDescription": "In this list you can find friends of mine and this site. Feel free to check them out for more interesting projects.",
|
"friendsDescription": "In this list you can find friends of mine and this site. Feel free to check them out for more interesting projects.",
|
||||||
"donate": "Donate",
|
"donate": "Donate",
|
||||||
"donateDescription": "Hey! It looks like you're thinking about donating to me. That's nice of you! If you want your donation to go towards a specific project, feel free to write your wishes into the donation comment.",
|
"donateDescription": "Hey! It looks like you're thinking about donating to me. That's nice of you! If you want your donation to go towards a specific project, feel free to write your wishes into the donation comment.",
|
||||||
"donateThanks": "Thanks for donating!",
|
"donateThanks": "Thanks for donating!",
|
||||||
"donateThanksText": "I really appreciate you appreciating my work and showing it! Feel free to mail me at <1>{{contactEmail}}</1> if you have anything you want to talk about!",
|
"donateThanksText": "I really appreciate you appreciating my work and showing it! Feel free to mail me at <1>{{contactEmail}}</1> if you have anything you want to talk about!",
|
||||||
"featuredProjects": "Featured Projects",
|
"featuredProjects": "Featured Projects",
|
||||||
"seeMore": "Explore more Projects",
|
"seeMore": "Explore more Projects",
|
||||||
"donateGitHub": "You can very easily support me via GitHub Sponsors using the following button!",
|
"donateGitHub": "You can very easily support me via GitHub Sponsors using the following button!",
|
||||||
"donatePayPal": "If you'd rather support me via PayPal the following button is for you:",
|
"donatePayPal": "If you'd rather support me via PayPal the following button is for you:",
|
||||||
"sponsorGitHub": "Sponsor using GitHub",
|
"sponsorGitHub": "Sponsor using GitHub",
|
||||||
"mySkills": "My Skills"
|
"mySkills": "My Skills",
|
||||||
|
"about": "About",
|
||||||
|
"explore": "Explore",
|
||||||
|
"myProjects": "my projects",
|
||||||
|
"discover": "Discover",
|
||||||
|
"mySocials": "my socials",
|
||||||
|
"learn": "Learn",
|
||||||
|
"moreAboutMe": "more about me",
|
||||||
|
"home": "Home",
|
||||||
|
"menu": "Menu"
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
"gatsby-source-filesystem": "3.14.0",
|
"gatsby-source-filesystem": "3.14.0",
|
||||||
"gatsby-transformer-json": "3.14.0",
|
"gatsby-transformer-json": "3.14.0",
|
||||||
"gatsby-transformer-sharp": "3.14.0",
|
"gatsby-transformer-sharp": "3.14.0",
|
||||||
|
"hamburger-react": "^2.4.1",
|
||||||
"i18next": "21.3.1",
|
"i18next": "21.3.1",
|
||||||
"locale": "0.1.0",
|
"locale": "0.1.0",
|
||||||
"lucide-react": "0.16.11",
|
"lucide-react": "0.16.11",
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
@mixin cardGeneric {
|
@mixin cardGeneric {
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-shadow: -1px 11px 33px -10px rgba(127, 127, 127, 0.3);
|
box-shadow: -1px 11px 33px -10px rgba(27, 27, 27, 0.3);
|
||||||
transition: transform 0.25s, box-shadow 0.25s, background-color 0.25s,
|
transition: transform 0.25s, box-shadow 0.25s, background-color 0.25s,
|
||||||
color 0.25s;
|
color 0.25s;
|
||||||
color: $textColor;
|
color: $textColor;
|
||||||
|
|
|
@ -1,12 +1,56 @@
|
||||||
|
/* eslint-disable no-undef */
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
import { Trans, Link } from "gatsby-plugin-react-i18next";
|
import { Trans, Link } from "gatsby-plugin-react-i18next";
|
||||||
import { graphql, StaticQuery } from "gatsby";
|
import { graphql, StaticQuery } from "gatsby";
|
||||||
|
import { createPortal } from "react-dom";
|
||||||
|
|
||||||
import * as styles from "./navigation.module.scss";
|
import * as styles from "./navigation.module.scss";
|
||||||
|
import { X } from "lucide-react";
|
||||||
|
import { Fade as Hamburger } from 'hamburger-react';
|
||||||
|
|
||||||
|
const OffScreenNav = ({active, close}) => {
|
||||||
|
if(typeof window === "undefined") {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return createPortal(<div className={styles.offscreenNav + " " + (active ? styles.active : "")}>
|
||||||
|
<div className={styles.inner}>
|
||||||
|
<button className={styles.close} onClick={close}><X/></button>
|
||||||
|
<span><Trans>menu</Trans></span>
|
||||||
|
<Link to="/" activeClassName={styles.active}>
|
||||||
|
<Trans>home</Trans>
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
id="navBtnProjects"
|
||||||
|
to="/about"
|
||||||
|
activeClassName={styles.active}
|
||||||
|
>
|
||||||
|
<Trans>about</Trans>
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
id="navBtnProjects"
|
||||||
|
to="/projects"
|
||||||
|
activeClassName={styles.active}
|
||||||
|
>
|
||||||
|
<Trans>projects</Trans>
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
id="navBtnSocial"
|
||||||
|
to="/social"
|
||||||
|
activeClassName={styles.active}
|
||||||
|
>
|
||||||
|
<Trans>social</Trans>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>, window.document.body)
|
||||||
|
}
|
||||||
|
|
||||||
const Navigation = ({ isHome }) => {
|
const Navigation = ({ isHome }) => {
|
||||||
let [atTop, setAtTop] = useState(false);
|
let [atTop, setAtTop] = useState(false);
|
||||||
|
const [offscreenNavActive, setOffscreenNavActive] = useState(false);
|
||||||
|
|
||||||
|
const closeOffscreenNav = () => setOffscreenNavActive(false);
|
||||||
|
|
||||||
const updateTransparency = () => {
|
const updateTransparency = () => {
|
||||||
if (typeof window === "undefined") return;
|
if (typeof window === "undefined") return;
|
||||||
|
@ -52,6 +96,7 @@ const Navigation = ({ isHome }) => {
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<nav className={styles.topBarInner}>
|
<nav className={styles.topBarInner}>
|
||||||
|
<OffScreenNav active={offscreenNavActive} close={closeOffscreenNav} />
|
||||||
<StaticQuery
|
<StaticQuery
|
||||||
query={graphql`
|
query={graphql`
|
||||||
query {
|
query {
|
||||||
|
@ -63,12 +108,19 @@ const Navigation = ({ isHome }) => {
|
||||||
}
|
}
|
||||||
`}
|
`}
|
||||||
render={(data) => (
|
render={(data) => (
|
||||||
<Link to="/" activeClassName={styles.active}>
|
<Link to="/" activeClassName={styles.active} className={styles.logo}>
|
||||||
{data.site.siteMetadata.title}
|
{data.site.siteMetadata.title}
|
||||||
</Link>
|
</Link>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<div className="flexSpacer"></div>
|
<div className="flexSpacer"></div>
|
||||||
|
<Link
|
||||||
|
id="navBtnProjects"
|
||||||
|
to="/about"
|
||||||
|
activeClassName={styles.active}
|
||||||
|
>
|
||||||
|
<Trans>about</Trans>
|
||||||
|
</Link>
|
||||||
<Link
|
<Link
|
||||||
id="navBtnProjects"
|
id="navBtnProjects"
|
||||||
to="/projects"
|
to="/projects"
|
||||||
|
@ -83,6 +135,7 @@ const Navigation = ({ isHome }) => {
|
||||||
>
|
>
|
||||||
<Trans>social</Trans>
|
<Trans>social</Trans>
|
||||||
</Link>
|
</Link>
|
||||||
|
<div className={styles.hamburger}><Hamburger toggle={setOffscreenNavActive} toggled={offscreenNavActive} rounded size={30} /></div>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,6 +1,75 @@
|
||||||
@import "../variables";
|
@import "../variables";
|
||||||
@import "../mixins";
|
@import "../mixins";
|
||||||
|
|
||||||
|
.offscreenNav {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 120px;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 1200;
|
||||||
|
background-color: rgba($background, 0.9);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
color: white;
|
||||||
|
overflow: auto;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity .25s, left .25s;
|
||||||
|
pointer-events: none;
|
||||||
|
overscroll-behavior: contain;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
left: 0;
|
||||||
|
opacity: 1;
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media(prefers-color-scheme: light) {
|
||||||
|
background-color: rgba($lightBackground, 0.9);
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inner {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
max-width: $layoutWidth;
|
||||||
|
margin: 0 auto;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
font-size: 1.25em;
|
||||||
|
|
||||||
|
.close {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
padding: $layoutPadding;
|
||||||
|
color: inherit;
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
font: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
> a {
|
||||||
|
text-decoration: underline dotted currentColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
> * {
|
||||||
|
padding: $layoutPadding;
|
||||||
|
color: inherit;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
border-left: 3px solid white;
|
||||||
|
border-right: 3px solid white;
|
||||||
|
|
||||||
|
@media(prefers-color-scheme: light) {
|
||||||
|
border-left: 3px solid black;
|
||||||
|
border-right: 3px solid black;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.topBar {
|
.topBar {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
@ -40,8 +109,18 @@
|
||||||
padding-right: $layoutPadding;
|
padding-right: $layoutPadding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hamburger {
|
||||||
|
display: none;
|
||||||
|
height: 43px;
|
||||||
|
|
||||||
|
@media(max-width: 500px) {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
display: block;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
padding: 10px $layoutPadding;
|
padding: 10px $layoutPadding;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
@ -59,6 +138,12 @@
|
||||||
border-color: $accentColor;
|
border-color: $accentColor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media(max-width: 500px) {
|
||||||
|
&:not(.logo) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ html,
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
font-family: $mainFont;
|
font-family: $mainFont;
|
||||||
|
scroll-behavior: smooth;
|
||||||
}
|
}
|
||||||
|
|
||||||
#gatsby-focus-wrapper {
|
#gatsby-focus-wrapper {
|
||||||
|
|
217
src/pages/about.js
Normal file
217
src/pages/about.js
Normal file
|
@ -0,0 +1,217 @@
|
||||||
|
import * as React from "react";
|
||||||
|
import Layout from "../layouts/default";
|
||||||
|
import PropTypes from "prop-types";
|
||||||
|
|
||||||
|
import * as styles from "./index.module.scss";
|
||||||
|
import * as projectStyles from "./projects.module.scss";
|
||||||
|
|
||||||
|
import { Trans, Link } from "gatsby-plugin-react-i18next";
|
||||||
|
import { graphql } from "gatsby";
|
||||||
|
import { MDXRenderer } from "gatsby-plugin-mdx";
|
||||||
|
import { GatsbyImage } from "gatsby-plugin-image";
|
||||||
|
|
||||||
|
import anime from "animejs";
|
||||||
|
|
||||||
|
import { ArrowRight } from "lucide-react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
export const query = graphql`
|
||||||
|
query GetProjectsAndSkills($language: String) {
|
||||||
|
allSkillsJson(sort: { fields: type, order: ASC }) {
|
||||||
|
nodes {
|
||||||
|
name
|
||||||
|
type
|
||||||
|
href
|
||||||
|
}
|
||||||
|
}
|
||||||
|
allProjectsJson(
|
||||||
|
filter: { lang: { eq: $language }, featured: { gte: 0 } }
|
||||||
|
sort: { fields: featured, order: ASC }
|
||||||
|
) {
|
||||||
|
nodes {
|
||||||
|
lang
|
||||||
|
urlname
|
||||||
|
name
|
||||||
|
image {
|
||||||
|
childImageSharp {
|
||||||
|
gatsbyImageData(placeholder: BLURRED, layout: FULL_WIDTH)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
shortDescription
|
||||||
|
featured
|
||||||
|
}
|
||||||
|
}
|
||||||
|
locales: allLocale(filter: { language: { eq: $language } }) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
ns
|
||||||
|
data
|
||||||
|
language
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file(
|
||||||
|
sourceInstanceName: { eq: "textblocks" }
|
||||||
|
relativeDirectory: { eq: "home/about" }
|
||||||
|
name: { eq: $language }
|
||||||
|
) {
|
||||||
|
id
|
||||||
|
childMdx {
|
||||||
|
body
|
||||||
|
}
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const AboutPage = (props) => {
|
||||||
|
const {t} = useTranslation();
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (typeof window === "undefined") return;
|
||||||
|
|
||||||
|
anime({
|
||||||
|
targets: [
|
||||||
|
"." + styles.profileCard + " > span",
|
||||||
|
"." + styles.profileCard + " a",
|
||||||
|
],
|
||||||
|
opacity: [0, 1],
|
||||||
|
translateX: [100, 0],
|
||||||
|
duration: 250,
|
||||||
|
delay: anime.stagger(20),
|
||||||
|
easing: "easeInOutCirc",
|
||||||
|
});
|
||||||
|
anime({
|
||||||
|
targets: ["." + styles.profileImageDummy],
|
||||||
|
translateX: [0, -3],
|
||||||
|
translateY: [0, 3],
|
||||||
|
duration: 250,
|
||||||
|
easing: "easeInOutCirc",
|
||||||
|
});
|
||||||
|
anime({
|
||||||
|
targets: ["." + styles.profileImage],
|
||||||
|
translateX: [0, 4],
|
||||||
|
translateY: [0, -4],
|
||||||
|
duration: 250,
|
||||||
|
easing: "easeInOutCirc",
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
let file = props.data.file;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Layout title={t("about")} description={t("siteDescription")}
|
||||||
|
image={"/owner.jpg"}
|
||||||
|
speakable={{
|
||||||
|
"@type": "SpeakableSpecification",
|
||||||
|
"xPath": [
|
||||||
|
"article"
|
||||||
|
]
|
||||||
|
}}>
|
||||||
|
|
||||||
|
<section className={styles.aboutSection} id="about">
|
||||||
|
<article>
|
||||||
|
<div className={styles.aboutText}>
|
||||||
|
<MDXRenderer>{file.childMdx.body}</MDXRenderer>
|
||||||
|
</div>
|
||||||
|
<div className={styles.skills}>
|
||||||
|
<h2>
|
||||||
|
<Trans>mySkills</Trans>
|
||||||
|
</h2>
|
||||||
|
<div className={styles.skillList}>
|
||||||
|
{props.data.allSkillsJson.nodes.map((skill) => {
|
||||||
|
return skill.href ? (
|
||||||
|
<a
|
||||||
|
className={
|
||||||
|
styles.skill +
|
||||||
|
" " +
|
||||||
|
styles["skill_" + skill.type]
|
||||||
|
}
|
||||||
|
href={skill.href}
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
>
|
||||||
|
{skill.name}
|
||||||
|
</a>
|
||||||
|
) : (
|
||||||
|
<span
|
||||||
|
className={
|
||||||
|
styles.skill +
|
||||||
|
" " +
|
||||||
|
styles["skill_" + skill.type]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{skill.name}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<article>
|
||||||
|
<h1>
|
||||||
|
<Trans>featuredProjects</Trans>
|
||||||
|
</h1>
|
||||||
|
<div className={projectStyles.projectList}>
|
||||||
|
{props.data.allProjectsJson.nodes.map((project) => {
|
||||||
|
return (
|
||||||
|
<Link
|
||||||
|
className={projectStyles.projectCard}
|
||||||
|
key={project.lang + "/" + project.urlname}
|
||||||
|
to={"/projects/" + project.urlname}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className={
|
||||||
|
projectStyles.projectCardImage
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div className={
|
||||||
|
projectStyles.projectCardBg
|
||||||
|
}>
|
||||||
|
<GatsbyImage image={project.image.childImageSharp.gatsbyImageData} objectFit="cover" style={{height: "100%"}}></GatsbyImage>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={
|
||||||
|
projectStyles.projectCardMeta
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className={
|
||||||
|
projectStyles.projectCardTitle
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{project.name}
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
{project.shortDescription}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
<Link to="/projects" className={styles.seeMoreButton}>
|
||||||
|
<Trans>seeMore</Trans>{" "}
|
||||||
|
<ArrowRight/>
|
||||||
|
</Link>
|
||||||
|
</article>
|
||||||
|
</section>
|
||||||
|
<Link className={styles.donationSection} to="/donate">
|
||||||
|
<div>
|
||||||
|
<span>
|
||||||
|
<Trans>donationCatchphrase</Trans>
|
||||||
|
</span>
|
||||||
|
<ArrowRight/>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
</Layout>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
AboutPage.propTypes = {
|
||||||
|
data: PropTypes.object.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AboutPage;
|
|
@ -3,12 +3,10 @@ import Layout from "../layouts/default";
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
|
|
||||||
import * as styles from "./index.module.scss";
|
import * as styles from "./index.module.scss";
|
||||||
import * as projectStyles from "./projects.module.scss";
|
|
||||||
|
|
||||||
import { Trans, Link } from "gatsby-plugin-react-i18next";
|
import { Trans, Link } from "gatsby-plugin-react-i18next";
|
||||||
import { graphql } from "gatsby";
|
import { graphql } from "gatsby";
|
||||||
import { MDXRenderer } from "gatsby-plugin-mdx";
|
import { StaticImage } from "gatsby-plugin-image";
|
||||||
import { StaticImage, GatsbyImage } from "gatsby-plugin-image";
|
|
||||||
|
|
||||||
import anime from "animejs";
|
import anime from "animejs";
|
||||||
|
|
||||||
|
@ -28,30 +26,6 @@ export const query = graphql`
|
||||||
contactMastodonHref
|
contactMastodonHref
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
allSkillsJson(sort: { fields: type, order: ASC }) {
|
|
||||||
nodes {
|
|
||||||
name
|
|
||||||
type
|
|
||||||
href
|
|
||||||
}
|
|
||||||
}
|
|
||||||
allProjectsJson(
|
|
||||||
filter: { lang: { eq: $language }, featured: { gte: 0 } }
|
|
||||||
sort: { fields: featured, order: ASC }
|
|
||||||
) {
|
|
||||||
nodes {
|
|
||||||
lang
|
|
||||||
urlname
|
|
||||||
name
|
|
||||||
image {
|
|
||||||
childImageSharp {
|
|
||||||
gatsbyImageData(placeholder: BLURRED, layout: FULL_WIDTH)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
shortDescription
|
|
||||||
featured
|
|
||||||
}
|
|
||||||
}
|
|
||||||
locales: allLocale(filter: { language: { eq: $language } }) {
|
locales: allLocale(filter: { language: { eq: $language } }) {
|
||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
|
@ -61,17 +35,6 @@ export const query = graphql`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
file(
|
|
||||||
sourceInstanceName: { eq: "textblocks" }
|
|
||||||
relativeDirectory: { eq: "home/about" }
|
|
||||||
name: { eq: $language }
|
|
||||||
) {
|
|
||||||
id
|
|
||||||
childMdx {
|
|
||||||
body
|
|
||||||
}
|
|
||||||
name
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -109,7 +72,6 @@ const IndexPage = (props) => {
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
let meta = props.data.site.siteMetadata;
|
let meta = props.data.site.siteMetadata;
|
||||||
let file = props.data.file;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout title="Kevin Kandlbinder" transparentTopbar={true} description={t("siteDescription")}
|
<Layout title="Kevin Kandlbinder" transparentTopbar={true} description={t("siteDescription")}
|
||||||
|
@ -195,46 +157,30 @@ const IndexPage = (props) => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
<div className={styles.spacer}></div>
|
||||||
<section className={styles.aboutSection}>
|
<div className={styles.landingCta}>
|
||||||
<article>
|
<Link to={"/projects"}>
|
||||||
<div className={styles.aboutText}>
|
<div>
|
||||||
<MDXRenderer>{file.childMdx.body}</MDXRenderer>
|
<span className={styles.ctaAccent}>{t("explore")}</span>{" "}
|
||||||
</div>
|
<span>{t("myProjects")}</span>
|
||||||
<div className={styles.skills}>
|
|
||||||
<h2>
|
|
||||||
<Trans>mySkills</Trans>
|
|
||||||
</h2>
|
|
||||||
<div className={styles.skillList}>
|
|
||||||
{props.data.allSkillsJson.nodes.map((skill) => {
|
|
||||||
return skill.href ? (
|
|
||||||
<a
|
|
||||||
className={
|
|
||||||
styles.skill +
|
|
||||||
" " +
|
|
||||||
styles["skill_" + skill.type]
|
|
||||||
}
|
|
||||||
href={skill.href}
|
|
||||||
target="_blank"
|
|
||||||
rel="noreferrer"
|
|
||||||
>
|
|
||||||
{skill.name}
|
|
||||||
</a>
|
|
||||||
) : (
|
|
||||||
<span
|
|
||||||
className={
|
|
||||||
styles.skill +
|
|
||||||
" " +
|
|
||||||
styles["skill_" + skill.type]
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{skill.name}
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<ArrowRight/>
|
||||||
</article>
|
</Link>
|
||||||
|
<Link to={"/social"}>
|
||||||
|
<div>
|
||||||
|
<span className={styles.ctaAccent}>{t("discover")}</span>{" "}
|
||||||
|
<span>{t("mySocials")}</span>
|
||||||
|
</div>
|
||||||
|
<ArrowRight/>
|
||||||
|
</Link>
|
||||||
|
<Link to={"/about"}>
|
||||||
|
<div>
|
||||||
|
<span className={styles.ctaAccent}>{t("learn")}</span>{" "}
|
||||||
|
<span>{t("moreAboutMe")}</span>
|
||||||
|
</div>
|
||||||
|
<ArrowRight/>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<a
|
<a
|
||||||
className={styles.creditSection}
|
className={styles.creditSection}
|
||||||
|
@ -250,64 +196,6 @@ const IndexPage = (props) => {
|
||||||
<ArrowRight/>
|
<ArrowRight/>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<section className="featuredSection">
|
|
||||||
<article>
|
|
||||||
<h1>
|
|
||||||
<Trans>featuredProjects</Trans>
|
|
||||||
</h1>
|
|
||||||
<div className={projectStyles.projectList}>
|
|
||||||
{props.data.allProjectsJson.nodes.map((project) => {
|
|
||||||
return (
|
|
||||||
<Link
|
|
||||||
className={projectStyles.projectCard}
|
|
||||||
key={project.lang + "/" + project.urlname}
|
|
||||||
to={"/projects/" + project.urlname}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className={
|
|
||||||
projectStyles.projectCardImage
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<div className={
|
|
||||||
projectStyles.projectCardBg
|
|
||||||
}>
|
|
||||||
<GatsbyImage image={project.image.childImageSharp.gatsbyImageData} objectFit="cover" style={{height: "100%"}}></GatsbyImage>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className={
|
|
||||||
projectStyles.projectCardMeta
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
className={
|
|
||||||
projectStyles.projectCardTitle
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{project.name}
|
|
||||||
</span>
|
|
||||||
<span>
|
|
||||||
{project.shortDescription}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Link>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
<Link to="/projects" className={styles.seeMoreButton}>
|
|
||||||
<Trans>seeMore</Trans>{" "}
|
|
||||||
<ArrowRight/>
|
|
||||||
</Link>
|
|
||||||
</article>
|
|
||||||
</section>
|
|
||||||
<Link className={styles.donationSection} to="/donate">
|
|
||||||
<div>
|
|
||||||
<span>
|
|
||||||
<Trans>donationCatchphrase</Trans>
|
|
||||||
</span>
|
|
||||||
<ArrowRight/>
|
|
||||||
</div>
|
|
||||||
</Link>
|
|
||||||
</Layout>
|
</Layout>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,15 +3,21 @@
|
||||||
|
|
||||||
.heroSection {
|
.heroSection {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 600px;
|
flex-grow: 1;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 800px;
|
||||||
|
//scroll-snap-align: start;
|
||||||
|
padding-top: 100px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
.heroSectionBg,
|
.heroSectionBg,
|
||||||
.heroSectionBgOver {
|
.heroSectionBgOver {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: unset;
|
max-width: unset;
|
||||||
height: 600px;
|
height: 100%;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
||||||
@media (pointer: coarse), (pointer: none) {
|
@media (pointer: coarse), (pointer: none) {
|
||||||
|
@ -19,9 +25,16 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.spacer {
|
||||||
|
flex-grow: 1;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.heroSectionBg {
|
.heroSectionBg {
|
||||||
/*background: radial-gradient(ellipse at top left, #1f0ba659, transparent),
|
/*background: radial-gradient(ellipse at top left, #1f0ba659, transparent),
|
||||||
radial-gradient(ellipse at bottom right, #4a086829, transparent);*/
|
radial-gradient(ellipse at bottom right, #4a086829, transparent);*/
|
||||||
|
margin-top: -100px;
|
||||||
|
|
||||||
background: linear-gradient(45deg, #000850 0%, #000320 100%),
|
background: linear-gradient(45deg, #000850 0%, #000320 100%),
|
||||||
radial-gradient(100% 225% at 100% 0%, #ff6928 0%, #000000 100%),
|
radial-gradient(100% 225% at 100% 0%, #ff6928 0%, #000000 100%),
|
||||||
|
@ -38,23 +51,70 @@
|
||||||
#0f0a3c 100%
|
#0f0a3c 100%
|
||||||
);
|
);
|
||||||
background-blend-mode: screen, overlay, hard-light, normal;
|
background-blend-mode: screen, overlay, hard-light, normal;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.heroSectionBgOver {
|
.heroSectionBgOver {
|
||||||
background: linear-gradient(to bottom, transparent 80%, $background);
|
bottom: 0;
|
||||||
transition: background-image 0.25s;
|
height: 150px;
|
||||||
|
/*background-color: $background;
|
||||||
|
transition: background-color 0.25s, box-shadow 0.25s;*/
|
||||||
|
|
||||||
|
@media(max-width: 950px) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@media (prefers-color-scheme: light) {
|
@media (prefers-color-scheme: light) {
|
||||||
background: linear-gradient(
|
background-color: $lightBackground;
|
||||||
to bottom,
|
|
||||||
transparent 90%,
|
|
||||||
$lightBackground
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (pointer: coarse), (pointer: none) {
|
.landingCta {
|
||||||
height: 700px;
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
|
||||||
|
@media(max-width: 1000px) {
|
||||||
|
flex-direction: column;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
@include cardGeneric;
|
||||||
|
display: flex;
|
||||||
|
padding: $layoutPadding;
|
||||||
|
background-color: $background;
|
||||||
|
margin: $layoutPadding;
|
||||||
|
color: $textColor;
|
||||||
|
font-size: 1.6em;
|
||||||
|
text-decoration: none;
|
||||||
|
border-radius: 10px;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
@media(max-width: 1000px) {
|
||||||
|
margin: 10px;
|
||||||
|
font-size: 1.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
> svg {
|
||||||
|
margin-left: $layoutPadding;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
> div {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-grow: 1;
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
.ctaAccent {
|
||||||
|
color: $accentColor;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile {
|
.profile {
|
||||||
|
@ -62,9 +122,7 @@
|
||||||
left: 50%;
|
left: 50%;
|
||||||
width: calc(90% - 40px);
|
width: calc(90% - 40px);
|
||||||
max-width: 600px;
|
max-width: 600px;
|
||||||
max-height: 400px;
|
|
||||||
transform: translate(-50%, 0%);
|
transform: translate(-50%, 0%);
|
||||||
top: 100px;
|
|
||||||
|
|
||||||
.hello {
|
.hello {
|
||||||
font-weight: 100;
|
font-weight: 100;
|
||||||
|
@ -157,7 +215,7 @@
|
||||||
clip-path: polygon(14% 4%, 95% 1%, 88% 96%, 2% 89%);
|
clip-path: polygon(14% 4%, 95% 1%, 88% 96%, 2% 89%);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 590px) {
|
@media (max-width: 690px) {
|
||||||
.profileImage,
|
.profileImage,
|
||||||
.profileImageDummy {
|
.profileImageDummy {
|
||||||
display: none;
|
display: none;
|
||||||
|
@ -212,7 +270,7 @@
|
||||||
.aboutSection {
|
.aboutSection {
|
||||||
> article {
|
> article {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: flex-start;
|
||||||
|
|
||||||
> div {
|
> div {
|
||||||
width: calc(50% - 40px);
|
width: calc(50% - 40px);
|
||||||
|
|
|
@ -6590,6 +6590,11 @@ gzip-size@5.1.1:
|
||||||
duplexer "^0.1.1"
|
duplexer "^0.1.1"
|
||||||
pify "^4.0.1"
|
pify "^4.0.1"
|
||||||
|
|
||||||
|
hamburger-react@^2.4.1:
|
||||||
|
version "2.4.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/hamburger-react/-/hamburger-react-2.4.1.tgz#44fac99c30720fe8ed098b2a33e919b14b3e007e"
|
||||||
|
integrity sha512-oqG9CrTVi8wM/dyQQh3JJOOfEiol9ChLOqwtjx+hFyRu0nYfe2ymNmzi2wtfQTDyExUdqETdyACZV9KZ9wpApA==
|
||||||
|
|
||||||
hard-rejection@^2.1.0:
|
hard-rejection@^2.1.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/hard-rejection/-/hard-rejection-2.1.0.tgz#1c6eda5c1685c63942766d79bb40ae773cecd883"
|
resolved "https://registry.yarnpkg.com/hard-rejection/-/hard-rejection-2.1.0.tgz#1c6eda5c1685c63942766d79bb40ae773cecd883"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue