1
0
mirror of https://github.com/kremalicious/portfolio.git synced 2024-12-22 09:13:19 +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 repo = await axios.get(
`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

View File

@ -25,7 +25,6 @@
},
"dependencies": {
"axios": "^0.19.0",
"classnames": "^2.2.6",
"file-saver": "^2.0.2",
"gatsby": "^2.17.10",
"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 { Link, StaticQuery, graphql } from 'gatsby'
import { Link, graphql, useStaticQuery } from 'gatsby'
import posed from 'react-pose'
import classNames from 'classnames'
import { moveInBottom } from '../atoms/Transitions'
import { ReactComponent as Logo } from '../../images/logo.svg'
import styles from './LogoUnit.module.scss'
@ -16,40 +15,24 @@ const query = graphql`
}
`
export default class LogoUnit extends PureComponent {
static propTypes = {
minimal: PropTypes.bool
}
Animation = posed.div(moveInBottom)
nameClasses = classNames('p-name', [styles.title])
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
return (
<this.Animation>
<Link className={wrapClasses} to={'/'}>
<Logo className={styles.logo} />
<h1 className={this.nameClasses}>{title.toLowerCase()}</h1>
<p className={this.descriptionClasses}>
{tagline.toLowerCase()}
</p>
</Link>
</this.Animation>
)
}}
/>
)
}
LogoUnit.propTypes = {
minimal: PropTypes.bool
}
export default function LogoUnit({ minimal }) {
const data = useStaticQuery(query)
const Animation = posed.div(moveInBottom)
const { title, tagline } = data.metaYaml
return (
<Animation>
<Link className={minimal ? styles.minimal : styles.logounit} to={'/'}>
<Logo className={styles.logo} />
<h1 className={`p-name ${styles.title}`}>{title.toLowerCase()}</h1>
<p className={`p-job-title ${styles.description}`}>
{tagline.toLowerCase()}
</p>
</Link>
</Animation>
)
}

View File

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

View File

@ -1,45 +1,35 @@
import React from 'react'
import PropTypes from 'prop-types'
import posed from 'react-pose'
import classNames from 'classnames'
import { moveInTop } from '../atoms/Transitions'
import LinkIcon from '../atoms/LinkIcon'
import { useMeta } from '../../hooks/use-meta'
import icons from '../atoms/Icons.module.scss'
import styles from './Networks.module.scss'
const Animation = posed.aside(moveInTop)
const linkClasses = key =>
classNames({
'u-url': key !== 'Email',
'u-email': key === 'Email',
[styles.link]: true
})
const Networks = ({ small, hide }) => {
export default function Networks({ small, hide }) {
const { social } = useMeta()
if (hide) return null
const wrapClasses = classNames([styles.networks], {
[styles.small]: small
})
const Animation = posed.aside(moveInTop)
const linkClasses = key =>
key === 'Email' ? `u-email ${styles.link}` : `u-url ${styles.link}`
return (
!hide && (
<Animation className={wrapClasses}>
{Object.keys(social).map((key, i) => (
<a
className={linkClasses(key)}
href={social[key]}
key={i}
data-testid={`network-${key.toLowerCase()}`}
>
<LinkIcon title={key} className={icons.icon} />
<span className={styles.title}>{key}</span>
</a>
))}
</Animation>
)
<Animation className={small ? styles.small : styles.networks}>
{Object.keys(social).map((key, i) => (
<a
className={linkClasses(key)}
href={social[key]}
key={i}
data-testid={`network-${key.toLowerCase()}`}
>
<LinkIcon title={key} className={icons.icon} />
<span className={styles.title}>{key}</span>
</a>
))}
</Animation>
)
}
@ -47,5 +37,3 @@ Networks.propTypes = {
small: PropTypes.bool,
hide: PropTypes.bool
}
export default Networks

View File

@ -52,6 +52,8 @@
}
.small {
composes: networks;
.link {
padding: $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 { StaticQuery, graphql } from 'gatsby'
import classNames from 'classnames'
import { graphql, useStaticQuery } from 'gatsby'
import Vcard from '../atoms/Vcard'
import LogoUnit from '../molecules/LogoUnit'
import Networks from '../molecules/Networks'
@ -22,34 +21,29 @@ const query = graphql`
}
`
const FooterMarkup = ({ pkg, meta, year }) => {
const classes = classNames('h-card', [styles.footer])
const FooterMarkup = ({ pkg, meta, year }) => (
<footer className={`h-card ${styles.footer}`}>
<LogoUnit minimal />
<Networks minimal />
return (
<footer className={classes}>
<LogoUnit minimal />
<Networks minimal />
<p className={styles.actions}>
<Vcard />
<a className="u-key" href={meta.gpg}>
PGP/GPG key
</a>
<a href={pkg.bugs}>Found a bug?</a>
</p>
<p className={styles.copyright}>
<small>
&copy; {year}{' '}
<a className="u-url" href={meta.url}>
{meta.title}
</a>{' '}
&mdash; All Rights Reserved
</small>
</p>
</footer>
)
}
<p className={styles.actions}>
<Vcard />
<a className="u-key" href={meta.gpg}>
PGP/GPG key
</a>
<a href={pkg.bugs}>Found a bug?</a>
</p>
<p className={styles.copyright}>
<small>
&copy; {year}{' '}
<a className="u-url" href={meta.url}>
{meta.title}
</a>{' '}
&mdash; All Rights Reserved
</small>
</p>
</footer>
)
FooterMarkup.propTypes = {
pkg: PropTypes.object.isRequired,
@ -57,20 +51,11 @@ FooterMarkup.propTypes = {
year: PropTypes.number.isRequired
}
export default class Footer extends PureComponent {
state = { year: new Date().getFullYear() }
export default function Footer() {
const data = useStaticQuery(query)
const pkg = data.portfolioJson
const meta = data.metaYaml
const year = new Date().getFullYear()
render() {
return (
<StaticQuery
query={query}
render={data => {
const pkg = data.portfolioJson
const meta = data.metaYaml
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 { StaticQuery, graphql } from 'gatsby'
import classNames from 'classnames'
import { graphql, useStaticQuery } from 'gatsby'
import Networks from '../molecules/Networks'
import Availability from '../molecules/Availability'
import ThemeSwitch from '../molecules/ThemeSwitch'
@ -18,33 +17,19 @@ const query = graphql`
}
`
export default class Header extends PureComponent {
static propTypes = {
minimal: PropTypes.bool
}
render() {
const { minimal } = this.props
return (
<StaticQuery
query={query}
render={data => {
const meta = data.metaYaml
const headerClasses = classNames([styles.header], {
[styles.minimal]: minimal
})
return (
<header className={headerClasses}>
<ThemeSwitch />
<LogoUnit minimal={minimal} />
<Networks hide={minimal} />
<Availability hide={minimal && !meta.availability.status} />
</header>
)
}}
/>
)
}
Header.propTypes = {
minimal: PropTypes.bool
}
export default function Header({ minimal }) {
const { metaYaml } = useStaticQuery(query)
return (
<header className={minimal ? styles.minimal : styles.header}>
<ThemeSwitch />
<LogoUnit minimal={minimal} />
<Networks hide={minimal} />
<Availability hide={minimal && !metaYaml.availability.status} />
</header>
)
}

View File

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

View File

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