wip Pup 1.0.0

This commit is contained in:
cleverbeagle 2017-05-23 20:05:46 -05:00
commit cdc15f019d
48 changed files with 1100 additions and 0 deletions

View file

@ -0,0 +1,22 @@
import React, { PropTypes } from 'react';
import { Route, Redirect } from 'react-router-dom';
const Authenticated = ({ loggingIn, authenticated, component, ...rest }) => (
<Route
{...rest}
render={(props) => {
if (loggingIn) return <div />;
return authenticated ?
(React.createElement(component, { ...props, loggingIn, authenticated })) :
(<Redirect to="/login" />);
}}
/>
);
Authenticated.propTypes = {
loggingIn: PropTypes.bool.isRequired,
authenticated: PropTypes.bool.isRequired,
component: PropTypes.func.isRequired,
};
export default Authenticated;

View file

@ -0,0 +1,30 @@
import React from 'react';
import PropTypes from 'prop-types';
import { LinkContainer } from 'react-router-bootstrap';
import { Nav, NavItem, NavDropdown, MenuItem } from 'react-bootstrap';
import { Meteor } from 'meteor/meteor';
const AuthenticatedNavigation = ({ name }) => (
<div>
<Nav>
<LinkContainer to="/documents">
<NavItem eventKey={1} href="/documents">Documents</NavItem>
</LinkContainer>
</Nav>
<Nav pullRight>
<NavDropdown eventKey={2} title={name} id="user-nav-dropdown">
<LinkContainer to="/profile">
<NavItem eventKey={2.1} href="/profile">Profile</NavItem>
</LinkContainer>
<MenuItem divider />
<MenuItem eventKey={2.2} onClick={() => Meteor.logout()}>Logout</MenuItem>
</NavDropdown>
</Nav>
</div>
);
AuthenticatedNavigation.propTypes = {
name: PropTypes.string.isRequired,
};
export default AuthenticatedNavigation;

View file

@ -0,0 +1,16 @@
import React from 'react';
import PropTypes from 'prop-types';
import './InputHint.scss';
const InputHint = ({ children }) => (
<div className="InputHint">
{children}
</div>
);
InputHint.propTypes = {
children: PropTypes.node.isRequired,
};
export default InputHint;

View file

@ -0,0 +1,9 @@
@import '../../stylesheets/colors';
.InputHint {
display: block;
margin-top: 8px;
font-style: italic;
color: $gray-light;
font-size: 13px;
}

View file

@ -0,0 +1,33 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Navbar } from 'react-bootstrap';
import { Link } from 'react-router-dom';
import PublicNavigation from '../PublicNavigation/PublicNavigation';
import AuthenticatedNavigation from '../AuthenticatedNavigation/AuthenticatedNavigation';
import './Navigation.scss';
const Navigation = ({ authenticated, name }) => (
<Navbar>
<Navbar.Header>
<Navbar.Brand>
<Link to="/">Pup</Link>
</Navbar.Brand>
<Navbar.Toggle />
</Navbar.Header>
<Navbar.Collapse>
{!authenticated ? <PublicNavigation /> : <AuthenticatedNavigation name={name} />}
</Navbar.Collapse>
</Navbar>
);
Navigation.defaultProps = {
name: PropTypes.string,
};
Navigation.propTypes = {
authenticated: PropTypes.bool.isRequired,
name: PropTypes.string,
};
export default Navigation;

View file

@ -0,0 +1,6 @@
.navbar {
border-radius: 0;
border-left: none;
border-right: none;
border-top: none;
}

View file

@ -0,0 +1,63 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Meteor } from 'meteor/meteor';
import { Bert } from 'meteor/themeteorchef:bert';
import './OAuthLoginButton.scss';
const handleLogin = (service, options, callback) => {
const defaultOptions = {
facebook: {
requestPermissions: ['email'],
loginStyle: 'redirect',
},
google: {
requestPermissions: ['email'],
requestOfflineToken: true,
loginStyle: 'redirect',
},
github: {
requestPermissions: ['user:email'],
loginStyle: 'redirect',
},
}[service];
const defaultCallback = (error) => {
if (error) Bert.alert(error.reason, 'danger');
};
return {
facebook: Meteor.loginWithFacebook,
google: Meteor.loginWithGoogle,
github: Meteor.loginWithGithub,
}[service](options || defaultOptions, callback || defaultCallback);
};
const serviceLabel = {
facebook: <span><i className="fa fa-facebook" /> Log In with Facebook</span>,
google: <span><i className="fa fa-google" /> Log In with Google</span>,
github: <span><i className="fa fa-github" /> Log In with GitHub</span>,
};
const OAuthLoginButton = ({ service, options, callback }) => (
<button
className={`OAuthLoginButton OAuthLoginButton-${service}`}
type="button"
onClick={() => handleLogin(service, options, callback)}
>
{serviceLabel[service]}
</button>
);
OAuthLoginButton.defaultProps = {
options: PropTypes.object,
callback: PropTypes.func,
};
OAuthLoginButton.propTypes = {
service: PropTypes.string.isRequired,
options: PropTypes.object, // eslint-disable-line react/forbid-prop-types
callback: PropTypes.func,
};
export default OAuthLoginButton;

View file

@ -0,0 +1,52 @@
@import '../../stylesheets/colors';
.OAuthLoginButton {
display: block;
width: 100%;
padding: 10px 15px;
border: none;
background: $gray-lighter;
border-radius: 3px;
i {
margin-right: 3px;
font-size: 18px;
position: relative;
top: 1px;
}
&.OAuthLoginButton-facebook {
background: $facebook;
color: #fff;
&:hover { background: darken($facebook, 5%); }
}
&.OAuthLoginButton-google {
background: $google;
color: #fff;
&:hover { background: darken($google, 5%); }
}
&.OAuthLoginButton-github {
background: $github;
color: #fff;
&:hover { background: darken($github, 5%); }
}
&:active {
position: relative;
top: 1px;
}
&:active,
&:focus {
outline: 0;
}
}
.OAuthLoginButton + .OAuthLoginButton {
margin-top: 10px;
}

View file

@ -0,0 +1,22 @@
import React, { PropTypes } from 'react';
import { Route, Redirect } from 'react-router-dom';
const Public = ({ loggingIn, authenticated, component, ...rest }) => (
<Route
{...rest}
render={(props) => {
if (loggingIn) return <div />;
return !authenticated ?
(React.createElement(component, { ...props, loggingIn, authenticated })) :
(<Redirect to="/documents" />);
}}
/>
);
Public.propTypes = {
loggingIn: PropTypes.bool.isRequired,
authenticated: PropTypes.bool.isRequired,
component: PropTypes.func.isRequired,
};
export default Public;

View file

@ -0,0 +1,16 @@
import React from 'react';
import { LinkContainer } from 'react-router-bootstrap';
import { Nav, NavItem } from 'react-bootstrap';
const PublicNavigation = () => (
<Nav pullRight>
<LinkContainer to="/signup">
<NavItem eventKey={1} href="/signup">Sign Up</NavItem>
</LinkContainer>
<LinkContainer to="/login">
<NavItem eventKey={2} href="/login">Log In</NavItem>
</LinkContainer>
</Nav>
);
export default PublicNavigation;