Vue.js Event Scheduler Component
This challenge asks you to build a reusable Vue.js component that allows users to schedule events. The component should provide a visual interface for displaying events on a daily, weekly, or monthly view and enable users to add new events. This is a fundamental building block for many productivity and calendar applications.
Problem Description
You need to create a Vue.js component named Scheduler. This component will be responsible for rendering a calendar-like interface and managing a list of scheduled events.
Key Requirements:
- View Modes: The
Schedulercomponent must support at least three view modes:- Day View: Shows events for a single selected day.
- Week View: Shows events for a selected week.
- Month View: Shows events for a selected month.
- Event Display: Events should be displayed clearly within their respective time slots or days. Each event should show its title and start/end times.
- Navigation: Users should be able to navigate between different days, weeks, or months.
- Event Creation: Users should be able to add new events. This could be through a modal dialog or a direct inline form within the scheduler.
- Data Management: The component should accept an array of event objects as a prop and emit an event when a new event is added.
- Styling: The component should be reasonably styled for clarity and usability.
Expected Behavior:
- When the component mounts, it should display the current day's schedule (or the default view).
- Users can switch between Day, Week, and Month views.
- Users can navigate forward and backward through time (e.g., next day, previous week).
- Clicking on a time slot or an empty day area should allow the user to create a new event.
- The
Schedulercomponent should emit aeventCreatedevent with the details of the new event when it's successfully added. - The component should be able to display events that span multiple days or hours within the selected view.
Edge Cases:
- Handling events that start and end within a specific view.
- Handling events that partially overlap with the view.
- Displaying events on days/times where there are no other events.
- Ensuring navigation works correctly at the beginning/end of months or years.
- Handling overlapping events within the same time slot (consider visual indicators or a list).
Examples
Example 1: Initial Display (Month View)
Input:
{
events: [
{ id: 1, title: 'Team Meeting', start: new Date(2023, 10, 15, 10, 0), end: new Date(2023, 10, 15, 11, 0) },
{ id: 2, title: 'Client Call', start: new Date(2023, 10, 16, 14, 30), end: new Date(2023, 10, 16, 15, 30) },
{ id: 3, title: 'Project Deadline', start: new Date(2023, 10, 30, 17, 0), end: new Date(2023, 10, 30, 17, 0) }
],
currentViewDate: new Date(2023, 10, 1) // November 1st, 2023
}
Output:
A calendar grid for November 2023.
- The 15th of November shows "Team Meeting (10:00 - 11:00)".
- The 16th of November shows "Client Call (14:30 - 15:30)".
- The 30th of November shows "Project Deadline (17:00)".
Navigation controls to move to December 2023 or October 2023.
A button/area to add new events.
Example 2: Adding a New Event (Day View)
Input:
User clicks on 10:00 AM on November 17th, 2023, in Day View.
A modal appears asking for Event Title, Start Time, and End Time.
User enters:
- Title: "Dentist Appointment"
- Start Time: 10:00 AM
- End Time: 11:30 AM
Output:
The Scheduler component emits an `eventCreated` event.
The emitted payload is:
{
title: 'Dentist Appointment',
start: new Date(2023, 10, 17, 10, 0),
end: new Date(2023, 10, 17, 11, 30)
}
The Scheduler component visually updates to show "Dentist Appointment (10:00 - 11:30)" on the 17th of November.
Example 3: Event Spanning Multiple Days (Week View)
Input:
{
events: [
{ id: 4, title: 'Conference', start: new Date(2023, 10, 20, 9, 0), end: new Date(2023, 10, 22, 17, 0) }
],
currentViewDate: new Date(2023, 10, 20) // Week starting November 20th, 2023
}
Output:
A week view from November 20th to November 26th, 2023.
- The event "Conference" is visually represented across November 20th, 21st, and 22nd.
- It should indicate the start time on the 20th and the end time on the 22nd, and span the duration within the view.
Constraints
- The
Schedulercomponent must be implemented in TypeScript. - The component should accept a prop named
eventswhich is an array of objects, each with at leastid(string or number),title(string),start(Date), andend(Date). - The component should accept an optional prop
initialViewDate(Date) to set the starting date for the calendar. - The component should emit an
eventCreatedevent. The signature of this event should be(newEvent: { title: string, start: Date, end: Date }) => void. - The component should be designed to be reasonably performant, especially when displaying a large number of events or navigating through dates.
- Avoid external libraries for the core scheduling logic. You may use a UI framework like BootstrapVue or Vuetify for styling if desired, but the scheduling logic itself should be custom.
Notes
- Consider how you will represent dates and times. The JavaScript
Dateobject is a good starting point. - Think about the data structure for events and how to efficiently filter and display them based on the current view.
- The visual representation of events can be flexible. You could use colored blocks, list items, etc.
- For event creation, a modal is a common approach, but consider other options as well.
- When navigating, ensure that the
currentViewDateprop is updated or managed internally, and that subsequent views reflect the new date. - You might find it helpful to create helper functions for date manipulation and formatting.