From 433355bfde18c21b98baade7a7cc795129e282f6 Mon Sep 17 00:00:00 2001 From: Javi Jimenez Villar Date: Thu, 28 May 2015 17:20:28 +0200 Subject: [PATCH] First use of React --- .gitignore | 29 +--- bower.json | 8 + dist/index.html | 23 +++ gulpfile.coffee | 80 ++++++++++ package.json | 32 ++++ source/app.cjsx | 41 ++++++ source/components/header.cjsx | 38 +++++ source/components/navigation.cjsx | 32 ++++ source/models/session.coffee | 33 +++++ source/modules/constants.coffee | 9 ++ source/screens/console.cjsx | 12 ++ source/screens/session.cjsx | 56 +++++++ source/styles/__constants.styl | 47 ++++++ source/styles/app.styl | 95 ++++++++++++ source/styles/components/header.styl | 6 + source/styles/normalize.styl | 211 +++++++++++++++++++++++++++ source/styles/screens/session.styl | 2 + 17 files changed, 728 insertions(+), 26 deletions(-) create mode 100644 bower.json create mode 100644 dist/index.html create mode 100644 gulpfile.coffee create mode 100644 package.json create mode 100644 source/app.cjsx create mode 100644 source/components/header.cjsx create mode 100644 source/components/navigation.cjsx create mode 100644 source/models/session.coffee create mode 100644 source/modules/constants.coffee create mode 100644 source/screens/console.cjsx create mode 100644 source/screens/session.cjsx create mode 100644 source/styles/__constants.styl create mode 100644 source/styles/app.styl create mode 100644 source/styles/components/header.styl create mode 100644 source/styles/normalize.styl create mode 100644 source/styles/screens/session.styl diff --git a/.gitignore b/.gitignore index 123ae94d..e32b782b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,27 +1,4 @@ -# Logs -logs -*.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 -# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git +bower_components +dist/assets/**/*.css +dist/assets/**/*.js node_modules diff --git a/bower.json b/bower.json new file mode 100644 index 00000000..7040a9a1 --- /dev/null +++ b/bower.json @@ -0,0 +1,8 @@ +{ + "name" : "secrets", + "version" : "0.5.28", + "dependencies" : { + "hamsa" : "*", + "stylmethods" : "*" + } +} diff --git a/dist/index.html b/dist/index.html new file mode 100644 index 00000000..35125e51 --- /dev/null +++ b/dist/index.html @@ -0,0 +1,23 @@ + + + + + Material Console + + + + + + + + + + + + + + + + + + diff --git a/gulpfile.coffee b/gulpfile.coffee new file mode 100644 index 00000000..37d67907 --- /dev/null +++ b/gulpfile.coffee @@ -0,0 +1,80 @@ +"use strict" + +# -- DEPENDENCIES -------------------------------------------------------------- +gulp = require "gulp" +cjsx = require "gulp-cjsx" +concat = require "gulp-concat" +connect = require "gulp-connect" +header = require "gulp-header" +gutil = require "gulp-util" +uglify = require "gulp-uglify" +stylus = require "gulp-stylus" +pkg = require "./package.json" +# -- BROWSERIFY ---------------------------------------------------------------- +browserify = require "browserify" +source = require "vinyl-source-stream" +bundler = browserify "./source/app.cjsx", extensions: [".cjsx", ".coffee"] +bundler.transform require "coffee-reactify" +# -- FILES --------------------------------------------------------------------- +path = + dist : "./dist" + source : [ "source/**/*.cjsx" + "source/**/*.coffee"] + style : [ "bower_components/STYLmethods/vendor.styl" + "source/styles/__constants.styl" + "source/styles/normalize.styl" + "source/styles/app.styl" + "source/styles/components/*.styl" + "source/styles/screens/*.styl"] + dependencies : [ "node_modules/react/dist/react-with-addons.js" + "bower_components/hamsa/dist/hamsa.js"] +# -- BANNER -------------------------------------------------------------------- +banner = [ + "/**" + " * <%= pkg.name %> - <%= pkg.description %>" + " * @version v<%= pkg.version %>" + " * @link <%= pkg.homepage %>" + " * @author <%= pkg.author.name %> (<%= pkg.author.site %>)" + " * @license <%= pkg.license %>" + " */" + "" +].join("\n") +# -- TASKS --------------------------------------------------------------------- +gulp.task "server", -> + connect.server + port : 8000 + livereload: true + root : path.dist + +gulp.task "source", -> + bundler.bundle() + .on "error", gutil.log.bind(gutil, "Browserify Error") + .pipe source "#{pkg.name}.js" + # .pipe uglify mangle: true + .pipe header banner, pkg: pkg + .pipe gulp.dest "#{path.dist}/assets/js" + .pipe connect.reload() + +gulp.task "style", -> + gulp.src path.style + .pipe concat "#{pkg.name}.styl" + .pipe stylus + compress: true + errors : true + .pipe header banner, pkg: pkg + .pipe gulp.dest "#{path.dist}/assets/css" + .pipe connect.reload() + +gulp.task "dependencies", -> + gulp.src path.dependencies + .pipe concat "#{pkg.name}.dependencies.js" + .pipe gulp.dest "#{path.dist}/assets/js" + # .pipe uglify mangle: true + .pipe connect.reload() + +gulp.task "init", ["source", "style", "dependencies"] + +gulp.task "default", -> + gulp.run ["server"] + gulp.watch path.source, ["source"] + gulp.watch path.style, ["style"] diff --git a/package.json b/package.json new file mode 100644 index 00000000..aca3449e --- /dev/null +++ b/package.json @@ -0,0 +1,32 @@ +{ + "name" : "material-console", + "version" : "0.5.28", + "description" : "", + "homepage" : "http://zetapath.com", + "author" : "Zetapath LTD.", + "dependencies": { + "coffee-script" : "*" + }, + "devDependencies": { + "browserify" : "^10.0.0", + "coffee-reactify" : "^3.0.0", + "moment" : "^2.10.2", + "react" : "^0.13.2", + "spa-router" : "^0.5.20", + "vinyl-source-stream" : "^1.1.0", + "gulp" : "*", + "gulp-cjsx" : "*", + "gulp-concat" : "*", + "gulp-connect" : "*", + "gulp-flatten" : "*", + "gulp-header" : "*", + "gulp-stylus" : "*", + "gulp-uglify" : "*", + "gulp-util" : "*", + "gulp-yml" : "*" + }, + "scripts": { + "start" : "gulp", + "postinstall" : "bower install" + } +} diff --git a/source/app.cjsx b/source/app.cjsx new file mode 100644 index 00000000..41e9f01e --- /dev/null +++ b/source/app.cjsx @@ -0,0 +1,41 @@ +"use strict" + +SPArouter = require "spa-router" +# -- Models +Session = require "./models/session" +# -- Screens +ScreenSession = require "./screens/session" +ScreenConsole = require "./screens/console" + +App = React.createClass + + # -- States & Properties + getInitialState: -> + session : null + context : "campaigns" + + # -- Lifecycle + componentWillMount: -> + SPArouter.listen + "/session/:id" : (id) => + @setState session: false, context: id + "/console/:context" : (context) => + @setState session: true, context: context + + # -- Events + onSessionSuccess: (data) -> + @setState session: true + SPArouter.path "console" + + # -- Render + render: -> + + { + if @state.session + + else + + } + + +React.render , document.body diff --git a/source/components/header.cjsx b/source/components/header.cjsx new file mode 100644 index 00000000..226662b1 --- /dev/null +++ b/source/components/header.cjsx @@ -0,0 +1,38 @@ +### +@todo +### + +Navigation = require './navigation' + +module.exports = React.createClass + + # -- States & Properties + propTypes: + title : React.PropTypes.string.required + routes : React.PropTypes.array.required + subroutes : React.PropTypes.array + + getDefaultProps: -> + routes : [] + title : undefined + subroutes : [] + + getInitialState: -> + expanded : @props.expanded + + # -- Lifecycle + componentDidUpdate: (nextProps) -> + @refs.header.getDOMNode().classList.remove "expanded" + + # -- Events + onProfile: (event) -> + event.preventDefault() + @refs.header.getDOMNode().classList.toggle "expanded" + + # -- Render + render: -> +
+ { if @props.routes } + {

{@props.title}

if @props.title } + { if @props.subroutes } +
diff --git a/source/components/navigation.cjsx b/source/components/navigation.cjsx new file mode 100644 index 00000000..51e57bca --- /dev/null +++ b/source/components/navigation.cjsx @@ -0,0 +1,32 @@ +### +@todo +### + +module.exports = React.createClass + + # -- States & Properties + propTypes: + routes : React.PropTypes.array + + getDefaultProps: -> + routes : [] + + # -- Events + onBack: (event) -> + event.preventDefault() + event.stopPropagation() + window.history.back() + + # -- Render + render: -> + diff --git a/source/models/session.coffee b/source/models/session.coffee new file mode 100644 index 00000000..893eaf0d --- /dev/null +++ b/source/models/session.coffee @@ -0,0 +1,33 @@ +### +@todo +### + +storage = require "../modules/storage" + +module.exports = class Session extends Hamsa + + @define + id : type: String + mail : type: String + token : type: String + username : type: String + name : type: String + bio : type: String + image : type: String + wallet : type: Number, default: 0 + + secrets : type: Array + purchases : type: Array + tips : type: Array + + followers : type: Array + following : type: Array + + updated_at : type: Date + created_at : type: Date, default: new Date() + + @update = -> + promise = new Hope.Promise() + @destroyAll() + + @instance = -> @find()[0] diff --git a/source/modules/constants.coffee b/source/modules/constants.coffee new file mode 100644 index 00000000..d01df63c --- /dev/null +++ b/source/modules/constants.coffee @@ -0,0 +1,9 @@ +### +@todo +### + +module.exports = + STORAGE : + SESSION : "material-console-session" + + CONTEXTS = [] diff --git a/source/screens/console.cjsx b/source/screens/console.cjsx new file mode 100644 index 00000000..c109dce4 --- /dev/null +++ b/source/screens/console.cjsx @@ -0,0 +1,12 @@ +### +@todo +### + +Header = require "../components/header" + +module.exports = React.createClass + + render: -> +
+
+
diff --git a/source/screens/session.cjsx b/source/screens/session.cjsx new file mode 100644 index 00000000..923a4e01 --- /dev/null +++ b/source/screens/session.cjsx @@ -0,0 +1,56 @@ +### +@todo +### + +module.exports = React.createClass + + # -- States & Properties + propTypes: + active : React.PropTypes.boolean + context : React.PropTypes.string + onSuccess : React.PropTypes.function + + getInitialState: -> + disabled: false + + # -- Events + onKeyUp: (event) -> + values = @_getFormValues() + @setState disabled: not(values.mail and values.password) + + onSign: (event) -> + event.preventDefault() + button = @refs.button.getDOMNode().classList + button.add "loading" + @props.onSuccess.call @props.onSuccess, token: "1" + + + componentDidMount: -> + setTimeout => + @setState active: true + , 450 + + # -- Render + render: -> + + + # -- Private methods + _getFormValues: -> + mail : @refs.mail.getDOMNode().value.trim() + password : @refs.password.getDOMNode().value.trim() diff --git a/source/styles/__constants.styl b/source/styles/__constants.styl new file mode 100644 index 00000000..1096eb54 --- /dev/null +++ b/source/styles/__constants.styl @@ -0,0 +1,47 @@ +@import url("http://fonts.googleapis.com/css?family=Roboto:500,300,700,400") + +// -- Colors +COLOR = #222222 +BACKGROUND = #ffffff +THEME = #ffc107 + +// -- Fonts +FONT_FAMILY = "Roboto", "Helvetica Neue", "Helvetica", "sans-serif" +FONT_SIZE = 16px +FONT_SIZE_TINY = 80% +FONT_SIZE_SMALL = 90% +FONT_SIZE_NORMAL = 100% +FONT_SIZE_BIG = 120% +FONT_WEIGHT_THIN = normal +FONT_WEIGHT_NORMAL = normal +FONT_WEIGHT_BOLD = bold + +// -- Sizes +UNIT = 4rem +SPACE = (UNIT * 0.29) +MENU_WIDTH = 85vw +HEADER_HEIGHT = 10vh +BUTTON_HEIGHT = (2.5 * SPACE) +BUTTON_HEIGHT = 14vw +BORDER_RADIUS = (SPACE / 2) +UPLOAD_IMAGE_USER = 45vw +H1_SHADOW = (SPACE / 6) (SPACE / 6) rgba(0,0,0,0.2) + +LI_AVATAR_SIZE = (UNIT / 1.2) +LI_HEIGHT = 72px + +// -- Animations +ANIMATION_DURATION = 450ms +ANIMATION_EASE = cubic-bezier(.55,0,.1,1) +ANIMATION_DELAY = (ANIMATION_DURATION / 5) + +delayChild(child, increment) + &:nth-child({child}) + transition-delay ((child + increment) * ANIMATION_DELAY) + +@keyframes LOADING + 0% + transform scale(0.0) + 100% + transform scale(1.0) + opacity: 0 diff --git a/source/styles/app.styl b/source/styles/app.styl new file mode 100644 index 00000000..61da6570 --- /dev/null +++ b/source/styles/app.styl @@ -0,0 +1,95 @@ +body + font-family : FONT_FAMILY + font-size : FONT_SIZE + color : COLOR + background-color : BACKGROUND + + a + color : WHITE + h1 + font-size : (1.75 * FONT_SIZE_NORMAL) + h2 + font-size : (1.5 * FONT_SIZE_NORMAL) + + .scroll + overflow-x : hidden + overflow-y : scroll + -webkit-overflow-scrolling: touch + + .type-01 /*stay*/ + background : url("/assets/img/bear.png") no-repeat + .type-02 /*drink*/ + background : url("/assets/img/dog.png") no-repeat + .type-03 /*eat*/ + background : url("/assets/img/pig.png") no-repeat + .type-04 /*listen*/ + background : url("/assets/img/rabbit.png") no-repeat + .type-05 /*see*/ + background : url("/assets/img/raccoon.png") no-repeat + +// -- ANIMATIONS --------------------------------------------------------------- +@keyframes LOADING + 0% + transform scale(0.0) + 100% + transform scale(1.0) + opacity: 0.1 + +// -- FLEX --------------------------------------------------------------------- +[data-flex] + display-flex() + body& + position : absolute + left : 0 + top : 0 + bottom : 0 + width : 100% + overflow : hidden + +// -- Direction +[data-flex^="horizontal"] + flex-direction row +[data-flex^="vertical"] + flex-direction column + +// -- Size +[data-flex*="grow"] + > *:not([data-column]):not([data-flex-grow]) + flex-grow 1 +[data-flex-grow="min"] + flex-grow 0 +[data-flex-grow="max"] + flex-grow 2 + +// -- Container properties +[data-flex*="wrap"] + flex-wrap wrap +[data-flex*="center"] + justify-content center + align-content center + align-items center +[data-flex-justify="start"] + justify-content flex-start +[data-flex-justify="center"] + justify-content center +[data-flex-justify="end"] + justify-content flex-end +[data-flex-content="start"] + align-content flex-start +[data-flex-content="center"] + align-content center +[data-flex-content="end"] + align-content flex-end +[data-flex-items="center"] + align-items center +[data-flex-items="start"] + align-items flex-start +[data-flex-items="end"] + align-items flex-end + +// -- Children properties +[data-flex-order="first"] + order: -1 + +[data-flex-order="last"] + order: 999999 diff --git a/source/styles/components/header.styl b/source/styles/components/header.styl new file mode 100644 index 00000000..1e6c17d4 --- /dev/null +++ b/source/styles/components/header.styl @@ -0,0 +1,6 @@ +header + position : fixed + height : UNIT + width : 100vw + background-color : THEME + color : WHITE diff --git a/source/styles/normalize.styl b/source/styles/normalize.styl new file mode 100644 index 00000000..325d5396 --- /dev/null +++ b/source/styles/normalize.styl @@ -0,0 +1,211 @@ +// normalize v3.0.2 | MIT License | git.io/normalize + +html + font-family sans-serif + -ms-text-size-adjust 100% + -webkit-text-size-adjust 100% + +body + margin 0 + +article, aside, details, figcaption, figure, footer, header, hgroup, main, menu, +nav, section, summary + display block + +audio, canvas, progress, video + display inline-block + vertical-align baseline + +audio + &:not([controls]) + display none + height 0 + +[hidden], template + display none + +a + background-color transparent + &:active, &:hover + outline 0 + +abbr[title] + border-bottom 1px dotted + +b, strong + font-weight bold + +dfn + font-style italic + +h1 + font-size 2em + margin 0.67em 0 + +mark + background #ff0 + color #000 + +small + font-size 80% + +sub, sup + font-size 75% + line-height 0 + position relative + vertical-align baseline + +sup + top -0.5em + +sub + bottom -0.25em + +img + border 0 + +svg + &:not(:root) + overflow hidden + +figure + margin 1em 40px + +hr + -moz-box-sizing content-box + box-sizing content-box + height 0 + +pre + overflow auto + +code, kbd, pre, samp + font-family monospace, monospace + font-size 1em + +button, input, optgroup, select, textarea + color inherit + font inherit + margin 0 + +button + overflow visible + +button, select + text-transform none + +button, html input[type="button"], input[type="reset"], input[type="submit"] + -webkit-appearance button + cursor pointer + +button[disabled], html input[disabled] + cursor default + +button::-moz-focus-inner, input::-moz-focus-inner + border 0 + padding 0 + +input + line-height normal + +input[type="checkbox"], input[type="radio"] + box-sizing border-box + padding 0 + +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button + height auto + +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 + +fieldset + border 1px solid #c0c0c0 + margin 0 2px + padding 0.35em 0.625em 0.75em + +legend + border 0 + padding 0 + +textarea + overflow auto + +optgroup + font-weight bold + +table + border-collapse collapse + border-spacing 0 + +td, th + padding 0 + + +// -- App ---------------------------------------------------------------------- +a,abbr,address,article,aside,audio,b,blockquote,body,caption,cite,code,dd,del,dfn,dialog,div,dl,dt,em,fieldset,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,hr,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,p,pre,q,samp,section,small,span,strong,sub,sup,table,tbody,td,tfoot,th,thead,time,tr,ul,var,video + border: 0 + margin: 0 + outline: 0 + padding: 0 + +*, *:before, *:after + margin: 0 + padding: 0 + box-sizing(border-box) + +html + position: absolute + height: 100% + width: 100% + margin: 0 + padding: 0 + overflow: hidden + +body + width: 100% + height: 100% + margin: 0 + padding: 0 + -webkit-touch-callout: none + -webkit-user-select: none + -moz-user-select: moz-none + user-select: none + overflow: hidden + + * + -webkit-tap-highlight-color: rgba(255, 255, 255, 0) + +h1, h2, h3, h4, h5, h6, label, p, button, abbr, a + -webkit-font-smoothing: subpixel-antialiased + font-smoothing: subpixel-antialiased + -webkit-text-size-adjust: 100% + -ms-text-size-adjust: 100% + text-size-adjust: 100% + +span + -webkit-font-smoothing: antialiased + font-smoothing: antialiased + +a + text-decoration: none + -webkit-tap-highlight-color: rgba(0,0,0,0) + +::-webkit-scrollbar + width: 0px + height: 0px + +input, button + -webkit-appearance: none + -moz-appearance: none + appearance: none + -webkit-touch-callout: none + -webkit-tap-highlight-color: rgba(255, 255, 255, 0) + outline: none diff --git a/source/styles/screens/session.styl b/source/styles/screens/session.styl new file mode 100644 index 00000000..2a835d76 --- /dev/null +++ b/source/styles/screens/session.styl @@ -0,0 +1,2 @@ +[data-screen="session"] + height : 100vh