mirror of
https://github.com/Unkn0wnCat/KevinK.dev.js.git
synced 2025-05-11 07:56:55 +02:00
Configure & Run prettier
This commit is contained in:
parent
79ab0bb9af
commit
420f8930fd
66 changed files with 31825 additions and 31500 deletions
|
@ -28,9 +28,7 @@
|
||||||
"EditorConfig.EditorConfig"
|
"EditorConfig.EditorConfig"
|
||||||
],
|
],
|
||||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||||
"forwardPorts": [
|
"forwardPorts": [8000],
|
||||||
8000
|
|
||||||
],
|
|
||||||
// Use 'postCreateCommand' to run commands after the container is created.
|
// Use 'postCreateCommand' to run commands after the container is created.
|
||||||
"postCreateCommand": "npm install",
|
"postCreateCommand": "npm install",
|
||||||
// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
|
// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
|
||||||
|
|
21
.eslintrc
21
.eslintrc
|
@ -1,15 +1,12 @@
|
||||||
{
|
{
|
||||||
"parser": "babel-eslint",
|
"parser": "babel-eslint",
|
||||||
"rules": {
|
"rules": {
|
||||||
"strict": 0
|
"strict": 0
|
||||||
},
|
},
|
||||||
"extends": [
|
"extends": ["eslint:recommended", "plugin:react/recommended"],
|
||||||
"eslint:recommended",
|
"settings": {
|
||||||
"plugin:react/recommended"
|
"react": {
|
||||||
],
|
"version": "detect"
|
||||||
"settings": {
|
}
|
||||||
"react": {
|
|
||||||
"version": "detect"
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
40
.github/workflows/build.yaml
vendored
40
.github/workflows/build.yaml
vendored
|
@ -1,30 +1,30 @@
|
||||||
name: Build Site
|
name: Build Site
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
update:
|
update:
|
||||||
name: Build Site
|
name: Build Site
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
name: Checkout Repo
|
name: Checkout Repo
|
||||||
|
|
||||||
- name: Use Node.js
|
- name: Use Node.js
|
||||||
uses: actions/setup-node@v2
|
uses: actions/setup-node@v2
|
||||||
with:
|
with:
|
||||||
node-version: '12.x'
|
node-version: "12.x"
|
||||||
|
|
||||||
- run: npm install
|
- run: npm install
|
||||||
name: Install Dependencies
|
name: Install Dependencies
|
||||||
|
|
||||||
- run: npm run build
|
- run: npm run build
|
||||||
name: Build Site
|
name: Build Site
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v2
|
- uses: actions/upload-artifact@v2
|
||||||
name: Upload Artifacts
|
name: Upload Artifacts
|
||||||
with:
|
with:
|
||||||
name: site
|
name: site
|
||||||
path: public
|
path: public
|
||||||
|
|
4
.prettierignore
Normal file
4
.prettierignore
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
/.cache
|
||||||
|
/.vscode
|
||||||
|
/node_modules
|
||||||
|
/public
|
8
.prettierrc.json
Normal file
8
.prettierrc.json
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"trailingComma": "es5",
|
||||||
|
"tabWidth": 4,
|
||||||
|
"semi": true,
|
||||||
|
"singleQuote": false,
|
||||||
|
"jsxBracketSameLine": true,
|
||||||
|
"endOfLine": "lf"
|
||||||
|
}
|
30
config.js
30
config.js
|
@ -1,18 +1,18 @@
|
||||||
// eslint-disable-next-line no-undef
|
// eslint-disable-next-line no-undef
|
||||||
module.exports = {
|
module.exports = {
|
||||||
siteName: "KevinK.dev",
|
siteName: "KevinK.dev",
|
||||||
siteAuthor: "@Unkn0wnKevin",
|
siteAuthor: "@Unkn0wnKevin",
|
||||||
siteURL: "https://kevink.dev",
|
siteURL: "https://kevink.dev",
|
||||||
payPalMail: "kevin@1in9.net",
|
payPalMail: "kevin@1in9.net",
|
||||||
siteKeywords:
|
siteKeywords:
|
||||||
"Kevin Kandlbinder, Kevin, Kandlbinder, Web, Web Developer, Developer, JavaScript, PHP, Java, Photos, Fotos",
|
"Kevin Kandlbinder, Kevin, Kandlbinder, Web, Web Developer, Developer, JavaScript, PHP, Java, Photos, Fotos",
|
||||||
iconPath: "src/images/fullbglogo@10x.png",
|
iconPath: "src/images/fullbglogo@10x.png",
|
||||||
languages: ["en", "de"],
|
languages: ["en", "de"],
|
||||||
contactEmail: "kevin@kevink.dev",
|
contactEmail: "kevin@kevink.dev",
|
||||||
contactPhone: "+4941068068004",
|
contactPhone: "+4941068068004",
|
||||||
mapsLink: "https://goo.gl/maps/KVq9z1PVaVP2",
|
mapsLink: "https://goo.gl/maps/KVq9z1PVaVP2",
|
||||||
contactTwitter: "Unkn0wnKevin",
|
contactTwitter: "Unkn0wnKevin",
|
||||||
contactGitHub: "Unkn0wnCat",
|
contactGitHub: "Unkn0wnCat",
|
||||||
contactMastodon: "@kevin@1in1.net",
|
contactMastodon: "@kevin@1in1.net",
|
||||||
contactMastodonHref: "https://mastodon.1in1.net/@kevin",
|
contactMastodonHref: "https://mastodon.1in1.net/@kevin",
|
||||||
};
|
};
|
||||||
|
|
206
gatsby-config.js
206
gatsby-config.js
|
@ -2,106 +2,112 @@
|
||||||
const extConfig = require("./config");
|
const extConfig = require("./config");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
siteMetadata: {
|
siteMetadata: {
|
||||||
title: extConfig.siteName,
|
title: extConfig.siteName,
|
||||||
author: extConfig.siteAuthor,
|
author: extConfig.siteAuthor,
|
||||||
siteUrl: extConfig.siteURL,
|
|
||||||
keywords: extConfig.siteKeywords,
|
|
||||||
payPalMail: extConfig.payPalMail,
|
|
||||||
contactEmail: extConfig.contactEmail,
|
|
||||||
contactPhone: extConfig.contactPhone,
|
|
||||||
mapsLink: extConfig.mapsLink,
|
|
||||||
contactTwitter: extConfig.contactTwitter,
|
|
||||||
contactGitHub: extConfig.contactGitHub,
|
|
||||||
contactMastodon: extConfig.contactMastodon,
|
|
||||||
contactMastodonHref: extConfig.contactMastodonHref,
|
|
||||||
},
|
|
||||||
assetPrefix: "/assets",
|
|
||||||
plugins: [
|
|
||||||
`gatsby-plugin-eslint`,
|
|
||||||
{
|
|
||||||
resolve: "gatsby-plugin-asset-path",
|
|
||||||
},
|
|
||||||
`gatsby-plugin-sharp`,
|
|
||||||
`gatsby-transformer-sharp`,
|
|
||||||
`gatsby-transformer-json`,
|
|
||||||
{
|
|
||||||
resolve: `gatsby-source-filesystem`,
|
|
||||||
options: {
|
|
||||||
path: `${__dirname}/content/textblocks`,
|
|
||||||
name: `textblocks`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
resolve: `gatsby-source-filesystem`,
|
|
||||||
options: {
|
|
||||||
path: `${__dirname}/content/projectTextblocks`,
|
|
||||||
name: `projectTextblocks`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"gatsby-plugin-mdx",
|
|
||||||
{
|
|
||||||
resolve: `gatsby-source-filesystem`,
|
|
||||||
options: {
|
|
||||||
path: `./content/`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
resolve: `gatsby-source-filesystem`,
|
|
||||||
options: {
|
|
||||||
path: `${__dirname}/locales`,
|
|
||||||
name: `locale`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
`gatsby-plugin-sass`,
|
|
||||||
{
|
|
||||||
resolve: `gatsby-plugin-manifest`,
|
|
||||||
options: {
|
|
||||||
name: extConfig.siteName,
|
|
||||||
short_name: extConfig.siteName,
|
|
||||||
start_url: `/`,
|
|
||||||
background_color: `#000710`,
|
|
||||||
theme_color: `#000710`,
|
|
||||||
display: `minimal-ui`,
|
|
||||||
icon: extConfig.iconPath, // This path is relative to the root of the site.
|
|
||||||
cache_busting_mode: "none",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
`gatsby-plugin-robots-txt`,
|
|
||||||
{
|
|
||||||
resolve: `gatsby-plugin-offline`,
|
|
||||||
options: {
|
|
||||||
precachePages: ["/", "/en", "/en/projects", "/de", "/de/projects"],
|
|
||||||
workboxConfig: {
|
|
||||||
globPatterns: ["**/*"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
`gatsby-plugin-sitemap`,
|
|
||||||
`gatsby-plugin-react-helmet`,
|
|
||||||
{
|
|
||||||
resolve: `gatsby-plugin-react-i18next`,
|
|
||||||
options: {
|
|
||||||
localeJsonSourceName: `locale`,
|
|
||||||
languages: extConfig.languages,
|
|
||||||
defaultLanguage: `en`,
|
|
||||||
generateDefaultLanguagePage: true,
|
|
||||||
siteUrl: extConfig.siteURL,
|
siteUrl: extConfig.siteURL,
|
||||||
i18nextOptions: {
|
keywords: extConfig.siteKeywords,
|
||||||
interpolation: {
|
payPalMail: extConfig.payPalMail,
|
||||||
escapeValue: false, // not needed for react as it escapes by default
|
contactEmail: extConfig.contactEmail,
|
||||||
},
|
contactPhone: extConfig.contactPhone,
|
||||||
keySeparator: false,
|
mapsLink: extConfig.mapsLink,
|
||||||
nsSeparator: false,
|
contactTwitter: extConfig.contactTwitter,
|
||||||
},
|
contactGitHub: extConfig.contactGitHub,
|
||||||
pages: [
|
contactMastodon: extConfig.contactMastodon,
|
||||||
{
|
contactMastodonHref: extConfig.contactMastodonHref,
|
||||||
matchPath: "/:lang/projects/:urlname",
|
|
||||||
getLanguageFromPath: true,
|
|
||||||
excludeLanguages: extConfig.languages,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
],
|
assetPrefix: "/assets",
|
||||||
|
plugins: [
|
||||||
|
`gatsby-plugin-eslint`,
|
||||||
|
{
|
||||||
|
resolve: "gatsby-plugin-asset-path",
|
||||||
|
},
|
||||||
|
`gatsby-plugin-sharp`,
|
||||||
|
`gatsby-transformer-sharp`,
|
||||||
|
`gatsby-transformer-json`,
|
||||||
|
{
|
||||||
|
resolve: `gatsby-source-filesystem`,
|
||||||
|
options: {
|
||||||
|
path: `${__dirname}/content/textblocks`,
|
||||||
|
name: `textblocks`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
resolve: `gatsby-source-filesystem`,
|
||||||
|
options: {
|
||||||
|
path: `${__dirname}/content/projectTextblocks`,
|
||||||
|
name: `projectTextblocks`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"gatsby-plugin-mdx",
|
||||||
|
{
|
||||||
|
resolve: `gatsby-source-filesystem`,
|
||||||
|
options: {
|
||||||
|
path: `./content/`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
resolve: `gatsby-source-filesystem`,
|
||||||
|
options: {
|
||||||
|
path: `${__dirname}/locales`,
|
||||||
|
name: `locale`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
`gatsby-plugin-sass`,
|
||||||
|
{
|
||||||
|
resolve: `gatsby-plugin-manifest`,
|
||||||
|
options: {
|
||||||
|
name: extConfig.siteName,
|
||||||
|
short_name: extConfig.siteName,
|
||||||
|
start_url: `/`,
|
||||||
|
background_color: `#000710`,
|
||||||
|
theme_color: `#000710`,
|
||||||
|
display: `minimal-ui`,
|
||||||
|
icon: extConfig.iconPath, // This path is relative to the root of the site.
|
||||||
|
cache_busting_mode: "none",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
`gatsby-plugin-robots-txt`,
|
||||||
|
{
|
||||||
|
resolve: `gatsby-plugin-offline`,
|
||||||
|
options: {
|
||||||
|
precachePages: [
|
||||||
|
"/",
|
||||||
|
"/en",
|
||||||
|
"/en/projects",
|
||||||
|
"/de",
|
||||||
|
"/de/projects",
|
||||||
|
],
|
||||||
|
workboxConfig: {
|
||||||
|
globPatterns: ["**/*"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
`gatsby-plugin-sitemap`,
|
||||||
|
`gatsby-plugin-react-helmet`,
|
||||||
|
{
|
||||||
|
resolve: `gatsby-plugin-react-i18next`,
|
||||||
|
options: {
|
||||||
|
localeJsonSourceName: `locale`,
|
||||||
|
languages: extConfig.languages,
|
||||||
|
defaultLanguage: `en`,
|
||||||
|
generateDefaultLanguagePage: true,
|
||||||
|
siteUrl: extConfig.siteURL,
|
||||||
|
i18nextOptions: {
|
||||||
|
interpolation: {
|
||||||
|
escapeValue: false, // not needed for react as it escapes by default
|
||||||
|
},
|
||||||
|
keySeparator: false,
|
||||||
|
nsSeparator: false,
|
||||||
|
},
|
||||||
|
pages: [
|
||||||
|
{
|
||||||
|
matchPath: "/:lang/projects/:urlname",
|
||||||
|
getLanguageFromPath: true,
|
||||||
|
excludeLanguages: extConfig.languages,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
};
|
};
|
||||||
|
|
299
gatsby-node.js
299
gatsby-node.js
|
@ -3,172 +3,177 @@ const path = require(`path`);
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
|
|
||||||
exports.createPages = async ({ actions, graphql, reporter }) => {
|
exports.createPages = async ({ actions, graphql, reporter }) => {
|
||||||
const { createPage } = actions;
|
const { createPage } = actions;
|
||||||
|
|
||||||
const projectTemplate = path.resolve(`src/templates/project.js`);
|
const projectTemplate = path.resolve(`src/templates/project.js`);
|
||||||
|
|
||||||
const result = await graphql(`
|
const result = await graphql(`
|
||||||
query AllPagesQuery {
|
query AllPagesQuery {
|
||||||
allProjectsJson {
|
allProjectsJson {
|
||||||
nodes {
|
nodes {
|
||||||
lang
|
lang
|
||||||
urlname
|
urlname
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
`);
|
||||||
|
|
||||||
|
if (result.errors) {
|
||||||
|
reporter.panicOnBuild(`Error while running GraphQL query.`);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
`);
|
|
||||||
|
|
||||||
if (result.errors) {
|
result.data.allProjectsJson.nodes.forEach((node) => {
|
||||||
reporter.panicOnBuild(`Error while running GraphQL query.`);
|
// eslint-disable-next-line no-undef
|
||||||
return;
|
console.log(
|
||||||
}
|
"Creating Page: ",
|
||||||
|
`/${node.lang}/projects/${node.urlname}`
|
||||||
|
);
|
||||||
|
|
||||||
result.data.allProjectsJson.nodes.forEach((node) => {
|
if (node.lang !== "ignoreme")
|
||||||
// eslint-disable-next-line no-undef
|
createPage({
|
||||||
console.log("Creating Page: ", `/${node.lang}/projects/${node.urlname}`);
|
path: `/${node.lang}/projects/${node.urlname}`,
|
||||||
|
component: projectTemplate,
|
||||||
if (node.lang !== "ignoreme")
|
context: {
|
||||||
createPage({
|
lang: node.lang,
|
||||||
path: `/${node.lang}/projects/${node.urlname}`,
|
urlname: node.urlname,
|
||||||
component: projectTemplate,
|
},
|
||||||
context: {
|
});
|
||||||
lang: node.lang,
|
});
|
||||||
urlname: node.urlname,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const config = require("./config.js");
|
const config = require("./config.js");
|
||||||
|
|
||||||
exports.onPostBuild = async ({ graphql, reporter }) => {
|
exports.onPostBuild = async ({ graphql, reporter }) => {
|
||||||
console.log("Building static api...");
|
console.log("Building static api...");
|
||||||
|
|
||||||
const apiPrefix = "./public/api";
|
const apiPrefix = "./public/api";
|
||||||
|
|
||||||
if (!fs.existsSync(apiPrefix)) fs.mkdirSync(apiPrefix);
|
if (!fs.existsSync(apiPrefix)) fs.mkdirSync(apiPrefix);
|
||||||
|
|
||||||
fs.writeFileSync(
|
|
||||||
`${apiPrefix}.json`,
|
|
||||||
JSON.stringify({
|
|
||||||
success: true,
|
|
||||||
endpoints: {
|
|
||||||
projects: [
|
|
||||||
{
|
|
||||||
name: "Projects Overview",
|
|
||||||
description: "Returns overview of all available projects",
|
|
||||||
path: "/api/projects.json",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Projects Overview for Language",
|
|
||||||
description:
|
|
||||||
"Returns overview of all available projects in a specified language",
|
|
||||||
path: "/api/projects/:lang.json",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Get specific Project",
|
|
||||||
description: "Returns specific project in specified language",
|
|
||||||
path: "/api/projects/:lang/:slug.json",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
const projectsPrefix = apiPrefix + "/projects";
|
|
||||||
|
|
||||||
if (!fs.existsSync(projectsPrefix)) fs.mkdirSync(projectsPrefix);
|
|
||||||
|
|
||||||
await graphql(`
|
|
||||||
query {
|
|
||||||
allProjectsJson {
|
|
||||||
nodes {
|
|
||||||
urlname
|
|
||||||
shortDescription
|
|
||||||
name
|
|
||||||
links {
|
|
||||||
github
|
|
||||||
website
|
|
||||||
}
|
|
||||||
lang
|
|
||||||
image {
|
|
||||||
publicURL
|
|
||||||
}
|
|
||||||
featured
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`).then((res) => {
|
|
||||||
if (res.errors) {
|
|
||||||
reporter.panicOnBuild(`Error while running GraphQL query.`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let projects = res.data.allProjectsJson.nodes.filter((project) => {
|
|
||||||
return project.lang !== "ignoreme";
|
|
||||||
});
|
|
||||||
|
|
||||||
fs.writeFileSync(
|
fs.writeFileSync(
|
||||||
`${projectsPrefix}.json`,
|
`${apiPrefix}.json`,
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
success: true,
|
success: true,
|
||||||
projects: projects.map((project) => {
|
endpoints: {
|
||||||
return {
|
projects: [
|
||||||
slug: project.urlname,
|
{
|
||||||
lang: project.lang,
|
name: "Projects Overview",
|
||||||
api: `/api/projects/${project.lang}/${project.urlname}.json`,
|
description:
|
||||||
};
|
"Returns overview of all available projects",
|
||||||
}),
|
path: "/api/projects.json",
|
||||||
})
|
},
|
||||||
|
{
|
||||||
|
name: "Projects Overview for Language",
|
||||||
|
description:
|
||||||
|
"Returns overview of all available projects in a specified language",
|
||||||
|
path: "/api/projects/:lang.json",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Get specific Project",
|
||||||
|
description:
|
||||||
|
"Returns specific project in specified language",
|
||||||
|
path: "/api/projects/:lang/:slug.json",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
config.languages.forEach((lang) => {
|
const projectsPrefix = apiPrefix + "/projects";
|
||||||
if (!fs.existsSync(`${projectsPrefix}/${lang}`))
|
|
||||||
fs.mkdirSync(`${projectsPrefix}/${lang}`);
|
|
||||||
|
|
||||||
fs.writeFileSync(
|
if (!fs.existsSync(projectsPrefix)) fs.mkdirSync(projectsPrefix);
|
||||||
`${projectsPrefix}/${lang}.json`,
|
|
||||||
JSON.stringify({
|
await graphql(`
|
||||||
success: true,
|
query {
|
||||||
projects: projects
|
allProjectsJson {
|
||||||
.filter((project) => {
|
nodes {
|
||||||
return project.lang == lang;
|
urlname
|
||||||
|
shortDescription
|
||||||
|
name
|
||||||
|
links {
|
||||||
|
github
|
||||||
|
website
|
||||||
|
}
|
||||||
|
lang
|
||||||
|
image {
|
||||||
|
publicURL
|
||||||
|
}
|
||||||
|
featured
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`).then((res) => {
|
||||||
|
if (res.errors) {
|
||||||
|
reporter.panicOnBuild(`Error while running GraphQL query.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let projects = res.data.allProjectsJson.nodes.filter((project) => {
|
||||||
|
return project.lang !== "ignoreme";
|
||||||
|
});
|
||||||
|
|
||||||
|
fs.writeFileSync(
|
||||||
|
`${projectsPrefix}.json`,
|
||||||
|
JSON.stringify({
|
||||||
|
success: true,
|
||||||
|
projects: projects.map((project) => {
|
||||||
|
return {
|
||||||
|
slug: project.urlname,
|
||||||
|
lang: project.lang,
|
||||||
|
api: `/api/projects/${project.lang}/${project.urlname}.json`,
|
||||||
|
};
|
||||||
|
}),
|
||||||
})
|
})
|
||||||
.map((project) => {
|
);
|
||||||
return {
|
|
||||||
slug: project.urlname,
|
|
||||||
lang: project.lang,
|
|
||||||
api: `/api/projects/${project.lang}/${project.urlname}.json`,
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
projects.forEach((project) => {
|
config.languages.forEach((lang) => {
|
||||||
fs.writeFileSync(
|
if (!fs.existsSync(`${projectsPrefix}/${lang}`))
|
||||||
`${projectsPrefix}/${project.lang}/${project.urlname}.json`,
|
fs.mkdirSync(`${projectsPrefix}/${lang}`);
|
||||||
JSON.stringify({
|
|
||||||
success: true,
|
fs.writeFileSync(
|
||||||
project: {
|
`${projectsPrefix}/${lang}.json`,
|
||||||
slug: project.urlname,
|
JSON.stringify({
|
||||||
lang: project.lang,
|
success: true,
|
||||||
name: project.name,
|
projects: projects
|
||||||
shortDescription: project.shortDescription,
|
.filter((project) => {
|
||||||
longDescription: project.longDescription,
|
return project.lang == lang;
|
||||||
links:
|
})
|
||||||
project.links !== null
|
.map((project) => {
|
||||||
? {
|
return {
|
||||||
github: project.links.github,
|
slug: project.urlname,
|
||||||
website: project.links.website,
|
lang: project.lang,
|
||||||
}
|
api: `/api/projects/${project.lang}/${project.urlname}.json`,
|
||||||
: null,
|
};
|
||||||
image: project.image.publicURL,
|
}),
|
||||||
featured: project.featured,
|
})
|
||||||
frontend: `/${project.lang}/projects/${project.urlname}`,
|
);
|
||||||
},
|
});
|
||||||
})
|
|
||||||
);
|
projects.forEach((project) => {
|
||||||
|
fs.writeFileSync(
|
||||||
|
`${projectsPrefix}/${project.lang}/${project.urlname}.json`,
|
||||||
|
JSON.stringify({
|
||||||
|
success: true,
|
||||||
|
project: {
|
||||||
|
slug: project.urlname,
|
||||||
|
lang: project.lang,
|
||||||
|
name: project.name,
|
||||||
|
shortDescription: project.shortDescription,
|
||||||
|
longDescription: project.longDescription,
|
||||||
|
links:
|
||||||
|
project.links !== null
|
||||||
|
? {
|
||||||
|
github: project.links.github,
|
||||||
|
website: project.links.website,
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
image: project.image.publicURL,
|
||||||
|
featured: project.featured,
|
||||||
|
frontend: `/${project.lang}/projects/${project.urlname}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,9 +11,7 @@
|
||||||
"develop": "gatsby develop",
|
"develop": "gatsby develop",
|
||||||
"start": "gatsby develop",
|
"start": "gatsby develop",
|
||||||
"build": "gatsby build --prefix-paths",
|
"build": "gatsby build --prefix-paths",
|
||||||
"build:fab": "npm run build && npm run fab:build",
|
"prettier": "npx prettier --write .",
|
||||||
"fab:build": "fab build",
|
|
||||||
"fab:serve": "fab serve fab.zip",
|
|
||||||
"serve": "gatsby serve",
|
"serve": "gatsby serve",
|
||||||
"clean": "gatsby clean"
|
"clean": "gatsby clean"
|
||||||
},
|
},
|
||||||
|
@ -63,6 +61,7 @@
|
||||||
"eslint-loader": "4.0.2",
|
"eslint-loader": "4.0.2",
|
||||||
"eslint-plugin-import": "2.23.4",
|
"eslint-plugin-import": "2.23.4",
|
||||||
"eslint-plugin-react": "7.24.0",
|
"eslint-plugin-react": "7.24.0",
|
||||||
"gatsby-plugin-eslint": "2.0.8"
|
"gatsby-plugin-eslint": "2.0.8",
|
||||||
|
"prettier": "2.3.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,28 +4,28 @@ import { Link, Trans, useI18next } from "gatsby-plugin-react-i18next";
|
||||||
import * as styles from "./languageSwitcher.module.scss";
|
import * as styles from "./languageSwitcher.module.scss";
|
||||||
|
|
||||||
export default function LanguageSwitcher() {
|
export default function LanguageSwitcher() {
|
||||||
const { languages, originalPath } = useI18next();
|
const { languages, originalPath } = useI18next();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.languageModal} id="languageChooser">
|
<div className={styles.languageModal} id="languageChooser">
|
||||||
<div className={styles.languageModalInner}>
|
<div className={styles.languageModalInner}>
|
||||||
<h2>
|
<h2>
|
||||||
Languages (
|
Languages (
|
||||||
<a href="#top" className={styles.modalCloseLink}>
|
<a href="#top" className={styles.modalCloseLink}>
|
||||||
×
|
×
|
||||||
</a>
|
</a>
|
||||||
)
|
)
|
||||||
</h2>
|
</h2>
|
||||||
<ul>
|
<ul>
|
||||||
{languages.map((lng) => (
|
{languages.map((lng) => (
|
||||||
<li key={lng}>
|
<li key={lng}>
|
||||||
<Link to={originalPath} language={lng}>
|
<Link to={originalPath} language={lng}>
|
||||||
<Trans>{lng}</Trans>
|
<Trans>{lng}</Trans>
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,86 +6,87 @@ import { graphql, StaticQuery } from "gatsby";
|
||||||
import * as styles from "./navigation.module.scss";
|
import * as styles from "./navigation.module.scss";
|
||||||
|
|
||||||
const Navigation = ({ isHome }) => {
|
const Navigation = ({ isHome }) => {
|
||||||
let [atTop, setAtTop] = useState(false);
|
let [atTop, setAtTop] = useState(false);
|
||||||
|
|
||||||
const updateTransparency = () => {
|
const updateTransparency = () => {
|
||||||
if (typeof window === "undefined") return;
|
if (typeof window === "undefined") return;
|
||||||
|
|
||||||
// eslint-disable-next-line no-undef
|
// eslint-disable-next-line no-undef
|
||||||
if (window.scrollY < 15) {
|
if (window.scrollY < 15) {
|
||||||
if (!atTop) setAtTop(true);
|
if (!atTop) setAtTop(true);
|
||||||
} else {
|
} else {
|
||||||
if (atTop) setAtTop(false);
|
if (atTop) setAtTop(false);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (typeof window === "undefined") return;
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-undef
|
|
||||||
window.addEventListener("scroll", updateTransparency);
|
|
||||||
// eslint-disable-next-line no-undef
|
|
||||||
window.addEventListener("navigate", updateTransparency);
|
|
||||||
|
|
||||||
updateTransparency();
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-undef
|
|
||||||
let int = window.setInterval(updateTransparency, 10000);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
// eslint-disable-next-line no-undef
|
|
||||||
window.removeEventListener("scroll", updateTransparency);
|
|
||||||
// eslint-disable-next-line no-undef
|
|
||||||
window.removeEventListener("navigate", updateTransparency);
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-undef
|
|
||||||
window.clearInterval(int);
|
|
||||||
};
|
};
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
useEffect(() => {
|
||||||
<div
|
if (typeof window === "undefined") return;
|
||||||
className={
|
|
||||||
styles.topBar +
|
// eslint-disable-next-line no-undef
|
||||||
(isHome ? " " + styles.homeBar : "") +
|
window.addEventListener("scroll", updateTransparency);
|
||||||
(atTop ? " " + styles.homeBarTransparent : "")
|
// eslint-disable-next-line no-undef
|
||||||
}
|
window.addEventListener("navigate", updateTransparency);
|
||||||
>
|
|
||||||
<nav className={styles.topBarInner}>
|
updateTransparency();
|
||||||
<StaticQuery
|
|
||||||
query={graphql`
|
// eslint-disable-next-line no-undef
|
||||||
query {
|
let int = window.setInterval(updateTransparency, 10000);
|
||||||
site {
|
|
||||||
siteMetadata {
|
return () => {
|
||||||
title
|
// eslint-disable-next-line no-undef
|
||||||
}
|
window.removeEventListener("scroll", updateTransparency);
|
||||||
}
|
// eslint-disable-next-line no-undef
|
||||||
}
|
window.removeEventListener("navigate", updateTransparency);
|
||||||
`}
|
|
||||||
render={(data) => (
|
// eslint-disable-next-line no-undef
|
||||||
<Link to="/" activeClassName={styles.active}>
|
window.clearInterval(int);
|
||||||
{data.site.siteMetadata.title}
|
};
|
||||||
</Link>
|
});
|
||||||
)}
|
|
||||||
/>
|
return (
|
||||||
<div className="flexSpacer"></div>
|
<div
|
||||||
<Link
|
className={
|
||||||
id="navBtnProjects"
|
styles.topBar +
|
||||||
to="/projects"
|
(isHome ? " " + styles.homeBar : "") +
|
||||||
activeClassName={styles.active}
|
(atTop ? " " + styles.homeBarTransparent : "")
|
||||||
>
|
}>
|
||||||
<Trans>projects</Trans>
|
<nav className={styles.topBarInner}>
|
||||||
</Link>
|
<StaticQuery
|
||||||
<Link id="navBtnSocial" to="/social" activeClassName={styles.active}>
|
query={graphql`
|
||||||
<Trans>social</Trans>
|
query {
|
||||||
</Link>
|
site {
|
||||||
</nav>
|
siteMetadata {
|
||||||
</div>
|
title
|
||||||
);
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`}
|
||||||
|
render={(data) => (
|
||||||
|
<Link to="/" activeClassName={styles.active}>
|
||||||
|
{data.site.siteMetadata.title}
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<div className="flexSpacer"></div>
|
||||||
|
<Link
|
||||||
|
id="navBtnProjects"
|
||||||
|
to="/projects"
|
||||||
|
activeClassName={styles.active}>
|
||||||
|
<Trans>projects</Trans>
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
id="navBtnSocial"
|
||||||
|
to="/social"
|
||||||
|
activeClassName={styles.active}>
|
||||||
|
<Trans>social</Trans>
|
||||||
|
</Link>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
Navigation.propTypes = {
|
Navigation.propTypes = {
|
||||||
isHome: PropTypes.bool.isRequired,
|
isHome: PropTypes.bool.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Navigation;
|
export default Navigation;
|
||||||
|
|
|
@ -5,89 +5,89 @@ import { useStaticQuery, graphql } from "gatsby";
|
||||||
import { useTranslation } from "gatsby-plugin-react-i18next";
|
import { useTranslation } from "gatsby-plugin-react-i18next";
|
||||||
|
|
||||||
function SEO({ description, meta, title }) {
|
function SEO({ description, meta, title }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { site } = useStaticQuery(
|
const { site } = useStaticQuery(
|
||||||
graphql`
|
graphql`
|
||||||
query {
|
query {
|
||||||
site {
|
site {
|
||||||
siteMetadata {
|
siteMetadata {
|
||||||
title
|
title
|
||||||
author
|
author
|
||||||
keywords
|
keywords
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
|
|
||||||
const metaDescription = description || t("siteDescription");
|
const metaDescription = description || t("siteDescription");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Helmet
|
<Helmet
|
||||||
title={title}
|
title={title}
|
||||||
titleTemplate={`%s | ${site.siteMetadata.title}`}
|
titleTemplate={`%s | ${site.siteMetadata.title}`}
|
||||||
meta={[
|
meta={[
|
||||||
{
|
{
|
||||||
name: `description`,
|
name: `description`,
|
||||||
content: metaDescription,
|
content: metaDescription,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
property: `og:title`,
|
property: `og:title`,
|
||||||
content: title,
|
content: title,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
property: `og:description`,
|
property: `og:description`,
|
||||||
content: metaDescription,
|
content: metaDescription,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
property: `og:type`,
|
property: `og:type`,
|
||||||
content: `website`,
|
content: `website`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: `twitter:card`,
|
name: `twitter:card`,
|
||||||
content: `summary`,
|
content: `summary`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: `twitter:creator`,
|
name: `twitter:creator`,
|
||||||
content: site.siteMetadata.author,
|
content: site.siteMetadata.author,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: `twitter:title`,
|
name: `twitter:title`,
|
||||||
content: title,
|
content: title,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: `twitter:description`,
|
name: `twitter:description`,
|
||||||
content: metaDescription,
|
content: metaDescription,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "keywords",
|
name: "keywords",
|
||||||
content: site.siteMetadata.keywords,
|
content: site.siteMetadata.keywords,
|
||||||
},
|
},
|
||||||
].concat(meta)}
|
].concat(meta)}>
|
||||||
>
|
<script
|
||||||
<script
|
src="https://kit.fontawesome.com/1377f925e0.js"
|
||||||
src="https://kit.fontawesome.com/1377f925e0.js"
|
crossOrigin="anonymous"></script>
|
||||||
crossOrigin="anonymous"
|
<link rel="preconnect" href="https://fonts.gstatic.com" />
|
||||||
></script>
|
<link
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" />
|
href="https://fonts.googleapis.com/css2?family=Anonymous+Pro:wght@400;700&family=Roboto&display=swap"
|
||||||
<link
|
rel="stylesheet"
|
||||||
href="https://fonts.googleapis.com/css2?family=Anonymous+Pro:wght@400;700&family=Roboto&display=swap"
|
/>
|
||||||
rel="stylesheet"
|
<meta
|
||||||
/>
|
name="battery-savings"
|
||||||
<meta name="battery-savings" content="allow-reduced-framerate"></meta>
|
content="allow-reduced-framerate"></meta>
|
||||||
</Helmet>
|
</Helmet>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
SEO.defaultProps = {
|
SEO.defaultProps = {
|
||||||
meta: [],
|
meta: [],
|
||||||
description: ``,
|
description: ``,
|
||||||
};
|
};
|
||||||
|
|
||||||
SEO.propTypes = {
|
SEO.propTypes = {
|
||||||
description: PropTypes.string,
|
description: PropTypes.string,
|
||||||
meta: PropTypes.arrayOf(PropTypes.object),
|
meta: PropTypes.arrayOf(PropTypes.object),
|
||||||
title: PropTypes.string.isRequired,
|
title: PropTypes.string.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default SEO;
|
export default SEO;
|
||||||
|
|
|
@ -8,55 +8,55 @@ import { Link, Trans } from "gatsby-plugin-react-i18next";
|
||||||
import LanguageSwitcher from "../components/languageSwitcher";
|
import LanguageSwitcher from "../components/languageSwitcher";
|
||||||
|
|
||||||
class Layout extends React.Component {
|
class Layout extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SEO
|
<SEO
|
||||||
description={this.props.description}
|
description={this.props.description}
|
||||||
lang={this.props.lang}
|
lang={this.props.lang}
|
||||||
meta={this.props.meta}
|
meta={this.props.meta}
|
||||||
title={this.props.title}
|
title={this.props.title}
|
||||||
/>
|
/>
|
||||||
<Navigation isHome={this.props.transparentTopbar} />
|
<Navigation isHome={this.props.transparentTopbar} />
|
||||||
<div id="content" role="main">
|
<div id="content" role="main">
|
||||||
{this.props.children}
|
{this.props.children}
|
||||||
</div>
|
</div>
|
||||||
<footer role="contentinfo">
|
<footer role="contentinfo">
|
||||||
CC-BY 4.0 Kevin Kandlbinder,{" "}
|
CC-BY 4.0 Kevin Kandlbinder,{" "}
|
||||||
<Link to="/legal/about" className="spf-link">
|
<Link to="/legal/about" className="spf-link">
|
||||||
<Trans i18nKey="imprint">Imprint</Trans>
|
<Trans i18nKey="imprint">Imprint</Trans>
|
||||||
</Link>{" "}
|
</Link>{" "}
|
||||||
|{" "}
|
|{" "}
|
||||||
<Link to="/legal/datasec" className="spf-link">
|
<Link to="/legal/datasec" className="spf-link">
|
||||||
<Trans i18nKey="datasec">Data Protection</Trans>
|
<Trans i18nKey="datasec">Data Protection</Trans>
|
||||||
</Link>{" "}
|
</Link>{" "}
|
||||||
|{" "}
|
|{" "}
|
||||||
<Link to="/legal/disclaimer" className="spf-link">
|
<Link to="/legal/disclaimer" className="spf-link">
|
||||||
<Trans i18nKey="disclaimer">Disclaimer</Trans>
|
<Trans i18nKey="disclaimer">Disclaimer</Trans>
|
||||||
</Link>{" "}
|
</Link>{" "}
|
||||||
| <a href="#languageChooser">Language</a>
|
| <a href="#languageChooser">Language</a>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
<LanguageSwitcher />
|
<LanguageSwitcher />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Layout.defaultProps = {
|
Layout.defaultProps = {
|
||||||
module: `none`,
|
module: `none`,
|
||||||
meta: [],
|
meta: [],
|
||||||
description: ``,
|
description: ``,
|
||||||
transparentTopbar: false,
|
transparentTopbar: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
Layout.propTypes = {
|
Layout.propTypes = {
|
||||||
description: PropTypes.string,
|
description: PropTypes.string,
|
||||||
lang: PropTypes.string,
|
lang: PropTypes.string,
|
||||||
meta: PropTypes.arrayOf(PropTypes.object),
|
meta: PropTypes.arrayOf(PropTypes.object),
|
||||||
title: PropTypes.string.isRequired,
|
title: PropTypes.string.isRequired,
|
||||||
transparentTopbar: PropTypes.bool,
|
transparentTopbar: PropTypes.bool,
|
||||||
children: PropTypes.any.isRequired,
|
children: PropTypes.any.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Layout;
|
export default Layout;
|
||||||
|
|
|
@ -3,19 +3,19 @@ import { Link } from "gatsby-plugin-react-i18next";
|
||||||
import Layout from "../layouts/default";
|
import Layout from "../layouts/default";
|
||||||
|
|
||||||
const NotFoundPage = () => {
|
const NotFoundPage = () => {
|
||||||
return (
|
return (
|
||||||
<Layout title="Not found">
|
<Layout title="Not found">
|
||||||
<section>
|
<section>
|
||||||
<article>
|
<article>
|
||||||
<h1>Page not found</h1>
|
<h1>Page not found</h1>
|
||||||
<p>
|
<p>
|
||||||
Whoops... That page doesn't exist, so you may as well{" "}
|
Whoops... That page doesn't exist, so you may as
|
||||||
<Link to="/">go home</Link>.
|
well <Link to="/">go home</Link>.
|
||||||
</p>
|
</p>
|
||||||
</article>
|
</article>
|
||||||
</section>
|
</section>
|
||||||
</Layout>
|
</Layout>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default NotFoundPage;
|
export default NotFoundPage;
|
||||||
|
|
|
@ -8,128 +8,135 @@ import GitHubButton from "react-github-btn";
|
||||||
import * as styles from "./donate.module.scss";
|
import * as styles from "./donate.module.scss";
|
||||||
|
|
||||||
export const query = graphql`
|
export const query = graphql`
|
||||||
query($language: String!) {
|
query ($language: String!) {
|
||||||
site {
|
site {
|
||||||
siteMetadata {
|
siteMetadata {
|
||||||
title
|
title
|
||||||
siteUrl
|
siteUrl
|
||||||
payPalMail
|
payPalMail
|
||||||
contactGitHub
|
contactGitHub
|
||||||
}
|
}
|
||||||
}
|
|
||||||
file(relativePath: { eq: "images/pplogo.png" }) {
|
|
||||||
childImageSharp {
|
|
||||||
resize(width: 240, height: 240, fit: CONTAIN) {
|
|
||||||
src
|
|
||||||
}
|
}
|
||||||
}
|
file(relativePath: { eq: "images/pplogo.png" }) {
|
||||||
}
|
childImageSharp {
|
||||||
locales: allLocale(filter: { language: { eq: $language } }) {
|
resize(width: 240, height: 240, fit: CONTAIN) {
|
||||||
edges {
|
src
|
||||||
node {
|
}
|
||||||
ns
|
}
|
||||||
data
|
}
|
||||||
language
|
locales: allLocale(filter: { language: { eq: $language } }) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
ns
|
||||||
|
data
|
||||||
|
language
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const DonatePage = (props) => {
|
const DonatePage = (props) => {
|
||||||
const [amount, setAmount] = useState(5);
|
const [amount, setAmount] = useState(5);
|
||||||
const { t } = useI18next();
|
const { t } = useI18next();
|
||||||
const { path } = React.useContext(I18nextContext);
|
const { path } = React.useContext(I18nextContext);
|
||||||
|
|
||||||
const { site, file } = props.data;
|
const { site, file } = props.data;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout title={t("donate")} description={t("donationCatchphrase")}>
|
<Layout title={t("donate")} description={t("donationCatchphrase")}>
|
||||||
<section>
|
<section>
|
||||||
<article>
|
<article>
|
||||||
<h1>
|
<h1>
|
||||||
<Trans>donate</Trans>
|
<Trans>donate</Trans>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<Trans>donateDescription</Trans>
|
<Trans>donateDescription</Trans>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<Trans>donateGitHub</Trans>
|
<Trans>donateGitHub</Trans>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p style={{ display: "block", textAlign: "center" }}>
|
<p style={{ display: "block", textAlign: "center" }}>
|
||||||
<GitHubButton
|
<GitHubButton
|
||||||
href={
|
href={
|
||||||
"https://github.com/sponsors/" + site.siteMetadata.contactGitHub
|
"https://github.com/sponsors/" +
|
||||||
}
|
site.siteMetadata.contactGitHub
|
||||||
data-color-scheme="no-preference: light; light: dark; dark: dark;"
|
}
|
||||||
data-icon="octicon-heart"
|
data-color-scheme="no-preference: light; light: dark; dark: dark;"
|
||||||
data-size="large"
|
data-icon="octicon-heart"
|
||||||
aria-label="Sponsor @Unkn0wnCat on GitHub"
|
data-size="large"
|
||||||
>
|
aria-label="Sponsor @Unkn0wnCat on GitHub">
|
||||||
<Trans>sponsorGitHub</Trans>
|
<Trans>sponsorGitHub</Trans>
|
||||||
</GitHubButton>
|
</GitHubButton>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<Trans>donatePayPal</Trans>
|
<Trans>donatePayPal</Trans>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div className={styles.priceAmount}>
|
<div className={styles.priceAmount}>
|
||||||
<label htmlFor="priceInput" className={styles.sronly}>
|
<label htmlFor="priceInput" className={styles.sronly}>
|
||||||
Amount
|
Amount
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
min="1"
|
min="1"
|
||||||
placeholder="10.00"
|
placeholder="10.00"
|
||||||
step="1"
|
step="1"
|
||||||
value={amount}
|
value={amount}
|
||||||
onChange={(ev) => {
|
onChange={(ev) => {
|
||||||
setAmount(ev.target.value);
|
setAmount(ev.target.value);
|
||||||
}}
|
}}
|
||||||
name="priceInput"
|
name="priceInput"
|
||||||
id="priceInput"
|
id="priceInput"
|
||||||
/>
|
/>
|
||||||
<div>€</div>
|
<div>€</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a
|
<a
|
||||||
className={styles.donateButton}
|
className={styles.donateButton}
|
||||||
rel="noopener"
|
rel="noopener"
|
||||||
id="payPalBtn"
|
id="payPalBtn"
|
||||||
href={
|
href={
|
||||||
"https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=" +
|
"https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=" +
|
||||||
encodeURIComponent(site.siteMetadata.payPalMail) +
|
encodeURIComponent(site.siteMetadata.payPalMail) +
|
||||||
"&item_name=" +
|
"&item_name=" +
|
||||||
encodeURIComponent(site.siteMetadata.title) +
|
encodeURIComponent(site.siteMetadata.title) +
|
||||||
"¤cy_code=EUR&image_url=" +
|
"¤cy_code=EUR&image_url=" +
|
||||||
encodeURIComponent(
|
encodeURIComponent(
|
||||||
site.siteMetadata.siteUrl + file.childImageSharp.resize.src
|
site.siteMetadata.siteUrl +
|
||||||
) +
|
file.childImageSharp.resize.src
|
||||||
"&return=" +
|
) +
|
||||||
encodeURIComponent(
|
"&return=" +
|
||||||
site.siteMetadata.siteUrl + "/" + path + "thank-you/"
|
encodeURIComponent(
|
||||||
) +
|
site.siteMetadata.siteUrl +
|
||||||
"&rm=0&cancel_return=" +
|
"/" +
|
||||||
encodeURIComponent(site.siteMetadata.siteUrl + "/" + path) +
|
path +
|
||||||
"&amount=" +
|
"thank-you/"
|
||||||
amount
|
) +
|
||||||
}
|
"&rm=0&cancel_return=" +
|
||||||
>
|
encodeURIComponent(
|
||||||
<span>Donate using PayPal</span>
|
site.siteMetadata.siteUrl + "/" + path
|
||||||
<i className="fas fa-fw fa-chevron-right" aria-hidden="true"></i>
|
) +
|
||||||
</a>
|
"&amount=" +
|
||||||
</article>
|
amount
|
||||||
</section>
|
}>
|
||||||
</Layout>
|
<span>Donate using PayPal</span>
|
||||||
);
|
<i
|
||||||
|
className="fas fa-fw fa-chevron-right"
|
||||||
|
aria-hidden="true"></i>
|
||||||
|
</a>
|
||||||
|
</article>
|
||||||
|
</section>
|
||||||
|
</Layout>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
DonatePage.propTypes = {
|
DonatePage.propTypes = {
|
||||||
data: PropTypes.object.isRequired,
|
data: PropTypes.object.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default DonatePage;
|
export default DonatePage;
|
||||||
|
|
|
@ -5,51 +5,55 @@ import { graphql } from "gatsby";
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
|
|
||||||
export const query = graphql`
|
export const query = graphql`
|
||||||
query GetThankYouPage($language: String!) {
|
query GetThankYouPage($language: String!) {
|
||||||
site {
|
site {
|
||||||
siteMetadata {
|
siteMetadata {
|
||||||
contactEmail
|
contactEmail
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
locales: allLocale(filter: { language: { eq: $language } }) {
|
locales: allLocale(filter: { language: { eq: $language } }) {
|
||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
ns
|
ns
|
||||||
data
|
data
|
||||||
language
|
language
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const ThankYouPage = (props) => {
|
const ThankYouPage = (props) => {
|
||||||
const { site } = props.data;
|
const { site } = props.data;
|
||||||
|
|
||||||
let contactEmail = site.siteMetadata.contactEmail;
|
let contactEmail = site.siteMetadata.contactEmail;
|
||||||
const { t } = useI18next();
|
const { t } = useI18next();
|
||||||
return (
|
return (
|
||||||
<Layout title={t("donate")}>
|
<Layout title={t("donate")}>
|
||||||
<section>
|
<section>
|
||||||
<article>
|
<article>
|
||||||
<h1>
|
<h1>
|
||||||
<Trans>donateThanks</Trans>
|
<Trans>donateThanks</Trans>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<Trans contactEmail={contactEmail} i18nKey="donateThanksText">
|
<Trans
|
||||||
donateThanksText
|
contactEmail={contactEmail}
|
||||||
<a href={"mailto:" + contactEmail}>{{ contactEmail }}</a>
|
i18nKey="donateThanksText">
|
||||||
</Trans>
|
donateThanksText
|
||||||
</p>
|
<a href={"mailto:" + contactEmail}>
|
||||||
</article>
|
{{ contactEmail }}
|
||||||
</section>
|
</a>
|
||||||
</Layout>
|
</Trans>
|
||||||
);
|
</p>
|
||||||
|
</article>
|
||||||
|
</section>
|
||||||
|
</Layout>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
ThankYouPage.propTypes = {
|
ThankYouPage.propTypes = {
|
||||||
data: PropTypes.object.isRequired,
|
data: PropTypes.object.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ThankYouPage;
|
export default ThankYouPage;
|
||||||
|
|
|
@ -7,31 +7,31 @@ import PropTypes from "prop-types";
|
||||||
import * as styles from "./friends.module.scss";
|
import * as styles from "./friends.module.scss";
|
||||||
|
|
||||||
export const query = graphql`
|
export const query = graphql`
|
||||||
query AllFriendsQuery($language: String!) {
|
query AllFriendsQuery($language: String!) {
|
||||||
allFriendsJson {
|
allFriendsJson {
|
||||||
nodes {
|
nodes {
|
||||||
name
|
name
|
||||||
profession
|
profession
|
||||||
url
|
url
|
||||||
imageURL
|
imageURL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
locales: allLocale(filter: { language: { eq: $language } }) {
|
locales: allLocale(filter: { language: { eq: $language } }) {
|
||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
ns
|
ns
|
||||||
data
|
data
|
||||||
language
|
language
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const FriendsPage = ({ data }) => {
|
const FriendsPage = ({ data }) => {
|
||||||
const { t } = useI18next();
|
const { t } = useI18next();
|
||||||
|
|
||||||
/*function shuffle(a) {
|
/*function shuffle(a) {
|
||||||
for (let i = a.length - 1; i > 0; i--) {
|
for (let i = a.length - 1; i > 0; i--) {
|
||||||
const j = Math.floor(Math.random() * (i + 1));
|
const j = Math.floor(Math.random() * (i + 1));
|
||||||
[a[i], a[j]] = [a[j], a[i]];
|
[a[i], a[j]] = [a[j], a[i]];
|
||||||
|
@ -39,59 +39,102 @@ const FriendsPage = ({ data }) => {
|
||||||
return a;
|
return a;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout title={t("friends")} description={t("friendsDescription")}>
|
<Layout title={t("friends")} description={t("friendsDescription")}>
|
||||||
<section>
|
<section>
|
||||||
<article>
|
<article>
|
||||||
<h1>
|
<h1>
|
||||||
<Trans>social</Trans>
|
<Trans>social</Trans>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<Trans>friendsDescription</Trans>
|
<Trans>friendsDescription</Trans>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div className={styles.friendsList}>
|
<div className={styles.friendsList}>
|
||||||
{/*shuffle(*/data.allFriendsJson.nodes/*)*/.map((friend) => {
|
{
|
||||||
return (
|
/*shuffle(*/ data.allFriendsJson.nodes /*)*/
|
||||||
<div
|
.map((friend) => {
|
||||||
className={styles.friendProfile}
|
return (
|
||||||
key={friend.url + "#" + friend.name}
|
<div
|
||||||
>
|
className={styles.friendProfile}
|
||||||
<div
|
key={
|
||||||
className={styles.friendImage}
|
friend.url + "#" + friend.name
|
||||||
style={{ backgroundImage: "url(" + friend.imageURL + ")" }}
|
}>
|
||||||
key={friend.url + "#" + friend.name + "#image"}
|
<div
|
||||||
>
|
className={styles.friendImage}
|
||||||
<span className={styles.friendName} key={friend.url + "#" + friend.name + "#name"}>{friend.name}</span>
|
style={{
|
||||||
<span className={styles.friendTitle} key={friend.url + "#" + friend.name + "#profession"}>
|
backgroundImage:
|
||||||
{friend.profession}
|
"url(" +
|
||||||
</span>
|
friend.imageURL +
|
||||||
</div>
|
")",
|
||||||
|
}}
|
||||||
|
key={
|
||||||
|
friend.url +
|
||||||
|
"#" +
|
||||||
|
friend.name +
|
||||||
|
"#image"
|
||||||
|
}>
|
||||||
|
<span
|
||||||
|
className={
|
||||||
|
styles.friendName
|
||||||
|
}
|
||||||
|
key={
|
||||||
|
friend.url +
|
||||||
|
"#" +
|
||||||
|
friend.name +
|
||||||
|
"#name"
|
||||||
|
}>
|
||||||
|
{friend.name}
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
className={
|
||||||
|
styles.friendTitle
|
||||||
|
}
|
||||||
|
key={
|
||||||
|
friend.url +
|
||||||
|
"#" +
|
||||||
|
friend.name +
|
||||||
|
"#profession"
|
||||||
|
}>
|
||||||
|
{friend.profession}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className={styles.contactLinks} key={friend.url + "#" + friend.name + "#links"}>
|
<div
|
||||||
<a
|
className={styles.contactLinks}
|
||||||
className={styles.contactLink}
|
key={
|
||||||
href={friend.url}
|
friend.url +
|
||||||
target="_blank"
|
"#" +
|
||||||
rel="noreferrer"
|
friend.name +
|
||||||
>
|
"#links"
|
||||||
<i className="fas fa-globe-europe" aria-hidden="true"></i>{" "}
|
}>
|
||||||
{friend.url}
|
<a
|
||||||
</a>
|
className={
|
||||||
</div>
|
styles.contactLink
|
||||||
</div>
|
}
|
||||||
);
|
href={friend.url}
|
||||||
})}
|
target="_blank"
|
||||||
</div>
|
rel="noreferrer">
|
||||||
</article>
|
<i
|
||||||
</section>
|
className="fas fa-globe-europe"
|
||||||
</Layout>
|
aria-hidden="true"></i>{" "}
|
||||||
);
|
{friend.url}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</section>
|
||||||
|
</Layout>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
FriendsPage.propTypes = {
|
FriendsPage.propTypes = {
|
||||||
data: PropTypes.object.isRequired,
|
data: PropTypes.object.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default FriendsPage;
|
export default FriendsPage;
|
||||||
|
|
|
@ -12,244 +12,253 @@ import { MDXRenderer } from "gatsby-plugin-mdx";
|
||||||
import anime from "animejs";
|
import anime from "animejs";
|
||||||
import { tsParticles } from "tsparticles";
|
import { tsParticles } from "tsparticles";
|
||||||
|
|
||||||
|
|
||||||
import * as particleConfig from "./index.particles.json";
|
import * as particleConfig from "./index.particles.json";
|
||||||
|
|
||||||
export const query = graphql`
|
export const query = graphql`
|
||||||
query GetMetaAndProjects($language: String) {
|
query GetMetaAndProjects($language: String) {
|
||||||
site {
|
site {
|
||||||
siteMetadata {
|
siteMetadata {
|
||||||
contactEmail
|
contactEmail
|
||||||
contactPhone
|
contactPhone
|
||||||
mapsLink
|
mapsLink
|
||||||
contactTwitter
|
contactTwitter
|
||||||
contactGitHub
|
contactGitHub
|
||||||
contactMastodon
|
contactMastodon
|
||||||
contactMastodonHref
|
contactMastodonHref
|
||||||
}
|
|
||||||
}
|
|
||||||
allProjectsJson(
|
|
||||||
filter: { lang: { eq: $language }, featured: { gte: 0 } }
|
|
||||||
sort: { fields: featured, order: ASC }
|
|
||||||
) {
|
|
||||||
nodes {
|
|
||||||
lang
|
|
||||||
urlname
|
|
||||||
name
|
|
||||||
image {
|
|
||||||
childImageSharp {
|
|
||||||
resize(width: 400, quality: 90) {
|
|
||||||
src
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
shortDescription
|
allProjectsJson(
|
||||||
featured
|
filter: { lang: { eq: $language }, featured: { gte: 0 } }
|
||||||
}
|
sort: { fields: featured, order: ASC }
|
||||||
}
|
) {
|
||||||
locales: allLocale(filter: { language: { eq: $language } }) {
|
nodes {
|
||||||
edges {
|
lang
|
||||||
node {
|
urlname
|
||||||
ns
|
name
|
||||||
data
|
image {
|
||||||
language
|
childImageSharp {
|
||||||
|
resize(width: 400, quality: 90) {
|
||||||
|
src
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
file(
|
|
||||||
sourceInstanceName: {eq: "textblocks"}, relativeDirectory: {eq: "home/about"}, name: {eq: $language}
|
|
||||||
) {
|
|
||||||
id
|
|
||||||
childMdx {
|
|
||||||
body
|
|
||||||
}
|
|
||||||
name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const IndexPage = (props) => {
|
const IndexPage = (props) => {
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (typeof window === "undefined") return;
|
if (typeof window === "undefined") return;
|
||||||
|
|
||||||
anime({
|
anime({
|
||||||
targets: [
|
targets: [
|
||||||
"." + styles.profileCard + " > span",
|
"." + styles.profileCard + " > span",
|
||||||
"." + styles.profileCard + " a",
|
"." + styles.profileCard + " a",
|
||||||
],
|
],
|
||||||
opacity: [0, 1],
|
opacity: [0, 1],
|
||||||
translateX: [100, 0],
|
translateX: [100, 0],
|
||||||
duration: 250,
|
duration: 250,
|
||||||
delay: anime.stagger(20),
|
delay: anime.stagger(20),
|
||||||
easing: "easeInOutCirc",
|
easing: "easeInOutCirc",
|
||||||
});
|
});
|
||||||
anime({
|
anime({
|
||||||
targets: ["." + styles.profileImageDummy],
|
targets: ["." + styles.profileImageDummy],
|
||||||
translateX: [0, -3],
|
translateX: [0, -3],
|
||||||
translateY: [0, 3],
|
translateY: [0, 3],
|
||||||
duration: 250,
|
duration: 250,
|
||||||
easing: "easeInOutCirc",
|
easing: "easeInOutCirc",
|
||||||
});
|
});
|
||||||
anime({
|
anime({
|
||||||
targets: ["." + styles.profileImage],
|
targets: ["." + styles.profileImage],
|
||||||
translateX: [0, 4],
|
translateX: [0, 4],
|
||||||
translateY: [0, -4],
|
translateY: [0, -4],
|
||||||
duration: 250,
|
duration: 250,
|
||||||
easing: "easeInOutCirc",
|
easing: "easeInOutCirc",
|
||||||
});
|
});
|
||||||
|
|
||||||
tsParticles.load("particle-container", particleConfig);
|
tsParticles.load("particle-container", particleConfig);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
let meta = props.data.site.siteMetadata;
|
let meta = props.data.site.siteMetadata;
|
||||||
let file = props.data.file;
|
let file = props.data.file;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout title="Kevin Kandlbinder" transparentTopbar={true}>
|
<Layout title="Kevin Kandlbinder" transparentTopbar={true}>
|
||||||
<section className={styles.heroSection}>
|
<section className={styles.heroSection}>
|
||||||
<div className={styles.heroSectionBg} id="particle-container"></div>
|
<div
|
||||||
<div className={styles.heroSectionBgOver}></div>
|
className={styles.heroSectionBg}
|
||||||
<div className={styles.profile + " profile"}>
|
id="particle-container"></div>
|
||||||
<div
|
<div className={styles.heroSectionBgOver}></div>
|
||||||
data-bg="url(https://cdn.kevink.dev/images/kevin/kevin-kandlbinder-03.jpg)"
|
<div className={styles.profile + " profile"}>
|
||||||
style={{
|
<div
|
||||||
backgroundImage:
|
data-bg="url(https://cdn.kevink.dev/images/kevin/kevin-kandlbinder-03.jpg)"
|
||||||
"url(https://cdn.kevink.dev/images/kevin/kevin-kandlbinder-03.jpg)",
|
style={{
|
||||||
}}
|
backgroundImage:
|
||||||
className={styles.profileImage + " lazy"}
|
"url(https://cdn.kevink.dev/images/kevin/kevin-kandlbinder-03.jpg)",
|
||||||
></div>
|
}}
|
||||||
<div className={styles.profileImageDummy}></div>
|
className={styles.profileImage + " lazy"}></div>
|
||||||
<div className={styles.profileCard}>
|
<div className={styles.profileImageDummy}></div>
|
||||||
<span className={styles.hello}>
|
<div className={styles.profileCard}>
|
||||||
<Trans>homeHello</Trans>
|
<span className={styles.hello}>
|
||||||
</span>
|
<Trans>homeHello</Trans>
|
||||||
<span className={styles.name}>Kevin Kandlbinder</span>
|
</span>
|
||||||
<span className={styles.description}>
|
<span className={styles.name}>Kevin Kandlbinder</span>
|
||||||
<Trans>homeMe</Trans>{" "}
|
<span className={styles.description}>
|
||||||
<span id="descriptionType">
|
<Trans>homeMe</Trans>{" "}
|
||||||
<Trans>homeWebDeveloper</Trans>
|
<span id="descriptionType">
|
||||||
</span>
|
<Trans>homeWebDeveloper</Trans>
|
||||||
.
|
</span>
|
||||||
</span>
|
.
|
||||||
|
</span>
|
||||||
|
|
||||||
<div className={styles.contactLinks}>
|
<div className={styles.contactLinks}>
|
||||||
<a
|
<a
|
||||||
className={styles.contactLink}
|
className={styles.contactLink}
|
||||||
href={"tel:" + meta.contactPhone}
|
href={"tel:" + meta.contactPhone}
|
||||||
rel="me"
|
rel="me">
|
||||||
>
|
<i className="fas fa-fw fa-phone"></i>
|
||||||
<i className="fas fa-fw fa-phone"></i>
|
{meta.contactPhone}
|
||||||
{meta.contactPhone}
|
</a>
|
||||||
</a>
|
<a
|
||||||
<a
|
className={styles.contactLink}
|
||||||
className={styles.contactLink}
|
href={"mailto:" + meta.contactEmail}
|
||||||
href={"mailto:" + meta.contactEmail}
|
rel="me">
|
||||||
rel="me"
|
<i className="far fa-fw fa-envelope"></i>
|
||||||
>
|
{meta.contactEmail}
|
||||||
<i className="far fa-fw fa-envelope"></i>
|
</a>
|
||||||
{meta.contactEmail}
|
<a
|
||||||
</a>
|
className={styles.contactLink}
|
||||||
<a
|
href={meta.mapsLink}
|
||||||
className={styles.contactLink}
|
rel="noreferrer "
|
||||||
href={meta.mapsLink}
|
target="_blank">
|
||||||
rel="noreferrer "
|
<i className="fas fa-fw fa-map-marker-alt"></i>
|
||||||
target="_blank"
|
<Trans>homeMyLocation</Trans>
|
||||||
>
|
</a>
|
||||||
<i className="fas fa-fw fa-map-marker-alt"></i>
|
<a
|
||||||
<Trans>homeMyLocation</Trans>
|
className={styles.contactLink}
|
||||||
</a>
|
href={meta.contactMastodonHref}
|
||||||
<a
|
rel="noreferrer me"
|
||||||
className={styles.contactLink}
|
target="_blank">
|
||||||
href={meta.contactMastodonHref}
|
<i className="fab fa-fw fa-mastodon"></i>
|
||||||
rel="noreferrer me"
|
{meta.contactMastodon}
|
||||||
target="_blank"
|
</a>
|
||||||
>
|
<a
|
||||||
<i className="fab fa-fw fa-mastodon"></i>
|
className={styles.contactLink}
|
||||||
{meta.contactMastodon}
|
href={
|
||||||
</a>
|
"https://github.com/" + meta.contactGitHub
|
||||||
<a
|
}
|
||||||
className={styles.contactLink}
|
rel="noreferrer me"
|
||||||
href={"https://github.com/" + meta.contactGitHub}
|
target="_blank">
|
||||||
rel="noreferrer me"
|
<i className="fab fa-fw fa-github"></i>
|
||||||
target="_blank"
|
{meta.contactGitHub}
|
||||||
>
|
</a>
|
||||||
<i className="fab fa-fw fa-github"></i>
|
</div>
|
||||||
{meta.contactGitHub}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section className="aboutSection">
|
|
||||||
<article>
|
|
||||||
<MDXRenderer>{file.childMdx.body}</MDXRenderer>
|
|
||||||
</article>
|
|
||||||
</section>
|
|
||||||
<a
|
|
||||||
className={styles.creditSection}
|
|
||||||
href="https://unsplash.com/@jannikkiel"
|
|
||||||
target="_blank"
|
|
||||||
rel="noreferrer"
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
<span>
|
|
||||||
<i className="fas fa-fw fa-camera"></i>{" "}
|
|
||||||
<Trans>homeImageCredit</Trans>
|
|
||||||
</span>
|
|
||||||
<i className="fas fa-fw fa-chevron-right"></i>
|
|
||||||
</div>
|
|
||||||
</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}
|
|
||||||
style={{
|
|
||||||
backgroundImage:
|
|
||||||
"url(" + project.image.childImageSharp.resize.src + ")",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className={projectStyles.projectCardMeta}>
|
|
||||||
<span className={projectStyles.projectCardTitle}>
|
|
||||||
{project.name}
|
|
||||||
</span>
|
|
||||||
<span>{project.shortDescription}</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</section>
|
||||||
);
|
<section className="aboutSection">
|
||||||
})}
|
<article>
|
||||||
</div>
|
<MDXRenderer>{file.childMdx.body}</MDXRenderer>
|
||||||
<Link to="/projects" className={styles.seeMoreButton}>
|
</article>
|
||||||
<Trans>seeMore</Trans>{" "}
|
</section>
|
||||||
<i className="fas fa-fw fa-chevron-right"></i>
|
<a
|
||||||
</Link>
|
className={styles.creditSection}
|
||||||
</article>
|
href="https://unsplash.com/@jannikkiel"
|
||||||
</section>
|
target="_blank"
|
||||||
<Link className={styles.donationSection} to="/donate">
|
rel="noreferrer">
|
||||||
<div>
|
<div>
|
||||||
<span>
|
<span>
|
||||||
<Trans>donationCatchphrase</Trans>
|
<i className="fas fa-fw fa-camera"></i>{" "}
|
||||||
</span>
|
<Trans>homeImageCredit</Trans>
|
||||||
<i className="fas fa-fw fa-chevron-right"></i>
|
</span>
|
||||||
</div>
|
<i className="fas fa-fw fa-chevron-right"></i>
|
||||||
</Link>
|
</div>
|
||||||
</Layout>
|
</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
|
||||||
|
}
|
||||||
|
style={{
|
||||||
|
backgroundImage:
|
||||||
|
"url(" +
|
||||||
|
project.image.childImageSharp
|
||||||
|
.resize.src +
|
||||||
|
")",
|
||||||
|
}}>
|
||||||
|
<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>{" "}
|
||||||
|
<i className="fas fa-fw fa-chevron-right"></i>
|
||||||
|
</Link>
|
||||||
|
</article>
|
||||||
|
</section>
|
||||||
|
<Link className={styles.donationSection} to="/donate">
|
||||||
|
<div>
|
||||||
|
<span>
|
||||||
|
<Trans>donationCatchphrase</Trans>
|
||||||
|
</span>
|
||||||
|
<i className="fas fa-fw fa-chevron-right"></i>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
</Layout>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
IndexPage.propTypes = {
|
IndexPage.propTypes = {
|
||||||
data: PropTypes.object.isRequired,
|
data: PropTypes.object.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default IndexPage;
|
export default IndexPage;
|
||||||
|
|
|
@ -6,7 +6,8 @@
|
||||||
height: 600px;
|
height: 600px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
.heroSectionBg, .heroSectionBgOver {
|
.heroSectionBg,
|
||||||
|
.heroSectionBgOver {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: unset;
|
max-width: unset;
|
||||||
|
@ -22,7 +23,20 @@
|
||||||
/*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);*/
|
||||||
|
|
||||||
background: linear-gradient(45deg, #000850 0%, #000320 100%), radial-gradient(100% 225% at 100% 0%, #FF6928 0%, #000000 100%), linear-gradient(225deg, #FF7A00 0%, #000000 100%), linear-gradient(135deg, #CDFFEB 10%, #CDFFEB 35%, #009F9D 35%, #009F9D 60%, #07456F 60%, #07456F 67%, #0F0A3C 67%, #0F0A3C 100%);
|
background: linear-gradient(45deg, #000850 0%, #000320 100%),
|
||||||
|
radial-gradient(100% 225% at 100% 0%, #ff6928 0%, #000000 100%),
|
||||||
|
linear-gradient(225deg, #ff7a00 0%, #000000 100%),
|
||||||
|
linear-gradient(
|
||||||
|
135deg,
|
||||||
|
#cdffeb 10%,
|
||||||
|
#cdffeb 35%,
|
||||||
|
#009f9d 35%,
|
||||||
|
#009f9d 60%,
|
||||||
|
#07456f 60%,
|
||||||
|
#07456f 67%,
|
||||||
|
#0f0a3c 67%,
|
||||||
|
#0f0a3c 100%
|
||||||
|
);
|
||||||
background-blend-mode: screen, overlay, hard-light, normal;
|
background-blend-mode: screen, overlay, hard-light, normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,107 +1,107 @@
|
||||||
{
|
{
|
||||||
"particles": {
|
"particles": {
|
||||||
"number": {
|
"number": {
|
||||||
"value": 33,
|
"value": 33,
|
||||||
"density": {
|
"density": {
|
||||||
"enable": true,
|
"enable": true,
|
||||||
"value_area": 800
|
"value_area": 800
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"color": {
|
"color": {
|
||||||
"value": "#1b1e34"
|
"value": "#1b1e34"
|
||||||
},
|
},
|
||||||
"shape": {
|
"shape": {
|
||||||
"type": "circle",
|
"type": "circle",
|
||||||
"stroke": {
|
"stroke": {
|
||||||
"width": 0,
|
"width": 0,
|
||||||
"color": "#000"
|
"color": "#000"
|
||||||
},
|
},
|
||||||
"polygon": {
|
"polygon": {
|
||||||
"nb_sides": 3
|
"nb_sides": 3
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"opacity": {
|
"opacity": {
|
||||||
"value": 0.4,
|
"value": 0.4,
|
||||||
"random": true,
|
"random": true,
|
||||||
"anim": {
|
"anim": {
|
||||||
"enable": false,
|
"enable": false,
|
||||||
"speed": 1,
|
"speed": 1,
|
||||||
"opacity_min": 0.1,
|
"opacity_min": 0.1,
|
||||||
"sync": false
|
"sync": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"size": {
|
"size": {
|
||||||
"value": 27.620603391810075,
|
"value": 27.620603391810075,
|
||||||
"random": true,
|
"random": true,
|
||||||
"anim": {
|
"anim": {
|
||||||
"enable": false,
|
"enable": false,
|
||||||
"speed": 10,
|
"speed": 10,
|
||||||
"size_min": 40,
|
"size_min": 40,
|
||||||
"sync": false
|
"sync": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"line_linked": {
|
|
||||||
"enable": false,
|
|
||||||
"distance": 200,
|
|
||||||
"color": "#ffffff",
|
|
||||||
"opacity": 0.14994041841268327,
|
|
||||||
"width": 2
|
|
||||||
},
|
|
||||||
"move": {
|
|
||||||
"enable": true,
|
|
||||||
"speed": 0.2,
|
|
||||||
"direction": "top",
|
|
||||||
"random": true,
|
|
||||||
"straight": false,
|
|
||||||
"out_mode": "out",
|
|
||||||
"bounce": false,
|
|
||||||
"attract": {
|
|
||||||
"enable": false,
|
|
||||||
"rotateX": 600,
|
|
||||||
"rotateY": 1200
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"interactivity": {
|
|
||||||
"detect_on": "window",
|
|
||||||
"events": {
|
|
||||||
"onhover": {
|
|
||||||
"enable": false,
|
|
||||||
"mode": "repulse"
|
|
||||||
},
|
|
||||||
"onclick": {
|
|
||||||
"enable": false,
|
|
||||||
"mode": "push"
|
|
||||||
},
|
|
||||||
"resize": true
|
|
||||||
},
|
|
||||||
"modes": {
|
|
||||||
"grab": {
|
|
||||||
"distance": 400,
|
|
||||||
"line_linked": {
|
"line_linked": {
|
||||||
"opacity": 1
|
"enable": false,
|
||||||
|
"distance": 200,
|
||||||
|
"color": "#ffffff",
|
||||||
|
"opacity": 0.14994041841268327,
|
||||||
|
"width": 2
|
||||||
|
},
|
||||||
|
"move": {
|
||||||
|
"enable": true,
|
||||||
|
"speed": 0.2,
|
||||||
|
"direction": "top",
|
||||||
|
"random": true,
|
||||||
|
"straight": false,
|
||||||
|
"out_mode": "out",
|
||||||
|
"bounce": false,
|
||||||
|
"attract": {
|
||||||
|
"enable": false,
|
||||||
|
"rotateX": 600,
|
||||||
|
"rotateY": 1200
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bubble": {
|
"interactivity": {
|
||||||
"distance": 400,
|
"detect_on": "window",
|
||||||
"size": 40,
|
"events": {
|
||||||
"duration": 2,
|
"onhover": {
|
||||||
"opacity": 8,
|
"enable": false,
|
||||||
"speed": 3
|
"mode": "repulse"
|
||||||
},
|
},
|
||||||
"repulse": {
|
"onclick": {
|
||||||
"distance": 200,
|
"enable": false,
|
||||||
"duration": 0.4
|
"mode": "push"
|
||||||
},
|
},
|
||||||
"push": {
|
"resize": true
|
||||||
"particles_nb": 4
|
},
|
||||||
},
|
"modes": {
|
||||||
"remove": {
|
"grab": {
|
||||||
"particles_nb": 2
|
"distance": 400,
|
||||||
}
|
"line_linked": {
|
||||||
}
|
"opacity": 1
|
||||||
},
|
}
|
||||||
"detectRetina": true,
|
},
|
||||||
"pauseOnBlur": true,
|
"bubble": {
|
||||||
"pauseOnOutsideViewport": true
|
"distance": 400,
|
||||||
|
"size": 40,
|
||||||
|
"duration": 2,
|
||||||
|
"opacity": 8,
|
||||||
|
"speed": 3
|
||||||
|
},
|
||||||
|
"repulse": {
|
||||||
|
"distance": 200,
|
||||||
|
"duration": 0.4
|
||||||
|
},
|
||||||
|
"push": {
|
||||||
|
"particles_nb": 4
|
||||||
|
},
|
||||||
|
"remove": {
|
||||||
|
"particles_nb": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"detectRetina": true,
|
||||||
|
"pauseOnBlur": true,
|
||||||
|
"pauseOnOutsideViewport": true
|
||||||
}
|
}
|
|
@ -4,53 +4,56 @@ import { Trans, useI18next } from "gatsby-plugin-react-i18next";
|
||||||
import { graphql } from "gatsby";
|
import { graphql } from "gatsby";
|
||||||
|
|
||||||
export const query = graphql`
|
export const query = graphql`
|
||||||
query($language: String!) {
|
query ($language: String!) {
|
||||||
locales: allLocale(filter: { language: { eq: $language } }) {
|
locales: allLocale(filter: { language: { eq: $language } }) {
|
||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
ns
|
ns
|
||||||
data
|
data
|
||||||
language
|
language
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default function ImprintPage() {
|
export default function ImprintPage() {
|
||||||
const { t } = useI18next();
|
const { t } = useI18next();
|
||||||
return (
|
return (
|
||||||
<Layout title={t("imprint")}>
|
<Layout title={t("imprint")}>
|
||||||
<section>
|
<section>
|
||||||
<article>
|
<article>
|
||||||
<h1>
|
<h1>
|
||||||
<Trans>imprint</Trans>
|
<Trans>imprint</Trans>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<p>Angaben gemäß § 5 TMG</p>
|
<p>Angaben gemäß § 5 TMG</p>
|
||||||
<p>
|
<p>
|
||||||
Kevin Kandlbinder
|
Kevin Kandlbinder
|
||||||
<br />
|
<br />
|
||||||
Eichenweg 48
|
Eichenweg 48
|
||||||
<br />
|
<br />
|
||||||
25451 Quickborn <br />
|
25451 Quickborn <br />
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
{" "}
|
{" "}
|
||||||
<strong>Vertreten durch: </strong>
|
<strong>Vertreten durch: </strong>
|
||||||
<br />
|
<br />
|
||||||
Kevin Kandlbinder
|
Kevin Kandlbinder
|
||||||
<br />
|
<br />
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<strong>Kontakt:</strong> <br />
|
<strong>Kontakt:</strong> <br />
|
||||||
Telefon: +49 4106 8068004
|
Telefon: +49 4106 8068004
|
||||||
<br />
|
<br />
|
||||||
E-Mail: <a href="mailto:contact@kevink.dev">contact@kevink.dev</a>
|
E-Mail:{" "}
|
||||||
<br />
|
<a href="mailto:contact@kevink.dev">
|
||||||
</p>
|
contact@kevink.dev
|
||||||
</article>
|
</a>
|
||||||
</section>
|
<br />
|
||||||
</Layout>
|
</p>
|
||||||
);
|
</article>
|
||||||
|
</section>
|
||||||
|
</Layout>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -4,91 +4,98 @@ import { Trans, useI18next } from "gatsby-plugin-react-i18next";
|
||||||
import { graphql } from "gatsby";
|
import { graphql } from "gatsby";
|
||||||
|
|
||||||
export const query = graphql`
|
export const query = graphql`
|
||||||
query($language: String!) {
|
query ($language: String!) {
|
||||||
locales: allLocale(filter: { language: { eq: $language } }) {
|
locales: allLocale(filter: { language: { eq: $language } }) {
|
||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
ns
|
ns
|
||||||
data
|
data
|
||||||
language
|
language
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default function DisclaimerPage() {
|
export default function DisclaimerPage() {
|
||||||
const { t } = useI18next();
|
const { t } = useI18next();
|
||||||
return (
|
return (
|
||||||
<Layout title={t("disclaimer")}>
|
<Layout title={t("disclaimer")}>
|
||||||
<section>
|
<section>
|
||||||
<article>
|
<article>
|
||||||
<h1>
|
<h1>
|
||||||
<Trans>disclaimer</Trans>
|
<Trans>disclaimer</Trans>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<h2>Haftung für Inhalte</h2>
|
<h2>Haftung für Inhalte</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Als Diensteanbieter sind wir gemäß § 7 Abs.1 TMG für eigene Inhalte
|
Als Diensteanbieter sind wir gemäß § 7 Abs.1 TMG für
|
||||||
auf diesen Seiten nach den allgemeinen Gesetzen verantwortlich. Nach
|
eigene Inhalte auf diesen Seiten nach den allgemeinen
|
||||||
§§ 8 bis 10 TMG sind wir als Diensteanbieter jedoch nicht
|
Gesetzen verantwortlich. Nach §§ 8 bis 10 TMG sind wir
|
||||||
verpflichtet, übermittelte oder gespeicherte fremde Informationen zu
|
als Diensteanbieter jedoch nicht verpflichtet,
|
||||||
überwachen oder nach Umständen zu forschen, die auf eine
|
übermittelte oder gespeicherte fremde Informationen zu
|
||||||
rechtswidrige Tätigkeit hinweisen.
|
überwachen oder nach Umständen zu forschen, die auf eine
|
||||||
</p>
|
rechtswidrige Tätigkeit hinweisen.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Verpflichtungen zur Entfernung oder Sperrung der Nutzung von
|
Verpflichtungen zur Entfernung oder Sperrung der Nutzung
|
||||||
Informationen nach den allgemeinen Gesetzen bleiben hiervon
|
von Informationen nach den allgemeinen Gesetzen bleiben
|
||||||
unberührt. Eine diesbezügliche Haftung ist jedoch erst ab dem
|
hiervon unberührt. Eine diesbezügliche Haftung ist
|
||||||
Zeitpunkt der Kenntnis einer konkreten Rechtsverletzung möglich. Bei
|
jedoch erst ab dem Zeitpunkt der Kenntnis einer
|
||||||
Bekanntwerden von entsprechenden Rechtsverletzungen werden wir diese
|
konkreten Rechtsverletzung möglich. Bei Bekanntwerden
|
||||||
Inhalte umgehend entfernen.
|
von entsprechenden Rechtsverletzungen werden wir diese
|
||||||
</p>
|
Inhalte umgehend entfernen.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h2>Haftung für Links</h2>
|
<h2>Haftung für Links</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Unser Angebot enthält Links zu externen Websites Dritter, auf deren
|
Unser Angebot enthält Links zu externen Websites
|
||||||
Inhalte wir keinen Einfluss haben. Deshalb können wir für diese
|
Dritter, auf deren Inhalte wir keinen Einfluss haben.
|
||||||
fremden Inhalte auch keine Gewähr übernehmen. Für die Inhalte der
|
Deshalb können wir für diese fremden Inhalte auch keine
|
||||||
verlinkten Seiten ist stets der jeweilige Anbieter oder Betreiber
|
Gewähr übernehmen. Für die Inhalte der verlinkten Seiten
|
||||||
der Seiten verantwortlich. Die verlinkten Seiten wurden zum
|
ist stets der jeweilige Anbieter oder Betreiber der
|
||||||
Zeitpunkt der Verlinkung auf mögliche Rechtsverstöße überprüft.
|
Seiten verantwortlich. Die verlinkten Seiten wurden zum
|
||||||
Rechtswidrige Inhalte waren zum Zeitpunkt der Verlinkung nicht
|
Zeitpunkt der Verlinkung auf mögliche Rechtsverstöße
|
||||||
erkennbar.
|
überprüft. Rechtswidrige Inhalte waren zum Zeitpunkt der
|
||||||
</p>
|
Verlinkung nicht erkennbar.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Eine permanente inhaltliche Kontrolle der verlinkten Seiten ist
|
Eine permanente inhaltliche Kontrolle der verlinkten
|
||||||
jedoch ohne konkrete Anhaltspunkte einer Rechtsverletzung nicht
|
Seiten ist jedoch ohne konkrete Anhaltspunkte einer
|
||||||
zumutbar. Bei Bekanntwerden von Rechtsverletzungen werden wir
|
Rechtsverletzung nicht zumutbar. Bei Bekanntwerden von
|
||||||
derartige Links umgehend entfernen.
|
Rechtsverletzungen werden wir derartige Links umgehend
|
||||||
</p>
|
entfernen.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h2>Urheberrecht</h2>
|
<h2>Urheberrecht</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Die durch die Seitenbetreiber erstellten Inhalte und Werke auf
|
Die durch die Seitenbetreiber erstellten Inhalte und
|
||||||
diesen Seiten unterliegen dem deutschen Urheberrecht. Die
|
Werke auf diesen Seiten unterliegen dem deutschen
|
||||||
Vervielfältigung, Bearbeitung, Verbreitung und jede Art der
|
Urheberrecht. Die Vervielfältigung, Bearbeitung,
|
||||||
Verwertung außerhalb der Grenzen des Urheberrechtes bedürfen der
|
Verbreitung und jede Art der Verwertung außerhalb der
|
||||||
schriftlichen Zustimmung des jeweiligen Autors bzw. Erstellers.
|
Grenzen des Urheberrechtes bedürfen der schriftlichen
|
||||||
Downloads und Kopien dieser Seite sind nur für den privaten, nicht
|
Zustimmung des jeweiligen Autors bzw. Erstellers.
|
||||||
kommerziellen Gebrauch gestattet.
|
Downloads und Kopien dieser Seite sind nur für den
|
||||||
</p>
|
privaten, nicht kommerziellen Gebrauch gestattet.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Soweit die Inhalte auf dieser Seite nicht vom Betreiber erstellt
|
Soweit die Inhalte auf dieser Seite nicht vom Betreiber
|
||||||
wurden, werden die Urheberrechte Dritter beachtet. Insbesondere
|
erstellt wurden, werden die Urheberrechte Dritter
|
||||||
werden Inhalte Dritter als solche gekennzeichnet. Sollten Sie
|
beachtet. Insbesondere werden Inhalte Dritter als solche
|
||||||
trotzdem auf eine Urheberrechtsverletzung aufmerksam werden, bitten
|
gekennzeichnet. Sollten Sie trotzdem auf eine
|
||||||
wir um einen entsprechenden Hinweis. Bei Bekanntwerden von
|
Urheberrechtsverletzung aufmerksam werden, bitten wir um
|
||||||
Rechtsverletzungen werden wir derartige Inhalte umgehend entfernen.
|
einen entsprechenden Hinweis. Bei Bekanntwerden von
|
||||||
</p>
|
Rechtsverletzungen werden wir derartige Inhalte umgehend
|
||||||
</article>
|
entfernen.
|
||||||
</section>
|
</p>
|
||||||
</Layout>
|
</article>
|
||||||
);
|
</section>
|
||||||
|
</Layout>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,82 +7,88 @@ import PropTypes from "prop-types";
|
||||||
import * as styles from "./projects.module.scss";
|
import * as styles from "./projects.module.scss";
|
||||||
|
|
||||||
export const query = graphql`
|
export const query = graphql`
|
||||||
query GetProjects($language: String) {
|
query GetProjects($language: String) {
|
||||||
allProjectsJson(filter: { lang: { eq: $language } }) {
|
allProjectsJson(filter: { lang: { eq: $language } }) {
|
||||||
nodes {
|
nodes {
|
||||||
lang
|
lang
|
||||||
urlname
|
urlname
|
||||||
name
|
name
|
||||||
image {
|
image {
|
||||||
childImageSharp {
|
childImageSharp {
|
||||||
resize(width: 400, quality: 90) {
|
resize(width: 400, quality: 90) {
|
||||||
src
|
src
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
shortDescription
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
shortDescription
|
locales: allLocale(filter: { language: { eq: $language } }) {
|
||||||
}
|
edges {
|
||||||
}
|
node {
|
||||||
locales: allLocale(filter: { language: { eq: $language } }) {
|
ns
|
||||||
edges {
|
data
|
||||||
node {
|
language
|
||||||
ns
|
}
|
||||||
data
|
}
|
||||||
language
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const ProjectsPage = ({ data }) => {
|
const ProjectsPage = ({ data }) => {
|
||||||
const { t } = useI18next();
|
const { t } = useI18next();
|
||||||
return (
|
return (
|
||||||
<Layout title={t("projects")} description={t("projectsDescription")}>
|
<Layout title={t("projects")} description={t("projectsDescription")}>
|
||||||
<section>
|
<section>
|
||||||
<article>
|
<article>
|
||||||
<h1>
|
<h1>
|
||||||
<Trans>projects</Trans>
|
<Trans>projects</Trans>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<Trans>projectsDescription</Trans>
|
<Trans>projectsDescription</Trans>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div className={styles.projectList}>
|
<div className={styles.projectList}>
|
||||||
{data.allProjectsJson.nodes.map((project) => {
|
{data.allProjectsJson.nodes.map((project) => {
|
||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
className={styles.projectCard}
|
className={styles.projectCard}
|
||||||
key={project.lang + project.urlname}
|
key={project.lang + project.urlname}
|
||||||
to={"/projects/" + project.urlname}
|
to={"/projects/" + project.urlname}>
|
||||||
>
|
<div
|
||||||
<div
|
className={styles.projectCardImage}
|
||||||
className={styles.projectCardImage}
|
style={{
|
||||||
style={{
|
backgroundImage:
|
||||||
backgroundImage:
|
"url(" +
|
||||||
"url(" + project.image.childImageSharp.resize.src + ")",
|
project.image.childImageSharp
|
||||||
}}
|
.resize.src +
|
||||||
>
|
")",
|
||||||
<div className={styles.projectCardMeta}>
|
}}>
|
||||||
<span className={styles.projectCardTitle}>
|
<div className={styles.projectCardMeta}>
|
||||||
{project.name}
|
<span
|
||||||
</span>
|
className={
|
||||||
<span>{project.shortDescription}</span>
|
styles.projectCardTitle
|
||||||
|
}>
|
||||||
|
{project.name}
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
{project.shortDescription}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</article>
|
||||||
</Link>
|
</section>
|
||||||
);
|
</Layout>
|
||||||
})}
|
);
|
||||||
</div>
|
|
||||||
</article>
|
|
||||||
</section>
|
|
||||||
</Layout>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ProjectsPage.propTypes = {
|
ProjectsPage.propTypes = {
|
||||||
data: PropTypes.object,
|
data: PropTypes.object,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ProjectsPage;
|
export default ProjectsPage;
|
||||||
|
|
|
@ -7,76 +7,77 @@ import PropTypes from "prop-types";
|
||||||
import * as styles from "./social.module.scss";
|
import * as styles from "./social.module.scss";
|
||||||
|
|
||||||
export const query = graphql`
|
export const query = graphql`
|
||||||
query AllSocialsQuery($language: String!) {
|
query AllSocialsQuery($language: String!) {
|
||||||
allSocialsJson {
|
allSocialsJson {
|
||||||
nodes {
|
nodes {
|
||||||
image
|
image
|
||||||
platformHandle
|
platformHandle
|
||||||
platformName
|
platformName
|
||||||
url
|
url
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
locales: allLocale(filter: { language: { eq: $language } }) {
|
locales: allLocale(filter: { language: { eq: $language } }) {
|
||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
ns
|
ns
|
||||||
data
|
data
|
||||||
language
|
language
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const SocialPage = ({ data }) => {
|
const SocialPage = ({ data }) => {
|
||||||
const { t } = useI18next();
|
const { t } = useI18next();
|
||||||
return (
|
return (
|
||||||
<Layout title={t("social")} description={t("socialDescription")}>
|
<Layout title={t("social")} description={t("socialDescription")}>
|
||||||
<section>
|
<section>
|
||||||
<article>
|
<article>
|
||||||
<h1>
|
<h1>
|
||||||
<Trans>social</Trans>
|
<Trans>social</Trans>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<Trans i18nKey="socialDescriptionWithLink">
|
<Trans i18nKey="socialDescriptionWithLink">
|
||||||
socialDescriptionWith<Link to="/friends">Link</Link>
|
socialDescriptionWith<Link to="/friends">Link</Link>
|
||||||
</Trans>
|
</Trans>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div className={styles.socialList}>
|
<div className={styles.socialList}>
|
||||||
{data.allSocialsJson.nodes.map((social) => {
|
{data.allSocialsJson.nodes.map((social) => {
|
||||||
return (
|
return (
|
||||||
<a
|
<a
|
||||||
className={styles.socialCard}
|
className={styles.socialCard}
|
||||||
href={social.url}
|
href={social.url}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noreferrer me"
|
rel="noreferrer me"
|
||||||
key={social.url}
|
key={social.url}>
|
||||||
>
|
<div
|
||||||
<div
|
className={styles.socialImage}
|
||||||
className={styles.socialImage}
|
style={{
|
||||||
style={{ backgroundImage: "url(" + social.image + ")" }}
|
backgroundImage:
|
||||||
>
|
"url(" + social.image + ")",
|
||||||
<span className={styles.socialName}>
|
}}>
|
||||||
{social.platformName}
|
<span className={styles.socialName}>
|
||||||
</span>
|
{social.platformName}
|
||||||
<span className={styles.socialUsername}>
|
</span>
|
||||||
{social.platformHandle}
|
<span className={styles.socialUsername}>
|
||||||
</span>
|
{social.platformHandle}
|
||||||
</div>
|
</span>
|
||||||
</a>
|
</div>
|
||||||
);
|
</a>
|
||||||
})}
|
);
|
||||||
</div>
|
})}
|
||||||
</article>
|
</div>
|
||||||
</section>
|
</article>
|
||||||
</Layout>
|
</section>
|
||||||
);
|
</Layout>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
SocialPage.propTypes = {
|
SocialPage.propTypes = {
|
||||||
data: PropTypes.object.isRequired,
|
data: PropTypes.object.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default SocialPage;
|
export default SocialPage;
|
||||||
|
|
|
@ -8,115 +8,121 @@ import * as styles from "./project.module.scss";
|
||||||
import { MDXRenderer } from "gatsby-plugin-mdx";
|
import { MDXRenderer } from "gatsby-plugin-mdx";
|
||||||
|
|
||||||
export const query = graphql`
|
export const query = graphql`
|
||||||
query GetProject($urlname: String!, $lang: String!, $language: String!) {
|
query GetProject($urlname: String!, $lang: String!, $language: String!) {
|
||||||
allProjectsJson(
|
allProjectsJson(
|
||||||
filter: { urlname: { eq: $urlname }, lang: { eq: $lang } }
|
filter: { urlname: { eq: $urlname }, lang: { eq: $lang } }
|
||||||
) {
|
) {
|
||||||
nodes {
|
nodes {
|
||||||
lang
|
lang
|
||||||
urlname
|
urlname
|
||||||
name
|
name
|
||||||
links {
|
links {
|
||||||
github
|
github
|
||||||
website
|
website
|
||||||
|
}
|
||||||
|
image {
|
||||||
|
publicURL
|
||||||
|
}
|
||||||
|
shortDescription
|
||||||
|
}
|
||||||
}
|
}
|
||||||
image {
|
locales: allLocale(filter: { language: { eq: $language } }) {
|
||||||
publicURL
|
edges {
|
||||||
|
node {
|
||||||
|
ns
|
||||||
|
data
|
||||||
|
language
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
shortDescription
|
file(
|
||||||
}
|
sourceInstanceName: { eq: "projectTextblocks" }
|
||||||
}
|
relativeDirectory: { eq: $urlname }
|
||||||
locales: allLocale(filter: { language: { eq: $language } }) {
|
name: { eq: $language }
|
||||||
edges {
|
) {
|
||||||
node {
|
id
|
||||||
ns
|
childMdx {
|
||||||
data
|
body
|
||||||
language
|
}
|
||||||
|
name
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
file(
|
|
||||||
sourceInstanceName: {eq: "projectTextblocks"}, relativeDirectory: {eq: $urlname}, name: {eq: $language}
|
|
||||||
) {
|
|
||||||
id
|
|
||||||
childMdx {
|
|
||||||
body
|
|
||||||
}
|
|
||||||
name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const ProjectTemplate = ({ data }) => {
|
const ProjectTemplate = ({ data }) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
let project = data.allProjectsJson.nodes[0];
|
let project = data.allProjectsJson.nodes[0];
|
||||||
let projectName = project.name;
|
let projectName = project.name;
|
||||||
let file = data.file;
|
let file = data.file;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout
|
<Layout
|
||||||
description={project.shortDescription}
|
description={project.shortDescription}
|
||||||
title={t("project") + ": " + projectName}
|
title={t("project") + ": " + projectName}
|
||||||
transparentTopbar={true}
|
transparentTopbar={true}>
|
||||||
>
|
<section className={styles.projectHeader}>
|
||||||
<section className={styles.projectHeader}>
|
<div style={{ paddingTop: 0 }}>
|
||||||
<div style={{ paddingTop: 0 }}>
|
<div
|
||||||
<div
|
className={styles.headerBackground}
|
||||||
className={styles.headerBackground}
|
style={{
|
||||||
style={{ backgroundImage: "url(" + project.image.publicURL + ")" }}
|
backgroundImage:
|
||||||
></div>
|
"url(" + project.image.publicURL + ")",
|
||||||
<header>
|
}}></div>
|
||||||
<div className={styles.headerInner}>
|
<header>
|
||||||
<h1>
|
<div className={styles.headerInner}>
|
||||||
<Trans>project</Trans>: {projectName}
|
<h1>
|
||||||
</h1>
|
<Trans>project</Trans>: {projectName}
|
||||||
<span>{project.shortDescription}</span>
|
</h1>
|
||||||
</div>
|
<span>{project.shortDescription}</span>
|
||||||
</header>
|
</div>
|
||||||
<div className={styles.headerPlaceholder}></div>
|
</header>
|
||||||
</div>
|
<div className={styles.headerPlaceholder}></div>
|
||||||
</section>
|
</div>
|
||||||
{file != null && file.childMdx != null ? (
|
</section>
|
||||||
<section className={styles.projectAbout}>
|
{file != null && file.childMdx != null ? (
|
||||||
<article>
|
<section className={styles.projectAbout}>
|
||||||
<MDXRenderer>{file.childMdx.body}</MDXRenderer>
|
<article>
|
||||||
</article>
|
<MDXRenderer>{file.childMdx.body}</MDXRenderer>
|
||||||
</section>
|
</article>
|
||||||
) : null}
|
</section>
|
||||||
{project.links !== null ? (
|
) : null}
|
||||||
<section className={styles.projectLinks}>
|
{project.links !== null ? (
|
||||||
<div>
|
<section className={styles.projectLinks}>
|
||||||
<h1>Links</h1>
|
<div>
|
||||||
<div className={styles.linkList}>
|
<h1>Links</h1>
|
||||||
{project.links.github !== null ? (
|
<div className={styles.linkList}>
|
||||||
<a href={project.links.github} target="_blank" rel="noreferrer">
|
{project.links.github !== null ? (
|
||||||
<i className="fab fa-github" aria-hidden="true"></i>{" "}
|
<a
|
||||||
<Trans>projectViewGitHub</Trans>
|
href={project.links.github}
|
||||||
</a>
|
target="_blank"
|
||||||
) : null}
|
rel="noreferrer">
|
||||||
{project.links.website !== null ? (
|
<i
|
||||||
<a
|
className="fab fa-github"
|
||||||
href={project.links.website}
|
aria-hidden="true"></i>{" "}
|
||||||
target="_blank"
|
<Trans>projectViewGitHub</Trans>
|
||||||
rel="noreferrer"
|
</a>
|
||||||
>
|
) : null}
|
||||||
<i
|
{project.links.website !== null ? (
|
||||||
className="fas fa-external-link-alt"
|
<a
|
||||||
aria-hidden="true"
|
href={project.links.website}
|
||||||
></i>{" "}
|
target="_blank"
|
||||||
<Trans>projectViewWebsite</Trans>
|
rel="noreferrer">
|
||||||
</a>
|
<i
|
||||||
) : null}
|
className="fas fa-external-link-alt"
|
||||||
</div>
|
aria-hidden="true"></i>{" "}
|
||||||
</div>
|
<Trans>projectViewWebsite</Trans>
|
||||||
</section>
|
</a>
|
||||||
) : null}
|
) : null}
|
||||||
</Layout>
|
</div>
|
||||||
);
|
</div>
|
||||||
|
</section>
|
||||||
|
) : null}
|
||||||
|
</Layout>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
ProjectTemplate.propTypes = {
|
ProjectTemplate.propTypes = {
|
||||||
data: PropTypes.object.isRequired,
|
data: PropTypes.object.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ProjectTemplate;
|
export default ProjectTemplate;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue