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: ->
+
+ Welcome...
+
+ {
+ if @props.context is "login"
+ Dont have an account? Sign Up
+ else
+ You have an account, Sign In
+ }
+ Copyright 2015
+
+
+ # -- 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