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
statusproperty: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.RelativeTimeFormatfor 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
lastSeendate 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.RelativeTimeFormatfor generating the relative timestamps. This provides a more localized and user-friendly experience. - Think about how to handle different timezones. Using UTC for the
lastSeendate 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.