diff --git a/.babelrc b/.babelrc
new file mode 100644
index 0000000..c6d5404
--- /dev/null
+++ b/.babelrc
@@ -0,0 +1,10 @@
+{
+ "presets": [
+ "@babel/preset-env",
+ "@babel/preset-react"
+ ],
+ "plugins": [
+ "@babel/plugin-syntax-dynamic-import",
+ "@babel/plugin-proposal-class-properties"
+ ]
+}
\ No newline at end of file
diff --git a/.env b/.env
deleted file mode 100644
index 09ac831..0000000
--- a/.env
+++ /dev/null
@@ -1,2 +0,0 @@
-REACT_APP_LESS=true
-REACT_APP_LESS_MODULES=true
diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..61cf7f7
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,3 @@
+REACT_APP_API_BASE_URL=http://localhost:8000/v1
+REACT_APP_API_TIMEOUT=30000
+REACT_APP_BACKEND_IMAGES_BASE_URL=http://localhost:8000/
\ No newline at end of file
diff --git a/.eslintrc b/.eslintrc
index 201d771..c459bcf 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -1,15 +1,43 @@
{
- "extends": "airbnb",
+ "parser": "@babel/eslint-parser",
+ "extends": [
+ "eslint:recommended",
+ "plugin:react/recommended"
+ ],
+ "settings": {
+ "react": {
+ "version": "detect"
+ }
+ },
"rules": {
- "indent": ["error", 2], // Require 2-space indent
- "quotes": 0, // No specified quote style; the programmer should take care of using only one style
- "max-len": ["error", 120], // 120-character lines are fine
- "curly": ["error", "all"], // Always require curlys.
- "comma-dangle": ["error", "only-multiline"], // Require trailing commas in multi-line literals (such as this)
- "complexity": ["error", {"max": 20}]
+ "indent": [
+ "error",
+ 2
+ ], // Require 2-space indent
+ "quotes": 0, // No specified quote style; the programmer should take care of using only one style
+ "max-len": [
+ "error",
+ 120
+ ], // 120-character lines are fine
+ "curly": [
+ "error",
+ "all"
+ ], // Always require curlys.
+ "comma-dangle": [
+ "error",
+ "only-multiline"
+ ], // Require trailing commas in multi-line literals (such as this)
+ "complexity": [
+ "error",
+ {
+ "max": 20
+ }
+ ]
},
"env": {
"browser": true,
- "mocha": true
+ "mocha": true,
+ "node": true,
+ "es6": true
}
-}
+}
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 0af3e41..617bc42 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,8 +7,12 @@
/coverage
# production
+/dist
/build
+# env
+.env
+
# misc
.DS_Store
npm-debug.log*
diff --git a/README.md b/README.md
index a93c944..a5f1b82 100644
--- a/README.md
+++ b/README.md
@@ -1,74 +1,51 @@
-The app is based on `create-react-app` script
-[https://github.com/facebookincubator/create-react-app](https://github.com/facebookincubator/create-react-app)
+# Living environment UI
+This is the frontend app for Living Environment platform built with React.
-## Clone the repo
+## Requirements
-`git clone https://github.com/City-of-Turku/living-environment-ui.git`
+Node.js version >= 20 and Yarn.
-## Configuration files
+## Installing
-In development app is reading the settings from `/src/config/config.dev.json`. For production mode, the settings from `/src/config/config.dev.json` are used.
-
-`api/baseUrl` should point to backend API base url (for ex. http://localhost:8000/api)
-`api/timeout` sets the request timeout given in milliseconds
-`backendImages` points to the base address of the images
-
-### `npm install`
-
-This command will install all app dependencies.
-
-### `npm start`
-
-Runs the app in the development mode.
-Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
-
-### `npm run build`
-
-Builds the app for production to the `build` folder.
-It correctly bundles React in production mode and optimizes the build for the best performance.
-
-The build is minified and the filenames include the hashes.
-Your app is ready to be deployed!
-
-The command creates a `build` directory with a production build of your app.
-
-### Static Server (testing the output of `build` command)
-
-For environments using [Node](https://nodejs.org/), the easiest way to handle this would be to install [serve](https://github.com/zeit/serve) and let it handle the rest:
+Clone the repo:
+```
+git clone https://github.com/City-of-Turku/living-environment-ui.git
+```
-```sh
-npm install -g serve
-serve -s build
+Go into the project directory:
+```
+cd living-environment-ui
```
-The last command shown above will serve your static site on the port **5000**. Like many of [serve](https://github.com/zeit/serve)’s internal settings, the port can be adjusted using the `-p` or `--port` flags.
+Install dependencies:
+```
+yarn install
+```
-Run this command to get a full list of the options available:
+Create `.env` file based on `.env.example` file.
-```sh
-serve -h
+Start development server:
+```
+yarn start
```
-# nginx server
-
-Install nginx server
+## Production
-Copy the content of the build folder to the Nginx application folder
+To build the project for production run:
+```
+yarn build
+```
+This command builds the project in `/dist` folder.
-```sh
-mkdir /var/www/app
-cp -a /path/to/living-environment-ui/build/. /var/www/app/
+To preview the production version you can run:
+```
+yarn preview
```
-Setup the nginx config
+## Testing
-```sh
-root /var/www/app
-location /api/ {
- proxy_pass http://django-rest:8000/api/;
-}
-location / {
- try_files $uri $uri/ /index.html;
-}
+This project uses Jest and React Testing Library for unit tests. To run them use command:
+```
+yarn test
```
diff --git a/jest.config.js b/jest.config.js
new file mode 100644
index 0000000..10ef5f5
--- /dev/null
+++ b/jest.config.js
@@ -0,0 +1,8 @@
+module.exports = {
+ testEnvironment: 'jsdom',
+ transform: {
+ '^.+\\.jsx?$': 'babel-jest',
+ "^.+\\.js$": "babel-jest",
+ ".+\\.(svg|css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$": "jest-transform-stub"
+ },
+};
diff --git a/package.json b/package.json
index 60cb6fd..592a81b 100644
--- a/package.json
+++ b/package.json
@@ -1,34 +1,36 @@
{
"name": "living-environment-ui",
"version": "0.1.0",
+ "overrides": {
+ "node-fetch": "^2.6.7"
+ },
"dependencies": {
"array.prototype.find": "^2.0.4",
- "axios": "^0.16.1",
- "bootstrap": "^3.3.7",
+ "axios": "^0.28.0",
+ "bootstrap": "^3.4.1",
"classnames": "^2.2.5",
"currency-formatter": "^1.2.1",
"font-awesome": "^4.7.0",
- "leaflet": "^1.0.3",
- "lodash": "^4.17.4",
- "npm": "^4.5.0",
+ "leaflet": "^1.9.4",
+ "lodash": "^4.17.21",
"number-formatter": "^1.2.0",
"point-in-polygon": "^1.0.1",
- "prop-types": "^15.5.8",
- "react": "^15.5.4",
- "react-bootstrap": "^0.31.0",
- "react-dom": "^15.5.4",
- "react-leaflet": "^1.1.6",
+ "prop-types": "^15.8.1",
+ "react": "^16.14.0",
+ "react-bootstrap": "^0.33.1",
+ "react-dom": "^16.14.0",
+ "react-leaflet": "^1.9.1",
"react-numeric-input": "^2.0.7",
- "react-redux": "^5.0.4",
+ "react-redux": "5.1.2",
"react-router": "^3.0.2",
- "react-router-bootstrap": "^0.23.1",
+ "react-router-bootstrap": "^0.23.3",
"react-router-redux": "^4.0.8",
- "react-scroll": "^1.5.2",
- "react-waypoint": "^6.0.0",
- "react-youtube": "^7.4.0",
- "redux": "^3.6.0",
+ "react-scroll": "^1.9.0",
+ "react-waypoint": "^7.3.4",
+ "react-youtube": "^7.14.0",
+ "redux": "3.7.2",
"redux-devtools-extension": "^2.13.0",
- "redux-form": "^6.6.3",
+ "redux-form": "^6.8.0",
"redux-logger": "^3.0.1",
"redux-promise-middleware": "^4.2.0",
"redux-saga": "^0.15.3",
@@ -37,22 +39,56 @@
"uuid": "^3.0.1"
},
"devDependencies": {
- "babel-cli": "^6.24.0",
- "babel-preset-react-app": "^2.2.0",
- "custom-react-scripts": "0.0.23",
- "eslint": "^3.15.0",
- "eslint-config-airbnb": "^14.1.0",
- "eslint-plugin-import": "^2.2.0",
- "eslint-plugin-jsx-a11y": "^4.0.0",
- "eslint-plugin-react": "6.10.0",
- "stylelint": "^7.10.1"
+ "@babel/core": "^7.24.0",
+ "@babel/eslint-parser": "^7.23.10",
+ "@babel/plugin-proposal-class-properties": "^7.18.6",
+ "@babel/plugin-syntax-dynamic-import": "^7.8.3",
+ "@babel/preset-env": "^7.24.0",
+ "@babel/preset-react": "^7.23.3",
+ "@testing-library/jest-dom": "^6.4.2",
+ "@testing-library/react": "^12",
+ "babel-loader": "^9.1.3",
+ "babel-plugin-syntax-dynamic-import": "^6.18.0",
+ "babel-preset-react-app": "^10.0.1",
+ "css-loader": "^6.10.0",
+ "dotenv-webpack": "^8.0.1",
+ "eslint": "^8.57.0",
+ "eslint-plugin-react": "^7.34.0",
+ "file-loader": "^6.2.0",
+ "html-webpack-plugin": "^5.6.0",
+ "jest": "^29.7.0",
+ "jest-environment-jsdom": "^29.7.0",
+ "jest-transform-stub": "^2.0.0",
+ "less": "^4.2.0",
+ "less-loader": "^12.2.0",
+ "resolve-url-loader": "^5.0.0",
+ "serve": "^14.2.1",
+ "style-loader": "^3.3.4",
+ "stylelint": "^16.2.1",
+ "url-loader": "^4.1.1",
+ "webpack": "^5.90.3",
+ "webpack-cli": "^5.1.4",
+ "webpack-dev-server": "^5.0.2"
},
"scripts": {
- "start": "node ./scripts/patch_webpack.js && react-scripts start",
- "build": "node ./scripts/patch_webpack.js && react-scripts build",
- "test": "node ./scripts/patch_webpack.js && react-scripts test --env=jsdom",
+ "start": "webpack-dev-server --config webpack.dev.js",
+ "build": "webpack --config webpack.prod.js",
+ "preview": "serve -p 8080 -s dist",
+ "test": "jest",
"eject": "react-scripts eject",
"lint": "./node_modules/eslint/bin/eslint.js src --ext .js,.jsx && stylelint \"src/**/*.less\"",
"lint-fix": "./node_modules/eslint/bin/eslint.js src --ext .js,.jsx --fix && stylelint \"src/**/*.less\" --fix"
+ },
+ "browserslist": {
+ "production": [
+ ">0.2%",
+ "not dead",
+ "not op_mini all"
+ ],
+ "development": [
+ "last 1 chrome version",
+ "last 1 firefox version",
+ "last 1 safari version"
+ ]
}
}
diff --git a/public/index.html b/public/index.html
index 6825c90..11deb75 100644
--- a/public/index.html
+++ b/public/index.html
@@ -1,11 +1,13 @@
-