Hone logo
Hone
Problems

Real-time Presence Indicators in a React Application

Presence indicators are a crucial feature in many collaborative applications, showing users who is online, offline, or away. This challenge asks you to build a reusable React component that displays presence status based on a provided user data array. This component will enhance user experience by providing immediate feedback on the availability of other users.

Problem Description

You need to create a PresenceIndicator React component that takes an array of user objects as input. Each user object will have the following structure:

interface User {
  id: string;
  name: string;
  status: 'online' | 'offline' | 'away';
  lastSeen: Date; // Date object representing the last time the user's status was updated
}

The PresenceIndicator component should render a visual representation of each user's presence status. The visual representation should include:

  • User Name: Display the user's name.
  • Status Icon: Display a different icon based on the status property:
    • online: A green circle.
    • offline: A grey circle.
    • away: A yellow circle.
  • Last Seen Timestamp: Display a relative timestamp indicating when the user was last seen. For example: "Online Now", "5 minutes ago", "2 hours ago", "Yesterday". Use Intl.RelativeTimeFormat for this.

The component should be reusable and accept the user data as a prop. It should handle an empty user array gracefully by displaying a message like "No users online."

Expected Behavior:

  • The component should render correctly for various user statuses and last seen timestamps.
  • The component should handle an empty user array without errors.
  • The relative timestamp should be accurate and user-friendly.
  • The component should be visually appealing and easy to understand.

Edge Cases to Consider:

  • Empty user array.
  • Users with very recent last seen timestamps (e.g., within the last minute).
  • Users with last seen timestamps from yesterday or earlier.
  • Different timezones (consider using UTC for consistency).

Examples

Example 1:

Input: [
  { id: "1", name: "Alice", status: "online", lastSeen: new Date() },
  { id: "2", name: "Bob", status: "offline", lastSeen: new Date(Date.now() - 300000) }, // 5 minutes ago
  { id: "3", name: "Charlie", status: "away", lastSeen: new Date(Date.now() - 7200000) } // 2 hours ago
]
Output: (Visual representation of Alice as online, Bob as offline (5 minutes ago), and Charlie as away (2 hours ago))
Explanation: The component iterates through the user array and renders the appropriate status icon and relative timestamp for each user.

Example 2:

Input: []
Output: "No users online."
Explanation: The component handles the empty array case by displaying a message indicating that no users are online.

Example 3:

Input: [
  { id: "4", name: "David", status: "online", lastSeen: new Date() },
  { id: "5", name: "Eve", status: "online", lastSeen: new Date(Date.now() - 60000) } // 1 minute ago
]
Output: (Visual representation of David as online, Eve as online (1 minute ago))
Explanation: Demonstrates handling of multiple online users with different last seen times.

Constraints

  • The component must be written in TypeScript.
  • The component should be reusable and accept the user data as a prop.
  • The relative timestamp should be accurate to within a few seconds.
  • The component should be visually appealing and easy to understand.
  • The lastSeen date should be used to calculate the relative time.
  • You can use any React UI library (e.g., Material UI, Ant Design, Bootstrap) or plain CSS for styling. If using a library, include the necessary imports.

Notes

  • Consider using Intl.RelativeTimeFormat for generating the relative timestamps. This provides a more localized and user-friendly experience.
  • Think about how to handle different timezones. Using UTC for the lastSeen date can help ensure consistency.
  • Focus on creating a clean, reusable, and well-documented component.
  • Error handling is not explicitly required, but consider how the component would behave if the input data is malformed.
  • Prioritize readability and maintainability of your code.
Loading editor...
typescript