# Classroom and Proctor SDK (/en/realtime-media/flexible-classroom/build/customize-the-ui-and-plugins/customize-classroom/electron)

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

This page explains the way UI components work in Classroom and Proctor SDK.

    ## Introduction to UI components [#introduction-to-ui-components-1]

    <CalloutContainer type="info">
      <CalloutDescription>
        The cloud classroom scene is included in `FcrUIScene`. If you need to integrate the cloud classroom scene UI, please refer to [FcrUIScene SDK](/en/realtime-media/flexible-classroom/build/customize-the-ui-and-plugins/customize-ui-scene-sdk).
      </CalloutDescription>
    </CalloutContainer>

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

    ### Function components [#function-components-1]

    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`.

    The Agora Classroom Education Scenario functional components are located in `packages/agora-classroom-sdk/src/ui-kit`, and the Agora Classroom Proctor Scenario components are in the `packages/agora-proctor-sdk/src/ui-kit` folder. 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:classroom` or `npm run dev:ui-kit:classroom` command and preview the function components in Storybook.

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

    | Folder          | Function components                                                                                                                                                          |
    | :-------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `/button`       | The button component.                                                                                                                                                        |
    | `/card`         | The card component.                                                                                                                                                          |
    | `/checkbox`     | The checkbox component.                                                                                                                                                      |
    | `/input`        | The input box.                                                                                                                                                               |
    | `/layout`       | The layout component helps with the overall layout of a web page.                                                                                                            |
    | `/loading`      | The loading component provides the state of joining a classroom or uploading a file.                                                                                         |
    | `/modal`        | The modal dialog box is used for user interaction that does not interrupt the current operation.                                                                             |
    | `/pagination`   | The pagination component is used for displaying long lists. It loads only one page of the data.                                                                              |
    | `/placeholder`  | The placeholder for videos or files.                                                                                                                                         |
    | `/popover`      | The pop-up box is used to display more content when the mouse clicks or moves in.                                                                                            |
    | `/radio`        | The radio buttons allow users to select one option from a set.                                                                                                               |
    | `/root-box`     | The root container wraps page elements.                                                                                                                                      |
    | `/roster`       | The roster is used to display the student list and allows teachers to invite students to address the class, send rewards to students, or kick students out of the classroom. |
    | `/select`       | The drop-down menu.                                                                                                                                                          |
    | `/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.                                                                                                                                            |
    | `/toast`        | The component for global prompts.                                                                                                                                            |
    | `/toolbar`      | The toolbar displays the teaching tools of teachers and students.                                                                                                            |
    | `/tooltip`      | The pop-up box for simple text tips.                                                                                                                                         |
    | `/tree`         | The tree component is used to show tree-structured data.                                                                                                                     |
    | `/volume`       | The component for displaying the volume.                                                                                                                                     |

    ### Business components [#business-components-1]

    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://web-cdn.agora.io/docs-files/1652870415192)

    You can find the business components in `packages/agora-classroom-sdk/src/ui-kit/capabilities/containers`.

    The business components for the Agora Classroom Education Scenario are located in `packages/agora-classroom-sdk/src/infra/capabilities/containers`, and the business components for Agora Classroom Proctor Scenario are in `packages/agora-proctor-sdk/src/infra/capabilities/containers`

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

    **Education Scene**

    | Folder               | Business components                                                                                                                                         |
    | :------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `/aside`             | The video and chat box containers on the right side of a large and small classroom.                                                                         |
    | `/award`             | The reward component that implements the logic of teachers issuing rewards to students. When students receive rewards, they are displayed in the video box. |
    | `/cloud-driver`      | The cloud drive component implements businesses such as uploading or deleting files.                                                                        |
    | `/device-setting`    | The component for device settings, such as displaying the list of cameras, microphones, and speakers.                                                       |
    | `/dialog`            | Pop-up windows during the class.                                                                                                                            |
    | `/hand-up`           | The component for the hand-raising feature.                                                                                                                 |
    | `/loading`           | The loading component.                                                                                                                                      |
    | `/nav`               | The navigation component for businesses such as displaying the network status and class status.                                                             |
    | `/pretest`           | The component for the device test before joining the classroom. Includes functions such as obtaining device list information and switching devices.         |
    | `/root-box`          | The root container. Used to maintain the 16:9 aspect ratio of the class, with areas outside the ratio showing a black background.                           |
    | `/roster`            | The roster component implements businesses such as checking the student information, processing requests for going onto the stage, and issuing rewards.     |
    | `/scene-switch`      | The component for switching between scenes.                                                                                                                 |
    | `/scenes-controller` | The component for controlling whiteboard scenes, such as adding or deleting whiteboard pages.                                                               |
    | `/screen-share`      | The component for the screen sharing feature. Responsible for rendering the shared screen and the screen sharing control bar.                               |
    | `/stream`            | The component for rendering audio and video streams. Handles audio and video rendering of each class, a small class carousel component.                     |
    | `/stream-window`     | The draggable window container component. Handles the dragging and arrangement logic of the video window.                                                   |
    | `/toast`             | Toast prompt component.                                                                                                                                     |
    | `/toolbar`           | The toolbar for the teaching tools of the teachers and students.                                                                                            |
    | `/widget`            | The Widget container component that is responsible for handling logic such as rendering and movement trajectory synchronization of custom Widgets.          |
    | `/camera-preview`    | The local video screen displayed in the lower right corner when the video wall function is turned on.                                                       |

    **Proctor Scene**

    | Folder      | Business components                                                                                                                                 |
    | :---------- | :-------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `/dialog`   | Pop-up windows during the class.                                                                                                                    |
    | `/pretest`  | The component for the device test before joining the classroom. Includes functions such as obtaining device list information and switching devices. |
    | `/root-box` | The root container.                                                                                                                                 |
    | `/stream`   | The component for rendering audio and video streams.                                                                                                |
    | `/toast`    | Toast prompt component.                                                                                                                             |
    | `/widget`   | The Widget component handles logic such as widget rendering and loading.                                                                            |

    ### Scenario components [#scenario-components-1]

    A scenario components is composed of multiple business components. Flexible classroom supports preset scenarios. Scenario components are located in `packages/agora-classroom-sdk/src/infra/capabilities/scenarios` for the Agora Classroom Education Scenario and in `packages/agora-proctor-sdk/src/infra/capabilities/scenarios` for the Agora Classroom Proctor Scenario. If you want to change the layout of a certain scene, just find the corresponding scene component and modify it.

    **Education Scene**

    | Folder              | Scenario components                                                        |
    | :------------------ | :------------------------------------------------------------------------- |
    | `/1v1`              | One-to-one interactive teaching scene                                      |
    | `/big-class`        | Interactive live broadcast of large class scene                            |
    | `/big-class-mobile` | Interactive live broadcast, large class scene for web and mobile terminals |
    | `/mid-class`        | Online interactive small class scene                                       |

    **Proctor Scene**

    | Folder      | Scenario components        |
    | :---------- | :------------------------- |
    | `proctor`   | Proctor teacher scene      |
    | `/examinee` | Invigilation student scene |

    ### Relationship between the three types of UI components [#relationship-between-the-three-types-of-ui-components-1]

    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 [#custom-functional-components-1]

    ### Add a functional component [#add-a-functional-component-1]

    To add a new functional component and use it in Flexible Classroom, follow these steps:

    1. Create a folder in the `packages/agora-classroom-sdk/src/ui-kit/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/agora-classroom-sdk/src/ui-kit/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. Create a new folder `packages/agora-classroom-sdk/src/ui-kit/components` under the directory, containing the corresponding files `.agora-demo`, `index.tsx`, `index.css`, and `index.stories.tsx`:

       ![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 />
       )
       ```

    2. Add `export * from './agora-demo';` to `packages/agora-classroom-sdk/src/ui-kit/components/index.ts`. You can see this function component in Storybook, as follows:

       ![Storybook component preview](https://web-cdn.agora.io/docs-files/1649914019254)

    ### Edit an existing functional component [#edit-an-existing-functional-component-1]

    If you want to modify the function and style of an existing functional component, just find 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 [#change-the-placeholder-color-of-the-input-component-1]

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

    **Before**

    ```css
    .fcr-input-wrapper input::-webkit-input-placeholder {
      color: #999;
    }
    ```

    **After**

    ```css
    .fcr-input-wrapper input::-webkit-input-placeholder {
      color: #ff6600;
    }
    ```

    ## Customize business components [#customize-business-components-1]

    ### Add a business component [#add-a-business-component-1]

    To add a new business component and use it in Flexible Classroom, create a folder in `packages/agora-classroom-sdk/src/infra/capabilities/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 business component, 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:

    ```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;
    }
    .agora-demo-title {
      color: red;
    }

    // index.tsx
    import React from 'react';
    import { observer } from 'mobx-react';
    import { useStore } from '@classroom/infra/hooks/ui-store';
    import './index.css';

    export default observer(function AgoraDemo() {
      const { navigationBarUIStore } = useStore();
      const { classStatusText, networkQualityLabel, delay, packetLoss } = navigationBarUIStore;
      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: {networkQualityLabel} Network Delay: {delay} Packet Loss Rate: {packetLoss}
          </div>
          <div>Class Status: {classStatusText}</div>
        </div>
      );
    });

    // packages/agora-classroom-sdk/src/infra/capabilities/scenarios/mid-class/index.tsx
    // Introduce this component in the small class scene
    import classnames from 'classnames';
    import { Layout } from '@classroom/ui-kit/components/layout';
    import { DialogContainer } from '@classroom/infra/capabilities/containers/dialog';
    import { HandsUpContainer } from '@classroom/infra/capabilities/containers/hand-up';
    import { LoadingContainer } from '@classroom/infra/capabilities/containers/loading';
    import { NavigationBar } from '@classroom/infra/capabilities/containers/nav';
    import { FixedAspectRatioRootBox } from '@classroom/infra/capabilities/containers/root-box';
    import { SceneSwitch } from '@classroom/infra/capabilities/containers/scene-switch';
    import { RoomMidStreamsContainer } from '@classroom/infra/capabilities/containers/stream/room-mid-player';
    import { ToastContainer } from '@classroom/infra/capabilities/containers/toast';
    import { Award } from '@classroom/infra/capabilities/containers/award';
    import Room from '../room';
    import { useStore } from '@classroom/infra/hooks/ui-store';
    import { Float } from '@classroom/ui-kit';
    import { RemoteControlContainer } from '@classroom/infra/capabilities/containers/remote-control';
    import { ScenesController } from '@classroom/infra/capabilities/containers/scenes-controller';
    import { ScreenShareContainer } from '@classroom/infra/capabilities/containers/screen-share';
    import { WhiteboardToolbar } from '@classroom/infra/capabilities/containers/toolbar';
    import { WidgetContainer } from '@classroom/infra/capabilities/containers/widget';
    import { Chat, Watermark, Whiteboard } from '@classroom/infra/capabilities/containers/widget/slots';
    import { StreamWindowsContainer } from '@classroom/infra/capabilities/containers/stream-windows-container';
    import { RemoteControlToolbar } from '@classroom/infra/capabilities/containers/remote-control/toolbar';
    import AgoraDemo from '@classroom/infra/capabilities/containers/agora-demo';

    export const MidClassScenario = () => {
      // Scene layout
      const layoutCls = classnames('edu-room', 'mid-class-room');
      const { shareUIStore } = useStore();

      return (
        <Room>
          {/* Here is the new business component */}
          <AgoraDemo />
          <FixedAspectRatioRootBox trackMargin={{ top: shareUIStore.navHeight }}>
            <SceneSwitch>
              <Layout className={layoutCls} direction="col">
                <NavigationBar />
                <Layout
                  className="flex-grow items-stretch relative justify-center fcr-room-bg"
                  direction="col">
                  <RoomMidStreamsContainer />
                  <Whiteboard />
                  <ScreenShareContainer />
                  <RemoteControlContainer />
                  <StreamWindowsContainer />
                </Layout>
                <RemoteControlToolbar />
                <WhiteboardToolbar />
                <ScenesController />
                <Float bottom={15} right={10} align="flex-end" gap={2}>
                  <HandsUpContainer />
                  <Chat />
                </Float>
                <DialogContainer />
                <LoadingContainer />
              </Layout>
              <WidgetContainer />
              <ToastContainer />
              <Award />
              <Watermark />
            </SceneSwitch>
          </FixedAspectRatioRootBox>
        </Room>
      );
    };
    ```

    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)

    ### Edit an existing business component [#edit-an-existing-business-component-1]

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

    #### Display the number of cameras that are available in the device settings pop-up window [#display-the-number-of-cameras-that-are-available-in-the-device-settings-pop-up-window-1]

    Open the file `packages/agora-classroom-sdk/src/infra/capabilities/containers/pretest/pretest-video.tsx` and modify it as follows:

    ```tsx
    const VideoDeviceList = observer(() => {
      const {
        pretestUIStore: { setCameraDevice, currentCameraDeviceId, cameraDevicesList },
      } = useStore();
      const t = useI18n();
      return (
        <VideoDeviceListPanel>

          <div className="-mt-10">{`${t('device.camera')} Number of devices: ${
            cameraDevicesList.length - 1
          }`}</div>
          <Field
            label=""
            type="select"
            value={currentCameraDeviceId}
            options={cameraDevicesList.map((value) => ({
              text: value.label,
              value: value.value,
            }))}
            onChange={(value) => {
              setCameraDevice(value);
            }}
          />
        </VideoDeviceListPanel>
      );
    ```

    **Before**

    ![Device settings camera list before showing camera count](https://web-cdn.agora.io/docs-files/1652870698533)

    **After**

    ![Device settings camera list after showing camera count](https://web-cdn.agora.io/docs-files/1652870718469)

    ## Change the scenario layout [#change-the-scenario-layout-1]

    To change the layout of a scenario, just edit the code of the scenario component.

    #### Move the position of the video and chat area [#move-the-position-of-the-video-and-chat-area-1]

    The following example demonstrates how to move the position of the video and chat areas from the right side of the screen to the left. This is a cross-component adjustment. Therefore, you need to edit the parent container of these two components, which is the one-to-one interactive teaching scene container in `packages/agora-classroom-sdk/src/infra/capabilities/scenarios/1v1/index.tsx`.

    **Before**

    ```tsx
    import { useStore } from '@classroom/infra/hooks/ui-store';
    import classnames from 'classnames';
    import { Layout } from '@classroom/ui-kit/components/layout';
    import { DialogContainer } from '@classroom/infra/capabilities/containers/dialog';
    import { LoadingContainer } from '@classroom/infra/capabilities/containers/loading';
    import { NavigationBar } from '@classroom/infra/capabilities/containers/nav';
    import { FixedAspectRatioRootBox } from '@classroom/infra/capabilities/containers/root-box/fixed-aspect-ratio';
    import { Room1v1StreamsContainer } from '@classroom/infra/capabilities/containers/stream/room-1v1-player';
    import { ToastContainer } from '@classroom/infra/capabilities/containers/toast';
    import { RemoteControlContainer } from '../../containers/remote-control';
    import { SceneSwitch } from '../../containers/scene-switch';
    import { ScenesController } from '../../containers/scenes-controller';
    import { ScreenShareContainer } from '../../containers/screen-share';
    import { StreamWindowsContainer } from '../../containers/stream-window';
    import { WhiteboardToolbar } from '../../containers/toolbar';
    import { WidgetContainer } from '../../containers/widget';
    import { Chat, Watermark, Whiteboard } from '../../containers/widget/slots';
    import { OneToOneClassAside as Aside } from '@classroom/infra/capabilities/containers/aside';
    import Room from '../room';
    import { RemoteControlToolbar } from '../../containers/remote-control/toolbar';

      const layoutCls = classnames('edu-room', 'one-on-one-class-room');
      const { shareUIStore } = useStore();
      return (
        <Room>
          <FixedAspectRatioRootBox trackMargin={{ top: shareUIStore.navHeight }}>
            <SceneSwitch>
              <Layout className={layoutCls} direction="col">
                <NavigationBar />
                <Layout className="flex-grow items-stretch fcr-room-bg h-full">
                  <Layout
                    className="flex-grow items-stretch relative"
                    direction="col"
                    style={{ paddingTop: 2 }}>
                    <Whiteboard />
                    <ScreenShareContainer />
                    <WhiteboardToolbar />
                    <ScenesController />
                    <RemoteControlContainer />
                    <StreamWindowsContainer />
                    <RemoteControlToolbar />
                  </Layout>
                  <Aside>
                    <Room1v1StreamsContainer />
                    <Chat />
                  </Aside>
                </Layout>
                <DialogContainer />
                <LoadingContainer />
              </Layout>
              <WidgetContainer />
              <ToastContainer />
              <Watermark />
            </SceneSwitch>
          </FixedAspectRatioRootBox>
        </Room>
      );
    };
    ```

    ![Flexible Classroom layout before moving the video and chat area](https://web-cdn.agora.io/docs-files/1652870751521)

    **After**

    ```tsx
    import { useStore } from '@classroom/infra/hooks/ui-store';
    import classnames from 'classnames';
    import { Layout } from '@classroom/ui-kit/components/layout';
    import { DialogContainer } from '@classroom/infra/capabilities/containers/dialog';
    import { LoadingContainer } from '@classroom/infra/capabilities/containers/loading';
    import { NavigationBar } from '@classroom/infra/capabilities/containers/nav';
    import { FixedAspectRatioRootBox } from '@classroom/infra/capabilities/containers/root-box/fixed-aspect-ratio';
    import { Room1v1StreamsContainer } from '@classroom/infra/capabilities/containers/stream/room-1v1-player';
    import { ToastContainer } from '@classroom/infra/capabilities/containers/toast';
    import { RemoteControlContainer } from '../../containers/remote-control';
    import { SceneSwitch } from '../../containers/scene-switch';
    import { ScenesController } from '../../containers/scenes-controller';
    import { ScreenShareContainer } from '../../containers/screen-share';
    import { StreamWindowsContainer } from '../../containers/stream-window';
    import { WhiteboardToolbar } from '../../containers/toolbar';
    import { WidgetContainer } from '../../containers/widget';
    import { Chat, Watermark, Whiteboard } from '../../containers/widget/slots';
    import { OneToOneClassAside as Aside } from '@classroom/infra/capabilities/containers/aside';
    import Room from '../room';
    import { RemoteControlToolbar } from '../../containers/remote-control/toolbar';

      const layoutCls = classnames('edu-room', 'one-on-one-class-room');
      const { shareUIStore } = useStore();
      return (
        <Room>
          <FixedAspectRatioRootBox trackMargin={{ top: shareUIStore.navHeight }}>
            <SceneSwitch>
              <Layout className={layoutCls} direction="col">
                <NavigationBar />
                <Layout className="flex-grow items-stretch fcr-room-bg h-full">
                  /** 调整 Layout 中 Content 与 Aside 的顺序。*/
                  <Aside>
                    <Room1v1StreamsContainer />
                    <Chat />
                  </Aside>
                  <Layout
                    className="flex-grow items-stretch relative"
                    direction="col"
                    style={{ paddingTop: 2 }}>
                    <Whiteboard />
                    <ScreenShareContainer />
                    <WhiteboardToolbar />
                    <ScenesController />
                    <RemoteControlContainer />
                    <StreamWindowsContainer />
                    <RemoteControlToolbar />
                  </Layout>
                </Layout>
                <DialogContainer />
                <LoadingContainer />
              </Layout>
              <WidgetContainer />
              <ToastContainer />
              <Watermark />
            </SceneSwitch>
          </FixedAspectRatioRootBox>
        </Room>
      );
    };
    ```

    ![Flexible Classroom layout after moving the video and chat area](https://web-cdn.agora.io/docs-files/1652870760213)

    #### Add a logo [#add-a-logo-1]

    If you want to add a logo to the right `<Aside>`, you need to implement the Logo component first, and then make the following changes in the `packages/agora-classroom-sdk/src/infra/capabilities/scenarios/1v1/index.tsx` file:

    ```tsx
    ...
    <Aside>
        <Logo/>
        <Room1v1StreamsContainer />
        <ChatWidgetPC />
    </Aside>
    ...
    ```

    ## Change the UI stores [#change-the-ui-stores-1]

    A business component is composed of multiple functional components and depends on UI stores. This section introduces how to edit the UI stores.

    UI stores are located in `packages/agora-classroom-sdk/src/infra/stores`:

    | Folder         | Description                                        |
    | :------------- | :------------------------------------------------- |
    | `/common`      | The common UI store for all scenarios              |
    | `/interactive` | The UI store for the Small Classroom scenario      |
    | `/lecture`     | The UI store for the Lecture Hall scenario         |
    | `/lecture-h5`  | The UI store for the Lecture Hall scenario in H5   |
    | `/one-on-one`  | The UI store for the One-to-one Classroom scenario |

    `EduClassroomUIStore` in `/common` is the base class. You can extend this class and rewrite the UI stores for a specific scenario.

    The following example shows how to customize the UI store for the Lecture Hall scenario:

    ```typescript
    import { EduClassroomStore } from 'agora-edu-core';
    import { EduClassroomUIStore } from '../common';
    import { LectureBoardUIStore } from './board';
    import { LectureRosterUIStore } from './roster';
    import { LectureRoomStreamUIStore } from './stream';
    import { LectrueToolbarUIStore } from './toolbar';

    export class EduLectureUIStore extends EduClassroomUIStore {
      constructor(store: EduClassroomStore) {
        super(store);
        // Rewrite Stream UI Store
        this._streamUIStore = new LectureRoomStreamUIStore(store, this.shareUIStore);
        // Rewrite Roster UI Store
        this._rosterUIStore = new LectureRosterUIStore(store, this.shareUIStore);
        // Rewrite Board UI Store
        this._boardUIStore = new LectureBoardUIStore(store, this.shareUIStore);
        // Rewrite Toolbar UI Store
        this._toolbarUIStore = new LectrueToolbarUIStore(store, this.shareUIStore);
      }

      get streamUIStore() {
        return this._streamUIStore as LectureRoomStreamUIStore;
      }

      get rosterUIStore() {
        return this._rosterUIStore as LectureRosterUIStore;
      }
    }
    ```

    ### Change the teaching tools of the student after the teacher gives permission [#change-the-teaching-tools-of-the-student-after-the-teacher-gives-permission-1]

    If you want to change the teaching tools of the student after the teacher gives the student permission in all scenarios, edit `toolbar/index.ts` in `/common`. If you want to apply the above change to only one scenario, create a `toolbar.ts` file in the folder of this scenario and rewrite the relevant methods.

    Taking One-to-one Classroom as an example, edit `packages/agora-classroom-sdk/src/infra/stores/one-on-one/toolbar.ts`, as follows:

    ```typescript
    // packages/agora-classroom-sdk/src/infra/stores/one-on-one/toolbar.ts
    ...
    // Extend the base class ToolbarUIStore
    export class OneToOneToolbarUIStore extends ToolbarUIStore {
      readonly allowedCabinetItems: string[] = [
        CabinetItemEnum.Whiteboard,
        CabinetItemEnum.ScreenShare,
        CabinetItemEnum.Laser,
      ];
      @computed
      get teacherTools(): ToolbarItem[] {
        let _tools: ToolbarItem[] = [];
        if (this.boardApi.mounted && !this.classroomStore.remoteControlStore.isHost) {
          _tools = [
            ToolbarItem.fromData({
              value: 'clicker',
              label: 'scaffold.clicker',
              icon: 'select',
              category: ToolbarItemCategory.Clicker,
            }),
            ToolbarItem.fromData({
              // Set the icon for the selector
              value: 'selection',
              label: 'scaffold.selector',
              icon: 'clicker',
              category: ToolbarItemCategory.Selector,
            }),
            ToolbarItem.fromData({
              value: 'pen',
              label: 'scaffold.pencil',
              icon: 'pen',
              category: ToolbarItemCategory.PenPicker,
            }),
            ToolbarItem.fromData({
              value: 'text',
              label: 'scaffold.text',
              icon: 'text',
              category: ToolbarItemCategory.Text,
            }),
            ToolbarItem.fromData({
              value: 'eraser',
              label: 'scaffold.eraser',
              icon: 'eraser',
              category: ToolbarItemCategory.Eraser,
            }),

            ToolbarItem.fromData({
              value: 'hand',
              label: 'scaffold.move',
              icon: 'hand',
              category: ToolbarItemCategory.Hand,
            }),
            ToolbarItem.fromData({
              value: 'save',
              label: 'scaffold.save',
              icon: 'save-ghost',
              category: ToolbarItemCategory.Save,
            }),
            {
              value: 'cloud',
              label: 'scaffold.cloud_storage',
              icon: 'cloud',
              category: ToolbarItemCategory.CloudStorage,
            },
            {
              value: 'tools',
              label: 'scaffold.tools',
              icon: 'tools',
              category: ToolbarItemCategory.Cabinet,
            },
          ];

          if (AgoraRteEngineConfig.platform === AgoraRteRuntimePlatform.Electron) {
            _tools.splice(
              5,
              0,
              ToolbarItem.fromData({
                value: 'slice',
                label: 'scaffold.slice',
                icon: 'slice',
                category: ToolbarItemCategory.Slice,
              }),
            );
          }
        } else {
          _tools = [
            {
              value: 'tools',
              label: 'scaffold.tools',
              icon: 'tools',
              category: ToolbarItemCategory.Cabinet,
            },
          ];
        }
        return _tools;
      }

      @computed
      get studentTools(): ToolbarItem[] {
        const { sessionInfo } = EduClassroomConfig.shared;
        const whiteboardAuthorized = this.boardApi.grantedUsers.has(sessionInfo.userUuid);

        if (!whiteboardAuthorized || this.classroomStore.remoteControlStore.isHost) {
          return [];
        }

        return [
          ToolbarItem.fromData({
            value: 'clicker',
            label: 'scaffold.clicker',
            icon: 'select',
            category: ToolbarItemCategory.Selector,
          }),
          ToolbarItem.fromData({
            // Set the icon for the selector
            value: 'selection',
            label: 'scaffold.selector',
            icon: 'clicker',
            category: ToolbarItemCategory.Clicker,
          }),
          ToolbarItem.fromData({
            value: 'pen',
            label: 'scaffold.pencil',
            icon: 'pen',
            category: ToolbarItemCategory.PenPicker,
          }),
          ToolbarItem.fromData({
            value: 'text',
            label: 'scaffold.text',
            icon: 'text',
            category: ToolbarItemCategory.Text,
          }),
          ToolbarItem.fromData({
            value: 'eraser',
            label: 'scaffold.eraser',
            icon: 'eraser',
            category: ToolbarItemCategory.Eraser,
          }),
        ];
      }
    }
    ```

    The above settings can override the teaching tools in `/common`. The final effect is as follows:

    ![Teacher toolbar after changing student teaching tools](https://web-cdn.agora.io/docs-files/1652870806492)

    ![Student toolbar after teacher authorization](https://web-cdn.agora.io/docs-files/1652870824396)

    ## Additional examples [#additional-examples-1]

    ### Change the background color of the classroom [#change-the-background-color-of-the-classroom-1]

    To change the background color of the classroom, edit `packages/agora-classroom-sdk/src/infra/capabilities/containers/root-box/fixed-aspect-ratio.tsx`.

    ```tsx
    const FixedAspectRatioContainer: React.FC<FixedAspectRatioProps> = observer(
        ({children, minimumWidth = 0, minimumHeight = 0}) => {
            const style = useClassroomStyle({minimumHeight, minimumWidth});

            const {shareUIStore} = useStore();

            return (
                <div
                    // You can use the tailwind class name
                    className="flex bg-black justify-center items-center h-screen w-screen"
                    // You can also set CSS properties
                    style={{backgroundColor: "red"}}>
                    <div style={style} className={`w-full h-full relative ${shareUIStore.classroomViewportClassName}`}>
                        {children}
                    </div>
                </div>
            );
        },
    );
    ```

    ### Change the background color of the whiteboard [#change-the-background-color-of-the-whiteboard-1]

    To change the background color of the whiteboard, edit `packages/agora-plugin-gallery/src/gallery/whiteboard/style.css`.

    ```css
    .netless-whiteboard-wrapper {
      height: 100%;
      width: 100%;
      border: 1px solid;
      border-radius: 4px;
      @apply bg-foreground border-divider;
      background: #000; /* Here we set the background color as black */
    }
    ```

    ### Adjust the whiteboard size [#adjust-the-whiteboard-size-1]

    To adjust the whiteboard layout, edit `packages/agora-classroom-sdk/src/infra/stores/common/board/index.ts`. Flexible Classroom will first calculate the width and height of the overall classroom area according to `packages/agora-classroom-sdk/src/infra/stores/common/share/index.ts`, then calculate the height of the whiteboard container, and finally dynamically set the size of the whiteboard according to the ratio of the whiteboard to the whiteboard container.`viewportAspectRatio` `heightRatio`

    ```typescript
    // packages/agora-classroom-sdk/src/infra/stores/common/share/index.ts
    ...
    // Set Classroom Size
    updateClassroomViewportSize() {
      ...
        // Get the current window width and height
        const { width, height } = getRootDimensions(this._containerNode);

        const aspectRatio = this._viewportAspectRatio;

        const curAspectRatio = height / width;

        const scopeSize = { height, width };
        // Ensure classroom maintains a fixed aspect ratio
        if (curAspectRatio > aspectRatio) {
          // shrink height
          scopeSize.height = width * aspectRatio;
        } else if (curAspectRatio < aspectRatio) {
          // shrink width
          scopeSize.width = height / aspectRatio;
        }
      ...
    }
    ...
    // packages/agora-classroom-sdk/src/infra/stores/common/board/index.ts
    // Set Whiteboard Scale
    ...
      protected get uiOverrides() {
        return {
          ...super.uiOverrides,
          heightRatio: 1
        };
      }

      /**
       * Whiteboard container height
       * @returns
       */
      @computed
      get boardAreaHeight() {
        // Set the height of the interactive area of ​​the whiteboard (Total minus the height of the navigation bar)
        const viewportHeight =
          this.shareUIStore.classroomViewportSize.height - this.shareUIStore.navHeight;
        // Set Whiteboard Scale
        const heightRatio = this.getters.stageVisible ? this.uiOverrides.heightRatio : 1;
        // Set whiteboard height
        const height = heightRatio * viewportHeight;

        return height;
      }
    ...
    ```

    The above changes are applied to all scenarios. If you only want to change the height of the whiteboard in a the One-to-one Classroom scenario, create a `board.ts` file in `packages/agora-classroom-sdk/src/infra/stores/one-on-one` with the following code:

    ```typescript
    // packages/agora-classroom-sdk/src/infra/stores/one-on-one/board.ts
    import {BoardUIStore} from "../common/board-ui";

    export class OneToOneBoardUIStore extends BoardUIStore {
        protected get uiOverrides() {
            return {
                ...super.uiOverrides,
                heightRatio: 1,
            };
        }
    }
    ```

    
  
