use onclickoutside for account/sign in box
This commit is contained in:
parent
c97b769a1a
commit
2bd27d7ee5
9 changed files with 47 additions and 72 deletions
|
@ -786,7 +786,6 @@ label {
|
||||||
width: 32px;
|
width: 32px;
|
||||||
}
|
}
|
||||||
.sidebarAccountBox {
|
.sidebarAccountBox {
|
||||||
display: none;
|
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
.authenticated .sidebarAccountBox {
|
.authenticated .sidebarAccountBox {
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
/* global $ */
|
|
||||||
|
|
||||||
import Filter from '../Filter'
|
|
||||||
|
|
||||||
const Account = {
|
|
||||||
isOpen: false,
|
|
||||||
changing: false,
|
|
||||||
init: function() {
|
|
||||||
var self = Account
|
|
||||||
$('body').click(self.close)
|
|
||||||
},
|
|
||||||
toggleBox: function(event) {
|
|
||||||
var self = Account
|
|
||||||
if (self.isOpen) self.close()
|
|
||||||
else self.open()
|
|
||||||
event.stopPropagation()
|
|
||||||
},
|
|
||||||
open: function() {
|
|
||||||
var self = Account
|
|
||||||
$('.sidebarAccountIcon .tooltipsUnder').addClass('hide')
|
|
||||||
if (!self.isOpen && !self.changing) {
|
|
||||||
self.changing = true
|
|
||||||
$('.sidebarAccountBox').fadeIn(200, function() {
|
|
||||||
self.changing = false
|
|
||||||
self.isOpen = true
|
|
||||||
$('.sidebarAccountBox #user_email').focus()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
close: function() {
|
|
||||||
var self = Account
|
|
||||||
$('.sidebarAccountIcon .tooltipsUnder').removeClass('hide')
|
|
||||||
if (!self.changing) {
|
|
||||||
self.changing = true
|
|
||||||
$('.sidebarAccountBox #user_email').blur()
|
|
||||||
$('.sidebarAccountBox').fadeOut(200, function() {
|
|
||||||
self.changing = false
|
|
||||||
self.isOpen = false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Account
|
|
|
@ -7,7 +7,6 @@ import { merge } from 'lodash'
|
||||||
|
|
||||||
import { notifyUser } from './index.js'
|
import { notifyUser } from './index.js'
|
||||||
import ImportDialog from './ImportDialog'
|
import ImportDialog from './ImportDialog'
|
||||||
import Account from './Account'
|
|
||||||
import Active from '../Active'
|
import Active from '../Active'
|
||||||
import DataModel from '../DataModel'
|
import DataModel from '../DataModel'
|
||||||
import { ExploreMaps, ChatView, TopicCard } from '../Views'
|
import { ExploreMaps, ChatView, TopicCard } from '../Views'
|
||||||
|
@ -103,8 +102,7 @@ const ReactApp = {
|
||||||
mobileTitle: self.mobileTitle,
|
mobileTitle: self.mobileTitle,
|
||||||
mobileTitleWidth: self.mobileTitleWidth,
|
mobileTitleWidth: self.mobileTitleWidth,
|
||||||
mobileTitleClick: (e) => Active.Map && InfoBox.toggleBox(e),
|
mobileTitleClick: (e) => Active.Map && InfoBox.toggleBox(e),
|
||||||
openInviteLightbox: () => self.openLightbox('invite'),
|
openInviteLightbox: () => self.openLightbox('invite')
|
||||||
toggleAccountBox: Account.toggleBox
|
|
||||||
},
|
},
|
||||||
self.getMapProps(),
|
self.getMapProps(),
|
||||||
self.getTopicProps(),
|
self.getTopicProps(),
|
||||||
|
|
|
@ -7,7 +7,6 @@ import Create from '../Create'
|
||||||
import ReactApp from './ReactApp'
|
import ReactApp from './ReactApp'
|
||||||
import Search from './Search'
|
import Search from './Search'
|
||||||
import CreateMap from './CreateMap'
|
import CreateMap from './CreateMap'
|
||||||
import Account from './Account'
|
|
||||||
import ImportDialog from './ImportDialog'
|
import ImportDialog from './ImportDialog'
|
||||||
|
|
||||||
const GlobalUI = {
|
const GlobalUI = {
|
||||||
|
@ -20,7 +19,6 @@ const GlobalUI = {
|
||||||
|
|
||||||
self.ReactApp.init(serverData, self.openLightbox)
|
self.ReactApp.init(serverData, self.openLightbox)
|
||||||
self.CreateMap.init(serverData)
|
self.CreateMap.init(serverData)
|
||||||
self.Account.init(serverData)
|
|
||||||
self.ImportDialog.init(serverData, self.openLightbox, self.closeLightbox)
|
self.ImportDialog.init(serverData, self.openLightbox, self.closeLightbox)
|
||||||
self.Search.init(serverData)
|
self.Search.init(serverData)
|
||||||
|
|
||||||
|
@ -153,5 +151,5 @@ const GlobalUI = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export { ReactApp, Search, CreateMap, Account, ImportDialog }
|
export { ReactApp, Search, CreateMap, ImportDialog }
|
||||||
export default GlobalUI
|
export default GlobalUI
|
||||||
|
|
|
@ -9,7 +9,7 @@ import DataModel from './DataModel'
|
||||||
import Debug from './Debug'
|
import Debug from './Debug'
|
||||||
import Filter from './Filter'
|
import Filter from './Filter'
|
||||||
import GlobalUI, {
|
import GlobalUI, {
|
||||||
ReactApp, Search, CreateMap, ImportDialog, Account as GlobalUIAccount
|
ReactApp, Search, CreateMap, ImportDialog
|
||||||
} from './GlobalUI'
|
} from './GlobalUI'
|
||||||
import Import from './Import'
|
import Import from './Import'
|
||||||
import JIT from './JIT'
|
import JIT from './JIT'
|
||||||
|
@ -45,7 +45,6 @@ Metamaps.GlobalUI = GlobalUI
|
||||||
Metamaps.GlobalUI.ReactApp = ReactApp
|
Metamaps.GlobalUI.ReactApp = ReactApp
|
||||||
Metamaps.GlobalUI.Search = Search
|
Metamaps.GlobalUI.Search = Search
|
||||||
Metamaps.GlobalUI.CreateMap = CreateMap
|
Metamaps.GlobalUI.CreateMap = CreateMap
|
||||||
Metamaps.GlobalUI.Account = GlobalUIAccount
|
|
||||||
Metamaps.GlobalUI.ImportDialog = ImportDialog
|
Metamaps.GlobalUI.ImportDialog = ImportDialog
|
||||||
Metamaps.Import = Import
|
Metamaps.Import = Import
|
||||||
Metamaps.JIT = JIT
|
Metamaps.JIT = JIT
|
||||||
|
|
|
@ -1,9 +1,16 @@
|
||||||
import React, { Component, PropTypes } from 'react'
|
import React, { Component, PropTypes } from 'react'
|
||||||
|
|
||||||
|
import onClickOutsideAddon from 'react-onclickoutside'
|
||||||
|
|
||||||
class AccountMenu extends Component {
|
class AccountMenu extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
currentUser: PropTypes.object,
|
currentUser: PropTypes.object,
|
||||||
onInviteClick: PropTypes.func
|
onInviteClick: PropTypes.func,
|
||||||
|
closeBox: PropTypes.func
|
||||||
|
}
|
||||||
|
|
||||||
|
handleClickOutside = () => {
|
||||||
|
this.props.closeBox()
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
|
@ -37,4 +44,4 @@ class AccountMenu extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default AccountMenu
|
export default onClickOutsideAddon(AccountMenu)
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
import React, { Component, PropTypes } from 'react'
|
import React, { Component, PropTypes } from 'react'
|
||||||
|
|
||||||
|
import onClickOutsideAddon from 'react-onclickoutside'
|
||||||
|
|
||||||
class LoginForm extends Component {
|
class LoginForm extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
loginFormAuthToken: PropTypes.string
|
loginFormAuthToken: PropTypes.string,
|
||||||
|
closeBox: PropTypes.func
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -15,13 +18,21 @@ class LoginForm extends Component {
|
||||||
this.setState({token})
|
this.setState({token})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
emailInputDidMount(node) {
|
||||||
|
node.focus()
|
||||||
|
}
|
||||||
|
|
||||||
|
handleClickOutside = () => {
|
||||||
|
this.props.closeBox()
|
||||||
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
return <form className="loginAnywhere" id="new_user" action="/login" acceptCharset="UTF-8" method="post">
|
return <form className="loginAnywhere" id="new_user" action="/login" acceptCharset="UTF-8" method="post">
|
||||||
<input name="utf8" type="hidden" value="✓" />
|
<input name="utf8" type="hidden" value="✓" />
|
||||||
<input type="hidden" name="authenticity_token" value={this.state.token} />
|
<input type="hidden" name="authenticity_token" value={this.state.token} />
|
||||||
<div className="accountImage"></div>
|
<div className="accountImage"></div>
|
||||||
<div className="accountInput accountEmail">
|
<div className="accountInput accountEmail">
|
||||||
<input placeholder="Email" type="email" name="user[email]" id="user_email" />
|
<input placeholder="Email" type="email" name="user[email]" id="user_email" ref={this.emailInputDidMount}/>
|
||||||
</div>
|
</div>
|
||||||
<div className="accountInput accountPassword">
|
<div className="accountInput accountPassword">
|
||||||
<input placeholder="Password" type="password" name="user[password]" id="user_password" />
|
<input placeholder="Password" type="password" name="user[password]" id="user_password" />
|
||||||
|
@ -43,4 +54,4 @@ class LoginForm extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default LoginForm
|
export default onClickOutsideAddon(LoginForm)
|
||||||
|
|
|
@ -9,16 +9,25 @@ class UpperRightUI extends Component {
|
||||||
currentUser: PropTypes.object,
|
currentUser: PropTypes.object,
|
||||||
signInPage: PropTypes.bool,
|
signInPage: PropTypes.bool,
|
||||||
unreadNotificationsCount: PropTypes.number,
|
unreadNotificationsCount: PropTypes.number,
|
||||||
openInviteLightbox: PropTypes.func,
|
openInviteLightbox: PropTypes.func
|
||||||
onClickAccount: PropTypes.func
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static contextTypes = {
|
constructor(props) {
|
||||||
location: PropTypes.object
|
super(props)
|
||||||
|
this.state = {accountBoxOpen: false}
|
||||||
|
}
|
||||||
|
|
||||||
|
reset = () => {
|
||||||
|
this.setState({accountBoxOpen: false})
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleAccountBox = () => {
|
||||||
|
this.setState({accountBoxOpen: !this.state.accountBoxOpen})
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { currentUser, signInPage, unreadNotificationsCount, openInviteLightbox, onClickAccount } = this.props
|
const { currentUser, signInPage, unreadNotificationsCount, openInviteLightbox } = this.props
|
||||||
|
const { accountBoxOpen } = this.state
|
||||||
return <div className="upperRightUI">
|
return <div className="upperRightUI">
|
||||||
{currentUser && <a href="/maps/new" target="_blank" className="addMap upperRightEl upperRightIcon">
|
{currentUser && <a href="/maps/new" target="_blank" className="addMap upperRightEl upperRightIcon">
|
||||||
<div className="tooltipsUnder">
|
<div className="tooltipsUnder">
|
||||||
|
@ -29,17 +38,17 @@ class UpperRightUI extends Component {
|
||||||
<NotificationIcon unreadNotificationsCount={unreadNotificationsCount} />
|
<NotificationIcon unreadNotificationsCount={unreadNotificationsCount} />
|
||||||
</span>}
|
</span>}
|
||||||
{!signInPage && <div className="sidebarAccount upperRightEl">
|
{!signInPage && <div className="sidebarAccount upperRightEl">
|
||||||
<div className="sidebarAccountIcon" onClick={onClickAccount}>
|
<div className="sidebarAccountIcon ignore-react-onclickoutside" onClick={this.toggleAccountBox}>
|
||||||
<div className="tooltipsUnder">Account</div>
|
<div className="tooltipsUnder">Account</div>
|
||||||
{currentUser && <img src={currentUser.get('image')} />}
|
{currentUser && <img src={currentUser.get('image')} />}
|
||||||
{!currentUser && 'SIGN IN'}
|
{!currentUser && 'SIGN IN'}
|
||||||
{!currentUser && <div className="accountInnerArrow"></div>}
|
{!currentUser && <div className="accountInnerArrow"></div>}
|
||||||
</div>
|
</div>
|
||||||
<div className="sidebarAccountBox upperRightBox">
|
{accountBoxOpen && <div className="sidebarAccountBox upperRightBox">
|
||||||
{currentUser
|
{currentUser
|
||||||
? <AccountMenu onInviteClick={openInviteLightbox} currentUser={currentUser} />
|
? <AccountMenu onInviteClick={openInviteLightbox} currentUser={currentUser} closeBox={this.reset} />
|
||||||
: <LoginForm />}
|
: <LoginForm closeBox={this.reset} />}
|
||||||
</div>
|
</div>}
|
||||||
</div>}
|
</div>}
|
||||||
<div className="clearfloat"></div>
|
<div className="clearfloat"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -16,7 +16,6 @@ class App extends Component {
|
||||||
mobileTitleWidth: PropTypes.number,
|
mobileTitleWidth: PropTypes.number,
|
||||||
mobileTitleClick: PropTypes.func,
|
mobileTitleClick: PropTypes.func,
|
||||||
openInviteLightbox: PropTypes.func,
|
openInviteLightbox: PropTypes.func,
|
||||||
toggleAccountBox: PropTypes.func,
|
|
||||||
map: PropTypes.object,
|
map: PropTypes.object,
|
||||||
userRequested: PropTypes.bool,
|
userRequested: PropTypes.bool,
|
||||||
requestAnswered: PropTypes.bool,
|
requestAnswered: PropTypes.bool,
|
||||||
|
@ -36,7 +35,7 @@ class App extends Component {
|
||||||
render () {
|
render () {
|
||||||
const { children, toast, unreadNotificationsCount, openInviteLightbox,
|
const { children, toast, unreadNotificationsCount, openInviteLightbox,
|
||||||
mobile, mobileTitle, mobileTitleWidth, mobileTitleClick, location,
|
mobile, mobileTitle, mobileTitleWidth, mobileTitleClick, location,
|
||||||
toggleAccountBox, map, userRequested, requestAnswered, requestApproved,
|
map, userRequested, requestAnswered, requestApproved,
|
||||||
onRequestAccess } = this.props
|
onRequestAccess } = this.props
|
||||||
const { pathname } = location || {}
|
const { pathname } = location || {}
|
||||||
// this fixes a bug that happens otherwise when you logout
|
// this fixes a bug that happens otherwise when you logout
|
||||||
|
@ -57,8 +56,7 @@ class App extends Component {
|
||||||
{!mobile && <UpperRightUI currentUser={currentUser}
|
{!mobile && <UpperRightUI currentUser={currentUser}
|
||||||
unreadNotificationsCount={unreadNotificationsCount}
|
unreadNotificationsCount={unreadNotificationsCount}
|
||||||
openInviteLightbox={openInviteLightbox}
|
openInviteLightbox={openInviteLightbox}
|
||||||
signInPage={pathname === '/login'}
|
signInPage={pathname === '/login'} />}
|
||||||
onClickAccount={toggleAccountBox} />}
|
|
||||||
<Toast message={toast} />
|
<Toast message={toast} />
|
||||||
{!mobile && currentUser && <a className='feedback-icon' target='_blank' href='https://hylo.com/c/metamaps'></a>}
|
{!mobile && currentUser && <a className='feedback-icon' target='_blank' href='https://hylo.com/c/metamaps'></a>}
|
||||||
{children}
|
{children}
|
||||||
|
|
Loading…
Add table
Reference in a new issue