From ab85004e4ee0cecc787807b5609750109e96d267 Mon Sep 17 00:00:00 2001 From: Ray Schamp Date: Fri, 11 Sep 2015 20:29:12 -0400 Subject: [PATCH] Add logged in state and dropdown --- src/components/login/login.jsx | 4 + src/components/login/login.scss | 2 + src/components/navigation/_colors.scss | 3 + src/components/navigation/dropdown.jsx | 36 +++++++ src/components/navigation/dropdown.scss | 74 ++++++++++++++ src/components/navigation/navigation.jsx | 102 ++++++++++--------- src/components/navigation/navigation.scss | 118 ++++++++++++---------- static/images/mystuff.png | Bin 0 -> 431 bytes static/images/nav-notifications.png | Bin 0 -> 1132 bytes 9 files changed, 241 insertions(+), 98 deletions(-) create mode 100644 src/components/navigation/_colors.scss create mode 100644 src/components/navigation/dropdown.jsx create mode 100644 src/components/navigation/dropdown.scss create mode 100644 static/images/mystuff.png create mode 100644 static/images/nav-notifications.png diff --git a/src/components/login/login.jsx b/src/components/login/login.jsx index 0acce2a11..48551d3b7 100644 --- a/src/components/login/login.jsx +++ b/src/components/login/login.jsx @@ -3,8 +3,12 @@ var React = require('react'); require('./login.scss'); module.exports = React.createClass({ + propTypes: { + onLogIn: React.PropTypes.func + }, handleSubmit: function (event) { event.preventDefault(); + this.props.onLogIn(); }, render: function () { return ( diff --git a/src/components/login/login.scss b/src/components/login/login.scss index 97f2a1521..f0c2342ae 100644 --- a/src/components/login/login.scss +++ b/src/components/login/login.scss @@ -1,4 +1,6 @@ .login { + padding: 14px 9px; + .submit-button { margin-right: 3px; } diff --git a/src/components/navigation/_colors.scss b/src/components/navigation/_colors.scss new file mode 100644 index 000000000..4f6923b5d --- /dev/null +++ b/src/components/navigation/_colors.scss @@ -0,0 +1,3 @@ +$base-background-color: #0f8bc0; +$active-background-color: rgb(1, 96, 135); +$border-color: rgb(20, 154, 203); diff --git a/src/components/navigation/dropdown.jsx b/src/components/navigation/dropdown.jsx new file mode 100644 index 000000000..125ff74c4 --- /dev/null +++ b/src/components/navigation/dropdown.jsx @@ -0,0 +1,36 @@ +var React = require('react'); + +require('./dropdown.scss'); + +module.exports = React.createClass({ + mixins: [ + require('react-onclickoutside') + ], + propTypes: { + onRequestClose: React.PropTypes.func, + isOpen: React.PropTypes.bool + }, + getDefaultProps: function () { + return { + as: 'div', + isOpen: false + }; + }, + handleClickOutside: function () { + if (this.props.isOpen) { + this.props.onRequestClose(); + } + }, + render: function () { + var className = [ + 'dropdown', + this.props.className, + this.props.isOpen ? 'open' : '' + ].join(' '); + return ( + + {this.props.children} + + ); + } +}); diff --git a/src/components/navigation/dropdown.scss b/src/components/navigation/dropdown.scss new file mode 100644 index 000000000..87bfe75f7 --- /dev/null +++ b/src/components/navigation/dropdown.scss @@ -0,0 +1,74 @@ +@import 'colors'; + +.dropdown { + position: absolute; + right: 0; + min-width: 160px; + max-width: 220px; + background-color: $base-background-color; + overflow: hidden; + border-radius: 0px 0px 4px 4px; + box-shadow: inset 0 1px 1px rgba(100,100,100,.25),0 1px 1px rgba(0,0,0,.25); + color: white; + font-weight: normal; + font-size: 0.8125rem; + + display: none; + &.open { + display: block; + } + + a { + color: white; + } + + input { + // 100% minus border and padding + width: calc(100% - 2px - 8px); + margin-bottom: 9px; + } + + label { + display: block; + margin-bottom: 5px; + } + + > li { + display: block; + line-height: 30px; + + &.divider { + border-top: 1px solid #149acb; + margin-top: 10px; + } + + a { + display: block; + padding: 0 10px; + + &:hover { + background-color: $active-background-color; + text-decoration: none; + } + } + } + + &.with-arrow { + $arrow-border-width: 11px; + overflow: visible; + margin-top: $arrow-border-width; + border-radius: 4px; + &:before { + position: absolute; + display: block; + right: 10%; + top: -$arrow-border-width; + left: auto; + border-color: transparent; + border-bottom-color: $base-background-color; + border-style: solid; + border-width: 0 $arrow-border-width $arrow-border-width $arrow-border-width; + content: " "; + } + } +} diff --git a/src/components/navigation/navigation.jsx b/src/components/navigation/navigation.jsx index 7033c7430..e47e6ee41 100644 --- a/src/components/navigation/navigation.jsx +++ b/src/components/navigation/navigation.jsx @@ -1,44 +1,19 @@ var React = require('react'); var Login = require('../login/login.jsx'); +var Dropdown = require('./dropdown.jsx'); require('./navigation.scss'); -var Dropdown = React.createClass({ - mixins: [ - require('react-onclickoutside') - ], - propTypes: { - onRequestClose: React.PropTypes.func, - isOpen: React.PropTypes.bool - }, - getDefaultProps: function () { - return { - isOpen: false - }; - }, - handleClickOutside: function () { - if (this.props.isOpen) { - this.props.onRequestClose(); - } - }, - render: function () { - var className = [ - 'dropdown', - this.props.className, - this.props.isOpen ? 'open' : '' - ].join(' '); - return ( -
- {this.props.children} -
- ); - } -}); - module.exports = React.createClass({ getInitialState: function () { return { - 'loginOpen': false + 'loginOpen': false, + 'loggedIn': false, + 'loggedInUser': { + 'username': 'raimondious', + 'thumbnail': '//cdn2.scratch.mit.edu/get_image/user/2584924_32x32.png' + }, + 'accountNavOpen': false }; }, handleLoginClick: function (e) { @@ -48,9 +23,25 @@ module.exports = React.createClass({ closeLogin: function () { this.setState({'loginOpen': false}); }, + handleLogIn: function () { + this.setState({'loggedIn': true}); + }, + handleLogOut: function () { + this.setState({'loggedIn': false}); + }, + handleClickAccountNav: function () { + this.setState({'accountNavOpen': true}); + }, + closeAccountNav: function () { + this.setState({'accountNavOpen': false}); + }, render: function () { + var className = [ + 'inner', + this.state.loggedIn ? 'logged-in' : 'logged-out' + ].join(' '); return ( -
+
); diff --git a/src/components/navigation/navigation.scss b/src/components/navigation/navigation.scss index bc8f6b15a..604b812f3 100644 --- a/src/components/navigation/navigation.scss +++ b/src/components/navigation/navigation.scss @@ -1,5 +1,4 @@ -$base-background-color: #0f8bc0; -$border-color: rgb(20, 154, 203); +@import 'colors'; #navigation { position: fixed; @@ -13,7 +12,7 @@ $border-color: rgb(20, 154, 203); /* NOTE: Height should match offset settings in main.scss file */ height: 35px; - ul { + .inner > ul { display: flex; flex-direction: row; flex-wrap: nowrap; @@ -24,7 +23,7 @@ $border-color: rgb(20, 154, 203); padding: 0; list-style: none; - li { + > li { display: inline-block; align-self: flex-start; float: left; @@ -65,7 +64,7 @@ $border-color: rgb(20, 154, 203); } > a:hover { - background-color: rgb(1, 96, 135); + background-color: $active-background-color; } } @@ -115,64 +114,77 @@ $border-color: rgb(20, 154, 203); margin-left: auto; font-weight: bold; - > a:hover { - background-color: #f79231; - } - &:last-child { border-right: 1px solid rgb(20, 154, 203); } } - .dropdown { - $dropdown-padding-h: 14px; - $dropdown-padding-v: 9px; - position: absolute; - right: 0; + .join > a:hover { + background-color: #f79231; + } + + .messages, .mystuff { + > a { + background-repeat: no-repeat; + background-position: center center; + padding-left: 10px; + padding-right: 10px; + text-indent: 100%; + white-space: nowrap; + overflow: hidden; + } + } + + .messages { + > a { + background-image: url('/images/nav-notifications.png'); + width: 22px; + } + } + + .mystuff { + > a { + background-image: url('/images/mystuff.png'); + width: 25px; + } + } + + .login-dropdown { width: 200px; - padding: $dropdown-padding-v $dropdown-padding-h; - background-color: $base-background-color; - border-radius: 4px; - box-shadow: 0 2px 4px rgba(0,0,0,0.2); - color: white; - font-weight: normal; - font-size: 0.8125rem; + } - display: none; - &.open { - display: block; + .account-nav { + > a { + font-weight: normal; + font-size: 0.8125rem; + + img { + width: 24px; + height: 24px; + margin-right: 5px; + vertical-align: middle; + } + + &:after { + $caret-border-width: 4px; + margin-left: $caret-border-width; + border: $caret-border-width solid transparent; + border-bottom-width: 0; + border-top-color: white; + content: " "; + opacity: 0.5; + vertical-align: middle; + width: 0; + height: 0; + display: inline-block; + } } - $arrow-border-width: 11px; - margin-top: $arrow-border-width; - &:before { - position: absolute; - display: block; - right: 10%; - top: -$arrow-border-width; - left: auto; - border-color: transparent; - border-bottom-color: $base-background-color; - border-style: solid; - border-width: 0 $arrow-border-width $arrow-border-width $arrow-border-width; - content: " "; + .dropdown { + width: 100%; + padding: 0; + padding-top: 5px; } - - a { - color: white; - } - - input { - // 100% minus border and padding - width: calc(100% - 2px - 8px); - margin-bottom: 9px; - } - - label { - display: block; - margin-bottom: 5px; - } - } } } diff --git a/static/images/mystuff.png b/static/images/mystuff.png new file mode 100644 index 0000000000000000000000000000000000000000..6c2a99acc971243d08530048ad1bcb38ecf11fa9 GIT binary patch literal 431 zcmV;g0Z{&lP)P000vR1^@s6Wpbtk0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzQAtEWRCwBAWIzM||NnPjAPgQbGBQ43 zAO`>~SpT1RU_g!q3jaw1^NBT^5!n(Tl|X{KKtZ;ESRVxZryY0?ay%2z9+JcM|A)H_ z|L*T1MyUW0E3gow^54^A4F9eyV)*~{B?FU~9>f3lcOh&=H=-QHM2w=pC%YLKetltJ zRtsYI_v#YZ0#X1IF+l^efJxDvfk`KpfyJo@l48X4sb>k?vfp1Ih6^ZzEnsBhCfX8$ zaRN3}P?_Q1&2~c^rF-co9Fmj7C`~`~r*&G8- z5LEHWzbD7QK41pM2P__#fkF3sZ6MfpOwv}ATLJ@r_LTr5K8}Hrl^g6ka4--V`9xU) z3LiC%8_!aM)~002ovPDHLkV1jrSsRjT5 literal 0 HcmV?d00001 diff --git a/static/images/nav-notifications.png b/static/images/nav-notifications.png new file mode 100644 index 0000000000000000000000000000000000000000..5f0769caa7dca2b79aa1c94c620d3ecaf3b2ae2e GIT binary patch literal 1132 zcmaJ=TWHfz7>>x?bn4KlpuU9Ep~%`KT`wlCPS>XR>BeP#hwPxPdP!I4_`xcsZGC^}!lAIp;ro-}hh7;fDIn z3+AnuM-aq<*cKs<_hopMmCV8a39TlLx8*33LJ8Q4vXTjiO$uxQWK5IVKpaR)cjqXm zCWzUTnoOaTSjWpy^GFWHV`~Ox6GU~5ZAfxEKx7MOQ}qxvb>k*Qs!E93?iU%+2!ph` zrN;z`p8BNR(=KxgRkMMtws|a|0VI*O)}dRx9ipand3<)RX^NbNp!N{;JE)Y{K!%|S zNWX`1%S?bF1FVOw@&$vzO47@)49$3H*6U`2e3h4H7;@&Lus2g_<>Nwh#uv6iR2m_J zr|E1q>&aGmpxH*V9LG5tUauP?+*Y@aB-^c9uAG7ZEZI~Iq(Yr^6r~oJK_Lo9`a1>9 z$jj>1Oqp=OXj?L9*26d{<$$92f2gMA(H4q>Kk@!k*h+RAfQ|zTW=t73uGQtZGWf6w zBm~VQgdMpmHl!hfRvH>)IN>KnNmg~op2mwJAJZ))=`x53Aqp#aR8`>xrYh)*)J9o9 z%du<(mx=X7xIi@E0P?6vA@yi8cEHn=wG_AI9=3vtiR;T#K8JbVz2Ao z&c$Oc>O