Next.js-ify, step 1

This commit is contained in:
Aarni Koskela
2019-09-23 15:39:18 +03:00
parent 24f6d4e7fb
commit 37e162732c
55 changed files with 302 additions and 432 deletions

View File

@@ -1,3 +0,0 @@
{
"presets": ["es2015", "react"]
}

6
.gitignore vendored
View File

@@ -1,5 +1,5 @@
npm-debug.log
*.log
.DS_Store
.next
node_modules
public
.DS_Store

44
components/Footer.jsx Normal file
View File

@@ -0,0 +1,44 @@
export function Footer() {
return (
<footer>
<div className="sponsors">
<div className="sponsors__label">Yhteistyössä</div>
<a href="http://futurice.com/" target="_blank">
<img src="/static/images/futurice.svg" className="sponsor sponsor__futurice" />
</a>
<a href="http://www.metosin.fi/" target="_blank">
<img src="/static/images/metosin.svg" className="sponsor sponsor__metosin" />
</a>
<a href="https://www.solita.fi/" target="_blank">
<img src="/static/images/solita.svg" className="sponsor" />
</a>
<a href="http://wakeone.co/" target="_blank">
<img src="/static/images/wakeone.svg" className="sponsor sponsor__wakeone" />
</a>
<a href="https://www.nordea.com/" target="_blank">
<img src="/static/images/nordea.png" className="sponsor sponsor__nordea" />
</a>
</div>
<div className="contacts">
<div>
<a href="https://koodiklinikka.slack.com">
<i className="fa fa-slack" />
</a>
<a href="https://github.com/koodiklinikka/koodiklinikka.fi">
<i className="fa fa-github" />
</a>
<a href="https://twitter.com/koodiklinikka">
<i className="fa fa-twitter" />
</a>
<a href="https://www.linkedin.com/groups/12025476">
<i className="fa fa-linkedin" />
</a>
<a href="https://www.facebook.com/koodiklinikka">
<i className="fa fa-facebook" />
</a>
<div id="email" className="email" />
</div>
</div>
</footer>
);
}

View File

@@ -1,193 +0,0 @@
import browserify from 'browserify';
import browserSync from 'browser-sync';
import duration from 'gulp-duration';
import es from 'event-stream';
import exorcist from 'exorcist';
import gulp from 'gulp';
import gutil from 'gulp-util';
import inject from 'gulp-inject';
import jade from 'gulp-jade';
import less from 'gulp-less';
import notifier from 'node-notifier';
import path from 'path';
import prefix from 'gulp-autoprefixer';
import rev from 'gulp-rev';
import source from 'vinyl-source-stream';
import sourcemaps from 'gulp-sourcemaps';
import streamify from 'gulp-streamify';
import stylus from 'gulp-stylus';
import transform from 'vinyl-transform';
import uglify from 'gulp-uglify';
import watch from 'gulp-watch';
import watchify from 'watchify';
/*eslint "no-process-env":0 */
const production = process.env.NODE_ENV === 'production';
const config = {
source: './src',
destination: './public',
scripts: {
source: './src/js/main.js',
destination: './public/js/',
extensions: ['.jsx'],
filename: 'bundle.js'
},
templates: {
source: './src/*.jade',
watch: './src/*.jade',
destination: './public/',
revision: './public/**/*.html'
},
styles: {
source: './src/styles/style.styl',
watch: './src/styles/**/*.styl',
icons: './src/styles/icons.less',
destination: './public/css/'
},
assets: {
source: ['./src/assets/**/*.*', './node_modules/font-awesome/fonts*/*.*'],
watch: './src/assets/**/*.*',
destination: './public/'
},
inject: {
resources: ['./public/**/*.css', './public/**/*.js']
}
};
const browserifyConfig = {
entries: [config.scripts.source],
extensions: config.scripts.extensions,
debug: !production,
cache: {},
packageCache: {}
};
function handleError(err) {
gutil.log(err.message);
gutil.beep();
notifier.notify({
title: 'Compile Error',
message: err.message
});
return this.emit('end');
}
gulp.task('scripts', () => {
let pipeline = browserify(browserifyConfig)
.bundle()
.on('error', handleError)
.pipe(source(config.scripts.filename));
if(production) {
pipeline = pipeline
.pipe(streamify(uglify()))
.pipe(streamify(rev()));
} else {
pipeline = pipeline.pipe(transform(() => {
return exorcist(path.join(config.scripts.destination, config.scripts.filename) + '.map');
}));
}
return pipeline.pipe(gulp.dest(config.scripts.destination));
});
gulp.task('templates', ['styles', 'scripts'], () => {
const resources = gulp.src(config.inject.resources, {read: false});
const pipeline = gulp.src(config.templates.source)
.pipe(jade({
pretty: !production
}))
.on('error', handleError)
.pipe(inject(resources, {ignorePath: 'public', removeTags: true}))
.pipe(gulp.dest(config.templates.destination));
if(production) {
return pipeline;
}
return pipeline.pipe(browserSync.reload({
stream: true
}));
});
gulp.task('styles', () => {
let pipeline = gulp.src(config.styles.source);
if(!production) {
pipeline = pipeline.pipe(sourcemaps.init());
}
const icons = gulp.src(config.styles.icons)
.pipe(less());
pipeline = es.merge(icons, pipeline.pipe(stylus({
'include css': true,
paths: ['node_modules', path.join(__dirname, config.source)],
compress: production
})))
.on('error', handleError)
.pipe(prefix('last 2 versions', 'Chrome 34', 'Firefox 28', 'iOS 7'));
if(production) {
pipeline = pipeline.pipe(rev());
} else {
pipeline = pipeline.pipe(sourcemaps.write('.'));
}
pipeline = pipeline.pipe(gulp.dest(config.styles.destination));
if(production) {
return pipeline;
}
return pipeline.pipe(browserSync.stream({
match: '**/*.css'
}));
});
gulp.task('assets', () => {
return gulp.src(config.assets.source)
.pipe(gulp.dest(config.assets.destination));
});
gulp.task('server', () => {
return browserSync({
open: false,
port: 9001,
notify: false,
ghostMode: false,
server: {
baseDir: config.destination
}
});
});
gulp.task('watch', () => {
['templates', 'styles', 'assets'].forEach((watched) => {
watch(config[watched].watch, () => {
gulp.start(watched);
});
});
const bundle = watchify(browserify(browserifyConfig));
bundle.on('update', () => {
const build = bundle.bundle()
.on('error', handleError)
.pipe(source(config.scripts.filename));
build
.pipe(transform(() => {
return exorcist(config.scripts.destination + config.scripts.filename + '.map');
}))
.pipe(gulp.dest(config.scripts.destination))
.pipe(duration('Rebundling browserify bundle'))
.pipe(browserSync.reload({stream: true}));
}).emit('update');
});
gulp.task('build', ['styles', 'assets', 'scripts', 'templates']);
gulp.task('default', ['styles', 'assets', 'templates', 'watch', 'server']);

2
next.config.js Normal file
View File

@@ -0,0 +1,2 @@
const withStylus = require('@zeit/next-stylus');
module.exports = withStylus({});

View File

@@ -10,70 +10,26 @@
"build": "rm -rf public && gulp build",
"dev": "SERVER=http://localhost:9000/ ENV=development npm start",
"prod": "ENV=production npm start",
"lint": "eslint src",
"test": "mocha src/**/__tests__/*.js --compilers js:babel-core/register --require test/test-helper"
"lint": "eslint src"
},
"keywords": [
"gulp",
"template"
],
"dependencies": {
"@zeit/next-css": "^1.0.1",
"@zeit/next-stylus": "^1.0.1",
"axios": "^0.4.2",
"classnames": "^2.2.1",
"font-awesome": "^4.4.0",
"http-server": "^0.11.1",
"lodash": "^3.9.1",
"next": "^9.0.6",
"parse-github-event": "^0.2.0",
"prop-types": "^15.5.10",
"react": "^0.14.3",
"react-dom": "^0.14.3",
"react": "^16.9.0",
"react-dom": "^16.9.0",
"react-stripe-checkout": "^2.4.0",
"stylus": "^0.54.7",
"timeago": "^0.2.0",
"twitter-text": "^1.11.0"
},
"devDependencies": {
"babel": "^6.1.18",
"babel-core": "^6.2.1",
"babel-eslint": "^4.1.3",
"babel-preset-es2015": "^6.1.18",
"babel-preset-react": "^6.1.18",
"babelify": "^7.2.0",
"browser-sync": "^2.9.4",
"browserify": "^10.2.1",
"chai": "^3.0.0",
"envify": "^3.4.0",
"eslint": "^1.5.1",
"eslint-config-airbnb": "0.0.9",
"eslint-plugin-react": "^3.4.2",
"event-stream": "4.0.1",
"exorcist": "^0.4.0",
"gulp": "3.9.0",
"gulp-autoprefixer": "1.0.1",
"gulp-duration": "0.0.0",
"gulp-inject": "^3.0.0",
"gulp-jade": "^1.1.0",
"gulp-less": "^3.0.5",
"gulp-replace": "^0.5.3",
"gulp-rev": "^4.0.0",
"gulp-sourcemaps": "^1.3.0",
"gulp-streamify": "0.0.5",
"gulp-stylus": "^2.6.0",
"gulp-uglify": "~1.0.1",
"gulp-util": "~3.0.1",
"gulp-watch": "^4.3.4",
"jsdom": "^5.6.0",
"mocha": "^2.2.5",
"node-notifier": "^4.2.1",
"rimraf": "^2.3.4",
"surge": "^0.20.1",
"vinyl-source-stream": "~1.0.0",
"vinyl-transform": "^1.0.0",
"watchify": "^3.2.1"
},
"browserify": {
"transform": [
"babelify",
"envify"
]
"prettier": "^1.18.2"
}
}

63
pages/_document.jsx Normal file
View File

@@ -0,0 +1,63 @@
import Document, { Html, Head, Main, NextScript } from "next/document";
import { Footer } from "../components/Footer";
class MyDocument extends Document {
static async getInitialProps(ctx) {
const initialProps = await Document.getInitialProps(ctx);
return { ...initialProps };
}
render() {
return (
<Html>
<Head>
<meta
name="description"
content="Koodiklinikka on suomalainen yhteisö ohjelmistoalan harrastajille ja ammattilaisille."
/>
<meta
name="keywords"
content="ohjelmointi,frontend,open source,devaus,suomi,javascript,clojure,go,java,node.js,io.js,angular.js,web"
/>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<link
rel="apple-touch-icon"
sizes="180x180"
href="/static/icons/apple-touch-icon.png"
/>
<link
rel="icon"
type="image/png"
sizes="32x32"
href="/static/icons/favicon-32x32.png"
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href="/static/icons/favicon-16x16.png"
/>
<link rel="manifest" href="/static/cons/site.webmanifest" />
<meta property="og:image" content="images/logo.png" />
<script src="https://js.stripe.com/v3/" />
<script src="//use.typekit.net/scb5xny.js" />
<script>{'try{Typekit.load();}catch(e){};'}</script>
</Head>
<body>
<div className="site">
<div className="container">
<Main />
<NextScript />
</div>
<Footer />
</div>
<div id="fader" />
</body>
</Html>
);
}
}
export default MyDocument;

176
pages/index.jsx Normal file
View File

@@ -0,0 +1,176 @@
import "../styles/style.styl";
import Head from "next/head";
const Hero = () => (
<div className="header">
<video
autoPlay
loop
poster="/static/images/poster.jpg"
className="header__video-bg"
>
<source src="/static/videos/jumbo.mp4" type="video/mp4" />
</video>
<div className="header__container">
<div className="header__nav">
<a href="/">
<img src="/static/images/logo-new.svg" alt="Etusivu" />
</a>
</div>
<div className="header__headline">
<h1 className="header__title">
Yhteisö kaikille ohjelmoinnista ja ohjelmistoalasta kiinnostuneille
harrastajille ja ammattilaisille.
</h1>
</div>
</div>
</div>
);
const IndexContent = () => (
<>
<div className="content with-feed">
<section>
<div className="row">
<h3>
Tule mukaan{" "}
<a target="_blank" href="https://slack.com/">
Slack
</a>
-yhteisöömme
</h3>
<div id="invite-form" className="form" />
<p className="code-of-conduct">
Ennen liittymistä yhteisöömme varmista, että olet lukenut yhteisön{" "}
<a
target="_blank"
href="https://github.com/koodiklinikka/code-of-conduct/blob/master/README.md"
>
käyttäytymissäännöt
</a>
.
</p>
</div>
</section>
<section>
<div className="row">
<div className="bread">
<div className="column column1-2">
<h3>Yhteisö ohjelmoinnista kiinnostuneille</h3>
<p>
Koodiklinikka on Suomen suurin ohjelmistoalan yhteisö, joka
kokoaa työntekijät, harrastajat ja vasta-alkajat yhteen.{"\n"}
Tarkoituksenamme on yhdistää ja kasvattaa suomalaista
ohjelmointiyhteisöä, sekä tarjota apua ja uusia kontakteja
ohjelmoinnista innostuneille nuorille.
</p>
<p>
Mukaan liittyminen on ilmaista ja helppoa. Jätä
sähköpostiosoitteesi ylläolevaan kenttään ja lähetämme sinulle
kutsun Slack-yhteisöömme.
</p>
</div>
<div className="column column1-2">
<a href="/static/images/slack.png" target="_blank">
<img src="/static/images/slack.png" />
</a>
</div>
</div>
</div>
<div className="row">
<div className="bread">
<div className="column column2-5">
<img src="/static/images/octocat.png" />
</div>
<div className="column column3-5">
<h3>Avoin lähdekoodi</h3>
<p>
Suosimme avointa lähdekoodia ja kaikki käyttämämme koodi on
vapaasti saatavilla ja hyödynnettävissä{" "}
<a href="https://github.com/koodiklinikka">
Github-organisaatiomme sivulta
</a>
. Organisaation jäseneksi otamme kaikki Slack-yhteisömme
jäsenet. Koodiklinikan projekteihin voi osallistua kuka tahansa
ja muutosideat ovat aina lämpimästi tervetulleita.
</p>
<div id="members" />
</div>
</div>
</div>
<div className="row">
<h2>Potilaiden projekteja</h2>
<div className="bread">
<div className="column column2-5">
<a href="https://redom.js.org" target="_blank">
<img src="/static/images/redom.svg" />
</a>
</div>
<div className="column column3-5">
<h4>RE:DOM</h4>
<p>
Tiny (2 KB) turboboosted JavaScript library for creating user
interfaces. Develop web apps with 100 % JavaScript and web
standards.
</p>
</div>
</div>
<div className="bread">
<div className="column column2-5">
<a href="https://codestats.net/" target="_blank">
<img
src="/static/images/codestats.png"
className="project-image__codestats"
/>
</a>
</div>
<div className="column column3-5">
<h4>Code::Stats</h4>
<p>
Code::Stats is a free stats tracking service for programmers
</p>
</div>
</div>
<div className="bread">
<div className="column column2-5">
<a href="https://reactabular.js.org/" target="_blank">
<img
src="/static/images/reactabular.png"
className="project-image__codestats"
/>
</a>
</div>
<div className="column column3-5">
<h4>Reactabular</h4>
<p>A framework for building the React table you need</p>
</div>
</div>
<div className="bread">
<div className="column column2-5">
<a href="https://avain.app" target="_blank">
<img src="/static/images/avain.svg" style={{ width: "7rem" }} />
</a>
</div>
<div className="column column3-5">
<h4>Avain.app</h4>
<p>Secure one-time password manager (PWA + Web Crypto)</p>
</div>
</div>
</div>
</section>
<div id="feed" />
</div>
</>
);
const Index = () => (
<React.Fragment>
<Head>
<title>Koodiklinikka</title>
</Head>
<Hero />
<IndexContent />
</React.Fragment>
);
export default Index;

View File

@@ -1,98 +0,0 @@
extends templates/head
block title
| Koodiklinikka
block header_content
video(autoplay, loop, poster='images/poster.jpg', class='header__video-bg')
source(src='videos/jumbo.mp4', type='video/mp4')
.header__container
.header__nav
a(href='/')
img(src="images/logo-new.svg", alt="Etusivu")
.header__headline
h1.header__title Yhteisö kaikille ohjelmoinnista ja ohjelmistoalasta kiinnostuneille harrastajille ja&nbsp;ammattilaisille.
block content
.content.with-feed
section
.row
h3 Tule mukaan <a target="_blank" href="https://slack.com/">Slack</a>-yhteisöömme
#invite-form.form
p.code-of-conduct Ennen liittymistä yhteisöömme varmista, että olet lukenut yhteisön <a target="_blank" href="https://github.com/koodiklinikka/code-of-conduct/blob/master/README.md">käyttäytymissäännöt</a>.
section
.row
.bread
.column.column1-2
h3 Yhteisö ohjelmoinnista kiinnostuneille
p.
Koodiklinikka on Suomen suurin ohjelmistoalan yhteisö, joka kokoaa työntekijät, harrastajat ja vasta-alkajat yhteen.
Tarkoituksenamme on yhdistää ja kasvattaa suomalaista ohjelmointiyhteisöä, sekä tarjota apua ja uusia kontakteja ohjelmoinnista innostuneille nuorille.
p.
Mukaan liittyminen on ilmaista ja helppoa. Jätä sähköpostiosoitteesi ylläolevaan kenttään ja lähetämme sinulle kutsun Slack-yhteisöömme.
.column.column1-2
a(href='images/slack.png', target='_blank')
img(src='images/slack.png')
.row
.bread
.column.column2-5
img(src='images/octocat.png')
.column.column3-5
h3 Avoin lähdekoodi
p
|Suosimme avointa lähdekoodia ja kaikki käyttämämme koodi on vapaasti saatavilla ja hyödynnettävissä <a href="https://github.com/koodiklinikka">Github-organisaatiomme sivulta</a>.
|Organisaation jäseneksi otamme kaikki Slack-yhteisömme jäsenet. Koodiklinikan projekteihin voi osallistua kuka tahansa ja muutosideat ovat aina lämpimästi tervetulleita.
#members
.row
h2 Potilaiden projekteja
.bread
.column.column2-5
a(href='https://redom.js.org', target='_blank')
img(src='images/redom.svg')
.column.column3-5
h4 RE:DOM
p.
Tiny (2 KB) turboboosted JavaScript library for creating user interfaces.
Develop web apps with 100 % JavaScript and web standards.
.bread
.column.column2-5
a(href='https://codestats.net/', target='_blank')
img.project-image__codestats(src='images/codestats.png')
.column.column3-5
h4 Code::Stats
p.
Code::Stats is a free stats tracking service for programmers
.bread
.column.column2-5
a(href='https://reactabular.js.org/', target='_blank')
img.project-image__codestats(src='images/reactabular.png')
.column.column3-5
h4 Reactabular
p.
A framework for building the React table you need
.bread
.column.column2-5
a(href='https://avain.app', target='_blank')
img(src='images/avain.svg' style='width: 7rem')
.column.column3-5
h4 Avain.app
p.
Secure one-time password manager (PWA + Web Crypto)
#feed

View File

@@ -1,70 +0,0 @@
doctype html
html
head
title
block title
// inject:css
// endinject
meta(name='description', content='Koodiklinikka on suomalainen yhteisö ohjelmistoalan harrastajille ja ammattilaisille.')
meta(name='keywords', content='ohjelmointi,frontend,open source,devaus,suomi,javascript,clojure,go,java,node.js,io.js,angular.js,web')
meta(charset='utf-8')
meta(name='viewport', content='width=device-width, initial-scale=1')
meta(name='apple-mobile-web-app-capable', content='yes')
script.
if(location.hostname === 'koodiklinikka.fi' && location.protocol !== 'https:') {
location.protocol = 'https';
}
link(rel='apple-touch-icon', sizes='180x180', href='icons/apple-touch-icon.png')
link(rel='icon', type='image/png', sizes='32x32', href='icons/favicon-32x32.png')
link(rel='icon', type='image/png', sizes='16x16', href='icons/favicon-16x16.png')
link(rel='manifest', href='icons/site.webmanifest')
meta(property='og:image', content='images/logo.png')
script(src='https://js.stripe.com/v3/')
script(src='//use.typekit.net/scb5xny.js')
script.
try{Typekit.load();}catch(e){};
body
.site
.container
.header
block header_content
block content
footer
.sponsors
.sponsors__label Yhteistyössä
a(href='http://futurice.com/', target='_blank')
img.sponsor.sponsor__futurice(src='images/futurice.svg')
a(href='http://www.metosin.fi/', target='_blank')
img.sponsor.sponsor__metosin(src='images/metosin.svg')
a(href='https://www.solita.fi/', target='_blank')
img.sponsor(src='images/solita.svg')
a(href='http://wakeone.co/', target='_blank')
img.sponsor.sponsor__wakeone(src='images/wakeone.svg')
a(href='https://www.nordea.com/', target='_blank')
img.sponsor.sponsor__nordea(src='images/nordea.png')
.contacts
div
a(href='https://koodiklinikka.slack.com')
i.fa.fa-slack
a(href='https://github.com/koodiklinikka/koodiklinikka.fi')
i.fa.fa-github
a(href='https://twitter.com/koodiklinikka')
i.fa.fa-twitter
a(href='https://www.linkedin.com/groups/12025476')
i.fa.fa-linkedin
a(href='https://www.facebook.com/koodiklinikka')
i.fa.fa-facebook
div#email.email
#fader
// inject:js
// endinject

View File

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

Before

Width:  |  Height:  |  Size: 263 B

After

Width:  |  Height:  |  Size: 263 B

View File

Before

Width:  |  Height:  |  Size: 550 B

After

Width:  |  Height:  |  Size: 550 B

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 286 KiB

After

Width:  |  Height:  |  Size: 286 KiB

View File

Before

Width:  |  Height:  |  Size: 293 KiB

After

Width:  |  Height:  |  Size: 293 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

Before

Width:  |  Height:  |  Size: 180 KiB

After

Width:  |  Height:  |  Size: 180 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

Before

Width:  |  Height:  |  Size: 142 KiB

After

Width:  |  Height:  |  Size: 142 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -1,7 +1,7 @@
headerHeight = 400px
.header
background url('../images/jumbo.jpg')
background url('/static/images/jumbo.jpg')
background-position bottom center
background-size cover
height headerHeight
@@ -42,7 +42,7 @@ headerHeight = 400px
@media screen and (max-width: 810px)
margin-left auto
margin-right auto
img
width: 100%;

View File

@@ -1,6 +1,6 @@
@import '../../node_modules/font-awesome/less/variables.less';
@import '../../node_modules/font-awesome/less/path.less';
@import '../../node_modules/font-awesome/less/core.less';
@import '../node_modules/font-awesome/less/variables.less';
@import '../node_modules/font-awesome/less/path.less';
@import '../node_modules/font-awesome/less/core.less';
.@{fa-css-prefix}-github:before { content: @fa-var-github; }
.@{fa-css-prefix}-slack:before { content: @fa-var-slack; }

View File

@@ -351,7 +351,7 @@ footer
display block
.bread-img
background url('../images/hp3_bw.jpg')
background url('/static/images/hp3_bw.jpg')
background-size cover
border-radius 160px
opacity 0.85

View File

@@ -1,7 +0,0 @@
'use strict';
import {jsdom} from 'jsdom';
const document = global.document = jsdom('<html><head></head><body></body></html>');
const window = global.window = document.defaultView;
global.navigator = window.navigator = {};