diff --git a/package.json b/package.json index ddf69a2..b019e03 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "dependencies": { "ical.js": "^1.2.2", "isomorphic-fetch": "^2.1.1", + "material-ui": "^0.20.0", "react": "^16.2.0", "react-dom": "^16.2.0", "react-router-dom": "^4.2.2", @@ -21,6 +22,7 @@ "devDependencies": { "@types/isomorphic-fetch": "^0.0.34", "@types/jest": "^21.1.8", + "@types/material-ui": "^0.18.5", "@types/node": "^8.0.53", "@types/react": "^16.0.25", "@types/react-dom": "^16.0.3", diff --git a/src/App.css b/src/App.css index 15adfdc..dbba618 100644 --- a/src/App.css +++ b/src/App.css @@ -18,7 +18,12 @@ font-size: large; } -@keyframes App-logo-spin { - from { transform: rotate(0deg); } - to { transform: rotate(360deg); } +.App-drawer-header { + background-color: #555; + padding: 10px; +} + +.App-drawer-logo { + width: 60px; + margin-bottom: 10px; } diff --git a/src/App.tsx b/src/App.tsx index 872b96d..546fa23 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,10 +1,47 @@ import * as React from 'react'; import { HashRouter } from 'react-router-dom'; +import getMuiTheme from 'material-ui/styles/getMuiTheme'; +import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; +import { amber500, amber700, lightBlue500, darkBlack, white } from 'material-ui/styles/colors'; +import AppBar from 'material-ui/AppBar'; +import Drawer from 'material-ui/Drawer'; +import IconButton from 'material-ui/IconButton'; +import { List, ListItem } from 'material-ui/List'; +import ActionCode from 'material-ui/svg-icons/action/code'; +import ActionHome from 'material-ui/svg-icons/action/home'; +import ActionBugReport from 'material-ui/svg-icons/action/bug-report'; +import ActionQuestionAnswer from 'material-ui/svg-icons/action/question-answer'; + +import NavigationMenu from 'material-ui/svg-icons/navigation/menu'; + import './App.css'; import { EteSyncContext } from './EteSyncContext'; import { RouteResolver } from './routes'; +import * as C from './Constants'; + +const logo = require('./images/logo.svg'); + +const muiTheme = getMuiTheme({ + palette: { + primary1Color: amber500, + primary2Color: amber700, + accent1Color: lightBlue500, + textColor: darkBlack, + alternateTextColor: white, + } +}); + +function getPalette(part: string): string { + const theme = muiTheme; + if ((theme.palette === undefined) || (theme.palette[part] === undefined)) { + return ''; + } + + return theme.palette[part]; +} + export const routeResolver = new RouteResolver({ home: '', journals: { @@ -28,11 +65,59 @@ export const routeResolver = new RouteResolver({ }); class App extends React.Component { + state: { + drawerOpen: boolean, + }; + + constructor(props: any) { + super(props); + this.state = { drawerOpen: false }; + + this.toggleDrawer = this.toggleDrawer.bind(this); + this.closeDrawer = this.closeDrawer.bind(this); + } + + toggleDrawer() { + this.setState({drawerOpen: !this.state.drawerOpen}); + } + + closeDrawer() { + this.setState({drawerOpen: false}); + } + render() { return ( - - - + +
+ } + /> + +
+ +
+ {C.appName} +
+
+ + } href={C.homePage} /> + } href={C.faq} /> + } href={C.sourceCode} /> + } href={C.reportIssue} /> + +
+ + + + +
+
); } } diff --git a/src/Constants.tsx b/src/Constants.tsx new file mode 100644 index 0000000..301fe8d --- /dev/null +++ b/src/Constants.tsx @@ -0,0 +1,7 @@ +export const appName = 'EteSync'; +export const homePage = 'https://www.etesync.com/'; +export const faq = homePage + 'faq/'; +export const sourceCode = 'https://github.com/etesync/etesync-web'; +export const reportIssue = sourceCode + '/issues'; + +export const serviceApiBase = 'http://localhost:8000'; diff --git a/src/EteSyncContext.tsx b/src/EteSyncContext.tsx index 1ba9ae7..fa25a3e 100644 --- a/src/EteSyncContext.tsx +++ b/src/EteSyncContext.tsx @@ -8,7 +8,7 @@ import * as EteSync from './api/EteSync'; import { routeResolver } from './App'; -const SERVICE_API = 'http://localhost:8000'; +import * as C from './Constants'; const CONTEXT_SESSION_KEY = 'EteSyncContext'; @@ -54,7 +54,7 @@ export class EteSyncContext extends React.Component { generateEncryption(e: any) { e.preventDefault(); - let authenticator = new EteSync.Authenticator(SERVICE_API); + let authenticator = new EteSync.Authenticator(C.serviceApiBase); this.setState({ loadState: LoadState.Working @@ -69,7 +69,7 @@ export class EteSyncContext extends React.Component { const derived = EteSync.deriveKey(username, encryptionPassword); const context = { - serviceApiUrl: SERVICE_API, + serviceApiUrl: C.serviceApiBase, credentials, encryptionKey: derived, }; diff --git a/src/images/logo.svg b/src/images/logo.svg new file mode 100644 index 0000000..009f1a8 --- /dev/null +++ b/src/images/logo.svg @@ -0,0 +1,162 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/logo.svg b/src/logo.svg deleted file mode 100644 index 6b60c10..0000000 --- a/src/logo.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/yarn.lock b/yarn.lock index 2414edf..315756b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18,10 +18,23 @@ version "3.2.16" resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.2.16.tgz#04419c404a3194350e7d3f339a90e72c88db3111" +"@types/material-ui@^0.18.5": + version "0.18.5" + resolved "https://registry.yarnpkg.com/@types/material-ui/-/material-ui-0.18.5.tgz#27f791226cc297f5df58ff811067fa44c5599dd3" + dependencies: + "@types/react" "*" + "@types/react-addons-linked-state-mixin" "*" + "@types/node@*", "@types/node@^8.0.53": version "8.0.53" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.53.tgz#396b35af826fa66aad472c8cb7b8d5e277f4e6d8" +"@types/react-addons-linked-state-mixin@*": + version "0.14.18" + resolved "https://registry.yarnpkg.com/@types/react-addons-linked-state-mixin/-/react-addons-linked-state-mixin-0.14.18.tgz#6977ae59e19aa0ce3a5d7a9e057961aaf1afe959" + dependencies: + "@types/react" "*" + "@types/react-dom@^16.0.3": version "16.0.3" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.0.3.tgz#8accad7eabdab4cca3e1a56f5ccb57de2da0ff64" @@ -449,7 +462,7 @@ babel-register@^6.26.0: mkdirp "^0.5.1" source-map-support "^0.4.15" -babel-runtime@^6.22.0, babel-runtime@^6.26.0: +babel-runtime@^6.22.0, babel-runtime@^6.23.0, babel-runtime@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" dependencies: @@ -585,6 +598,10 @@ boom@5.x.x: dependencies: hoek "4.x.x" +bowser@^1.7.3: + version "1.8.1" + resolved "https://registry.yarnpkg.com/bowser/-/bowser-1.8.1.tgz#49785777e7302febadb1a5b71d9a646520ed310d" + boxen@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/boxen/-/boxen-0.6.0.tgz#8364d4248ac34ff0ef1b2f2bf49a6c60ce0d81b6" @@ -800,6 +817,10 @@ center-align@^0.1.1: align-text "^0.1.3" lazy-cache "^1.0.3" +chain-function@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/chain-function/-/chain-function-1.0.0.tgz#0d4ab37e7e18ead0bdc47b920764118ce58733dc" + chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -818,6 +839,10 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0: escape-string-regexp "^1.0.5" supports-color "^4.0.0" +change-emitter@^0.1.2: + version "0.1.6" + resolved "https://registry.yarnpkg.com/change-emitter/-/change-emitter-0.1.6.tgz#e8b2fe3d7f1ab7d69a32199aff91ea6931409515" + chardet@^0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" @@ -1129,6 +1154,12 @@ css-color-names@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" +css-in-js-utils@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/css-in-js-utils/-/css-in-js-utils-2.0.0.tgz#5af1dd70f4b06b331f48d22a3d86e0786c0b9435" + dependencies: + hyphenate-style-name "^1.0.2" + css-loader@0.28.4: version "0.28.4" resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.28.4.tgz#6cf3579192ce355e8b38d5f42dd7a1f2ec898d0f" @@ -1389,6 +1420,10 @@ dom-converter@~0.1: dependencies: utila "~0.3" +dom-helpers@^3.2.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.2.1.tgz#3203e07fed217bd1f424b019735582fc37b2825a" + dom-serializer@0: version "0.1.0" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82" @@ -1803,7 +1838,7 @@ fb-watchman@^2.0.0: dependencies: bser "^2.0.0" -fbjs@^0.8.16: +fbjs@^0.8.1, fbjs@^0.8.16: version "0.8.16" resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db" dependencies: @@ -2248,7 +2283,7 @@ hoek@4.x.x: version "4.2.0" resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d" -hoist-non-react-statics@^2.3.0: +hoist-non-react-statics@^2.3.0, hoist-non-react-statics@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.3.1.tgz#343db84c6018c650778898240135a1420ee22ce0" @@ -2378,6 +2413,10 @@ https-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" +hyphenate-style-name@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz#31160a36930adaf1fc04c6074f7eb41465d4ec4b" + ical.js@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/ical.js/-/ical.js-1.2.2.tgz#59b517362a8f61dce0342fe67deb7c20dd119f6e" @@ -2437,6 +2476,13 @@ ini@^1.3.4, ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" +inline-style-prefixer@^3.0.8: + version "3.0.8" + resolved "https://registry.yarnpkg.com/inline-style-prefixer/-/inline-style-prefixer-3.0.8.tgz#8551b8e5b4d573244e66a34b04f7d32076a2b534" + dependencies: + bowser "^1.7.3" + css-in-js-utils "^2.0.0" + inquirer@3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" @@ -3080,6 +3126,10 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" +keycode@^2.1.8: + version "2.1.9" + resolved "https://registry.yarnpkg.com/keycode/-/keycode-2.1.9.tgz#964a23c54e4889405b4861a5c9f0480d45141dfa" + kind-of@^3.0.2: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -3192,6 +3242,10 @@ lodash.memoize@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" +lodash.merge@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.0.tgz#69884ba144ac33fe699737a6086deffadd0f89c5" + lodash.template@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.4.0.tgz#e73a0385c8355591746e020b99679c690e68fba0" @@ -3205,6 +3259,10 @@ lodash.templatesettings@^4.0.0: dependencies: lodash._reinterpolate "~3.0.0" +lodash.throttle@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" + lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" @@ -3263,6 +3321,22 @@ map-obj@^1.0.0, map-obj@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" +material-ui@^0.20.0: + version "0.20.0" + resolved "https://registry.yarnpkg.com/material-ui/-/material-ui-0.20.0.tgz#85411bb59c916c9c7703f29dcffc44e3a67d5111" + dependencies: + babel-runtime "^6.23.0" + inline-style-prefixer "^3.0.8" + keycode "^2.1.8" + lodash.merge "^4.6.0" + lodash.throttle "^4.1.1" + prop-types "^15.5.7" + react-event-listener "^0.5.1" + react-transition-group "^1.2.1" + recompose "^0.26.0" + simple-assign "^0.1.0" + warning "^3.0.0" + math-expression-evaluator@^1.2.14: version "1.2.17" resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz#de819fdbcd84dccd8fae59c6aeb79615b9d266ac" @@ -4221,7 +4295,7 @@ promise@^7.1.1: dependencies: asap "~2.0.3" -prop-types@^15.5.4, prop-types@^15.6.0: +prop-types@^15.5.4, prop-types@^15.5.6, prop-types@^15.5.7, prop-types@^15.6.0: version "15.6.0" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856" dependencies: @@ -4375,6 +4449,15 @@ react-error-overlay@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-3.0.0.tgz#c2bc8f4d91f1375b3dad6d75265d51cd5eeaf655" +react-event-listener@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/react-event-listener/-/react-event-listener-0.5.1.tgz#ba36076e47bc37c5a67ff5ccd4a9ff0f15621040" + dependencies: + babel-runtime "^6.26.0" + fbjs "^0.8.16" + prop-types "^15.6.0" + warning "^3.0.0" + react-router-dom@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-4.2.2.tgz#c8a81df3adc58bba8a76782e946cbd4eae649b8d" @@ -4434,6 +4517,16 @@ react-scripts-ts@2.8.0: optionalDependencies: fsevents "1.1.2" +react-transition-group@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-1.2.1.tgz#e11f72b257f921b213229a774df46612346c7ca6" + dependencies: + chain-function "^1.0.0" + dom-helpers "^3.2.0" + loose-envify "^1.3.1" + prop-types "^15.5.6" + warning "^3.0.0" + react@^16.2.0: version "16.2.0" resolved "https://registry.yarnpkg.com/react/-/react-16.2.0.tgz#a31bd2dab89bff65d42134fa187f24d054c273ba" @@ -4510,6 +4603,15 @@ readdirp@^2.0.0: readable-stream "^2.0.2" set-immediate-shim "^1.0.1" +recompose@^0.26.0: + version "0.26.0" + resolved "https://registry.yarnpkg.com/recompose/-/recompose-0.26.0.tgz#9babff039cb72ba5bd17366d55d7232fbdfb2d30" + dependencies: + change-emitter "^0.1.2" + fbjs "^0.8.1" + hoist-non-react-statics "^2.3.1" + symbol-observable "^1.0.4" + recursive-readdir@2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.1.tgz#90ef231d0778c5ce093c9a48d74e5c5422d13a99" @@ -4890,6 +4992,10 @@ signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" +simple-assign@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/simple-assign/-/simple-assign-0.1.0.tgz#17fd3066a5f3d7738f50321bb0f14ca281cc4baa" + "sjcl@git+https://github.com/etesync/sjcl": version "1.0.7" resolved "git+https://github.com/etesync/sjcl#5cdf1d4d1d9e8e19fffdf6b498b5c7c073995abb" @@ -5194,6 +5300,10 @@ sw-toolbox@^3.4.0: path-to-regexp "^1.0.1" serviceworker-cache-polyfill "^4.0.0" +symbol-observable@^1.0.4: + version "1.1.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.1.0.tgz#5c68fd8d54115d9dfb72a84720549222e8db9b32" + symbol-tree@^3.2.1: version "3.2.2" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6"