diff --git a/src/components/App.js b/src/components/App.js
index f330c41..4fa2b31 100644
--- a/src/components/App.js
+++ b/src/components/App.js
@@ -1,7 +1,6 @@
import React, { Component } from 'react'
import { Switch, Route, Redirect } from 'react-router'
import { Link } from 'react-router-dom'
-import PropTypes from 'prop-types'
import logo from '../logo.svg'
import StarCount from './StarCount'
@@ -9,7 +8,6 @@ import TableOfContents from './TableOfContents'
import Section from './Section'
import CurrentUser from './CurrentUser'
import Profile from './Profile'
-import withAuth from '../lib/withAuth'
import Reviews from './Reviews'
const Book = ({ user }) => (
@@ -24,8 +22,6 @@ const Book = ({ user }) => (
class App extends Component {
render() {
- const { logout, ...authProps } = this.props
-
return (
@@ -34,27 +30,16 @@ class App extends Component {
The GraphQL Guide
-
+
} />
- }
- />
- } />
+
+
)
}
}
-App.propTypes = {
- user: PropTypes.object,
- login: PropTypes.func.isRequired,
- logout: PropTypes.func.isRequired,
- loading: PropTypes.bool.isRequired
-}
-
-export default withAuth(App)
+export default App
diff --git a/src/components/CurrentUser.js b/src/components/CurrentUser.js
index 94ebfdf..dfb69f0 100644
--- a/src/components/CurrentUser.js
+++ b/src/components/CurrentUser.js
@@ -2,19 +2,20 @@ import React from 'react'
import PropTypes from 'prop-types'
import { Link } from 'react-router-dom'
-const CurrentUser = ({ user, login, loading }) => {
- const User = () => (
-
-
- {user.firstName}
-
- )
+import { withUser } from '../lib/withUser'
+import { login } from '../lib/auth'
+const CurrentUser = ({ user, loggingIn }) => {
let content
if (user) {
- content =
- } else if (loading) {
+ content = (
+
+
+ {user.firstName}
+
+ )
+ } else if (loggingIn) {
content =
} else {
content =
@@ -28,8 +29,7 @@ CurrentUser.propTypes = {
firstName: PropTypes.string.isRequired,
photo: PropTypes.string.isRequired
}),
- login: PropTypes.func.isRequired,
- loading: PropTypes.bool.isRequired
+ loggingIn: PropTypes.bool.isRequired
}
-export default CurrentUser
+export default withUser(CurrentUser)
diff --git a/src/components/Profile.js b/src/components/Profile.js
index 4cbe616..8db29d8 100644
--- a/src/components/Profile.js
+++ b/src/components/Profile.js
@@ -1,8 +1,11 @@
import React from 'react'
import PropTypes from 'prop-types'
-const Profile = ({ user, login, logout, loading }) => {
- if (loading) {
+import { withUser } from '../lib/withUser'
+import { login, logout } from '../lib/auth'
+
+const Profile = ({ user, loggingIn }) => {
+ if (loggingIn) {
return (
@@ -63,9 +66,7 @@ Profile.propTypes = {
email: PropTypes.string.isRequired,
hasPurchased: PropTypes.string
}),
- login: PropTypes.func.isRequired,
- logout: PropTypes.func.isRequired,
- loading: PropTypes.bool.isRequired
+ loggingIn: PropTypes.bool.isRequired
}
-export default Profile
+export default withUser(Profile)
diff --git a/src/components/Reviews.js b/src/components/Reviews.js
index 4713b16..b51dca5 100644
--- a/src/components/Reviews.js
+++ b/src/components/Reviews.js
@@ -7,6 +7,7 @@ import AddIcon from 'material-ui-icons/Add'
import Modal from 'material-ui/Modal'
import ReviewList from './ReviewList'
+import { withUser } from '../lib/withUser'
import ReviewForm from './ReviewForm'
class Reviews extends Component {
@@ -76,4 +77,4 @@ Reviews.propTypes = {
})
}
-export default Reviews
+export default withUser(Reviews)
diff --git a/src/index.js b/src/index.js
index 6b48562..5e89560 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,66 +1,13 @@
import React from 'react'
import ReactDOM from 'react-dom'
-import { ApolloClient } from 'apollo-client'
import { ApolloProvider } from 'react-apollo'
-import { InMemoryCache } from 'apollo-cache-inmemory'
-import { split } from 'apollo-link'
-import { WebSocketLink } from 'apollo-link-ws'
-import { createHttpLink } from 'apollo-link-http'
-import { getMainDefinition } from 'apollo-utilities'
import { BrowserRouter } from 'react-router-dom'
-import { setContext } from 'apollo-link-context'
-import { getAuthToken } from 'auth0-helpers'
import { MuiThemeProvider, createMuiTheme } from 'material-ui/styles'
import './index.css'
import registerServiceWorker from './registerServiceWorker'
import App from './components/App'
-import { errorLink } from './lib/errorLink'
-
-const httpLink = createHttpLink({
- uri: 'https://api.graphql.guide/graphql'
-})
-
-const authLink = setContext(async (_, { headers }) => {
- const token = await getAuthToken({
- doLoginIfTokenExpired: true
- })
-
- if (token) {
- return {
- headers: {
- ...headers,
- authorization: `Bearer ${token}`
- }
- }
- } else {
- return { headers }
- }
-})
-
-const authedHttpLink = authLink.concat(httpLink)
-
-const wsLink = new WebSocketLink({
- uri: `wss://api.graphql.guide/subscriptions`,
- options: {
- reconnect: true
- }
-})
-
-const networkLink = split(
- ({ query }) => {
- const { kind, operation } = getMainDefinition(query)
- return kind === 'OperationDefinition' && operation === 'subscription'
- },
- wsLink,
- authedHttpLink
-)
-
-const link = errorLink.concat(networkLink)
-
-const cache = new InMemoryCache()
-
-const client = new ApolloClient({ link, cache })
+import { apollo } from './lib/apollo'
const GRAPHQL_PINK = '#e10098'
@@ -70,7 +17,7 @@ const theme = createMuiTheme({
ReactDOM.render(
-
+
diff --git a/src/lib/apollo.js b/src/lib/apollo.js
new file mode 100644
index 0000000..5ed57e3
--- /dev/null
+++ b/src/lib/apollo.js
@@ -0,0 +1,55 @@
+import { ApolloClient } from 'apollo-client'
+import { InMemoryCache } from 'apollo-cache-inmemory'
+import { split } from 'apollo-link'
+import { WebSocketLink } from 'apollo-link-ws'
+import { createHttpLink } from 'apollo-link-http'
+import { getMainDefinition } from 'apollo-utilities'
+import { setContext } from 'apollo-link-context'
+import { getAuthToken } from 'auth0-helpers'
+
+import { errorLink } from './errorLink'
+
+const httpLink = createHttpLink({
+ uri: 'https://api.graphql.guide/graphql'
+})
+
+const authLink = setContext(async (_, { headers }) => {
+ const token = await getAuthToken({
+ doLoginIfTokenExpired: true
+ })
+
+ if (token) {
+ return {
+ headers: {
+ ...headers,
+ authorization: `Bearer ${token}`
+ }
+ }
+ } else {
+ return { headers }
+ }
+})
+
+const authedHttpLink = authLink.concat(httpLink)
+
+const wsLink = new WebSocketLink({
+ uri: `wss://api.graphql.guide/subscriptions`,
+ options: {
+ reconnect: true
+ }
+})
+
+const networkLink = split(
+ ({ query }) => {
+ const { kind, operation } = getMainDefinition(query)
+ return kind === 'OperationDefinition' && operation === 'subscription'
+ },
+ wsLink,
+ authedHttpLink
+)
+
+const link = errorLink.concat(networkLink)
+
+const cache = new InMemoryCache()
+
+export const apollo = new ApolloClient({ link, cache })
diff --git a/src/lib/auth.js b/src/lib/auth.js
new file mode 100644
index 0000000..2ac23f4
--- /dev/null
+++ b/src/lib/auth.js
@@ -0,0 +1,48 @@
+import auth0 from 'auth0-js'
+import {
+ initAuthHelpers,
+ login as auth0Login,
+ logout as auth0Logout
+} from 'auth0-helpers'
+
+import { apollo } from './apollo'
+
+const client = new auth0.WebAuth({
+ domain: 'graphql.auth0.com',
+ clientID: '8fErnZoF3hbzQ2AbMYu5xcS0aVNzQ0PC',
+ responseType: 'token',
+ audience: 'https://api.graphql.guide',
+ scope: 'openid profile guide'
+})
+
+initAuthHelpers({
+ client,
+ usePopup: true,
+ authOptions: {
+ connection: 'github',
+ owp: true,
+ popupOptions: { height: 623 } // make tall enough for content
+ },
+ checkSessionOptions: {
+ redirect_uri: window.location.origin
+ },
+ onError: e => console.error(e)
+})
+
+export const login = () => {
+ auth0Login({
+ onCompleted: e => {
+ if (e) {
+ console.error(e)
+ return
+ }
+
+ apollo.reFetchObservableQueries()
+ }
+ })
+}
+
+export const logout = () => {
+ auth0Logout()
+ apollo.resetStore()
+}
diff --git a/src/lib/withUser.js b/src/lib/withUser.js
new file mode 100644
index 0000000..0bf5587
--- /dev/null
+++ b/src/lib/withUser.js
@@ -0,0 +1,25 @@
+import { graphql } from 'react-apollo'
+import gql from 'graphql-tag'
+
+export const USER_QUERY = gql`
+ query UserQuery {
+ currentUser {
+ firstName
+ name
+ username
+ email
+ photo
+ hasPurchased
+ favoriteReviews {
+ id
+ }
+ }
+ }
+`
+
+export const withUser = graphql(USER_QUERY, {
+ props: ({ data: { currentUser, loading } }) => ({
+ user: currentUser,
+ loggingIn: loading
+ })
+})