mirror of
https://github.com/koodiklinikka/koodiklinikka.fi.git
synced 2026-03-20 02:05:57 +00:00
Merge pull request #23 from Keksike/master
Add Yhdistys-page with membership-form
This commit is contained in:
@@ -8,6 +8,8 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "rm -rf public && gulp",
|
"start": "rm -rf public && gulp",
|
||||||
"build": "rm -rf public && gulp build",
|
"build": "rm -rf public && gulp build",
|
||||||
|
"dev": "SERVER=http://localhost:9000/ ENV=development npm start",
|
||||||
|
"prod": "ENV=production npm start",
|
||||||
"lint": "eslint src",
|
"lint": "eslint src",
|
||||||
"test": "mocha src/**/__tests__/*.js --compilers js:babel-core/register --require test/test-helper"
|
"test": "mocha src/**/__tests__/*.js --compilers js:babel-core/register --require test/test-helper"
|
||||||
},
|
},
|
||||||
@@ -22,8 +24,10 @@
|
|||||||
"http-server": "^0.8.0",
|
"http-server": "^0.8.0",
|
||||||
"lodash": "^3.9.1",
|
"lodash": "^3.9.1",
|
||||||
"parse-github-event": "^0.2.0",
|
"parse-github-event": "^0.2.0",
|
||||||
|
"prop-types": "^15.5.10",
|
||||||
"react": "^0.14.3",
|
"react": "^0.14.3",
|
||||||
"react-dom": "^0.14.3",
|
"react-dom": "^0.14.3",
|
||||||
|
"react-stripe-checkout": "^2.4.0",
|
||||||
"timeago": "^0.2.0",
|
"timeago": "^0.2.0",
|
||||||
"twitter-text": "^1.11.0"
|
"twitter-text": "^1.11.0"
|
||||||
},
|
},
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.5 KiB |
BIN
src/assets/images/hp3_bw.jpg
Normal file
BIN
src/assets/images/hp3_bw.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 286 KiB |
16
src/config.js
Normal file
16
src/config.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
var development = {
|
||||||
|
stripe: {
|
||||||
|
publicKey: "pk_test_OmNve9H1OuORlmD4rblpjgzh"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var production = {
|
||||||
|
stripe: {
|
||||||
|
publicKey: "pk_live_xrnwdLNXbt20LMxpIDffJnnC"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = function () {
|
||||||
|
return process.env.ENV == 'development' ? development : production;
|
||||||
|
}
|
||||||
197
src/index.jade
197
src/index.jade
@@ -1,150 +1,79 @@
|
|||||||
doctype html
|
extends templates/head
|
||||||
html
|
|
||||||
head
|
|
||||||
title Koodiklinikka
|
|
||||||
// inject:css
|
|
||||||
// endinject
|
|
||||||
meta(name='description', content='Koodiklinikka on suomalainen Slack-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.
|
block title
|
||||||
if(location.hostname === 'koodiklinikka.fi' && location.protocol !== 'https:') {
|
| Koodiklinikka
|
||||||
location.protocol = 'https';
|
|
||||||
}
|
|
||||||
link(rel='apple-touch-icon', sizes='57x57', href='icons/apple-touch-icon-57x57.png')
|
|
||||||
link(rel='apple-touch-icon', sizes='114x114', href='icons/apple-touch-icon-114x114.png')
|
|
||||||
link(rel='apple-touch-icon', sizes='72x72', href='icons/apple-touch-icon-72x72.png')
|
|
||||||
link(rel='apple-touch-icon', sizes='144x144', href='icons/apple-touch-icon-144x144.png')
|
|
||||||
link(rel='apple-touch-icon', sizes='60x60', href='icons/apple-touch-icon-60x60.png')
|
|
||||||
link(rel='apple-touch-icon', sizes='120x120', href='icons/apple-touch-icon-120x120.png')
|
|
||||||
link(rel='apple-touch-icon', sizes='76x76', href='icons/apple-touch-icon-76x76.png')
|
|
||||||
link(rel='apple-touch-icon', sizes='152x152', href='icons/apple-touch-icon-152x152.png')
|
|
||||||
link(rel='apple-touch-icon', sizes='180x180', href='icons/apple-touch-icon-180x180.png')
|
|
||||||
link(rel='icon', type='image/png', href='icons/favicon-192x192.png', sizes='192x192')
|
|
||||||
link(rel='icon', type='image/png', href='icons/favicon-160x160.png', sizes='160x160')
|
|
||||||
link(rel='icon', type='image/png', href='icons/favicon-96x96.png', sizes='96x96')
|
|
||||||
link(rel='icon', type='image/png', href='icons/favicon-16x16.png', sizes='16x16')
|
|
||||||
link(rel='icon', type='image/png', href='icons/favicon-32x32.png', sizes='32x32')
|
|
||||||
link(rel='shortcut icon', href='icons/favicon.ico')
|
|
||||||
link(rel='icon', href='icons/favicon.ico')
|
|
||||||
meta(name='msapplication-TileColor', content='#10558c')
|
|
||||||
meta(name='msapplication-TileImage', content='icons/mstile-144x144.png')
|
|
||||||
meta(property='og:image', content='images/logo.png')
|
|
||||||
script(src='//use.typekit.net/scb5xny.js')
|
|
||||||
script.
|
|
||||||
try{Typekit.load();}catch(e){};
|
|
||||||
|
|
||||||
body
|
block header_content
|
||||||
.site
|
video(autoplay, loop, poster='images/poster.jpg', class='header__video-bg')
|
||||||
.container
|
source(src='videos/jumbo.mp4', type='video/mp4')
|
||||||
.header
|
.header__container
|
||||||
video(autoplay, loop, poster='images/poster.jpg', class='header__video-bg')
|
.header__nav
|
||||||
source(src='videos/jumbo.mp4', type='video/mp4')
|
a(href='/') etusivu
|
||||||
.header__container
|
a(href='/yhdistys.html') yhdistys
|
||||||
.header__headline
|
.header__headline
|
||||||
.header__logo
|
.header__logo
|
||||||
h1.header__title <a target="_blank" href="https://slack.com/">Slack</a>-yhteisö kaikille ohjelmoinnista ja ohjelmistoalasta kiinnostuneille harrastajille ja ammattilaisille.
|
h1.header__title <a target="_blank" href="https://slack.com/">Slack</a>-yhteisö kaikille ohjelmoinnista ja ohjelmistoalasta kiinnostuneille harrastajille ja ammattilaisille.
|
||||||
|
|
||||||
.content
|
block content
|
||||||
section
|
.content.with-feed
|
||||||
.row
|
section
|
||||||
h3 Tule mukaan
|
.row
|
||||||
#invite-form
|
h3 Tule mukaan
|
||||||
|
#invite-form.form
|
||||||
|
|
||||||
section
|
section
|
||||||
.row
|
.row
|
||||||
.bread
|
.bread
|
||||||
.column.column1-2
|
.column.column1-2
|
||||||
h3 Yhteisö ohjelmoinnista kiinnostuneille
|
h3 Yhteisö ohjelmoinnista kiinnostuneille
|
||||||
p.
|
p.
|
||||||
Koodiklinikka on Suomen suurin ohjelmistoalan yhteisö, joka kokoaa työntekijät, harrastajat ja vasta-alkajat yhteen.
|
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.
|
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.
|
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
|
.column.column1-2
|
||||||
a(href='images/slack.png', target='_blank')
|
a(href='images/slack.png', target='_blank')
|
||||||
img(src='images/slack.png')
|
img(src='images/slack.png')
|
||||||
|
|
||||||
|
|
||||||
.row
|
.row
|
||||||
.bread
|
.bread
|
||||||
.column.column2-5
|
.column.column2-5
|
||||||
img(src='images/octocat.png')
|
img(src='images/octocat.png')
|
||||||
|
|
||||||
.column.column3-5
|
.column.column3-5
|
||||||
h3 Avoin lähdekoodi
|
h3 Avoin lähdekoodi
|
||||||
p
|
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>.
|
|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 ja kontribuutio projekteihimme otetaan lämpimästi vastaan.
|
|Organisaation jäseneksi otamme kaikki Slack-yhteisömme jäsenet ja kontribuutio projekteihimme otetaan lämpimästi vastaan.
|
||||||
|
|
||||||
#members
|
#members
|
||||||
|
|
||||||
.row
|
.row
|
||||||
h2 Potilaiden projekteja
|
h2 Potilaiden projekteja
|
||||||
.bread
|
.bread
|
||||||
.column.column2-5
|
.column.column2-5
|
||||||
a(href='https://redom.js.org', target='_blank')
|
a(href='https://redom.js.org', target='_blank')
|
||||||
img(src='images/redom.svg')
|
img(src='images/redom.svg')
|
||||||
|
|
||||||
.column.column3-5
|
.column.column3-5
|
||||||
h4 RE:DOM
|
h4 RE:DOM
|
||||||
|
|
||||||
p.
|
p.
|
||||||
Tiny (2 KB) turboboosted JavaScript library for creating user interfaces.
|
Tiny (2 KB) turboboosted JavaScript library for creating user interfaces.
|
||||||
Develop web apps with 100 % JavaScript and web standards.
|
Develop web apps with 100 % JavaScript and web standards.
|
||||||
|
|
||||||
.bread
|
.bread
|
||||||
.column.column2-5
|
.column.column2-5
|
||||||
a(href='https://codestats.net/', target='_blank')
|
a(href='https://codestats.net/', target='_blank')
|
||||||
img.project-image__codestats(src='images/codestats.png')
|
img.project-image__codestats(src='images/codestats.png')
|
||||||
|
|
||||||
.column.column3-5
|
.column.column3-5
|
||||||
h4 Code::Stats
|
h4 Code::Stats
|
||||||
|
|
||||||
p.
|
p.
|
||||||
Code::Stats is a free stats tracking service for programmers
|
Code::Stats is a free stats tracking service for programmers
|
||||||
|
|
||||||
#members
|
#members
|
||||||
|
|
||||||
#feed
|
#feed
|
||||||
|
|
||||||
|
|
||||||
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://leonidasoy.fi/', target='_blank')
|
|
||||||
img.sponsor.sponsor__leonidas(src='images/leonidas.png')
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
#fader
|
|
||||||
// inject:js
|
|
||||||
// endinject
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ var React = require('react');
|
|||||||
var classSet = require('classnames');
|
var classSet = require('classnames');
|
||||||
|
|
||||||
var api = require('../api');
|
var api = require('../api');
|
||||||
|
var Loader = require('./loader');
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
return {
|
return {
|
||||||
@@ -48,6 +48,7 @@ module.exports = React.createClass({
|
|||||||
},
|
},
|
||||||
render() {
|
render() {
|
||||||
var formClasses = classSet({
|
var formClasses = classSet({
|
||||||
|
'form': true,
|
||||||
'invite-form': true,
|
'invite-form': true,
|
||||||
'has-success': this.state.submitted,
|
'has-success': this.state.submitted,
|
||||||
'has-error': this.state.error,
|
'has-error': this.state.error,
|
||||||
@@ -76,7 +77,7 @@ module.exports = React.createClass({
|
|||||||
}
|
}
|
||||||
|
|
||||||
feedbackMessage = (
|
feedbackMessage = (
|
||||||
<div className='invite-form--message'>
|
<div className='form--message'>
|
||||||
{messageText}
|
{messageText}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -98,11 +99,11 @@ module.exports = React.createClass({
|
|||||||
disabled={this.state.error || this.state.submitted}>
|
disabled={this.state.error || this.state.submitted}>
|
||||||
⏎
|
⏎
|
||||||
</button>
|
</button>
|
||||||
<span
|
<div className='invite-form__loader'>
|
||||||
className='loader'>
|
<Loader />
|
||||||
</span>
|
</div>
|
||||||
{feedbackMessage}
|
{feedbackMessage}
|
||||||
</form>
|
</form>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
12
src/js/components/loader.js
Normal file
12
src/js/components/loader.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
const React = require('react');
|
||||||
|
|
||||||
|
module.exports = function Loader() {
|
||||||
|
return (
|
||||||
|
<div className='sk-folding-cube'>
|
||||||
|
<div className='sk-cube1 sk-cube'></div>
|
||||||
|
<div className='sk-cube2 sk-cube'></div>
|
||||||
|
<div className='sk-cube4 sk-cube'></div>
|
||||||
|
<div className='sk-cube3 sk-cube'></div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -7,7 +7,7 @@ var _ = require('lodash');
|
|||||||
var api = require('../api');
|
var api = require('../api');
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
return {
|
return {
|
||||||
members: []
|
members: []
|
||||||
};
|
};
|
||||||
|
|||||||
34
src/js/components/membershipForm.js
Normal file
34
src/js/components/membershipForm.js
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import MembershipInfoForm from './membershipInfoForm';
|
||||||
|
|
||||||
|
module.exports = React.createClass({
|
||||||
|
getInitialState() {
|
||||||
|
return {
|
||||||
|
paymentSuccess: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
handlePaymentSuccess() {
|
||||||
|
this.setState({ paymentSuccess: true });
|
||||||
|
},
|
||||||
|
render() {
|
||||||
|
if(!this.state.paymentSuccess) {
|
||||||
|
return (
|
||||||
|
<MembershipInfoForm onPaymentSuccess={this.handlePaymentSuccess} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<svg height='50' width='50' viewBox='0 0 512 512' xmlns='http://www.w3.org/2000/svg'>
|
||||||
|
<path
|
||||||
|
fill='#349c4a'
|
||||||
|
d='M256 6.998c-137.533 0-249 111.467-249 249 0 137.534 111.467 249 249 249s249-111.467 249-249c0-137.534-111.467-249-249-249zm0 478.08c-126.31 0-229.08-102.77-229.08-229.08 0-126.31 102.77-229.08 229.08-229.08 126.31 0 229.08 102.77 229.08 229.08 0 126.31-102.77 229.08-229.08 229.08z' />
|
||||||
|
<path
|
||||||
|
fill='#349c4a'
|
||||||
|
d='M384.235 158.192L216.92 325.518 127.86 236.48l-14.142 14.144 103.2 103.18 181.36-181.47' />
|
||||||
|
</svg>
|
||||||
|
<p> Maksu ja rekisteröityminen onnistui.</p>
|
||||||
|
<p> Tervetuloa Koodiklinikka ry:n jäseneksi!</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
199
src/js/components/membershipInfoForm.js
Normal file
199
src/js/components/membershipInfoForm.js
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
var _ = require('lodash');
|
||||||
|
var request = require('axios');
|
||||||
|
var React = require('react');
|
||||||
|
var classSet = require('classnames');
|
||||||
|
var StripeCheckout = require('react-stripe-checkout').default;
|
||||||
|
|
||||||
|
var api = require('../api');
|
||||||
|
var Loader = require('./loader');
|
||||||
|
var config = require('../../config.js')();
|
||||||
|
|
||||||
|
var fieldNameTranslations = {
|
||||||
|
address: { fi: 'Osoite' },
|
||||||
|
city: { fi: 'Paikkakunta' },
|
||||||
|
email: { fi: 'Sähköpostiosoite' },
|
||||||
|
handle: { fi: 'Slack-käyttäjätunnus ' },
|
||||||
|
name: { fi: 'Koko nimi ' },
|
||||||
|
postcode: { fi: 'Postinumero' }
|
||||||
|
};
|
||||||
|
|
||||||
|
function validateEmail(email) {
|
||||||
|
var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||||
|
return re.test(email);
|
||||||
|
}
|
||||||
|
|
||||||
|
const fieldNames = ['name', 'email', 'handle', 'address', 'city', 'postcode'];
|
||||||
|
|
||||||
|
function getUserInfo(state) {
|
||||||
|
return _.pick(state, fieldNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = React.createClass({
|
||||||
|
|
||||||
|
getInitialState() {
|
||||||
|
return {
|
||||||
|
address: '',
|
||||||
|
city: '',
|
||||||
|
email: '',
|
||||||
|
handle: '',
|
||||||
|
name: '',
|
||||||
|
postcode: '',
|
||||||
|
sending: false,
|
||||||
|
pristineFields: fieldNames
|
||||||
|
};
|
||||||
|
},
|
||||||
|
onSubmit(token) {
|
||||||
|
this.setState({
|
||||||
|
sending: true,
|
||||||
|
error: null
|
||||||
|
});
|
||||||
|
|
||||||
|
request.post(api('membership'), {
|
||||||
|
userInfo: getUserInfo(this.state),
|
||||||
|
stripeToken: token.id
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
this.setState({ sending: false });
|
||||||
|
this.props.onPaymentSuccess();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
this.setState({ error: err, sending: false });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onChange(e) {
|
||||||
|
var name = e.target.name;
|
||||||
|
if (e.target.value === this.state[name]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
[e.target.name]: e.target.value,
|
||||||
|
pristineFields: this.state.pristineFields.filter((fieldName) => fieldName !== name),
|
||||||
|
errors: []
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
getDataErrors() {
|
||||||
|
var foundErrors = [];
|
||||||
|
|
||||||
|
fieldNames.forEach((fieldName) => {
|
||||||
|
if (!this.state[fieldName]) {
|
||||||
|
foundErrors.push({ field: fieldName, type: 'missing' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (this.state.email && !validateEmail(this.state.email)) {
|
||||||
|
foundErrors.push({ field: 'email', type: 'invalid' });
|
||||||
|
}
|
||||||
|
|
||||||
|
return foundErrors;
|
||||||
|
},
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const inputErrors = this.getDataErrors();
|
||||||
|
|
||||||
|
var formClasses = classSet({
|
||||||
|
'form': true,
|
||||||
|
'membership-form': true,
|
||||||
|
'has-error': inputErrors.length !== 0 || this.state.error,
|
||||||
|
'sending': this.state.sending
|
||||||
|
});
|
||||||
|
|
||||||
|
function getErrorMessage(err) {
|
||||||
|
var feedbackText;
|
||||||
|
|
||||||
|
if (err.type === 'missing') {
|
||||||
|
feedbackText = `${fieldNameTranslations[err.field].fi} on pakollinen.`;
|
||||||
|
} else if (err.type === 'invalid') {
|
||||||
|
feedbackText = `${fieldNameTranslations[err.field].fi} on virheellinen.`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <div key={err.field} className='form--message'>{feedbackText}</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* generate error messages */
|
||||||
|
var visibleErrors = inputErrors
|
||||||
|
.filter((error) => this.state.pristineFields.indexOf(error.field) === -1);
|
||||||
|
|
||||||
|
var fieldsWithErrors = visibleErrors.map(({ field }) => field);
|
||||||
|
|
||||||
|
var inputFields = fieldNames.map((fieldName) => {
|
||||||
|
var inputClasses = classSet({
|
||||||
|
'input': true,
|
||||||
|
'has-error': _.includes(fieldsWithErrors, fieldName),
|
||||||
|
'half': fieldName === 'city' || fieldName === 'postcode',
|
||||||
|
'left': fieldName === 'city'
|
||||||
|
});
|
||||||
|
|
||||||
|
function showsErrorFor(field) {
|
||||||
|
if (fieldName === 'city') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return field === fieldName || fieldName === 'postcode' && field === 'city';
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span key={fieldName}>
|
||||||
|
<input
|
||||||
|
className={inputClasses}
|
||||||
|
type={fieldName === 'email' ? 'email' : 'text'}
|
||||||
|
name={fieldName}
|
||||||
|
placeholder={fieldNameTranslations[fieldName].fi}
|
||||||
|
value={this.state[fieldName]}
|
||||||
|
onChange={this.onChange} />
|
||||||
|
{
|
||||||
|
visibleErrors
|
||||||
|
.filter(({ field }) => showsErrorFor(field))
|
||||||
|
.map(getErrorMessage)
|
||||||
|
|
||||||
|
}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
if (this.state.sending) {
|
||||||
|
return (
|
||||||
|
<div className='membership-form__loader'>
|
||||||
|
<Loader />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h3>Liity jäseneksi</h3>
|
||||||
|
<form className={formClasses}>
|
||||||
|
{inputFields}
|
||||||
|
{this.state.error && (
|
||||||
|
<div className='form--message'>
|
||||||
|
Jotain meni pieleen! Ota yhteyttä info@koodiklinikka.fi
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<br />
|
||||||
|
<StripeCheckout
|
||||||
|
amount={1000}
|
||||||
|
currency='EUR'
|
||||||
|
description='Jäsenmaksu'
|
||||||
|
email={this.state.email}
|
||||||
|
image='https://avatars3.githubusercontent.com/u/10520119?v=3&s=200'
|
||||||
|
locale='fi'
|
||||||
|
name='Koodiklinikka ry'
|
||||||
|
stripeKey={config.stripe.publicKey}
|
||||||
|
token={this.onSubmit}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
type='button'
|
||||||
|
disabled={inputErrors.length !== 0}
|
||||||
|
className='btn btn__submit'>
|
||||||
|
Siirry maksamaan
|
||||||
|
</button>
|
||||||
|
</StripeCheckout>
|
||||||
|
<p>
|
||||||
|
<small>Seuraava vuosimaksu veloitetaan automaattisesti <br />kortiltasi vuoden kuluttua.</small>
|
||||||
|
</p>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -3,31 +3,49 @@ require('./ga');
|
|||||||
let ReactDOM = require('react-dom');
|
let ReactDOM = require('react-dom');
|
||||||
var React = require('react');
|
var React = require('react');
|
||||||
|
|
||||||
|
|
||||||
var inviteForm = React.createFactory(require('./components/inviteForm'));
|
var inviteForm = React.createFactory(require('./components/inviteForm'));
|
||||||
var fader = React.createFactory(require('./components/fader'));
|
var fader = React.createFactory(require('./components/fader'));
|
||||||
var members = React.createFactory(require('./components/members'));
|
var members = React.createFactory(require('./components/members'));
|
||||||
var feed = React.createFactory(require('./components/feed'));
|
var feed = React.createFactory(require('./components/feed'));
|
||||||
var email = React.createFactory(require('./components/email'));
|
var email = React.createFactory(require('./components/email'));
|
||||||
|
var membershipForm = React.createFactory(require('./components/membershipForm'));
|
||||||
|
|
||||||
ReactDOM.render(
|
const pathName = window.location.pathname;
|
||||||
inviteForm(),
|
|
||||||
document.getElementById('invite-form'));
|
|
||||||
|
|
||||||
ReactDOM.render(
|
document.querySelectorAll('.email').forEach((element) =>
|
||||||
fader(),
|
ReactDOM.render(email(), element)
|
||||||
document.getElementById('fader'));
|
);
|
||||||
|
|
||||||
|
if (pathName == '/') {
|
||||||
|
ReactDOM.render(
|
||||||
|
inviteForm(),
|
||||||
|
document.getElementById('invite-form'));
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
members(),
|
fader(),
|
||||||
document.getElementById('members'));
|
document.getElementById('fader'));
|
||||||
|
|
||||||
|
ReactDOM.render(
|
||||||
|
members(),
|
||||||
|
document.getElementById('members'));
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
feed(),
|
feed(),
|
||||||
document.getElementById('feed'));
|
document.getElementById('feed'));
|
||||||
|
|
||||||
ReactDOM.render(
|
} else if (pathName == '/yhdistys.html') {
|
||||||
email(),
|
ReactDOM.render(
|
||||||
document.getElementById('email'));
|
membershipForm(),
|
||||||
|
document.getElementById('membership-form'));
|
||||||
|
|
||||||
|
ReactDOM.render(
|
||||||
|
fader(),
|
||||||
|
document.getElementById('fader'));
|
||||||
|
|
||||||
|
ReactDOM.render(
|
||||||
|
React.createElement('div', {}, [
|
||||||
|
members({ key: 0 }),
|
||||||
|
members({ key: 1 })
|
||||||
|
]),
|
||||||
|
document.getElementById('members'));
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
|
headerHeight = 400px
|
||||||
|
|
||||||
.header
|
.header
|
||||||
background url('../images/jumbo.jpg')
|
background url('../images/jumbo.jpg')
|
||||||
background-position bottom center
|
background-position bottom center
|
||||||
background-size cover
|
background-size cover
|
||||||
height 400px
|
height headerHeight
|
||||||
overflow hidden
|
overflow hidden
|
||||||
position relative
|
position relative
|
||||||
width 100%
|
width 100%
|
||||||
@@ -23,6 +25,43 @@
|
|||||||
vertical-align middle
|
vertical-align middle
|
||||||
width 100%
|
width 100%
|
||||||
|
|
||||||
|
.header__nav
|
||||||
|
position absolute
|
||||||
|
right 60px
|
||||||
|
top 32px
|
||||||
|
|
||||||
|
@media screen and (max-width: 1030px)
|
||||||
|
right 40px
|
||||||
|
top 20px
|
||||||
|
a
|
||||||
|
color white
|
||||||
|
font-size 16px
|
||||||
|
font-weight bold
|
||||||
|
margin-left 16px
|
||||||
|
text-shadow 0 2px 0 rgba(0,0,0,0.1)
|
||||||
|
position relative
|
||||||
|
@media screen and (max-width: 420px)
|
||||||
|
display block
|
||||||
|
margin-top 5px
|
||||||
|
|
||||||
|
&:last-child
|
||||||
|
margin-left 1.5em
|
||||||
|
&:before
|
||||||
|
content '!'
|
||||||
|
font-size 11px
|
||||||
|
line-height 15px
|
||||||
|
width 14px
|
||||||
|
height 14px
|
||||||
|
text-align center
|
||||||
|
background #ec3d3d
|
||||||
|
display inline-block
|
||||||
|
margin-right 5px
|
||||||
|
top -5px
|
||||||
|
right -15px
|
||||||
|
border-radius 100%
|
||||||
|
position absolute
|
||||||
|
text-shadow none
|
||||||
|
|
||||||
.header__headline
|
.header__headline
|
||||||
display table-cell
|
display table-cell
|
||||||
padding 0 1em
|
padding 0 1em
|
||||||
@@ -85,3 +124,59 @@
|
|||||||
@media (min-aspect-ratio: 1/2)
|
@media (min-aspect-ratio: 1/2)
|
||||||
width 100%
|
width 100%
|
||||||
height auto
|
height auto
|
||||||
|
|
||||||
|
@keyframes spin
|
||||||
|
0%
|
||||||
|
top 0
|
||||||
|
50%
|
||||||
|
top -(headerHeight)
|
||||||
|
50.0001%
|
||||||
|
top headerHeight
|
||||||
|
100%
|
||||||
|
top 0
|
||||||
|
|
||||||
|
@keyframes spin2
|
||||||
|
0%
|
||||||
|
top (headerHeight)
|
||||||
|
50%
|
||||||
|
top 0
|
||||||
|
99.99999%
|
||||||
|
top -(headerHeight)
|
||||||
|
100%
|
||||||
|
top (headerHeight)
|
||||||
|
|
||||||
|
.header__members
|
||||||
|
width 100%
|
||||||
|
height 100%
|
||||||
|
z-index -1
|
||||||
|
position absolute
|
||||||
|
top 0
|
||||||
|
left 0
|
||||||
|
|
||||||
|
.member
|
||||||
|
margin 0
|
||||||
|
border-radius 0
|
||||||
|
width (100/18)%
|
||||||
|
|
||||||
|
@media screen and (min-width: 2000px)
|
||||||
|
width 5%
|
||||||
|
@media screen and (max-width: 1200px)
|
||||||
|
width (100/15)%
|
||||||
|
@media screen and (max-width: 810px)
|
||||||
|
width 10%
|
||||||
|
@media screen and (max-width: 450px)
|
||||||
|
width 20%
|
||||||
|
|
||||||
|
.members
|
||||||
|
position absolute
|
||||||
|
overflow hidden
|
||||||
|
top 0
|
||||||
|
left 0
|
||||||
|
right 0
|
||||||
|
height headerHeight
|
||||||
|
animation spin 40s infinite linear
|
||||||
|
&:first-child
|
||||||
|
z-index 1
|
||||||
|
&:last-child
|
||||||
|
animation spin2 40s infinite linear
|
||||||
|
|
||||||
|
|||||||
@@ -30,3 +30,8 @@
|
|||||||
.input.has-error
|
.input.has-error
|
||||||
border-color rgba(226, 33, 112, 0.6)
|
border-color rgba(226, 33, 112, 0.6)
|
||||||
color rgb(226, 33, 112)
|
color rgb(226, 33, 112)
|
||||||
|
|
||||||
|
.input.half
|
||||||
|
width 48%
|
||||||
|
&.left
|
||||||
|
margin-right 4%
|
||||||
|
|||||||
55
src/styles/_loader.styl
Normal file
55
src/styles/_loader.styl
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
.sk-folding-cube
|
||||||
|
margin auto
|
||||||
|
width 100%
|
||||||
|
height 100%
|
||||||
|
position relative
|
||||||
|
transform rotateZ(45deg)
|
||||||
|
|
||||||
|
.sk-folding-cube .sk-cube
|
||||||
|
float left
|
||||||
|
width 50%
|
||||||
|
height 50%
|
||||||
|
position relative
|
||||||
|
transform scale(1.1)
|
||||||
|
|
||||||
|
.sk-folding-cube .sk-cube:before
|
||||||
|
content ''
|
||||||
|
position absolute
|
||||||
|
top 0
|
||||||
|
left 0
|
||||||
|
width 100%
|
||||||
|
height 100%
|
||||||
|
background-color linkColor
|
||||||
|
animation sk-foldCubeAngle 2.4s infinite linear both
|
||||||
|
transform-origin 100% 100%
|
||||||
|
|
||||||
|
.sk-folding-cube .sk-cube2
|
||||||
|
transform scale(1.1) rotateZ(90deg)
|
||||||
|
|
||||||
|
.sk-folding-cube .sk-cube3
|
||||||
|
transform scale(1.1) rotateZ(180deg)
|
||||||
|
|
||||||
|
.sk-folding-cube .sk-cube4
|
||||||
|
transform scale(1.1) rotateZ(270deg)
|
||||||
|
|
||||||
|
.sk-folding-cube .sk-cube2:before
|
||||||
|
animation-delay 0.3s
|
||||||
|
|
||||||
|
.sk-folding-cube .sk-cube3:before
|
||||||
|
animation-delay 0.6s
|
||||||
|
|
||||||
|
.sk-folding-cube .sk-cube4:before
|
||||||
|
animation-delay 0.9s
|
||||||
|
|
||||||
|
@keyframes sk-foldCubeAngle
|
||||||
|
0%, 10%
|
||||||
|
transform perspective(140px) rotateX(-180deg)
|
||||||
|
opacity 0
|
||||||
|
25%, 75%
|
||||||
|
transform perspective(140px) rotateX(0deg)
|
||||||
|
opacity 1
|
||||||
|
90%, 100%
|
||||||
|
transform perspective(140px) rotateY(180deg)
|
||||||
|
opacity 0
|
||||||
|
|
||||||
|
|
||||||
@@ -6,6 +6,7 @@ footerHeight = 50px
|
|||||||
@require '_input'
|
@require '_input'
|
||||||
@require '_button'
|
@require '_button'
|
||||||
@require '_header'
|
@require '_header'
|
||||||
|
@require '_loader'
|
||||||
|
|
||||||
body, html
|
body, html
|
||||||
margin 0
|
margin 0
|
||||||
@@ -25,6 +26,9 @@ h1, h2, h3
|
|||||||
h2
|
h2
|
||||||
margin-bottom 1em
|
margin-bottom 1em
|
||||||
|
|
||||||
|
h3
|
||||||
|
font-size 1.25em
|
||||||
|
|
||||||
p
|
p
|
||||||
margin-top 1em
|
margin-top 1em
|
||||||
line-height 1.5em
|
line-height 1.5em
|
||||||
@@ -51,13 +55,17 @@ section
|
|||||||
.content
|
.content
|
||||||
z-index 2
|
z-index 2
|
||||||
position relative
|
position relative
|
||||||
padding-right feedWidth
|
|
||||||
min-height 50vh
|
min-height 50vh
|
||||||
box-sizing border-box
|
box-sizing border-box
|
||||||
|
|
||||||
@media screen and (max-width: 700px)
|
@media screen and (max-width: 700px)
|
||||||
h3
|
h3
|
||||||
margin-top 0
|
margin-top 0
|
||||||
|
|
||||||
|
&.with-feed
|
||||||
|
padding-right feedWidth
|
||||||
|
|
||||||
|
|
||||||
section:first-child
|
section:first-child
|
||||||
box-shadow -1px -1px 1px rgba(0, 0, 0, 0.05)
|
box-shadow -1px -1px 1px rgba(0, 0, 0, 0.05)
|
||||||
border-bottom 1px solid #EEEEEE
|
border-bottom 1px solid #EEEEEE
|
||||||
@@ -104,35 +112,55 @@ section:first-child
|
|||||||
padding 0
|
padding 0
|
||||||
&:first-child
|
&:first-child
|
||||||
margin-top 0
|
margin-top 0
|
||||||
|
|
||||||
|
.form
|
||||||
|
.btn
|
||||||
|
background linkColor
|
||||||
|
border-bottom 2px solid #117280
|
||||||
|
color rgba(255, 255, 255, 0.9)
|
||||||
|
&.sending
|
||||||
|
.btn
|
||||||
|
display none
|
||||||
|
.invite-form__loader
|
||||||
|
display block
|
||||||
.invite-form
|
.invite-form
|
||||||
position relative
|
position relative
|
||||||
.btn
|
.btn
|
||||||
width 40px
|
width 40px
|
||||||
height 32px
|
height 32px
|
||||||
background linkColor
|
|
||||||
padding 0
|
padding 0
|
||||||
position absolute
|
position absolute
|
||||||
right 8px
|
right 8px
|
||||||
top 7px
|
top 7px
|
||||||
|
|
||||||
border-bottom 2px solid #117280
|
|
||||||
color rgba(255, 255, 255, 0.5)
|
color rgba(255, 255, 255, 0.5)
|
||||||
&:active
|
&:active
|
||||||
border-bottom 0
|
border-bottom 0
|
||||||
.loader
|
.invite-form__loader
|
||||||
|
display none
|
||||||
|
width 20px
|
||||||
|
height 20px
|
||||||
position absolute
|
position absolute
|
||||||
right 9px
|
right 14px
|
||||||
top 9px
|
top 14px
|
||||||
width 0px
|
|
||||||
height 0px
|
.membership-form
|
||||||
background transparent url('../images/ajax-loader.gif') no-repeat center center
|
.input
|
||||||
|
margin 8px 0px
|
||||||
|
.btn
|
||||||
|
margin-top 12px
|
||||||
|
|
||||||
|
.membership-form__loader
|
||||||
|
width 70px
|
||||||
|
height 70px
|
||||||
|
margin auto
|
||||||
|
|
||||||
|
.stripe-form
|
||||||
|
margin 20px 0px
|
||||||
|
.name
|
||||||
|
margin-top 20px
|
||||||
|
text-align left
|
||||||
display block
|
display block
|
||||||
&.sending
|
color rgba(0, 0, 0, 0.4)
|
||||||
.btn
|
|
||||||
display none
|
|
||||||
.loader
|
|
||||||
width 28px
|
|
||||||
height 28px
|
|
||||||
|
|
||||||
@keyframes drop
|
@keyframes drop
|
||||||
0%
|
0%
|
||||||
@@ -146,7 +174,7 @@ section:first-child
|
|||||||
100%
|
100%
|
||||||
transform rotateX(0deg)
|
transform rotateX(0deg)
|
||||||
|
|
||||||
.invite-form--message
|
.form--message
|
||||||
background linkColor
|
background linkColor
|
||||||
color #fff
|
color #fff
|
||||||
line-height 40px
|
line-height 40px
|
||||||
@@ -156,8 +184,8 @@ section:first-child
|
|||||||
transform-origin 100% 0
|
transform-origin 100% 0
|
||||||
animation drop 0.6s linear
|
animation drop 0.6s linear
|
||||||
|
|
||||||
.invite-form.has-error
|
.form.has-error
|
||||||
.invite-form--message
|
.form--message
|
||||||
background rgb(226, 33, 112)
|
background rgb(226, 33, 112)
|
||||||
|
|
||||||
.members
|
.members
|
||||||
@@ -182,7 +210,7 @@ footer
|
|||||||
justify-content space-between
|
justify-content space-between
|
||||||
flex-wrap wrap
|
flex-wrap wrap
|
||||||
text-align center
|
text-align center
|
||||||
@media screen and (max-width: 760px)
|
@media screen and (max-width: 940px)
|
||||||
display block
|
display block
|
||||||
i
|
i
|
||||||
margin 0 0.30em
|
margin 0 0.30em
|
||||||
@@ -194,7 +222,7 @@ footer
|
|||||||
display flex
|
display flex
|
||||||
flex-direction column
|
flex-direction column
|
||||||
justify-content center
|
justify-content center
|
||||||
@media screen and (max-width: 760px)
|
@media screen and (max-width: 940px)
|
||||||
margin-top 1em
|
margin-top 1em
|
||||||
|
|
||||||
.sponsors
|
.sponsors
|
||||||
@@ -215,16 +243,17 @@ footer
|
|||||||
height 40px
|
height 40px
|
||||||
margin-right 1em
|
margin-right 1em
|
||||||
vertical-align middle
|
vertical-align middle
|
||||||
@media screen and (max-width: 760px)
|
@media screen and (max-width: 940px)
|
||||||
margin-top 1em
|
margin-top 1em
|
||||||
|
|
||||||
|
|
||||||
.sponsor__futurice, .sponsor__metosin, .sponsor__leonidas
|
.sponsor__futurice, .sponsor__metosin, .sponsor__leonidas
|
||||||
height 30px
|
height 30px
|
||||||
|
|
||||||
.sponsor__nordea
|
.sponsor__nordea
|
||||||
height 25px
|
height 25px
|
||||||
margin-top: -3px
|
margin-top -3px
|
||||||
|
@media screen and (max-width: 940px)
|
||||||
|
margin-top 1em
|
||||||
|
|
||||||
.feed
|
.feed
|
||||||
width feedWidth
|
width feedWidth
|
||||||
@@ -242,7 +271,7 @@ footer
|
|||||||
@media screen and (max-width: 980px)
|
@media screen and (max-width: 980px)
|
||||||
.feed
|
.feed
|
||||||
width 0
|
width 0
|
||||||
.content
|
.content.with-feed
|
||||||
padding-right 0
|
padding-right 0
|
||||||
|
|
||||||
.message
|
.message
|
||||||
@@ -314,3 +343,24 @@ footer
|
|||||||
display block
|
display block
|
||||||
.column
|
.column
|
||||||
display block
|
display block
|
||||||
|
|
||||||
|
.bread-img
|
||||||
|
background url('../images/hp3_bw.jpg')
|
||||||
|
background-size cover
|
||||||
|
border-radius 160px
|
||||||
|
opacity 0.85
|
||||||
|
width 320px
|
||||||
|
height 320px
|
||||||
|
margin auto
|
||||||
|
|
||||||
|
@media screen and (max-width: 700px)
|
||||||
|
.bread-img
|
||||||
|
display none
|
||||||
|
|
||||||
|
.organization
|
||||||
|
padding-top 3em
|
||||||
|
|
||||||
|
.membership-information.column
|
||||||
|
vertical-align initial
|
||||||
|
p:first-child
|
||||||
|
margin-top 37px
|
||||||
|
|||||||
84
src/templates/head.jade
Normal file
84
src/templates/head.jade
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
doctype html
|
||||||
|
html
|
||||||
|
head
|
||||||
|
title
|
||||||
|
block title
|
||||||
|
// inject:css
|
||||||
|
// endinject
|
||||||
|
meta(name='description', content='Koodiklinikka on suomalainen Slack-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='57x57', href='icons/apple-touch-icon-57x57.png')
|
||||||
|
link(rel='apple-touch-icon', sizes='114x114', href='icons/apple-touch-icon-114x114.png')
|
||||||
|
link(rel='apple-touch-icon', sizes='72x72', href='icons/apple-touch-icon-72x72.png')
|
||||||
|
link(rel='apple-touch-icon', sizes='144x144', href='icons/apple-touch-icon-144x144.png')
|
||||||
|
link(rel='apple-touch-icon', sizes='60x60', href='icons/apple-touch-icon-60x60.png')
|
||||||
|
link(rel='apple-touch-icon', sizes='120x120', href='icons/apple-touch-icon-120x120.png')
|
||||||
|
link(rel='apple-touch-icon', sizes='76x76', href='icons/apple-touch-icon-76x76.png')
|
||||||
|
link(rel='apple-touch-icon', sizes='152x152', href='icons/apple-touch-icon-152x152.png')
|
||||||
|
link(rel='apple-touch-icon', sizes='180x180', href='icons/apple-touch-icon-180x180.png')
|
||||||
|
link(rel='icon', type='image/png', href='icons/favicon-192x192.png', sizes='192x192')
|
||||||
|
link(rel='icon', type='image/png', href='icons/favicon-160x160.png', sizes='160x160')
|
||||||
|
link(rel='icon', type='image/png', href='icons/favicon-96x96.png', sizes='96x96')
|
||||||
|
link(rel='icon', type='image/png', href='icons/favicon-16x16.png', sizes='16x16')
|
||||||
|
link(rel='icon', type='image/png', href='icons/favicon-32x32.png', sizes='32x32')
|
||||||
|
link(rel='shortcut icon', href='icons/favicon.ico')
|
||||||
|
link(rel='icon', href='icons/favicon.ico')
|
||||||
|
meta(name='msapplication-TileColor', content='#10558c')
|
||||||
|
meta(name='msapplication-TileImage', content='icons/mstile-144x144.png')
|
||||||
|
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://leonidasoy.fi/', target='_blank')
|
||||||
|
img.sponsor.sponsor__leonidas(src='images/leonidas.png')
|
||||||
|
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
|
||||||
48
src/yhdistys.jade
Normal file
48
src/yhdistys.jade
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
extends templates/head
|
||||||
|
|
||||||
|
block title
|
||||||
|
| Yhdistys
|
||||||
|
|
||||||
|
block header_content
|
||||||
|
.header__container
|
||||||
|
.header__nav
|
||||||
|
a(href='/') etusivu
|
||||||
|
a(href='/yhdistys.html') yhdistys
|
||||||
|
.header__headline
|
||||||
|
.header__logo
|
||||||
|
h1.header__title Koodiklinikka ry
|
||||||
|
.header__members
|
||||||
|
#members
|
||||||
|
|
||||||
|
block content
|
||||||
|
.content
|
||||||
|
section.organization
|
||||||
|
.row
|
||||||
|
.bread
|
||||||
|
.column.column1-2
|
||||||
|
h3 Rekisteröity yhdistys
|
||||||
|
p.
|
||||||
|
Koodiklinikka on nyt rekisteröity yhdistys!
|
||||||
|
p.
|
||||||
|
Lähes nelivuotisen taipaleensa aikana Koodiklinikka on kasvanut lähes tuhannen rekisteröityneen jäsenen yhteisöiksi ja näin saavuttanut aseman Suomen suurimpana ohjelmointiaiheisena yhteisönä! Liittymällä Koodiklinikka ry:n jäseneksi tuet toimintaamme, ja tulevaisuudessa yhdistyksen jäsenyys oikeuttaa etuihin Koodiklinikan tapahtumissa.
|
||||||
|
p.
|
||||||
|
Yhdistyksen jäsenyys <b>ei ole</b>, eikä tule olemaan, <b>pakollinen</b> Koodiklinikan käyttäjille tai meetuppeihin osallistujille.
|
||||||
|
.column.column1-2
|
||||||
|
.bread-img
|
||||||
|
.row
|
||||||
|
.bread
|
||||||
|
.column.column1-2
|
||||||
|
#membership-form.form
|
||||||
|
|
||||||
|
.column.column1-2.membership-information
|
||||||
|
p.
|
||||||
|
Kuka tahansa Slack:iin rekisteröitynyt käyttäjä voi liittyä yhdistyksen jäseneksi maksamalla <b>10€</b> vuosittaisen jäsenmaksun.
|
||||||
|
p.
|
||||||
|
Jäsenmaksulla tulemme tekemään tapahtumistamme vieläkin mielenkiintoisempia ja kattamaan kustannuksia jäsenmäärämme kasvaessa.
|
||||||
|
p.
|
||||||
|
Jos tarvitset Slack-kutsun, siirry <a target="_blank" href="/">etusivulle</a>.
|
||||||
|
p.
|
||||||
|
Jäsenrekisterin rekisteriseloste luettavissa <a target="_blank" href="https://docs.google.com/document/d/1w-NZkf1EFYMC8a4LsoZouhpMVKORmPi8UFWRhurr0oM/edit?usp=sharing">Google Drivessä</a>.
|
||||||
|
p.
|
||||||
|
Lisätietoa yhdistyksen jäsenyydestä tai vuosimaksusta emaililla <span class="email"></span>
|
||||||
|
|
||||||
Reference in New Issue
Block a user