1
0
mirror of https://github.com/kremalicious/portfolio.git synced 2024-12-22 17:23:22 +01:00

refactor header & footer, add github token auth

This commit is contained in:
Matthias Kretschmann 2019-11-10 13:17:13 +01:00
parent cc4c256824
commit fda8949627
Signed by: m
GPG Key ID: 606EEEF3C479A91F
11 changed files with 101 additions and 152 deletions

1
.env.example Normal file
View File

@ -0,0 +1 @@
#GITHUB_TOKEN=

View File

@ -35,7 +35,12 @@ async function getGithubRepos(data) {
const repoName = item.split('/')[1] const repoName = item.split('/')[1]
const repo = await axios.get( const repo = await axios.get(
`https://api.github.com/repos/${user}/${repoName}`, `https://api.github.com/repos/${user}/${repoName}`,
{ headers: { 'User-Agent': 'kremalicious/portfolio' } } {
headers: {
'User-Agent': 'kremalicious/portfolio',
Authorization: `token ${process.env.GITHUB_TOKEN}`
}
}
) )
holder.name = repo.data.name holder.name = repo.data.name

View File

@ -25,7 +25,6 @@
}, },
"dependencies": { "dependencies": {
"axios": "^0.19.0", "axios": "^0.19.0",
"classnames": "^2.2.6",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"gatsby": "^2.17.10", "gatsby": "^2.17.10",
"gatsby-image": "^2.2.30", "gatsby-image": "^2.2.30",

View File

@ -1,8 +1,7 @@
import React, { PureComponent } from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { Link, StaticQuery, graphql } from 'gatsby' import { Link, graphql, useStaticQuery } from 'gatsby'
import posed from 'react-pose' import posed from 'react-pose'
import classNames from 'classnames'
import { moveInBottom } from '../atoms/Transitions' import { moveInBottom } from '../atoms/Transitions'
import { ReactComponent as Logo } from '../../images/logo.svg' import { ReactComponent as Logo } from '../../images/logo.svg'
import styles from './LogoUnit.module.scss' import styles from './LogoUnit.module.scss'
@ -16,40 +15,24 @@ const query = graphql`
} }
` `
export default class LogoUnit extends PureComponent { LogoUnit.propTypes = {
static propTypes = {
minimal: PropTypes.bool minimal: PropTypes.bool
} }
Animation = posed.div(moveInBottom) export default function LogoUnit({ minimal }) {
const data = useStaticQuery(query)
nameClasses = classNames('p-name', [styles.title]) const Animation = posed.div(moveInBottom)
descriptionClasses = classNames('p-job-title', [styles.description])
render() {
const wrapClasses = classNames([styles.logounit], {
[styles.minimal]: this.props.minimal
})
return (
<StaticQuery
query={query}
render={data => {
const { title, tagline } = data.metaYaml const { title, tagline } = data.metaYaml
return ( return (
<this.Animation> <Animation>
<Link className={wrapClasses} to={'/'}> <Link className={minimal ? styles.minimal : styles.logounit} to={'/'}>
<Logo className={styles.logo} /> <Logo className={styles.logo} />
<h1 className={this.nameClasses}>{title.toLowerCase()}</h1> <h1 className={`p-name ${styles.title}`}>{title.toLowerCase()}</h1>
<p className={this.descriptionClasses}> <p className={`p-job-title ${styles.description}`}>
{tagline.toLowerCase()} {tagline.toLowerCase()}
</p> </p>
</Link> </Link>
</this.Animation> </Animation>
) )
}}
/>
)
}
} }

View File

@ -48,8 +48,8 @@
} }
.minimal { .minimal {
composes: logounit;
pointer-events: all; pointer-events: all;
width: auto;
&, &,
&:hover, &:hover,

View File

@ -1,32 +1,23 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import posed from 'react-pose' import posed from 'react-pose'
import classNames from 'classnames'
import { moveInTop } from '../atoms/Transitions' import { moveInTop } from '../atoms/Transitions'
import LinkIcon from '../atoms/LinkIcon' import LinkIcon from '../atoms/LinkIcon'
import { useMeta } from '../../hooks/use-meta' import { useMeta } from '../../hooks/use-meta'
import icons from '../atoms/Icons.module.scss' import icons from '../atoms/Icons.module.scss'
import styles from './Networks.module.scss' import styles from './Networks.module.scss'
const Animation = posed.aside(moveInTop) export default function Networks({ small, hide }) {
const linkClasses = key =>
classNames({
'u-url': key !== 'Email',
'u-email': key === 'Email',
[styles.link]: true
})
const Networks = ({ small, hide }) => {
const { social } = useMeta() const { social } = useMeta()
if (hide) return null
const wrapClasses = classNames([styles.networks], { const Animation = posed.aside(moveInTop)
[styles.small]: small
}) const linkClasses = key =>
key === 'Email' ? `u-email ${styles.link}` : `u-url ${styles.link}`
return ( return (
!hide && ( <Animation className={small ? styles.small : styles.networks}>
<Animation className={wrapClasses}>
{Object.keys(social).map((key, i) => ( {Object.keys(social).map((key, i) => (
<a <a
className={linkClasses(key)} className={linkClasses(key)}
@ -40,12 +31,9 @@ const Networks = ({ small, hide }) => {
))} ))}
</Animation> </Animation>
) )
)
} }
Networks.propTypes = { Networks.propTypes = {
small: PropTypes.bool, small: PropTypes.bool,
hide: PropTypes.bool hide: PropTypes.bool
} }
export default Networks

View File

@ -52,6 +52,8 @@
} }
.small { .small {
composes: networks;
.link { .link {
padding: $spacer / 4; padding: $spacer / 4;
margin-left: $spacer / 4; margin-left: $spacer / 4;

View File

@ -1,7 +1,6 @@
import React, { PureComponent } from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { StaticQuery, graphql } from 'gatsby' import { graphql, useStaticQuery } from 'gatsby'
import classNames from 'classnames'
import Vcard from '../atoms/Vcard' import Vcard from '../atoms/Vcard'
import LogoUnit from '../molecules/LogoUnit' import LogoUnit from '../molecules/LogoUnit'
import Networks from '../molecules/Networks' import Networks from '../molecules/Networks'
@ -22,13 +21,9 @@ const query = graphql`
} }
` `
const FooterMarkup = ({ pkg, meta, year }) => { const FooterMarkup = ({ pkg, meta, year }) => (
const classes = classNames('h-card', [styles.footer]) <footer className={`h-card ${styles.footer}`}>
return (
<footer className={classes}>
<LogoUnit minimal /> <LogoUnit minimal />
<Networks minimal /> <Networks minimal />
<p className={styles.actions}> <p className={styles.actions}>
@ -48,8 +43,7 @@ const FooterMarkup = ({ pkg, meta, year }) => {
</small> </small>
</p> </p>
</footer> </footer>
) )
}
FooterMarkup.propTypes = { FooterMarkup.propTypes = {
pkg: PropTypes.object.isRequired, pkg: PropTypes.object.isRequired,
@ -57,20 +51,11 @@ FooterMarkup.propTypes = {
year: PropTypes.number.isRequired year: PropTypes.number.isRequired
} }
export default class Footer extends PureComponent { export default function Footer() {
state = { year: new Date().getFullYear() } const data = useStaticQuery(query)
render() {
return (
<StaticQuery
query={query}
render={data => {
const pkg = data.portfolioJson const pkg = data.portfolioJson
const meta = data.metaYaml const meta = data.metaYaml
const year = new Date().getFullYear()
return <FooterMarkup year={this.state.year} pkg={pkg} meta={meta} /> return <FooterMarkup year={year} pkg={pkg} meta={meta} />
}}
/>
)
}
} }

View File

@ -1,7 +1,6 @@
import React, { PureComponent } from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { StaticQuery, graphql } from 'gatsby' import { graphql, useStaticQuery } from 'gatsby'
import classNames from 'classnames'
import Networks from '../molecules/Networks' import Networks from '../molecules/Networks'
import Availability from '../molecules/Availability' import Availability from '../molecules/Availability'
import ThemeSwitch from '../molecules/ThemeSwitch' import ThemeSwitch from '../molecules/ThemeSwitch'
@ -18,33 +17,19 @@ const query = graphql`
} }
` `
export default class Header extends PureComponent { Header.propTypes = {
static propTypes = {
minimal: PropTypes.bool minimal: PropTypes.bool
} }
render() { export default function Header({ minimal }) {
const { minimal } = this.props const { metaYaml } = useStaticQuery(query)
return ( return (
<StaticQuery <header className={minimal ? styles.minimal : styles.header}>
query={query}
render={data => {
const meta = data.metaYaml
const headerClasses = classNames([styles.header], {
[styles.minimal]: minimal
})
return (
<header className={headerClasses}>
<ThemeSwitch /> <ThemeSwitch />
<LogoUnit minimal={minimal} /> <LogoUnit minimal={minimal} />
<Networks hide={minimal} /> <Networks hide={minimal} />
<Availability hide={minimal && !meta.availability.status} /> <Availability hide={minimal && !metaYaml.availability.status} />
</header> </header>
) )
}}
/>
)
}
} }

View File

@ -13,6 +13,7 @@
} }
.minimal { .minimal {
composes: header;
min-height: 0; min-height: 0;
padding-top: $spacer * 2; padding-top: $spacer * 2;
padding-bottom: 0; padding-bottom: 0;

View File

@ -13,7 +13,7 @@ describe('Header', () => {
it('renders correctly', () => { it('renders correctly', () => {
const { container } = render( const { container } = render(
<Context.Provider value={{ dark: false, toggleDark: () => null }}> <Context.Provider value={{ darkMode: false, toggleDark: () => null }}>
<Header /> <Header />
</Context.Provider> </Context.Provider>
) )
@ -22,7 +22,7 @@ describe('Header', () => {
it('Availability can be hidden', () => { it('Availability can be hidden', () => {
const { container } = render( const { container } = render(
<Context.Provider value={{ dark: false, toggleDark: () => null }}> <Context.Provider value={{ darkMode: false, toggleDark: () => null }}>
<Header minimal={true} /> <Header minimal={true} />
</Context.Provider> </Context.Provider>
) )