diff --git a/package-lock.json b/package-lock.json index 1ede7b8..24f95bc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -135,7 +135,7 @@ }, "is-accessor-descriptor": { "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "optional": true, @@ -157,7 +157,7 @@ }, "is-data-descriptor": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "optional": true, @@ -1283,6 +1283,30 @@ "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.1.7.tgz", "integrity": "sha512-ego8jRVSHfq/iq4KRZJKQeUAdi3ZjGNrqw4oPN3fNdvTBnLCSntwVCnc37bsAJP9UB8MhrTfPnZYxkv2vpS4pg==" }, + "@fortawesome/fontawesome-svg-core": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.10.tgz", + "integrity": "sha512-x9rYQ4jPVWnXgsle/MzaV2qDwNfc1Gm5DB0T76WOp4RDZ/esjEE0OvKtMa2qFvG1NqYbelgN4gChA+ttAqPtaw==", + "requires": { + "@fortawesome/fontawesome-common-types": "^0.2.10" + }, + "dependencies": { + "@fortawesome/fontawesome-common-types": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.10.tgz", + "integrity": "sha512-FbrzSgFDzoC6Dm8w7gCWxgdffFbYV7O/4THOtYDQEplZVOpYIA3vjgnxCXApY49YaIQ91mxIGROS3d7wS+fO3A==" + } + } + }, + "@fortawesome/react-fontawesome": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.3.tgz", + "integrity": "sha512-tc689l67rPZ7+ynZVUgOXY80rAt5KxvuH1qjPpJcbyJzJHzk5yhrD993BjsSEdPBLTtPqmvwynsO/XrAQqHbtg==", + "requires": { + "humps": "^2.0.1", + "prop-types": "^15.5.10" + } + }, "@sendgrid/client": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/@sendgrid/client/-/client-6.3.0.tgz", @@ -1736,7 +1760,7 @@ }, "array-flatten": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "resolved": "http://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, "array-union": { @@ -2620,7 +2644,7 @@ "dependencies": { "resolve": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "resolved": "http://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", "dev": true } @@ -2833,7 +2857,7 @@ }, "callsites": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "resolved": "http://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", "dev": true }, @@ -3674,7 +3698,7 @@ }, "regexpu-core": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz", "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=", "dev": true, "requires": { @@ -3691,7 +3715,7 @@ }, "regjsparser": { "version": "0.1.5", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "resolved": "http://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", "dev": true, "requires": { @@ -4070,7 +4094,7 @@ "dependencies": { "globby": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "resolved": "http://registry.npmjs.org/globby/-/globby-6.1.0.tgz", "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", "dev": true, "requires": { @@ -4956,7 +4980,7 @@ }, "expand-range": { "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "resolved": "http://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", "requires": { "fill-range": "^2.1.0" @@ -5297,7 +5321,7 @@ }, "flagged-respawn": { "version": "0.3.2", - "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-0.3.2.tgz", + "resolved": "http://registry.npmjs.org/flagged-respawn/-/flagged-respawn-0.3.2.tgz", "integrity": "sha1-/xke3c1wiKZ1smEP/8l2vpuAdLU=" }, "flat-cache": { @@ -5386,7 +5410,7 @@ }, "forever": { "version": "0.15.3", - "resolved": "https://registry.npmjs.org/forever/-/forever-0.15.3.tgz", + "resolved": "http://registry.npmjs.org/forever/-/forever-0.15.3.tgz", "integrity": "sha1-d9nX4V/S9RGtnYShEMfdj8js68I=", "requires": { "cliff": "~0.1.9", @@ -5993,6 +6017,11 @@ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, + "g": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/g/-/g-2.0.1.tgz", + "integrity": "sha1-C1lj69DKcOO8jGdmk0oCGCHIuFc=" + }, "generic-pool": { "version": "2.5.4", "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-2.5.4.tgz", @@ -6570,7 +6599,7 @@ }, "string_decoder": { "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true } @@ -6698,7 +6727,7 @@ }, "is-accessor-descriptor": { "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { @@ -6718,7 +6747,7 @@ }, "is-data-descriptor": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { @@ -6914,6 +6943,11 @@ "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", "dev": true }, + "humps": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/humps/-/humps-2.0.1.tgz", + "integrity": "sha1-3QLqYIG9BWjcXQcxhEY5V7qe+ao=" + }, "i": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/i/-/i-0.3.6.tgz", @@ -7155,7 +7189,7 @@ }, "is-accessor-descriptor": { "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "requires": { "kind-of": "^3.0.2" @@ -7219,7 +7253,7 @@ }, "is-data-descriptor": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "requires": { "kind-of": "^3.0.2" @@ -8413,7 +8447,7 @@ }, "string_decoder": { "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" }, "supports-color": { @@ -9626,7 +9660,7 @@ }, "path-browserify": { "version": "0.0.0", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", + "resolved": "http://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", "dev": true }, @@ -10441,7 +10475,7 @@ }, "ps-tree": { "version": "0.0.3", - "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-0.0.3.tgz", + "resolved": "http://registry.npmjs.org/ps-tree/-/ps-tree-0.0.3.tgz", "integrity": "sha1-2/jXUqf+Ivp9WGNWiUmWEOknbdw=", "requires": { "event-stream": "~0.5" @@ -10910,7 +10944,7 @@ }, "is-accessor-descriptor": { "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "requires": { "kind-of": "^3.0.2" @@ -10928,7 +10962,7 @@ }, "is-data-descriptor": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "requires": { "kind-of": "^3.0.2" @@ -11386,7 +11420,7 @@ }, "callsites": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "resolved": "http://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", "dev": true }, @@ -11423,7 +11457,7 @@ }, "resolve-dir": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz", + "resolved": "http://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz", "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=", "requires": { "expand-tilde": "^1.2.2", @@ -11482,7 +11516,7 @@ }, "rgba-regex": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=", "dev": true }, @@ -11657,7 +11691,7 @@ }, "is-accessor-descriptor": { "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { @@ -11677,7 +11711,7 @@ }, "is-data-descriptor": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { @@ -12277,7 +12311,7 @@ "dependencies": { "source-map": { "version": "0.5.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "resolved": "http://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", "dev": true } @@ -12354,7 +12388,7 @@ }, "sprintf-js": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "resolved": "http://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, @@ -12441,7 +12475,7 @@ }, "stream-browserify": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", + "resolved": "http://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", "dev": true, "requires": { @@ -12532,7 +12566,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "requires": { "safe-buffer": "~5.1.0" @@ -12712,7 +12746,7 @@ }, "tape": { "version": "2.3.3", - "resolved": "https://registry.npmjs.org/tape/-/tape-2.3.3.tgz", + "resolved": "http://registry.npmjs.org/tape/-/tape-2.3.3.tgz", "integrity": "sha1-Lnzgox3wn41oUWZKcYQuDKUFevc=", "requires": { "deep-equal": "~0.1.0", @@ -13193,7 +13227,7 @@ }, "tty-browserify": { "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "resolved": "http://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", "dev": true }, @@ -13639,7 +13673,7 @@ }, "vm-browserify": { "version": "0.0.4", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", + "resolved": "http://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", "dev": true, "requires": { @@ -13808,7 +13842,7 @@ }, "is-accessor-descriptor": { "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { @@ -13828,7 +13862,7 @@ }, "is-data-descriptor": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { @@ -14179,7 +14213,7 @@ }, "is-accessor-descriptor": { "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { @@ -14199,7 +14233,7 @@ }, "is-data-descriptor": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { @@ -14869,7 +14903,7 @@ }, "is-accessor-descriptor": { "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { @@ -14889,7 +14923,7 @@ }, "is-data-descriptor": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { diff --git a/package.json b/package.json index 5b8934d..0d5815c 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "forever": "^0.15.3", "formik": "^1.3.0", "fs-extra": "^2.0.0", - "graphql": "^0.4.9", + "graphql": "^0.4.18", "graphql-bookshelf": "github:otech47/graphql-bookshelf", "knex": "^0.12.6", "lodash": "^4.16.4", diff --git a/web/components/Card.js b/web/components/Card.js index 2f8d883..77a1e49 100644 --- a/web/components/Card.js +++ b/web/components/Card.js @@ -37,7 +37,7 @@ Card.propTypes = { ...backgroundSize.propTypes, ...backgroundPosition.propTypes, ...backgroundRepeat.propTypes, - depth: PropTypes.oneOf([1, 2, 3, 4, 5, 6, 7]) + depth: PropTypes.oneOf([1, 2, 3, 4, 5, 6, 7, 8, 9]) } export default Card \ No newline at end of file diff --git a/web/components/DayBlock.jsx b/web/components/DayBlock.jsx index fb1cfa6..64925fc 100644 --- a/web/components/DayBlock.jsx +++ b/web/components/DayBlock.jsx @@ -1,12 +1,77 @@ +import { connect } from 'react-redux'; +import moment from 'moment'; import React from 'react'; -export default class DayBlock extends React.Component { +import Flex from './Flex'; +import Text from './Text'; +import Card from './Card'; + +class DayBlock extends React.Component { + + renderTinySetBlocks = (setBlocks, day) => { + const blockDay = moment(day).format('YYYY-MM-DD') + const setBlocksByDate = _.groupBy(setBlocks, 'date') + const setBlocksToRender = setBlocksByDate[blockDay] || []; + + return setBlocksToRender.map( setBlock => ( + + + )) + } + render() { + const { day, selected, onClick, currentTeamMember, fetchingData } = this.props + return ( -
-
DayBlock
-
+ + onClick(day)} + > + + + { // If you are waiting for the API to respond, it does not render + !fetchingData && this.renderTinySetBlocks(currentTeamMember.weeklySetblocks, day) + } + + + + {day.getDate()} + + + {day.toDateString().slice(0, 3)} + + + + + ); } } +const mapStateToProps = ({ environment }) => { + return { + ...environment + }; +}; + +const mapDispatchToProps = { +}; +export default connect(mapStateToProps, mapDispatchToProps)(DayBlock) \ No newline at end of file diff --git a/web/components/Header.jsx b/web/components/Header.jsx index fb7d09e..02987fe 100644 --- a/web/components/Header.jsx +++ b/web/components/Header.jsx @@ -12,7 +12,9 @@ export default class Header extends React.Component { width='375px' > ); diff --git a/web/components/Loading.js b/web/components/Loading.js new file mode 100644 index 0000000..e1284bc --- /dev/null +++ b/web/components/Loading.js @@ -0,0 +1,34 @@ +import React, { Component } from 'react'; +import styled, { keyframes } from 'styled-components'; + +const BounceAnimation = keyframes` + 0% { margin-bottom: 0; } + 50% { margin-bottom: 5px } + 100% { margin-bottom: 0 } +`; +const DotWrapper = styled.div` + display: flex; + align-items: flex-end; +`; +const Dot = styled.div` + background-color: rgb(46,73,122); + border-radius: 50%; + width: 4px; + height: 4px; + margin: 0 3px; + /* Animation */ + animation: ${BounceAnimation} 0.5s linear infinite; + animation-delay: ${props => props.delay}; +`; + +export default class LoadingDots extends Component { + render() { + return ( + + + + + + ) + } +} \ No newline at end of file diff --git a/web/components/NavLinkItem.js b/web/components/NavLinkItem.js index 5293998..3b53c94 100644 --- a/web/components/NavLinkItem.js +++ b/web/components/NavLinkItem.js @@ -1,5 +1,6 @@ import React from 'react' import { Link } from 'react-router-dom' + import Box from './Box' import Flex from './Flex' import Text from './Text' @@ -16,9 +17,11 @@ export default ({ style={{ textDecoration: 'none' }} > {React.createElement(icon, { size: 24, - color: selected ? 'white' : 'black' + color: selected ? 'green' : 'black' })} -) \ No newline at end of file +) diff --git a/web/components/NavigationBar.js b/web/components/NavigationBar.js index 5dfe146..39722ba 100644 --- a/web/components/NavigationBar.js +++ b/web/components/NavigationBar.js @@ -1,5 +1,6 @@ import React from 'react'; import { connect } from 'react-redux'; +var _ = require('lodash'); import NavLinkItem from './NavLinkItem'; @@ -9,10 +10,11 @@ import Flex from './Flex'; class NavigationBar extends React.Component { renderNavItem = (item) => { const { path } = this.props; + const route = '/' + _.split(path, '/', 2)[1]; return ( ) diff --git a/web/components/ScheduleHeader.jsx b/web/components/ScheduleHeader.jsx index 0edb8b5..ff57ff4 100644 --- a/web/components/ScheduleHeader.jsx +++ b/web/components/ScheduleHeader.jsx @@ -1,12 +1,35 @@ import React from 'react'; +import moment from 'moment'; + +import Text from './Text'; +import Card from './Card'; +import Flex from './Flex'; + export default class ScheduleHeader extends React.Component { render() { + const { selectedDay } = this.props; return ( -
-
ScheduleHeader
-
+ + + + {moment(selectedDay).format('dddd, MMMM D, YYYY')} + + ); } } - diff --git a/web/components/SchedulePage.jsx b/web/components/SchedulePage.jsx index 7069a95..f129566 100644 --- a/web/components/SchedulePage.jsx +++ b/web/components/SchedulePage.jsx @@ -1,33 +1,149 @@ import React from 'react'; +import moment from 'moment'; +import { connect } from 'react-redux'; -export default class SchedulePage extends React.Component { - renderBaseOnParams = (match) => { - if (match.params.teamMemberId) { +import ScheduleHeader from './ScheduleHeader'; +import SideBar from './SideBar'; +import Flex from './Flex'; +import SetBlock from './SetBlock'; +import Text from './Text'; + +import { fetchCurrentTeamMemberById, setSelectedDay } from '../reducers/environment'; +import LoadingDots from './Loading'; + +class SchedulePage extends React.Component { + state = { + daysOfWeek: [], + } + + componentDidMount() { + const { history, match } = this.props; + const teamMemberId = match.params.teamMemberId || 'recGVSamjigJbZoJ8';// mocked id until to have a login + this.props.fetchCurrentTeamMemberById({ id: teamMemberId }) + this.getDaysOfWeek() + if (!match.params.teamMemberId) { + const today = moment().toDate(); + // If the match.params don't have a teamMemberId are u seeing your schedule + history.push('/schedule/' + today.getDay()); + // /schedule - SchedulePage, have today's day selected by default + this.props.setSelectedDay(today) + } + } + + renderSetBlocks = (selectedDay) => { + const { currentTeamMember } = this.props; + selectedDay = moment(selectedDay).format('YYYY-MM-DD') + const setBlocksByDate = _.groupBy(currentTeamMember.weeklySetblocks, 'date') + const setBlocks = setBlocksByDate[selectedDay]; + if (setBlocks) { + return setBlocks.map(setBlock => { + return + }) + } else { return ( -
- teamMemberId: - {match.params.teamMemberId} -
+ This user hasn't committed any Setblocks for this day ) } + } + + getDaysOfWeek = () => { + const startOfWeek = moment() + .startOf('isoWeek'); + const endOfWeek = moment() + .endOf('isoWeek'); + + const days = []; + let day = startOfWeek; + + while (day <= endOfWeek) { + days.push(day.toDate()); + day = day.clone() + .add(1, 'd'); + } + + this.setState({ + daysOfWeek: days, + }) + this.props.setSelectedDay(days[0]) + } - if (match.params.dayOfWeek) { + renderIfItReady() { + const { + match, currentTeamMember, fetchingData, selectedDay + } = this.props + if (fetchingData) { + return ( // If you are waiting for the API to respond, render a loading + + Loading + + + ) + } else { return ( -
- dayOfWeek: - {match.params.dayOfWeek} -
+ + + {match.params.teamMemberId ? currentTeamMember.name : 'Your'} + {' Schedule\'s Page'} + + {this.renderSetBlocks(selectedDay)} + ) } } render() { - const { match } = this.props; + const { selectedDay } = this.props; + const { daysOfWeek } = this.state; return ( -
-
SchedulePage
- {this.renderBaseOnParams(match)} -
+ + + + + + + + + {this.renderIfItReady()} + + ); } } + +const mapStateToProps = ({ environment }) => { + return { + ...environment + }; +}; + +const mapDispatchToProps = (dispatch) => { + return { + fetchCurrentTeamMemberById: (params) => dispatch(fetchCurrentTeamMemberById(params)), + setSelectedDay: (selectedDay) => dispatch(setSelectedDay(selectedDay)) + }; +}; +export default connect(mapStateToProps, mapDispatchToProps)(SchedulePage); diff --git a/web/components/SetBlock.jsx b/web/components/SetBlock.jsx index e48c3ba..5390e7e 100644 --- a/web/components/SetBlock.jsx +++ b/web/components/SetBlock.jsx @@ -1,12 +1,40 @@ import React from 'react'; +import Flex from './Flex'; +import Text from './Text'; +import Card from './Card'; + export default class SetBlock extends React.Component { render() { + const { data } = this.props; return ( -
-
SetBlock
-
+ + + + + + {data.blockTime} + + + + + {data.description} + + + ); } } - diff --git a/web/components/SideBar.jsx b/web/components/SideBar.jsx index bc439cd..1bd0db8 100644 --- a/web/components/SideBar.jsx +++ b/web/components/SideBar.jsx @@ -1,11 +1,59 @@ import React from 'react'; +import { withRouter } from 'react-router-dom'; +import { connect } from 'react-redux'; + +import Flex from './Flex'; +import DayBlock from './DayBlock'; + +import { setSelectedDay } from '../reducers/environment'; + +class SideBar extends React.Component { + + goToScheduleDay(day) { + const { history, match } = this.props; + if (match.params.teamMemberId) { + history.push('/team/' + match.params.teamMemberId + '/' + day.getDay()); + } else { + // If the match.params don't have a teamMemberId are u seeing your schedule + history.push('/schedule/' + day.getDay()); + } + this.props.setSelectedDay(day); + } -export default class SideBar extends React.Component { render() { + const { days, selectedDay } = this.props; return ( -
-
SideBar
-
+ + { + days.map(day => ( + this.goToScheduleDay(day)} + /> + )) + } + + ); } } + +const mapStateToProps = ({ environment }) => { + return { + ...environment + }; +}; + +const mapDispatchToProps = (dispatch) => { + return { + setSelectedDay: (selectedDay) => dispatch(setSelectedDay(selectedDay)) + }; +}; +export default withRouter(connect(mapStateToProps, mapDispatchToProps)(SideBar)); diff --git a/web/components/TeamList.js b/web/components/TeamList.js index fa80c58..16058de 100644 --- a/web/components/TeamList.js +++ b/web/components/TeamList.js @@ -7,46 +7,29 @@ import { fetchAllTeamMembers } from '../reducers/environment' class TeamList extends React.Component { - constructor(props) { - super(props); - this.state = { - mockTeamMembers: ['Oscar Lafarga', 'Vitoria Lafarga', 'Quinn Pruit', 'David Lafarga'] - } - } - componentDidMount() { this.props.fetchAllTeamMembers() } - goToPage = () => { - console.log('goToTeamMember') - }; - + generateColor () { + return '#' + Math.random().toString(16).substr(-6); + } render() { - const { mockTeamMembers } = this.state; + const { teamMembers, goToPage } = this.props; return ( <> - - - - + {teamMembers.map(teamMember => { + return ( + { goToPage(teamMember) }} + color={this.generateColor()} + /> + ) + }) + } ) } @@ -58,9 +41,9 @@ const mapStateToProps = ({ environment }) => { }; }; -const mapDispatchToProps = () => { +const mapDispatchToProps = (dispatch) => { return { - fetchAllTeamMembers + fetchAllTeamMembers: () => dispatch(fetchAllTeamMembers()) }; }; diff --git a/web/components/TeamLogo.jsx b/web/components/TeamLogo.jsx index 5814f86..de68630 100644 --- a/web/components/TeamLogo.jsx +++ b/web/components/TeamLogo.jsx @@ -1,7 +1,6 @@ import React from 'react'; import Image from './Image'; -import Card from './Card'; import Flex from './Flex'; export default class TeamLogo extends React.Component { @@ -12,19 +11,13 @@ export default class TeamLogo extends React.Component { alignItems='center' mx='auto' my='1rem' - width='100px' + width='375px' > - - - +
); } diff --git a/web/components/TeamMember.jsx b/web/components/TeamMember.jsx index 1bd0cfc..49d8b9d 100644 --- a/web/components/TeamMember.jsx +++ b/web/components/TeamMember.jsx @@ -11,44 +11,43 @@ export default class TeamMember extends React.Component { return ( <> + {name} - - - + diff --git a/web/components/TeamPage.js b/web/components/TeamPage.js index e6ffa15..c0ea101 100644 --- a/web/components/TeamPage.js +++ b/web/components/TeamPage.js @@ -6,23 +6,27 @@ import Header from './Header'; import Flex from './Flex'; - export default class TeamPage extends React.Component { + goToPage = (teamMember) => { + const { history } = this.props; + history.push('/team/' + teamMember.id + '/1'); + } + render() { return (
- + ); } diff --git a/web/images/SetBlockHeading2.png b/web/images/SetBlockHeading2.png new file mode 100644 index 0000000..3baa6b1 Binary files /dev/null and b/web/images/SetBlockHeading2.png differ diff --git a/web/reducers/environment.js b/web/reducers/environment.js index 56fc9ff..44bc7c4 100644 --- a/web/reducers/environment.js +++ b/web/reducers/environment.js @@ -1,11 +1,23 @@ +import moment from 'moment'; + import api from 'scripts/api' // Index of Action Types const RECEIVE_TEAM_MEMBERS = 'RECEIVE_TEAM_MEMBERS' +const RECEIVE_TEAM_MEMBER = 'RECEIVE_TEAM_MEMBER' +const SET_SELECTED_DAY = 'SET_SELECTED_DAY' +const FETCHING_DATA = 'FETCHING_DATA' // Reducer const initialState = { - teamMembers: [] + teamMembers: [], + currentTeamMember: { + id: '', + name: '', + weeklySetblocks: [] + }, + selectedDay: moment.now(), + fetchingData: false } export default function reducer(state = initialState, action) { @@ -15,6 +27,21 @@ export default function reducer(state = initialState, action) { ...state, teamMembers: action.members } + case RECEIVE_TEAM_MEMBER: + return { + ...state, + currentTeamMember: action.member + } + case SET_SELECTED_DAY: + return { + ...state, + selectedDay: action.selectedDay + } + case FETCHING_DATA: + return { + ...state, + fetchingData: action.fetchingData + } default: return state } @@ -22,7 +49,9 @@ export default function reducer(state = initialState, action) { // Actions export function fetchAllTeamMembers(params) { + return dispatch => { + dispatch(setFetchingData(true)) api.graph({ query: `query { teamMembers { @@ -35,6 +64,7 @@ export function fetchAllTeamMembers(params) { // Handle payload // Dispatch additional actions dispatch(receiveTeamMembers(payload.teamMembers)) + dispatch(setFetchingData(false)) }) .catch(err => { // Handle error @@ -42,9 +72,61 @@ export function fetchAllTeamMembers(params) { } } +export function fetchCurrentTeamMemberById(params) { + return dispatch => { + dispatch(setFetchingData(true)) + api.graph({ + query: `query { + teamMemberById(id: "${params.id}") { + id, + name, + weeklySetblocks { + id, + date, + blockTime, + blockFraction, + description + } + } + }` + }) + .then(payload => { + // Handle payload + // Dispatch additional actions + dispatch(receiveTeamMember(payload.teamMemberById)) + dispatch(setFetchingData(false)) + }) + .catch(err => { + // Handle error + }) + } +} + + export function receiveTeamMembers(members) { return { type: RECEIVE_TEAM_MEMBERS, members } } + +export function receiveTeamMember(member) { + return { + type: RECEIVE_TEAM_MEMBER, + member + } +} + +export function setSelectedDay(selectedDay) { + return { + type: SET_SELECTED_DAY, + selectedDay + } +} + +export function setFetchingData(fetchingData) { + return { + type: FETCHING_DATA, + fetchingData + } +} \ No newline at end of file diff --git a/web/routes.js b/web/routes.js index 070ff00..be41ac0 100644 --- a/web/routes.js +++ b/web/routes.js @@ -21,11 +21,11 @@ export default ( - - } /> - } /> - - + + + + + ); \ No newline at end of file diff --git a/web/styles/theme.js b/web/styles/theme.js index d3cbd30..b564358 100644 --- a/web/styles/theme.js +++ b/web/styles/theme.js @@ -17,7 +17,9 @@ export default { 4: '0px 4px 21px rgba(0,0,0,0.14)', 5: '0px 5px 25px rgba(0,0,0,0.14)', 6: '-2px 0px 10px rgba(0,0,0,0.5)', - 7: '-1px 0px 15px rgba(0,0,0,0.65)' + 7: '1px 0px 5px rgba(0,0,0,0.65)', + 8: '1px 0px 5px 0px rgba(136,136,136, 0.8)', + 9: '4px 4px 4px -1px rgba(136,136,136, 0.8)' }, // Colors (styled-system) colors: { @@ -38,7 +40,18 @@ export default { facebook: '#32529F', overlay: 'rgba(0,0,0,0.5)', transparent: 'transparent', - bottomColor: '#3B3B3B' + bottomColor: '#3B3B3B', + + backgroundPrimary: '#E1E2E1', + backgroundSecondary: '#F5F5F6', + primary: '#f93b6a', + primaryLight: '#ff7498', + primaryDark: '#c00040', + textPrimary: '#ffffff', + secondary: '#00e676', + secondaryLight: '#66ffa6', + secondaryDark: '#00b248', + textSecondary: '#000000' }, gradients: { vertical: 'linear-gradient(#1C9EF6, #0ACFFE)',