From 2986eeb89c72bbc80f40abc851b4d3db5e3866c7 Mon Sep 17 00:00:00 2001 From: sipp11 Date: Tue, 17 May 2016 08:53:16 +0700 Subject: [PATCH] Init --- .babelrc | 27 ++++++ .eslintrc | 27 ++++++ .gitignore | 35 ++++++++ client/app.js | 1 + client/data/config.js | 13 +++ client/styles/_animations.styl | 17 ++++ client/styles/_normalize.styl | 10 +++ client/styles/_typography.styl | 45 ++++++++++ client/styles/style.styl | 149 +++++++++++++++++++++++++++++++++ devServer.js | 27 ++++++ index.html | 13 +++ package.json | 60 +++++++++++++ readme.md | 13 +++ webpack.config.dev.js | 35 ++++++++ webpack.config.prod.js | 44 ++++++++++ 15 files changed, 516 insertions(+) create mode 100644 .babelrc create mode 100644 .eslintrc create mode 100644 .gitignore create mode 100644 client/app.js create mode 100644 client/data/config.js create mode 100644 client/styles/_animations.styl create mode 100644 client/styles/_normalize.styl create mode 100644 client/styles/_typography.styl create mode 100644 client/styles/style.styl create mode 100644 devServer.js create mode 100644 index.html create mode 100644 package.json create mode 100644 readme.md create mode 100644 webpack.config.dev.js create mode 100644 webpack.config.prod.js diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..2488eb1 --- /dev/null +++ b/.babelrc @@ -0,0 +1,27 @@ +{ + "presets": ["react", "es2015"], + "env": { + "development": { + "plugins": [ + ["transform-object-rest-spread"], + ["transform-react-display-name"], + ["react-transform", { + "transforms": [{ + "transform": "react-transform-hmr", + "imports": ["react"], + "locals": ["module"] + }, { + "transform": "react-transform-catch-errors", + "imports": ["react", "redbox-react"] + }] + }] + ] + }, + "production": { + "plugins": [ + ["transform-object-rest-spread"], + ["transform-react-display-name"] + ] + } + } +} diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..f6daa6e --- /dev/null +++ b/.eslintrc @@ -0,0 +1,27 @@ +{ + "ecmaFeatures": { + "jsx": true, + "modules": true + }, + "env": { + "browser": true, + "node": true + }, + "parser": "babel-eslint", + "rules": { + "quotes": [2, "single"], + "strict": [2, "never"], + "babel/generator-star-spacing": 1, + "babel/new-cap": 1, + "babel/object-shorthand": 1, + "babel/arrow-parens": 1, + "babel/no-await-in-loop": 1, + "react/jsx-uses-react": 2, + "react/jsx-uses-vars": 2, + "react/react-in-jsx-scope": 2 + }, + "plugins": [ + "babel", + "react" + ] +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..41607c2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,35 @@ +# Logs +logs +*.log +npm-debug.log* + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directory +node_modules + +# Optional npm cache directory +.npm + +# Optional REPL history +.node_repl_history + +.DS_Store diff --git a/client/app.js b/client/app.js new file mode 100644 index 0000000..598ea18 --- /dev/null +++ b/client/app.js @@ -0,0 +1 @@ +// let's go! diff --git a/client/data/config.js b/client/data/config.js new file mode 100644 index 0000000..6e38765 --- /dev/null +++ b/client/data/config.js @@ -0,0 +1,13 @@ +import Raven from 'raven-js'; + +const sentry_key = 'cb55d4f05cd443ce82303222f77ef5e0'; +const sentry_app = '61499'; +export const sentry_url = `https://${sentry_key}@app.getsentry.com/${sentry_app}`; + +export function logException(ex, context) { + Raven.captureException(ex, { + extra: context + }); + /*eslint no-console:0*/ + window && window.console && console.error && console.error(ex); +} diff --git a/client/styles/_animations.styl b/client/styles/_animations.styl new file mode 100644 index 0000000..5952e21 --- /dev/null +++ b/client/styles/_animations.styl @@ -0,0 +1,17 @@ +// offset variable gets tacked for centering in addition to the scaling + +offsets = translateX(-50%) translateY(-50%) +.likes-heart + opacity 0 + transition all 0.5s // time to fade out after its done + transform offsets scale(5) // this is the "end state" + display block + &.like-enter + transition all .2s + transform offsets scale(1) + opacity 1 + &.like-enter-active + transform offsets scale(5) + .like-leave-active + display none + diff --git a/client/styles/_normalize.styl b/client/styles/_normalize.styl new file mode 100644 index 0000000..67eef68 --- /dev/null +++ b/client/styles/_normalize.styl @@ -0,0 +1,10 @@ +article,aside,details,figcaption,figure,footer,header,hgroup,nav,section,summary{display:block;}audio,canvas,video{display:inline-block;}audio:not([controls]){display:none;height:0;}[hidden]{display:none;}html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;}a:focus{outline:thin dotted;}a:active,a:hover{outline:0;}h1{font-size:2em;}abbr[title]{border-bottom:1px dotted;}b,strong{font-weight:700;}dfn{font-style:italic;}mark{background:#ff0;color:#000;}code,kbd,pre,samp{font-family:monospace, serif;font-size:1em;}pre{white-space:pre-wrap;word-wrap:break-word;}q{quotes:\201C \201D \2018 \2019;}small{font-size:80%;}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;}sup{top:-.5em;}sub{bottom:-.25em;}img{border:0;}svg:not(:root){overflow:hidden;}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em;}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0;}button,input{line-height:normal;}button,html input[type=button],/* 1 */ +input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;}button[disabled],input[disabled]{cursor:default;}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0;}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none;}textarea{overflow:auto;vertical-align:top;}table{border-collapse:collapse;border-spacing:0;}body,figure{margin:0;}legend,button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0;} + +.clearfix:after {visibility: hidden; display: block; font-size: 0; content: " "; clear: both; height: 0; } + +* { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; } + + +img + max-width 100% diff --git a/client/styles/_typography.styl b/client/styles/_typography.styl new file mode 100644 index 0000000..aeaf45d --- /dev/null +++ b/client/styles/_typography.styl @@ -0,0 +1,45 @@ +/* + Variables +*/ + +blue = #125688 +offwhite = #fafafa +lightgrey = #EDEEED +lightgray = lightgrey // OH Canada! + +html + font-size 10px + font-family sans-serif + +p + font-size 1.6rem + line-height 1.5 + +h1 + font-family billabong, 'billabongregular' + text-align center + font-weight 100 + font-size 13rem + margin 2rem 0 + letter-spacing -1px + text-shadow 0px 4px 0 rgba(18, 86, 136, 0.11) + a + color blue + text-decoration none + &:focus + outline 0 + + +// "Instagram-like" webfont + +@font-face { + font-family: 'billabongregular'; + src: url('https://cdn.rawgit.com/milktronics/beaglegr.am/master/public/fonts/billabong-webfont.eot'); + src: url('https://cdn.rawgit.com/milktronics/beaglegr.am/master/public/fonts/billabong-webfont.eot?#iefix') format('embedded-opentype'), + url('https://cdn.rawgit.com/milktronics/beaglegr.am/master/public/fonts/billabong-webfont.woff') format('woff'), + url('https://cdn.rawgit.com/milktronics/beaglegr.am/master/public/fonts/billabong-webfont.ttf') format('truetype'), + url('https://cdn.rawgit.com/milktronics/beaglegr.am/master/public/fonts/billabong-webfont.svg#billabongregular') format('svg'); + font-weight: normal; + font-style: normal; + +} diff --git a/client/styles/style.styl b/client/styles/style.styl new file mode 100644 index 0000000..d47d400 --- /dev/null +++ b/client/styles/style.styl @@ -0,0 +1,149 @@ +@import '_normalize.styl' +@import '_typography.styl' +@import '_animations.styl' + +body + background offwhite + +.photo-grid + display flex + flex-wrap wrap + max-width 1200px + margin 0 auto + +.grid-figure + flex-basis calc(33.333% - 4rem) + flex-grow 1 + flex-shrink 0 + margin 0 2rem 2rem 2rem + padding 2rem + border 1px solid lightgray + background white + box-shadow 0 0 0 5px rgba(0,0,0,0.03); + position relative + +.single-photo + @extend .grid-figure + max-width 900px + margin 0 auto + display flex + background white + .grid-figure + box-shadow none + margin 0 2rem 0 0 + border 0 + padding 0 + flex 1 0 60% + max-width 60% + .comments + flex 1 0 40% + max-width 40% + .grid-photo + width 100% + margin 0 + +.grid-photo + width calc(100% + 4rem) + margin-left -2rem + margin-top -2rem + max-width none + +// Comments +.remove-comment + background none + border 0 + line-height 1 + opacity 0 + &:hover + color red + +.comment + border-bottom 1px solid lightgrey + padding 0.5rem 0 + p + font-size 1.2rem + margin 0 + strong + color blue + margin-right 5px + &:hover + .remove-comment + opacity 1 + +.comment-form + input, textarea + width 100% + border 0 + font-size 1.3rem + padding 1rem 0 + border-bottom 1px solid lightgrey + outline none + resize vertical + + +.grid-photo-wrap + position relative + +.likes-heart + background url(http://f.cl.ly/items/3Y373q2Q3J3Y1j203n0m/Bitmap-3.png) center no-repeat + background-size contain + font-size 2rem + padding 1rem + position absolute + color blue + left 50% + top 50% + pointer-events none + + +/* + Buttons +*/ + +.control-buttons + display flex + justify-content space-between + +button, .button + border 2px solid lighten(grey, 90%) + background none + flex-basis 48% + display inline-block + line-height 2 + text-decoration none + padding 5px + text-align center + font-size 15px + color blue + transition all 0.2s + box-sizing padding-box + &:hover, &:focus + border-color blue + outline 0 + +/* + Cowboy style speech bubble - you should probably use an SVG for this if you are doing more icons. +*/ +.speech-bubble + size = 1.25rem + width size * 1.2 + height size + background blue + display inline-block + border-radius 50% + position relative + &:after + display inline-block + position absolute + content '' + width: 0; + height: 0; + border-style: solid; + border-width: 0 size size 0 + border-color: transparent blue transparent transparent + top 30% + left 0 + + + + diff --git a/devServer.js b/devServer.js new file mode 100644 index 0000000..e4b3f5b --- /dev/null +++ b/devServer.js @@ -0,0 +1,27 @@ +var path = require('path'); +var express = require('express'); +var webpack = require('webpack'); +var config = require('./webpack.config.dev'); + +var app = express(); +var compiler = webpack(config); + +app.use(require('webpack-dev-middleware')(compiler, { + noInfo: true, + publicPath: config.output.publicPath +})); + +app.use(require('webpack-hot-middleware')(compiler)); + +app.get('*', function(req, res) { + res.sendFile(path.join(__dirname, 'index.html')); +}); + +app.listen(7700, 'localhost', function(err) { + if (err) { + console.log(err); + return; + } + + console.log('Listening at http://localhost:7700'); +}); diff --git a/index.html b/index.html new file mode 100644 index 0000000..7acb349 --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ + + + + + React + Redux + + + + +
+ + + diff --git a/package.json b/package.json new file mode 100644 index 0000000..34aea9c --- /dev/null +++ b/package.json @@ -0,0 +1,60 @@ +{ + "name": "learn-redux", + "version": "0.0.1", + "description": ":) ", + "scripts": { + "build:webpack": "NODE_ENV=production webpack --config webpack.config.prod.js", + "build": "npm run clean && npm run build:webpack", + "test": "NODE_ENV=production mocha './tests/**/*.spec.js' --compilers js:babel-core/register", + "clean": "rimraf dist", + "start": "node devServer.js", + "tunnel": "browser-sync start --proxy localhost:7700 --tunnel wesbos" + }, + "repository": { + "type": "git", + "url": "https://github.com/wesbos/Learn-Redux.git" + }, + "author": "@sipp11", + "license": "MIT", + "homepage": "https://www.traffy.in.th", + "dependencies": { + "babel-core": "^6.7.7", + "babel-eslint": "^6.0.4", + "babel-loader": "^6.2.4", + "babel-plugin-react-transform": "^2.0.2", + "babel-plugin-transform-object-rest-spread": "^6.6.5", + "babel-plugin-transform-react-display-name": "^6.5.0", + "babel-polyfill": "^6.7.4", + "babel-preset-es2015": "^6.6.0", + "babel-preset-react": "^6.5.0", + "css-loader": "^0.23.1", + "eslint": "^2.9.0", + "eslint-plugin-babel": "^3.2.0", + "eslint-plugin-react": "^5.0.1", + "express": "^4.13.4", + "raven-js": "^2.3.0", + "react": "^15.0.2", + "react-addons-css-transition-group": "^15.0.2", + "react-dom": "^15.0.2", + "react-redux": "^4.4.5", + "react-router": "^2.4.0", + "react-router-redux": "^4.0.4", + "react-transform-catch-errors": "^1.0.2", + "react-transform-hmr": "^1.0.4", + "redbox-react": "^1.2.3", + "redux": "^3.5.2", + "rimraf": "^2.5.2", + "style-loader": "^0.13.1", + "stylus": "^0.54.5", + "stylus-loader": "^2.0.0", + "webpack": "^1.13.0", + "webpack-dev-middleware": "^1.6.1", + "webpack-hot-middleware": "^2.10.0" + }, + "devDependencies": { + "expect": "^1.18.0", + "expect-jsx": "^2.5.1", + "mocha": "^2.4.5", + "react-addons-test-utils": "^15.0.2" + } +} diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..6d5713e --- /dev/null +++ b/readme.md @@ -0,0 +1,13 @@ +# App React Redux + +A simple React + Redux implementation. + +## Running + +First `npm install` to grab all the necessary dependencies. + +Then run `npm start` and open in your browser. + +## Production Build + +Run `npm build` to create a distro folder and a bundle.js file. diff --git a/webpack.config.dev.js b/webpack.config.dev.js new file mode 100644 index 0000000..e88ee52 --- /dev/null +++ b/webpack.config.dev.js @@ -0,0 +1,35 @@ +var path = require('path'); +var webpack = require('webpack'); + +module.exports = { + devtool: 'source-map', + entry: [ + 'webpack-hot-middleware/client', + './client/app' + ], + output: { + path: path.join(__dirname, 'dist'), + filename: 'bundle.js', + publicPath: '/static/' + }, + plugins: [ + new webpack.HotModuleReplacementPlugin(), + new webpack.NoErrorsPlugin() + ], + module: { + loaders: [ + // js + { + test: /\.js$/, + loaders: ['babel'], + include: path.join(__dirname, 'client') + }, + // CSS + { + test: /\.styl$/, + include: path.join(__dirname, 'client'), + loader: 'style-loader!css-loader!stylus-loader' + } + ] + } +}; diff --git a/webpack.config.prod.js b/webpack.config.prod.js new file mode 100644 index 0000000..9cb024c --- /dev/null +++ b/webpack.config.prod.js @@ -0,0 +1,44 @@ +var path = require('path'); +var webpack = require('webpack'); + +module.exports = { + devtool: 'source-map', + entry: [ + + './client/app' + ], + output: { + path: path.join(__dirname, 'dist'), + filename: 'bundle.js', + publicPath: '/static/' + }, + plugins: [ + new webpack.optimize.OccurenceOrderPlugin(), + new webpack.DefinePlugin({ + 'process.env': { + 'NODE_ENV': "'production'" + } + }), + new webpack.optimize.UglifyJsPlugin({ + compressor: { + warnings: false + } + }) + ], + module: { + loaders: [ + // js + { + test: /\.js$/, + loaders: ['babel'], + include: path.join(__dirname, 'client') + }, + // CSS + { + test: /\.styl$/, + include: path.join(__dirname, 'client'), + loader: 'style-loader!css-loader!stylus-loader' + } + ] + } +};