[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/docs/README.md from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```markdown
=� Use this project, [contribute](https://github.com/vtex-apps/b2b-organizations) to it or open issues to help evolve it using [Store Discussion](https://github.com/vtex-apps/store-discussion).

# B2B Organizations

<!-- DOCS-IGNORE:start -->
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->

[![All Contributors](https://img.shields.io/badge/all_contributors-0-orange.svg?style=flat-square)](#contributors-)

<!-- ALL-CONTRIBUTORS-BADGE:END -->
<!-- DOCS-IGNORE:end -->

> 9 The **B2B Organizations** app is part of VTEXs [B2B Suite](https://developers.vtex.com/vtex-developer-docs/docs/vtex-b2b-suite) solution: a collection of apps that allow stores to manage organizations, storefront roles and permissions, and checkout settings for B2B commerce relationships. We recommend that you use it alongside the other apps in this suite for all functionalities to work as expected.

In the B2B model, sales goals go beyond a high order conversion rate. They include simplifying the relationship between companies, reducing costs, and increasing performance by providing the customer with the best possible shopping experience.

B2B commerce relations are usually complex and often require a customized service. Therefore, grouping different users from the same company under an organization, and defining custom payment methods, product selections, and prices for each customer are common tasks in this scenario.

The **B2B Organizations** app enables you to group B2B users into organizations. You can assign specific payment methods, price tables, and product collections to each organization, allowing all of the organizations users to share the same commercial conditions. Each organization is further segmented into one or more cost centers, with its own shipping addresses.

## Before you start

First, make sure you have the [VTEX IO CLI (Command Line Interface)](https://developers.vtex.com/vtex-developer-docs/docs/vtex-io-documentation-vtex-io-cli-install) installed in your machine.

Note that installing B2B Organizations will also result in [Storefront Permissions](https://developers.vtex.com/vtex-developer-docs/docs/vtex-storefront-permissions) being installed as a dependency app  it allows you to grant specific storefront roles for B2B users in an organization. This is especially useful for organizations with multiple users who have different responsibilities, such as placing orders, approving orders or managing the organization users. See the [Storefront Permissions](https://developers.vtex.com/vtex-developer-docs/docs/vtex-storefront-permissions) app documentation for information on the available roles and how to customize their permissions.

If you want to be able to manage roles and permissions on the VTEX Admin, you must install [Storefront Permissions UI](https://developers.vtex.com/vtex-developer-docs/docs/vtex-storefront-permissions-ui) as well.

## Installation

You can install the **B2B Organizations** app by running `vtex install vtex.b2b-organizations` in your terminal, using the [VTEX IO CLI](https://developers.vtex.com/vtex-developer-docs/docs/vtex-io-documentation-vtex-io-cli-installation-and-command-reference).

## User widget configuration

To enable the [user widget](#user-widget) in your storefront, this app provides a `b2b-user-widget` block that you can add to the account's store theme. We recommend that you add it to the store header, as shown below.

![01-user-widget-header](https://user-images.githubusercontent.com/77292838/159766647-a8d22a55-61da-4169-a1be-1072a4ca8d73.png)

Follow the instructions below to display the user widget.

1. Open your store theme apps repository in your local files.
2. In the `manifest.json` file, under `dependencies`, add `"vtex.b2b-organizations": "1.x"`, like so:

   ```json
   "dependencies": {
       "vtex.b2b-organizations": "1.x"
     },
   ```

3. Within your store theme's `store` > `blocks` > `header` folder, edit the `header.jsonc` file, placing the `b2b-user-widget` block in the desired location, as exemplified below.

   We recommend placing it on the top row of the store header. The `b2b-user-widget` block accepts no props.

   ```json
   "header-layout.desktop": {
       "children": [
         "flex-layout.row#0-desktop",
         "flex-layout.row#1-desktop",
         "flex-layout.row#2-desktop",
         "flex-layout.row#3-desktop",
         "sticky-layout#4-desktop"
       ]
     },

     "flex-layout.row#0-desktop": {
       "children": ["b2b-user-widget"],
       "props": {
         "fullWidth": true
       }
     },
   ```

4. Publish and install the modified store theme. You can follow our documentation on [Making your theme content public](https://developers.vtex.com/vtex-developer-docs/docs/vtex-io-documentation-making-your-theme-content-public) to do so.

## Seller Wrapper configuration

To complete the Seller experience, follow the instructions:

1. Check if the `"vtex.b2b-organizations": "1.x"` is a dependency on `manifest.json` file
2. Within your store theme's `store` > `blocks` > `product` > `box.jsonc` and  `store` > `blocks` > `product.jsonc` you must wrap the target content to the block `b2b-seller-wrapper`.

***box.jsonc***
```json
  "flex-layout.row#box": {
    "children": ["flex-layout.col#box"],
    "props": {
      "blockClass": ["b2b-seller-wrapper#product"],
    }
  },
  "b2b-seller-wrapper#product": {
    "children": ["flex-layout.col#box"]
  },
```

***product.jsonc***
```json
  "flex-layout.row#product": {
      "children": ["b2b-seller-wrapper#pdp"]
  },
  "b2b-seller-wrapper#pdp": {
    "children": ["flex-layout.col#product"]
  },
```

3. Publish and install the modified store theme. You can follow our documentation on [Making your theme content public](https://developers.vtex.com/vtex-developer-docs/docs/vtex-io-documentation-making-your-theme-content-public) to do so.

## Configuration

if we have only one associated organization:
![](https://i.imgur.com/5yXFU6y.png)

if we have more than one associated organization:
![](https://i.imgur.com/ScQtfIz.png)

### `b2b-user-widget`
| Prop name                  | Type                              | Description                                                                                | Default value |
| -------------------------- | --------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------- |
| `showDropdown`               | `Boolean`                          | controls whether we are viewing the dropdown if we have more than one organization associated with the same email.                  | `true`          |
| `showLoadingIndicator`       | `Boolean`                          | controls whether a loading indicator will be displayed while widget data is loading.                                                | `false`          |
## Customization

In order to apply CSS customizations in this and other apps, follow the instructions on [Using CSS Handles for store customization](https://developers.vtex.com/vtex-developer-docs/docs/vtex-io-documentation-using-css-handles-for-store-customization).

CSS handles are available for the **Organization Request Form** component and the **User Widget** component.

| **CSS Handles**                   |
| --------------------------------- |
| `newOrganizationContainer`        |
| `newOrganizationInput`            |
| `newOrganizationAddressForm`      |
| `newOrganizationButtonsContainer` |
| `newOrganizationButtonSubmit`     |
| `userWidgetContainer`             |
| `userWidgetLoading`             |
| `userWidgetRow`                   |
| `userWidgetItem`                  |
| `userWidgetButton`                |
| `userWidgetImpersonationItem`     |
| `userWidgetImpersonationButton`   |
| `userWidgetImpersonationError`    |

## How the app works

The **B2B Organizations** app adds the following functionalities and components to your VTEX store, divided into VTEX Admin, Master Data v2, and Storefront capabilities:

    Public
    Availability
    Location
    Feature

    B2B store administrator
    VTEX Admin
    Organization Requests page
    Review Organization Requests

    Organizations page
    Manage Organizations

    Organization Details page
    Manage Cost Centers associated with organizations

    Manage Collections associated with organizations

    Manage Payment Terms associated with organizations

    Manage Price Tables associated with organizations

    Manage organization Users

    Message Center Templates page
    Manage email templates related to the B2B Organizations app

    B2B store administrator or developers
    Master Data v2
    Master Data API v2
    Retrieve and edit information on organization requests, organizations, and cost centers stored in Master Data v2

    B2B customer (organization user) with required permissions
    Storefront
    Storefront form
    Request New Organization

    My Organization
    Manage Organization

    Manage Cost Centers

    Manage Users

    Impersonate Users

    Storefront navigation
    User Widget

> ℹ This app can also be used together with [B2B Quotes](https://developers.vtex.com/vtex-developer-docs/docs/vtex-orderquote), allowing order quotes to be managed at the organization level. Please read our B2B Quotes documentation for more details.

### VTEX Admin

After installing and setting up the **B2B Organizations** app, its VTEX Admin capabilities can be found by accessing **Account Settings > B2B Organizations & Cost Centers**.

#### Organization Requests

To request the creation of an organization, B2B customers can use the page available at `/organization-request`. This page allows customers to request an organization creation and its cost center. Add `/organization-request` to your store’s domain to access it.

Once this step is done by the customer, B2B store administrators may review the organization request by going to **VTEX Admin** > **Account Settings** > **B2B Organizations & Cost Centers** > **Organization Requests** (or at `/admin/b2b-organizations/requests`).

In this page, they can view a list of all the organization requests placed in their store.

![02-organization-requests](https://user-images.githubusercontent.com/77292838/159766650-d989a5bc-a33b-4fee-9e60-76f26567b067.png)

Each organization can have a status of **pending**, **approved** or **declined**. Pending requests are the ones that still need review.

To review a request, you must:

1. Click on a request from the table  or click on  > `View`.
2. Write a comment on the **Add note** field, if necessary.
3. Click on `Approve` or `Decline`.

![03-manage-organization-request](https://user-images.githubusercontent.com/77292838/159766653-ba4f6d4b-4bda-4856-86a3-0080f8d22e1e.png)

Upon approval, the request status will change to **Approved** and the organization will be created. The [Organization Admin and the Sales Admins](https://developers.vtex.com/vtex-developer-docs/docs/vtex-storefront-permissions#available-storefront-roles) will be notified about this via email. You can learn more about this notification in the [Email templates](#email-templates) section. In addition, the user designated as the Organization Admin will be granted access to the [My Organization](#my-organization) tab on the **My Account** page of your storefront.

If the organization request is declined, the request status will be changed to **Declined** and the organization will not be created. The user designated as the Organization Admin is notified via email of this result. Read more about this notification in the [Email templates](#email-templates) section.

#### Organizations

The **Organizations** page includes a list of all the organizations created in your store and their respective status, and also allows store administrators to:

- [Add organizations](#add-organization).
- Access the [Organization details](#organization-details) page, which includes organization data, cost centers, collections, payment terms, price tables and users.

To access the page, go to **Account Settings** > **B2B Organizations & Cost Centers** > **Organizations** in the VTEX Admin (or at `/admin/b2b-organizations/organizations`).

![04-organizations](https://user-images.githubusercontent.com/77292838/159766661-63f7191a-51c4-49d7-a34d-d909456f2692.png)

You can click `Refetch` to refresh the organizations list on this page, fetching information about recently created organizations.

It is possible to use the search bar to find an organization by name or filter the organizations by status.

Each organization can have one of the following statuses:

- **Active**: the organization has been approved by the store administrators and it is currently active.
- **On hold**: the organization is currently paused, which means its users are not allowed to complete purchases at the moment.
- **Inactive**: the organization has been deactivated by the store administrators, so its users will not be able to login.

##### Add organization

You can manually create a new organization on the **Organizations** page. Follow these steps to do so:

1. Click on the `New` button.
2. Fill in the required information about the new organization, as illustrated in the image below.
   - **Name of organization:** name of the organization you want to create.
   - **Name of cost center:** name of the initial cost center associated with the organization.
   - **Country:** country where the cost center is located.
   - **ZIP:** postal code of the cost center address.
   - **Address Line 1:** primary address information, including street number and street name where the cost center is located.
   - **Address Line 2:** optional field for additional address information.
   - **City:** city where the cost center is located. This is filled in automatically based on the ZIP code informed.
   - **State:** state where the cost center is located. This is filled in automatically based on the ZIP code informed.
   - **Receiver:** name of the person that will receive orders in the informed address.
3. Click on `Add`.

![05-add-organization](https://user-images.githubusercontent.com/77292838/159766663-e1b2005a-0c2d-4bec-84ad-612007f17d64.gif)

> ℹ Additional cost centers and addresses may be added after creating the organization, as explained in the next section of this documentation.

#### Organization Details

In the **Organizations Details** page, you can see and edit the information of an existing organization:

- [Organization Name and Status](#organization-name-and-status)
- [Cost Centers](#cost-centers)
- [Collections](#collections)
- [Payment Terms](#payment-terms)
- [Price Tables](#price-tables)
- [Users ](#users)

You can access this page by going to **Account Settings** > **B2B Organizations & Cost Centers** > **Organizations** in the VTEX Admin and clicking on the organization whose details you want to view, or on  > `View`.

> ℹ Note that assigning collections, payment terms, and price tables to an organization is optional. If these are not assigned, users of the organization will see the stores default catalog, have access to all payment methods, and see the store's default pricing.

##### Organization Name and Status

In the top section of the page, you can view the following information:

- **Organization Name:** name of the organization. This information can be edited.
- **Status:** status of the organization. You can set it to **Active**, **On Hold** or **Inactive** by selecting from a list.
- **Created:** date when the organization was created.

![06-organization-name-status](https://user-images.githubusercontent.com/77292838/159766675-bd899388-7537-427d-af37-fc048aaf8636.png)

##### Cost Centers

In the **Cost Centers** section, you can view all the cost centers associated with the organization. VTEX Admin users can view and manage cost centers for any organization.

![07-cost-centers](https://user-images.githubusercontent.com/77292838/159766678-0fd6c361-e1e6-470b-a9fc-c98b530c05e9.png)

> ℹ Each organization must have at least one cost center.

By default, each cost center will allow all of the [payment terms](#payment-terms) that have been assigned to the parent organization. However, **Organization Admin** users have the ability to enable or disable individual payment terms at the cost center level  see [Manage Cost Centers](#manage-cost-centers) for more information on this.

To create a new cost center, follow the steps below.

1. Click on the `New` button.
2. Fill in the required information about the new cost center, as illustrated in the image below.
   - **Name:** name of the cost center.
   - **Country:** country where the cost center is located.
   - **ZIP:** postal code of the cost center address.
   - **Address Line 1:** primary address information, including street number and street name where the cost center is located.
   - **Address Line 2:** optional field for additional address information.
   - **City:** city where the cost center is located. This is filled in automatically based on the ZIP code informed.
   - **State:** state where the cost center is located. This is filled in automatically based on the ZIP code informed.
   - **Receiver:** name of the person that will receive orders in the informed address.
3. Click on `Add`.

![08-add-cost-center](https://user-images.githubusercontent.com/77292838/159766680-5eb39381-a7da-4278-b8da-8cc7efe3e90a.gif)

##### Cost Center Details

You can view or edit the details of an existing cost center by clicking on it in the **Organization Details** page.

This will lead you to the **Cost Center Details** page, where you can:

- View or edit the cost centers **Name** and **Addresses**.
- View or edit the cost center's **Business Document**.
- Add a new shipping address associated with the cost center.
- Delete the cost center

![09-cost-center-details](https://user-images.githubusercontent.com/77292838/159766691-4557a032-a38c-4abb-a5a1-29019b833ad2.png)

The optional **Business Document** field may be used to store a Tax ID, VAT ID, CNPJ, or similar business identifier. If a Business Document is present in a user's cost center, it will be applied as the `corporateDocument` in the user's profile and therefore attached to any orders placed by the user.

> ℹ The shipping addresses assigned to a cost center will be available to that cost center's users at checkout if you install [B2B Checkout Settings](https://developers.vtex.com/vtex-developer-docs/docs/vtex-b2b-checkout-settings). No other addresses will be available. Therefore, each cost center must have at least one shipping address.

To edit or delete an existing address, click  next to it and select **Edit** or **Delete**.

If you would like to add a new shipping address related to that cost center, follow these instructions:

1. Click on `Add new address`.
2. Fill in the required information about the new address.
   - **Country:** country where the cost center is located.
   - **ZIP:** postal code of the cost center address.
   - **Address Line 1:** primary address information, including street number and street name where the cost center is located.
   - **Address Line 2:** optional field for additional address information.
   - **City:** city where the cost center is located. This is filled in automatically based on the ZIP code informed.
   - **State:** state where the cost center is located. This is filled in automatically based on the ZIP code informed.
   - **Receiver:** name of the person that will receive orders in the informed address.
3. Click on `Add`.

Make sure to click `Save` in the top right of the **Cost Center Details** page after any changes.

If you want to delete the cost center, click on `Delete` instead.

##### Collections

> ℹ You must use the **Collections Beta** solution to be able to associate collections to organizations using **B2B Organizations**. Read our article on [Creating Collections Beta](https://help.vtex.com/tutorial/creating-collections-beta--yJBHqNMViOAnnnq4fyOye) for more information.

This section allows you to manage the [product collections](https://help.vtex.com/tutorial/creating-collections-beta--yJBHqNMViOAnnnq4fyOye) assigned to the organization. Your selections define the assortment of products the organization users will see in the storefront.

To add a collection, select the collection you want to add from the **Available** list and click `Add to org`.

To remove a collection, select the collection you want to remove from the **Assigned to organization** list and click `Remove from org`.

![10-collections](https://user-images.githubusercontent.com/77292838/159766692-aec018f6-d09b-4290-a180-a0e2b7040295.gif)

##### Payment Terms

In this section, you can choose which [payment conditions](https://help.vtex.com/en/tutorial/how-to-configure-payment-conditions--tutorials_455?&utm_source=autocomplete) are assigned to the organization. Your selections determine which payment options are available to organization users during checkout.

Note that the available payment options can be further customized per cost center by the **Organization Admin**. Check the [Manage Cost Centers](#manage-cost-centers) section for more information on this.

To add a payment term, select the option you want to add from the **Available** list and click `Add to org`.

To remove a payment term, select the option you want to remove from the **Assigned to organization** list and click `Remove from org`.

![11-payment-terms](https://user-images.githubusercontent.com/77292838/159766697-27de2f5b-18b3-4067-a4f1-81da8fb61bc0.gif)

> ℹ To customize the checkout according to each organization users role, you need to install and configure [B2B Checkout Settings](https://github.com/vtex-apps/b2b-checkout-settings).

##### Price Tables

This section allows you to choose which [price tables](https://help.vtex.com/en/tutorial/creating-price-tables--58YmY2Iwggyw4WeSCGg24S) are assigned to the organization. The price tables you select determine the prices the organization users will see in the storefront.

Price tables associated with an organization override the base price only when fulfillment is performed by the main account. When franchises perform the fulfillment, the price table is not applied, resulting in incorrect price displays. To ensure correct operation, configure both the logistics and the price tables directly in the main account, avoiding the use of franchises that inherit price settings.

To add a price table, select the option you want to add from the **Available** list and click `Add to org`.

To remove a price table, select the option you want to remove from the **Assigned to organization** list and click `Remove from org`.

![12-price-tables](https://user-images.githubusercontent.com/77292838/159766700-34ebfaaf-f6fa-42b6-85a9-a83dca5505ef.gif)

##### Users

This section presents a list of users associated with the organization, showing their **emails**, their **roles** within the organization, and the **cost center** to which they are associated. It is worth noting that the same email can be associated with up to 949 different organizations or cost centers.

![13-users-list](https://user-images.githubusercontent.com/77292838/159766707-572dd167-e948-4300-b259-1c9cd0b8a341.png)

To add a new user to the organization, follow these steps:

1. In the **Users** list, click on the `New` button.
2. Fill in the users information, as illustrated below.
   - **Name:** full name of the user.
   - **Email:** email of the user.
   - **Cost Center:** cost center the user will be associated with.
   - **Role:** role the user will have in the storefront. See more details on the available roles in the [Storefront Permissions documentation](https://developers.vtex.com/vtex-developer-docs/docs/vtex-storefront-permissions#available-storefront-roles).
3. Click on `Add`.

![14-add-new-user](https://user-images.githubusercontent.com/77292838/159766710-4e35973c-880d-4e98-8f93-4a6c87d3f4e8.png)

Once you add a new user to the organization, if a customer account did not already exist in your store for the provided email address, it will be created.

To edit or remove an existing user, follow these steps:

1. Click on the user you want to edit or delete in the **Users** list.
2. Edit the desired information.

   You can change the users **Cost Center** and their **Role**.

   If you want to remove the user from the organization, click `Remove user` instead and skip the next step.

3. To apply your changes, click `Save`.

![15-edit-user](https://user-images.githubusercontent.com/77292838/159766713-03778c4a-370a-4c13-be4a-8f507cee0a73.png)

If a user is removed from an organization, their account will continue to exist in the store, but they will no longer be assigned to an organization, a cost center, and a B2B role. Thus, they will no longer have access to details of their organization in the **My Organization** page. Instead, they will have the ability to [request the creation of a new organization](#request-new-organization), if necessary.

> ℹ As an optional feature, you can install the [Admin Customers](https://developers.vtex.com/docs/apps/vtex.admin-customers) app for additional customer management capabilities on the VTEX Admin.

#### Email templates

The **B2B Organizations** app provides a set of four email templates to be sent to B2B organization users, triggered automatically based on specific changes:

| **Template name**               | **Recipient**                          | **Trigger**                                 |
| ------------------------------- | -------------------------------------- | ------------------------------------------- |
| **Organization Approved**       | User with the Organization Admin role  | The organization request has been approved. |
| **Organization Created**        | Users with a Sales Admin role          | The organization has been created.          |
| **Organization Declined**       | User with the Organization Admin role  | The organization request has been declined. |
| **Organization Status Changed** | Users with the Organization Admin role | The organization status has changed.        |

If you want to view or edit any of these templates, follow the steps below.

1. In the VTEX Admin, go to **Customer > Message center > Templates**.
2. In the search bar, type `organization`.
3. Click on the template you want to view or edit.
4. Make the desired changes in the template. You can learn more about editing **Message Center** templates by reading our documentation on [How to create and edit transactional email templates](https://help.vtex.com/en/tracks/transactional-emails--6IkJwttMw5T84mlY9RifRP/335JZKUYgvYlGOJgvJYxRO).
5. Click on `Save`.

![16-templates](https://user-images.githubusercontent.com/77292838/159766714-6b5feaaf-3d81-472e-a713-55d952a1e556.gif)

### Master Data v2

The **B2B Organizations** app stores information about organization requests, organizations, and cost centers in [Master Data v2](https://help.vtex.com/pt/tutorial/master-data-v2--3JJ1mlzuo88w22gO0gy0QS).

This means that it is possible for store administrators or developers to fetch this information using the [Master Data API v2](https://developers.vtex.com/vtex-rest-api/reference/master-data-api-v2-overview), by using their **data entity name** as the value for the `data_entity_name` parameter.

You can see the data entity names in the table below.

| **Data entity names**   |
| ----------------------- |
| `organization_requests` |
| `organizations`         |
| `cost_centers`          |

### Storefront

Storefront capabilities, in turn, are accessible to B2B customers who visit a suppliers store, provided that they are logged in and have the required permissions.

The following sections describe what your customer can do in your storefront, after you've finished setting up the B2B Organizations app.

#### Request New Organization

A B2B user who is not already part of an organization can request the creation of a new buyer organization in your store by filling in the **Request New Organization** form. They can follow the steps below to do so.

1. Access the store website.
2. Click on **My Account** > **My Organization**.
3. Provide the required information, as shown in the image below.
   - **Organization Name:** name of the organization.
   - **User to become Organization Admin:** section where you must provide information about the first user of the organization, who will be assigned as the Organization Admin.
     - **First Name:** first name of the Organization Admin user.
     - **Last Name:** last name of the Organization Admin user.
     - **Email Address:** email address of the Organization Admin user.
   - **Default Cost Center:** section where you must provide information about the first cost center associated with the organization.
     - **Cost Center Name:** name of the cost center.
     - **Business Document:** optional field for a business document such as a Tax ID, CNPJ, etc.
     - **Country:** country where the cost center is located.
     - **ZIP:** postal code of the cost center address.
     - **Address Line 1:** primary address information, including street number and street name where the cost center is located.
     - **Address Line 2:** optional field for additional address information.
     - **City:** city where the cost center is located. This is filled in automatically based on the ZIP code informed.
     - **State:** state where the cost center is located. This is filled in automatically based on the ZIP code informed.
     - **Receiver:** name of the person that will receive orders in the informed address.
4. Click `Submit`.

![17-organization-request](https://user-images.githubusercontent.com/77292838/159766733-14da23e9-55d6-44e8-8cfc-95d62e3b4ade.gif)

After submitting the form, the request will be sent to a queue for review by the B2B store administrator  for more details on this, refer to the [Organization Requests](#organization-requests) section.

The user designated as the **Organization Admin** for the new organization will receive an email notification when the request has either been approved or declined by the store administrator. You can learn more about this notification in the [Email templates](#email-templates) section.

#### My Organization

Users who are designated as the **Organization Admin** or **Sales Admin** can manage the details of their organization in the storefront, on the **My Organization** page.

Users with the **Organization Buyer** or **Organization Approver** roles can also view a read-only version of this page.

To access **My Organization**, follow the instructions below.

1. Access the storefront and log in.
2. Click `Hello, {name}`.
3. Click on **My Account**.
4. Go to **My Organization** on the sidebar. You will see the page below.

![18-my-organization](https://user-images.githubusercontent.com/77292838/159766773-4d62c3ed-4282-45a9-bf36-d0041684cc50.png)

On this page, the user with the **Organization Admin** or **Sales Admin** roles may do the following:

- [Manage Cost Centers](#manage-cost-centers)
- [Manage Users](#manage-users)

##### Manage Cost Centers

**Organization Admin** or **Sales Admin** storefront users can find the cost centers associated with their organization in the **Cost Centers** section of the **My Organization** page.

To add a new cost center, they should go to **My Account > My Organization**, where they have access to the same options described in [Cost Centers](#cost-centers). It is possible to view or edit the details of an existing cost center by clicking on it, the same way as described in [Cost Center Details](#cost-center-details).

**Organization Admins** may also view and/or edit the **Business Document** assigned to each cost center, as described in [Cost Center Details](#cost-center-details).

In addition, **Organization Admins** can enable specific payment terms for a cost center, by using the toggle button to activate or deactivate the payment terms assigned to the organization, as shown below.

> ℹ This section will only be available on the **My Organization** page if [payment terms](#payment-terms) have previously been assigned to the organization by the VTEX Admin users.

![19-payment-terms-cost-center](https://user-images.githubusercontent.com/77292838/159766775-dd0a17bd-8418-401b-a377-7d4c9ed0cf11.png)

##### Manage Users

**Organization Admin** or **Sales Admin** storefront users can also see and manage the users of their organization in the **Users** section in **My Organization**. To do this, they should go to **My Account > My Organization**, where they have access to the same options described in the [Users](#users) section of this documentation.

Users with the **Organization Admin** role may add, edit, or remove users with any of the following roles: **Organization Admin**, **Organization Approver**, and **Organization Buyer**.

Users with the **Sales Admin** role may add, edit, or remove users with any of the following roles: **Sales Admin**, **Sales Manager**, and **Sales Representative**.

###### Impersonate Users

In telesales, assisted sales, or customer support scenarios where the B2B customer needs help from a salesperson to navigate the store or place orders, it is common to make use of impersonation.

In the **B2B Organizations** app, only users with **Sales** roles or the **Organization Admin** role may impersonate another user.

This action will temporarily apply the impersonated user's email, organization, and cost center to their storefront session. It allows the impersonating users to do the following:

- Browse the store and see the prices, products, shipping addresses and payment methods that would be seen by the impersonated user.
- Take actions on behalf of the impersonated user, such as placing orders.
- Use their regular permissions.

To use impersonation, users with **Sales** roles or the **Organization Admin** role must follow the steps below.

1. In the **Users** section of [My Organization](#my-organization), click on  in the row of the user they want to impersonate.
2. Click on **Impersonate User**.

![20-users](https://user-images.githubusercontent.com/77292838/159766777-1ff83458-cad0-46de-82e4-1e3c3e4bb144.png)

#### User widget

To give storefront users visibility into their currently assigned organization, cost center, and role, this app provides a user widget which can be added to the account's store theme:

![21-user-widget](https://user-images.githubusercontent.com/77292838/159766781-8edabb7e-292c-4c8e-a88e-ae937ec7db86.png)

> ℹ To display the user widget, it is necessary to follow the instructions in the [User widget configuration](#user-widget-configuration) section.

If users click `Manage organization`, they can access the **My Organization** page directly.

In case impersonation is currently active, this block will also show the email of the user being impersonated, as well as a `Stop impersonation` button:

![22-user-widget-impersonation](https://user-images.githubusercontent.com/77292838/159766784-6bce63af-9cc6-4ac4-bc59-460b74722dbe.png)

#### Seller Wrapper Block

> ℹ 10 This topic is related to the Seller functionality.

To persist the Organization seller throughout the PDP and shelves, it must have the "seller-wrapper" block in the store theme configuration.

Please check [Seller wrapper configuration](#seller-wrapper)

## Contributors (

Thanks goes to these wonderful people:

This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind are welcome!

**Upcoming documentation:**

 - [[B2BORG-96] Fix duplicate check](https://github.com/vtex-apps/b2b-organizations/pull/29)

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/vtex.storefront-permissions/configuration.json from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "name": "B2B Organizations",
  "features": [
    {
      "label": "Manage My Organization",
      "value": "manage-organization",
      "roles": ["customer-admin"]
    },
    {
      "label": "Create and Edit Cost Centers in Same Organization",
      "value": "create-cost-center-organization",
      "roles": ["customer-admin"]
    },
    {
      "label": "Add Organization Users to any Cost Center in Same Organization",
      "value": "add-users-organization",
      "roles": ["customer-admin"]
    },
    {
      "label": "Remove Organization Users from any Cost Center in Same Organization",
      "value": "remove-users-organization",
      "roles": ["customer-admin"]
    },
    {
      "label": "Add Sales Users to any Organization",
      "value": "add-sales-users-all",
      "roles": ["sales-admin"]
    },
    {
      "label": "Add Sales Users to current Organization",
      "value": "add-sales-users-current",
      "roles": ["sales-manager"]
    },
    {
      "label": "Remove Sales Users from any Organization",
      "value": "remove-sales-users-all",
      "roles": ["sales-admin"]
    },
    {
      "label": "Impersonate Organization Users in Same Cost Center",
      "value": "impersonate-users-costcenter",
      "roles": ["sales-representative"]
    },
    {
      "label": "Impersonate Organization Users in Same Organization",
      "value": "impersonate-users-organization",
      "roles": ["customer-admin", "sales-manager"]
    },
    {
      "label": "Impersonate Organization Users in Any Organization",
      "value": "impersonate-users-all",
      "roles": ["sales-admin"]
    }
  ]
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/react/OrganizationDetails.tsx from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```tsx
import OrganizationDetails from './admin/OrganizationDetails'

export default OrganizationDetails

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/react/StorefrontWarningTopbarInactiveOrganization.tsx from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```tsx
import StorefrontWarningTopbarInactiveOrganization from './components/WarningTopbarInactiveOrganization'

export default StorefrontWarningTopbarInactiveOrganization

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/react/StorefrontOrganizationDetails.tsx from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```tsx
import StorefrontOrganizationDetails from './components/OrganizationDetails'

export default StorefrontOrganizationDetails

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/react/RequestOrganizationForm.tsx from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```tsx
import RequestOrganizationForm from './components/RequestOrganizationForm'

export default RequestOrganizationForm

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/react/OrganizationRequestsTable.tsx from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```tsx
import OrganizationRequestsTable from './admin/OrganizationRequestsTable'

export default OrganizationRequestsTable

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/react/CostCenterDetails.tsx from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```tsx
import CostCenterDetails from './admin/CostCenterDetails'

export default CostCenterDetails

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/react/MyOrganizationLink.tsx from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```tsx
import type { FC } from 'react'
import { useEffect, useState } from 'react'
import { defineMessages, useIntl } from 'react-intl'
import { useQuery } from 'react-apollo'

import { useSessionResponse } from './modules/session'
import GetBinding from './graphql/getBinding.graphql'

const messages = defineMessages({
  linkText: {
    id: 'store/b2b-organizations.my-account-link',
  },
})

const MyOrganizationLink: FC = ({ render }: any) => {
  const { formatMessage } = useIntl()
  const sessionResponse: any = useSessionResponse()
  const userEmail = sessionResponse?.namespaces?.profile?.email?.value

  const [show, setShow] = useState(false)

  const { data } = useQuery(GetBinding, {
    variables: { email: userEmail },
    skip: !userEmail,
  })

  useEffect(() => {
    if (!data) {
      return
    }

    if (data.getBinding === true) {
      setShow(true)
    }
  }, [data, userEmail, sessionResponse])

  const parameter = {
    name: formatMessage(messages.linkText),
    path: `/organization`,
  }

  return show ? render([parameter]) : null
}

export default MyOrganizationLink

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/react/MyOrganizationPage.tsx from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Fragment } from 'react'
import type { FC } from 'react'
import { useQuery } from 'react-apollo'
import { Route } from 'vtex.my-account-commons/Router'
import { Spinner } from 'vtex.styleguide'

import GET_ORGANIZATION from './graphql/getOrganizationStorefront.graphql'
import OrganizationDetails from './components/OrganizationDetails'
import CostCenterDetails from './components/CostCenterDetails'
import RequestOrganizationForm from './components/RequestOrganizationForm'

const MyOrganizationPage: FC = () => {
  const { data, loading } = useQuery(GET_ORGANIZATION, { ssr: false })

  const componentToRender = data?.getOrganizationByIdStorefront?.id
    ? OrganizationDetails
    : RequestOrganizationForm

  return (
    <Fragment>
      <Route
        exact
        path="/organization"
        component={loading ? Spinner : componentToRender}
      />
      <Route path="/organization/:id" component={OrganizationDetails} />
      <Route path="/cost-center/:id" component={CostCenterDetails} />
    </Fragment>
  )
}

export default MyOrganizationPage

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/react/package.json from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "name": "vtex.b2b-organizations",
  "version": "3.1.2",
  "license": "UNLICENSED",
  "scripts": {
    "test": "vtex-test-tools test --passWithNoTests"
  },
  "devDependencies": {
    "@apollo/react-testing": "^3.1.3",
    "@types/faker": "^5.5.7",
    "@types/jest": "^25.1.4",
    "@types/lodash": "^4.14.185",
    "@types/node": "^13.9.8",
    "@types/react": "^16.9.31",
    "@types/react-router": "^5.1.11",
    "@types/react-router-dom": "^5.1.11",
    "@vtex/test-tools": "^3.3.2",
    "@vtex/tsconfig": "^0.6.0",
    "apollo-cache-inmemory": "^1.6.5",
    "graphql": "^14.6.0",
    "vtex.address-form": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.address-form@4.23.3/public/@types/vtex.address-form",
    "vtex.admin-graphql": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.admin-graphql@2.40.0/public/@types/vtex.admin-graphql",
    "vtex.b2b-organizations": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.b2b-organizations@1.31.3/public/@types/vtex.b2b-organizations",
    "vtex.b2b-organizations-graphql": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.b2b-organizations-graphql@0.49.4/public/@types/vtex.b2b-organizations-graphql",
    "vtex.catalog-graphql": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.catalog-graphql@1.103.1/public/@types/vtex.catalog-graphql",
    "vtex.country-codes": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.country-codes@2.0.1/public/_types/react",
    "vtex.css-handles": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.css-handles@0.4.4/public/@types/vtex.css-handles",
    "vtex.my-account": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.my-account@1.27.1/public/@types/vtex.my-account",
    "vtex.my-account-commons": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.my-account-commons@1.7.1/public/@types/vtex.my-account-commons",
    "vtex.product-context": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.product-context@0.10.1/public/@types/vtex.product-context",
    "vtex.render-runtime": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.render-runtime@8.134.2/public/@types/vtex.render-runtime",
    "vtex.store": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.store@2.135.0/public/@types/vtex.store",
    "vtex.store-graphql": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.store-graphql@2.170.2/public/@types/vtex.store-graphql",
    "vtex.storefront-permissions": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.storefront-permissions@1.40.4/public/@types/vtex.storefront-permissions",
    "vtex.styleguide": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.styleguide@9.146.9/public/@types/vtex.styleguide"
  },
  "dependencies": {
    "@vtex/admin-ui": "^0.136.1",
    "@vtex/bulk-import-ui": "1.1.10",
    "@vtex/css-handles": "^1.0.0",
    "apollo-client": "^2.6.10",
    "axios": "1.4.0",
    "react": "^16.9.2",
    "react-apollo": "^3.1.5",
    "react-intl": "^5.13.4",
    "react-router": "^5.1.2",
    "react-router-dom": "^5.1.2",
    "swr": "^2.2.4"
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/react/OrganizationsTable.tsx from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```tsx
import OrganizationsTable from './admin/OrganizationsTable'

export default OrganizationsTable

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/react/B2BAdminLayout.tsx from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```tsx
import type { FunctionComponent } from 'react'
import React from 'react'
import { ThemeProvider, ToastProvider } from '@vtex/admin-ui'
import 'vtex.country-codes/locales'
import { BulkImportProvider } from '@vtex/bulk-import-ui'

import { useTranslate } from './hooks'

const B2BAdminLayout: FunctionComponent = ({ children }) => {
  const { translate } = useTranslate()

  return (
    <ThemeProvider>
      <BulkImportProvider value={{ translate }}>
        <ToastProvider>{children}</ToastProvider>
      </BulkImportProvider>
    </ThemeProvider>
  )
}

export default B2BAdminLayout

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/react/styles.global.css from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```css
html,
body,
#render-container,
#render-provider,
.render-container,
.render-provider {
  height: 100%;
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/react/OrganizationRequestDetails.tsx from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```tsx
import OrganizationRequestDetails from './admin/OrganizationRequestDetails'

export default OrganizationRequestDetails

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/react/StorefrontCostCenterDetails.tsx from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```tsx
import StorefrontCostCenterDetails from './components/CostCenterDetails'

export default StorefrontCostCenterDetails

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/react/StorefrontUserWidget.tsx from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```tsx
import StorefrontUserWidget from './components/UserWidget'

export default StorefrontUserWidget

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/react/SellerWrapper.tsx from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```tsx
import SellerWrapper from './components/SellerWrapper/SellerWrapper'

export default SellerWrapper

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/store/contentSchemas.json from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "definitions": {
    "StorefrontUserWidgetProps": {
      "title": "userWidget",
      "properties": {
        "showDropdown": {
          "title": "showDropdown",
          "type": "boolean",
          "default": true
        },
        "showLoadingIndicator": {
          "title": "showLoadingIndicator",
          "type": "boolean",
          "default": false
        }
      }
    },
    "StorefrontWarningTopbarInactiveOrganizationProps": {
      "title": "warningTopbarInactiveOrganization"
    }
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/store/blocks.json from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store.organization-request": {
    "blocks": ["request-organization"]
  },
  "store.organization-details": {
    "blocks": ["organization-details"]
  },
  "store.costcenter-details": {
    "blocks": ["costcenter-details"]
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/store/interfaces.json from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "my-account-page.my-organization": {
    "component": "MyOrganizationPage"
  },
  "my-account-link.my-organization": {
    "component": "MyOrganizationLink"
  },
  "store.organization-request": {
    "required": ["request-organization"]
  },
  "request-organization": {
    "component": "RequestOrganizationForm"
  },
  "store.organization-details": {
    "required": ["organization-details"]
  },
  "organization-details": {
    "component": "StorefrontOrganizationDetails"
  },
  "store.costcenter-details": {
    "required": ["costcenter-details"]
  },
  "costcenter-details": {
    "component": "StorefrontCostCenterDetails"
  },
  "b2b-user-widget": {
    "component": "StorefrontUserWidget"
  },
  "b2b-warning-topbar-inactive-organization": {
    "component": "StorefrontWarningTopbarInactiveOrganization"
  },
  "b2b-seller-wrapper": {
    "component": "SellerWrapper",
    "allowed": "*",
    "composition": "children"
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/store/routes.json from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store.organization-request": {
    "title": "Organization Signup",
    "path": "/organization-request"
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/store/plugins.json from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "my-account-pages > my-account-page": "my-account-page.my-organization",
  "my-account-menu > my-account-link": "my-account-link.my-organization"
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/react/bulkImport/messages.ts from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { defineMessages } from 'react-intl'
import type {
  ImportMessageKey,
  UploadMessageKey,
} from '@vtex/bulk-import-ui/dist/i18n/keys'

export type BulkImportMessageKey =
  | UploadMessageKey
  | ImportMessageKey
  | 'reportInformationListTotal'
  | 'reportInformationImportSuccessFully'
  | 'reportInformationImportFailed'
  | 'importReportTabTitle'
  | 'importReportTitle'
  | 'reportInformationTitle'
  | 'reportInformationDescription'
  | 'reportScreenSuccessCount'
  | 'reportScreenTitle'
  | 'reportScreenDescription'
  | 'reportScreenLabel'
  | 'reportInformationInitialImport'
  | 'reportInformationInitialUpload'
  | 'reportInformationNextSteps'
  | 'reportInformationStep1'
  | 'reportInformationStep2'
  | 'reportInformationStep3Upload'
  | 'reportInformationStep3Import'
  | 'reportInformationStep4'
  | 'helpLinks'
  | 'downloadReviewedLink'
  | 'errorMessage'
  | 'permissionAlertTooltip'

export const bulkUploadMessages: Record<
  BulkImportMessageKey,
  { id: string }
> = defineMessages({
  back: {
    id: 'admin/b2b-organizations.bulk-import.upload.back',
  },
  close: {
    id: 'admin/b2b-organizations.bulk-import.upload.close',
  },
  dragDrop: {
    id: 'admin/b2b-organizations.bulk-import.upload.dragDrop',
  },
  filesType: {
    id: 'admin/b2b-organizations.bulk-import.upload.filesType',
  },
  maxSize: {
    id: 'admin/b2b-organizations.bulk-import.upload.maxSize',
  },
  helpLinks: {
    id: 'admin/b2b-organizations.bulk-import.upload.helpLinks',
  },
  unknownRowName: {
    id: 'admin/b2b-organizations.bulk-import.upload.unknownRowName',
  },
  upload: {
    id: 'admin/b2b-organizations.bulk-import.upload.upload',
  },
  uploading: {
    id: 'admin/b2b-organizations.bulk-import.upload.uploading',
  },
  uploadErrorCount: {
    id: 'admin/b2b-organizations.bulk-import.upload.uploadErrorCount',
  },
  uploadErrorReport: {
    id: 'admin/b2b-organizations.bulk-import.upload.uploadErrorReport',
  },
  uploadErrorReportMessage: {
    id: 'admin/b2b-organizations.bulk-import.upload.uploadErrorReportMessage',
  },
  uploadFinish: {
    id: 'admin/b2b-organizations.bulk-import.upload.uploadFinish',
  },
  uploadGeneralFailure: {
    id: 'admin/b2b-organizations.bulk-import.upload.uploadGeneralFailure',
  },
  uploadMultipleErrors: {
    id: 'admin/b2b-organizations.bulk-import.upload.uploadMultipleErrors',
  },
  uploadSuccess: {
    id: 'admin/b2b-organizations.bulk-import.upload.uploadSuccess',
  },
  uploadSuccessItems: {
    id: 'admin/b2b-organizations.bulk-import.upload.uploadSuccessItems',
  },
  uploadTitle: {
    id: 'admin/b2b-organizations.bulk-import.upload.uploadTitle',
  },
  uploadViewReport: {
    id: 'admin/b2b-organizations.bulk-import.upload.uploadViewReport',
  },
  done: {
    id: 'admin/b2b-organizations.bulk-import.import.done',
  },
  importing: {
    id: 'admin/b2b-organizations.bulk-import.import.importing',
  },
  importError: {
    id: 'admin/b2b-organizations.bulk-import.import.importError',
  },
  importErrorReportTitle: {
    id: 'admin/b2b-organizations.bulk-import.import.importErrorReportTitle',
  },
  importProgress: {
    id: 'admin/b2b-organizations.bulk-import.import.importProgress',
  },
  importReportErrorTab: {
    id: 'admin/b2b-organizations.bulk-import.import.importReportErrorTab',
  },
  importReportGenericError: {
    id: 'admin/b2b-organizations.bulk-import.import.importReportGenericError',
  },
  importReportSuccessTab: {
    id: 'admin/b2b-organizations.bulk-import.import.importReportSuccessTab',
  },
  importReportTabTitle: {
    id: 'admin/b2b-organizations.bulk-import.import.importReportTabTitle',
  },
  importReportTitle: {
    id: 'admin/b2b-organizations.bulk-import.import.importReportTitle',
  },
  importSuccess: {
    id: 'admin/b2b-organizations.bulk-import.import.importSuccess',
  },
  importSuccessReportTitle: {
    id: 'admin/b2b-organizations.bulk-import.import.importSuccessReportTitle',
  },
  importDetails: {
    id: 'admin/b2b-organizations.bulk-import.import.importDetails',
  },
  fileExtensionError: {
    id: 'admin/b2b-organizations.bulk-import.import.fileExtensionError',
  },
  fileSizeError: {
    id: 'admin/b2b-organizations.bulk-import.import.fileSizeError',
  },
  importErrorTryAgain: {
    id: 'admin/b2b-organizations.bulk-import.import.importErrorTryAgain',
  },
  reportInformationTitle: {
    id: 'admin/b2b-organizations.bulk-import.import.reportInformationTitle',
  },
  reportInformationDescription: {
    id:
      'admin/b2b-organizations.bulk-import.import.reportInformationDescription',
  },
  reportInformationListTotal: {
    id: 'admin/b2b-organizations.bulk-import.import.reportInformationListTotal',
  },
  reportInformationImportSuccessFully: {
    id:
      'admin/b2b-organizations.bulk-import.import.reportInformationImportSuccessFully',
  },
  reportInformationImportFailed: {
    id:
      'admin/b2b-organizations.bulk-import.import.reportInformationImportFailed',
  },
  reportScreenTitle: {
    id: 'admin/b2b-organizations.bulk-import.import.reportScreenTitle',
  },
  reportScreenDescription: {
    id: 'admin/b2b-organizations.bulk-import.import.reportScreenDescription',
  },
  reportScreenLabel: {
    id: 'admin/b2b-organizations.bulk-import.import.reportScreenLabel',
  },
  reportScreenSuccessCount: {
    id: 'admin/b2b-organizations.bulk-import.import.reportScreenSuccessCount',
  },
  reportInformationInitialUpload: {
    id:
      'admin/b2b-organizations.bulk-import.import.reportInformationInitialUpload',
  },
  reportInformationInitialImport: {
    id:
      'admin/b2b-organizations.bulk-import.import.reportInformationInitialImport',
  },
  reportInformationNextSteps: {
    id: 'admin/b2b-organizations.bulk-import.import.reportInformationNextSteps',
  },
  reportInformationStep1: {
    id: 'admin/b2b-organizations.bulk-import.import.reportInformationStep1',
  },
  reportInformationStep2: {
    id: 'admin/b2b-organizations.bulk-import.import.reportInformationStep2',
  },
  reportInformationStep3Upload: {
    id:
      'admin/b2b-organizations.bulk-import.import.reportInformationStep3Upload',
  },
  reportInformationStep3Import: {
    id:
      'admin/b2b-organizations.bulk-import.import.reportInformationStep3Import',
  },
  reportInformationStep4: {
    id: 'admin/b2b-organizations.bulk-import.import.reportInformationStep4',
  },
  reportInformationStep4Filename: {
    id:
      'admin/b2b-organizations.bulk-import.import.reportInformationStep4Filename',
  },
  reportInformationStep4NeedGuidance: {
    id:
      'admin/b2b-organizations.bulk-import.import.reportInformationStep4NeedGuidance',
  },
  reportInformationStep4ImportGuide: {
    id:
      'admin/b2b-organizations.bulk-import.import.reportInformationStep4ImportGuide',
  },
  downloadReviewedLink: {
    id: 'admin/b2b-organizations.bulk-import.import.downloadReviewedLink',
  },
  errorMessage: {
    id: 'admin/b2b-organizations.bulk-import.import.errorMessage',
  },
  permissionAlertTooltip: {
    id: 'admin/b2b-organizations.bulk-import.import.permissionAlertTooltip',
  },
})

export const hasTranslation = (key: string): key is BulkImportMessageKey => {
  return key in bulkUploadMessages
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/react/organizations/navigate.ts from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { useRuntime } from 'vtex.render-runtime'

export const useNavigateToDetailsPage = () => {
  const { navigate } = useRuntime()

  return (id: string) =>
    navigate({
      page: 'admin.app.b2b-organizations.organization-details',
      params: { id },
    })
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/react/organizations/table.tsx from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { useIntl } from 'react-intl'
import { createColumns, csx, IconEye, Tag, Skeleton } from '@vtex/admin-ui'
import type { TagProps } from '@vtex/admin-ui'

import { organizationMessages as messages } from '../admin/utils/messages'
import { useNavigateToDetailsPage } from './navigate'

interface OrganizationSimple {
  id: string
  name: string
  status: string
}

export const TagVariantByStatus: Record<string, TagProps['variant']> = {
  active: 'green',
  inactive: 'red',
  'on-hold': 'orange',
}

export const useOrgsTableColumns = () => {
  const { formatMessage } = useIntl()
  const navigateToDetailsPage = useNavigateToDetailsPage()

  return createColumns<OrganizationSimple>([
    {
      id: 'name',
      header: formatMessage(messages.tableColumnName),
      width: '3fr',
      resolver: {
        type: 'text',
        columnType: 'name',
        mapText: ({ name }) => name,
        render: ({ data }) => (
          <div className={csx({ minWidth: '10rem' })}>{data}</div>
        ),
      },
      sortable: true,
    },
    {
      id: 'status',
      header: formatMessage(messages.columnStatus),
      resolver: {
        type: 'root',
        render: ({ item, context }) => {
          if (context === 'loading') {
            return <Skeleton className={csx({ height: '1.5rem' })} />
          }

          return (
            <Tag
              label={item.status}
              size="normal"
              variant={TagVariantByStatus[item.status]}
            />
          )
        },
      },
      sortable: true,
    },
    {
      id: 'menu',
      resolver: {
        type: 'menu',
        actions: [
          {
            label: formatMessage(messages.view),
            icon: <IconEye />,
            onClick: ({ id }) => navigateToDetailsPage(id),
          },
        ],
      },
    },
  ])
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/react/organizations/hooks.ts from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { useQuery } from 'react-apollo'

import GET_ORGANIZATIONS from '../graphql/getOrganizations.graphql'

export interface FetchListOptions {
  status: string[]
  search: string
  page: number
  pageSize: number
  sortOrder: 'ASC' | 'DESC'
  sortedBy: string
}

export const INITIAL_FETCH_LIST_OPTIONS: FetchListOptions = {
  status: ['active', 'on-hold', 'inactive'],
  search: '',
  page: 1,
  pageSize: 25,
  sortOrder: 'ASC',
  sortedBy: 'name',
}

export const useOrganizationsList = () => {
  return useQuery(GET_ORGANIZATIONS, {
    variables: INITIAL_FETCH_LIST_OPTIONS,
    ssr: false,
  })
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/react/types/BulkImport.d.ts from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { UploadFinishedData } from '@vtex/bulk-import-ui'

type ImportState =
  | 'InProgress'
  | 'InValidation'
  | 'ReadyToImport'
  | 'Completed'
  | 'ValidationFailed'
  | 'CompletedWithError'
  | 'Failed'

export type ImportResult = {
  name: string
  importedRows: number
  rowsWithError: number
}

export type ImportError = {
  error: 'InvalidFileType' | 'InvalidFileSize' | 'FieldValidationError'
  lineErrors: LineError[]
}

export type LineError = {
  line: number
  displayTitle: string
  errors: FieldError[]
}

export type FieldError = {
  error: 'MissingRequiredField'
  description: string
  column: string
}

export type ImportReportData = {
  title: string
  success: {
    percentage: number
    imports: number
  }
  error: {
    percentage: number
    imports: number
  }
}

export type ImportDetails = {
  importId: string
  accountName: string
  fileName: string
  importResult?: {
    imports: ImportResult[]
    reportDownloadLink: string
  }
  percentage: string
  lastUpdateDate: string
  importState: ImportState
  importedAt: string
  importedUserEmail: string
  importedUserName: string
  validationResult?: {
    reportDownloadLink: string
    validationResult: ValidationResult[]
  }
}

export type UploadFileResult = {
  successCount?: number
  fileData: ImportDetails
}

export type ValidationResult = {
  name: string
  validRows: number
  invalidRows: number
}

export type FieldValidationError = {
  description?: string
  error: 'FieldValidationError'
  errorDownloadLink: string
  validationResult: ValidationResult[]
  fileName?: string
}

export type AnotherImportInProgress = {
  description: string
  error: 'AnotherImportInProgress'
  fileName?: string
}

export type BulkImportUploadError =
  | FieldValidationError
  | AnotherImportInProgress

export type UploadFileData = UploadFinishedData<
  UploadFileResult,
  BulkImportUploadError
>

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/react/css/user-widget.css from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```css
.userWidgetModalTableContainer {
  max-height: 60vh;
  overflow-y: auto;
}
.userWidgetModalRow .col:last-child {
  padding: 1rem;
  background: #F5F4F4;
  display: none;
}
.userWidgetModalRow .col:first-child {
  width: 100%;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}
.userWidgetModalRow {
  max-width: 980px;
  min-height: 800px;
  padding: 0;
  flex-direction: column-reverse;
  justify-content: start;
}
.userWidgetModalTable {
  width: 100%;
  border-spacing: 0;
}
.userWidgetModalTableRow:hover {
  background: #bcbcbc !important;
}
.userWidgetModalTableRowChecked {
  background: #0f3e99!important;
  color: white!important;
  pointer-events: none;
}
.userWidgetModalTableRow {
  margin: 0.75rem 0;
  display: flex;
  justify-content: space-between;
  cursor: pointer;
}
.userWidgetModalTableRow:nth-child(even) {
  background: #F5F4F4;
}
.userWidgetModalTableRow:nth-child(odd) {
  background: #DFDCDC;
}
.userWidgetModalTableCell:first-child {
  display: none;
}
.userWidgetModalTableCell {
  padding: 1rem;
}

.userWidgetModalTableRadio {
  display: none;
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/react/typings/global.d.ts from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```typescript
interface FilterStatement {
  subject: string
  verb: string
  object: Record<string, unknown>
}

interface AddressFormFields {
  [key: string]: {
    value: null | string | number | number[]
    valid?: boolean
    geolocationAutoCompleted?: boolean
    postalCodeAutoCompleted?: boolean
  }
}

interface Address {
  addressId: string
  addressType: string
  addressQuery: string
  postalCode: string
  country: string
  receiverName: string
  city: string
  state: string
  street: string
  number: string
  complement: string
  neighborhood: string
  geoCoordinates: number[]
  reference: string
  checked?: boolean
}

interface MessageDescriptor {
  id: string
  description?: string | Record<string, unknown>
  defaultMessage?: string
  values?: Record<string, unknown>
}

interface UserInput {
  name: string
  email: string
  orgId: string
  costId: string
  roleId: string
}

interface UserDetails {
  id: string
  roleId: string
  userId: string
  clId: string
  orgId: string
  costId: string
  name: string
  email: string
  canImpersonate: boolean
}

interface CustomField {
  name: string
  type: 'text' | 'dropdown'
  value?: string
  dropdownValues?: Array<{ label: string; value: string }>
  useOnRegistration?: boolean
}

interface CustomFieldSetting {
  name: string
  type: 'text' | 'dropdown'
}

interface Window {
  __RUNTIME__: any
}

interface CellRendererProps {
  rowData: Address
  updateCellMeasurements: () => void
}

interface TableState {
  tableLength: number
  currentPage: number
  filteredItems: Address[]
  slicedData: Address[]
  currentItemFrom: number
  currentItemTo: number
  searchValue: string
  itemsLength: number
  emptyStateLabel: string
  filterStatements: unknown[]
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/react/typings/vtex.address-form.d.ts from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module 'vtex.address-form'

declare module 'vtex.address-form/inputs' {
  export const StyleguideInput
  export const GeolocationInput
}

declare module 'vtex.address-form/helpers' {
  export const addValidation
  export const removeValidation
  export const isValidAddress
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/react/typings/graphql.d.ts from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module '*.graphql' {
  import type { DocumentNode } from 'graphql'

  const value: DocumentNode
  export default value
}

declare module '*.gql' {
  import type { DocumentNode } from 'graphql'

  const value: DocumentNode
  export default value
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/react/admin/CustomFields.tsx from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { useEffect, useState } from 'react'
import { useMutation, useQuery } from 'react-apollo'
import { FormattedMessage, useIntl } from 'react-intl'
import { Button, Spinner } from 'vtex.styleguide'
import { useToast, Dropdown, useDropdownState } from '@vtex/admin-ui'

import GET_B2BSETTINGS from '../graphql/getB2BSettings.graphql'
import SAVE_B2BSETTINGS from '../graphql/updateB2BSettings.graphql'
import {
  organizationCustomFieldsMessages as customFieldsMessages,
  organizationSettingsMessages as settingMessage,
  organizationMessages as messages,
} from './utils/messages'
import CustomFieldsTable from './CustomFieldsTable'
import { useOrgPermission } from '../hooks/useOrgPermission'
import { ORGANIZATION_EDIT } from '../utils/constants'

const CustomFields: React.FC = () => {
  /**
   * Hooks
   */
  const { formatMessage } = useIntl()
  const showToast = useToast()

  /**
   * States
   */

  const [activeCustomFields, setActiveCustomFields] = useState<CustomField[]>(
    []
  )

  const [organizationCustomFields, setOrganizationCustomFields] = useState<
    CustomField[]
  >([])

  const [costCenterCustomFields, setCostCenterCustomFields] = useState<
    CustomField[]
  >([])

  const customFieldsLocation = [
    formatMessage(messages.organizationsTitle),
    formatMessage(messages.costCenters),
  ]

  const customFieldsDropdownState = useDropdownState({
    items: customFieldsLocation,
    initialSelectedItem: formatMessage(messages.organizationsTitle),
  })

  const isOrgActive =
    customFieldsDropdownState.selectedItem ===
    formatMessage(messages.organizationsTitle)

  /**
   * Queries
   */
  const { data: b2bSettings, loading: b2bSettingsLoading } = useQuery(
    GET_B2BSETTINGS,
    {
      ssr: false,
    }
  )

  const { data: canEditBuyerOrg } = useOrgPermission({
    resourceCode: ORGANIZATION_EDIT,
  })

  /**
   * Mutations
   */
  const [saveB2BSettingsRequest] = useMutation(SAVE_B2BSETTINGS)

  /**
   * Functions
   */
  const translateMessage = (message: MessageDescriptor) => {
    return formatMessage(message)
  }

  const toastMessage = (
    message: MessageDescriptor,
    type: 'critical' | 'info' | 'positive' | 'warning'
  ) => {
    const translatedMessage = translateMessage(message)

    showToast({ message: translatedMessage, duration: 5000, variant: type })
  }

  const saveB2BSettings = () => {
    const B2BSettingsInput = {
      organizationCustomFields,
      costCenterCustomFields,
    }

    saveB2BSettingsRequest({
      variables: {
        input: B2BSettingsInput,
      },
    })
      .then(() => {
        toastMessage(settingMessage.toastUpdateSuccess, 'positive')
      })
      .catch(() => {
        toastMessage(settingMessage.toastUpdateFailure, 'warning')
      })
  }

  const addCustomField = () => {
    setActiveCustomFields([...activeCustomFields, { name: '', type: 'text' }])
  }

  const removeCustomField = (indexToRemove: number) => {
    // remove item at the provided index
    const customFieldsWithoutLastItem = activeCustomFields.filter(
      (_, index) => index !== indexToRemove
    )

    setActiveCustomFields(customFieldsWithoutLastItem)
    if (isOrgActive) {
      setOrganizationCustomFields(customFieldsWithoutLastItem)
    } else {
      setCostCenterCustomFields(customFieldsWithoutLastItem)
    }
  }

  const handleUpdate = (index: number, customField: CustomField) => {
    // populate activeCustomFields array with values from inputs

    const newCustomFields = [...activeCustomFields]

    newCustomFields[index] = customField
    setActiveCustomFields(newCustomFields)

    if (isOrgActive) {
      setOrganizationCustomFields(newCustomFields)
    } else {
      setCostCenterCustomFields(newCustomFields)
    }
  }

  /**
   * Effects
   */

  const organizationCustomFieldsData =
    b2bSettings?.getB2BSettings?.organizationCustomFields

  const costCenterCustomFieldsData =
    b2bSettings?.getB2BSettings?.costCenterCustomFields

  useEffect(() => {
    if (organizationCustomFieldsData) {
      // in case activeCustomFields comes as null, make an empty array
      setOrganizationCustomFields(organizationCustomFieldsData ?? [])
    }
  }, [organizationCustomFieldsData?.length])

  useEffect(() => {
    if (costCenterCustomFieldsData) {
      setCostCenterCustomFields(costCenterCustomFieldsData ?? [])
    }
  }, [costCenterCustomFieldsData?.length])

  useEffect(() => {
    if (isOrgActive) {
      setActiveCustomFields(organizationCustomFields)
    } else {
      setActiveCustomFields(costCenterCustomFields)
    }
  }, [
    customFieldsDropdownState.selectedItem,
    organizationCustomFields?.length > 0,
    costCenterCustomFields?.length > 0,
  ])

  return (
    <>
      <div className="flex justify-between items-center">
        <Dropdown
          variant="primary"
          items={customFieldsLocation}
          state={customFieldsDropdownState}
          label="Organization or Cost Center"
        />
        <Button
          variation="primary"
          onClick={() => {
            saveB2BSettings()
          }}
          disabled={!canEditBuyerOrg}
        >
          Save Settings
        </Button>
      </div>

      <h4 className="mt6 t-heading-6">
        {formatMessage(customFieldsMessages.customFieldsExplanation)}
      </h4>

      {b2bSettingsLoading ? (
        <Spinner />
      ) : (
        <CustomFieldsTable
          customFields={activeCustomFields}
          handleDelete={removeCustomField}
          handleUpdate={handleUpdate}
        />
      )}

      <div className="mt6 flex flex-row-reverse">
        <Button
          variation="primary"
          onClick={() => addCustomField()}
          disabled={!canEditBuyerOrg}
        />
        <FormattedMessage id="admin/b2b-organizations.custom-fields.addField" />
      </div>
    </>
  )
}

export default CustomFields

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of b2b-organizations/react/admin/CostCenterAddressList.tsx from the b2b-organizations VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { useState, useEffect } from 'react'
import { useIntl, FormattedMessage } from 'react-intl'
import { Table, Toggle } from 'vtex.styleguide'

import { costCenterMessages as messages } from './utils/messages'
import { useOrgPermission } from '../hooks/useOrgPermission'
import { ORGANIZATION_EDIT } from '../utils/constants'

const tableLength = 5

interface AddressListProps {
  addressList: Address[]
  handleNewAddressModal: () => void
  handleCheckDefault: (address: Address) => void
  handleEditAddressModal: (addressId: string) => void
  handleDeleteAddressModal: (addressId: string) => void
}

const CostCenterAddressList: React.FC<AddressListProps> = ({
  addressList,
  handleCheckDefault,
  handleNewAddressModal,
  handleEditAddressModal,
  handleDeleteAddressModal,
}) => {
  const { formatMessage } = useIntl()

  const {
    data: canEditBuyerOrg,
    isLoading: permissionLoading,
  } = useOrgPermission({
    resourceCode: ORGANIZATION_EDIT,
  })

  const initialState: TableState = {
    tableLength,
    currentPage: 1,
    filteredItems: addressList,
    slicedData: addressList.slice(0, tableLength),
    currentItemFrom: 1,
    currentItemTo: tableLength,
    searchValue: '',
    itemsLength: addressList.length,
    emptyStateLabel: formatMessage(messages.nothingToShow),
    filterStatements: [],
  }

  const [state, setState] = useState<TableState>(initialState)
  const jsonschema = {
    properties: {
      street: {
        title: formatMessage(messages.address),
        cellRenderer: ({ rowData }: CellRendererProps) => {
          return `${rowData.street}, ${rowData.city}, ${rowData.state}, ${rowData.postalCode}`
        },
      },
      receiverName: {
        title: formatMessage(messages.receiverName),
        cellRenderer: ({ rowData }: CellRendererProps) => {
          try {
            const receiver = JSON.parse(rowData?.receiverName)
            const strings = Object.keys(receiver).map(
              (key: string) => receiver[key]
            )

            return strings.join(' - ')
          } catch (e) {
            return rowData?.receiverName
          }
        },
      },
      checked: {
        title: formatMessage(messages.defaultAddress),
        width: 150,
        cellRenderer: ({ rowData }: CellRendererProps) => {
          return (
            <Toggle
              onChange={() => {
                handleCheckDefault(rowData)
              }}
              checked={rowData.checked}
            />
          )
        },
      },
    },
  }

  useEffect(() => {
    if (addressList?.length > 0) {
      setState(prevState => ({
        ...prevState,
        filteredItems: addressList,
        slicedData: addressList.slice(0, tableLength),
        itemsLength: addressList.length,
      }))
    }
  }, [addressList])

  const filterItems = (searchValue: string) => {
    if (!searchValue) {
      return addressList
    }

    const regex = new RegExp(searchValue, 'i')

    return addressList.filter((item: Address) => {
      return (
        regex.test(item.postalCode) ||
        regex.test(item.country) ||
        (typeof item.receiverName === 'string' &&
          regex.test(item.receiverName)) ||
        regex.test(item.city) ||
        regex.test(item.state) ||
        regex.test(item.street) ||
        (item.complement && regex.test(item.complement)) ||
        (item.neighborhood && regex.test(item.neighborhood)) ||
        (item.reference && regex.test(item.reference))
      )
    })
  }

  const handleRowsChange = (_: unknown, value: string) => {
    const newTableLength: number = parseInt(value, 10)

    setState({
      ...state,
      tableLength: newTableLength,
      currentPage: 1,
      currentItemFrom: 1,
      currentItemTo: Math.min(newTableLength, state.filteredItems.length),
      slicedData: state.filteredItems.slice(0, newTableLength),
    })
  }

  const handleInputSearchSubmit = (e: { target: { value: string } }) => {
    const searchValue = e?.target?.value
    const filteredItems = filterItems(searchValue)

    setState({
      ...state,
      searchValue,
      filteredItems,
      slicedData: filteredItems.slice(0, state.tableLength),
      itemsLength: filteredItems.length,
    })
  }

  const handleNextClick = () => {
    const newPage = state.currentPage + 1
    const itemFrom = state.currentItemTo + 1
    const itemTo = Math.min(
      itemFrom + state.tableLength - 1,
      state.filteredItems.length
    )

    setState({
      ...state,
      currentPage: newPage,
      currentItemFrom: itemFrom,
      currentItemTo: itemTo,
      slicedData: state.filteredItems.slice(itemFrom - 1, itemTo),
    })
  }

  const handlePrevClick = () => {
    if (state.currentPage === 1) return

    const newPage = state.currentPage - 1
    const itemFrom = state.currentItemFrom - state.tableLength
    const itemTo = state.currentItemFrom - 1

    setState({
      ...state,
      currentPage: newPage,
      currentItemFrom: itemFrom,
      currentItemTo: itemTo,
      slicedData: state.filteredItems.slice(itemFrom - 1, itemTo),
    })
  }

  const lineActions =
    canEditBuyerOrg && !permissionLoading
      ? [
          {
            label: () => `${formatMessage(messages.addressEdit)}`,
            onClick: ({ rowData }: CellRendererProps) => {
              handleEditAddressModal(rowData.addressId)
            },
          },
          {
            label: () => formatMessage(messages.addressDelete),
            isDangerous: true,
            onClick: ({ rowData }: CellRendererProps) => {
              handleDeleteAddressModal(rowData.addressId)
            },
          },
        ]
      : []

  const onClearHandle = () => {
    const filteredItems = filterItems('')

    setState({
      ...state,
      searchValue: '',
      filteredItems,
      slicedData: filteredItems.slice(0, state.tableLength),
      itemsLength: filteredItems.length,
    })
  }

  return (
    <Table
      fullWidth
      schema={jsonschema}
      items={state.slicedData}
      emptyStateLabel={state.emptyStateLabel}
      toolbar={{
        inputSearch: {
          value: state.searchValue,
          placeholder: formatMessage(messages.searchAddress),
          onChange: (e: { target: { value: string } }) =>
            setState({ ...state, searchValue: e.target.value }),
          onClear: onClearHandle,
          onSubmit: handleInputSearchSubmit,
        },
        newLine: {
          label: (
            <FormattedMessage id="admin/b2b-organizations.costCenter-details.address.new" />
          ),
          handleCallback: () => {
            handleNewAddressModal()
          },
          disabled: !canEditBuyerOrg || permissionLoading,
        },
      }}
      pagination={{
        onNextClick: handleNextClick,
        onPrevClick: handlePrevClick,
        currentItemFrom: state.currentItemFrom,
        currentItemTo: state.currentItemTo,
        onRowsChange: handleRowsChange,
        textShowRows: formatMessage(messages.showRows),
        textOf: formatMessage(messages.of),
        totalItems: state.itemsLength,
        rowsOptions: [5, 10, 15, 25],
      }}
      lineActions={lineActions}
      onRowClick={() => {}}
    />
  )
}

export default CostCenterAddressList

```