Rework homepage concept

This commit is contained in:
Kevin Kandlbinder 2021-10-18 16:51:26 +02:00
parent 07c240be4f
commit b50b7d83c3
11 changed files with 548 additions and 222 deletions

217
src/pages/about.js Normal file
View 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;

View file

@ -3,12 +3,10 @@ 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 { StaticImage, GatsbyImage } from "gatsby-plugin-image";
import { StaticImage } from "gatsby-plugin-image";
import anime from "animejs";
@ -28,30 +26,6 @@ export const query = graphql`
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 } }) {
edges {
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 file = props.data.file;
return (
<Layout title="Kevin Kandlbinder" transparentTopbar={true} description={t("siteDescription")}
@ -195,46 +157,30 @@ const IndexPage = (props) => {
</div>
</div>
</div>
</section>
<section className={styles.aboutSection}>
<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 className={styles.spacer}></div>
<div className={styles.landingCta}>
<Link to={"/projects"}>
<div>
<span className={styles.ctaAccent}>{t("explore")}</span>{" "}
<span>{t("myProjects")}</span>
</div>
</div>
</article>
<ArrowRight/>
</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>
<a
className={styles.creditSection}
@ -250,64 +196,6 @@ const IndexPage = (props) => {
<ArrowRight/>
</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
}
>
<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>
);
};

View file

@ -3,15 +3,21 @@
.heroSection {
width: 100%;
height: 600px;
flex-grow: 1;
overflow: hidden;
display: flex;
flex-direction: column;
min-height: 800px;
//scroll-snap-align: start;
padding-top: 100px;
position: relative;
.heroSectionBg,
.heroSectionBgOver {
position: absolute;
width: 100%;
max-width: unset;
height: 600px;
height: 100%;
padding: 0;
@media (pointer: coarse), (pointer: none) {
@ -19,9 +25,16 @@
}
}
.spacer {
flex-grow: 1;
padding: 0;
margin: 0;
}
.heroSectionBg {
/*background: radial-gradient(ellipse at top left, #1f0ba659, transparent),
radial-gradient(ellipse at bottom right, #4a086829, transparent);*/
margin-top: -100px;
background: linear-gradient(45deg, #000850 0%, #000320 100%),
radial-gradient(100% 225% at 100% 0%, #ff6928 0%, #000000 100%),
@ -38,23 +51,70 @@
#0f0a3c 100%
);
background-blend-mode: screen, overlay, hard-light, normal;
}
.heroSectionBgOver {
background: linear-gradient(to bottom, transparent 80%, $background);
transition: background-image 0.25s;
bottom: 0;
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) {
background: linear-gradient(
to bottom,
transparent 90%,
$lightBackground
);
background-color: $lightBackground;
}
}
@media (pointer: coarse), (pointer: none) {
height: 700px;
.landingCta {
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 {
@ -62,9 +122,7 @@
left: 50%;
width: calc(90% - 40px);
max-width: 600px;
max-height: 400px;
transform: translate(-50%, 0%);
top: 100px;
.hello {
font-weight: 100;
@ -157,7 +215,7 @@
clip-path: polygon(14% 4%, 95% 1%, 88% 96%, 2% 89%);
}
@media (max-width: 590px) {
@media (max-width: 690px) {
.profileImage,
.profileImageDummy {
display: none;
@ -212,7 +270,7 @@
.aboutSection {
> article {
display: flex;
align-items: center;
align-items: flex-start;
> div {
width: calc(50% - 40px);