To share the knowledge of backoffice web for team members.

(blue star) Base information

General overview & how to run: Back-office front-end (BOFE)

Project repo: https://github.com/SafiBank/SaFiMono/tree/main/app-bo

Technologies & best practices: Back-office FE

  1. React - Use hooks https://reactjs.org/docs/hooks-intro.html (not HOCs). This is a document of Hooks vs HOCs https://devcore.io/en/react/hocs-vs-hooks-what-to-use-and-why/. Both two patterns are good choices, but the author thinks Hook is simple.

  2. Typescript - type vs interface. The article https://blog.logrocket.com/types-vs-interfaces-in-typescript/ explains both of them. In fact, we can use them together according to different situations.

Interface work better with objects and method objects, and types are better to work with functions, complex types, etc. I think BOFE web’s code style is tended functions pattern.

(blue star) Project structure

This document https://safibank.atlassian.net/wiki/spaces/ITArch/pages/39551052/Back-office+FE#Project-structure provides an overview of this project. More details below.

public
scripts
src
├╴clients
├╴components
├╴config
├╴hooks
├╴icons
├╴routes
| ├╴CustomerSearch
| | ├╴CustomerSearch.styles.ts
| | ├╴CustomerSearch.tsx
| | ├╴CustomerSearchResult.tsx
| | ├╴index.tsx
| | └╴utils.ts
| └╴...
├╴pages
├╴types
| ├╴apis-autogenerated
| ├╴customer.ts
| └╴...
├╴utils
| ├╴App.tsx
| ├╴index.tsx
| └╴...
├╴__tests__
└╴mocks
  • Firstly, let’s know the difference between .js .jsx .ts .tsx .

type

description

.js

This is a plain JavaScript.

.jsx

https://reactjs.org/docs/introducing-jsx.html a syntax extension to JavaScript

.ts

https://www.typescriptlang.org/

.tsx

TypeScript with the JSX language extension

  • Description of the action of each part of the project.

path

description

public/index.html

This is the entry point.

<div id="root"></div>

src/index.tsx

calls ReactDOM.render(), which is the root React component.

app-bo code: create root

And render <App/>, so link to App.tsx

app-bo code: define app

src/App.tsx

Define app element, which contains several elements.

QueryClientProvider : connect and provide a QueryClient to your application.

ThemeProvider : If you wish to customize the theme, you need to use the ThemeProvider component in order to inject a theme into your application.

CssBaseline : The CssBaseline component helps to kickstart an elegant, consistent, and simple baseline to build upon.

BrowserRouter : A <Router> that uses the HTML5 history API (pushState, replaceState and the popstate event) to keep your UI in sync with the URL.

SecurityWrapper : okta security auth.

AppRoutes : This is defined in App.tsx. Return a set of routers .

picture 1

This code block shows lots of Route elements. And Layout controls whether you redirect to the Login page.

So Layout is very important to decide which page to display.

  • How Layout works

The important part of Layout is useEffecthttps://reactjs.org/docs/hooks-effect.html . The function useEffect will be called when first render and after every update.

If you have not login with okta, the web will navigate ( navigate(`${LOGIN_ROUTE}?${query}`) and export const LOGIN_ROUTE = '/login'`).

Therefore, you can see Layout of how to control which Route can display.

When not permitted, web will not show CUSTOMER SEARCH page.

Layout also controls the AppBar and Toolbar , so it plays an important role in the distribution of the layout components of the page.

There are some comments in the useEffect .

// TODO investigate why this gets sometimes called on the /login too

// When not permitted, redirect to home (we may add some "access denied" page later)

Maybe some code here needs to be optimized.

  • Explain how UI elements on the website are related to the code of this project.

When you log in Back office website (https://bofe.apps.brave.safibank.online/) and login in, you can see.

You can get more information from the folder routes ->CustomerSearch and think the code associated with the UI component is in the routes folder.

This part is related to app-bo code:

When you want to find the front-end code related to a module on a web page, first go to the routes folder to fetch it.

Explain in more detail about the part of Search customer.

On the left of picture 6 is white SearchBox , which contains five search options(phone, email, etc.), and FormContainer which contains a CustomButton. You can see the relationship between UI elements and code.

  • Deeper, how to display five options. Find the definition of Options.

It uses useMemo https://reactjs.org/docs/hooks-reference.html#usememo . useMemo will only recompute the memoized value when one of the dependencies has changed. It means [searchBy, reset, t] are changed, which will lead to re-computing the memoized value.

Variable searchBy is defined from the code:

const [searchBy, setSearchBy] = useState<SearchBy>('phone')

You can see useState function from react https://reactjs.org/docs/hooks-reference.html#usestate . Returns a stateful value, and a function to update it.

And Generics<SearchBy> is limit the input type. It is defined in src/routes/CustomerSearch/utils.ts .

export type SearchBy = 'id' | 'phone' | 'email' | 'profile' | 'account'

That limit the type value of SearchBy . So variable searchBy get initial value is 'phone'. You see the searchOptions, foreach the array to compare the element and searchBy value, if they’re equal then the option will be active as in picture 8.

And the definition of searchOption.

type SearchOption = {
  value: SearchBy
  labelKey: CustomerSearchI18nKey
  icon: CustomIcon
}
  • Field input element

Input the phone number, there are two inputs(country code + phone number). They are wrapped with a Grid(red box).

You can find components in the code.

Because of searchBy is 'phone' it will iterate two elements to create two Grids. You will see two elements in the 'phone' property.

FormInputField is an input box. And there are default values, rules(pattern RegExp) Input properties(input icon), etc.

A common request has an important code.

It returns a useQuery, which can invoke a function to send a request. On level up, there is the code.

The useCustomerSearch is invoked in

Send a request in

Now, let’s input the phone number and click the search button. You’ll see the request URL (https://backoffice-manager.apps.brave.safibank.online/customer-proxy/admin/customers/search?countryCode=63&phoneNumber=1231231232).

  • To see the back-end code

The request path contains customer-proxy/admin/customers/search , so find the controller and then locate a specific function. You can see there are two query parameters in URL, they are countryCode and phoneNumber. The parameters of the search function use the annotation @QueryValue .

Annotation

Description

Example

@QueryValue

Binds from a request query parameter

@QueryValue String myParam

val bankUserDto = iamDefaultApiClient.getUser(bankUser.uid)
userAuthorizationService.verifyUserHasPermission(bankUserDto, UserPermission.CUSTOMER_PROFILE_VIEW)

This code is to get bank user info and verify the user. If no permission, the request will be rejected.

customerProxyService.validateCustomerSearchFilter It is search validation, invalid there is throw CustomerSearchBadRequestException .

Now let’s see the code customerManagerAdminApiClient.search .

customerManagerAdminApiClient is customer-manager client, the function search is in https://github.com/SafiBank/SaFiMono/blob/11c1cd4e0447e0792305b2e32c93e443a9d7de99/services/customer-manager/src/main/kotlin/ph/safibank/customermanager/controller/customer/CustomerAdminV1Controller.kt#L74.

Use swagger to generate an open API to send a request to another microservice.

The main search function is a red box.

The function uses a repository object to call findAll function with a search filter and fetch the result to return a page object.

The final result is returned to the front end.

  • Conclusion

This page introduces Back Office front-end structure and leading technologies. Write the example website Search customer sending a request to back end backoffice-manager, also this page introduces back office controller, search function invoked process and finally locate to the database query. This page is only the guideline and overviews the process of SaFiBank front-end to back-end. Future documents will describe each module in more detail.

Related to

https://reactjs.org/docs/hooks-effect.html