Vue Hydration Challenge: Dynamic Water Intake Tracker
This challenge focuses on building a simple hydration tracker using Vue.js and TypeScript. Hydration is crucial for health, and a user-friendly tracker can encourage better habits. You'll implement a component that allows users to log water intake and visually represents their progress towards a daily goal.
Problem Description
You are tasked with creating a Vue component called HydrationTracker that allows users to track their daily water intake. The component should:
- Display a Daily Goal: Show a configurable daily water intake goal (in ounces). This goal should be passed as a prop.
- Allow Water Logging: Provide a button or input field that allows the user to log water intake in increments (e.g., 8 ounces). Each click/submission should add to the current intake.
- Track Current Intake: Maintain a reactive variable to store the current water intake.
- Visual Progress: Display a visual representation of the user's progress towards their goal. This could be a progress bar, a circle graph, or any other suitable visual. The visual should update dynamically as the user logs water.
- Reset Functionality: Include a button to reset the current intake to zero.
- Error Handling: If the daily goal is not a positive number, display an error message.
Expected Behavior:
- The component should render correctly with the provided daily goal.
- Clicking the "Log Water" button should increment the current intake by 8 ounces (or a configurable amount).
- The visual progress indicator should accurately reflect the current intake relative to the daily goal.
- The "Reset" button should set the current intake back to zero.
- An error message should be displayed if the daily goal is invalid.
Examples
Example 1:
Input: dailyGoal = 64
Initial State: currentIntake = 0
Action: User clicks "Log Water" 3 times.
Output: currentIntake = 24, Progress Bar: 37.5% full
Explanation: 3 clicks * 8 ounces/click = 24 ounces. 24/64 = 0.375 = 37.5%
Example 2:
Input: dailyGoal = 128
Initial State: currentIntake = 32
Action: User clicks "Reset"
Output: currentIntake = 0, Progress Bar: 0% full
Explanation: Reset button sets currentIntake to 0.
Example 3: (Edge Case)
Input: dailyGoal = -10
Initial State: currentIntake = 0
Output: Error message displayed: "Daily goal must be a positive number."
Explanation: Negative daily goals are invalid and should trigger an error.
Constraints
- Daily Goal: The
dailyGoalprop must be a number. - Intake Increment: The water intake increment should be configurable (e.g., 8 ounces). Make this configurable via a prop as well.
- Component Structure: The component should be well-structured and easy to understand.
- Reactivity: Use Vue's reactivity system to ensure the UI updates automatically when the
currentIntakechanges. - Error Handling: Handle invalid
dailyGoalvalues gracefully. - Performance: The component should render and update efficiently. Avoid unnecessary re-renders.
Notes
- Consider using a progress bar library or creating a simple one yourself for the visual representation.
- Think about how to make the component reusable and configurable.
- Focus on clean, readable code and proper TypeScript typing.
- You can use any Vue.js features you are comfortable with (e.g., computed properties, watchers, methods).
- The visual representation doesn't need to be fancy; a simple progress bar is sufficient. The core functionality of tracking and displaying progress is the priority.
- The increment amount should also be a prop.