# FcrUIScene SDK (/en/realtime-media/flexible-classroom/build/customize-the-ui-and-plugins/customize-ui-scene-sdk)

> For AI agents: see the complete documentation index at [llms.txt](/llms.txt).

FcrUIScene SDK is supported only on the Web platform.

## Introduction to UI components

The UI components in Flexible Classroom can be divided into three types: function components, business components, and scenario components.

### Function components

Function components are the most basic UI components in Flexible Classroom and are not bound to any business logic. A function component maintains the internal state and logic of a function, such as `Button`, `Modal`, `Select`, or `Tree`.

Functional components are located in `packages/fcr-ui-kit/src/components`. The technologies used are `react`, `ts`, and `storybook`. Each functional component folder contains the following files:

* `.tsx`: Implements the functionality of the component.
* `.css`: Implements the style of the component.
* `.stories.tsx`: Enables previewing and debugging the component in Storybook. Developers can run the project through the `yarn dev:ui-kit:scene` or `npm run dev:ui-kit:scene` command and preview the function components in Storybook.

The following table lists the function components used in Flexible Classroom:

| Folder          | Function components                                                                             |
| :-------------- | :---------------------------------------------------------------------------------------------- |
| `/avatar`       | The username avatar.                                                                            |
| `/button`       | The button component.                                                                           |
| `/checkbox`     | The checkbox component.                                                                         |
| `/dialog`       | The dialog box.                                                                                 |
| `/dropdown`     | The dropdown selection box.                                                                     |
| `/input`        | The input box.                                                                                  |
| `/input-number` | The number input box.                                                                           |
| `/pagination`   | The pagination component is used for displaying long lists. It loads only one page of the data. |
| `/popover`      | The pop-up box is used to display more content when the mouse clicks or moves in.               |
| `/progress`     | The progress bar.                                                                               |
| `/radio`        | The radio buttons allow users to select one option from a set.                                  |
| `/slider`       | The component to drag the progress bar.                                                         |
| `/sound-player` | The component for playing audio files.                                                          |
| `/svg-img`      | SVG images.                                                                                     |
| `/table`        | The table displays rows of data.                                                                |
| `/tabs`         | The component for switching tabs.                                                               |
| `/textarea`     | Multi-line text input box.                                                                      |
| `/toast`        | The component for global prompts.                                                               |
| `/tooltip`      | The pop-up box for simple text tips.                                                            |
| `/volume`       | The component for displaying the volume.                                                        |

### Business components

Business components are the UI components bound to business logic in Flexible Classroom. Most of the business components are composed of multiple function components. Depending on the observable objects and functions from the UI Store, the UI of business components can be automatically changed as the data updates. Taking the hand-raising feature as an example, this business component provides a button for users to raise their hands and ask for permission to speak, and then displays the list of users who have raised their hands.

![Flexible Classroom hand-raising business component](https://assets-docs.agora.io/images/flexible-classroom/custom-ui-component.png)

You can find the business components in `packages/fcr-ui-scene/src/containers`.

The following table lists the business components used in Flexible Classroom:

**Education Scene**

| Folder            | Business components                                                                                                                                                                     |
| :---------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `/action-bar`     | The bottom function button bar.                                                                                                                                                         |
| `/breakout-room`  | The Group discussion function.                                                                                                                                                          |
| `/cloud`          | The cloud drive component implements businesses such as uploading or deleting files.                                                                                                    |
| `/device-pretest` | The device pre-check component implements device pre-check business before entering the classroom, including functions such as obtaining device list information and switching devices. |
| `/device-setting` | The component for device settings, such as displaying the list of cameras, microphones, and speakers.                                                                                   |
| `/dialog`         | Pop-up windows during the class.                                                                                                                                                        |
| `/layout`         | The scene UI layout.                                                                                                                                                                    |
| `/loading`        | The loading component and the loading handling logic.                                                                                                                                   |
| `/participants`   | The roster component implements services such as viewing student information, processing platform requests, and issuing rewards.                                                        |
| `/status-bar`     | The top status bar.                                                                                                                                                                     |
| `/stream-window`  | The window container component responsible for rendering video and video toolbar.                                                                                                       |
| `/toast`          | The toast prompt component.                                                                                                                                                             |
| `/widget`         | The Widget container component that is responsible for handling logic such as rendering and movement trajectory synchronization of custom Widgets.                                      |

### Scenario components

A scenario component is composed of multiple business components. Scenario components are located in `packages/fcr-ui-scene/src/scenarios`. If you want to change the layout of a certain scene, just find the corresponding scenario component and modify it.

| Folder       | Scenario components     |
| :----------- | :---------------------- |
| `/classroom` | General education scene |

### Relationship between the three types of UI components

The following figure illustrates the relationship between the three types of UI components:

![Relationship between Flexible Classroom function, business, and scenario components](https://web-cdn.agora.io/docs-files/1652870469390)

## Custom functional components

### Add a functional component

To add a new functional component and use it in Flexible Classroom, follow these steps. The following is an example of a Flexible Classroom education scenario:

1. Create a folder in the `packages/fcr-ui-kit/src/components` directory for the new functional component that you want to add. This folder should contain the following three files:
   * `index.tsx`: Implements the functionality of the UI component.
   * `index.css`: Implements the style of the UI component.
   * `index.stories.tsx`: Enables previewing and debugging the UI component in Storybook.
2. After adding the functional component, export this component in `packages/fcr-ui-kit/src/components/index.ts`. Then you can import this component into your project.

The following example shows how to add a functional component `agora-demo`:

1. A new folder is created under the `packages/agora-classroom-sdk/src/ui-kit/components` directory containing the corresponding files:

   ![AgoraDemo component files in the source tree](https://web-cdn.agora.io/docs-files/1649913888493)

   ```tsx
    // index.css
       .agora-demo {
           color: red
       }
       // index.tsx
       import React from 'react'
       import './index.css'

       export const AgoraDemo = () => {
         return (
           <div className="agora-demo">AgoraDemo</div>
         )
       }
       // index.stories.tsx
       import React from 'react';
       import { Meta } from '@storybook/react';
       import { AgoraDemo } from './index';

       const meta: Meta = {
           title: 'Components/AgoraDemo',
           component: AgoraDemo,
       };
       export default meta;

       export const Docs = () => (
           <AgoraDemo />
       )
   ```

You can see this function component in Storybook, as follows:

![AgoraDemo component preview in Storybook](https://assets-docs.agora.io/images/flexible-classroom/agora-demo.png)

### Edit an existing functional component

If you want to modify the function and style of an existing functional component, just find the component folder and edit the code to suit your needs. The following examples are provided for your reference.

#### Change the placeholder color of the input component

To change the color of the placeholder text in the input component, edit the `packages/fcr-ui-kit/src/components/input/index.css` file as follows:

**Before**

```css
.fcr-input input::placeholder {
  @apply fcr-text-3;
```

![Input placeholder style before customization](https://assets-docs.agora.io/images/flexible-classroom/no-highlight.png)

**After**

```css
.fcr-input input::placeholder {
    color: skyblue;
    font-size: 14px;
}
```

![Input placeholder style after customization](https://assets-docs.agora.io/images/flexible-classroom/highlight.png)

## Customize business components

### Add a business component

To add a new business component and use it in Flexible Classroom, create a folder in `packages/fcr-ui-scene/src/containers`. The folder should contain the following files:

* `index.tsx`: Combines functional components and implements the business logic.
* `index.css`: Implements the style of the business component.

After adding the corresponding folder, you can directly import this business component and run the project to see how it looks in Flexible Classroom.

The following example shows how to add a business component that displays the class and network status:

1. Create a new folder `agora-demo` under `packages/fcr-ui-scene/src/containers`, containing the `index.tsx` and `index.css` files.

   ```tsx
   // index.css
   .agora-demo {
       width: 50%;
       height: 50%;
       position: fixed;
       top: 0;
       right: 0;
       bottom: 0;
       left: 0;
       margin: auto;
       border: 1px solid black;
       display: flex;
       flex-direction: column;
       justify-content: center;
       align-items: center;
       z-index: 99999999;
       background: #fff;
   }
   .agora-demo-title {
       color: red;
   }
   // index.tsx
   import React from 'react';
   import { observer } from 'mobx-react';
   import './index.css';
   import { useStore } from '@ui-scene/utils/hooks/use-store';

   export default observer(function AgoraDemo() {
   const { statusBarUIStore } = useStore();
   return (
       <div className="agora-demo">
       <h1 className="agora-demo-title">This is our new business component</h1>
       <h2>This component is used to display the network status and class status</h2>
       <div>
           Network status: {statusBarUIStore.networkQuality} Network Delay: {statusBarUIStore.delay} Packet loss：
           {statusBarUIStore.packetLoss}
       </div>
       <div>Class status: {statusBarUIStore.classStatusText}</div>
       </div>
   );
   });
   ```

2. Import this component in the interactive small class scene `packages/fcr-ui-scene/src/scenarios/classroom.tsx` file:

   ```tsx
   ...
   import AgoraDemo from '@ui-scene/containers/agora-demo';

       const {
           join,
           layoutUIStore: { classroomViewportClassName },
       } = useStore();
       useEffect(() => {
           join();
       }, []);
       return (
           <div className={classroomViewportClassName}>
               ...
               <AgoraDemo />
           </div>
       );
   });
   ```

The effect of this business component in Flexible Classroom is as follows:

![AgoraDemo business component displayed in Flexible Classroom](https://web-cdn.agora.io/docs-files/1652870671265)

## Change the UI stores

A business component is composed of multiple functional components and depends on UI stores. If you add or modify a business structure, you need to modify the UI Store. This section introduces how to edit the UI stores.

UI stores are located in `packages/fcr-ui-scene/src/uistores`:

| Folder               | Description                                       |
| :------------------- | :------------------------------------------------ |
| `/cloud`             | The UI Store common to all scenarios.             |
| `/subscription`      | The UI Store customized for small classes.        |
| `/action-bar`        | The UI Store customized for large classes.        |
| `/breakout`          | The UI Store customized for H5 large classes.     |
| `/device-setting`    | The UI Store customized for one-on-one scenarios. |
| `/gallery-view`      | The UI Store customized for large classes.        |
| `/layout`            | The UI Store customized for H5 large classes.     |
| `/notification`      | The Store customized for one-on-one scenarios.    |
| `/participants`      | The UI Store customized for large classes.        |
| `/presentation-view` | The UI Store customized for H5 large classes.     |
| `/status-bar`        | The UI Store customized for one-on-one scenarios. |
| `/stream`            | The UI Store customized for one-on-one scenarios. |
| `/widget`            | The UI Store customized for one-on-one scenarios. |
| `/base`              | The base class for all UI Stores.                 |

All UI Stores need to integrate the `EduUIStoreBase` class in `/base`. This class provides the initialization method `onInstall` and the destruction method `onDestroy`, which are called when the classroom is created and destroyed, respectively.

If you need to modify or expand the functional logic of a business component, you can find the UI Store corresponding to the component and modify it according to the above functional description.

## Monitor classroom events

The SDK provides `EduEventCenter` with the ability to monitor certain events that occur in the classroom. The event monitoring code is generally written in the UI Store `onInstall` method. The `onDestory` event monitoring is canceled in the method.

For example, when receiving a reward prompt, displaying a prompt through Toast can be achieved through the following code:

```tsx
onInstall(): void {
    ...
    // Add a classroom event handler
    EduEventCenter.shared.onClassroomEvents(this._handleClassroomEvent);
}
onDestroy(): void {
    ...
    // Remove a classroom event handler
    EduEventCenter.shared.offClassroomEvents(this._handleClassroomEvent);
}
```

Add an event handling method for `_handleClassroomEvent` to `NotiticationUIStore`:

```tsx
// Introduce a decorator and bind the This pointer
import { bound } from 'agora-rte-sdk';

...
@bound
private _handleClassroomEvent(event: AgoraEduClassroomEvent, param: any) {
    if (
    event === AgoraEduClassroomEvent.RewardReceived
    ) {
    // An array of recipients and quantities
    const users: { userUuid: string; userName: string }[] = param;
    const userNames = users.map((user) => user.userName);
        // Use ToastApi to pop up prompt box
        ToastApi.open({
        toastProps: {
            type: 'info',
            content: "congratulate" + userNames.join(',') + "Earn rewards",
        },
        });
    }
}
```

`EduEventCenter` provides the following classroom events:

| Event type                       | Description                                               |
| :------------------------------- | :-------------------------------------------------------- |
| `Ready`                          | `1` Entered the classroom successfully                    |
| `Destroyed`                      | `2`  The classroom has been destroyed.                    |
| `FailedToJoin`                   | `3` Failed to enter the classroom.                        |
| `KickOut`                        | `101` Being kicked out of the room.                       |
| `TeacherTurnOnMyMic`             | `102` Audio streaming permission is enabled.              |
| `TeacherTurnOffMyMic`            | `103` Audio streaming permission is turned off.           |
| `UserAcceptToStage`              | `106`  Get on the podium.                                 |
| `UserLeaveStage`                 | `107` Leave the podium.                                   |
| `RewardReceived`                 | `108` Reward received.                                    |
| `TeacherTurnOnMyCam`             | `109` The video streaming permission is enabled.          |
| `TeacherTurnOffMyCam`            | `110` The video streaming permission has been turned off. |
| `CurrentCamUnplugged`            | `111` The current camera device is unplugged              |
| `CurrentMicUnplugged`            | `112` The current microphone device is unplugged.         |
| `CurrentSpeakerUnplugged`        | `113` The current speaker is unplugged.                   |
| `CaptureScreenPermissionDenied	` | `114` No screen capture permission.                       |
| `BatchRewardReceived`            | `117` Receive bulk rewards.                               |
| `InvitedToGroup`                 | `118` Receive invitation to join group.                   |
| `MoveToOtherGroup`               | `119`  Moved to other groups.                             |
| `JoinSubRoom`                    | `120` Join a group.                                       |
| `LeaveSubRoom`                   | `121` Leave the group.                                    |
| `AcceptedToGroup`                | `122`  The user accepts to join the group.                |
| `UserJoinGroup`                  | `123` Other users join the group.                         |
| `UserLeaveGroup`                 | `124` Other users leave the group.                        |
| `RejectedToGroup`                | `125`  The user refuses to join the group.                |
| `RTCStateChanged`                | `201` RTC connection status change.                       |
| `ClassStateChanged`              | `202` Classroom status changes.                           |

## Internationalization

Flexible Classroom has two built-in languages: English `en` and Chinese `zh`. If you need to support other languages, such as Spanish, you can do so by modifying the code:

1. Modify the `packages/fcr-ui-scene/src/type.ts` file to add Spanish to the Language type:

   ```tsx
   // Add Spanish es
   export type Language = 'en' | 'zh' | 'es';
   ```

2. Create a `esAr.ts` language pack file in `packages/fcr-ui-scene/src/resources/translations` with the following content:

   ```tsx
   // You can copy the content from the enUs.ts file here and modify the corresponding language text

       // Language pack Key: Value
       ...
   }
   ```

3. Load the language pack corresponding to the language when the launch method is called:

   ```tsx
   // Introduce language pack
   import { esAr } from './resources/translations/esAr.ts';
   ...

   static launch(dom: HTMLElement, launchOptions: LaunchOptions) {
       ...
       // Load the language pack corresponding to es
       Promise.all([addResourceBundle('zh', zhCn), addResourceBundle('en', enUs), addResourceBundle('es', esAr)])
       ...
   }
   ```

4. Pass in the corresponding language when calling the launch method:

   ```tsx
   FcrUIScene.launch(document.querySelector('#root'), {
       ...
       language: 'es',
       ...
   });
   ```
