Display Micro Progress

Display Micro nutrients progress using nutrients from PassioFoodItem and PassioRecipe.

Example

Obtain the utility function for fetching nutrition from the provided page.

Utils PassioNutrient

MicrosView

import React from 'react';
import { View } from 'react-native';
import { FlatList } from 'react-native';
import { unitForNutrient } from '../../../models';
import { microItemStyle } from './microView.styles';
import { useMicroNutrients, type MicroNutrition } from './useMicroNutrients';
import { Text } from 'react-native';

const MicrosView = () => {
  // Fetch micro-nutrition data using the custom hook
  const { microNutrition } = useMicroNutrients();

  // Render function for each micro-nutrient item
  const renderMicroItem = (micro: MicroNutrition) => {
    const { title, recommended, achieved } = micro;
    const unit = unitForNutrient(micro.id);

    // Set userAchieved to 0 if achieved is null or undefined
    const userAchieved =
      achieved !== null && achieved !== undefined ? achieved : 0;

    // Calculate remaining micro-nutrient value
    const remain = Math.max(0, recommended - userAchieved);

    return (
      <View>
        <View style={microItemStyle.infoContainer}>
          <Text style={microItemStyle.title}>
            {`${title} `}
            <Text
              style={microItemStyle.achieved}
            >{`${userAchieved.toFixed(2)} ${unit}`}</Text>
          </Text>
          <View style={microItemStyle.recommendedContainer}>
            <Text style={microItemStyle.recommendedValue}>
              {`${Math.round(remain).toFixed(2)} ${unit}`}
            </Text>
            <Text style={microItemStyle.remainingText}>{'Remaining'}</Text>
          </View>
        </View>
        <View style={microItemStyle.progressContainer}>
          <View
            style={[
              { flex: Math.round(userAchieved) },
              microItemStyle.progress,
            ]}
          />
          <View style={{ flex: Math.round(remain) }} />
        </View>
      </View>
    );
  };

  return (
    <FlatList
      data={microNutrition}
      contentContainerStyle={microItemStyle.list}
      renderItem={({ item }: { item: MicroNutrition }) => renderMicroItem(item)}
      keyExtractor={(__: MicroNutrition, index: number) => index.toString()}
      extraData={microNutrition}
    />
  );
};

// Wrap the MicrosView component with the withLoading higher-order component
export default MicrosView;

export const microItemStyle = StyleSheet.create({
  infoContainer: {
    flexDirection: 'row',
    paddingVertical: 8,
    alignItems: 'center',
  },
  title: {
    color: COLORS.grey7,
    paddingStart: 16,
    fontSize: 15,
    flex: 1,
    fontWeight: '600',
    alignItems: 'center',
  },
  achieved: {
    color: "gray",
    paddingHorizontal: 8,
    fontSize: 15,
    fontWeight: '400',
    alignItems: 'center',
  },
  remainingText: {
    color: "gray",
    fontWeight: '400',
    paddingHorizontal: 8,
    alignItems: 'center',
  },
  recommendedContainer: {
    flexDirection: 'row',
    alignItems: 'center',
  },
  recommendedValue: {
    minWidth: 70,
    color: "gray",
    alignSelf: 'center',
    alignItems: 'center',
    textAlign: 'center',
    fontWeight: '600',
    borderRadius: 28,
    padding: 4,
  },
  progressContainer: {
    flex: 1,
    backgroundColor: "gray",
    height: 10,
    flexDirection: 'row',
    marginHorizontal: 16,
    borderRadius: 16,
  },
  progress: {
    backgroundColor: "blue",
    borderRadius: 16,
  },
  list: {
    paddingBottom: 50,
  },
});

useMicroNutrients

import { useEffect, useState } from 'react';
import {
  getNutrientsFromAttribute,
  mergeNutrients,
  micros,
  type Nutrients,
  type NutrientsTypes,
} from '../../../utils/PassioNutrient';
import { mockFood } from '../macro/mockFood';
import { PassioSDK } from '@passiolife/nutritionai-react-native-sdk-v2';

export interface MicroNutrition {
  recommended: number;
  title: string;
  id: NutrientsTypes;
  achieved?: number;
}

export const useMicroNutrients = () => {
  // State to store micro-nutrition data
  const [microNutrition, setMicroNutrition] = useState<MicroNutrition[]>([]);

  // Food logs from mock data
  const foodLogs = mockFood;

  useEffect(() => {
    // Function to initialize and fetch micro-nutrition data
    async function init() {
      // Array to store micro-nutrient data
      let data: Nutrients[] = [];

      // Iterate through food logs to fetch attributes and extract micro-nutrients
      await Promise.all(
        foodLogs.map(async (item) => {
          const attribute = await PassioSDK.getAttributesForPassioID(
            item.passioID
          );

          // If attributes are available, extract micro-nutrients
          if (attribute) {
            const nutrients = getNutrientsFromAttribute(attribute, micros);
            data.push(...nutrients);
          }
        })
      );

      // Merge the micro-nutrient data
      data = mergeNutrients(data);

      // Define default micro-nutrients with recommended values
      const defaultMicroNutrients: MicroNutrition[] = [
        {
          title: 'dietaryFiber',
          id: 'fiber' as const,
          recommended: 28,
        },
        {
          title: 'sugar',
          id: 'sugar' as const,
          recommended: 50,
        },
        {
          id: 'saturatedFat' as const,
          title: 'SaturatedFat',
          recommended: 20,
        },
        {
          id: 'transFat' as const,
          title: 'transFat',
          recommended: 0,
        },
        {
          id: 'polyunsaturatedFat' as const,
          title: 'polyunsaturatedFat',
          recommended: 22,
        },
        {
          id: 'monounsaturatedFat' as const,
          title: 'monounsaturatedFat',
          recommended: 44,
        },
        {
          id: 'cholesterol' as const,
          title: 'cholesterol',
          recommended: 300,
        },
        {
          title: 'sodium',
          id: 'sodium' as const,
          recommended: 2300,
        },
        {
          id: 'potassium' as const,
          title: 'potassium',
          recommended: 4700,
        },
        {
          id: 'iron' as const,
          title: 'iron',
          recommended: 18,
        },
        {
          id: 'magnesium' as const,
          title: 'magnesium',
          recommended: 420,
        },
        {
          id: 'iodine' as const,
          title: 'iodine',
          recommended: 150,
        },
        {
          id: 'vitaminA' as const,
          title: 'vitaminA',
          recommended: 900,
        },
        {
          id: 'vitaminB6' as const,
          title: 'vitaminB6',
          recommended: 1.7,
        },
        {
          id: 'vitaminB12' as const,
          title: 'vitaminB12',
          recommended: 2.4,
        },
        {
          id: 'vitaminC' as const,
          title: 'vitaminC',
          recommended: 90,
        },
        {
          id: 'vitaminD' as const,
          title: 'vitaminD',
          recommended: 20,
        },
        {
          id: 'vitaminE' as const,
          title: 'vitaminE',
          recommended: 15,
        },
      ].map((item) => ({
        ...item,
        // Calculate achieved value by filtering the micro-nutrient data
        achieved: data.find(
          (allNutrimentItem) => allNutrimentItem.name === item.id
        )?.unitMass?.value,
      }));

      // Update the state with the processed micro-nutrient data
      setMicroNutrition(defaultMicroNutrients);
    }

    // Call the init function
    init();
  }, [foodLogs]); // Re-run the effect when foodLogs change

  // Return the micro-nutrition data
  return {
    microNutrition,
  };
};

Result

Last updated