- resource-watch/graph Knowledge graph and future recommendation system
- resource-watch-app Old repository for the app
- resource-watch-manager Old repository for the back office
- rw-components Old repository used to store components that were used in both resource-watch-app and resource-watch-manager
The application is built on top of Next.js - a framework for server-rendered React apps - and was created starting from the template created with nextjs-starter - a starter project for Next.js with oAuth and email based authentication -. The code created by this starter kit was however modified and improved so that it better fitted our needs.
components React components (.js file extension instead of .jsx due to Next.js)
Application components under app folder and back office ones under admin. The rest of folders are used to store components that could be used in any of the two.
css Styles Replicating folder structure of React components
Top level files:
- index.scss: used to load all the styles
- config.scss: configuration and variables
- layouts.scss: general layout styles
- base.scss: base styles
- foundation_settings.scss: main styles for foundation
pages Folder where Next.js will look for pages that should be rendered according to the routes definition
Pages that are part of the back office are located under the sub-folder admin, pages that are part of the public portal are located under app respectively.
services One file per entity (dataset, widget, layer...) that includes the logic necessary to perform operations over it (CRUD)
static Equivalent to public folder in used with other technologies. This folder is used to store the assets needed across the application.
utils General logic that could potentially be used anywhere in the code.
We discarded the approach followed by nextjs-starter and decided to use passport-control-tower instead.
We're using the package next-routes for routing. This package allows us to define routes with unique names in a very straightforward way and, thanks to this, we can reference them from anywhere in the code without having to specify the route itself everywhere - which could result into errors when updating the value of a route in several places.
The routes are defined in the file routes.js. Here's an excerpt of the file:
// ----- DATASET --------
routes.add('admin_home', '/admin', 'admin/dataset');
routes.add('datasets', '/admin/datasets', 'admin/dataset');
routes.add('edit_dataset', '/admin/datasets/:id/edit', 'admin/dataset/edit');
The first value of the method represents the unique name of the route, the second is the route itself, while the third represents the path to the page that should be rendered (starting from the folder pages).
RW uses Redux together with the next-redux-wrapper. In order to wrap a React component with Redux we have to do the following:
Import the store and withRedux
import withRedux from 'next-redux-wrapper';
import { initStore } from 'store';
Deine the functions mapStateToProps and mapDispatchToProps if necessary (simply pass null otherwise)
const mapStateToProps = state => ({
layerActive: state.pulse.layerActive
});
const mapDispatchToProps = dispatch => ({
toggleActiveLayer: (id, threedimensional, hemisphere) => {
dispatch(toggleActiveLayer(id, threedimensional, hemisphere));
},
getLayerPoints: (id, tableName) => {
dispatch(getLayerPoints(id, tableName));
}
});
Export the class using the function withRedux
export default withRedux(initStore, mapStateToProps, mapDispatchToProps)(LayerNavDropdown);