## Development Instructions
### Directory Structure
```
.
├── public # Public Assets
├── src
│ ├── app # Stores/Hooks
│ ├── features
│ ├── auth # components/services related to authentication/authorization
│ ├── program # Program related components/services
│ ├── round # Round related components/services
│ ├── api.ts # Empty API service (feature APIs will inject endpoints)
│ ├── browserPatches.tsx # Browser polyfill
│ ├── index.tsx # Routes
│ ├── index.css # Global CSS
├── tsconfig.json # Typescript documentation
├── craco.json # Craco configuration
├── package.json # Package configuration
└── README.md
```
The app structure ensures all components and services related to a particular feature are kept in a subdirectory of the `features` directory.
Observe the directory structure for Authentication feature in `features/auth`
```
├── features
│ ├── auth
│ │ ├── ProtectedRoute.tsx
│ │ ├── web3Service.tsx
```
It contains the `ProtectedRoute` component and `web3Service` which extends the base API service defined in `src/api.ts` by endpoint injection.
### Adding a new route
Global routing configuration is held in `src/index.tsx`. Below is an example of a route definition
```jsx=
<Route path="/program/create" element={<CreateProgram />} />
<Route path="/program/:id" element={<ViewProgram />} />
```
A protected route i.e a routed which requires a user's wallet connection should be within the parent `ProtectedRoute` component route
```jsx=
<Route element={<ProtectedRoute />}>
<Route path="/program/create" element={<CreateProgram />} />
<Route path="/program/:id" element={<ViewProgram />} />
</Route>
```
Find more information about routing [here](https://reactrouter.com/docs/en/v6).
### Creating a new feature
This is as easy as creating a new folder in the `features` directory that holds all the resources for that particular feature.
The directory structure requires that all components and services which are related to a particular feature be kept in a subdirectory of the `features` directory.
Observe the directory structure for Authentication feature in `features/auth`
```
├── features
│ ├── auth
│ │ ├── ProtectedRoute.tsx
│ │ ├── web3Service.tsx
```
It contains the `ProtectedRoute` component and `web3Service` which extends the base API service defined in `src/api.ts` by endpoint injection.
### Defining a new API
Some features require server-side state management which involves keeping the UI in sync with an external data source e.g REST/GraphQL API service, Smart Contract etc. We use [RTK Query](https://redux-toolkit.js.org/rtk-query/overview) which is
> a powerful data fetching and caching tool. It is designed to simplify common cases for loading data in a web application, eliminating the need to hand-write data fetching & caching logic yourself
All queries and mutations inject endpoints into the base API `src/api.ts`
```typescript=
import { createApi, fakeBaseQuery } from "@reduxjs/toolkit/query/react"
// initialize an empty api service that we'll inject endpoints into later as needed
export const api = createApi({
reducerPath: "api",
baseQuery: fakeBaseQuery<string>(),
endpoints: () => ({}),
})
```
web3Service.tsx
```typescript=
export const web3Api = api.injectEndpoints({
endpoints: (builder) => ({
getWeb3: builder.query<Web3Instance, void>({
queryFn: async () => {
...
},
}),
}),
overrideExisting: false
})
export const { useGetWeb3Query } = web3Api
```
UI components access data and states thus,
```jsx=
const { data, error, refetch, isSuccess, isFetching, isLoading } = useGetWeb3Query()
```
Learn more about [Redux Toolkit](https://redux-toolkit.js.org/) and [RTK Query](https://redux-toolkit.js.org/tutorials/rtk-query).