diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..6e87a00
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,13 @@
+# Editor configuration, see http://editorconfig.org
+root = true
+
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 2
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.md]
+max_line_length = off
+trim_trailing_whitespace = false
diff --git a/.eslintrc.js b/.eslintrc.js
new file mode 100644
index 0000000..375b9af
--- /dev/null
+++ b/.eslintrc.js
@@ -0,0 +1,26 @@
+module.exports = {
+ env: {
+ browser: true,
+ es6: true,
+ jquery: true
+ },
+ globals: {
+ "fetch": false,
+ "window": true,
+ "document": true
+ },
+ extends: 'eslint:recommended',
+ parserOptions: {
+ sourceType: 'module'
+ },
+ rules: {
+ indent: ['error', 2],
+ 'no-unused-vars': [1, { vars: 'local', args: 'none' }],
+ 'linebreak-style': 'off',
+ quotes: ['error', 'single'],
+ semi: ['error', 'always']
+ },
+ env: {
+ node: true
+ }
+};
diff --git a/.gitignore b/.gitignore
index 40b878d..ec26407 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,5 @@
-node_modules/
\ No newline at end of file
+dist
+node_modules
+package-lock.json
+.DS_Store
+.vscode/settings.json
diff --git a/.stylintrc b/.stylintrc
new file mode 100644
index 0000000..021eb5c
--- /dev/null
+++ b/.stylintrc
@@ -0,0 +1,62 @@
+{
+ "blocks": false,
+ "brackets": {
+ "expect": "never",
+ "error": true
+ },
+ "colons": {
+ "expect": "never",
+ "error": true
+ },
+ "colors": "always",
+ "commaSpace": "aways",
+ "commentSpace": "always",
+ "cssLiteral": "never",
+ "customProperties": [],
+ "depthLimit": {
+ "expect": 3,
+ "error": true
+ },
+ "duplicates": true,
+ "efficient": "always",
+ "extendPref": false,
+ "globalDupe": false,
+ "groupOutputByFile": true,
+ "indentPref": {
+ "expect": 2,
+ "error": true
+ },
+ "leadingZero": "never",
+ "maxErrors": false,
+ "maxWarnings": false,
+ "mixed": false,
+ "mixins": [],
+ "namingConvention": false,
+ "namingConventionStrict": false,
+ "none": "never",
+ "noImportant": false,
+ "parenSpace": false,
+ "placeholders": "always",
+ "prefixVarsWithDollar": "always",
+ "quotePref": false,
+ "reporterOptions": {
+ "columns": ["lineData", "severity", "description", "rule"],
+ "columnSplitter": " ",
+ "showHeaders": false,
+ "truncate": true
+ },
+ "semicolons": {
+ "expect": "never",
+ "error": true
+ },
+ "sortOrder": {
+ "expect": "alphabetical",
+ "error": true
+ },
+ "stackedProperties": "never",
+ "trailingWhitespace": false,
+ "universal": false,
+ "valid": false,
+ "zeroUnits": "never",
+ "zIndexNormalize": false
+}
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..9ba9abc
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,10 @@
+language: node_js
+node_js:
+ - "7"
+before_script:
+ - npm i
+cache:
+ directories:
+ - "node_modules"
+script:
+ - npm run deploy
diff --git a/README.md b/README.md
index c3a90dd..d3b52c4 100644
--- a/README.md
+++ b/README.md
@@ -1,39 +1,73 @@
-Survey - Front-End
-=======
+
+
+
-Pesquisa de mercado realizada entre front-end developers do Brasil.
+# Survey Front-end Brasil
-[Visualizar o projeto](http://www.felipefialho.com/survey)
+> Pesquisa salarial entre frontenders do Brasil
-## Contribuição
+[](./license.md)
+[](https://github.com/LFeh/survey/graphs/contributors)
-Por favor leia o [Coding Style](https://github.com/LFeh/coding-style/) para [Issues](https://github.com/LFeh/survey/issues) e as regras de código.
+## Getting Started
-Todas as alterações devem ser feitas na pasta `/dev`. O CSS precisa ser modificado usando o pré-processador **LESS**.
+```sh
+# install dependencies
+$ npm i
-Issues e commits devem ser enviados em pt-BR.
+# Run the project
+$ npm start
+```
- ```bash
+With the commands above, you have everything to start.
+
+## About CSS
+
+### Post CSS libs
- # Getting Started
- # ---------------
+For grid system uses [Autoprefixer](https://github.com/postcss/autoprefixer) to make easy use browser prefixes, [Lost](https://github.com/peterramsing/lost) with some help from, [Rucksack](http://simplaio.github.io/rucksack/) for animations, reset and a lot of great mixins, [Rupture](https://github.com/jenius/rupture) for responsive utilities. And [Font Magician](https://github.com/jonathantneal/postcss-font-magician/) to get the webfonts.
- # 1. Fork esse repositório e clone
- git clone https://github.com//survey.git
+### CSS Modules
- # 2. Navegue até a nova pasta
- cd survey
+To make easier create your components and avoid a lot of problems, it boilerplate use [CSS Modules](https://github.com/css-modules/css-modules).
- # 3. Instale as dependências
- npm install
+Example
+```css
+.host
+ text-align center
- # Development
- # -----------
+.title
+ font-size 4rem
- # Para assistir as alterações no .less e no .js rode o comando
- grunt w
+.description
+ font-size 2rem
+```
- # Build o projeto para deploy
- grunt build
- ```
+After the transformation it will become like this
+
+```css
+._host_4897k_1 {
+ text-align: center;
+}
+
+._title_4897k_9 {
+ font-size: 4rem;
+}
+
+._description_4897k_12 {
+ font-size: 2rem;
+}
+```
+
+## Tasks
+
+- `npm start`: run all tasks and initialize watch for changes and a server
+- `npm run build`: run all production tasks create a `dist` folder to deploy
+- `npm run lint`: lint javascript and css
+- `npm run fix`: command to fix all eslint errors
+- `npm run deploy`: run all tasks to build and deploy on gh-pages
+
+## License
+
+MIT License © Felipe Fialho
diff --git a/app.config.json b/app.config.json
new file mode 100644
index 0000000..20395c7
--- /dev/null
+++ b/app.config.json
@@ -0,0 +1,10 @@
+{
+ "title": "Survey - Front-End Brasil 2018",
+ "description": "Pesquisa salarial entre frontenders do Brasil",
+ "url": "https://github.com/LFeh/survey",
+ "logo": "images/logo.png",
+ "theme_color": "#333333",
+ "short_name": "Survey 2018",
+ "ga": "UA-40410936-3",
+ "twitter": "@lfeh"
+}
diff --git a/license b/license
new file mode 100644
index 0000000..6afa163
--- /dev/null
+++ b/license
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018 Felipe Fialho
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..6501f06
--- /dev/null
+++ b/package.json
@@ -0,0 +1,75 @@
+{
+ "name": "survey",
+ "version": "2.0.0",
+ "title": "Survey",
+ "description": "Pesquisa salarial entre frontenders do Brasil",
+ "homepage": "https://github.com/LFeh/survey",
+ "browserslist": [
+ "> 1%",
+ "last 2 versions"
+ ],
+ "author": {
+ "name": "Felipe Fialho",
+ "email": "hi@felipefialho.com",
+ "url": "http://www.felipefialho.com"
+ },
+ "scripts": {
+ "start": "webpack-dev-server --mode development",
+ "build": "webpack --mode production",
+ "deploy": "gh-pages-deploy",
+ "analyzer": "npm run build && webpack-bundle-analyzer ./dist/stats.json",
+ "lint": "npm run lint:js && npm run lint:styl",
+ "lint:styl": "stylint src/**/*.styl",
+ "lint:scss": "sass-lint -c sass-lint.json 'src/**/*.scss' -v -q",
+ "lint:js": "eslint ./src/",
+ "fix:js": "eslint ./src/ --fix",
+ "precommit": "npm run lint"
+ },
+ "gh-pages-deploy": {
+ "staticpath": "dist",
+ "prep": [
+ "build"
+ ],
+ "noprompt": true
+ },
+ "dependencies": {},
+ "devDependencies": {
+ "autoprefixer": "^9.0.0",
+ "babel-core": "^6.26.3",
+ "babel-loader": "^7.1.5",
+ "babel-preset-env": "^1.7.0",
+ "clean-webpack-plugin": "^0.1.19",
+ "copy-webpack-plugin": "^4.5.2",
+ "css-loader": "^1.0.0",
+ "cssnano": "^4.0.2",
+ "eslint": "^5.1.0",
+ "file-loader": "1.1.11",
+ "gh-pages-deploy": "^0.5.0",
+ "html-webpack-plugin": "^3.2.0",
+ "imagemin-webpack-plugin": "^2.1.5",
+ "lost": "^8.3.0",
+ "mini-css-extract-plugin": "^0.4.1",
+ "node-sass": "^4.9.2",
+ "offline-plugin": "^5.0.5",
+ "postcss-font-magician": "^2.2.1",
+ "postcss-loader": "^2.1.6",
+ "postcss-modules": "^1.1.0",
+ "pug": "^2.0.3",
+ "pug-loader": "^2.4.0",
+ "rucksack-css": "^1.0.2",
+ "rupture": "^0.7.1",
+ "rupture-sass": "^0.3.0",
+ "sass-lint": "^1.12.1",
+ "sass-loader": "^7.0.3",
+ "style-loader": "^0.21.0",
+ "stylint": "^1.5.9",
+ "stylus": "^0.54.5",
+ "stylus-loader": "^3.0.2",
+ "uglifyjs-webpack-plugin": "^1.2.7",
+ "webpack": "^4.16.1",
+ "webpack-bundle-analyzer": "^2.13.1",
+ "webpack-cli": "^3.0.8",
+ "webpack-dev-server": "^3.1.4",
+ "webpack-pwa-manifest": "^3.6.2"
+ }
+}
diff --git a/postcss.config.js b/postcss.config.js
new file mode 100644
index 0000000..e698775
--- /dev/null
+++ b/postcss.config.js
@@ -0,0 +1,22 @@
+module.exports = {
+ plugins: {
+ 'autoprefixer': {},
+ 'rucksack-css': {},
+ 'lost': {},
+ 'postcss-font-magician': {},
+ 'cssnano': {},
+ 'postcss-modules': {
+ getJSON: function(cssFileName, json, outputFileName) {
+ const fs = require('fs');
+ const path = require('path');
+ const isComponent = /components/.test(path.dirname(cssFileName));
+
+ if (isComponent) {
+ const cssName = path.basename(`${cssFileName}`);
+ const jsonFileName = path.resolve(`${path.dirname(cssFileName)}/${cssName.split('.')[0]}-css.json`);
+ fs.writeFileSync(jsonFileName, JSON.stringify(json));
+ }
+ }
+ }
+ }
+};
diff --git a/src/app.js b/src/app.js
new file mode 100644
index 0000000..7525b69
--- /dev/null
+++ b/src/app.js
@@ -0,0 +1,12 @@
+import * as offline from 'offline-plugin/runtime';
+import './app.styl';
+import './components/welcome/welcome.js';
+import './components/introduction/introduction.js';
+import './components/footer/footer.js';
+
+
+offline.install({
+ onUpdateReady: function() {
+ offline.applyUpdate();
+ }
+});
diff --git a/src/app.styl b/src/app.styl
new file mode 100644
index 0000000..5fb1b16
--- /dev/null
+++ b/src/app.styl
@@ -0,0 +1,2 @@
+@import 'styles/core';
+@import 'styles/base';
diff --git a/src/favicon.ico b/src/favicon.ico
new file mode 100644
index 0000000..4f131de
Binary files /dev/null and b/src/favicon.ico differ
diff --git a/src/images/logo.png b/src/images/logo.png
new file mode 100644
index 0000000..f1a9461
Binary files /dev/null and b/src/images/logo.png differ
diff --git a/src/index.pug b/src/index.pug
new file mode 100644
index 0000000..bea69a7
--- /dev/null
+++ b/src/index.pug
@@ -0,0 +1,40 @@
+- var data = require('../app.config.json');
+
+doctype html
+html(lang='pt-br')
+ head
+ title #{data.title} - #{data.description}
+ meta(charset='utf-8')
+ meta(name='description' content=data.description)
+ meta(name='image' content=data.url + data.logo)
+ meta(itemprop='name' content=data.title)
+ meta(itemprop='description' content=data.description)
+ meta(itemprop='image' content=data.url + data.logo)
+ meta(name='twitter:card' content='summary')
+ meta(name='twitter:title' content=data.title)
+ meta(name='twitter:description' content=data.description)
+ meta(name='twitter:site' content=data.twitter)
+ meta(name='twitter:creator' content=data.twitter)
+ meta(name='twitter:image:src' content=data.url + data.logo)
+ meta(name='og:title' content=data.title)
+ meta(name='og:description' content=data.description)
+ meta(name='og:image' content=data.url + data.logo)
+ meta(name='og:url' content=data.url)
+ meta(name='og:site_name' content=data.title)
+ meta(name='og:locale' content='en')
+ meta(name='og:type' content='website')
+ meta(http-equiv='X-UA-Compatible' content='IE=edge')
+ meta(name='viewport' content='width=device-width, initial-scale=1, maximum-scale=5')
+ meta(name='theme-color' content=data.theme_color)
+ link(rel='shortcut icon' type='image/favicon' href='favicon.ico')
+ script(async src='https://www.googletagmanager.com/gtag/js?id=' + data.ga)
+ script.
+ window.dataLayer = window.dataLayer || [];
+ function gtag(){dataLayer.push(arguments);}
+ gtag('js', new Date());
+ gtag('config', '#{data.ga}');
+ body
+ include components/welcome/welcome.pug
+ .main
+ include components/introduction/introduction.pug
+ include components/footer/footer.pug
diff --git a/src/js/main.js b/src/js/main.js
new file mode 100644
index 0000000..e69de29
diff --git a/src/styles/base.styl b/src/styles/base.styl
new file mode 100644
index 0000000..770b675
--- /dev/null
+++ b/src/styles/base.styl
@@ -0,0 +1,31 @@
+*
+ box-sizing border-box
+ margin 0
+ padding 0
+
+ &:before
+ &:after
+ box-sizing border-box
+
+ &:hover
+ &:focus
+ outline transparent
+
+a
+ cursor pointer
+
+html
+ -moz-osx-font-smoothing auto
+ -webkit-font-smoothing auto
+ font-size 10px
+ font-size responsive 8px 10px
+
+body
+ -webkit-overflow-scrolling touch
+ background-color $gray-white
+ color $gray-darker
+ font-family 'Open Sans', Arial, sans-serif
+ font-size 1.8rem
+ font-smoothing auto
+ overflow-x hidden
+
diff --git a/src/styles/core.styl b/src/styles/core.styl
new file mode 100644
index 0000000..3aad32c
--- /dev/null
+++ b/src/styles/core.styl
@@ -0,0 +1,2 @@
+@import 'core/variables'
+
diff --git a/src/styles/core/variables.styl b/src/styles/core/variables.styl
new file mode 100644
index 0000000..d501365
--- /dev/null
+++ b/src/styles/core/variables.styl
@@ -0,0 +1,73 @@
+// ==================================================
+// Variables
+//
+// 1. Colors
+// 2. Spaces
+// 3. Media Queries
+// 4. zIndex
+// ==================================================
+
+// --------------------------------------------------
+// 1. Colors
+// --------------------------------------------------
+
+//
+// Colors
+// --------------------------------------------------
+
+$gray-darker = #282828
+$gray-dark = #333
+$gray = #666
+$gray-medium = #aaa
+$gray-light = #c8c8c8
+$gray-lighter = #dedede
+$gray-white = #fafafa
+$white = #fff
+
+$yellow = #f0ad4e
+$green = #5cb85c
+$blue = #5891ff
+$blue-light = #aceff9
+
+// -------------------------------------------------
+// 2. Spaces
+// --------------------------------------------------
+
+$space-xxs = .4rem // Smallest space margin
+$space-xs = .8rem // Extra small space margin
+$space-sm = 1.6rem // Small space margin
+$space = 2.4rem // Regular space margin
+$space-md = 3.2rem // Medium space margin
+$space-lg = 4.8rem // Large space margin
+$space-xlg = 6.4rem // Extra Large space margin
+$space-xxlg = 8.8rem // Extra Large space margin
+
+// --------------------------------------------------
+// 3. Media Queries
+// --------------------------------------------------
+
+$screen-xxs = 380px // xExtra small screen / phone
+$screen-xs = 440px // Extra small screen / phone
+$screen-sm = 768px // Small screen / tablet
+$screen-md = 992px // Medium screen / desktop
+$screen-lg = 1200px // Large screen / wide desktop
+$screen-xlg = 1400px // Extra Large screen / wide desktop
+$screen-xxlg = 1600px // Extra Large screen / wide desktop
+
+// Rupture Settings
+// @stylint off
+rupture.mobile-cutoff = $screen-sm
+rupture.tablet-cutoff = $screen-md
+rupture.desktop-cutoff = $screen-lg
+rupture.hd-cutoff = $screen-xlg
+
+rupture.scale = 0 $screen-xxs $screen-sm $screen-md $screen-lg $screen-xlg $screen-xxlg
+rupture.scale-names = 'xxs' 'xs' 'sm' 'md' 'lg' 'xlg' 'hd'
+rupture.anti-overlap = -1px
+// @stylint on
+
+// --------------------------------------------------
+// 4. zIndex
+// --------------------------------------------------
+
+$zindex-default = 1
diff --git a/webpack.config.js b/webpack.config.js
new file mode 100644
index 0000000..38a2062
--- /dev/null
+++ b/webpack.config.js
@@ -0,0 +1,157 @@
+const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
+const CleanWebpackPlugin = require('clean-webpack-plugin');
+const config = require('./app.config.json');
+const CopyWebpackPlugin = require('copy-webpack-plugin');
+const HtmlWebpackPlugin = require('html-webpack-plugin');
+const ImageminPlugin = require('imagemin-webpack-plugin').default;
+const MiniCssExtractPlugin = require('mini-css-extract-plugin');
+const OfflinePlugin = require('offline-plugin');
+const path = require('path');
+const rupture = require('rupture');
+const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
+const webpack = require('webpack');
+const WebpackPwaManifest = require('webpack-pwa-manifest');
+
+const webapp = {
+ name: config.title,
+ short_name: config.short_name,
+ description: config.description,
+ background_color: config.theme_color,
+ theme_color: config.theme_color,
+ orientation: 'landscape',
+ icons: [
+ {
+ src: path.resolve('./src/images/logo.png'),
+ sizes: [96, 128, 192, 256, 384, 512]
+ }
+ ]
+};
+
+const copyFiles = [
+ { from: './src/images/', to: './images' },
+ { from: './src/favicon.ico', to: './' },
+];
+
+const sw = {
+ safeToUseOptionalCaches: true,
+ caches: {
+ main: ['index.html'],
+ additional: ['*.js?*']
+ },
+ navigateFallbackURL: '/',
+ autoUpdate: true,
+ responseStrategy: 'cache-first',
+ ServiceWorker: { events: true },
+ AppCache: { events: true }
+};
+
+const baseWebpack = {
+ entry: {
+ app: './src/app.js'
+ },
+ output: {
+ path: path.resolve(__dirname, 'dist'),
+ filename: '[name].bundle.js'
+ },
+ module: {
+ rules: [
+ {
+ test: /\.pug/,
+ loader: 'pug-loader',
+ },
+ {
+ test: /\.styl/,
+ use: [
+ 'style-loader',
+ MiniCssExtractPlugin.loader,
+ {
+ loader: 'css-loader',
+ options: { importLoaders: 1 }
+ },
+ 'postcss-loader',
+ {
+ loader: 'stylus-loader',
+ options: {
+ use: [rupture()],
+ }
+ }
+ ]
+ },
+ {
+ test: /\.scss/,
+ use: [
+ 'style-loader',
+ MiniCssExtractPlugin.loader,
+ {
+ loader: 'css-loader',
+ options: { importLoaders: 1 }
+ },
+ 'postcss-loader',
+ {
+ loader: 'sass-loader'
+ }
+ ]
+ },
+ {
+ test: /\.jpe?g$|\.gif$|\.png$|\.svg$/,
+ use: 'file-loader'
+ },
+ {
+ test: /\.js$/,
+ exclude: /node_modules/,
+ use: {
+ loader: 'babel-loader',
+ options: {
+ presets: ['env']
+ }
+ }
+ }
+ ]
+ },
+ plugins: [
+ new webpack.DefinePlugin({
+ 'process.env.WEBPACK_MODE': JSON.stringify(process.env.WEBPACK_MODE)
+ }),
+ new CleanWebpackPlugin(['dist']),
+ new HtmlWebpackPlugin({
+ hash: true,
+ template: './src/index.pug'
+ }),
+ new MiniCssExtractPlugin({
+ filename: 'style.[contenthash].css',
+ }),
+ new CopyWebpackPlugin(copyFiles)
+ ]
+};
+
+const prodStart = () => {
+ baseWebpack.optimization = {
+ minimizer: [ new UglifyJsPlugin() ],
+ };
+ baseWebpack.plugins.push(new ImageminPlugin({ test: /\.(jpe?g|png|gif|svg)$/i }));
+ baseWebpack.plugins.push(new BundleAnalyzerPlugin({analyzerMode: 'disabled'}));
+ baseWebpack.plugins.push(new WebpackPwaManifest(webapp));
+ baseWebpack.plugins.push(new OfflinePlugin(sw));
+};
+
+const devStart = () => {
+ baseWebpack.devServer = {
+ contentBase: path.join(__dirname, 'dist'),
+ compress: true,
+ open: true,
+ port: 9000
+ };
+};
+
+module.exports = (env, options) => {
+ if (options.mode === 'production') {
+ prodStart();
+ }
+
+ if (options.mode === 'development') {
+ devStart();
+ }
+
+ return baseWebpack;
+};
+
\ No newline at end of file