UI Kit - React.js integration

Embeddable UI components

The Amberflo UI Kit is a React component library for our customers to be able to consume and make use of principal Amberflo views, for one of their customers, on their own site.

UI Kit components are responsible of making the API calls. To use them you just first need to import the components into your app.

Installation

Run yarn add @amberflo/uikit or npm install @amberflo/uikit to install Amberflo UI Kit in your React project.

📘

Technologies

React v17.0.2
Node v16.13.1
Typescript v4.5.5


Available Versions

All versions can be found on npm repository: @amberflo/uikit


Getting Started

Amberflo Provider

The AmberfloProvider is a Provider component that needs to wrap your app, so the components can hit our API. It requires a customer-specific session and a theme. You can check here how to:

<AmberfloProvider
  session="<YOUR_SESSION_ID>"
  theme={{
    barndColor: "<YOUR_BRAND_COLOR>",
    fontSize: <DEFAULT_FONT_SIZE>,
    fontfamily: "<DEFAULT_FONT_FAMILY>"
  }}
>
  ...
</AmberfloProvider>

Imports

To import a single Amberflo UI Kit component into your application (Recommended):

import { CostExplorerBarGraph } from "@amberflo/uikit/compnents/organisms/CostExplorerBarGraph";
import { InvoicesList } from '@amberflo/uikit/components/organisms/InvoiceList'

This will allow to perform tree-shaking so unused components will be dropped from the final bundle that will weight less and load faster.

📘

To make this possible the bundler needs to allow tree shaking.

To import multiple components from the root:

import { CostExplorerBarGraph, InvoicesList } from "@amberflo/ui-kit";

📘

Notice tree shaking won’t be effective if you use this approach.


Theming

To customize the AmberfloProvider above with the theme, we expect this object in the theme prop:

{
  brandColor: string // it can be hex, or color name
  fontSize: number // Basic font size, all rest of font sizes will scale dynamically to this value
  fontFamily: string // name of the font to use. The font must be available on your site. Or you can use a custom font as showed below.
  customFontUrl: string // google font url to import to your site
}

Common Props

There are a few props that are supported by all views:

NameTypeDescription
withTitlebooleanIf true, will show the widget title (If the container is enabled) see below
withContainerbooleanIf true, a container wrapper will show around the widget
titlestringCustom title for the block
hideLoaderbooleanIf true, Loader won’t show while loading. Useful if you are showing many components with the same data, and you want a single loader. Or to use your own custom loader
callToAction{ text?: string | JSX.Element; onClick?: () => void; type?: "add" | "disabledAdd" | "remove" | "deleteAll"; noIcon?: boolean; disabled?: boolean; }Shows a button link on the title of container, that can be attached any action
onError(error) => voidA event called when there was some kind of error with the component. So it can show the error to customer
onLoadingChange(isLoading: boolean) => voidAn event called each time the component switches the status of loading. So you can show your own loading for instance.

Also, there are a few props that are supported by all views that has a date picker. This views are:

This are the allowed props:

NameTypeDefaultDescription
startDatenumberCurrent day minus 7 daysDefault value for the start date on the date picker.
periodValue"daily" | "weekly" | "monthly"dailyDefault value for the date picker value.
onPeriodChange(period: string) => voidundefinedFunction to be called when period is changed
onDateChange(startDate: number, endDate: number) => voidundefinedFunction to be called when date is changed
endDatenumberCurrent DayDefault value for the end date on the date picker.
withDatePickerbooleantrueIf false, DatePicker will be hidden.

Types

Amberflo UI Kit is heavily typed, which will allow, if you use typescript on your project, to easily see which kind of properties a component receives, or what would return a specific function or hook.


Hooks

We provide a few hooks to access the same data we show on our components, in case you need to render your own component. All hooks can be imported from:

import { ... } from '@amberflo/uikit/hooks`

Available hooks are:

useCost = (startDate: number, endDate: number, period: string) => { data: CostResponse, isFetching: boolean }

useCurrentPricingPlan = () => { data: PricingPlanResponse, isFetching: boolean, handleSelectPlan: (pricingPlanId: string) => void }

useInvoiceDetails = (invoiceDate: string) => { data: InvoiceType, isFetching: boolean }

useInvoices = () => { data: InvoiceType[], isFetching: boolean }

useMeters = () => { data: Meter[], isFetching: boolean }

usePrepaidSummary = () => { data: PrepaidItem[], isFetching: boolean }

useStripeClientSecret = () => { data: string, isFetching: boolean }

useUsage = (meters: string[], startDate: number, endDate: number, period: string, groupBy?: string) => { data: UsageResponse[], isFetching: boolean }


Available Views

Cost Explorer Bar Graph

17141714

How to import:

import { CostExplorerBarGraph } from "@amberflo/uikit/components/organisms/CostExplorerBarGraph";

Available Props

There are a few extra props, that are common for all components, and are listed here: ReactJS Integration | Common Props

Prop NameTypeDefaultDescription
customGraphOptionsRecord<string, Record<string, string>>undefinedIf defined, customGraphOptions will overwrite the default graph options for the Cost bar graph.

At the moment, the customGraphOptions will replace the top level key/values. For example, if the default options are:



{ option1: { value1: "test", value2: "test" }, option2: { value1: "test" } }

and you pass customGraphOptions of:
{ option1: { value3: "test" } }

You will end up with:

{ option1: { value3: "test", }, option2: { value1: "test" } }



Cost Table

932932

How to import:

import { CostExplorerTable } from '@amberflo/uikit/components/organisms/CostExplorerTable'

Available Props

There are no specific props for this view. There are a few extra props, that are common for all components, and are listed here: ReactJS Integration | Common Props




Invoice Details

16611661

How to import:

import { InvoiceDetails } from '@amberflo/uikit/components/organisms/InvoiceDetails'

Available Props

There are a few extra props, that are common for all components, and are listed here: ReactJS Integration | Common Props

Prop NameTypeDefault ValueDescription
dimensionsMapRecord<string, Record<string, string>>undefinedAn object containing the dimension name as key, and another object as value, containing the dimension value and the new dimension name to be replaced with.

For instance if you have a dimension called availability_zone, with a value of dim1, and you want to see it as Dimension 1, you can pass an object like this:

dimensionsMap={{ availability_zone: { dim1: "Dimension 1" } }}

This will apply to dimensions on graph, and to dimension selector on top.
invoiceDatestringundefinedDate of the invoice to show on UTC and in format l
hideBreakdownbooleanfalseHide invoices details breakdown



Invoices List

18821882

How to import:

import { InvoicesList } from '@amberflo/uikit/components/organismsInvoiceList'

Available Props

There are a few extra props, that are common for all components, and are listed here: ReactJS Integration | Common Props

Prop NameTypeDefault ValueDescription
onRowClick(invoice: Invoice) => nullundefinedData for the invoice clicked



Prepaid Summary Graph

13801380

How to import:

import { PrepaidSummaryGraph } from '@amberflo/uikit/PrepaidSummaryGraph'

Available Props

There are no specific props for this view. There are a few extra props, that are common for all components, and are listed here: ReactJS Integration | Common Props




Prepaid Summary Table

18141814

How to import:

import { PrepaidSummaryTable } from '@amberflo/uikit/PrepaidSummaryTable'

Available Props

There are no specific props for this view. There are a few extra props, that are common for all components, and are listed here: ReactJS Integration | Common Props




Pricing Plan

561561

How to import:

import { PricingPlan } from '@amberflo/uikit/PricingPlan'

Available Props

There are a few extra props, that are common for all components, and are listed here: ReactJS Integration | Common Props

Prop NameTypeDefault ValueDescription
pricestring""Text to show under the title
titlestring""Title of pricing plan
productItemsstring[][]Array un strings to show as product items
pricingPlanId*stringundefinedId of the pricing plan, to call correct endpoints
onClick(pricingPlanId: string) => voidundefinedFunction to be called when button is pressed



Usage Graph

17681768

How to import:

import { UsageByMeterLineGraph } from '@amberflo/uikit/components/organisms/UsageByMeterLineGraph'

Available Props

There are a few extra props, that are common for all components, and are listed here: ReactJS Integration | Common Props

Prop NameTypeDefault ValueDescription
meterstring""Meter ApiName of the meter to show on the graph
dimensionsMapRecord<string, string>undefinedAn object to map dimensions to a new name.

For instance if you have a dimension called 'Dim1' and want to show dimension 1 instead, you can pass this prop as

dimensionsMap={{ dim1: 'Dimension 1' }}

If the value set on the object for a specific dimension is null. The dimension won’t show on the dimension selector.
customGraphOptionsRecord<string, Record<string, string>>undefinedIf defined, customGraphOptions will overwrite the default graph options for the Usage Graph.



At the moment, the customGraphOptions will replace the top level key/values. For example, if the default options are:

{ option1: { value1: "test", value2: "test" }, option2: { value1: "test" } }

and you pass customGraphOptions of:

{ option1: { value3: "test" } }

You will end up with:

{ option1: { value3: "test", }, option2: { value1: "test" } }
onDimensonsChange`(dimension: string) => voidundefinedFunction to be called when a dimension is selected using the dimension selector.
withDimensionsSelectorboolean | undefinedundefinedIf true, will enable the dimensions selector to be shown. In addition to this, additional props must be provided to display the selector including a list of dimensions and an onDimensionChange handler.
dimensionstringundefinedIf set, we will group by this dimension.
onMeterChange(meter: string) => voidundefinedFunction to be called when the meter is selected using the dimension selector.
withMeterSelectorboolean | undefinedundefinedIf true, will enable the meter selector to be shown
hideDeprecatedMetersbooleanundefinedIf true, deprecated meters won’t show on the graph
dimensionSelectorListstring[] | undefinedundefinedA list of available dimensions to show on the dimension selector. Only this dimensions will be shown there. To see all available dimensions, do not send this prop.



Usage Table

931931

How to import:

import { UsageByMeterTable } from '@amberflo/uikit/components/organisms/UsageByMeterTable'

Available Props

There are a few extra props, that are common for all components, and are listed here: ReactJS Integration | Common Props

Prop NameTypeDefault ValueDescription
meterApiNamesstring[][]List of meter api names to show on the table
onRowClick(row: Row) => void;undefinedonRowClick is a function. If defined, the onRowClick function will be invoked when clicking on a row of the table. The onRowClick function will receive a Row type object as an argument.



Stripe Setup Intent

20702070

How to import:

import { StripeSetupIntent } from '@amberflo/uikit/components/organisms/StripeSetupIntent'

Available Props

There are a few extra props, that are common for all components, and are listed here: ReactJS Integration | Common Props

Prop NameTypeDefault ValueDescription
publishableKey*stringundefinedPublishable key you can get from stripe. You can see how here
buttonTextstring"Submit"Text to show on the button
returnUrlstringundefinedURL where to go after payment method is saved
showTermsbooleantrueIf true, you allow stripe to show terms below the payment form. In the above image, it is above the Cancel and Submit button
onCancel() => voidundefinedonCancel should be a function. If an onCancel function is passed, a Cancel button will appear and invoke the onCancel function when clicked.

How To Get Secret Key From Stripe

Call this endpoint:

📘

POST

https://app.amberflo.io/customer-portal/setup-intent

Payload:

{
     "provider": "stripe"
}

Response Body:

{
    "id": "seti_1LIBSbFZnIN3GxYXnNiuvLGe",
    "clientSecret": "seti_3MKDTdHBpKP5IzAZpNiuvLGe_secret_M0BqOmOj5LWcKZ910nPEzRCy1wFfe8M"
}

How to make a payment the default payment method

  1. After creating a new payment method, you’ll get redirected to a new URL with some query string parameters. There is one called setup_intent_client_secret.

  2. You need to retrieve the payment method from Stripe, by running:
    const { setupIntent } = await stripe.retrieveSetupIntent(setupIntentClientSecret);

  3. Submit the payment method to endpoint to set as default payment method:

📘

POST

https://app.amberflo.io/customer-portal/payment-method

Payload

{
  provider: "stripe",
  paymentMethodId: <Payment method ID from Stripe>,
}