Skip to main content

Components

The mobile app uses a set of reusable React Native components for a consistent user experience.

Component Hierarchyโ€‹

ImageCaptureโ€‹

Camera interface for capturing ingredient labels.

Usageโ€‹

<ImageCapture
onCapture={(base64Image) => handleCapture(base64Image)}
onCancel={() => setShowCamera(false)}
/>

Propsโ€‹

PropTypeDescription
onCapture(base64: string) => voidCalled with captured image
onCancel() => voidCalled when user cancels

Featuresโ€‹

  • Real-time camera viewfinder
  • Tap-to-capture
  • Gallery image selection
  • Automatic orientation handling
  • Base64 image encoding

Implementation Notesโ€‹

// Camera capture
const takePicture = async () => {
if (cameraRef.current) {
const photo = await cameraRef.current.takePictureAsync({
base64: true,
quality: 0.8,
});
onCapture(photo.base64);
}
};

// Gallery selection
const pickImage = async () => {
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
base64: true,
quality: 0.8,
});

if (!result.canceled && result.assets[0].base64) {
onCapture(result.assets[0].base64);
}
};

IngredientCardโ€‹

Expandable card showing ingredient safety details.

Usageโ€‹

<IngredientCard ingredient={ingredientDetail} />

Propsโ€‹

PropTypeDescription
ingredientIngredientDetailIngredient data object

Displaysโ€‹

Collapsed View:

  • Ingredient name with safety score
  • Color-coded safety bar
  • Purpose tag
  • Expand/collapse arrow

Expanded View:

  • Full purpose description
  • Origin (Natural/Synthetic)
  • Concerns (if any)
  • Recommendation badge (SAFE/CAUTION/AVOID)
  • Category and Allergy Risk
  • Safer alternatives

Visual Designโ€‹

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ โš ๏ธ Fragrance 4/10 โ— โ”‚
โ”‚ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘ โ”‚
โ”‚ Scent, masking agent โ–ผ โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ PURPOSE โ”‚
โ”‚ Provides scent, masks other odors โ”‚
โ”‚ โ”‚
โ”‚ ORIGIN โ”‚
โ”‚ Synthetic โ”‚
โ”‚ โ”‚
โ”‚ CONCERNS โ”‚
โ”‚ Common allergen, may cause... โ”‚
โ”‚ โ”‚
โ”‚ RECOMMENDATION โ”‚
โ”‚ [CAUTION] โ”‚
โ”‚ โ”‚
โ”‚ Category: Cosmetics Allergy: High โ”‚
โ”‚ โ”‚
โ”‚ SAFER ALTERNATIVES โ”‚
โ”‚ [fragrance-free] [essential oils] โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Score Visualizationโ€‹

ScoreColorEmoji
8-10Green (#22c55e)โœ“
6-7Light Green (#84cc16)โ—
4-5Amber (#f59e0b)โ—
1-3Red (#ef4444)!

ProfileSelectorโ€‹

User profile configuration with theme toggle.

Usageโ€‹

<ProfileSelector
profile={userProfile}
onProfileChange={setUserProfile}
/>

Propsโ€‹

PropTypeDescription
profileUserProfileCurrent profile state
onProfileChange(profile: UserProfile) => voidProfile update handler

Settingsโ€‹

  • Dark/Light mode toggle
  • Known allergies (multi-select):
    • Fragrance, Sulfates, Parabens
    • Formaldehyde, Peanut, Tree Nut
    • Milk/Dairy, Soy, Wheat/Gluten
    • Egg, Shellfish
  • Skin type (single select):
    • Normal, Dry, Oily, Combination, Sensitive
  • Explanation style:
    • Simple (beginner)
    • Technical (expert)

UI Layoutโ€‹

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Your Profile โœ• โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Appearance โ”‚
โ”‚ โ˜€๏ธ Light ๐ŸŒ™ Dark [โ—โ”โ”โ”โ—‹] โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Known Allergies โ”‚
โ”‚ [Fragrance โœ“] [Sulfates] [Parabens] โ”‚
โ”‚ [Peanut] [Tree Nut โœ“] [Milk/Dairy] โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Skin Type โ”‚
โ”‚ โ—‹ Normal โ—‹ Dry โ— Sensitive โ”‚
โ”‚ โ—‹ Oily โ—‹ Combination โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Explanation Style โ”‚
โ”‚ โ— Simple (beginner) โ”‚
โ”‚ โ—‹ Technical (expert) โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

ResultsHeaderโ€‹

Analysis summary with overall risk assessment.

Usageโ€‹

<ResultsHeader
productName="CeraVe Moisturizer"
overallRisk="low"
averageSafetyScore={8.2}
ingredientCount={12}
allergenWarnings={[]}
/>

Propsโ€‹

PropTypeDescription
productNamestringAnalyzed product name
overallRiskRiskLevelOverall risk assessment
averageSafetyScorenumberAverage score (1-10)
ingredientCountnumberTotal ingredients
allergenWarningsstring[]Allergen warning messages

Visual Designโ€‹

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ CeraVe Moisturizer โ”‚
โ”‚ โ”‚
โ”‚ Overall Risk: LOW โ”‚
โ”‚ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–‘โ–‘โ–‘โ–‘ 8.2/10 โ”‚
โ”‚ โ”‚
โ”‚ 12 Ingredients Analyzed โ”‚
โ”‚ โ”‚
โ”‚ โš ๏ธ 1 Allergen Warning โ”‚
โ”‚ Fragrance matches your sensitivity โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

SafetyBarโ€‹

Horizontal safety score visualization.

Usageโ€‹

<SafetyBar score={8} maxScore={10} />

Propsโ€‹

PropTypeDefaultDescription
scorenumber-Current score
maxScorenumber10Maximum score
heightnumber6Bar height in pixels

Color Mappingโ€‹

const getScoreColor = (score: number): string => {
if (score >= 8) return '#22c55e'; // Green
if (score >= 6) return '#84cc16'; // Light green
if (score >= 4) return '#f59e0b'; // Amber
if (score >= 2) return '#f97316'; // Orange
return '#ef4444'; // Red
};

RiskBadgeโ€‹

Risk level indicator badge.

Usageโ€‹

<RiskBadge level="low" />
<RiskBadge level="medium" />
<RiskBadge level="high" />

Propsโ€‹

PropTypeDescription
levelRiskLevelRisk level to display

Stylingโ€‹

LevelBackgroundText
Low#dcfce7#166534
Medium#fef9c3#854d0e
High#fee2e2#991b1b

Type Definitionsโ€‹

// types/index.ts

export interface UserProfile {
allergies: string[];
skinType: SkinType;
expertise: ExpertiseLevel;
}

export type SkinType = 'normal' | 'dry' | 'oily' | 'combination' | 'sensitive';
export type ExpertiseLevel = 'beginner' | 'expert';
export type ThemeMode = 'light' | 'dark';
export type RiskLevel = 'low' | 'medium' | 'high';

export interface IngredientDetail {
name: string;
purpose: string;
safety_score: number;
risk_level: RiskLevel;
concerns: string;
recommendation: string;
origin: string;
category: string;
allergy_risk: string;
is_allergen_match: boolean;
alternatives: string[];
}