> ## Documentation Index
> Fetch the complete documentation index at: https://docs.wealthyhood.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Home screen

> How to build the Wealthyhood Home screen with daily portfolio summaries, performance metrics, and market insights

The Wealthyhood Home screen displays a daily summary of the user's portfolio, market data, and investment insights. All data is fetched from a single endpoint that returns historical and current portfolio information.

<Info>
  All routes require a bearer token with the appropriate scopes plus the `x-user-id` header to identify the user account.
</Info>

## Data sources

<CardGroup cols={1}>
  <Card title="Get Daily Summaries" icon="chart-line" href="/api-reference/daily-summaries/get-daily-summaries">
    Retrieve historical daily portfolio summaries with performance metrics, market insights, and sentiment scores.
  </Card>
</CardGroup>

## Prerequisites

* Bearer token with required scopes
* `x-user-id` header to identify the user

## What to fetch

<AccordionGroup>
  <Accordion title="Daily summaries">
    Use [Get daily summaries](/api-reference/daily-summaries/get-daily-summaries) to retrieve all data needed for the home screen.

    Returns:

    * Historical portfolio snapshots (cash, savings, holdings, total)
    * Performance metrics (returns, performers)
    * Market data (today's markets, market summary)
    * Sentiment scores
    * Chart scaling data (`maxValueDifferences`)

    <Warning>
      You'll need to generate date labels client-side using the `timestamp` field. See implementation notes in each component section.
    </Warning>
  </Accordion>
</AccordionGroup>

## Component Guide

### 1. Date Selector / Time Series Navigation

**Purpose**: Allows users to navigate through historical portfolio data by selecting different dates.

**Data Source**:

* Use the `data` array from the response
* Filter out items where `isOnlyForChartLabel` is `true` (these entries are used for chart axis labeling in future & past data points when there is no daily summary for those dates)

**Fields to Use**:

* `timestamp` - Unix timestamp in milliseconds for the date
* `isOnlyForChartLabel` - Boolean flag to identify chart-label-only entries

***

### 2. Portfolio Value Cards

**Purpose**: Display four key portfolio metrics as cards that users can swipe through.

**Data Source**:

* `portfolio` object from the selected daily summary item

**Fields to Use**:

#### Total Account Value Card

* `portfolio.total.displayValue` - Formatted value string (e.g., "€12,345.67")
* `portfolio.total.value` - Numeric value in cents

#### Holdings Card

* `portfolio.holdings.displayValue` - Formatted investment value
* `portfolio.holdings.upBy` - Percentage increase (if positive)
* `portfolio.holdings.downBy` - Percentage decrease (if negative)

#### Savings Card

* `portfolio.savings.displayValue` - Formatted savings value
* `portfolio.savings.dailyInterest` - Daily interest earned (if applicable)
* `portfolio.savings.unrealisedMonthlyInterest` - Monthly interest (if applicable)
* `portfolio.savings.estimated` - Boolean indicating if interest is estimated

#### Cash Card

* `portfolio.cash.displayValue` - Formatted cash balance
* `portfolio.cash.value` - Numeric value in cents

**Implementation Notes**:

* Display cards in a horizontal scrollable container
* Show up/down indicators with appropriate colors (green for up, red for down)
* Cards should be swipeable/scrollable
* Default selection should be "Total" (index 0)

***

### 3. Portfolio Chart

**Purpose**: Visualize portfolio value trends over time with an interactive line chart.

**Data Source**:

* Use the entire `data` array from the response
* Filter based on selected portfolio type (Total, Holdings, Savings, or Cash)

**Fields to Use** (depending on selected portfolio type):

#### For Total Account Value:

* Iterate through all items in `data` array
* Use `data[].portfolio.total.chartValue` - Numeric value for chart plotting
* Use `data[].timestamp` - For sorting and date handling
* Use `data[].portfolio.total.displayValue` - Tooltip/display value on hover
* **X-axis Labels**: Generate labels from `timestamp` field

#### For Holdings:

* `data[].portfolio.holdings.chartValue`
* `data[].timestamp`
* `data[].portfolio.holdings.displayValue`

#### For Savings:

* `data[].portfolio.savings.chartValue`
* `data[].timestamp`
* `data[].portfolio.savings.displayValue`

#### For Cash:

* `data[].portfolio.cash.chartValue`
* `data[].timestamp`
* `data[].portfolio.cash.displayValue`

**Additional Data**:

* `maxValueDifferences.total` - Maximum value difference for Total (used for chart scaling)
* `maxValueDifferences.holdings` - Maximum value difference for Holdings
* `maxValueDifferences.savings` - Maximum value difference for Savings
* `maxValueDifferences.cash` - Maximum value difference for Cash

**Implementation Notes**:

* Chart should update when user selects a different portfolio card type
* Chart should highlight the currently selected date
* Use `maxValueDifferences` to properly scale the Y-axis
* Chart should be interactive, allowing users to tap/click on data points to select that date
* **Chart Label Handling**: For items where `isOnlyForChartLabel` is `true`, generate labels from `timestamp` for x-axis display
* Filter out chart-label-only points when allowing date selection, but include them in chart rendering for proper axis labels

***

### 4. Top Movers (Best & Worst Performers)

**Purpose**: Display the best and worst performing assets in the user's portfolio.

**Data Source**:

* `performers` object from the selected daily summary item

<Warning>
  **Important**: The `performers` field may be `undefined`. Always check if `performers` exists before accessing its properties.
</Warning>

**Fields to Use**:

#### Best Performers Section

* `performers.best` - Array of top performing assets
  * Each item contains:
    * `value` - Formatted value string
    * `upBy` - Percentage increase
    * `weight` - Portfolio weight percentage
    * `assetId` - Asset identifier for navigation

#### Worst Performers Section

* `performers.worst` - Array of worst performing assets
  * Each item contains:
    * `value` - Formatted value string
    * `downBy` - Percentage decrease
    * `weight` - Portfolio weight percentage
    * `assetId` - Asset identifier for navigation

**Additional Data**:

* `performers.all` - Complete list of all performers (used for "See All" functionality)
* `seeAllTopPerformersEnabled` - Boolean indicating if "See All" button should be enabled

**Implementation Notes**:

* Only show this section if `performers` exists and has data
* Display best performers in green/positive styling
* Display worst performers in red/negative styling
* Show "See All" button if `performers.all` is not empty and `seeAllTopPerformersEnabled` is `true`
* Hide the entire section if `performers` is null/undefined or both arrays are empty

***

### 5. Today's Markets

**Purpose**: Display a scrolling ticker of market indices and their daily performance.

**Data Source**:

* `todayMarkets` array from the selected daily summary item

**Fields to Use**:

* `todayMarkets[]` - Array of market items
  * Each item contains:
    * `label` - Market/index name (e.g., "FTSE 100", "S\&P 500")
    * `returns.upBy` - Percentage increase (if positive)
    * `returns.downBy` - Percentage decrease (if negative)

**Implementation Notes**:

* Display as a horizontally scrolling ticker/marquee
* Auto-scroll continuously if multiple markets are present
* Show green/positive styling for `upBy`, red/negative styling for `downBy`
* Hide the section if `todayMarkets` is null or empty
* Pause auto-scroll on user interaction, resume after a delay

***

### 6. Sentiment Score

**Purpose**: Display a comprehensive sentiment score gauge showing overall portfolio sentiment and breakdowns.

**Data Source**:

* `sentimentScore` object from the selected daily summary item

**Fields to Use**:

#### Overall Sentiment

* `sentimentScore.total.score` - Overall sentiment score (integer, typically 0-100)
* `sentimentScore.total.label` - Score label: "optimal", "suboptimal", or "underperforming"

#### News Sentiment

* `sentimentScore.news.score` - News-based sentiment score (if available)
* `sentimentScore.news.label` - Score label

#### Analyst Sentiment

* `sentimentScore.analyst.score` - Analyst-based sentiment score (if available)
* `sentimentScore.analyst.label` - Score label

#### Price Momentum

* `sentimentScore.priceMomentum.score` - Price momentum score (if enabled)
* `sentimentScore.priceMomentum.label` - Score label

**Implementation Notes**:

* Display as a gauge/chart visualization
* Use color coding based on `label`:
  * "optimal" - Green
  * "suboptimal" - Yellow/Orange
  * "underperforming" - Red
* Show breakdown sections for News, Analyst, and Price Momentum (only if they exist)
* Price Momentum section should only be shown if `priceMomentum` exists
* Hide the entire section if `sentimentScore` is null

***

### 7. Market Summary

**Purpose**: Display a daily market summary with overview text and detailed sections.

**Data Source**:

* `marketSummary` object from the selected daily summary item

**Fields to Use**:

#### Overview Section

* `marketSummary.overview` - Main summary text (displayed on home screen)

#### Detailed Sections (for full view)

* `marketSummary.sections[]` - Array of detailed sections
  * Each section contains:
    * `tag` - Section category/tag
    * `title` - Section title
    * `content` - Section content text
    * `assetId` - Related asset ID (if applicable)
    * `tickerSymbol` - Ticker symbol (if applicable)
    * `assetReturns.upBy` - Asset return percentage (if positive)
    * `assetReturns.downBy` - Asset return percentage (if negative)

**Implementation Notes**:

* Display overview text on the home screen
* Show "Read more" button/link if `marketSummary.sections` exists and has items
* Navigate to full market summary view when "Read more" is clicked
* Hide the section if `marketSummary` is null

***

### 8. Uninvested State

**Purpose**: Show a special state when the user hasn't made any investments yet.

**Data Source**:

* `isUninvested` boolean from the selected daily summary item

**Fields to Use**:

* `isUninvested` - Boolean flag indicating if user has no investments

**Implementation Notes**:

* When `isUninvested` is `true`:
  * Hide or blur portfolio value cards
  * Hide chart
  * Hide top movers section
  * Show call-to-action buttons for first investment
  * Display encouraging message about starting to invest
* When `isUninvested` is `false`, show all normal components

***

## Data Flow

1. **Initial Load**:
   * Fetch data from `GET /daily-summaries` endpoint with `x-user-id` header
   * Filter `data` array to remove items where `isOnlyForChartLabel` is `true`
   * Select the most recent date (last item in filtered array) as default
   * Render all components using data from the selected date

2. **Date Selection**:
   * When user selects a different date from the date selector
   * Update all components with data from the newly selected daily summary item
   * Update chart highlight to show selected date
   * Maintain selected portfolio card type (Total/Holdings/Savings/Cash)

3. **Portfolio Card Selection**:
   * When user selects a different portfolio card (Total/Holdings/Savings/Cash)
   * Update chart to show data for the selected portfolio type
   * Use corresponding `maxValueDifferences` value for chart scaling
   * Update chart data points using the appropriate `portfolio.*.chartValue` fields

4. **Refresh**:
   * Re-fetch from `GET /daily-summaries` endpoint
   * Update all components with fresh data
   * Maintain current date and portfolio card selection if still valid

***

## Error Handling

* If the API request fails, display an appropriate error message
* If `data` array is empty or null, show an empty state
* If specific fields are missing (e.g., `portfolio`, `performers`), hide the corresponding components gracefully
* Handle cases where historical data might be incomplete
* Always check if optional fields exist before accessing nested properties (especially `performers`, `sentimentScore`, `todayMarkets`, `marketSummary`)

***

## Performance Considerations

* The `data` array may contain many items (potentially weeks or months of data)
* Consider pagination or limiting the number of data points if the array becomes very large
* Cache the response appropriately to avoid unnecessary API calls
* Filter `isOnlyForChartLabel` items early to reduce processing overhead
* Use `maxValueDifferences` values to optimize chart rendering
* Generate date labels efficiently using cached formatters

***

## Example: Complete Fetch Implementation

<CodeGroup>
  ```javascript Node.js theme={null}
  const BASE = 'https://api.wealthyhood.com';

  async function fetchHomeScreen({ token, userId }) {
    const headers = {
      'Authorization': `Bearer ${token}`,
      'x-user-id': userId,
      'Accept': 'application/json'
    };

    const response = await fetch(`${BASE}/daily-summaries`, { headers });
    
    if (!response.ok) {
      throw new Error(`Failed to fetch daily summaries: ${response.status}`);
    }

    const data = await response.json();
    
    // Filter out chart-label-only entries for date selector
    const selectableDates = data.data.filter(
      item => !('isOnlyForChartLabel' in item && item.isOnlyForChartLabel)
    );
    
    // Get most recent date (last item)
    const selectedDate = selectableDates[selectableDates.length - 1];
    
    // Generate date labels client-side
    const formatDateLabel = (timestamp) => {
      const date = new Date(timestamp);
      const today = new Date();
      const isToday = date.toDateString() === today.toDateString();
      
      if (isToday) return 'Today';
      
      return date.toLocaleDateString('en-GB', { 
        day: 'numeric', 
        month: 'short' 
      });
    };
    
    return {
      ...data,
      selectableDates: selectableDates.map(item => ({
        ...item,
        dateLabel: formatDateLabel(item.timestamp)
      })),
      selectedDate: {
        ...selectedDate,
        dateLabel: formatDateLabel(selectedDate.timestamp)
      }
    };
  }
  ```

  ```bash cURL theme={null}
  curl -X GET 'https://api.wealthyhood.com/daily-summaries' \
    -H 'Accept: application/json' \
    -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
    -H 'x-user-id: 64f0c51e7fb3fc001234a111'
  ```
</CodeGroup>

<Tip>
  Implement a client-side date formatting utility that handles:

  * Locale-specific formatting
  * Relative dates ("Today", "Yesterday")
  * Consistent formatting across all components
  * Timezone handling
</Tip>

<Warning>
  Always check if `performers` exists before accessing its properties, as it may be `undefined` even when other data is present.
</Warning>

## See also

* [API Reference → Get Daily Summaries](/api-reference/daily-summaries/get-daily-summaries)
