diff --git a/src/app/src/App.js b/src/app/src/App.js index 368debd2..e6df1181 100644 --- a/src/app/src/App.js +++ b/src/app/src/App.js @@ -1,5 +1,11 @@ import { Box, Flex } from '@chakra-ui/react'; -import { BrowserRouter, Navigate, Routes, Route } from 'react-router-dom'; +import { + BrowserRouter, + Outlet, + Navigate, + Routes, + Route, +} from 'react-router-dom'; import './App.css'; import Login from './pages/Login'; @@ -9,11 +15,16 @@ import Welcome from './pages/Welcome'; import Draw from './pages/Draw'; import Submissions from './pages/Submissions'; import Sidebar from './components/Sidebar'; +import NavBar from './components/NavBar'; import PrivateRoute from './components/PrivateRoute'; const privateRoutes = ( + + } /> + } /> + } /> diff --git a/src/app/src/components/Map.js b/src/app/src/components/Map.js index c0b4e182..7dcefa95 100644 --- a/src/app/src/components/Map.js +++ b/src/app/src/components/Map.js @@ -1,15 +1,23 @@ import { MapContainer } from 'react-leaflet'; +import { useLocation } from 'react-router-dom'; -import { MAP_CENTER, MAP_INITIAL_ZOOM } from '../constants'; +import { MAP_CENTER, MAP_INITIAL_ZOOM, NAVBAR_HEIGHT } from '../constants'; import MapPanes from './MapPanes'; export default function Map({ children }) { + const location = useLocation(); + + // Anywhere but welcome activity, deduct height of nav bar + const heightExpression = location.pathname.startsWith('/welcome') + ? '100vh' + : `calc(100vh - ${NAVBAR_HEIGHT}px)`; + return ( {children} diff --git a/src/app/src/components/NavBar.js b/src/app/src/components/NavBar.js new file mode 100644 index 00000000..0b976f88 --- /dev/null +++ b/src/app/src/components/NavBar.js @@ -0,0 +1,132 @@ +import { + Button, + Flex, + SimpleGrid, + Heading, + Icon, + IconButton, + Select, + Spacer, + Text, +} from '@chakra-ui/react'; +import { useDispatch, useSelector } from 'react-redux'; +import { useLocation, useNavigate } from 'react-router-dom'; +import { ArrowLeftIcon, CogIcon, LogoutIcon } from '@heroicons/react/outline'; +import apiClient from '../api/client'; +import { API_URLS, NAVBAR_HEIGHT } from '../constants'; +import { logout, setSelectedUtility } from '../store/authSlice'; + +const NAVBAR_VARIANTS = { + DRAW: 'draw', + SUBMISSION: 'submission', +}; + +export default function NavBar() { + const location = useLocation(); + + let variant = NAVBAR_VARIANTS.SUBMISSION; + if (location.pathname.startsWith('/draw')) { + variant = NAVBAR_VARIANTS.DRAW; + } + + return ( + + + + + + + + Boundary Sync + + + + + + + + + + ); +} + +function SettingsButton({ variant }) { + const navigate = useNavigate(); + + return variant === NAVBAR_VARIANTS.SUBMISSION ? ( + } + aria-label='Settings' + onClick={() => { + navigate('/settings'); + }} + /> + ) : null; +} + +function ExitButton({ variant }) { + const navigate = useNavigate(); + const dispatch = useDispatch(); + + return variant === NAVBAR_VARIANTS.SUBMISSION ? ( + + ) : ( + + ); +} + +function UtilityControl({ variant }) { + const dispatch = useDispatch(); + + // placeholders + const utilities = ['Raleigh City of', 'Azavea Test Utility']; + const selectedUtility = + useSelector(state => state.auth.selectedUtility) || utilities[0]; + + return variant === NAVBAR_VARIANTS.SUBMISSION && utilities.length > 1 ? ( + + ) : ( + {selectedUtility} + ); +} diff --git a/src/app/src/components/Sidebar.js b/src/app/src/components/Sidebar.js index 8e84a11a..6ab91f51 100644 --- a/src/app/src/components/Sidebar.js +++ b/src/app/src/components/Sidebar.js @@ -12,7 +12,6 @@ import { Tooltip, } from '@chakra-ui/react'; import { - MenuIcon, QuestionMarkCircleIcon as HelpIcon, PlusIcon, EyeIcon, @@ -37,7 +36,6 @@ export default function Sidebar() { return ( - @@ -47,17 +45,6 @@ export default function Sidebar() { ); } -function TitleBar() { - return ( - - - - Boundary Sync - - - ); -} - function ReferenceLayers() { const dispatch = useDispatch(); const addReferenceImage = useAddReferenceImage(); diff --git a/src/app/src/constants.js b/src/app/src/constants.js index 6dd16d1b..914467fc 100644 --- a/src/app/src/constants.js +++ b/src/app/src/constants.js @@ -30,6 +30,8 @@ export const SIDEBAR_TEXT_TOOLTIP_THRESHOLD = 30; export const MUNICIPAL_BOUNDARY_LABELS_MIN_ZOOM_LEVEL = 9; +export const NAVBAR_HEIGHT = 68; + // https://leafletjs.com/reference.html#map-mappane export const PANES = { BASEMAP: { label: 'basemap', zIndex: 200 }, diff --git a/src/app/src/store/authSlice.js b/src/app/src/store/authSlice.js index 46265b5d..96f102b2 100644 --- a/src/app/src/store/authSlice.js +++ b/src/app/src/store/authSlice.js @@ -3,6 +3,8 @@ import { createSlice } from '@reduxjs/toolkit'; const initialState = { signedIn: false, locationBeforeAuth: '/welcome', + utilities: [], + selectedUtility: null, }; export const authSlice = createSlice({ @@ -20,9 +22,21 @@ export const authSlice = createSlice({ state.locationBeforeAuth = location; } }, + setUtilities: (state, { payload: utilities }) => { + state.utilities = utilities; + }, + setSelectedUtility: (state, { payload: selectedUtility }) => { + state.selectedUtility = selectedUtility; + }, }, }); -export const { login, logout, setLocationBeforeAuth } = authSlice.actions; +export const { + login, + logout, + setLocationBeforeAuth, + setUtilities, + setSelectedUtility, +} = authSlice.actions; export default authSlice.reducer; diff --git a/src/app/src/theme.js b/src/app/src/theme.js index b7ecf759..ff183270 100644 --- a/src/app/src/theme.js +++ b/src/app/src/theme.js @@ -209,6 +209,12 @@ const theme = extendTheme({ fontSize: '16px', color: 'gray.700', }, + selectedUtility: { + fontFamily: `'Inter', sans-serif`, + fontWeight: 400, + fontSize: '20px', + color: 'white', + }, }, styles: { global: {