Compare commits

...

2 Commits
gulp ... master

  1. 3
      css/_colors.styl
  2. 9
      css/_normalize.styl
  3. 25
      css/_typography.styl
  4. 292
      css/style.styl
  5. 111
      gulpfile.js
  6. 2
      index.html
  7. 11
      package.json
  8. 1
      src/app.jsx
  9. 0
      src/components/AuthenticatedApp.js
  10. 0
      src/components/AuthenticatedComponent.js
  11. 0
      src/components/Home.js
  12. 101
      src/components/Login.js
  13. 44
      src/components/Login.jsx
  14. 0
      src/components/Quote.js
  15. 0
      src/components/Signup.js
  16. 3
      src/constants/LoginConstants.js
  17. 13
      src/services/AuthService.js

3
css/_colors.styl

@ -0,0 +1,3 @@
orange = #F5A623
red = #d12028
green = #2DC22D

9
css/_normalize.styl vendored

@ -0,0 +1,9 @@
// CSS Normalize
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], 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
.clearfix:after {visibility: hidden; display: block; font-size: 0; content: " "; clear: both; height: 0; }
// Sane border box
* { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; }

25
css/_typography.styl

@ -0,0 +1,25 @@
html
font-size 62.5%
body
background #D4D4D4
-webkit-font-smoothing antialiased
-moz-osx-font-smoothing grayscale
font-family 'Open Sans', sans-serif
font-size 2rem
h1
text-align center
font-weight normal
margin 0
h2,h3,h4,h5,h6
font-weight normal
h2
text-align center
margin-top 0
margin-bottom 2rem
h3
font-size 3rem

292
css/style.styl

@ -0,0 +1,292 @@
// Import all partials
@require './_*.styl'
header.top
text-align center
h1
font-size 14.4rem
line-height 0.7 // this font has a wacky baseline
display flex
justify-content: center;
// This is a bunch of goofy CSS to make the logo look decent
.ofThe
display flex
font-size 3rem
color orange
justify-content: center;
align-items: center;
background url('images/anchor.svg') center no-repeat;
background-size cover
padding 0 1rem
.of
padding-right 2rem
position relative
right -0.5rem
h3
margin 0
font-size 2rem
color orange
position relative
display inline-block
span
background white
position relative
z-index 2
padding-left 1rem
padding-right 1rem
&:before, &:after
display block
z-index 1
background black
position absolute
width 130%
height 1px
content ''
top 5px
margin-left -15%
&:after
top auto
bottom 7px
.catch-of-the-day
display flex
height 90vh
max-width:1500px
margin 0 auto
margin-top 5vh
perspective: 1000;
transform-style preserve-3d
& > *
flex 1 4 auto
padding 2rem
border 1rem double lighten(black,10%)
position relative
background white
transition all 0.3s
box-shadow 0px 5px 5px rgba(0,0,0,0.1)
overflow scroll
&:first-child
flex-shrink 1 // take 4x the extra room
flex-basis 50%
transform translateX(50%) rotateY(6deg) translateX(-50%)
&:nth-child(2)
transform translateX(-50%) rotateY(-14deg) translateX(50%)
border-left 0
border-right 0
min-width 300px
&:last-child
flex-shrink 1 // take 4x the extra room
flex-basis 50%
transform translateX(-50%) rotateY(10deg) translateX(50%) scale(1.08) translateX(24px)
// Folding Transforms
// Take off folding when not checked
input#fold:not(:checked) ~ #main
.catch-of-the-day > *
transform none
label[for="fold"]
position absolute
top 1rem
left 1rem
text-transform uppercase
font-size 1.3rem
background black
color white
border 2px solid black
cursor pointer
padding 0.5rem 1rem
input#fold
display none
&:checked + label
background white
color black
ul
list-style none
margin 0
padding 0
ul.order
li
border-bottom 1px solid black
padding 2rem 0
display flex
font-size 1.4rem
justify-content space-between
align-items center
&:hover
// padding 1rem 0
button
display inline
button
border 0
display none
line-height 1
padding 0
&.total
font-weight 600
border-bottom 3px solid black
border-top 3px double black
&.unavailable
text-decoration line-through
background lighten(red, 80%)
.price
font-size 1.2rem
span.count
position relative
overflow hidden
float left // only works if it's floated?!
span
display inline-block
// transition all 0.5s
.order-title
text-align center
.fish-edit
margin-bottom 20px
border 2px solid black
overflow hidden
display flex
flex-wrap wrap
input, textarea, select
width 33.33%
padding 10px
line-height 1
font-size 1.2rem
border 0
border-bottom 1px solid black
border-right 1px solid black
appearance none
border-radius 0
background white
&:focus
outline 0
background lighten(orange, 85%)
textarea
width 100%
input:last-of-type
width 100%
button
width 100%
border 0
// Menu Styles
.list-of-fish
border-top 2px solid black
border-bottom 1px solid black
padding-top 5px
margin-top 2rem
transform translateZ(0);
.menu-fish
border-bottom 2px solid black
border-top 1px solid black
padding-bottom 2rem
padding-top 2rem
margin-bottom 5px
clear both
overflow hidden
p
margin 0
font-size 1.8rem
.fish-name
margin 0
display flex
justify-content space-between
align-items center
.price
font-size 1.4rem
// color orange
justify-content flex-end
// font-family 'Open Sans Condensed'
img
float left
width 150px
margin-right 1rem
button, input[type=submit]
text-transform uppercase
background none
border 1px solid black
font-weight 600
font-size 1.5rem
font-family 'Open Sans'
transition all 0.2s
position relative
z-index 2
&[disabled]
color red
background white
border-color red
transform rotate(-10deg) scale(2) translateX(50%) translateY(-50%)
&:hover
color red
cursor not-allowed
&:after
display none
&:after
content ''
z-index -1
display block
background black
position absolute
width 100%
height 0%
left 0
top 0
transition all 0.2s
&:hover, &:focus
color white
outline 0
&:after
height 100%
// variants
&.warning
&:after
background red
&.success
&:after
background green
&.github, &.facebook, &.twitter
border 0
display block
margin-bottom 2rem
width 100%
color white
padding 2rem
&.github
background #82D465
&:after
background darken(#82D465, 20%)
&.facebook
background #3864A3
&:after
background darken(#3864A3, 20%)
&.twitter
background #5EA9DD
&:after
background darken(#5EA9DD, 20%)
// Store Selector
.store-selector
background white
max-width 500px
margin 50px auto
padding 2rem
border 2px solid black
input
width 100%
&[type="text"]
text-align center
font-size 3rem

111
gulpfile.js

@ -0,0 +1,111 @@
var source = require('vinyl-source-stream');
var gulp = require('gulp');
var gutil = require('gulp-util');
var browserify = require('browserify');
var babelify = require('babelify');
var watchify = require('watchify');
var notify = require('gulp-notify');
var stylus = require('gulp-stylus');
var autoprefixer = require('gulp-autoprefixer');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
var buffer = require('vinyl-buffer');
var browserSync = require('browser-sync');
var reload = browserSync.reload;
var historyApiFallback = require('connect-history-api-fallback')
/*
Styles Task
*/
gulp.task('styles',function() {
// move over fonts
gulp.src('css/fonts/**.*')
.pipe(gulp.dest('build/css/fonts'))
// Compiles CSS
gulp.src('css/style.styl')
.pipe(stylus())
.pipe(autoprefixer())
.pipe(gulp.dest('./build/css/'))
.pipe(reload({stream:true}))
});
/*
Images
*/
gulp.task('images',function(){
gulp.src('css/images/**')
.pipe(gulp.dest('./build/css/images'))
});
/*
Browser Sync
*/
gulp.task('browser-sync', function() {
browserSync({
// we need to disable clicks and forms for when we test multiple rooms
server : {},
middleware : [ historyApiFallback() ],
ghostMode: false
});
});
function handleErrors() {
var args = Array.prototype.slice.call(arguments);
notify.onError({
title: 'Compile Error',
message: '<%= error.message %>'
}).apply(this, args);
this.emit('end'); // Keep gulp from hanging on this task
}
function buildScript(file, watch) {
var props = {
entries: ['./src/' + file],
debug : true,
transform: [babelify.configure({ stage : 0 })],
cache: {}, packageCache: {}, fullPaths: true // Requirement of watchify
};
// watchify() if watch requested, otherwise run browserify() once
var bundler = watch ? watchify(browserify(props)) : browserify(props);
function rebundle() {
var stream = bundler.bundle();
return stream
.on('error', handleErrors)
.pipe(source(file))
.pipe(rename('build.js'))
.pipe(gulp.dest('./build/'))
// If you also want to uglify it
// .pipe(buffer())
// .pipe(uglify())
// .pipe(rename('app.min.js'))
// .pipe(gulp.dest('./build'))
.pipe(reload({stream:true}))
}
// listen for an update and run rebundle
bundler.on('update', function() {
rebundle();
gutil.log('Rebundle...');
});
// run it once the first time buildScript is called
return rebundle();
}
gulp.task('scripts', function() {
return buildScript('app.jsx', false); // this will run once because we set watch to false
});
// run 'scripts' task first, then watch for future changes
gulp.task('default', ['images','styles','scripts','browser-sync'], function() {
gulp.watch('css/**/*', ['styles']); // gulp watch for stylus changes
return buildScript('app.jsx', true); // browserify watch for JS changes
});

2
index.html

@ -3,12 +3,12 @@
<head>
<title>React Browserify SPA seed</title>
<link rel="stylesheet" type="text/css" href="build/build.css">
<link rel="stylesheet" href="/build/css/style.css">
</head>
<body>
<!-- content section -->
<section id="content"></section>
<!-- Initialize SPA -->
<script type="text/javascript" src="build/build.js"></script>
</body>
</html>

11
package.json

@ -48,13 +48,24 @@
"browser-sync": "^2.1.6",
"browserify": "^8.0.3",
"clean-css": "^3.1.9",
"connect-history-api-fallback": "^1.1.0",
"eslint": "^0.14.1",
"gulp": "^3.9.0",
"gulp-autoprefixer": "^3.1.0",
"gulp-notify": "^2.2.0",
"gulp-rename": "^1.2.2",
"gulp-stylus": "^2.1.0",
"gulp-uglify": "^1.5.1",
"gulp-util": "^3.0.7",
"nodemon": "^1.5.0",
"reactify": "^1.1.1",
"rework": "^1.0.1",
"rework-npm": "^1.0.0",
"rework-npm-cli": "^0.1.1",
"serve": "^1.4.0",
"uglify-js": "^2.4.15",
"vinyl-buffer": "^1.0.0",
"vinyl-source-stream": "^1.1.0",
"watchify": "^2.1.1"
}
}

1
src/app.jsx

@ -28,4 +28,3 @@ if (jwt) {
router.run(function (Handler) {
React.render(<Handler />, document.getElementById('content'));
});

0
src/components/AuthenticatedApp.jsx → src/components/AuthenticatedApp.js

0
src/components/AuthenticatedComponent.jsx → src/components/AuthenticatedComponent.js

0
src/components/Home.jsx → src/components/Home.js

101
src/components/Login.js

@ -0,0 +1,101 @@
import React from 'react/addons';
import ReactMixin from 'react-mixin';
import Auth from '../services/AuthService'
export default class Login extends React.Component {
constructor() {
super()
this.state = {
user: '',
password: ''
};
}
login(e) {
e.preventDefault();
Auth.login(this.state.user, this.state.password)
.catch(function(err) {
alert("There's an error logging in");
console.log("Error logging in", err);
});
}
render() {
return (
<div className="login jumbotron center-block">
{/*
<h1>Login</h1>
<form role="form">
<div className="form-group">
<label htmlFor="username">Username</label>
<input type="text" valueLink={this.linkState('user')} className="form-control" id="username" placeholder="Username" />
</div>
<div className="form-group">
<label htmlFor="password">Password</label>
<input type="password" valueLink={this.linkState('password')} className="form-control" id="password" ref="password" placeholder="Password" />
</div>
<button type="submit" className="btn btn-default" onClick={this.login.bind(this)}>Submit</button>
</form>
*/}
<a href="#" className="fb-login-button" data-max-rows="1" data-size="large" onClick={this.handleClickFb.bind(this)}>FB Login</a>
</div>
);
}
componentDidMount() {
window.fbAsyncInit = function() {
FB.init({
appId : '147935535403714',
xfbml : true,
version : 'v2.5'
});
FB.getLoginStatus(function(response) {
this.statusChangeCallback(response);
}.bind(this))
}.bind(this)
}
componentWillMount() {
(function(d, s, id){
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {return;}
js = d.createElement(s); js.id = id;
js.src = '//connect.facebook.net/en_US/sdk.js';
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
}
statusChangeCallback(response) {
if (response.status === 'connected') {
var access_token = response.authResponse.accessToken;
Auth.socialLogin('facebook', access_token);
// console.log(access_token);
// FB.api('/me', { locale: 'en_US', fields: 'first_name, email, picture' },
// function(response) {
// console.log(response);
// Auth.socialLogin('facebook', access_token, response.email, response.first_name);
// }
// );
} else if (response.status === 'not_authorized') {
console.log('not not_authorized');
} else {
console.log('not logged into facebook');
}
}
checkLoginState() {
FB.getLoginStatus((response) => {
this.statusChangeCallback(response);
}.bind(this))
}
handleClickFb() {
FB.login((response) => {
this.statusChangeCallback(response);
}, {scope: 'email', return_scopes: true});
}
}
ReactMixin(Login.prototype, React.addons.LinkedStateMixin);

44
src/components/Login.jsx

@ -1,44 +0,0 @@
import React from 'react/addons';
import ReactMixin from 'react-mixin';
import Auth from '../services/AuthService'
export default class Login extends React.Component {
constructor() {
super()
this.state = {
user: '',
password: ''
};
}
login(e) {
e.preventDefault();
Auth.login(this.state.user, this.state.password)
.catch(function(err) {
alert("There's an error logging in");
console.log("Error logging in", err);
});
}
render() {
return (
<div className="login jumbotron center-block">
<h1>Login</h1>
<form role="form">
<div className="form-group">
<label htmlFor="username">Username</label>
<input type="text" valueLink={this.linkState('user')} className="form-control" id="username" placeholder="Username" />
</div>
<div className="form-group">
<label htmlFor="password">Password</label>
<input type="password" valueLink={this.linkState('password')} className="form-control" id="password" ref="password" placeholder="Password" />
</div>
<button type="submit" className="btn btn-default" onClick={this.login.bind(this)}>Submit</button>
</form>
</div>
);
}
}
ReactMixin(Login.prototype, React.addons.LinkedStateMixin);

0
src/components/Quote.jsx → src/components/Quote.js

0
src/components/Signup.jsx → src/components/Signup.js

3
src/constants/LoginConstants.js

@ -2,7 +2,8 @@ var BASE_URL = 'http://rocket.dev/';
export default {
BASE_URL: BASE_URL,
LOGIN_URL: BASE_URL + 'api-token-auth/',
SIGNUP_URL: BASE_URL + 'users',
SOCIAL_LOGIN_URL: BASE_URL + 'rest-auth/',
SIGNUP_URL: BASE_URL + 'user/',
LOGIN_USER: 'LOGIN_USER',
LOGOUT_USER: 'LOGOUT_USER'
}

13
src/services/AuthService.js

@ -1,6 +1,6 @@
import request from 'reqwest';
import when from 'when';
import {LOGIN_URL, SIGNUP_URL} from '../constants/LoginConstants';
import {LOGIN_URL, SIGNUP_URL, SOCIAL_LOGIN_URL} from '../constants/LoginConstants';
import LoginActions from '../actions/LoginActions';
class AuthService {
@ -17,6 +17,17 @@ class AuthService {
})));
}
socialLogin(provider, token) {
return this.handleAuth(when(request({
url: SOCIAL_LOGIN_URL + provider + "/",
method: 'POST',
crossOrigin: true,
data: {
access_token: token
}
})));
}
logout() {
LoginActions.logoutUser();
}

Loading…
Cancel
Save