Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Set Up

Sync Data from MDM

The first change from our current implementation is to expect all nutrition info to come from MDM. Instead of calculating a per-weight or per-volume value for a given nutrient, that data will be stored in Sanity and will come directly from MDM. How the data is synced is outside the scope of this design review.

The relevant part to understand is that there will now be a row of data keyed by calories and a new row of data keyed by caloriesPer100. If the app is configured to show a table of "Per 100g/100ml" values, it will source that information from the new rows of data with a key like caloriesPer100.

New Sanity Schemas

The following subsections will roughly describe new schemas to support Nutrition 2.0. Keep in mind that the goal of the new configuration will be to give franchisee owners the ability to configure nutrition information in a way that meets legal requirements in their country.

Nutrition Feature

The nutrition 2.0 configuration object will live in a feature singleton. Using a feature singleton makes it easy to cache the information and manage the state.

...

Code Block
{
  title: 'Feature Nutrition 2.0',
  name: 'featureNutrition2.0',
  description: 'App-wide nutrition information configuration',
  type: 'document',
  fields: [
    {
      name: 'nutritionTables',
      title: 'Nutrition Tables',
      description: 'The list of tables that contain per-item nutrition information',
      type: 'array',
      of: [{ type: 'nutritionTable' }],
    }
  ]
}
Nutrition Table

In the UK, the nutrition info modal displays two tables: "Per serving" and "Per 100g or ml". In the US, we only display per-serving nutrition info. We want to support one or more tables. Each table will be represented by an object that looks like this:

Code Block
{
  title: 'Nutrition Table',
  name: 'nutritionTable',
  description: 'Nutrition items (or groups of nutrition items) to show in a given nutrition table',
  type: 'object',
  fields: [
    {
      title: 'Title',
      description: 'The title of the nutrition table, e.g. Per Serving',
      name: 'title',
      type: 'localeString',
      validation: (Rule) => Rule.required(),
    },
    {
      title: 'Items',
      description: 'The items or groups of items that will be shown the table',
      name: 'items',
      type: 'array',
      of: [{ type: 'nutritionItemGroup' }, { type: 'nutritionItem' }],
      validation: (Rule) => Rule.required().min(1),
    }
  ]
}
Nutrition Item Group

We need a way to tell the UI that items should be grouped together. Imagine a UI like:

...

Code Block
{
  title: 'Nutrition Item Group',
  name: 'nutritionItemGroup',
  description: 'Group of nutrition items that will be displayed displayed as a main item with sub-items',
  type: 'object',
  fields: [
    {
      title: 'Main Item',
      description: 'The main nutrition item',
      name: 'mainItem',
      type: 'nutritionItem',
      validation: (Rule) => Rule.required()
    },
    {
      title: 'Line Items',
      description: 'The items that will be displayed below the main item',
      name: 'lineItems',
      type: 'array',
      of: [{ type: 'nutritionItem' }],
      validation: (Rule) => Rule.required().min(1),
    },
  ]
}
Nutrition Item

The final piece of the puzzle is the Nutrition Item. This schema must support:

...