diff --git a/app/assets/stylesheets/application.scss.erb b/app/assets/stylesheets/application.scss.erb index d255b652..11330ef9 100644 --- a/app/assets/stylesheets/application.scss.erb +++ b/app/assets/stylesheets/application.scss.erb @@ -826,6 +826,7 @@ label { font-size: 14px; line-height: 14px; color: #757575; + cursor: pointer; } .accountListItem:hover { color: #424242; diff --git a/app/assets/stylesheets/clean.css.erb b/app/assets/stylesheets/clean.css.erb index 3bc37d68..0790437e 100644 --- a/app/assets/stylesheets/clean.css.erb +++ b/app/assets/stylesheets/clean.css.erb @@ -668,19 +668,19 @@ box-shadow: 0px 3px 3px rgba(0,0,0,0.23), 0 3px 3px rgba(0,0,0,0.16); } -#exploreMapsHeader { +#navBar { position: absolute; width: 100%; } -.exploreMapsBar { +.navBarContainer { z-index:2; background-color:#FAFAFA; height: 42px; padding-top: 52px; } -.exploreMapsMenu { +.navBarMenu { display: block; width: 100%; height:42px; @@ -689,11 +689,11 @@ text-align: center; } -.exploreMapsCenter { +.navBarCenter { display: block; } -.exploreMapsButton { +.navBarButton { color: #757575; cursor: default; font-weight: normal; @@ -706,13 +706,13 @@ cursor: pointer; position:relative; } -.exploreMapsButton:hover, .exploreMapsButton.active { +.navBarButton:hover, .navBarButton.active { text-decoration: none; color: #424242; border-bottom: 2px solid #00BCD4; } -.exploreMapsButton.mapperButton { +.navBarButton.mapperButton { height: 40px; padding: 0; } @@ -729,7 +729,7 @@ } -.exploreMapsButton .exploreMapsIcon { +.navBarButton .navBarIcon { background-repeat: no-repeat; width:32px; height:32px; @@ -738,53 +738,53 @@ left:5px; } -.exploreMapsCenter .authedApps .exploreMapsIcon { +.navBarCenter .authedApps .navBarIcon { background-image: url(<%= asset_path('user_sprite.png') %>); background-position: 0 -32px; } -.exploreMapsCenter .myMaps .exploreMapsIcon { +.navBarCenter .myMaps .navBarIcon { background-image: url(<%= asset_path 'exploremaps_sprite.png' %>); background-position: -32px 0; } -.exploreMapsCenter .sharedMaps .exploreMapsIcon { +.navBarCenter .sharedMaps .navBarIcon { background-image: url(<%= asset_path 'exploremaps_sprite.png' %>); background-position: -128px 0; } -.exploreMapsCenter .activeMaps .exploreMapsIcon { +.navBarCenter .activeMaps .navBarIcon { background-image: url(<%= asset_path 'exploremaps_sprite.png' %>); background-position: 0 0; } -.exploreMapsCenter .featuredMaps .exploreMapsIcon { +.navBarCenter .featuredMaps .navBarIcon { background-image: url(<%= asset_path 'exploremaps_sprite.png' %>); background-position: -96px 0; } -.exploreMapsCenter .starredMaps .exploreMapsIcon { +.navBarCenter .starredMaps .navBarIcon { background-image: url(<%= asset_path 'exploremaps_sprite.png' %>); background-position: -96px 0; } -.exploreMapsCenter .notificationsLink .exploreMapsIcon { +.navBarCenter .notificationsLink .navBarIcon { background-image: url(<%= asset_path 'topright_sprite.png' %>); background-position: -128px 0; } -.authedApps:hover .exploreMapsIcon, .authedApps.active .exploreMapsIcon { +.authedApps:hover .navBarIcon, .authedApps.active .navBarIcon { background-position-x: -32px; } -.myMaps:hover .exploreMapsIcon, .myMaps.active .exploreMapsIcon { +.myMaps:hover .navBarIcon, .myMaps.active .navBarIcon { background-position: -32px -32px; } -.activeMaps:hover .exploreMapsIcon, .activeMaps.active .exploreMapsIcon { +.activeMaps:hover .navBarIcon, .activeMaps.active .navBarIcon { background-position: 0 -32px; } -.featuredMaps:hover .exploreMapsIcon, .featuredMaps.active .exploreMapsIcon { +.featuredMaps:hover .navBarIcon, .featuredMaps.active .navBarIcon { background-position: -96px -32px; } -.starredMaps:hover .exploreMapsIcon, .starredMaps.active .exploreMapsIcon { +.starredMaps:hover .navBarIcon, .starredMaps.active .navBarIcon { background-position: -96px -32px; } -.sharedMaps:hover .exploreMapsIcon, .sharedMaps.active .exploreMapsIcon { +.sharedMaps:hover .navBarIcon, .sharedMaps.active .navBarIcon { background-position: -128px -32px; } -.notificationsLink:hover .exploreMapsIcon, .notificationsLink.active .exploreMapsIcon { +.notificationsLink:hover .navBarIcon, .notificationsLink.active .navBarIcon { background-position-y: -32px; } diff --git a/app/assets/stylesheets/mobile.scss.erb b/app/assets/stylesheets/mobile.scss.erb index 704569c8..02aefeb4 100644 --- a/app/assets/stylesheets/mobile.scss.erb +++ b/app/assets/stylesheets/mobile.scss.erb @@ -32,7 +32,7 @@ /* Smartphones (portrait and landscape) ----------- the minimum space that two map cards can fit side by side */ @media only screen and (max-width : 504px) { - .upperLeftUI, .upperRightUI, .openCheatsheet, .mapInfoIcon, .feedback-icon, .chat-box, #exploreMapsHeader { + .upperLeftUI, .upperRightUI, .openCheatsheet, .mapInfoIcon, .feedback-icon, .chat-box, #navBar { display: none !important; } diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 3ebbbad6..340874fc 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -6,10 +6,10 @@ #%> <%= render :partial => 'layouts/head' %> - controller-<%= controller_name %> action-<%= action_name %>"> + controller-<%= controller_name %> action-<%= action_name %>">
<%= yield %> - <% if authenticated? %> + <% if current_user %> <% # for creating and pulling in topics and synapses %> <% if controller_name == 'maps' && action_name == "conversation" %> <%= render :partial => 'maps/newtopicsecret' %> diff --git a/app/views/layouts/doorkeeper.html.erb b/app/views/layouts/doorkeeper.html.erb deleted file mode 100644 index b9ff5bef..00000000 --- a/app/views/layouts/doorkeeper.html.erb +++ /dev/null @@ -1,31 +0,0 @@ -<%# -# @file -# Main application file. Holds scaffolding present on every page. -# Then a certain non-partial view (no _ preceding filename) will be -# displayed within, based on URL -#%> - -<%= render :partial => 'layouts/head' %> - -
- <%= yield %> -
-
-
-
- <% if current_user && current_user.admin %> - -
Registered Apps -
- <% end %> - -
Authorized Apps -
- -
Maps -
-
-
-
-
-<%= render :partial => 'layouts/foot' %> diff --git a/app/views/notifications/_header.html.erb b/app/views/notifications/_header.html.erb deleted file mode 100644 index 2507b2ef..00000000 --- a/app/views/notifications/_header.html.erb +++ /dev/null @@ -1,14 +0,0 @@ -
-
- -
-
diff --git a/app/views/notifications/index.html.erb b/app/views/notifications/index.html.erb index 3efbcb45..4b0a69d2 100644 --- a/app/views/notifications/index.html.erb +++ b/app/views/notifications/index.html.erb @@ -76,5 +76,3 @@ <% end %> - -<%= render partial: 'notifications/header' %> diff --git a/app/views/notifications/show.html.erb b/app/views/notifications/show.html.erb index a552aa77..e2cb2bd2 100644 --- a/app/views/notifications/show.html.erb +++ b/app/views/notifications/show.html.erb @@ -9,7 +9,7 @@

<% case @notification.notification_code when MAP_ACCESS_REQUEST - request = @notification.notified_object + request = @notification.notified_object map = request.map %> <%= image_tag @notification.sender.image(:thirtytwo), class: 'thirty-two-avatar' %> <%= request.user.name %> wants to collaborate on map <%= map.name %> <% else %> @@ -24,7 +24,7 @@ <% if request.approved %> You already responded to this access request, and allowed access. <% elsif !request.approved %> - You already responded to this access request, and declined access. If you changed your mind, you can still grant + You already responded to this access request, and declined access. If you changed your mind, you can still grant them access by going to the map and adding them as a collaborator. <% end %> <% else %> @@ -50,5 +50,3 @@ <% end %> - -<%= render partial: 'notifications/header' %> diff --git a/config/application.rb b/config/application.rb index 8731e76a..06842eb6 100644 --- a/config/application.rb +++ b/config/application.rb @@ -25,9 +25,9 @@ module Metamaps config.encoding = 'utf-8' config.to_prepare do - Doorkeeper::ApplicationsController.layout 'doorkeeper' - Doorkeeper::AuthorizationsController.layout 'doorkeeper' - Doorkeeper::AuthorizedApplicationsController.layout 'doorkeeper' + Doorkeeper::ApplicationsController.layout 'application' + Doorkeeper::AuthorizationsController.layout 'application' + Doorkeeper::AuthorizedApplicationsController.layout 'application' Doorkeeper::ApplicationController.helper ApplicationHelper end diff --git a/frontend/src/components/App/NavBar.js b/frontend/src/components/App/NavBar.js new file mode 100644 index 00000000..92ec9591 --- /dev/null +++ b/frontend/src/components/App/NavBar.js @@ -0,0 +1,19 @@ +import React, { Component } from 'react' + +class NavBar extends Component { + render() { + return ( + + ) + } +} + +export default NavBar diff --git a/frontend/src/components/App/NavBarLink.js b/frontend/src/components/App/NavBarLink.js new file mode 100644 index 00000000..033de2e9 --- /dev/null +++ b/frontend/src/components/App/NavBarLink.js @@ -0,0 +1,65 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import { Link } from 'react-router' +import _ from 'lodash' + +const PROP_LIST = [ + 'matchChildRoutes', + 'hardReload', + 'show', + 'text', + 'href', + 'linkClass' +] + +class NavBarLink extends Component { + static propTypes = { + matchChildRoutes: PropTypes.bool, + hardReload: PropTypes.bool, + show: PropTypes.bool, + text: PropTypes.string, + href: PropTypes.string, + linkClass: PropTypes.string + } + + static contextTypes = { + location: PropTypes.object + } + + render = () => { + const { + matchChildRoutes, + hardReload, + show, + text, + href, + linkClass + } = this.props + const { location } = this.context + const otherProps = _.omit(this.props, PROP_LIST) + const classes = ['navBarButton', linkClass] + const active = matchChildRoutes ? + location.pathname.startsWith(href) : + location.pathname === href + if (active) classes.push('active') + if (!show) { + return null + } + if (hardReload) { + return ( + +
+ {text} +
+ ) + } + return ( + +
+ {text} + + ) + } +} + +export default NavBarLink diff --git a/frontend/src/components/App/index.js b/frontend/src/components/App/index.js index 9d4d3ee0..9a830255 100644 --- a/frontend/src/components/App/index.js +++ b/frontend/src/components/App/index.js @@ -38,17 +38,38 @@ class App extends Component { return {location} } + constructor (props) { + super(props) + this.state = { + yieldHTML: null + } + } + + componentDidMount () { + this.setYield() + } + + setYield () { + const yieldHTML = document.getElementById('yield') + if (yieldHTML) { + this.setState({yieldHTML: yieldHTML.innerHTML}) + document.body.removeChild(yieldHTML) + } + } + render () { const { children, toast, unreadNotificationsCount, openInviteLightbox, mobile, mobileTitle, mobileTitleWidth, mobileTitleClick, location, map, userRequested, requestAnswered, requestApproved, serverData, onRequestAccess, notifications, fetchNotifications, markAsRead, markAsUnread } = this.props + const { yieldHTML } = this.state const { pathname } = location || {} // this fixes a bug that happens otherwise when you logout const currentUser = this.props.currentUser && this.props.currentUser.id ? this.props.currentUser : null const unauthedHome = pathname === '/' && !currentUser return
+ {yieldHTML &&
} {mobile && { + const { currentUser } = this.props + + return ( + + {currentUser && currentUser.get('admin') && } + + + + ) + } +} + +export default Apps diff --git a/frontend/src/components/Maps/Header.js b/frontend/src/components/Maps/Header.js index 2168e0c0..770c0efb 100644 --- a/frontend/src/components/Maps/Header.js +++ b/frontend/src/components/Maps/Header.js @@ -1,80 +1,50 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import { Link } from 'react-router' -import _ from 'lodash' - -const MapLink = props => { - const { show, text, href, linkClass } = props - const otherProps = _.omit(props, ['show', 'text', 'href', 'linkClass']) - if (!show) { - return null - } - - return ( - -
- {text} - - ) -} +import NavBar from '../App/Navbar' +import NavBarLink from '../App/NavBarLink' class Header extends Component { render = () => { const { signedIn, section, user } = this.props - const activeClass = (title) => { - let forClass = 'exploreMapsButton' - forClass += ' ' + title + 'Maps' - if (title === 'my' && section === 'mine' || - title === section) forClass += ' active' - return forClass - } - const explore = section === 'mine' || section === 'active' || section === 'starred' || section === 'shared' || section === 'featured' const mapper = section === 'mapper' return ( -
-
-
-
- - - - - - - {mapper ? ( -
- {user && } - {user &&
{user.name}’s Maps
} -
-
- ) : null } -
+ + + + + + + {mapper ? ( +
+ {user && } + {user &&
{user.name}’s Maps
} +
-
-
+ ) : null } + ) } } diff --git a/frontend/src/components/Maps/index.js b/frontend/src/components/Maps/index.js index 081515fe..c6835a5f 100644 --- a/frontend/src/components/Maps/index.js +++ b/frontend/src/components/Maps/index.js @@ -6,7 +6,6 @@ import MapperCard from './MapperCard' import MapCard from './MapCard' class Maps extends Component { - static propTypes = { section: PropTypes.string, maps: PropTypes.object, diff --git a/frontend/src/components/Notifications/index.js b/frontend/src/components/Notifications/index.js new file mode 100644 index 00000000..a744e0c3 --- /dev/null +++ b/frontend/src/components/Notifications/index.js @@ -0,0 +1,17 @@ +import React, { Component } from 'react' +import NavBar from '../App/Navbar' +import NavBarLink from '../App/NavBarLink' + +class Notifications extends Component { + render = () => { + return ( + + + + + ) + } +} + +export default Notifications diff --git a/frontend/src/components/makeRoutes.js b/frontend/src/components/makeRoutes.js index 45f8b746..90146627 100644 --- a/frontend/src/components/makeRoutes.js +++ b/frontend/src/components/makeRoutes.js @@ -1,8 +1,10 @@ import React from 'react' import { Route, IndexRoute } from 'react-router' import App from './App' +import Apps from './Apps' import Maps from './Maps' import MapView from './MapView' +import Notifications from './Notifications' import TopicView from './TopicView' function nullComponent(props) { @@ -31,8 +33,8 @@ export default function makeRoutes (currentUser) { - - + + @@ -50,20 +52,20 @@ export default function makeRoutes (currentUser) { - + - - + + - - - - + + + +