# Page Controller

Page Controller can be used for the following purposes

1. Customize page level CSS (Look & Feel) using the [SX prop](https://mui.com/system/the-sx-prop)
2. Define event handler functions for supported components on the page
3. Define an page level React component that will stay mounted while the page is in use

{% hint style="info" %}
If you want complete control on the page, then define an empty page and return a PageComponent that takes up and control the whole page.
{% endhint %}

> Example Page Controller

{% code overflow="wrap" lineNumbers="true" %}

```typescript
import React from 'react';
import { Box } from '@mui/material';
import type { BaseFunctionProps, FormatColumnValueFunction, IOComponentProps, IconValueWithToolTip } from 'cloudio';
import { getSessionProperty } from 'cloudio';
import platform from 'platform';

function getUserName() {
    return getSessionProperty(platform, 'userName');
}

function PageComponent(props: IOComponentProps) {
  console.log(props, 'PageComponent.render');
  React.useEffect(() => {
      // fetch and initialize page level data
      console.log(props, 'PageComponent.useEffect');
  }, []);
  return null;
}

const NF = {
  USD: new Intl.NumberFormat('en-US', {
    style: 'currency',
    currency: 'USD',
  }),
};

const formatColumnValue: FormatColumnValueFunction = ({ viewAttribute, value, rawValue, record, theme }) => {
  if (rawValue) {
      let icon: IconValueWithToolTip | undefined;
      switch (rawValue) {
          case 7:
              icon = { iconName: 'check', color: theme.palette.success.main, iconType: 'light' };
              break;
          case 9:
              icon = { iconName: 'wrench', color: theme.palette.warning.main, iconType: 'light' };
              break;
          case 8:
              icon = { iconName: 'times', color: theme.palette.error.main, iconType: 'light' };
              break;
          default:
              icon = { iconName: 'desktop', color: theme.palette.primary.main, iconType: 'light', iconSize: 30, tooltip: 'some tooltip...' + value };
              break;
      }
      return { value, icon };
  }
  return value;
}

function onSomeTextFieldChange({ pageId, itemId, platform, oldValue, value, ...otherProps }: BaseFunctionProps) {
  // validate the user entered value
  if (value === 'test') {
      // show an error message to the user
      platform.showError(`Invalid value ${value}!`);
      // return the oldValue to override user entered value
      return oldValue;
  }
  return value;
}

function someDebugFunction(props: BaseFunctionProps) {
  // use this function to just print all the incoming properties
  // console.log(props);
}

async function getPageSX({ theme, platform, appUid }: BaseFunctionProps) {
  // refer https://mui.com/system/the-sx-prop/
  /*
  const darkMode = theme.palette.mode === 'dark';
  return {
      bgcolor: darkMode ? '#000' : '#fff',
      '& #someId': { display: 'none' },
      '& .someCSSClassName': { backgroundColor: theme.palette.background.paper }
  };
  */
  return {};
}

// must export a default object with all the functions to be used by this page
export default {
  formatColumnValue,
  // getPageSX, // page level sx prop refer https://mui.com/system/the-sx-prop/
  onSomeTextFieldChange,
  someDebugFunction,
  PageComponent, // PageComponent will be rendered at the root of the page and will get unmounted when the page is exited.
}
```

{% endcode %}

### Navigation Steps

Navigate to the Pages tab on the sidebar and click on the Edit Page icon as shown below

![](/files/2EoW2NXzm8XDzdWHsIOa)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://next-docs.cloudio.io/ui/page-controller.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
