Skip to content

Commit 27b733c

Browse files
feat: brand consolodation (#778)
* theme adjustments * home mobile styling * active tab * links * header controls margin, not container
1 parent 3d75359 commit 27b733c

40 files changed

+232
-141
lines changed

web-app/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
"recharts": "^2.12.7",
4848
"redux-persist": "^6.0.0",
4949
"redux-saga": "^1.2.3",
50-
"typeface-muli": "^1.1.13",
5150
"yup": "^1.3.2"
5251
},
5352
"peerDependencies": {

web-app/public/index.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@
2424
work correctly both with client-side routing and a non-root public URL.
2525
Learn how to configure a non-root public URL by running `npm run build`.
2626
-->
27+
<link rel="preconnect" href="https://fonts.googleapis.com">
28+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
29+
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&display=swap" rel="stylesheet">
30+
<link href="https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,200..1000;1,200..1000&display=swap" rel="stylesheet">
2731
<title>Mobility Database</title>
2832
</head>
2933
<body>

web-app/src/app/App.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
1515
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
1616

1717
function App(): React.ReactElement {
18-
require('typeface-muli'); // Load font
1918
const dispatch = useDispatch();
2019
const [isAppReady, setIsAppReady] = useState(false);
2120

web-app/src/app/Theme.ts

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,27 @@ declare module '@mui/material/styles/createMixins' {
1616
}
1717
}
1818

19+
export const fontFamily = {
20+
primary: '"Mulish"',
21+
secondary: '"IBM Plex Mono"',
22+
};
23+
1924
const palette = {
2025
primary: {
2126
main: '#3959fa',
27+
dark: '#002eea',
28+
light: '#989ffc',
2229
contrastText: '#f9faff',
2330
},
2431
secondary: {
25-
main: '#96a1ff',
32+
main: '#96a1ff', // original mobility data purple
33+
dark: '#4a5fe8',
34+
light: '#e7e8ff',
35+
contrastText: '#f9faff',
2636
},
2737
background: {
2838
default: '#ffffff',
29-
paper: '#f7f7f7',
39+
paper: '#F8F5F5',
3040
},
3141
text: {
3242
primary: '#474747',
@@ -47,7 +57,7 @@ export const theme = createTheme({
4757
},
4858
},
4959
typography: {
50-
fontFamily: '"Muli"',
60+
fontFamily: fontFamily.primary,
5161
},
5262
components: {
5363
MuiFormLabel: {
@@ -79,6 +89,21 @@ export const theme = createTheme({
7989
root: {
8090
textTransform: 'none',
8191
boxShadow: 'none',
92+
fontFamily: fontFamily.secondary,
93+
boxSizing: 'border-box',
94+
'&.MuiButton-contained': {
95+
border: '2px solid transparent',
96+
},
97+
'&.MuiButton-containedPrimary:hover': {
98+
boxShadow: 'none',
99+
backgroundColor: 'transparent',
100+
border: `2px solid ${palette.primary.main}`,
101+
color: palette.primary.main,
102+
},
103+
'&.MuiButton-outlinedPrimary:hover': {
104+
backgroundColor: palette.primary.main,
105+
color: palette.primary.contrastText,
106+
},
82107
},
83108
},
84109
},

web-app/src/app/components/Footer.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,27 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
66
import { faSlack } from '@fortawesome/free-brands-svg-icons';
77
import { GitHub, LinkedIn, OpenInNew } from '@mui/icons-material';
88
import { MOBILITY_DATA_LINKS } from '../constants/Navigation';
9+
import { fontFamily } from '../Theme';
910

1011
const Footer: React.FC = () => {
1112
const navigateTo = (link: string): void => {
1213
window.open(link, '_blank');
1314
};
1415

1516
return (
16-
<footer className='footer'>
17+
<footer className='footer' style={{ fontFamily: fontFamily.secondary }}>
1718
<a
1819
href={'https://share.mobilitydata.org/mobility-database-feedback'}
1920
target={'_blank'}
2021
rel='noreferrer'
2122
className={'btn-link'}
2223
>
2324
<Button
24-
sx={{ textTransform: 'none', mb: 2 }}
25+
sx={{
26+
textTransform: 'none',
27+
mb: 2,
28+
fontFamily: fontFamily.secondary,
29+
}}
2530
variant={'outlined'}
2631
endIcon={<OpenInNew />}
2732
>

web-app/src/app/components/Header.tsx

Lines changed: 95 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
Menu,
1818
MenuItem,
1919
Select,
20+
type SxProps,
2021
} from '@mui/material';
2122
import MenuIcon from '@mui/icons-material/Menu';
2223
import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown';
@@ -29,7 +30,7 @@ import {
2930
buildNavigationItems,
3031
} from '../constants/Navigation';
3132
import type NavigationItem from '../interface/Navigation';
32-
import { useNavigate } from 'react-router-dom';
33+
import { useLocation, useNavigate } from 'react-router-dom';
3334
import { useSelector } from 'react-redux';
3435
import { selectIsAuthenticated, selectUserEmail } from '../store/selectors';
3536
import LogoutConfirmModal from './LogoutConfirmModal';
@@ -43,7 +44,7 @@ import { useRemoteConfig } from '../context/RemoteConfigProvider';
4344
import i18n from '../../i18n';
4445
import { NestedMenuItem } from 'mui-nested-menu';
4546
import DirectionsBusIcon from '@mui/icons-material/DirectionsBus';
46-
import { theme } from '../Theme';
47+
import { fontFamily, theme } from '../Theme';
4748

4849
const drawerWidth = 240;
4950
const websiteTile = 'Mobility Database';
@@ -71,7 +72,7 @@ const DrawerContent: React.FC<{
7172
<Avatar src='/assets/MOBILTYDATA_logo_purple_M.png'></Avatar>
7273
<Typography
7374
variant='h6'
74-
sx={{ my: 2, cursor: 'pointer' }}
75+
sx={{ my: 2, cursor: 'pointer', color: theme.palette.primary.main }}
7576
data-testid='websiteTile'
7677
>
7778
{websiteTile}
@@ -94,7 +95,11 @@ const DrawerContent: React.FC<{
9495
pl: '16px',
9596
}}
9697
>
97-
<ListItemText>
98+
<ListItemText
99+
sx={{
100+
'.MuiTypography-root': { fontFamily: fontFamily.secondary },
101+
}}
102+
>
98103
{item.title}{' '}
99104
{item.external === true ? (
100105
<OpenInNew sx={{ verticalAlign: 'middle' }} />
@@ -113,7 +118,10 @@ const DrawerContent: React.FC<{
113118
<TreeItem
114119
nodeId='1'
115120
label='GTFS Metrics'
116-
sx={{ color: theme.palette.primary.main }}
121+
sx={{
122+
color: theme.palette.primary.main,
123+
'.MuiTreeItem-label': { fontFamily: fontFamily.secondary },
124+
}}
117125
>
118126
<TreeItem
119127
nodeId='2'
@@ -182,7 +190,10 @@ const DrawerContent: React.FC<{
182190
<TreeItem
183191
nodeId='1'
184192
label='Account'
185-
sx={{ color: theme.palette.primary.main }}
193+
sx={{
194+
color: theme.palette.primary.main,
195+
'.MuiTreeItem-label': { fontFamily: fontFamily.secondary },
196+
}}
186197
data-cy='accountHeader'
187198
>
188199
<TreeItem
@@ -229,8 +240,10 @@ const DrawerContent: React.FC<{
229240
};
230241

231242
export default function DrawerAppBar(): React.ReactElement {
243+
const location = useLocation();
232244
const [mobileOpen, setMobileOpen] = React.useState(false);
233245
const [openDialog, setOpenDialog] = React.useState(false);
246+
const [activeTab, setActiveTab] = React.useState('');
234247
const [navigationItems, setNavigationItems] = React.useState<
235248
NavigationItem[]
236249
>([]);
@@ -243,6 +256,10 @@ export default function DrawerAppBar(): React.ReactElement {
243256
setCurrentLanguage(i18n.language);
244257
});
245258

259+
React.useEffect(() => {
260+
setActiveTab(location.pathname);
261+
}, [location.pathname]);
262+
246263
React.useEffect(() => {
247264
setNavigationItems(buildNavigationItems(config));
248265
}, [config]);
@@ -290,14 +307,61 @@ export default function DrawerAppBar(): React.ReactElement {
290307

291308
const metricsOptionsEnabled =
292309
config.enableMetrics || userEmail?.endsWith('mobilitydata.org') === true;
310+
const AnimatedButtonStyling: SxProps = {
311+
minWidth: 'fit-content',
312+
px: 0,
313+
mx: {
314+
md: 1,
315+
lg: 2,
316+
},
317+
fontFamily: fontFamily.secondary,
318+
'&:hover, &.active': {
319+
backgroundColor: 'transparent',
320+
'&::after': {
321+
transform: 'scaleX(1)',
322+
left: 0,
323+
right: 0,
324+
transformOrigin: 'left',
325+
},
326+
},
327+
'&.active.short': {
328+
'&::after': {
329+
right: '20px',
330+
},
331+
},
332+
'&::after': {
333+
content: '""',
334+
height: '2px',
335+
position: 'absolute',
336+
left: 0,
337+
right: 0,
338+
bottom: 0,
339+
backgroundColor: theme.palette.primary.main,
340+
opacity: 0.7,
341+
transition: 'transform 0.9s cubic-bezier(0.19, 1, 0.22, 1)',
342+
transform: 'scaleX(0)',
343+
transformOrigin: 'right',
344+
pointerEvents: 'none',
345+
},
346+
};
293347

294348
return (
295-
<Box sx={{ display: 'flex' }}>
349+
<Box
350+
sx={{
351+
display: 'flex',
352+
height: '64px',
353+
mb: { xs: 2, md: 4 },
354+
}}
355+
>
296356
<AppBar
297357
component='nav'
298358
color='inherit'
299359
elevation={0}
300-
sx={{ background: 'white' }}
360+
sx={{
361+
background: 'white',
362+
fontFamily: fontFamily.secondary,
363+
borderBottom: '1px solid rgba(0,0,0,0.2)',
364+
}}
301365
>
302366
<Toolbar sx={{ display: 'flex', justifyContent: 'space-between' }}>
303367
<Box sx={{ display: 'flex', alignItems: 'center' }}>
@@ -325,6 +389,7 @@ export default function DrawerAppBar(): React.ReactElement {
325389
component='div'
326390
className='website-title'
327391
sx={{
392+
ml: 1,
328393
display: { xs: 'none', md: 'block' },
329394
}}
330395
>
@@ -336,13 +401,19 @@ export default function DrawerAppBar(): React.ReactElement {
336401
<Box sx={{ display: { xs: 'none', md: 'block' } }}>
337402
{navigationItems.map((item) => (
338403
<Button
404+
sx={{
405+
...AnimatedButtonStyling,
406+
color: theme.palette.text.primary,
407+
}}
339408
href={item.external === true ? item.target : '/' + item.target}
340409
key={item.title}
341-
sx={{ color: item.color, minWidth: 'fit-content', mx: 1 }}
342410
target={item.external === true ? '_blank' : '_self'}
343411
rel={item.external === true ? 'noopener noreferrer' : ''}
344412
variant={'text'}
345413
endIcon={item.external === true ? <OpenInNew /> : null}
414+
className={
415+
activeTab.includes('/' + item.target) ? 'active' : ''
416+
}
346417
>
347418
{item.title}
348419
</Button>
@@ -355,8 +426,14 @@ export default function DrawerAppBar(): React.ReactElement {
355426
aria-haspopup='true'
356427
endIcon={<ArrowDropDownIcon />}
357428
onClick={handleMenuOpen}
358-
sx={{ color: 'black' }}
429+
sx={{
430+
...AnimatedButtonStyling,
431+
color: theme.palette.text.primary,
432+
}}
359433
id='analytics-button-menu'
434+
className={
435+
activeTab.includes('metrics') ? 'active short' : ''
436+
}
360437
>
361438
Metrics
362439
</Button>
@@ -434,6 +511,8 @@ export default function DrawerAppBar(): React.ReactElement {
434511
onClick={handleMenuOpen}
435512
endIcon={<ArrowDropDownIcon />}
436513
id='account-button-menu'
514+
sx={AnimatedButtonStyling}
515+
className={activeTab === '/account' ? 'active short' : ''}
437516
>
438517
Account
439518
</Button>
@@ -464,7 +543,12 @@ export default function DrawerAppBar(): React.ReactElement {
464543
</Menu>
465544
</>
466545
) : (
467-
<Button href={SIGN_IN_TARGET}>Login</Button>
546+
<Button
547+
sx={{ fontFamily: fontFamily.secondary }}
548+
href={SIGN_IN_TARGET}
549+
>
550+
Login
551+
</Button>
468552
)}
469553
{/* Testing language tool */}
470554
{config.enableLanguageToggle && currentLanguage !== undefined && (

web-app/src/app/screens/About.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ import Container from '@mui/material/Container';
55
import '../styles/SignUp.css';
66
import { Button, Typography } from '@mui/material';
77
import { OpenInNew } from '@mui/icons-material';
8+
import { theme } from '../Theme';
89

910
export default function About(): React.ReactElement {
1011
return (
1112
<Container component='main'>
1213
<CssBaseline />
1314
<Box
1415
sx={{
15-
mt: 12,
1616
display: 'flex',
1717
flexDirection: 'column',
1818
}}
@@ -22,7 +22,7 @@ export default function About(): React.ReactElement {
2222
</Typography>
2323
<Box
2424
sx={{
25-
background: '#F8F5F5',
25+
background: theme.palette.background.paper,
2626
mt: 2,
2727
p: 2,
2828
borderRadius: '6px 6px 0px 0px',

web-app/src/app/screens/Account.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,6 @@ export default function APIAccount(): React.ReactElement {
259259
component={'main'}
260260
maxWidth={false}
261261
sx={{
262-
mt: 12,
263262
display: 'flex',
264263
flexDirection: 'column',
265264
alignItems: 'center',

web-app/src/app/screens/Analytics/GBFSFeedAnalytics/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -276,8 +276,8 @@ export default function GBFSFeedAnalytics(): React.ReactElement {
276276
});
277277

278278
return (
279-
<Box sx={{ m: 10 }}>
280-
<Typography variant='h5' color='primary' sx={{ fontWeight: 700 }}>
279+
<Box sx={{ mx: 6 }}>
280+
<Typography variant='h4' color='primary' sx={{ fontWeight: 700, mb: 2 }}>
281281
GBFS Feeds Metrics
282282
</Typography>
283283
{error != null && (

0 commit comments

Comments
 (0)