Skip to content
This repository was archived by the owner on Oct 12, 2019. It is now read-only.

Commit c8f1b43

Browse files
Merge pull request #113 from ecatch-kyst/develop
Develop
2 parents c09fda3 + 0a5c8ea commit c8f1b43

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

98 files changed

+2190
-4041
lines changed

.eslintrc

+3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
},
1111
"parser":"babel-eslint",
1212
"rules": {
13+
"object-shorthand":"error",
14+
"multiline-comment-style": ["error", "starred-block"],
15+
"no-irregular-whitespace":"error",
1316
"require-jsdoc":"warn",
1417
"no-useless-escape":"error",
1518
"block-spacing":["warn", "never"],

CHANGELOG.md

+10
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@
22
All notable changes to this project will be documented in this file.
33

44
## Unreleased
5+
### Added
6+
- First time you send a message information from Preset is used to fill input
7+
- Fish on board tracking
8+
- translations to validation error messages
9+
- redirect to Preset page for the first time
10+
### Changed
11+
- Refactored dropdown select menus. Using native solutions where possible. Multiple select is turned into a popup with checkboxes, for better a11y. 🚸
12+
13+
### Changed
14+
- period is now used in a consistant manner for every notification
515

616
## [1.0.0-beta5] - 2019-04-08
717
### Changed

package.json

+11-11
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,17 @@
77
"@material-ui/core": "^3.9.3",
88
"@material-ui/icons": "^3.0.2",
99
"date-fns": "^2.0.0-alpha.27",
10-
"deepmerge": "^3.1.0",
11-
"firebase": "^5.8.0",
12-
"i18next": "^15.0.0",
13-
"prop-types": "^15.6.2",
14-
"react": "^16.8.5",
15-
"react-dom": "^16.8.5",
16-
"react-i18next": "^10.0.0",
10+
"deepmerge": "^3.2.0",
11+
"firebase": "^5.11.0",
12+
"i18next": "^15.1.0",
13+
"prop-types": "^15.7.2",
14+
"react": "^16.8.6",
15+
"react-dom": "^16.8.6",
16+
"react-i18next": "^10.9.0",
1717
"react-router": "^5.0.0",
1818
"react-router-dom": "^5.0.0",
1919
"react-scripts": "2.1.8",
20-
"react-select": "^2.3.0",
20+
"react-select": "^2.4.3",
2121
"react-virtualized": "^9.21.0"
2222
},
2323
"scripts": {
@@ -49,10 +49,10 @@
4949
],
5050
"devDependencies": {
5151
"enzyme": "^3.9.0",
52-
"enzyme-adapter-react-16": "^1.11.2",
53-
"eslint-config-prettier": "^4.0.0",
52+
"enzyme-adapter-react-16": "^1.12.1",
53+
"eslint-config-prettier": "^4.2.0",
5454
"eslint-plugin-prettier": "^3.0.1",
5555
"eslint-plugin-react": "^7.12.4",
56-
"node-sass": "^4.11.0"
56+
"node-sass": "^4.12.0"
5757
}
5858
}

public/index.html

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
<body>
3838
<noscript>You need to enable JavaScript to run this app.</noscript>
3939
<div id="root"></div>
40+
<div id="notification"></div>
41+
<div id="dialog"></div>
4042
<!--
4143
This HTML file is a template.
4244
If you open it directly in the browser, you will see an empty page.

src/App.js

+38-85
Original file line numberDiff line numberDiff line change
@@ -1,107 +1,60 @@
11
import React from 'react'
2-
import {Route, Switch, withRouter, Link} from "react-router-dom"
2+
import {Redirect, Route, Switch, withRouter} from "react-router-dom"
33

4-
import ProfileIcon from "@material-ui/icons/PersonOutlineOutlined"
5-
import DashboardIcon from "@material-ui/icons/DashboardOutlined"
6-
import TripIcon from "@material-ui/icons/CompareArrowsOutlined"
7-
import PresetIcon from "@material-ui/icons/AddSharp"
4+
import {withTheme} from '@material-ui/core'
85

9-
import {withTheme, BottomNavigation, BottomNavigationAction} from '@material-ui/core'
10-
11-
import {routes} from './lib/router'
6+
import {routes as ROUTES} from './lib/router'
127

138
import {
14-
Landing,
15-
Profile,
16-
Register,
17-
OfflineStatus,
18-
HomePage,
19-
NotFound,
20-
Dialog,
21-
Trips,
22-
Messages,
23-
Trip,
24-
EditCatch,
25-
Form,
26-
Notification,
27-
Preset
9+
Dialog, EditCatch, Form, Home,
10+
Landing, Messages, NotFound, Notification,
11+
OfflineStatus, Preset, Profile, Register,
12+
Trip, Trips
2813
} from './components'
2914

30-
import {useTranslation} from 'react-i18next'
31-
15+
import Navigation from './Navigation'
16+
17+
18+
// Define new pages here
19+
const routes = [
20+
{component: Landing, path: ROUTES.ROOT},
21+
{component: Register, path: ROUTES.REGISTER}, // REVIEW: Delete?
22+
{component: Profile, path: ROUTES.PROFILE},
23+
{component: Home, path: ROUTES.HOMEPAGE},
24+
{component: Preset, path: ROUTES.PRESET},
25+
{component: Trips, path: ROUTES.TRIPS},
26+
{component: Trip, path: `${ROUTES.TRIPS}/:tripId`},
27+
{component: Messages, path: ROUTES.MESSAGES},
28+
{component: EditCatch, path: `${ROUTES.MESSAGES}/:type/:messageId${ROUTES.EDIT}`},
29+
{component: Form, path: `${ROUTES.MESSAGES}/:type${ROUTES.NEW}`}
30+
]
3231

3332
export const App = ({theme: {palette: {type}}}) =>
34-
<div className="app" style={{backgroundColor: type === "dark" ? "#000" : ""}}>
33+
<div className={`app ${type === "dark" ? "dark" : ""}`}>
34+
<Route component={Navigation}/>
3535
<Switch>
36-
<Route component={Landing} exact path={routes.ROOT}/>
37-
<Route component={Register} exact path={routes.REGISTER}/>
38-
<Route component={Profile} exact path={routes.PROFILE}/>
39-
<Route component={HomePage} exact path={routes.HOMEPAGE}/>
40-
<Route component={Preset} exact path={routes.PRESET}/>
41-
<Route component={Trips} exact path={routes.TRIPS}/>
42-
<Route component={Trip} exact path={`${routes.TRIPS}/:tripId`}/>
43-
<Route component={Messages} exact path={routes.MESSAGES}/>
44-
<Route component={EditCatch} exact path={`${routes.MESSAGES}/:type/:messageId${routes.EDIT}`}/>
45-
<Route component={Form} exact path={`${routes.MESSAGES}/:type${routes.NEW}`}/>
36+
{routes.map(route =>
37+
<Route key={route.path} {...route} exact/>
38+
)}
4639
<Route component={NotFound}/>
4740
</Switch>
48-
<Route
49-
render={
50-
({location: {pathname}}) =>
51-
![routes.ROOT, routes.REGISTER].includes(pathname) ?
52-
<Navigation value={pathname.slice(1)} /> :
53-
null
54-
}
55-
/>
5641
<OfflineStatus/>
5742
<Dialog/>
5843
<Notification/>
44+
<FirstTimeRedirect/>
5945
</div>
6046

61-
6247
export default withRouter(withTheme()(App))
6348

6449

65-
const navigation = [
66-
{
67-
id: "homepage",
68-
icon: <DashboardIcon/>,
69-
to: routes.HOMEPAGE
70-
},
71-
{
72-
id: "trips",
73-
icon: <TripIcon/>,
74-
to: routes.TRIPS
75-
},
76-
{
77-
id: "profile",
78-
icon: <ProfileIcon/>,
79-
to: routes.PROFILE
80-
},
81-
{
82-
id: "preset",
83-
icon: <PresetIcon/>,
84-
to: routes.PRESET
50+
/**
51+
* If the user opens the page for the first time,
52+
* they will be redirected to the PRESET page.
53+
*/
54+
const FirstTimeRedirect = () => {
55+
if (!localStorage.getItem("noRedirect")) {
56+
localStorage.setItem("noRedirect", 1)
57+
return <Redirect to={ROUTES.PRESET}/>
8558
}
86-
]
87-
88-
export const Navigation = ({value}) => {
89-
const [t] = useTranslation("common")
90-
return (
91-
<BottomNavigation
92-
style={{position: "fixed", bottom: 0, width: "100vw"}}
93-
value={value}
94-
>
95-
{navigation.map(({id, icon, to}) =>
96-
<BottomNavigationAction
97-
component={Link}
98-
icon={icon}
99-
key={id}
100-
label={t(`navigation.${id}`)}
101-
to={to}
102-
value={id}
103-
/>
104-
)}
105-
</BottomNavigation>
106-
)
59+
return null
10760
}

src/Navigation.jsx

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import React from 'react'
2+
import {Link} from "react-router-dom"
3+
import {BottomNavigation, BottomNavigationAction} from '@material-ui/core'
4+
import {HomeIcon, PresetIcon, ProfileIcon, TripIcon} from "./icons"
5+
import {useTranslation} from 'react-i18next'
6+
import {routes} from './lib/router'
7+
8+
9+
// Navigation buttons should be added here
10+
const navigation = [
11+
{
12+
id: "homepage",
13+
icon: <HomeIcon/>,
14+
to: routes.HOMEPAGE
15+
},
16+
{
17+
id: "trips",
18+
icon: <TripIcon/>,
19+
to: routes.TRIPS
20+
},
21+
{
22+
id: "profile",
23+
icon: <ProfileIcon/>,
24+
to: routes.PROFILE
25+
},
26+
{
27+
id: "preset",
28+
icon: <PresetIcon/>,
29+
to: routes.PRESET
30+
}
31+
]
32+
33+
34+
export const Navigation = ({location: {pathname}}) => {
35+
if (pathname === routes.ROOT) return null // Don't show Navigation on login page
36+
const [t] = useTranslation("common")
37+
38+
return (
39+
<BottomNavigation
40+
className="bottom-navigation"
41+
value={pathname.split("/")[1]}
42+
>
43+
{navigation.map(({id, icon, to}) =>
44+
<BottomNavigationAction
45+
component={Link}
46+
icon={icon}
47+
key={id}
48+
label={t(`navigation.${id}`)}
49+
showLabel
50+
to={to}
51+
value={id}
52+
/>
53+
)}
54+
</BottomNavigation>
55+
)
56+
}
57+
58+
export default Navigation

src/__mocks__/react-i18next.js

+11-9
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,15 @@ module.exports = {
3939
t => t,
4040
{changeLanguage: jest.fn()}
4141
])
42-
// mock if needed
43-
// Interpolate: reactI18next.Interpolate,
44-
// I18nextProvider: reactI18next.I18nextProvider,
45-
// loadNamespaces: reactI18next.loadNamespaces,
46-
// reactI18nextModule: reactI18next.reactI18nextModule,
47-
// setDefaults: reactI18next.setDefaults,
48-
// getDefaults: reactI18next.getDefaults,
49-
// setI18n: reactI18next.setI18n,
50-
// getI18n: reactI18next.getI18n
42+
/*
43+
* mock if needed
44+
* Interpolate: reactI18next.Interpolate,
45+
* I18nextProvider: reactI18next.I18nextProvider,
46+
* loadNamespaces: reactI18next.loadNamespaces,
47+
* reactI18nextModule: reactI18next.reactI18nextModule,
48+
* setDefaults: reactI18next.setDefaults,
49+
* getDefaults: reactI18next.getDefaults,
50+
* setI18n: reactI18next.setI18n,
51+
* getI18n: reactI18next.getI18n
52+
*/
5153
}

src/a2hs.js

+11-11
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
11

22
window.addEventListener('beforeinstallprompt', (e) => {
33
// Prevent Chrome 67 and earlier from automatically showing the prompt
4-
e.preventDefault();
4+
e.preventDefault()
55
// Stash the event so it can be triggered later.
6-
deferredPrompt = e;
6+
deferredPrompt = e
77
// Update UI notify the user they can add to home screen
8-
btnAdd.style.display = 'block';
9-
});
8+
btnAdd.style.display = 'block'
9+
})
1010

1111
btnAdd.addEventListener('click', (e) => {
1212
// hide our user interface that shows our A2HS button
13-
btnAdd.style.display = 'none';
13+
btnAdd.style.display = 'none'
1414
// Show the prompt
15-
deferredPrompt.prompt();
15+
deferredPrompt.prompt()
1616
// Wait for the user to respond to the prompt
1717
deferredPrompt.userChoice
1818
.then((choiceResult) => {
1919
if (choiceResult.outcome === 'accepted') {
20-
console.log('User accepted the A2HS prompt');
20+
console.log('User accepted the A2HS prompt')
2121
} else {
22-
console.log('User dismissed the A2HS prompt');
22+
console.log('User dismissed the A2HS prompt')
2323
}
24-
deferredPrompt = null;
25-
});
26-
});
24+
deferredPrompt = null
25+
})
26+
})

src/components/Centered.jsx

+7-4
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@ import {Grid} from '@material-ui/core'
33
import {useDimensions} from '../hooks'
44

55

6-
const Centered = ({children, style, ...props}) => {
6+
/*
7+
* Centers content on the middle of the device,
8+
* responsive to height changes
9+
*/
10+
const Centered = ({children, style, heightOffset=0, ...props}) => {
711
const {height} = useDimensions()
8-
912
return (
1013
<Grid
1114
alignItems="center"
@@ -14,8 +17,8 @@ const Centered = ({children, style, ...props}) => {
1417
direction="column"
1518
justify="center"
1619
style={{
17-
minHeight: height,
18-
maxHeight: height,
20+
minHeight: height+heightOffset,
21+
maxHeight: height+heightOffset,
1922
...style
2023
}}
2124
{...props}

0 commit comments

Comments
 (0)