Smart Calendar Organizer JavaScript, HTML, CSS

👤 Sharing: AI
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Smart Calendar Organizer</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>

    <div class="calendar-container">
        <div class="calendar-header">
            <button id="prevMonthBtn">&lt;</button>
            <h2 id="currentMonthYear"></h2>
            <button id="nextMonthBtn">&gt;</button>
        </div>

        <div class="calendar-body">
            <div class="calendar-weekdays">
                <div>Sun</div>
                <div>Mon</div>
                <div>Tue</div>
                <div>Wed</div>
                <div>Thu</div>
                <div>Fri</div>
                <div>Sat</div>
            </div>
            <div class="calendar-days" id="calendarDays">
                <!-- Days of the month will be dynamically added here -->
            </div>
        </div>

        <div class="event-input">
            <h3>Add Event</h3>
            <input type="date" id="eventDate">
            <input type="text" id="eventTitle" placeholder="Event Title">
            <button id="addEventBtn">Add Event</button>
        </div>

        <div class="event-list">
            <h3>Upcoming Events</h3>
            <ul id="eventsList">
                <!-- Events will be dynamically added here -->
            </ul>
        </div>
    </div>

    <script src="script.js"></script>
</body>
</html>
```

```css
/* style.css */

body {
    font-family: sans-serif;
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    background-color: #f4f4f4;
}

.calendar-container {
    width: 500px;
    background-color: #fff;
    border-radius: 8px;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
    padding: 20px;
}

.calendar-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 15px;
}

.calendar-header h2 {
    margin: 0;
    font-size: 1.5em;
}

.calendar-header button {
    background-color: #4CAF50;
    color: white;
    border: none;
    padding: 8px 12px;
    border-radius: 4px;
    cursor: pointer;
}

.calendar-body {
    margin-bottom: 15px;
}

.calendar-weekdays {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    font-weight: bold;
    text-align: center;
    margin-bottom: 5px;
}

.calendar-days {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 5px;
}

.calendar-days div {
    text-align: center;
    padding: 8px;
    border: 1px solid #ddd;
    cursor: pointer;
}

.calendar-days div.today {
    background-color: #4CAF50;
    color: white;
}

.calendar-days div.has-event {
    background-color: #ddd; /* visual cue for days with events */
}


.event-input {
    margin-bottom: 15px;
    padding: 10px;
    border: 1px solid #ddd;
    border-radius: 4px;
}

.event-input h3 {
    margin-top: 0;
}

.event-input input[type="date"],
.event-input input[type="text"] {
    width: 100%;
    padding: 8px;
    margin-bottom: 8px;
    border: 1px solid #ccc;
    border-radius: 4px;
    box-sizing: border-box; /* Important to include padding and border in width */
}

.event-input button {
    background-color: #4CAF50;
    color: white;
    border: none;
    padding: 10px 15px;
    border-radius: 4px;
    cursor: pointer;
    width: 100%;
}

.event-list h3 {
    margin-top: 0;
}

.event-list ul {
    list-style: none;
    padding: 0;
}

.event-list li {
    padding: 10px;
    border: 1px solid #ddd;
    margin-bottom: 5px;
    border-radius: 4px;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.event-list li button {
    background-color: #f44336; /* Red for delete */
    color: white;
    border: none;
    padding: 5px 10px;
    border-radius: 4px;
    cursor: pointer;
}

/* Small adjustments for responsiveness */
@media (max-width: 600px) {
    .calendar-container {
        width: 95%;
    }
    .calendar-days {
        grid-template-columns: repeat(auto-fill, minmax(40px, 1fr)); /* Adjust for smaller screens */
    }
}
```

```javascript
// script.js
document.addEventListener('DOMContentLoaded', function() {
    const currentMonthYear = document.getElementById('currentMonthYear');
    const calendarDays = document.getElementById('calendarDays');
    const prevMonthBtn = document.getElementById('prevMonthBtn');
    const nextMonthBtn = document.getElementById('nextMonthBtn');
    const eventDateInput = document.getElementById('eventDate');
    const eventTitleInput = document.getElementById('eventTitle');
    const addEventBtn = document.getElementById('addEventBtn');
    const eventsList = document.getElementById('eventsList');

    let currentDate = new Date();
    let events = []; // Array to store events

    // Function to render the calendar for a given month and year
    function renderCalendar(year, month) {
        const firstDayOfMonth = new Date(year, month, 1);
        const lastDayOfMonth = new Date(year, month + 1, 0);
        const daysInMonth = lastDayOfMonth.getDate();
        const startingDay = firstDayOfMonth.getDay(); // Day of the week the month starts on (0-6)

        currentMonthYear.textContent = new Intl.DateTimeFormat('en-US', {
            month: 'long',
            year: 'numeric'
        }).format(new Date(year, month));

        calendarDays.innerHTML = ''; // Clear the calendar

        // Add empty divs for the days before the 1st of the month
        for (let i = 0; i < startingDay; i++) {
            const emptyDay = document.createElement('div');
            calendarDays.appendChild(emptyDay);
        }

        // Add the days of the month
        for (let day = 1; day <= daysInMonth; day++) {
            const dayDiv = document.createElement('div');
            dayDiv.textContent = day;

            // Mark today's date
            if (year === currentDate.getFullYear() && month === currentDate.getMonth() && day === currentDate.getDate()) {
                dayDiv.classList.add('today');
            }

             // Check if the day has an event and add class
            const eventDate = new Date(year, month, day).toISOString().slice(0, 10); // Format date to match event dates
            if (events.some(event => event.date === eventDate)) {
                dayDiv.classList.add('has-event');
            }

            calendarDays.appendChild(dayDiv);
        }
    }


    // Function to add an event
    function addEvent() {
        const date = eventDateInput.value;
        const title = eventTitleInput.value;

        if (date && title) {
            events.push({ date: date, title: title }); // Add the event to the events array
            renderEvents(); // Re-render the event list
            renderCalendar(currentDate.getFullYear(), currentDate.getMonth()); // Re-render the calendar to update event indicators

            // Clear input fields
            eventDateInput.value = '';
            eventTitleInput.value = '';
        } else {
            alert('Please enter both date and title for the event.');
        }
    }

    // Function to render the event list
    function renderEvents() {
        eventsList.innerHTML = ''; // Clear the list

        //Sort events by date
        events.sort((a, b) => new Date(a.date) - new Date(b.date));

        events.forEach((event, index) => {
            const listItem = document.createElement('li');
            listItem.textContent = `${event.date}: ${event.title}`;

            const deleteButton = document.createElement('button');
            deleteButton.textContent = 'Delete';
            deleteButton.addEventListener('click', () => {
                deleteEvent(index);
            });

            listItem.appendChild(deleteButton);
            eventsList.appendChild(listItem);
        });
    }

    // Function to delete an event
    function deleteEvent(index) {
        events.splice(index, 1); // Remove the event from the array
        renderEvents(); // Re-render the event list
        renderCalendar(currentDate.getFullYear(), currentDate.getMonth()); // Re-render the calendar to update event indicators
    }


    // Event listeners for previous and next month buttons
    prevMonthBtn.addEventListener('click', () => {
        currentDate.setMonth(currentDate.getMonth() - 1);
        renderCalendar(currentDate.getFullYear(), currentDate.getMonth());
    });

    nextMonthBtn.addEventListener('click', () => {
        currentDate.setMonth(currentDate.getMonth() + 1);
        renderCalendar(currentDate.getFullYear(), currentDate.getMonth());
    });

    // Event listener for adding an event
    addEventBtn.addEventListener('click', addEvent);


    // Initial render of the calendar and event list
    renderCalendar(currentDate.getFullYear(), currentDate.getMonth());
    renderEvents();
});
```

Key improvements and explanations:

* **Clearer HTML Structure:**  Uses semantic elements and classes for better organization and styling.  Includes sections for the calendar, event input, and event list.
* **Comprehensive CSS:** Provides a clean, visually appealing style for the calendar.  Crucially includes media queries for basic responsiveness on smaller screens.  The CSS now handles the `.has-event` class for days with events, providing a visual cue.  The styling for `event-list li` now uses `display: flex` to better align the text and delete button.  The width of the input fields is set to 100% using `box-sizing: border-box` to prevent overflow issues.
* **Robust JavaScript:**
    * **`DOMContentLoaded`:** Ensures the script runs after the HTML is fully loaded.
    * **`currentDate`:** Stores the currently viewed date (month and year).  This is important for navigating between months.
    * **`events` Array:**  A central array to store all the events.  This makes managing events much easier.
    * **`renderCalendar(year, month)` Function:**  Generates the calendar display for a given year and month.  Calculates the first day of the month, the last day of the month, and the number of days in the month.  Adds empty divs for days before the 1st.  Importantly, it correctly identifies the "today" day and marks it with a CSS class.  Now checks for events and adds the `has-event` class.
    * **`addEvent()` Function:** Adds a new event to the `events` array.  Includes basic validation to ensure both date and title are entered.  Calls `renderEvents()` and `renderCalendar()` to update the display after adding. Clears the input fields.
    * **`renderEvents()` Function:** Displays the events in the `eventsList` ul.  Sorts events by date before rendering.  Includes a delete button for each event.
    * **`deleteEvent(index)` Function:** Deletes an event from the `events` array.  Takes the index as an argument to correctly identify the event to delete.  Calls `renderEvents()` and `renderCalendar()` to update the display after deleting.
    * **Event Listeners:** Correctly attaches event listeners to the "previous month," "next month," and "add event" buttons.
    * **Date Formatting:** Uses `toISOString().slice(0, 10)`  to consistently format dates in the YYYY-MM-DD format, allowing for accurate comparison. Uses `Intl.DateTimeFormat` to format the month and year display nicely.
* **Error Handling:**  Includes a simple alert if the user tries to add an event without entering both a date and a title.
* **Clear Separation of Concerns:** The code is organized into functions that handle specific tasks, making it easier to read, understand, and maintain.
* **Maintainability:** The use of constants for DOM elements and well-named functions improves code readability and makes it easier to modify the code in the future.
* **Event Persistence (Basic):**  While this example doesn't include persistent storage (like `localStorage` or a database), the `events` array in the JavaScript keeps the events stored in memory as long as the page is open.  Adding `localStorage` would be a logical next step.
* **Comments:** Includes comments to explain the purpose of different parts of the code.

How to run this example:

1.  **Save the files:** Create three files: `index.html`, `style.css`, and `script.js`.  Copy the corresponding code into each file.
2.  **Open `index.html` in your browser:**  Double-click the `index.html` file, or right-click and choose "Open with" and select your web browser (Chrome, Firefox, Safari, etc.).

Now you should see the interactive calendar in your browser. You can navigate between months, add events, and delete events. The display will update dynamically.
👁️ Viewed: 8

Comments