Logo

InfoCards

The Dashboard page opens with a set of infocards. Here is a simplified version of two of them.
<App>
  <variable name="dashboardStats" value="{
    {
      value:
        [
          { outstanding: 3569, paid_this_year: 1745}
        ]
    }
  }" />

<HStack>
  <Card>
      <Text>Outstanding</Text>
      <Text>{ dashboardStats.value[0].outstanding } </Text>
  </Card>
  <Card>
      <Text>Paid this year</Text>
      <Text>{ dashboardStats.value[0].paid_this_year } </Text>
  </Card>
</HStack>
</App>
<App>
  <variable name="dashboardStats" value="{
    {
      value:
        [
          { outstanding: 3569, paid_this_year: 1745}
        ]
    }
  }" />

<HStack>
  <Card>
      <Text>Outstanding</Text>
      <Text>{ dashboardStats.value[0].outstanding } </Text>
  </Card>
  <Card>
      <Text>Paid this year</Text>
      <Text>{ dashboardStats.value[0].paid_this_year } </Text>
  </Card>
</HStack>
</App>
In the app, dashboardStats is a DataSource.
<DataSource id="dashboardStats" url="/api/dashboard/stats" method="GET" />
It returns a structure like the variable we've defined above: an object with a value key that points to a list of objects corresponding to rows in the database. In this case there's only one row because the query behind /api/dashboard/stats reports multiple values (count of invoices, total amount outstanding, total amount paid this year, etc) as columns in that single row.

A custom Card

There are five infocards on the XMLUI Invoice dashboard. To style them all in a consistent way, the app defines an InfoCard that wraps Card and Text.
<Component name="InfoCard">

    <Card width="{$props.width}" borderRadius="8px" boxShadow="$boxShadow-spread">

        <Text>{$props.title}</Text>

        <Text fontWeight="$fontWeight-extra-bold" fontSize="larger">
            { $props.currency === 'true' ? '$' + $props.value : $props.value }
        </Text>
    </Card>

</Component>
These are in turn wrapped in a Dashboard that passes properties to InfoCard: title, width, value, and optionally a currency flag for $ formatting.
<Component name="Dashboard">

  <DataSource id="dashboardStats" url="/api/dashboard/stats" method="GET"/>

  <HStack>
    <H1>Dashboard</H1>
    <SpaceFiller/>
    <Button label="Create Invoice" onClick="navigate('/invoices/new')"/>
  </HStack>

  <FlowLayout>
    <InfoCard
      width="20%"
      title="Outstanding"
      value="{ dashboardStats.value[0] }"
      currency='true'
    />
    <InfoCard
      ...
    />
    <InfoCard
      ...
    />
    <InfoCard
      ...
    />
    <InfoCard
      ...
    />

    <Statuses width="50%" title="Statuses"/>

    <MonthlyStatus width="50%" title="Monthly Status"/>

  </FlowLayout>

  <DailyRevenue title="Daily Revenue"/>

</Component>
A user-defined component like Dashboard can define any set of names and values. InfoCard receives them in its $props context variable. InfoCard is opinionated about borderRadius and boxShadow. It could also receive these in $props but chooses not to. And while it is strongly opinionated about the borderRadius, which it hardcodes, it is willing to use the theme variable $boxShadow-spread so that setting can be theme-governed.
Here's a more complete version of the row of InfoCards used in the Invoices app.
<App>
  <Dashboard />
</App>
<App>
  <Dashboard />
</App>
This site is an XMLUI™ app.