
# Documentation

This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).

## Table of Contents
1. [Directory Structure](#directory-structure)
2. [Guidelines](#guidelines)
    1. [Create a new route](#create-a-new-route)
    2. [Reusable components](#reusable-components)
    3. [Create a new module](#create-a-new-module)
    4. [API requests](#api-requests)
    5. [Create a new reducer](#create-a-new-reducer)
    6. [Localization](#localization)
    7. [HTML code in components](#html-code-in-components)
    8. [Unit Testing](#unit-testing)
3. [Available Scripts](#available-scripts)
    1. [`npm start`](#npm-start)
    2. [`npm test`](#npm-test)
    3. [`npm run build`](#npm-run-build)
    4. [`npm run devbuild`](#npm-run-devbuild)
    5. [`npm run prodbuild`](#npm-run-prodbuild)
    6. [`npm run eject`](#npm-run-eject)
4. [Learn More](#learn-more)
    1. [Code Splitting](#code-splitting)
    2. [Analyzing the Bundle Size](#analyzing-the-bundle-size)
    3. [Making a Progressive Web App](#making-a-progressive-web-app)
    4. [Advanced Configuration](#advanced-configuration)
    5. [Deployment](#deployment)
    6. [`npm run build` fails to minify](#npm-run-build-fails-to-minify)
## Directory Structure

This section explains the folder structure inside the `src` folder.

- **api** - All api requests are declared inside this folder
- **assets** - This folder contains different assets such as scss, image etc. 
- **components** - This folder contains commonly used components like sidebar, header etc.
- **constants** - This folder contains the constant definitions that are used in other components or files.
- **hooks** - Custom hook definitions are stored in this folder.
- **layouts** - Page layout components are stored in this folder.
- **modules** - This folder contains the components that represent pages.
- **reducers** - This folder contains the Redux reducer files.
- **routes** - React route definitions are stored in this folder.
- **store** - This folder contains the Redux store files.
- **utils** - This folder contains various utility files.

## Guidelines
### Create a new route

The main routes used in the application are defined in the `routes/mainRoutes.js`. Routes defined in `routes/mainRoutes.js` file are wrapped using the `layouts/MainLayout.js` layout component which contains navbar and sidebar. All routes in `mainRoutes.js` file are wrapped using the `RequireAuth` component which verifies user authentication.

Routes inside modules can be defined in separate files and can be imported in the `index.js` file of the module folder. For example, the routes inside the reports module are handled by `routes/reportRoutes.js`. 

Modules should be lazy loaded to reduce the size of the javascript bundle which is initially loaded by the application. This helps to minimize initial loading time.

**Reference**
- https://reactrouter.com/docs/en/v6/getting-started/concepts
- https://reactjs.org/docs/code-splitting.html

### Reusable components

Reusable components such as sidebar, header etc. should be created inside the `components` folder.

### Create a new module

New modules should be created as folders inside the `modules` folder. The modules folder contains components used in routes. A module may have internal routing. Pages inside a module should be created inside the `module` folder.

### API requests

API request definitions are included in the `utils/axios.js` file. This file is used to set the base url for API requests and to set request headers such as API authentication token. 

The base url for development environment can be defined as `REACT_APP_LOCAL_URL` environment variable inside the `.env.development` file. The `REACT_APP_LOCAL_URL` variable is not needed inside the `.env.production` file. In production builds the API url will be the base url of the current page (`window.location.origin`);

API requests can be done by importing the `utils/axios.js` file and declaring a function for each API request. API request functions should be stored inside files in the `api` folder. These files can then be imported and called inside components. 
### Create a new reducer

Reducers are stored inside the `reducers` folder. Each new reducer should be imported inside the `store/index.js` file and should be added to the `reducer` object. Please refer the reference documentation given below regarding usage of reducers.

**Reference**
- https://redux-toolkit.js.org/tutorials/quick-start
- https://redux-toolkit.js.org/usage/immer-reducers#immer-usage-patterns

### Localization

Localization is done using the package [react-i18next](https://react.i18next.com/guides/quick-start). Localization settings are defined inside the `utils/i18n.js` file. 

Language definitions using `react-i18next` consists of mainly two parts - a language identifier and a namespace. In the `assets/locales/` folder the language definitions are stored in files with names in the format `{language}_{namespace}.json`. For example, `assets/locales/en_default.json`.

The localization set up is defined to work in the following way. First, a request to the backend is done to get the language definition json data. The API request will contain the language and namespace in its API url. (eg: `https://dev.mykademy.com/locales/fr_default.json`) If this request fails then the language definitions given in the `assets/locales/` folder will be used as fallback.

Language definitions can be used in function components using the `useTranslation` hook provided by the `react-i18next` library (See `components/NavUserProfileDropDown.js` for example). In class componets this can be accomplished using Higher Order Components (HOC).

**Reference**
- https://react.i18next.com/guides/quick-start

### HTML code in components

It is recommened to convert HTML to JSX using an online tool or editor plugin while adding bulk HTML code in React components.

### Unit Testing

Unit testing can be done using the [react testing library](https://testing-library.com/docs/react-testing-library/intro/). It is recommended to put the test files (or `__tests__` folders) next to the code they are testing so that relative imports appear shorter.

## Available Scripts

In the project directory, you can run:

### `npm start`

Runs the app in the development mode.\
Open [http://localhost:3000](http://localhost:3000) to view it in your browser.

The page will reload when you make changes.\
You may also see any lint errors in the console.

### `npm test`

Launches the test runner in the interactive watch mode.\
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.

### `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!

See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.

### `npm run devbuild`

Builds the app for production to the `build_<timestamp>` folder.\
It runs the `build.sh` script file and generates a build with public url pointing to the development cloudfront url.

The `build.sh` should have execution permission to run this script. Execution permission can be set by running `chmod +x build.sh`.

### `npm run prodbuild`

Builds the app for production to the `build_<timestamp>` folder.\
It runs the `build.sh` script file and generates a build with public url pointing to the production cloudfront url.

The `build.sh` should have execution permission to run this script. Execution permission can be set by running `chmod +x build.sh`.

### `npm run eject`

**Note: this is a one-way operation. Once you `eject`, you can't go back!**

If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.

Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.

You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.

## Learn More

You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).

To learn React, check out the [React documentation](https://reactjs.org/).

### Code Splitting

This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)

### Analyzing the Bundle Size

This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)

### Making a Progressive Web App

This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)

### Advanced Configuration

This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)

### Deployment

This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)

### `npm run build` fails to minify

This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
