Incorporate apollo, material-ui and auth0
No files matched your search
@@ -62,6 +62,8 @@
|
||||
"dependencies": {
|
||||
"@advancedalgos/key-vault-client": "0.0.5",
|
||||
"@advancedalgos/teams-client": "0.0.8",
|
||||
"@material-ui/core": "^3.2.0",
|
||||
"@material-ui/icons": "^3.0.1",
|
||||
"babel-polyfill": "^6.26.0",
|
||||
"react": "^16.5.2",
|
||||
"react-dom": "^16.5.2",
|
||||
|
||||
@@ -1,20 +1,46 @@
|
||||
import { ApolloProvider } from 'react-apollo'
|
||||
import React, { Component } from 'react'
|
||||
import { Route, BrowserRouter, Switch } from 'react-router-dom'
|
||||
|
||||
import App from '@advancedalgos/teams-client'
|
||||
import App2 from '@advancedalgos/key-vault-client'
|
||||
import MuiThemeProvider from '@material-ui/core/styles/MuiThemeProvider'
|
||||
import CssBaseline from '@material-ui/core/CssBaseline'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import { theme, globalStyles } from './styles'
|
||||
|
||||
export const Master = () => (
|
||||
import client from './graphql/apollo'
|
||||
import Auth from './auth'
|
||||
|
||||
import { Header, Footer, Home, Callback } from './views'
|
||||
|
||||
import Teams from '@advancedalgos/teams-client'
|
||||
import KeyVault from '@advancedalgos/key-vault-client'
|
||||
|
||||
export const auth = new Auth(
|
||||
result => console.log('auth result', result),
|
||||
client
|
||||
)
|
||||
|
||||
export const MasterApp = () => (
|
||||
<BrowserRouter>
|
||||
<Switch>
|
||||
<Route exact path='/' component={App} />
|
||||
<Route exact path='/key-vault' component={App2} />
|
||||
</Switch>
|
||||
<ApolloProvider client={client}>
|
||||
<MuiThemeProvider theme={theme}>
|
||||
<CssBaseline />
|
||||
<div className='App'>
|
||||
<Header auth={auth} />
|
||||
<Switch>
|
||||
<Route exact path='/' component={Home} />
|
||||
<Route
|
||||
exact
|
||||
path='/teams'
|
||||
render={props => <Teams {...props} auth={auth} />}
|
||||
/>
|
||||
<Route exact path='/key-vault' component={KeyVault} />
|
||||
</Switch>
|
||||
<Footer />
|
||||
</div>
|
||||
</MuiThemeProvider>
|
||||
</ApolloProvider>
|
||||
</BrowserRouter>
|
||||
)
|
||||
|
||||
export const Temporary = () =>(
|
||||
<div>Hello Advanced Alogs!</div>
|
||||
)
|
||||
|
||||
export default Master
|
||||
export default withStyles(globalStyles)(MasterApp)
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 120 24"><defs><style>.cls-1,.cls-3{fill:none;}.cls-2{clip-path:url(#clip-path);}.cls-3{stroke:#2a96ff;stroke-miterlimit:10;stroke-width:0.5px;}.cls-4{fill:#fff;}.cls-5{fill:#e3493c;}</style><clipPath id="clip-path"><rect class="cls-1" x="272.54" y="79.59" width="600" height="600"/></clipPath></defs><title>aa-logo-dark</title><g id="Layer_1" data-name="Layer 1"><g class="cls-2"><circle class="cls-3" cx="338.14" cy="263.28" r="277.97"/></g></g><g id="Layer_4" data-name="Layer 4"><path class="cls-4" d="M27.67,15.74l-.19-1.58H26.29l-.2,1.58H24.51L25.7,7.79h2.39l1.19,8Zm-.75-6.39h-.08l-.4,3.41h.89Z"/><path class="cls-4" d="M32.15,7.79h1.93a2.39,2.39,0,0,1,1.46.35,1.68,1.68,0,0,1,.54,1.11,21,21,0,0,1,.1,2.52,20.93,20.93,0,0,1-.1,2.51,1.68,1.68,0,0,1-.54,1.11,2.39,2.39,0,0,1-1.46.35H32.15Zm1.93,6.51a.46.46,0,0,0,.37-.12,1.19,1.19,0,0,0,.13-.6c0-.32,0-.93,0-1.81s0-1.5,0-1.82a1.19,1.19,0,0,0-.13-.6.46.46,0,0,0-.37-.12h-.36V14.3Z"/><path class="cls-4" d="M39.94,15.74,38.87,7.79h1.59l.66,6.31h.12l.61-6.31h1.57l-1.07,8Z"/><path class="cls-4" d="M48.8,15.74l-.19-1.58H47.42l-.2,1.58H45.64l1.19-7.95h2.39l1.19,8Zm-.75-6.39H48l-.4,3.41h.89Z"/><path class="cls-4" d="M56.06,15.74l-1.23-4h0v4h-1.5V7.79h1.47l1.13,3.61h.06V7.79h1.51v8Z"/><path class="cls-4" d="M63.14,15.77a3.11,3.11,0,0,1-.59.06,2.06,2.06,0,0,1-1.36-.37,1.94,1.94,0,0,1-.58-1.19,17.1,17.1,0,0,1-.13-2.5,14.22,14.22,0,0,1,.15-2.5,1.94,1.94,0,0,1,.58-1.2,2,2,0,0,1,1.34-.37,4.21,4.21,0,0,1,.62,0,1.86,1.86,0,0,1,.45.12V9.2a5.77,5.77,0,0,0-.78-.06.77.77,0,0,0-.55.15,1.22,1.22,0,0,0-.18.64c0,.33,0,.94,0,1.84s0,1.5,0,1.83a1.22,1.22,0,0,0,.18.64.77.77,0,0,0,.55.15,4.74,4.74,0,0,0,.8-.06v1.29A1.56,1.56,0,0,1,63.14,15.77Z"/><path class="cls-4" d="M66.59,15.74V7.79h3.19V9.23h-1.6V11h1.41v1.45H68.18V14.3h1.6v1.44Z"/><path class="cls-4" d="M72.79,7.79h1.92a2.4,2.4,0,0,1,1.47.35,1.67,1.67,0,0,1,.53,1.11,20.46,20.46,0,0,1,.11,2.52,20.38,20.38,0,0,1-.11,2.51,1.67,1.67,0,0,1-.53,1.11,2.4,2.4,0,0,1-1.47.35H72.79Zm1.92,6.51a.48.48,0,0,0,.38-.12,1.19,1.19,0,0,0,.13-.6c0-.32,0-.93,0-1.81s0-1.5,0-1.82a1.19,1.19,0,0,0-.13-.6.48.48,0,0,0-.38-.12h-.35V14.3Z"/><path class="cls-5" d="M85.6,15.74l-.91-2.31H80.93L80,15.74h-.76l3.11-7.95h.89l3.12,8ZM82.84,8.66h-.06l-1.61,4.08h3.27Z"/><path class="cls-5" d="M88.44,15.74V7.79h.74V15H93v.72Z"/><path class="cls-5" d="M97.86,12.24v-.68h2.7v4c-.37.06-.8.12-1.26.16s-.87.06-1.22.06a5.68,5.68,0,0,1-2.14-.3A1.71,1.71,0,0,1,95,14.4a9.76,9.76,0,0,1-.26-2.63A9.85,9.85,0,0,1,95,9.13,1.71,1.71,0,0,1,96,8a5.91,5.91,0,0,1,2.13-.29c.38,0,.81,0,1.27.06s.86.1,1.18.16v.66a13.61,13.61,0,0,0-2-.19,8.76,8.76,0,0,0-2,.16,1.21,1.21,0,0,0-.79.85,8.45,8.45,0,0,0-.23,2.37A10.48,10.48,0,0,0,95.66,14a1.27,1.27,0,0,0,.7.91,4.41,4.41,0,0,0,1.72.24l.9,0c.35,0,.64,0,.87-.09V12.24Z"/><path class="cls-5" d="M103.84,15.54a1.48,1.48,0,0,1-.83-1.08,13.91,13.91,0,0,1-.17-2.69,14,14,0,0,1,.17-2.7A1.48,1.48,0,0,1,103.84,8a6,6,0,0,1,2.21-.29,5.94,5.94,0,0,1,2.2.29,1.46,1.46,0,0,1,.83,1.08,13.75,13.75,0,0,1,.18,2.7,13.7,13.7,0,0,1-.18,2.69,1.46,1.46,0,0,1-.83,1.08,5.94,5.94,0,0,1-2.2.29A6,6,0,0,1,103.84,15.54Zm3.93-.57a1,1,0,0,0,.61-.81,13.62,13.62,0,0,0,.14-2.39,13.68,13.68,0,0,0-.14-2.4,1,1,0,0,0-.61-.81,8.84,8.84,0,0,0-3.45,0,1,1,0,0,0-.6.81,12.47,12.47,0,0,0-.15,2.4,12.42,12.42,0,0,0,.15,2.39,1,1,0,0,0,.6.81,8.84,8.84,0,0,0,3.45,0Z"/><path class="cls-5" d="M112.94,15.79c-.5,0-.94-.06-1.31-.11V15l1.33.1c.48,0,.88.05,1.2.05a8.75,8.75,0,0,0,1-.05,1.78,1.78,0,0,0,.65-.22.68.68,0,0,0,.35-.47,3.13,3.13,0,0,0,.09-.83,4.54,4.54,0,0,0-.06-.9.57.57,0,0,0-.31-.37,3.72,3.72,0,0,0-.88-.18l-2-.22a2.08,2.08,0,0,1-1.06-.32,1.18,1.18,0,0,1-.44-.64,5,5,0,0,1-.09-1.07,2.57,2.57,0,0,1,.3-1.38,1.56,1.56,0,0,1,.9-.63,6.12,6.12,0,0,1,1.59-.16c.45,0,.9,0,1.35,0s.81.08,1.07.13v.66c-.31,0-.68-.07-1.11-.1s-.83,0-1.19,0a6.52,6.52,0,0,0-1.1.07,1.88,1.88,0,0,0-.66.22.73.73,0,0,0-.33.44,2.52,2.52,0,0,0-.08.75,2.94,2.94,0,0,0,.07.77.61.61,0,0,0,.29.36,2.05,2.05,0,0,0,.69.16l2,.21a4.86,4.86,0,0,1,1.17.24,1,1,0,0,1,.55.63,4.24,4.24,0,0,1,.13,1.27,3,3,0,0,1-.31,1.54,1.36,1.36,0,0,1-.85.64,5.78,5.78,0,0,1-1.47.14C113.93,15.83,113.45,15.82,112.94,15.79Z"/><path class="cls-5" d="M11.36,13.89a7.43,7.43,0,0,1,2.52.4c.82.58,2,.89,2.5.3s0-1.61-.79-2.38a7.64,7.64,0,0,1-.93-2.35c.11-1-.23-2.23-1-2.35s-1.47,1-1.65,1.88a7.38,7.38,0,0,1-1.61,2c-.9.42-1.77,1.3-1.49,2S10.48,14.16,11.36,13.89Z"/><path class="cls-5" d="M14.75,3.42C16,3.47,16.49,6,16.29,7.91a26.16,26.16,0,0,0,1.64,4.69,1.88,1.88,0,0,0,.79.79,10.55,10.55,0,0,1-.84-5c.79-2.19.44-5.15-.75-5.84a2.71,2.71,0,0,0-3.68,1.2A1.8,1.8,0,0,1,14.75,3.42Z"/><path class="cls-5" d="M5,14C4.4,13,6.3,11.26,8.09,10.45,8.66,10.2,11,7.2,11.33,6.7a2,2,0,0,0,.29-1.09A10.62,10.62,0,0,1,7.68,8.86C5.38,9.27,3,11.05,3,12.42A2.71,2.71,0,0,0,5.87,15,1.88,1.88,0,0,1,5,14Z"/><path class="cls-5" d="M19.12,17.42c-.66,1-3.07.23-4.67-.92a25.88,25.88,0,0,0-4.87-.92,1.79,1.79,0,0,0-1.08.29,10.37,10.37,0,0,1,4.Line truncated
|
||||
|
After Width: | Height: | Size: 5.0 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 98 140"><defs><style>.cls-1,.cls-3{fill:none;}.cls-2{clip-path:url(#clip-path);}.cls-3{stroke:#2a96ff;stroke-miterlimit:10;stroke-width:0.5px;}.cls-4{fill:#4d4d4d;}.cls-5{fill:#e3493c;}</style><clipPath id="clip-path"><rect class="cls-1" x="144.54" y="59.59" width="600" height="600"/></clipPath></defs><title>aa-logo-vert</title><g id="Layer_1" data-name="Layer 1"><g class="cls-2"><circle class="cls-3" cx="210.14" cy="243.28" r="277.97"/></g></g><g id="Layer_4" data-name="Layer 4"><path class="cls-4" d="M11.27,108.29l-.38-3H8.62l-.38,3h-3L7.49,93.1h4.57l2.28,15.19ZM9.83,96.08H9.68L8.9,102.6h1.71Z"/><path class="cls-4" d="M18,93.1h3.69a4.53,4.53,0,0,1,2.79.67,3.22,3.22,0,0,1,1,2.11,41.13,41.13,0,0,1,.19,4.82,41,41,0,0,1-.19,4.81,3.19,3.19,0,0,1-1,2.11,4.46,4.46,0,0,1-2.79.67H18Zm3.69,12.43a.89.89,0,0,0,.71-.22,2.31,2.31,0,0,0,.25-1.15c0-.61,0-1.77,0-3.46s0-2.85,0-3.47a2.31,2.31,0,0,0-.25-1.15.89.89,0,0,0-.71-.22H21v9.67Z"/><path class="cls-4" d="M31.16,108.29,29.11,93.1h3l1.25,12.06h.23L34.8,93.1h3l-2.05,15.19Z"/><path class="cls-4" d="M46.35,108.29l-.38-3H43.7l-.38,3h-3L42.57,93.1h4.57l2.28,15.19ZM44.91,96.08h-.15L44,102.6h1.7Z"/><path class="cls-4" d="M58.44,108.29l-2.36-7.62H56v7.62H53.12V93.1h2.8L58.09,100h.11V93.1h2.89v15.19Z"/><path class="cls-4" d="M70.19,108.36a6.43,6.43,0,0,1-1.12.11,4,4,0,0,1-2.61-.71,3.72,3.72,0,0,1-1.1-2.28,31.28,31.28,0,0,1-.26-4.78,29.46,29.46,0,0,1,.28-4.77,3.82,3.82,0,0,1,1.12-2.3,3.9,3.9,0,0,1,2.57-.71,7.72,7.72,0,0,1,1.18.1,3.21,3.21,0,0,1,.85.24v2.53a11.75,11.75,0,0,0-1.48-.11,1.48,1.48,0,0,0-1.05.29,2.16,2.16,0,0,0-.35,1.23c0,.62-.08,1.79-.08,3.5s0,2.87.08,3.5a2.15,2.15,0,0,0,.35,1.22,1.48,1.48,0,0,0,1.05.29,9.89,9.89,0,0,0,1.53-.11v2.47A4.23,4.23,0,0,1,70.19,108.36Z"/><path class="cls-4" d="M75,108.29V93.1h6.09v2.76H78v3.38h2.7V102H78v3.53h3.07v2.76Z"/><path class="cls-4" d="M85.08,93.1h3.69a4.55,4.55,0,0,1,2.79.67,3.16,3.16,0,0,1,1,2.11,38.45,38.45,0,0,1,.2,4.82,38.37,38.37,0,0,1-.2,4.81,3.14,3.14,0,0,1-1,2.11,4.48,4.48,0,0,1-2.79.67H85.08Zm3.69,12.43a.89.89,0,0,0,.71-.22,2.31,2.31,0,0,0,.25-1.15c0-.61,0-1.77,0-3.46s0-2.85,0-3.47a2.31,2.31,0,0,0-.25-1.15.89.89,0,0,0-.71-.22h-.69v9.67Z"/><path class="cls-5" d="M19.79,134.79l-2.1-5.3H9.08L7,134.79H5.24l7.15-18.23h2l7.16,18.23Zm-6.33-16.24h-.14L9.64,127.9h7.5Z"/><path class="cls-5" d="M26.41,134.79V116.56h1.7v16.58H37v1.65Z"/><path class="cls-5" d="M48.1,126.76V125.2h6.2v9.3c-.87.14-1.84.26-2.9.35s-2,.15-2.8.15a12.88,12.88,0,0,1-4.9-.69,3.89,3.89,0,0,1-2.15-2.6,22.5,22.5,0,0,1-.58-6,22.11,22.11,0,0,1,.6-6A3.87,3.87,0,0,1,43.72,117a13.15,13.15,0,0,1,4.88-.67c.88,0,1.85.05,2.92.14s2,.22,2.7.36v1.51a33.49,33.49,0,0,0-4.66-.42,18.69,18.69,0,0,0-4.55.37,2.7,2.7,0,0,0-1.81,1.93,18.81,18.81,0,0,0-.53,5.43,23.5,23.5,0,0,0,.39,5.13,3,3,0,0,0,1.59,2.09,10.15,10.15,0,0,0,4,.55c.56,0,1.25,0,2.07-.08s1.47-.12,2-.19v-6.41Z"/><path class="cls-5" d="M61.91,134.32A3.33,3.33,0,0,1,60,131.86a31.94,31.94,0,0,1-.41-6.19,31.89,31.89,0,0,1,.41-6.18A3.33,3.33,0,0,1,61.91,117a13.45,13.45,0,0,1,5.07-.67A13.42,13.42,0,0,1,72,117a3.33,3.33,0,0,1,1.89,2.47,31.89,31.89,0,0,1,.41,6.18,31.94,31.94,0,0,1-.41,6.19A3.33,3.33,0,0,1,72,134.32,13.38,13.38,0,0,1,67,135,13.4,13.4,0,0,1,61.91,134.32Zm9-1.29a2.34,2.34,0,0,0,1.37-1.86,29.55,29.55,0,0,0,.34-5.5,29.7,29.7,0,0,0-.34-5.5,2.32,2.32,0,0,0-1.37-1.85,13.69,13.69,0,0,0-4-.38,13.73,13.73,0,0,0-4,.38,2.32,2.32,0,0,0-1.37,1.85,28.82,28.82,0,0,0-.34,5.5,28.68,28.68,0,0,0,.34,5.5A2.34,2.34,0,0,0,63,133a13.73,13.73,0,0,0,4,.38A13.69,13.69,0,0,0,70.94,133Z"/><path class="cls-5" d="M82.89,134.91c-1.17-.07-2.18-.15-3-.25v-1.59c.91.08,1.93.16,3,.23s2,.11,2.76.11a17.72,17.72,0,0,0,2.32-.12,4,4,0,0,0,1.49-.49,1.67,1.67,0,0,0,.81-1.07,7.68,7.68,0,0,0,.2-1.92,9.6,9.6,0,0,0-.15-2.07,1.14,1.14,0,0,0-.71-.83,7.63,7.63,0,0,0-2-.42L83,126a4.91,4.91,0,0,1-2.42-.74,2.61,2.61,0,0,1-1-1.47,10.4,10.4,0,0,1-.23-2.45,5.81,5.81,0,0,1,.71-3.17,3.47,3.47,0,0,1,2-1.44,14.24,14.24,0,0,1,3.66-.37c1,0,2,0,3.09.1a19.49,19.49,0,0,1,2.44.29v1.51c-.7-.08-1.55-.16-2.54-.22s-1.9-.09-2.73-.09a15.54,15.54,0,0,0-2.52.16,4.18,4.18,0,0,0-1.51.5,1.74,1.74,0,0,0-.76,1,6,6,0,0,0-.19,1.72,6.83,6.83,0,0,0,.17,1.76,1.32,1.32,0,0,0,.67.82,4.9,4.9,0,0,0,1.57.39l4.51.47a10.3,10.3,0,0,1,2.69.56,2.23,2.23,0,0,1,1.25,1.43,9.9,9.9,0,0,1,.3,2.91,6.84,6.84,0,0,1-.72,3.54,3.17,3.17,0,0,1-2,1.47,14.17,14.17,0,0,1-3.38.32C85.14,135,84.05,135,82.89,134.91Z"/><path class="cls-5" d="M47.08,49.62c1.17-.36,8.61.83,9.61,1.53,3.13,2.21,7.71,3.41,9.55,1.15s-.08-6.13-3-9.1c-.88-.88-3.7-7.75-3.56-9,.42-3.87-.85-8.5-3.73-9s-5.61,3.66-6.3,7.16c-.24,1.22-5,7.11-6.14,7.62-3.48,1.62-6.77,5-5.73,7.69S43.7,50.65,47.08,49.62Z"/><path class="cls-5" d="M60,9.61c4.68.2,6.65,9.72,5.89,17.18-.24,2.37,5.27,15.71,6.24,17.91a7.29,7.29,0,0,0,3,3C71.63,38.07,71.32,30.32,72,28.51c3-8.4,1.71-19.69-2.85-22.32-3.07-1.77-9.79-2.48-14.07,4.56A6.91,6.91,0,0,1,60,9.61Z"/><path class="cls-5" d="M22.61,50.2C20.Line truncated
|
||||
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 6.4 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square150x150logo src="/mstile-150x150.png"/>
|
||||
<TileColor>#da532c</TileColor>
|
||||
</tile>
|
||||
</msapplication>
|
||||
</browserconfig>
|
||||
|
After Width: | Height: | Size: 502 B |
|
After Width: | Height: | Size: 758 B |
|
After Width: | Height: | Size: 15 KiB |
@@ -0,0 +1,9 @@
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
||||
<link rel="manifest" href="/site.webmanifest">
|
||||
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#e3493c">
|
||||
<meta name="apple-mobile-web-app-title" content="Advanced Algos">
|
||||
<meta name="application-name" content="Advanced Algos">
|
||||
<meta name="msapplication-TileColor" content="#da532c">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
@@ -0,0 +1 @@
|
||||
<svg version="1" xmlns="http://www.w3.org/2000/svg" width="1365.333" height="1365.333" viewBox="0 0 1024.000000 1024.000000"><path d="M685.9 27.4c-.2.2-3 .7-6.1 1-12.6 1.5-34.6 8.5-45.2 14.5-2 1.2-5.3 3.1-7.3 4.2-14.3 8.1-30.2 22.3-43.5 38.8-5.9 7.4-16.2 22.1-15.5 22.1.2 0 3.6-1.7 7.5-3.9 17.4-9.6 28.8-12.1 52.2-11.7 13.4.3 17.7.8 23.1 2.5 25.1 8 45.2 36.6 58.9 83.7 1.8 6 3.3 11.6 3.5 12.4 2.3 10.8 3.5 17.1 4 20 .3 1.9 1 6 1.5 9 1.2 7.3 1.8 11.3 2.5 18.5.4 3.3.8 7.6 1.1 9.5 1.6 14.3 2.2 51.4 1 69.5-1.4 21.3-1.5 26-.5 31 .5 2.7 1.2 6.3 1.5 8 2.3 12.9 20.6 69 33.4 102.5 1.6 4.1 4.8 12.4 7.1 18.5 17.1 45.2 47.3 118.6 49.1 119.3.4.2.8.9.8 1.5.1 3.8 18.3 22 29.2 29.1 4.7 3.1 8.8 5.6 9 5.6.3 0-3.2-10.9-7.7-24.3-4.5-13.3-8.4-25.3-8.7-26.7-.4-1.4-2-7.2-3.7-13-4.3-14.5-12.2-45.3-13.7-54-.3-1.4-.7-3.3-1-4.2-.3-1-.7-3-1-4.5-.2-1.6-.9-4.8-1.4-7.3-.5-2.5-1.4-7.2-2-10.5-.5-3.3-1.2-7.1-1.5-8.5-.3-1.4-1-5.7-1.5-9.5-.6-3.9-1.2-8.1-1.5-9.5-.3-2.3-.7-5.4-2-16.3-3.1-25.8-3.8-58.6-1.5-73.2.7-4.4 2.2-10.7 3.5-14 2.3-6.1 9-28.9 9.9-33.5.3-1.4 1.2-5.2 2-8.5s1.7-7.4 1.9-9c.3-1.7 1.4-8.2 2.6-14.6 1.1-6.3 2.3-14.7 2.6-18.5.4-3.8.9-8.3 1.1-9.9 2.2-16.2 2.2-69.4 0-83.5-.2-1.4-.7-5-1.1-8-6.7-56.6-26.4-102.4-53.1-123.1-11.1-8.5-31-16.4-49.9-19.7-9.6-1.7-38.4-2.9-39.6-1.8zM465 215.4c-2.3 3-9.7 11.7-14.5 17-1.1 1.2-5.6 6.2-10 11.1-8.3 9.3-43.9 45.2-53.5 54-51.1 46.9-108.8 86-132.5 90-2.2.4-4.4.8-5 .9-.5.2-2.8.6-5 1.1-24.5 4.7-70 20.4-91 31.3-2.7 1.4-5.2 2.6-5.5 2.7-.7.1-12.3 6.2-16.7 8.7-2.1 1.2-5.4 3.1-7.5 4.2C62.4 471.4 16.3 519 4.3 559.8.9 571.3.5 590 3.4 603.5c2.6 12.1 7.2 25.6 11.8 35 19.6 39.1 52.7 65.8 95.3 76.8 5.5 1.4 12 2.9 14.5 3.2 2.5.4 5.4.9 6.5 1.1 2.8.5 11.7 1.4 19.5 1.9l6.4.4-3.4-2.1c-20.8-12.5-29.7-21.3-39-38.3-1.8-3.3-4.3-7.8-5.5-10-6.1-11.2-8.2-22.8-6.4-35.1 7.4-48 72.3-111.2 159.4-155 10.5-5.3 21-11.2 23.5-13.1 8.7-6.7 26.9-25.3 45.4-46.3 1.7-2 4.9-5.6 7.1-8.1 2.2-2.4 6-6.9 8.5-9.8 2.5-3 5-5.9 5.5-6.5.6-.6 3-3.6 5.5-6.6 6.5-8 7.1-8.6 15.2-18.5 12.7-15.4 51.5-64.5 61.3-77.6 1.1-1.5 5.9-7.8 10.6-14 11.5-15.2 13.3-18.1 16.8-26.9 3-7.7 3.5-9.3 5.1-19 1.2-7.1 1.9-21.9 1.1-22.4-.3-.2-1.7 1.1-3.1 2.8zM563.9 315c-21.5 5.4-43.9 28.6-59.4 61.3-5.2 11-10.1 24.9-12.5 35.7-2 8.8-6.1 16.2-21 37.4-1.8 2.6-17.8 23.2-20.7 26.6-14.7 17.6-22.4 26.2-31.2 35.1-8.7 8.6-12.2 11.3-19.6 15.2-16.7 8.7-25.6 14.5-37 23.8-22.2 18.1-36.8 38.2-41 56.4-1.6 6.6-2.2 17.6-1.1 19.3.3.5.7 2.1 1 3.7.8 4.3 5.3 12.7 9.1 16.8 10.1 11.1 27.7 18.5 50.5 21.3 12.2 1.5 36.1.8 49-1.6 11.6-2 12.6-2.3 20.5-4.5s31.7-2.2 43.5 0c.8.2 4.4.6 8 1 3.6.4 7.4.9 8.4 1.1 1.1.2 4.2.6 6.9.9 2.8.3 5.3.8 5.6.9.3.2 2.9.7 5.6 1 9.1 1.3 39 7.5 47.9 10.1 8.9 2.6 18.5 7 20.6 9.6 1.9 2.3 30.1 16.5 39.5 20 9.1 3.3 26.6 7.7 33.7 8.6 9.2 1.1 23.9.7 30-.7 19.5-4.6 33.3-18.5 36.3-36.7.7-4.2.8-19 .1-20.1-.2-.4-.7-2.4-1-4.6-1-6.1-5.5-18.3-10.3-28.1-4.2-8.3-15.4-26.1-20.1-31.6-5.8-7-14.5-17-18.6-21.4-2.6-2.8-6.5-8-8.7-11.7-6.3-10.8-17.6-35.1-25.4-55.3-1.5-3.9-3.3-8.4-4-10-1.4-3.5-4.9-12.8-5-13.5 0-.3-1.2-3.7-2.5-7.5-1.3-3.9-2.5-7.5-2.6-8-.1-.6-.9-3.5-1.8-6.6-2.6-8.9-2.8-10-2.6-17.4.7-25.5.3-39.3-1.3-49.5-.3-1.4-.8-4.5-1.2-7-.3-2.4-.8-4.7-1-5.1-.2-.3-.7-2.1-1-4-.9-5.4-6.3-20.6-9.7-27.3-7.5-14.9-16.6-24.9-27.5-30.3-6.3-3.1-8.3-3.6-16-3.9-4.8-.2-10.4.1-12.4.6zM340 752.1c-12.3 2.1-18.9 4.4-31.5 10.7-10.5 5.3-11.8 4.4 13 9.2 69 13.5 135.5 34.9 186.8 60.2 24.5 12.1 41 22.8 49.7 32.3 24.3 26.6 37.9 39.4 60 56.6 50.3 39.2 116.2 69.8 162.5 75.5 2.8.3 6.8.9 9 1.3 4.8.9 28.3.6 34-.3 23.2-4 37.1-11.8 56.6-31.7 33-33.8 46.8-81.2 37.4-128.4-3.2-16-8-29.9-16.2-46.5l-4.2-8.5-.1 8c-.1 4.4-.3 8.7-.4 9.5-.2.8-.6 3.8-1 6.6-1.8 14.4-15.1 40.8-26.4 52.7-17.8 18.7-53.6 23.1-99.2 12.2-5.8-1.4-11.5-2.7-12.6-3-1.2-.3-7.7-2.3-14.5-4.6-36.3-12-78-32.8-111.4-55.7-6-4.1-13-8.4-15.5-9.4-2.5-1.1-5.4-2.3-6.5-2.8-5.6-2.4-39.7-11.2-52.5-13.5-1.9-.3-4.2-.7-5-.9-.8-.1-4-.8-7-1.4-9.8-2-26.4-5.1-30-5.6-3-.5-29.1-4.8-37-6.1-1.4-.2-4.3-.7-6.5-1-6.9-1.1-9.8-1.5-15.5-2.5-3-.5-8.2-1.2-11.5-1.6-3.3-.3-6.2-.7-6.5-.9-.3-.2-4.4-.9-9-1.5-4.7-.6-9.6-1.3-11-1.5-1.4-.2-6.3-.9-11-1.5s-9.6-1.3-11-1.5c-5.9-.8-10.8-1.5-15-2-5.1-.6-9.4-1.2-16-2.1-7.1-.9-20.1-1.1-25-.3z"/></svg>
|
||||
|
After Width: | Height: | Size: 4.0 KiB |
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "Advanced Algos",
|
||||
"short_name": "Advanced Algos",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/android-chrome-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"theme_color": "#ffffff",
|
||||
"background_color": "#ffffff",
|
||||
"display": "standalone"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
export const AUTH_CONFIG = {
|
||||
api_audience: process.env.AUTH0_AUDIENCE,
|
||||
domain: process.env.AUTH0_DOMAIN,
|
||||
clientId: process.env.AUTH0_CLIENTID,
|
||||
callbackUrl: process.env.AUTH0_CALLBACK_URL,
|
||||
logoutUrl: process.env.AUTH0_LOGOUT_URL
|
||||
}
|
||||
@@ -0,0 +1,256 @@
|
||||
import Auth0Lock from 'auth0-lock'
|
||||
import gql from 'graphql-tag'
|
||||
|
||||
import { getItem, setItem, removeItem } from '../utils/local-storage'
|
||||
import { validObject, deleteCookie } from '../utils/js-helpers'
|
||||
|
||||
import { client } from '../App'
|
||||
|
||||
import { AUTH_CONFIG } from './Auth0' // create by renaming Auth0.sample.js to Auth0.js and setting vars
|
||||
|
||||
const AUTHENTICATE = gql`
|
||||
mutation authenticate($idToken: String!) {
|
||||
authenticate(idToken: $idToken) {
|
||||
alias
|
||||
authId
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const VERIFY_TEAM_INVITE = gql`
|
||||
mutation verifyTeamInvite($token: String!) {
|
||||
verifyTeamInvite(token: $token) {
|
||||
email
|
||||
team {
|
||||
slug
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
export const defaultOptions = {
|
||||
oidcConformant: true,
|
||||
autoclose: true,
|
||||
auth: {
|
||||
sso: true,
|
||||
redirectUrl: window.location.origin + '/callback',
|
||||
responseType: 'token id_token',
|
||||
audience: `${AUTH_CONFIG.api_audience}`,
|
||||
params: {
|
||||
scope: `openid profile email user_metadata app_metadata picture`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const inviteOptions = {
|
||||
oidcConformant: true,
|
||||
autoclose: false,
|
||||
allowedConnections: ['Username-Password-Authentication'],
|
||||
allowShowPassword: true,
|
||||
auth: {
|
||||
sso: false,
|
||||
redirectUrl: window.location.origin + '/callback',
|
||||
responseType: 'token id_token',
|
||||
audience: `${AUTH_CONFIG.api_audience}`,
|
||||
params: {
|
||||
state: '',
|
||||
scope: `email`
|
||||
}
|
||||
},
|
||||
prefill: { email: '' }
|
||||
}
|
||||
|
||||
let lock = new Auth0Lock(AUTH_CONFIG.clientId, AUTH_CONFIG.domain, defaultOptions)
|
||||
|
||||
class Auth {
|
||||
constructor (cb, apolloClient) {
|
||||
this.handleAuthentication()
|
||||
// binds functions to keep this context
|
||||
this.apolloClient = apolloClient
|
||||
this.cb = cb.bind(this)
|
||||
this.login = this.login.bind(this)
|
||||
this.loginInvite = this.loginInvite.bind(this)
|
||||
this.logout = this.logout.bind(this)
|
||||
this.isAuthenticated = this.isAuthenticated.bind(this)
|
||||
this.checkSession = this.checkSession.bind(this)
|
||||
}
|
||||
|
||||
login () {
|
||||
// Call the show method to display the widget.
|
||||
lock.show()
|
||||
}
|
||||
|
||||
async loginInvite (jwt) {
|
||||
let email
|
||||
let team
|
||||
try {
|
||||
const data = await client.mutate({
|
||||
mutation: VERIFY_TEAM_INVITE,
|
||||
variables: { token: jwt }
|
||||
})
|
||||
|
||||
console.log('loginInvite auth: ', await data.data.verifyTeamInvite)
|
||||
setItem('invite', JSON.stringify(data.data.verifyTeamInvite))
|
||||
|
||||
email = data.data.verifyTeamInvite.email
|
||||
team = data.data.verifyTeamInvite.team.slug
|
||||
} catch (err) {
|
||||
return console.log('loginInvite err: ', err)
|
||||
}
|
||||
inviteOptions.prefill.email = email
|
||||
inviteOptions.auth.params.state = `${email}|${team}`
|
||||
let lockInvite = new Auth0Lock(AUTH_CONFIG.clientId, AUTH_CONFIG.domain, inviteOptions)
|
||||
lockInvite.show()
|
||||
}
|
||||
|
||||
handleAuthentication () {
|
||||
// Add a callback for Lock's `authenticated` event
|
||||
lock.on('authenticated', this.setSession.bind(this))
|
||||
// Add a callback for Lock's `authorization_error` event
|
||||
lock.on('authorization_error', err => {
|
||||
const data = { status: `error`, errMessage: err.error }
|
||||
this.cb(data)
|
||||
})
|
||||
}
|
||||
|
||||
checkSession () {
|
||||
return new Promise((resolve, reject) => {
|
||||
// Add a callback for Lock's `authenticated` event
|
||||
lock.checkSession(
|
||||
{
|
||||
responseType: 'token id_token',
|
||||
audience: AUTH_CONFIG.api_audience,
|
||||
scope:
|
||||
'openid email profile read:teams write:teams read:member write:member',
|
||||
connection: 'github',
|
||||
prompt: 'none'
|
||||
},
|
||||
function (err, authResult) {
|
||||
if (!err) {
|
||||
resolve(authResult)
|
||||
} else {
|
||||
reject(err)
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
setSession (authResult) {
|
||||
if (authResult && authResult.accessToken && authResult.idToken) {
|
||||
// Set the time that the access token will expire at
|
||||
let expiresAt = JSON.stringify(
|
||||
authResult.expiresIn * 1000 + new Date().getTime()
|
||||
)
|
||||
setItem('access_token', authResult.accessToken)
|
||||
setItem('id_token', authResult.idToken)
|
||||
setItem('expires_at', expiresAt)
|
||||
const data = {
|
||||
status: `success`,
|
||||
accessToken: authResult.accessToken,
|
||||
idToken: authResult.idToken,
|
||||
expiresAt
|
||||
}
|
||||
console.log('setSession idTokenPayload: ', authResult.idTokenPayload)
|
||||
|
||||
this.signinOrCreateAccount({ ...data })
|
||||
this.cb(data)
|
||||
const user = {
|
||||
authId: authResult.idTokenPayload.sub,
|
||||
alias: authResult.idTokenPayload.nickname
|
||||
}
|
||||
setItem('user', JSON.stringify(user))
|
||||
if (window.location.href.includes(`callback`)) {
|
||||
// window.location.href = '/dashboard'
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
async signinOrCreateAccount ({ accessToken, idToken, expiresAt }) {
|
||||
try {
|
||||
const data = await client.mutate({
|
||||
mutation: AUTHENTICATE,
|
||||
variables: { idToken }
|
||||
})
|
||||
|
||||
const user = {
|
||||
authId: data.data.authenticate.authId,
|
||||
alias: data.data.authenticate.alias
|
||||
}
|
||||
setItem('user', JSON.stringify(user))
|
||||
if (window.location.href.includes(`callback`)) {
|
||||
window.location.href = '/dashboard'
|
||||
}
|
||||
return data
|
||||
} catch (err) {
|
||||
return console.log('Sign in or create account error: ', err)
|
||||
}
|
||||
}
|
||||
|
||||
logout () {
|
||||
// Clear access token and ID token from local storage
|
||||
removeItem('access_token')
|
||||
removeItem('id_token')
|
||||
removeItem('expires_at')
|
||||
removeItem('authUser')
|
||||
removeItem('auth0.ssodata')
|
||||
window.localStorage.clear()
|
||||
deleteCookie('ajs_anonymous_id')
|
||||
deleteCookie('ajs_user_id')
|
||||
deleteCookie('current_tenant')
|
||||
|
||||
lock.logout({ returnTo: AUTH_CONFIG.logoutUrl })
|
||||
}
|
||||
|
||||
async isAuthenticated () {
|
||||
// check session and run Auth0 SS0
|
||||
const getUser = await getItem('authUser')
|
||||
const getExpires = await getItem('expires_at')
|
||||
let user = JSON.parse(getUser)
|
||||
|
||||
if (new Date().getTime() < getExpires * 1000) {
|
||||
console.log(
|
||||
'handleAuth.user exp: ',
|
||||
user,
|
||||
getExpires,
|
||||
window.location.href
|
||||
)
|
||||
|
||||
return user
|
||||
}
|
||||
|
||||
const checkSSO = await this.checkSession()
|
||||
.then(result => {
|
||||
console.log('handleAuth.checksessions: ', result)
|
||||
const user = {
|
||||
authId: result.idTokenPayload.sub,
|
||||
alias: result.idTokenPayload.nickname
|
||||
}
|
||||
setItem('authUser', JSON.stringify(user))
|
||||
// user confirmed, log into client
|
||||
this.setSession(result)
|
||||
return result.idTokenPayload
|
||||
})
|
||||
.catch(err => {
|
||||
if (err.error === 'login_required') {
|
||||
// If graphql error, update session
|
||||
// otherwise send to login
|
||||
// return this.login()
|
||||
}
|
||||
return err
|
||||
})
|
||||
|
||||
if (/manage|profile|create|dashboard/.test(window.location.href) && !user) {
|
||||
this.login()
|
||||
}
|
||||
|
||||
if (validObject(checkSSO, 'error')) {
|
||||
return false
|
||||
} else {
|
||||
return checkSSO
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Auth
|
||||
@@ -0,0 +1,113 @@
|
||||
import { ApolloClient } from 'apollo-client'
|
||||
import { HttpLink } from 'apollo-link-http'
|
||||
import { InMemoryCache } from 'apollo-cache-inmemory'
|
||||
import { ApolloLink, split, Observable } from 'apollo-link'
|
||||
import { onError } from 'apollo-link-error'
|
||||
import { setContext } from 'apollo-link-context'
|
||||
import { WebSocketLink } from 'apollo-link-ws'
|
||||
import { SubscriptionClient } from 'subscriptions-transport-ws'
|
||||
import { getMainDefinition } from 'apollo-utilities'
|
||||
|
||||
import { getItem } from './utils/local-storage'
|
||||
|
||||
const graphqlEndpoint =
|
||||
process.env.NODE_ENV === 'production'
|
||||
? process.env.PROD_GRAPHQL
|
||||
: process.env.DEV_GRAPHQL
|
||||
|
||||
const wsUri = graphqlEndpoint.replace(/^http/, 'ws')
|
||||
|
||||
const globalVar =
|
||||
typeof global !== 'undefined'
|
||||
? global
|
||||
: typeof window !== 'undefined'
|
||||
? window
|
||||
: {}
|
||||
const webSocketImpl = globalVar.WebSocket || globalVar.MozWebSocket
|
||||
|
||||
const wsClient = new SubscriptionClient(
|
||||
wsUri,
|
||||
{
|
||||
reconnect: true
|
||||
},
|
||||
webSocketImpl
|
||||
)
|
||||
|
||||
wsClient.onDisconnected(() => {
|
||||
// console.log('onDisconnected')
|
||||
})
|
||||
|
||||
wsClient.onReconnected(() => {
|
||||
// console.log('onReconnected')
|
||||
})
|
||||
|
||||
const httpLink = new HttpLink({ uri: graphqlEndpoint })
|
||||
|
||||
const link = split(
|
||||
({ query }) => {
|
||||
const { kind, operation } = getMainDefinition(query)
|
||||
return kind === 'OperationDefinition' && operation === 'subscription'
|
||||
},
|
||||
new WebSocketLink(wsClient),
|
||||
httpLink
|
||||
)
|
||||
|
||||
const authRetryLink = onError(
|
||||
({ graphQLErrors, networkError, operation, forward }) => {
|
||||
if (graphQLErrors) {
|
||||
// User access token has expired
|
||||
// console.log('authLink: ', graphQLErrors) // check for error message to intercept and resend with Auth0 access token
|
||||
if (graphQLErrors[0].message === 'Not logged in') {
|
||||
// We assume we have auth0 access token needed to run the async request
|
||||
// Let's refresh token through async request
|
||||
return new Observable(observer => {
|
||||
getItem('access_token')
|
||||
.then(accessToken => {
|
||||
operation.setContext(({ headers = {} }) => ({
|
||||
headers: {
|
||||
// Re-add old headers
|
||||
...headers,
|
||||
// Switch out old access token for new one
|
||||
Authorization: `Bearer ${accessToken}` || null
|
||||
}
|
||||
}))
|
||||
})
|
||||
.then(() => {
|
||||
const subscriber = {
|
||||
next: observer.next.bind(observer),
|
||||
error: observer.error.bind(observer),
|
||||
complete: observer.complete.bind(observer)
|
||||
}
|
||||
|
||||
// Retry last failed request
|
||||
forward(operation).subscribe(subscriber)
|
||||
})
|
||||
.catch(error => {
|
||||
// No auth0 access token available, we force user to login
|
||||
observer.error(error)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const authLink = setContext(async (_, { headers }) => {
|
||||
// get the authentication token from local storage if it exists
|
||||
await getItem('access_token').then(token => {
|
||||
return {
|
||||
headers: {
|
||||
...headers,
|
||||
Authorization: token ? `Bearer ${token}` : ``
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
const cache = new InMemoryCache().restore(window.__APOLLO_STATE__)
|
||||
|
||||
export const client = new ApolloClient({
|
||||
link: ApolloLink.from([authRetryLink, authLink, link]),
|
||||
cache,
|
||||
connectToDevTools: true
|
||||
})
|
||||
@@ -2,9 +2,9 @@
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
|
||||
import App from './App'
|
||||
import MasterApp from './App'
|
||||
|
||||
ReactDOM.render(<App />, document.getElementById('root'))
|
||||
ReactDOM.render(<MasterApp />, document.getElementById('root'))
|
||||
|
||||
let frontendReloadCount = 0
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
import { createMuiTheme } from '@material-ui/core/styles'
|
||||
import indigo from '@material-ui/core/colors/indigo'
|
||||
// import red from '@material-ui/core/colors/red'
|
||||
|
||||
export const theme = createMuiTheme({
|
||||
palette: {
|
||||
primary: { main: '#303036' },
|
||||
secondary: indigo
|
||||
},
|
||||
typography: {
|
||||
fontFamily: '"Saira","Saira Condenses", sans-serif'
|
||||
},
|
||||
overrides: {
|
||||
Paper: {
|
||||
root: {
|
||||
backgroundColor: '#ffffff'
|
||||
},
|
||||
elevation: 0,
|
||||
square: true
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export const globalStyles = theme => ({
|
||||
'@global': {
|
||||
body: {
|
||||
backgroundColor: theme.palette.common.white
|
||||
}
|
||||
},
|
||||
appBar: {
|
||||
position: 'relative'
|
||||
},
|
||||
toolbarTitle: {
|
||||
flex: 1
|
||||
},
|
||||
layout: {
|
||||
width: 'auto',
|
||||
marginLeft: theme.spacing.unit * 3,
|
||||
marginRight: theme.spacing.unit * 3,
|
||||
[theme.breakpoints.up(900 + theme.spacing.unit * 3 * 2)]: {
|
||||
width: 900,
|
||||
marginLeft: 'auto',
|
||||
marginRight: 'auto'
|
||||
}
|
||||
},
|
||||
heroContent: {
|
||||
maxWidth: 600,
|
||||
margin: '0 auto',
|
||||
padding: `${theme.spacing.unit * 8}px 0 ${theme.spacing.unit * 6}px`
|
||||
},
|
||||
cardHeader: {
|
||||
backgroundColor: theme.palette.grey[200]
|
||||
},
|
||||
cardPricing: {
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'baseline',
|
||||
marginBottom: theme.spacing.unit * 2
|
||||
},
|
||||
cardActions: {
|
||||
[theme.breakpoints.up('sm')]: {
|
||||
paddingBottom: theme.spacing.unit * 2
|
||||
}
|
||||
},
|
||||
footer: {
|
||||
marginTop: theme.spacing.unit * 8,
|
||||
borderTop: `1px solid ${theme.palette.divider}`,
|
||||
padding: `${theme.spacing.unit * 6}px 0`
|
||||
}
|
||||
})
|
||||
|
||||
export default theme
|
||||
@@ -0,0 +1,70 @@
|
||||
export function isDefined (d) {
|
||||
return d !== null && typeof d !== 'undefined'
|
||||
}
|
||||
|
||||
export function isNotDefined (d) {
|
||||
return !isDefined(d)
|
||||
}
|
||||
|
||||
export const isArray = Array.isArray
|
||||
|
||||
export function isObject (d) {
|
||||
return isDefined(d) && typeof d === 'object' && !Array.isArray(d)
|
||||
}
|
||||
|
||||
export function isEmpty (obj) {
|
||||
for (var key in obj) {
|
||||
if (obj.hasOwnProperty(key)) return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
export function isString (value) {
|
||||
return typeof value === 'string' || value instanceof String
|
||||
}
|
||||
|
||||
export function validObject (object, ...keys) {
|
||||
return keys.reduce((a, b) => (a || {})[b], object) !== undefined
|
||||
}
|
||||
|
||||
export function mergeDeep (target, ...sources) {
|
||||
if (!sources.length) return target
|
||||
const source = sources.shift()
|
||||
|
||||
if (isObject(target) && isObject(source)) {
|
||||
for (const key in source) {
|
||||
if (isObject(source[key])) {
|
||||
if (!target[key]) Object.assign(target, { [key]: {} })
|
||||
mergeDeep(target[key], source[key])
|
||||
} else {
|
||||
Object.assign(target, { [key]: source[key] })
|
||||
}
|
||||
}
|
||||
}
|
||||
return mergeDeep(target, ...sources)
|
||||
}
|
||||
|
||||
export function deleteCookie (c) {
|
||||
document.cookie.split(';').forEach(function (c) {
|
||||
document.cookie = c
|
||||
.replace(/^ +/, '')
|
||||
.replace(/=.*/, '=;expires=' + new Date().toUTCString() + ';path=/')
|
||||
})
|
||||
}
|
||||
|
||||
export function slugify (string) {
|
||||
const a = 'àáäâãåèéëêìíïîòóöôùúüûñçßÿœæŕśńṕẃǵǹḿǘẍźḧ·/_,:;'
|
||||
const b = 'aaaaaaeeeeiiiioooouuuuncsyoarsnpwgnmuxzh------'
|
||||
const p = new RegExp(a.split('').join('|'), 'g')
|
||||
|
||||
return string
|
||||
.toString()
|
||||
.toLowerCase()
|
||||
.replace(/\s+/g, '-') // Replace spaces with -
|
||||
.replace(p, c => b.charAt(a.indexOf(c))) // Replace special characters
|
||||
.replace(/&/g, '-and-') // Replace & with 'and'
|
||||
.replace(/[^\w-]+/g, '') // Remove all non-word characters
|
||||
.replace(/--+/g, '-') // Replace multiple - with single -
|
||||
.replace(/^-+/, '') // Trim - from start of text
|
||||
.replace(/-+$/, '') // Trim - from end of text
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
const getItem = async name => window.localStorage.getItem(name)
|
||||
const setItem = async (name, value) => window.localStorage.setItem(name, value)
|
||||
const removeItem = async name => window.localStorage.removeItem(name)
|
||||
|
||||
export {
|
||||
getItem,
|
||||
setItem,
|
||||
removeItem
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { NavLink } from 'react-router-dom'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import classNames from 'classnames'
|
||||
import Typography from '@material-ui/core/Typography'
|
||||
import Grid from '@material-ui/core/Grid'
|
||||
|
||||
import aalogo from '../../assets/advanced-algos/aa-logo-vert.svg'
|
||||
|
||||
const styles = theme => ({
|
||||
'@global': {
|
||||
body: {
|
||||
backgroundColor: theme.palette.common.white
|
||||
}
|
||||
},
|
||||
layout: {
|
||||
width: 'auto',
|
||||
marginTop: theme.spacing.unit * 7,
|
||||
marginLeft: theme.spacing.unit * 3,
|
||||
marginRight: theme.spacing.unit * 3,
|
||||
[theme.breakpoints.up(1200 + theme.spacing.unit * 3 * 2)]: {
|
||||
width: 1200,
|
||||
marginLeft: 'auto',
|
||||
marginRight: 'auto'
|
||||
}
|
||||
},
|
||||
footer: {
|
||||
borderTop: `1px solid ${theme.palette.divider}`,
|
||||
padding: `${theme.spacing.unit * 6}px 0`
|
||||
},
|
||||
footerContainer: {
|
||||
marginRight: theme.spacing.unit * 8,
|
||||
marginLeft: theme.spacing.unit * 8
|
||||
},
|
||||
footerLink: {
|
||||
textDecoration: 'none'
|
||||
}
|
||||
})
|
||||
|
||||
const Footer = ({ classes }) => {
|
||||
return (
|
||||
<footer className={classNames(classes.footer, classes.layout)}>
|
||||
<Grid
|
||||
container
|
||||
spacing={32}
|
||||
justify='space-evenly'
|
||||
className={classNames(classes.footerContainer)}
|
||||
>
|
||||
<Grid item xs>
|
||||
<Typography variant='title' color='textPrimary' gutterBottom>
|
||||
Pages
|
||||
</Typography>
|
||||
<NavLink to='/' className={classNames(classes.footerLink)}>
|
||||
<Typography variant='subheading' color='textSecondary'>
|
||||
Home
|
||||
</Typography>
|
||||
</NavLink>
|
||||
<NavLink to='/browse' className={classNames(classes.footerLink)}>
|
||||
<Typography variant='subheading' color='textSecondary'>
|
||||
Browse
|
||||
</Typography>
|
||||
</NavLink>
|
||||
<NavLink to='/search' className={classNames(classes.footerLink)}>
|
||||
<Typography variant='subheading' color='textSecondary'>
|
||||
Search
|
||||
</Typography>
|
||||
</NavLink>
|
||||
<NavLink to='/contact' className={classNames(classes.footerLink)}>
|
||||
<Typography variant='subheading' color='textSecondary'>
|
||||
Contact
|
||||
</Typography>
|
||||
</NavLink>
|
||||
<NavLink to='/about' className={classNames(classes.footerLink)}>
|
||||
<Typography variant='subheading' color='textSecondary'>
|
||||
About
|
||||
</Typography>
|
||||
</NavLink>
|
||||
</Grid>
|
||||
<Grid item xs>
|
||||
|
||||
<Typography variant='title' color='textPrimary' gutterBottom>
|
||||
Support
|
||||
</Typography>
|
||||
|
||||
<a
|
||||
href='https://advancedalgos.net/documentation-quick-start.shtml'
|
||||
target='_blank>'
|
||||
className={classNames(classes.footerLink)}
|
||||
>
|
||||
<Typography variant='subheading' color='textSecondary'>
|
||||
Documentation
|
||||
</Typography>
|
||||
</a>
|
||||
<a
|
||||
href='https://t.me/advancedalgoscommunity'
|
||||
target='_blank>'
|
||||
className={classNames(classes.footerLink)}
|
||||
>
|
||||
<Typography variant='subheading' color='textSecondary'>
|
||||
Telegram
|
||||
</Typography>
|
||||
</a>
|
||||
</Grid>
|
||||
<Grid item xs>
|
||||
<Typography variant='title' color='textPrimary' gutterBottom>
|
||||
Modules
|
||||
</Typography>
|
||||
<a
|
||||
href='https://develop.advancedalgos.net'
|
||||
target='_blank>'
|
||||
className={classNames(classes.footerLink)}
|
||||
>
|
||||
<Typography variant='subheading' color='textSecondary'>
|
||||
Platform
|
||||
</Typography>
|
||||
</a>
|
||||
<a
|
||||
href='https://users.advancedalgos.net'
|
||||
target='_blank>'
|
||||
className={classNames(classes.footerLink)}
|
||||
>
|
||||
<Typography variant='subheading' color='textSecondary'>
|
||||
Users
|
||||
</Typography>
|
||||
</a>
|
||||
<a
|
||||
href='https://teams.advancedalgos.net'
|
||||
target='_blank>'
|
||||
className={classNames(classes.footerLink)}
|
||||
>
|
||||
<Typography variant='subheading' color='textSecondary'>
|
||||
Teams
|
||||
</Typography>
|
||||
</a>
|
||||
<a
|
||||
href='https://keyvault.advancedalgos.net'
|
||||
target='_blank>'
|
||||
className={classNames(classes.footerLink)}
|
||||
>
|
||||
<Typography variant='subheading' color='textSecondary'>
|
||||
Key Vault
|
||||
</Typography>
|
||||
</a>
|
||||
</Grid>
|
||||
<Grid item xs>
|
||||
<NavLink to='/'>
|
||||
<img alt='' src={aalogo} width={98} height={140} />
|
||||
</NavLink>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</footer>
|
||||
)
|
||||
}
|
||||
|
||||
Footer.propTypes = {
|
||||
classes: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
export default withStyles(styles)(Footer)
|
||||
@@ -0,0 +1,47 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { graphql } from 'react-apollo'
|
||||
|
||||
import LoggedInMenu from './LoggedInMenu'
|
||||
|
||||
import { GetCurrentMember } from '../../graphql/members'
|
||||
|
||||
import { isDefined } from '../../utils/js-helpers'
|
||||
|
||||
export const LoggedIn = props => {
|
||||
let { data, user, auth } = props
|
||||
console.log('LoggedIn :', data, user)
|
||||
let displayName = 'No Display Name'
|
||||
|
||||
if (isDefined(user.alias)) {
|
||||
displayName = user.alias
|
||||
}
|
||||
|
||||
if (isDefined(user.nickname)) {
|
||||
displayName = user.nickname
|
||||
}
|
||||
|
||||
if (isDefined(user.firstName)) {
|
||||
displayName = user.firstName
|
||||
}
|
||||
|
||||
if (isDefined(user.firstName) && isDefined(user.lastName)) {
|
||||
displayName = user.firstName + ' ' + user.lastName
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<p>
|
||||
<LoggedInMenu menuLabel={displayName} auth={auth} />
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
LoggedIn.propTypes = {
|
||||
data: PropTypes.object,
|
||||
user: PropTypes.object.isRequired,
|
||||
auth: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
export default graphql(GetCurrentMember)(LoggedIn)
|
||||
@@ -0,0 +1,77 @@
|
||||
import React, { Component } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import Button from '@material-ui/core/Button'
|
||||
import Menu from '@material-ui/core/Menu'
|
||||
import MenuItem from '@material-ui/core/MenuItem'
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
import ProfileIcon from '@material-ui/icons/Person'
|
||||
import LogoutIcon from '@material-ui/icons/DirectionsWalk'
|
||||
|
||||
const UserLink = props => <Link to='/user' {...props} />
|
||||
const LogoutLink = props => <Link to='/' {...props} />
|
||||
|
||||
class LoggedInUserMenu extends Component {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
|
||||
this.handleMenu = this.handleMenu.bind(this)
|
||||
this.handleClose = this.handleClose.bind(this)
|
||||
this.handleLogout = this.handleLogout.bind(this)
|
||||
|
||||
this.state = {
|
||||
menu: null
|
||||
}
|
||||
}
|
||||
|
||||
render () {
|
||||
const { menuLabel } = this.props
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Button
|
||||
aria-owns={this.state.open ? 'render-props-menu' : null}
|
||||
aria-haspopup='true'
|
||||
onClick={e => this.handleMenu(e)}
|
||||
color='inherit'
|
||||
>
|
||||
{menuLabel}
|
||||
</Button>
|
||||
<Menu
|
||||
id='render-props-menu'
|
||||
anchorEl={this.state.menu}
|
||||
open={Boolean(this.state.menu)}
|
||||
onClose={this.handleClose}
|
||||
>
|
||||
<MenuItem onClick={this.handleClose} component={UserLink}>
|
||||
<ProfileIcon />
|
||||
<div>Profile</div>
|
||||
</MenuItem>
|
||||
<MenuItem onClick={this.handleLogout} component={LogoutLink}>
|
||||
<LogoutIcon />
|
||||
<div>Logout</div>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
handleMenu (e) {
|
||||
this.setState({ menu: e.currentTarget })
|
||||
}
|
||||
|
||||
handleClose () {
|
||||
this.setState({ menu: null })
|
||||
}
|
||||
|
||||
handleLogout () {
|
||||
this.props.auth.logout()
|
||||
this.setState({ menu: null })
|
||||
}
|
||||
}
|
||||
|
||||
LoggedInUserMenu.propTypes = {
|
||||
menuLabel: PropTypes.string.isRequired,
|
||||
auth: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
export default LoggedInUserMenu
|
||||
@@ -0,0 +1,141 @@
|
||||
import React, { Component } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import AppBar from '@material-ui/core/AppBar'
|
||||
import Toolbar from '@material-ui/core/Toolbar'
|
||||
import Typography from '@material-ui/core/Typography'
|
||||
import IconButton from '@material-ui/core/IconButton'
|
||||
import Button from '@material-ui/core/Button'
|
||||
|
||||
// icons
|
||||
import HomeIcon from '@material-ui/icons/Home'
|
||||
import DashboardIcon from '@material-ui/icons/Dashboard'
|
||||
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
import { getItem } from '../../utils/local-storage'
|
||||
|
||||
// components
|
||||
import { LoggedIn } from './LoggedIn'
|
||||
import { LoggedOut } from './LoggedOut'
|
||||
|
||||
import AALogo from '../../assets/advanced-algos/aa-logo-dark.svg'
|
||||
|
||||
const AboutLink = props => <Link to='/about' {...props} />
|
||||
const TeamsLink = props => <Link to='/teams' {...props} />
|
||||
const DashboardLink = props => <Link to='/dashboard' {...props} />
|
||||
const HomeLink = props => <Link to='/' {...props} />
|
||||
|
||||
const styles = theme => ({
|
||||
'@global': {
|
||||
body: {
|
||||
backgroundColor: theme.palette.common.white
|
||||
}
|
||||
},
|
||||
root: {
|
||||
flexGrow: 1
|
||||
},
|
||||
colorDefault: {
|
||||
color: '#000'
|
||||
},
|
||||
flex: {
|
||||
flexGrow: 1
|
||||
},
|
||||
toolbarTitle: {
|
||||
flex: 1
|
||||
},
|
||||
menuButton: {
|
||||
marginLeft: -12,
|
||||
marginRight: 20
|
||||
},
|
||||
appBar: {
|
||||
position: 'relative'
|
||||
},
|
||||
img: {
|
||||
margin: 20,
|
||||
display: 'block',
|
||||
maxWidth: 240,
|
||||
maxHeight: 48
|
||||
}
|
||||
})
|
||||
|
||||
class Header extends Component {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
user: null,
|
||||
open: false
|
||||
}
|
||||
}
|
||||
|
||||
async componentDidMount () {
|
||||
const user = await getItem('user')
|
||||
console.log('NavBar CDM: ', user, this.state)
|
||||
this.setState({ user })
|
||||
}
|
||||
|
||||
render () {
|
||||
let { classes, auth } = this.props
|
||||
|
||||
let user = JSON.parse(this.state.user)
|
||||
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
<AppBar
|
||||
position='static'
|
||||
classes={{ root: classes.appBar, colorDefault: classes.colorDefault }}
|
||||
>
|
||||
<Toolbar>
|
||||
<img className={classes.img} src={AALogo} alt='Advanced Algos' />
|
||||
<Typography
|
||||
variant='title'
|
||||
color='inherit'
|
||||
className={classes.toolbarTitle}
|
||||
>
|
||||
Teams
|
||||
</Typography>
|
||||
|
||||
<IconButton
|
||||
className={classes.menuButton}
|
||||
color='inherit'
|
||||
title='Home'
|
||||
component={HomeLink}
|
||||
>
|
||||
<HomeIcon />
|
||||
</IconButton>
|
||||
<Button component={TeamsLink} color='inherit'>
|
||||
Teams
|
||||
</Button>
|
||||
<Button component={AboutLink} color='inherit'>
|
||||
About
|
||||
</Button>
|
||||
|
||||
{this.state.user !== undefined && this.state.user !== null ? (
|
||||
<React.Fragment>
|
||||
<IconButton
|
||||
className={classes.menuButton}
|
||||
color='inherit'
|
||||
title='Dashboard'
|
||||
component={DashboardLink}
|
||||
>
|
||||
<DashboardIcon />
|
||||
</IconButton>
|
||||
<LoggedIn user={user} auth={auth} styles={styles} />
|
||||
</React.Fragment>
|
||||
) : (
|
||||
<LoggedOut auth={auth} styles={styles} />
|
||||
)}
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Header.propTypes = {
|
||||
classes: PropTypes.object.isRequired,
|
||||
auth: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
export default withStyles(styles)(Header)
|
||||
@@ -0,0 +1,61 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
import CssBaseline from '@material-ui/core/CssBaseline'
|
||||
import Typography from '@material-ui/core/Typography'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
|
||||
const styles = theme => ({
|
||||
'@global': {
|
||||
body: {
|
||||
backgroundColor: theme.palette.common.white
|
||||
}
|
||||
},
|
||||
layout: {
|
||||
width: 'auto',
|
||||
marginLeft: theme.spacing.unit * 3,
|
||||
marginRight: theme.spacing.unit * 3,
|
||||
[theme.breakpoints.up(900 + theme.spacing.unit * 3 * 2)]: {
|
||||
width: 900,
|
||||
marginLeft: 'auto',
|
||||
marginRight: 'auto'
|
||||
}
|
||||
},
|
||||
heroContent: {
|
||||
maxWidth: 600,
|
||||
margin: '0 auto',
|
||||
padding: `${theme.spacing.unit * 8}px 0 ${theme.spacing.unit * 6}px`
|
||||
}
|
||||
})
|
||||
|
||||
const Home = ({ classes }) => (
|
||||
<React.Fragment>
|
||||
<CssBaseline />
|
||||
<main className={classes.layout}>
|
||||
<div className={classes.heroContent}>
|
||||
<Typography
|
||||
variant='display3'
|
||||
align='center'
|
||||
color='textPrimary'
|
||||
gutterBottom
|
||||
>
|
||||
Collaborate. Innovate. Evolve.
|
||||
</Typography>
|
||||
<Typography
|
||||
variant='title'
|
||||
align='center'
|
||||
color='textSecondary'
|
||||
component='h3'
|
||||
>
|
||||
Welcome to Advanced Algos
|
||||
</Typography>
|
||||
</div>
|
||||
</main>
|
||||
</React.Fragment>
|
||||
)
|
||||
|
||||
Home.propTypes = {
|
||||
classes: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
export default withStyles(styles)(Home)
|
||||
@@ -0,0 +1,6 @@
|
||||
import Header from './header'
|
||||
import Footer from './footer'
|
||||
import Home from './home'
|
||||
import Callback from './callback'
|
||||
|
||||
export { Header, Footer, Home, Callback }
|
||||