{
- (typeof props.msg === 'string' || props.msg instanceof String)?
+ typeof props.msg === 'string' ?
props.msg
: 'Enjoy the colouring! Usual service should resume shortly.'
}
@@ -21,9 +24,4 @@ const InfoBox = (props) => (
);
-InfoBox.propTypes = {
- msg: PropTypes.string,
- children: PropTypes.node
-}
-
export default InfoBox;
diff --git a/app/src/frontend/components/tooltip.tsx b/app/src/frontend/components/tooltip.tsx
index b9de9267..04cb8a28 100644
--- a/app/src/frontend/components/tooltip.tsx
+++ b/app/src/frontend/components/tooltip.tsx
@@ -1,14 +1,17 @@
import React, { Component } from 'react';
-import PropTypes from 'prop-types';
import './tooltip.css';
import { InfoIcon } from './icons';
-class Tooltip extends Component
{ // TODO: add proper types
- static propTypes = { // TODO: generate propTypes from TS
- text: PropTypes.string
- };
+interface TooltipProps {
+ text: string;
+}
+interface TooltipState {
+ active: boolean;
+}
+
+class Tooltip extends Component {
constructor(props) {
super(props);
this.state = {
diff --git a/app/src/frontend/header.tsx b/app/src/frontend/header.tsx
index 861dbb4a..6ca98615 100644
--- a/app/src/frontend/header.tsx
+++ b/app/src/frontend/header.tsx
@@ -1,13 +1,14 @@
import React, { Fragment } from 'react';
import { NavLink } from 'react-router-dom';
-import PropTypes from 'prop-types';
import { Logo } from './components/logo';
+import { User } from './models/user';
+
import './header.css';
interface HeaderProps {
- user: any;
+ user: User;
animateLogo: boolean;
}
@@ -18,14 +19,7 @@ interface HeaderState {
/**
* Render the main header using a responsive design
*/
-class Header extends React.Component { // TODO: add proper types
- static propTypes = { // TODO: generate propTypes from TS
- user: PropTypes.shape({
- username: PropTypes.string
- }),
- animateLogo: PropTypes.bool
- };
-
+class Header extends React.Component {
constructor(props) {
super(props);
this.state = {collapseMenu: true};
diff --git a/app/src/frontend/map-app.tsx b/app/src/frontend/map-app.tsx
index 7849a56d..cf4cfda9 100644
--- a/app/src/frontend/map-app.tsx
+++ b/app/src/frontend/map-app.tsx
@@ -1,6 +1,5 @@
import React, { Fragment } from 'react';
import { Switch, Route, RouteComponentProps, Redirect } from 'react-router-dom';
-import PropTypes from 'prop-types';
import Welcome from './pages/welcome';
import Sidebar from './building/sidebar';
@@ -19,10 +18,10 @@ interface MapAppRouteParams {
}
interface MapAppProps extends RouteComponentProps {
- building: Building;
- building_like: boolean;
- user: any;
- revisionId: number;
+ building?: Building;
+ building_like?: boolean;
+ user?: any;
+ revisionId?: number;
}
interface MapAppState {
@@ -33,13 +32,6 @@ interface MapAppState {
}
class MapApp extends React.Component {
- static propTypes = {
- category: PropTypes.string,
- revision_id: PropTypes.number,
- building: PropTypes.object,
- building_like: PropTypes.bool,
- user: PropTypes.object
- };
constructor(props: Readonly) {
super(props);
@@ -235,7 +227,7 @@ class MapApp extends React.Component {
-
+
(
diff --git a/app/src/frontend/map/legend.tsx b/app/src/frontend/map/legend.tsx
index b1e8bddb..75ea3d44 100644
--- a/app/src/frontend/map/legend.tsx
+++ b/app/src/frontend/map/legend.tsx
@@ -1,5 +1,4 @@
import React from 'react';
-import PropTypes from 'prop-types';
import './legend.css';
import { Logo } from '../components/logo';
@@ -114,13 +113,15 @@ const LEGEND_CONFIG = {
};
-class Legend extends React.Component { // TODO: add proper types
- static propTypes = { // TODO: generate propTypes from TS
- slug: PropTypes.string,
- color: PropTypes.string,
- text: PropTypes.string
- };
+interface LegendProps {
+ slug: string;
+}
+interface LegendState {
+ collapseList: boolean;
+}
+
+class Legend extends React.Component {
constructor(props) {
super(props);
this.state = {collapseList: false};
diff --git a/app/src/frontend/map/map.tsx b/app/src/frontend/map/map.tsx
index 4a57efa5..f8199f1b 100644
--- a/app/src/frontend/map/map.tsx
+++ b/app/src/frontend/map/map.tsx
@@ -1,4 +1,3 @@
-import PropTypes from 'prop-types';
import React, { Component, Fragment } from 'react';
import { Map, TileLayer, ZoomControl, AttributionControl, GeoJSON } from 'react-leaflet-universal';
import { GeoJsonObject } from 'geojson';
@@ -15,12 +14,12 @@ import { Building } from '../models/building';
const OS_API_KEY = 'NVUxtY5r8eA6eIfwrPTAGKrAAsoeI9E9';
interface ColouringMapProps {
- building: Building;
+ building?: Building;
mode: 'basic' | 'view' | 'edit' | 'multi-edit';
category: string;
revision_id: number;
- selectBuilding: any;
- colourBuilding: any;
+ selectBuilding: (building: Building) => void;
+ colourBuilding: (building: Building) => void;
}
interface ColouringMapState {
@@ -34,15 +33,6 @@ interface ColouringMapState {
* Map area
*/
class ColouringMap extends Component {
- static propTypes = { // TODO: generate propTypes from TS
- building: PropTypes.object,
- mode: PropTypes.string,
- category: PropTypes.string,
- revision_id: PropTypes.number,
- selectBuilding: PropTypes.func,
- colourBuilding: PropTypes.func
- };
-
constructor(props) {
super(props);
this.state = {
diff --git a/app/src/frontend/map/search-box.tsx b/app/src/frontend/map/search-box.tsx
index 06d2b67b..79fd03f2 100644
--- a/app/src/frontend/map/search-box.tsx
+++ b/app/src/frontend/map/search-box.tsx
@@ -1,16 +1,35 @@
import React, { Component } from 'react';
-import PropTypes from 'prop-types';
import './search-box.css';
import { SearchIcon } from '../components/icons';
+import { Point } from 'geojson';
+
+interface SearchResult {
+ type: string;
+ attributes: {
+ label: string;
+ zoom: number;
+ };
+ geometry: Point
+}
+
+
+interface SearchBoxProps {
+ onLocate: (lat: number, lng: number, zoom: number) => void
+}
+
+interface SearchBoxState {
+ q: string;
+ results: SearchResult[];
+ fetching: boolean;
+ collapsedSearch: boolean;
+ smallScreen: boolean;
+}
+
/**
* Search for location
*/
-class SearchBox extends Component { // TODO: add proper types
- static propTypes = { // TODO: generate propTypes from TS
- onLocate: PropTypes.func
- };
-
+class SearchBox extends Component {
constructor(props) {
super(props);
this.state = {
diff --git a/app/src/frontend/map/theme-switcher.tsx b/app/src/frontend/map/theme-switcher.tsx
index 3d87478d..c1db9815 100644
--- a/app/src/frontend/map/theme-switcher.tsx
+++ b/app/src/frontend/map/theme-switcher.tsx
@@ -1,9 +1,13 @@
import React from 'react';
-import PropTypes from 'prop-types';
import './theme-switcher.css';
-const ThemeSwitcher = (props) => (
+interface ThemeSwitcherProps {
+ currentTheme: string;
+ onSubmit: (e: React.FormEvent) => void;
+}
+
+const ThemeSwitcher: React.FC = (props) => (
);
-ThemeSwitcher.propTypes = {
- currentTheme: PropTypes.string,
- onSubmit: PropTypes.func.isRequired
-}
-
export default ThemeSwitcher;
diff --git a/app/src/frontend/models/user.ts b/app/src/frontend/models/user.ts
index 2b5c662b..4f3fa245 100644
--- a/app/src/frontend/models/user.ts
+++ b/app/src/frontend/models/user.ts
@@ -1,5 +1,9 @@
interface User {
- username: string;
+ username?: string;
+ email?: string;
+ registered?: Date;
+ api_key?: string;
+ error?: string;
// TODO: add other fields as needed
}
diff --git a/app/src/frontend/user/login.tsx b/app/src/frontend/user/login.tsx
index a7007b67..dbfbb12c 100644
--- a/app/src/frontend/user/login.tsx
+++ b/app/src/frontend/user/login.tsx
@@ -1,17 +1,17 @@
import React, { Component } from 'react';
import { Redirect, Link } from 'react-router-dom';
-import PropTypes from 'prop-types';
import ErrorBox from '../components/error-box';
import InfoBox from '../components/info-box';
import SupporterLogos from '../components/supporter-logos';
+import { User } from '../models/user';
-class Login extends Component { // TODO: add proper types
- static propTypes = { // TODO: generate propTypes from TS
- login: PropTypes.func,
- user: PropTypes.object
- };
+interface LoginProps {
+ user: User,
+ login: (user: User) => void;
+}
+class Login extends Component {
constructor(props) {
super(props);
this.state = {
diff --git a/app/src/frontend/user/my-account.tsx b/app/src/frontend/user/my-account.tsx
index 0659d217..5948ba99 100644
--- a/app/src/frontend/user/my-account.tsx
+++ b/app/src/frontend/user/my-account.tsx
@@ -1,23 +1,23 @@
import React, { Component, FormEvent } from 'react';
import { Link, Redirect } from 'react-router-dom';
-import PropTypes from 'prop-types';
import ConfirmationModal from '../components/confirmation-modal';
import ErrorBox from '../components/error-box';
+import { User } from '../models/user';
-class MyAccountPage extends Component { // TODO: add proper types
- static propTypes = { // TODO: generate propTypes from TS
- user: PropTypes.shape({
- username: PropTypes.string,
- email: PropTypes.string,
- registered: PropTypes.instanceOf(Date), // TODO: check if fix correct
- api_key: PropTypes.string,
- error: PropTypes.object
- }),
- updateUser: PropTypes.func,
- logout: PropTypes.func
- };
+interface MyAccountPageProps {
+ user: User;
+ updateUser: (user: User) => void;
+ logout: () => void;
+}
+interface MyAccountPageState {
+ showDeleteConfirm: boolean;
+ error: string;
+}
+
+
+class MyAccountPage extends Component {
constructor(props) {
super(props);
this.state = {
diff --git a/app/src/frontend/user/password-reset.tsx b/app/src/frontend/user/password-reset.tsx
index aacd06a5..e270aa61 100644
--- a/app/src/frontend/user/password-reset.tsx
+++ b/app/src/frontend/user/password-reset.tsx
@@ -1,4 +1,4 @@
-import React, { ChangeEvent, FormEvent } from 'react';
+import React, { FormEvent } from 'react';
import { RouteComponentProps, Redirect } from 'react-router';
import ErrorBox from '../components/error-box';
diff --git a/app/src/frontend/user/signup.tsx b/app/src/frontend/user/signup.tsx
index 1a8ad00e..6c1e2835 100644
--- a/app/src/frontend/user/signup.tsx
+++ b/app/src/frontend/user/signup.tsx
@@ -1,17 +1,27 @@
import React, { Component } from 'react';
import { Redirect, Link } from 'react-router-dom';
-import PropTypes from 'prop-types';
import ErrorBox from '../components/error-box';
import InfoBox from '../components/info-box';
import SupporterLogos from '../components/supporter-logos';
+import { User } from '../models/user';
-class SignUp extends Component { // TODO: add proper types
- static propTypes = { // TODO: generate propTypes from TS
- login: PropTypes.func.isRequired,
- user: PropTypes.object
- };
+interface SignUpProps {
+ login: (user: User) => void;
+ user: User;
+}
+interface SignUpState {
+ username: string;
+ email: string;
+ confirm_email: string;
+ show_password: boolean;
+ password: string;
+ confirm_conditions: boolean;
+ error: string;
+}
+
+class SignUp extends Component {
constructor(props) {
super(props);
this.state = {
@@ -19,7 +29,7 @@ class SignUp extends Component { // TODO: add proper types
email: '',
confirm_email: '',
password: '',
- show_password: '',
+ show_password: false,
confirm_conditions: false,
error: undefined
};
@@ -31,11 +41,11 @@ class SignUp extends Component { // TODO: add proper types
handleChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
- const name = target.name;
+ const name: keyof SignUpState = target.name;
this.setState({
[name]: value
- });
+ } as Pick);
}
handleSubmit(event) {