From b0270cc98b03582c7eb9eaea2a4bd7f08e143541 Mon Sep 17 00:00:00 2001 From: cleverbeagle Date: Mon, 29 May 2017 22:02:22 -0500 Subject: [PATCH] add oauth flows, profile, logout page, and index page --- .meteor/packages | 18 +- .meteor/release | 2 +- .meteor/versions | 8 +- imports/api/Documents/Documents.js | 2 +- imports/api/OAuth/server/methods.js | 14 ++ imports/api/Users/server/publications.js | 1 + .../email-templates.js} | 0 imports/startup/server/accounts/index.js | 2 + imports/startup/server/accounts/oauth.js | 13 ++ .../startup/server/accounts/on-create-user.js | 7 + imports/startup/server/api.js | 2 + .../components/Authenticated/Authenticated.js | 2 +- .../DocumentEditor/DocumentEditor.js | 2 +- .../ui/components/Navigation/Navigation.js | 7 +- .../OAuthLoginButton/OAuthLoginButton.js | 36 ++-- .../OAuthLoginButtons/OAuthLoginButtons.js | 42 +++++ .../OAuthLoginButtons/OAuthLoginButtons.scss} | 18 +- imports/ui/layouts/App/App.js | 11 +- imports/ui/pages/Documents/Documents.js | 1 + imports/ui/pages/Index/Index.js | 19 ++- imports/ui/pages/Index/Index.scss | 58 +++++++ imports/ui/pages/Login/Login.js | 17 +- imports/ui/pages/Login/Login.scss | 21 --- imports/ui/pages/Logout/Logout.js | 23 +++ imports/ui/pages/Logout/Logout.scss | 57 +++++++ imports/ui/pages/Profile/Profile.js | 154 +++++++++++------- imports/ui/pages/Profile/Profile.scss | 39 +++++ imports/ui/pages/Signup/Signup.js | 17 +- imports/ui/stylesheets/_colors.scss | 5 + package.json | 1 + settings-development.json | 12 +- 31 files changed, 449 insertions(+), 162 deletions(-) create mode 100644 imports/api/OAuth/server/methods.js rename imports/startup/server/{accounts.js => accounts/email-templates.js} (100%) create mode 100644 imports/startup/server/accounts/index.js create mode 100644 imports/startup/server/accounts/oauth.js create mode 100644 imports/startup/server/accounts/on-create-user.js create mode 100644 imports/ui/components/OAuthLoginButtons/OAuthLoginButtons.js rename imports/ui/{pages/Signup/Signup.scss => components/OAuthLoginButtons/OAuthLoginButtons.scss} (51%) delete mode 100644 imports/ui/pages/Login/Login.scss create mode 100644 imports/ui/pages/Logout/Logout.js create mode 100644 imports/ui/pages/Logout/Logout.scss create mode 100644 imports/ui/pages/Profile/Profile.scss diff --git a/.meteor/packages b/.meteor/packages index 2921f6c..628ed8d 100644 --- a/.meteor/packages +++ b/.meteor/packages @@ -21,14 +21,14 @@ react-meteor-data alanning:roles fourseven:scss twbs:bootstrap -accounts-base -accounts-password -service-configuration -accounts-facebook -accounts-github -accounts-google +accounts-base@1.2.17 +accounts-password@1.3.6 +service-configuration@1.0.11 +accounts-facebook@1.1.1 +accounts-github@1.2.1 +accounts-google@1.1.2 themeteorchef:bert fortawesome:fontawesome -aldeed:collection2-core -audit-argument-checks -ddp-rate-limiter +aldeed:collection2-core@2.0.0 +audit-argument-checks@1.0.7 +ddp-rate-limiter@1.0.7 diff --git a/.meteor/release b/.meteor/release index fb6f3bc..01490b6 100644 --- a/.meteor/release +++ b/.meteor/release @@ -1 +1 @@ -METEOR@1.4.4.2 +METEOR@1.4.4.3 diff --git a/.meteor/versions b/.meteor/versions index e690fd9..d151e1f 100644 --- a/.meteor/versions +++ b/.meteor/versions @@ -5,8 +5,7 @@ accounts-google@1.1.2 accounts-oauth@1.1.15 accounts-password@1.3.6 alanning:roles@1.2.16 -aldeed:collection2-core@1.2.0 -aldeed:simple-schema@1.5.3 +aldeed:collection2-core@2.0.1 allow-deny@1.0.5 audit-argument-checks@1.0.7 autoupdate@1.3.12 @@ -36,7 +35,7 @@ email@1.2.1 es5-shim@4.6.15 facebook-oauth@1.3.0 fastclick@1.0.13 -fortawesome:fontawesome@4.4.0_1 +fortawesome:fontawesome@4.7.0 fourseven:scss@4.5.0 geojson-utils@1.0.10 github-oauth@1.2.0 @@ -51,7 +50,6 @@ launch-screen@1.1.1 livedata@1.0.18 localstorage@1.0.12 logging@1.1.17 -mdg:validation-error@0.2.0 meteor@1.6.1 meteor-base@1.0.4 minifier-css@1.2.16 @@ -93,7 +91,7 @@ templating-compiler@1.3.2 templating-runtime@1.3.2 templating-tools@1.1.2 themeteorchef:bert@2.1.2 -tmeasday:check-npm-versions@0.2.0 +tmeasday:check-npm-versions@0.3.1 tracker@1.1.3 twbs:bootstrap@3.3.6 ui@1.0.13 diff --git a/imports/api/Documents/Documents.js b/imports/api/Documents/Documents.js index f428830..4974aab 100644 --- a/imports/api/Documents/Documents.js +++ b/imports/api/Documents/Documents.js @@ -46,6 +46,6 @@ Documents.schema = new SimpleSchema({ }, }); -// Documents.attachSchema(Documents.schema); +Documents.attachSchema(Documents.schema); export default Documents; diff --git a/imports/api/OAuth/server/methods.js b/imports/api/OAuth/server/methods.js new file mode 100644 index 0000000..c3de385 --- /dev/null +++ b/imports/api/OAuth/server/methods.js @@ -0,0 +1,14 @@ +import { Meteor } from 'meteor/meteor'; +import { check } from 'meteor/check'; +import { ServiceConfiguration } from 'meteor/service-configuration'; + +Meteor.methods({ + 'oauth.verifyConfiguration': function oauthVerifyConfiguration(services) { + check(services, Array); + const verifiedServices = []; + services.forEach((service) => { + if (ServiceConfiguration.configurations.findOne({ service })) verifiedServices.push(service); + }); + return verifiedServices.sort(); + }, +}); diff --git a/imports/api/Users/server/publications.js b/imports/api/Users/server/publications.js index 1b0acec..7728b4b 100644 --- a/imports/api/Users/server/publications.js +++ b/imports/api/Users/server/publications.js @@ -5,6 +5,7 @@ Meteor.publish('users.editProfile', function usersProfile() { fields: { emails: 1, profile: 1, + services: 1, }, }); }); diff --git a/imports/startup/server/accounts.js b/imports/startup/server/accounts/email-templates.js similarity index 100% rename from imports/startup/server/accounts.js rename to imports/startup/server/accounts/email-templates.js diff --git a/imports/startup/server/accounts/index.js b/imports/startup/server/accounts/index.js new file mode 100644 index 0000000..c7a0cba --- /dev/null +++ b/imports/startup/server/accounts/index.js @@ -0,0 +1,2 @@ +import './oauth'; +import './email-templates'; diff --git a/imports/startup/server/accounts/oauth.js b/imports/startup/server/accounts/oauth.js new file mode 100644 index 0000000..545519a --- /dev/null +++ b/imports/startup/server/accounts/oauth.js @@ -0,0 +1,13 @@ +import { Meteor } from 'meteor/meteor'; +import { ServiceConfiguration } from 'meteor/service-configuration'; + +const OAuthSettings = Meteor.settings.private.OAuth; + +if (OAuthSettings) { + Object.keys(OAuthSettings).forEach((service) => { + ServiceConfiguration.configurations.upsert( + { service }, + { $set: OAuthSettings[service] }, + ); + }); +} diff --git a/imports/startup/server/accounts/on-create-user.js b/imports/startup/server/accounts/on-create-user.js new file mode 100644 index 0000000..ede5150 --- /dev/null +++ b/imports/startup/server/accounts/on-create-user.js @@ -0,0 +1,7 @@ +import { Accounts } from 'meteor/accounts-base'; + +Accounts.onCreateUser((options, user) => { + const userToCreate = user; + if (options.profile) userToCreate.profile = options.profile; + return userToCreate; +}); diff --git a/imports/startup/server/api.js b/imports/startup/server/api.js index c39fc72..18a93a0 100644 --- a/imports/startup/server/api.js +++ b/imports/startup/server/api.js @@ -1,5 +1,7 @@ import '../../api/Documents/methods'; import '../../api/Documents/server/publications'; +import '../../api/OAuth/server/methods'; + import '../../api/Users/server/methods'; import '../../api/Users/server/publications'; diff --git a/imports/ui/components/Authenticated/Authenticated.js b/imports/ui/components/Authenticated/Authenticated.js index 442d0eb..83dccc3 100644 --- a/imports/ui/components/Authenticated/Authenticated.js +++ b/imports/ui/components/Authenticated/Authenticated.js @@ -8,7 +8,7 @@ const Authenticated = ({ loggingIn, authenticated, component, ...rest }) => ( if (loggingIn) return
; return authenticated ? (React.createElement(component, { ...props, loggingIn, authenticated })) : - (); + (); }} /> ); diff --git a/imports/ui/components/DocumentEditor/DocumentEditor.js b/imports/ui/components/DocumentEditor/DocumentEditor.js index ff66cbd..4a42df7 100644 --- a/imports/ui/components/DocumentEditor/DocumentEditor.js +++ b/imports/ui/components/DocumentEditor/DocumentEditor.js @@ -86,7 +86,7 @@ class DocumentEditor extends React.Component { } DocumentEditor.defaultProps = { - doc: PropTypes.object, + doc: { title: '', body: '' }, }; DocumentEditor.propTypes = { diff --git a/imports/ui/components/Navigation/Navigation.js b/imports/ui/components/Navigation/Navigation.js index 2993b39..ffc3020 100644 --- a/imports/ui/components/Navigation/Navigation.js +++ b/imports/ui/components/Navigation/Navigation.js @@ -7,7 +7,7 @@ import AuthenticatedNavigation from '../AuthenticatedNavigation/AuthenticatedNav import './Navigation.scss'; -const Navigation = ({ authenticated, name }) => ( +const Navigation = props => ( @@ -16,18 +16,17 @@ const Navigation = ({ authenticated, name }) => ( - {!authenticated ? : } + {!props.authenticated ? : } ); Navigation.defaultProps = { - name: PropTypes.string, + name: '', }; Navigation.propTypes = { authenticated: PropTypes.bool.isRequired, - name: PropTypes.string, }; export default Navigation; diff --git a/imports/ui/components/OAuthLoginButton/OAuthLoginButton.js b/imports/ui/components/OAuthLoginButton/OAuthLoginButton.js index b30e90e..24cca9e 100644 --- a/imports/ui/components/OAuthLoginButton/OAuthLoginButton.js +++ b/imports/ui/components/OAuthLoginButton/OAuthLoginButton.js @@ -5,58 +5,54 @@ import { Bert } from 'meteor/themeteorchef:bert'; import './OAuthLoginButton.scss'; -const handleLogin = (service, options, callback) => { - const defaultOptions = { +const handleLogin = (service, callback) => { + const options = { facebook: { requestPermissions: ['email'], - loginStyle: 'redirect', + loginStyle: 'popup', + }, + github: { + requestPermissions: ['user:email'], + loginStyle: 'popup', }, google: { requestPermissions: ['email'], requestOfflineToken: true, - loginStyle: 'redirect', - }, - github: { - requestPermissions: ['user:email'], - loginStyle: 'redirect', + loginStyle: 'popup', }, }[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); + google: Meteor.loginWithGoogle, + }[service](options, callback); }; const serviceLabel = { facebook: Log In with Facebook, - google: Log In with Google, github: Log In with GitHub, + google: Log In with Google, }; -const OAuthLoginButton = ({ service, options, callback }) => ( +const OAuthLoginButton = ({ service, callback }) => ( ); OAuthLoginButton.defaultProps = { - options: PropTypes.object, - callback: PropTypes.func, + callback: (error) => { + if (error) Bert.alert(error.message, 'danger'); + }, }; OAuthLoginButton.propTypes = { service: PropTypes.string.isRequired, - options: PropTypes.object, callback: PropTypes.func, }; diff --git a/imports/ui/components/OAuthLoginButtons/OAuthLoginButtons.js b/imports/ui/components/OAuthLoginButtons/OAuthLoginButtons.js new file mode 100644 index 0000000..60dc857 --- /dev/null +++ b/imports/ui/components/OAuthLoginButtons/OAuthLoginButtons.js @@ -0,0 +1,42 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { Meteor } from 'meteor/meteor'; +import { createContainer } from 'meteor/react-meteor-data'; +import { ReactiveVar } from 'meteor/reactive-var'; +import OAuthLoginButton from '../OAuthLoginButton/OAuthLoginButton'; + +import './OAuthLoginButtons.scss'; + +const OAuthLoginButtons = ({ services, emailMessage }) => (services.length ? ( +
+ {services.map(service => )} + {emailMessage ?

+ {emailMessage.text} +

: ''} +
+) :
); + +OAuthLoginButtons.propTypes = { + services: PropTypes.array.isRequired, + emailMessage: PropTypes.object.isRequired, +}; + +const verificationComplete = new ReactiveVar(false); +const verifiedServices = new ReactiveVar([]); + +export default createContainer(({ services }) => { + if (!verificationComplete.get()) { + Meteor.call('oauth.verifyConfiguration', services, (error, response) => { + if (error) { + console.warn(error); + } else { + verifiedServices.set(response); + verificationComplete.set(true); + } + }); + } + + return { + services: verifiedServices.get(), + }; +}, OAuthLoginButtons); diff --git a/imports/ui/pages/Signup/Signup.scss b/imports/ui/components/OAuthLoginButtons/OAuthLoginButtons.scss similarity index 51% rename from imports/ui/pages/Signup/Signup.scss rename to imports/ui/components/OAuthLoginButtons/OAuthLoginButtons.scss index d3e9bac..673e347 100644 --- a/imports/ui/pages/Signup/Signup.scss +++ b/imports/ui/components/OAuthLoginButtons/OAuthLoginButtons.scss @@ -1,20 +1,20 @@ @import '../../stylesheets/colors'; -.Signup { - form { - position: relative; - border-top: 1px solid $gray-lighter; - margin-top: 15px; - padding-top: 25px; +.OAuthLoginButtons { + margin-bottom: 25px; - .SignupWithEmail { + &.WithEmailMessage { + position: relative; + border-bottom: 1px solid $gray-lighter; + padding-bottom: 30px; + + .EmailMessage { display: inline-block; background: #fff; padding: 0 10px; position: absolute; - top: -12px; + bottom: -19px; left: 50%; - margin-left: -106px; } } } diff --git a/imports/ui/layouts/App/App.js b/imports/ui/layouts/App/App.js index 014d9b4..0d189d9 100644 --- a/imports/ui/layouts/App/App.js +++ b/imports/ui/layouts/App/App.js @@ -15,6 +15,7 @@ import ViewDocument from '../../pages/ViewDocument/ViewDocument'; import EditDocument from '../../pages/EditDocument/EditDocument'; import Signup from '../../pages/Signup/Signup'; import Login from '../../pages/Login/Login'; +import Logout from '../../pages/Logout/Logout'; import RecoverPassword from '../../pages/RecoverPassword/RecoverPassword'; import ResetPassword from '../../pages/ResetPassword/ResetPassword'; import Profile from '../../pages/Profile/Profile'; @@ -34,6 +35,7 @@ const App = props => ( + @@ -47,17 +49,24 @@ App.propTypes = { loading: PropTypes.bool.isRequired, }; +const getUserName = name => ({ + string: name, + object: `${name.first} ${name.last}`, +}[typeof name]); + export default createContainer(() => { const loggingIn = Meteor.loggingIn(); const user = Meteor.user(); const userId = Meteor.userId(); const loading = !Roles.subscription.ready(); + const name = user && user.profile && user.profile.name && getUserName(user.profile.name); + const emailAddress = user && user.emails && user.emails[0].address; return { loading, loggingIn, authenticated: !loggingIn && !!userId, - name: user && user.profile ? `${user.profile.name.first} ${user.profile.name.last}` : '', + name: name || emailAddress, roles: !loading && Roles.getRolesForUser(userId), }; }, App); diff --git a/imports/ui/pages/Documents/Documents.js b/imports/ui/pages/Documents/Documents.js index 1abffa6..e084e58 100644 --- a/imports/ui/pages/Documents/Documents.js +++ b/imports/ui/pages/Documents/Documents.js @@ -73,6 +73,7 @@ Documents.propTypes = { export default createContainer(() => { const subscription = Meteor.subscribe('documents'); + console.log(DocumentsCollection.find().fetch()); return { loading: !subscription.ready(), documents: DocumentsCollection.find().fetch(), diff --git a/imports/ui/pages/Index/Index.js b/imports/ui/pages/Index/Index.js index 212b840..7db421b 100644 --- a/imports/ui/pages/Index/Index.js +++ b/imports/ui/pages/Index/Index.js @@ -1,17 +1,20 @@ import React from 'react'; -import { Jumbotron } from 'react-bootstrap'; +import { Button } from 'react-bootstrap'; import './Index.scss'; const Index = () => (
- - Clever Beagle -

Need help building your app? Check out our mentorship service.

-
+ Clever Beagle +

Pup

+

A boilerplate for products.

+
+ + +
); diff --git a/imports/ui/pages/Index/Index.scss b/imports/ui/pages/Index/Index.scss index e69de29..218d2ab 100644 --- a/imports/ui/pages/Index/Index.scss +++ b/imports/ui/pages/Index/Index.scss @@ -0,0 +1,58 @@ +@import '../../stylesheets/mixins'; +@import '../../stylesheets/colors'; + +.Index { + padding: 20px; + background: $cb-blue; + text-align: center; + border-radius: 3px; + color: #fff; + + img { + width: 100px; + height: auto; + } + + h1 { + font-size: 28px; + } + + p { + font-size: 18px; + color: lighten($cb-blue, 25%); + } + + > div { + display: inline-block; + margin: 10px 0 0; + + .btn:first-child { + margin-right: 10px; + } + + .btn { + border: none; + } + + .btn:last-child { + background: darken($cb-blue, 20%); + color: lighten($cb-blue, 30%); + + &:hover { + color: #fff; + } + } + } +} + +@include breakpoint(tablet) { + .Index { + padding: 30px; + } +} + +@include breakpoint(desktop) { + .Index { + padding: 40px; + } +} diff --git a/imports/ui/pages/Login/Login.js b/imports/ui/pages/Login/Login.js index c1ef3aa..29f4fa2 100644 --- a/imports/ui/pages/Login/Login.js +++ b/imports/ui/pages/Login/Login.js @@ -4,12 +4,10 @@ import PropTypes from 'prop-types'; import { Link } from 'react-router-dom'; import { Meteor } from 'meteor/meteor'; import { Bert } from 'meteor/themeteorchef:bert'; -import OAuthLoginButton from '../../components/OAuthLoginButton/OAuthLoginButton'; +import OAuthLoginButtons from '../../components/OAuthLoginButtons/OAuthLoginButtons'; import AccountPageFooter from '../../components/AccountPageFooter/AccountPageFooter'; import validate from '../../../modules/validate'; -import './Login.scss'; - class Login extends React.Component { constructor(props) { super(props); @@ -62,15 +60,16 @@ class Login extends React.Component {

Log In

- - - - - +
(this.form = form)} onSubmit={event => event.preventDefault()}> -

Log In with an Email Address

Email Address ( +
+ Clever Beagle +

Stay safe out there.

+

{'Don\'t forget to like and follow Clever Beagle elsewhere on the web:'}

+
    +
  • +
  • +
  • +
+
+); + +Logout.propTypes = {}; + +export default Logout; diff --git a/imports/ui/pages/Logout/Logout.scss b/imports/ui/pages/Logout/Logout.scss new file mode 100644 index 0000000..6eeba19 --- /dev/null +++ b/imports/ui/pages/Logout/Logout.scss @@ -0,0 +1,57 @@ +@import '../../stylesheets/mixins'; +@import '../../stylesheets/colors'; + +.Logout { + padding: 20px; + background: $cb-blue; + text-align: center; + border-radius: 3px; + color: #fff; + + img { + width: 100px; + height: auto; + } + + h1 { + font-size: 28px; + } + + p { + font-size: 18px; + color: lighten($cb-blue, 25%); + } + + ul { + list-style: none; + display: inline-block; + padding: 0; + margin: 10px 0 0; + } + + ul li { + float: left; + font-size: 28px; + line-height: 28px; + + a { + color: #fff; + } + + &:not(:last-child) { + margin-right: 15px; + } + } +} + +@include breakpoint(tablet) { + .Logout { + padding: 30px; + } +} + +@include breakpoint(desktop) { + .Logout { + padding: 40px; + } +} diff --git a/imports/ui/pages/Profile/Profile.js b/imports/ui/pages/Profile/Profile.js index 6247a04..dbb3738 100644 --- a/imports/ui/pages/Profile/Profile.js +++ b/imports/ui/pages/Profile/Profile.js @@ -3,6 +3,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Row, Col, FormGroup, ControlLabel, Button } from 'react-bootstrap'; +import { capitalize } from '@cleverbeagle/strings'; import { Meteor } from 'meteor/meteor'; import { Accounts } from 'meteor/accounts-base'; import { Bert } from 'meteor/themeteorchef:bert'; @@ -10,10 +11,17 @@ import { createContainer } from 'meteor/react-meteor-data'; import InputHint from '../../components/InputHint/InputHint'; import validate from '../../../modules/validate'; +import './Profile.scss'; + class Profile extends React.Component { constructor(props) { super(props); + + this.getUserType = this.getUserType.bind(this); this.handleSubmit = this.handleSubmit.bind(this); + this.renderOAuthUser = this.renderOAuthUser.bind(this); + this.renderPasswordUser = this.renderPasswordUser.bind(this); + this.renderProfileForm = this.renderProfileForm.bind(this); } componentDidMount() { @@ -66,6 +74,13 @@ class Profile extends React.Component { }); } + getUserType(user) { + const userToCheck = user; + delete userToCheck.services.resume; + const service = Object.keys(userToCheck.services)[0]; + return service === 'password' ? 'password' : 'oauth'; + } + handleSubmit() { const profile = { emailAddress: this.emailAddress.value, @@ -88,6 +103,85 @@ class Profile extends React.Component { }); } + renderOAuthUser(loading, user) { + return !loading ? (
+ {Object.keys(user.services).map(service => ( +
+
+

{`You're logged in with ${capitalize(service)} using the email address ${user.services[service].email}.`}

+
+ ))} +
) :
; + } + + renderPasswordUser(loading, user) { + return !loading ? (
+ + + + First Name + (this.firstName = firstName)} + className="form-control" + /> + + + + + Last Name + (this.lastName = lastName)} + className="form-control" + /> + + + + + Email Address + (this.emailAddress = emailAddress)} + className="form-control" + /> + + + Current Password + (this.currentPassword = currentPassword)} + className="form-control" + /> + + + New Password + (this.newPassword = newPassword)} + className="form-control" + /> + Use at least six characters. + + +
) :
; + } + + renderProfileForm(loading, user) { + return !loading ? ({ + password: this.renderPasswordUser, + oauth: this.renderOAuthUser, + }[this.getUserType(user)])(loading, user) :
; + } + render() { const { loading, user } = this.props; return (
@@ -95,65 +189,7 @@ class Profile extends React.Component {

Edit Profile

(this.form = form)} onSubmit={event => event.preventDefault()}> - {!loading ? (
- - - - First Name - (this.firstName = firstName)} - className="form-control" - /> - - - - - Last Name - (this.lastName = lastName)} - className="form-control" - /> - - - - - Email Address - (this.emailAddress = emailAddress)} - className="form-control" - /> - -
Change Password
- - Current Password - (this.currentPassword = currentPassword)} - className="form-control" - /> - - - New Password - (this.newPassword = newPassword)} - className="form-control" - /> - Use at least six characters. - - -
) :
} + {this.renderProfileForm(loading, user)} diff --git a/imports/ui/pages/Profile/Profile.scss b/imports/ui/pages/Profile/Profile.scss new file mode 100644 index 0000000..c1a8971 --- /dev/null +++ b/imports/ui/pages/Profile/Profile.scss @@ -0,0 +1,39 @@ +@import '../../stylesheets/colors'; + +.OAuthProfile { + .LoggedInWith { + padding: 10px 20px; + border-radius: 3px; + color: #fff; + + p { + margin: 0; + } + + .ServiceIcon { + float: left; + width: auto; + margin-right: 15px; + height: 30px; + text-align: center; + + i { + font-size: 30px; + position: relative; + top: 5px; + } + } + + &.facebook { + background: $facebook; + } + + &.github { + background: $github; + } + + &.google { + background: $google; + } + } +} diff --git a/imports/ui/pages/Signup/Signup.js b/imports/ui/pages/Signup/Signup.js index 42d0871..d69c1e3 100644 --- a/imports/ui/pages/Signup/Signup.js +++ b/imports/ui/pages/Signup/Signup.js @@ -4,13 +4,11 @@ import PropTypes from 'prop-types'; import { Link } from 'react-router-dom'; import { Accounts } from 'meteor/accounts-base'; import { Bert } from 'meteor/themeteorchef:bert'; -import OAuthLoginButton from '../../components/OAuthLoginButton/OAuthLoginButton'; +import OAuthLoginButtons from '../../components/OAuthLoginButtons/OAuthLoginButtons'; import InputHint from '../../components/InputHint/InputHint'; import AccountPageFooter from '../../components/AccountPageFooter/AccountPageFooter'; import validate from '../../../modules/validate'; -import './Signup.scss'; - class Signup extends React.Component { constructor(props) { super(props); @@ -86,15 +84,16 @@ class Signup extends React.Component {

Sign Up

- - - - - +
(this.form = form)} onSubmit={event => event.preventDefault()}> -

Sign Up with an Email Address

diff --git a/imports/ui/stylesheets/_colors.scss b/imports/ui/stylesheets/_colors.scss index 5914a7e..0e0e2f2 100644 --- a/imports/ui/stylesheets/_colors.scss +++ b/imports/ui/stylesheets/_colors.scss @@ -13,3 +13,8 @@ $gray-lighter: #eee; $facebook: #3b5998; $google: #ea4335; $github: $gray-dark; + +$cb-blue: #4285F4; +$cb-green: #00D490; +$cb-yellow: #FFCF50; +$cb-red: #DA5847; diff --git a/package.json b/package.json index 4902b20..91774cb 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "dependencies": { "@cleverbeagle/dates": "^0.2.0", "@cleverbeagle/seeder": "^1.1.0", + "@cleverbeagle/strings": "^0.1.0", "babel-runtime": "^6.20.0", "bcrypt": "^1.0.2", "jquery": "^2.2.4", diff --git a/settings-development.json b/settings-development.json index 2d824da..afe4cc7 100644 --- a/settings-development.json +++ b/settings-development.json @@ -1,18 +1,22 @@ { "public": {}, "private": { + "MAIL_URL": "", "OAuth": { "facebook": { - "clientId": "", - "secret": "" + "appId": "", + "secret": "", + "loginStyle": "popup" }, "google": { "clientId": "", - "secret": "" + "secret": "", + "loginStyle": "popup" }, "github": { "clientId": "", - "secret": "" + "secret": "", + "loginStyle": "popup" } } }