Debug School

rakesh kumar
rakesh kumar

Posted on

List out feature of full calender in react

Select and Drag Date
Allow users to select a date range by clicking and dragging over calendar days.

<FullCalendar
  plugins={[dayGridPlugin, interactionPlugin]}
  selectable={true}
  select={handleDateSelect}
/>

const handleDateSelect = (selectInfo) => {
  alert(`Selected from ${selectInfo.startStr} to ${selectInfo.endStr}`);
};
Enter fullscreen mode Exit fullscreen mode

2️⃣ Drag and Drop Events
Make calendar events draggable to reschedule them easily.

<FullCalendar
  plugins={[dayGridPlugin, interactionPlugin]}
  editable={true} // Enables drag & drop
  eventDrop={handleEventDrop}
/>

const handleEventDrop = (eventDropInfo) => {
  alert(`Event moved to ${eventDropInfo.event.start}`);
};
Enter fullscreen mode Exit fullscreen mode

3️⃣ Resize Events
Users can extend or shorten an event by dragging its edges.

<FullCalendar
  plugins={[dayGridPlugin, interactionPlugin]}
  editable={true} // Enables resizing
  eventResize={handleEventResize}
/>

const handleEventResize = (resizeInfo) => {
  alert(`Event resized: New End Date is ${resizeInfo.event.end}`);
};
Enter fullscreen mode Exit fullscreen mode

4️⃣ Event Click to Show Details
When users click an event, show event details in a popup.

<FullCalendar
  plugins={[dayGridPlugin, interactionPlugin]}
  events={[
    { title: "Meeting", start: "2025-01-25", end: "2025-01-26" },
  ]}
  eventClick={handleEventClick}
/>

const handleEventClick = (info) => {
  alert(`Event: ${info.event.title}`);
};
Enter fullscreen mode Exit fullscreen mode

5️⃣ Dynamic Event Creation (Double Click)
Users can double-click on a date to create a new event.

<FullCalendar
  plugins={[dayGridPlugin, interactionPlugin]}
  dateClick={handleDateClick}
/>

const handleDateClick = (info) => {
  const title = prompt("Enter event title:");
  if (title) {
    info.view.calendar.addEvent({
      title,
      start: info.dateStr,
      allDay: true,
    });
  }
};
Enter fullscreen mode Exit fullscreen mode

6️⃣ Different Calendar Views
Switch between monthly, weekly, and daily views dynamically.

<FullCalendar
  plugins={[dayGridPlugin, timeGridPlugin]}
  initialView="dayGridMonth"
  headerToolbar={{
    left: "prev,next today",
    center: "title",
    right: "dayGridMonth,timeGridWeek,timeGridDay",
  }}
/>
Enter fullscreen mode Exit fullscreen mode

7️⃣ Event Colors & Styling
Customize event colors dynamically based on conditions.

<FullCalendar
  plugins={[dayGridPlugin]}
  events={[
    { title: "Important Meeting", start: "2025-01-21", backgroundColor: "red" },
    { title: "Casual Event", start: "2025-01-22", backgroundColor: "blue" },
  ]}
/>
Enter fullscreen mode Exit fullscreen mode

8️⃣ Recurring Events (Repeating Events)
Create events that repeat on specific days.

<FullCalendar
  plugins={[dayGridPlugin]}
  events={[
    {
      title: "Weekly Stand-up",
      startRecur: "2025-01-01",
      daysOfWeek: [1], // Monday
    },
  ]}
/>
Enter fullscreen mode Exit fullscreen mode

9️⃣ Event Tooltips (Hover to Show Details)
Show extra event details when the user hovers over an event.

<FullCalendar
  plugins={[dayGridPlugin, interactionPlugin]}
  eventMouseEnter={handleEventHover}
/>

const handleEventHover = (info) => {
  const tooltip = document.createElement("div");
  tooltip.innerHTML = `<strong>${info.event.title}</strong>`;
  tooltip.style.position = "absolute";
  tooltip.style.background = "#fff";
  tooltip.style.padding = "5px";
  tooltip.style.border = "1px solid #ccc";
  document.body.appendChild(tooltip);

  info.el.addEventListener("mouseleave", () => {
    tooltip.remove();
  });
};
Enter fullscreen mode Exit fullscreen mode

🔟 Google Calendar Integration
Fetch and display events from a Google Calendar.

<FullCalendar
  plugins={[dayGridPlugin]}
  googleCalendarApiKey="YOUR_GOOGLE_CALENDAR_API_KEY"
  events={{
    googleCalendarId: "your-calendar-id@group.calendar.google.com",
  }}
/>
Enter fullscreen mode Exit fullscreen mode

These features make FullCalendar in React a powerful and flexible scheduling tool.

Load Events from API (Dynamic Data Fetching)
Fetch events dynamically from a backend API.

import { useState, useEffect } from "react";
import axios from "axios";
import FullCalendar from "@fullcalendar/react";
import dayGridPlugin from "@fullcalendar/daygrid";

const MyCalendar = () => {
  const [events, setEvents] = useState([]);

  useEffect(() => {
    axios.get("/api/events") // Replace with your API endpoint
      .then((response) => setEvents(response.data))
      .catch((error) => console.error("Error fetching events:", error));
  }, []);

  return (
    <FullCalendar
      plugins={[dayGridPlugin]}
      events={events} // Dynamic event loading
    />
  );
};

export default MyCalendar;
Enter fullscreen mode Exit fullscreen mode

2️⃣ Add External Draggable Events
Drag external events into the calendar.

import { Draggable } from "@fullcalendar/interaction";

useEffect(() => {
  let draggableEl = document.getElementById("external-events");
  new Draggable(draggableEl, {
    itemSelector: ".fc-event",
    eventData: function (eventEl) {
      return { title: eventEl.innerText };
    },
  });
}, []);

return (
  <div>
    <div id="external-events">
      <div className="fc-event">Meeting</div>
      <div className="fc-event">Workshop</div>
    </div>
    <FullCalendar
      plugins={[dayGridPlugin, interactionPlugin]}
      droppable={true} // Enable drag-drop support
      eventReceive={(info) => alert(`Dropped event: ${info.event.title}`)}
    />
  </div>
);
Enter fullscreen mode Exit fullscreen mode

3️⃣ Restrict Selectable Dates
Disable past dates and weekends.

<FullCalendar
  plugins={[dayGridPlugin, interactionPlugin]}
  validRange={{
    start: new Date(), // Disable past dates
  }}
  selectable={true}
  select={handleDateSelect}
/>

const handleDateSelect = (selectInfo) => {
  alert(`Selected: ${selectInfo.startStr} to ${selectInfo.endStr}`);
};
Enter fullscreen mode Exit fullscreen mode

4️⃣ Custom Event Render (Modify Event Display)
Customize how events are displayed.

<FullCalendar
  plugins={[dayGridPlugin]}
  events={[
    { title: "Custom Event", start: "2025-01-22", description: "Important Event" },
  ]}
  eventContent={(arg) => {
    return (
      <div style={{ background: "lightblue", padding: "5px", borderRadius: "5px" }}>
        <strong>{arg.event.title}</strong>
        <p>{arg.event.extendedProps.description}</p>
      </div>
    );
  }}
/>
Enter fullscreen mode Exit fullscreen mode

5️⃣ Custom Time Slots (Business Hours)
Only allow event bookings within working hours.

<FullCalendar
  plugins={[timeGridPlugin]}
  initialView="timeGridWeek"
  businessHours={{
    daysOfWeek: [1, 2, 3, 4, 5], // Monday to Friday
    startTime: "09:00",
    endTime: "17:00",
  }}
/>
Enter fullscreen mode Exit fullscreen mode

6️⃣ Prevent Event Overlapping
Ensure no two events overlap.

<FullCalendar
  plugins={[dayGridPlugin, interactionPlugin]}
  events={[
    { title: "Meeting", start: "2025-01-21T10:00:00", end: "2025-01-21T12:00:00" },
  ]}
  selectOverlap={false} // Prevent overlapping
/>
Enter fullscreen mode Exit fullscreen mode

7️⃣ Display Event Count in Month View
Show the number of events on each day.

<FullCalendar
  plugins={[dayGridPlugin]}
  views={{
    dayGridMonth: {
      eventLimit: 3, // Show only 3 events per day
    },
  }}
/>
Enter fullscreen mode Exit fullscreen mode

8️⃣ Change Event Order (Sorting Events)
Sort events dynamically.

<FullCalendar
  plugins={[dayGridPlugin]}
  events={[
    { title: "Task A", start: "2025-01-21", sortOrder: 2 },
    { title: "Task B", start: "2025-01-21", sortOrder: 1 },
  ]}
  eventOrder="sortOrder" // Sort events based on sortOrder property
/>
Enter fullscreen mode Exit fullscreen mode

9️⃣ Add Custom Buttons in Toolbar
Add new buttons to the FullCalendar header.

<FullCalendar
  plugins={[dayGridPlugin]}
  headerToolbar={{
    left: "prev,next today customButton",
    center: "title",
    right: "dayGridMonth,timeGridWeek,timeGridDay",
  }}
  customButtons={{
    customButton: {
      text: "Alert",
      click: () => alert("Custom Button Clicked!"),
    },
  }}
/>
Enter fullscreen mode Exit fullscreen mode

🔟 Show Tooltip on Hover
Display tooltips when hovering over events.

import Tooltip from "tooltip.js";

<FullCalendar
  plugins={[dayGridPlugin, interactionPlugin]}
  events={[
    { title: "Project Deadline", start: "2025-01-20", description: "Submit by 5 PM" },
  ]}
  eventDidMount={(info) => {
    new Tooltip(info.el, {
      title: info.event.extendedProps.description,
      placement: "top",
    });
  }}
/>
Enter fullscreen mode Exit fullscreen mode

Practical implemention of full calender

step1:Run dependency

npm install @fullcalendar/react @fullcalendar/daygrid @fullcalendar/timegrid @fullcalendar/interaction
Enter fullscreen mode Exit fullscreen mode

step2:import calender dependence
import FullCalendar from "@fullcalendar/react";
import dayGridPlugin from "@fullcalendar/daygrid";
import timeGridPlugin from "@fullcalendar/timegrid";
import interactionPlugin from "@fullcalendar/interaction";
import "./Calendar.css";

Add css calender.css

.vehicle-details-container {
    width: 90%;
    margin: auto;
    padding: 20px;
}

/* Flexbox layout for desktop */
.vehicle-content-wrapper {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 30px;
}
.vehicle-details-box {
    background: #f5f5f5;
    padding: 10px 15px;
    border-radius: 5px;
    font-size: 14px;
    width: fit-content;

  }

  .vehicle-details-box p {
    margin: 5px 0;
  }
/* Vehicle Image Section */
.vehicle-image-container {
    flex: 1;
    max-width: 60%;
    display: flex;
    flex-direction: column;
    align-items: center;
}

.vehicle-img {
    width: 100%;
    max-width: 500px;
    border-radius: 10px;
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
}

.vehicle-info {
    display: flex;
    justify-content: space-around;
    width: 100%;
    margin-top: 10px;
}

.kms-driven, .make-year {
    font-size: 14px;
    background: #f5f5f5;
    padding: 5px 10px;
    border-radius: 5px;
}

/* Vehicle Details Section */
.vehicle-details {
    flex: 1;
    max-width: 40%;
}

.vehicle-title {
    font-size: 22px;
    font-weight: bold;
}

.package-dropdown {
    width: 100%;
    padding: 8px;
    margin-top: 10px;
    border: 1px solid #ccc;
    border-radius: 5px;
}

.payment-option {
    margin-top: 15px;
}

.payment-option label {
    display: block;
    font-size: 16px;
    margin-bottom: 5px;
}

.fare-details {
    margin-top: 15px;
    font-size: 16px;
}

.deposit {
    margin-top: 10px;
    padding: 8px;
    background: #d4f3d1;
    color: #218c21;
    border-radius: 5px;
}

/* Book Now Button */
.book-now-button {
    width: 100%;
    padding: 10px;
    background: #4CAF50;
    color: white;
    border: none;
    font-size: 18px;
    cursor: pointer;
    margin-top: 10px;
    border-radius: 5px;
}

.book-now-button:hover {
    background: #45a049;
}

/* 📍 Location & Calendar Section */
.location-calendar-section {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 30px;
    margin-top: 30px;
}

/* 🌍 Location Section */
.location-container {
    flex: 1;
    max-width: 50%;
}

.map-container iframe {
    border-radius: 10px;
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
    width: 100%;
    height: 250px; /* Set a proper height */
}

.map-container p {
    margin-top: 10px;
    font-size: 14px;
    color: #555;
}

/* 🗓 Calendar Section */
.calendar-container {
    flex: 1;
    max-width: 50%;
}

.calendar-container .small-calendar {
    width: 100%;
    max-width: 400px;
    margin: auto;
}

/* 🎨 FullCalendar Customization */
.fc .fc-toolbar-title {
    font-size: 14px !important;
}

.fc-daygrid-day {
    text-align: center;
    font-size: 12px;
    padding: 5px;
    border-radius: 4px;
    background-color: #d4edda ; /* Remove green color */
    color: #333; /* Default text color */
}

/* Highlight booked dates */
.fc-event {
    font-size: 10px !important;
    padding: 2px 5px;
    border-radius: 4px;
    background-color: red !important;
    color: white !important;
}

/* Highlight today's date */
.fc-day-today {
    background-color: rgba(255, 193, 7, 0.2) !important; /* Light yellow for today */
}

/* 📱 MOBILE VIEW - Responsive */
@media (max-width: 768px) {
    /* Ensure sections stack in mobile */
    .vehicle-content-wrapper,
    .location-calendar-section {
        flex-direction: column;
        align-items: center;
        text-align: center;
    }

    .vehicle-image-container,
    .vehicle-details,
    .location-container,
    .calendar-container {
        max-width: 100%;
    }

    /* Adjust calendar size */
    .small-calendar {
        max-width: 100%;
    }

    .map-container iframe {
        height: 200px;
    }
}
.calendar-legend {
    display: flex;
    gap: 15px;
    margin-top: 10px;
  }

  .legend-item {
    display: flex;
    align-items: center;
    font-size: 14px;
  }

  .legend-color {
    width: 15px;
    height: 10px;
    border-radius: 3px;
    display: inline-block;
    margin-right: 5px;
  }

  .available {
    background-color: #d4edda; /* ✅ Green for Available */
  }

  .booked {
    background-color: #ff9999; /* 🔴 Red for Booked */
  }
  .calendar-section {
    width: 100%;
    margin: auto;
    padding: 10px;
}

/* 📌 Header Alignment */
.calendar-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 10px;
    padding: 10px 0;
}

.calendar-title {
    font-size: 22px;
    font-weight: bold;
}

.calendar-header h5 {
    font-size: 22px;
    font-weight: bold;
}
Enter fullscreen mode Exit fullscreen mode

step3: declare variable

 const [selectedRange, setSelectedRange] = useState(null);
  const [calendarEvents, setCalendarEvents] = useState([]);
Enter fullscreen mode Exit fullscreen mode

step4: implwmnt dull calender component

{selectedRange && (
  <p style={{ backgroundColor: 'yellow', padding: '10px', borderRadius: '5px', marginBottom: '10px' }}>
    Selected Range: {selectedRange.start} to {new Date(selectedRange.end).toISOString().split("T")[0]}
  </p>
)}
            <FullCalendar
              plugins={[dayGridPlugin, timeGridPlugin, interactionPlugin]}
              initialView="dayGridMonth"
              selectable={true}
              selectMirror={true}
              events={calendarEvents}
              select={handleDateSelect}
              headerToolbar={{
                left: "prev,next",
                center: "title",
                right: "dayGridMonth,timeGridWeek,timeGridDay",
              }}
              height="auto"
              contentHeight="auto"
              aspectRatio={1.2}
              fixedWeekCount={false}
            />
Enter fullscreen mode Exit fullscreen mode

step5:define methods

  const handleDateSelect = (selectInfo) => {
    selectInfo.jsEvent.preventDefault(); // Prevents default browser behavior

    const { startStr, endStr } = selectInfo;

    // Correct end date for display and backend (subtract one day)
    const correctedEndDate = new Date(endStr);
    correctedEndDate.setDate(correctedEndDate.getDate() - 1);
    const formattedEndDate = correctedEndDate.toISOString().split("T")[0];

    // Set the selected range (corrected for UI and backend)
    setSelectedRange({
        start: startStr,
        end: formattedEndDate, // Corrected for proper display
    });

    // Add event to FullCalendar (WITHOUT subtracting one day)
    setCalendarEvents((prevEvents) => [
        ...prevEvents,
        {
            start: startStr,
            end: endStr, // Keep FullCalendar's behavior (no correction)
            backgroundColor: "purple",
            borderColor: "purple",
            display: "background",
        },
    ]);

    setPopupVisible(true);
};
Enter fullscreen mode Exit fullscreen mode

output

Image description
after select date

Image description

Full code

import React, { useState, useEffect } from "react";
import FullCalendar from "@fullcalendar/react";
import dayGridPlugin from "@fullcalendar/daygrid";
import timeGridPlugin from "@fullcalendar/timegrid";
import interactionPlugin from "@fullcalendar/interaction";
import axios from "axios"; // Axios for API calls
import SearchvehicleFilter from "./SearchvehicleFilter";
import ImageSlider from "./ImageSlider";
import "./Calendar.css";

const VehicleDetails = ({ vehicle, location, bookings = [] }) => {
  const [popupVisible, setPopupVisible] = useState(false);
  const [filteredVehicles, setFilteredVehicles] = useState([]);
  const [selectedRange, setSelectedRange] = useState(null);
  const [calendarEvents, setCalendarEvents] = useState([]);

  const handlePopupOpen = () => setPopupVisible(true);

  const handlePopupClose = () => setPopupVisible(false);

  const handleSearch = (term) => {
    const results = location.filter((loc) =>
      loc.city.toLowerCase().includes(term.toLowerCase())
    );
    setFilteredVehicles(results);
  };

  const handleDateSelect = (selectInfo) => {
    selectInfo.jsEvent.preventDefault(); // Prevents default browser behavior

    const { startStr, endStr } = selectInfo;

    // Correct end date for display and backend (subtract one day)
    const correctedEndDate = new Date(endStr);
    correctedEndDate.setDate(correctedEndDate.getDate() - 1);
    const formattedEndDate = correctedEndDate.toISOString().split("T")[0];

    // Set the selected range (corrected for UI and backend)
    setSelectedRange({
        start: startStr,
        end: formattedEndDate, // Corrected for proper display
    });

    // Add event to FullCalendar (WITHOUT subtracting one day)
    setCalendarEvents((prevEvents) => [
        ...prevEvents,
        {
            start: startStr,
            end: endStr, // Keep FullCalendar's behavior (no correction)
            backgroundColor: "purple",
            borderColor: "purple",
            display: "background",
        },
    ]);

    setPopupVisible(true);
};

  const handleFilter = (filter) => {
    if (filter) {
      const results = location.filter((loc) => loc.vehicleType === filter);
      setFilteredVehicles(results);
    } else {
      setFilteredVehicles(location);
    }
  };

  const handleRentNow = async () => {
    try {
        // Prepare request payload
        const payload = {
            vehicle_id: vehicle?.id, // Vehicle ID
        };

        // Only include start_date and end_date if they are selected
        if (selectedRange?.start && selectedRange?.end) {
            payload.start_date = selectedRange.start;
            payload.end_date = selectedRange.end;
        }

        const response = await axios.post(
            `/rent-vehicle`, // Replace with your backend route
            payload,
            {
                headers: {
                    "Content-Type": "application/json",
                },
            }
        );

        if (response.data.success) {       
            // Redirect user to the dynamic booking page
            window.location.href = response.data.redirect_url; 
        } else {
            alert(response.data.message || "Failed to rent vehicle.");
        }
    } catch (error) {
        console.error("Rent Now Error:", error);
        alert("An error occurred while renting the vehicle. Please try again.");
    }
};


  useEffect(() => {
    if (Array.isArray(bookings)) {
      const bookedDates = bookings.map((booking) => ({
        start: booking.start_date,
        end: booking.end_date,
        backgroundColor: "#ff9999",
        borderColor: "#ff6666",
        display: "background",
      }));
      setCalendarEvents(bookedDates);
    }
  }, [bookings]);

  const vehicleImages = Array.isArray(vehicle?.vechicle_image)
    ? vehicle?.vechicle_image
    : JSON.parse(vehicle?.vechicle_image || "[]");

  return (
    <div className="vehicle-details-container">
      <SearchvehicleFilter onSearch={handleSearch} onFilter={handleFilter} />

      <div className="vehicle-content-wrapper">
        <div className="vehicle-image-container">
          <ImageSlider imageUrls={vehicleImages} />
          <div className="vehicle-info">
            <span className="kms-driven">🚗 {vehicle?.kms_driven || "0"} kms driven</span>
            <span className="make-year">📅 {vehicle?.make_year || "Unknown Year"}</span>
          </div>
        </div>

        <div className="vehicle-details">
          <div className="vehicle-details-box">
            <h3>Vehicle Details</h3>
            <p><strong>Vehicle:</strong> {vehicle?.vechicle || "N/A"}</p>
            <p><strong>Brand:</strong> {vehicle?.brand || "Unknown Brand"}</p>
            <p><strong>Model:</strong> {vehicle?.model || "N/A"}</p>
            <p><strong>City:</strong> {vehicle?.city || "N/A"}</p>
            <p><strong>Shop Location:</strong> {vehicle?.shoplocation || "N/A"}</p>
            <p><strong>Price:</strong> <strong>{vehicle?.price || "N/A"} INR</strong></p>
          </div>
          <button className="book-now-button" onClick={handleRentNow}>Rent Now</button>
        </div>
      </div>

      <div className="location-calendar-section">
        <div className="location-container">
          <h5>Location</h5>
          <div className="map-container">
            <iframe
              title="Vehicle Location"
              src={`https://www.google.com/maps?q=${vehicle?.latitude || 0},${vehicle?.longitude || 0}&output=embed`}
              width="100%"
              height="300"
              frameBorder="0"
              style={{ border: 0, borderRadius: "10px" }}
              allowFullScreen
            ></iframe>
            <p>The vehicle will be parked nearby. You'll get the exact location after booking.</p>
          </div>
        </div>

        <div className="calendar-container">
          <div className="calendar-header">
            <div className="calendar-title">

            </div>
            <div className="calendar-legend">
              <div className="legend-item">
                <span className="legend-color available"></span> Available
              </div>
              <div className="legend-item">
                <span className="legend-color booked"></span> Booked
              </div>
            </div>
          </div>

          <div className="small-calendar" id="calendar1">
            <h5>Availibility</h5>
            {selectedRange && (
  <p style={{ backgroundColor: 'yellow', padding: '10px', borderRadius: '5px', marginBottom: '10px' }}>
    Selected Range: {selectedRange.start} to {new Date(selectedRange.end).toISOString().split("T")[0]}
  </p>
)}
            <FullCalendar
              plugins={[dayGridPlugin, timeGridPlugin, interactionPlugin]}
              initialView="dayGridMonth"
              selectable={true}
              selectMirror={true}
              events={calendarEvents}
              select={handleDateSelect}
              headerToolbar={{
                left: "prev,next",
                center: "title",
                right: "dayGridMonth,timeGridWeek,timeGridDay",
              }}
              height="auto"
              contentHeight="auto"
              aspectRatio={1.2}
              fixedWeekCount={false}
            />
          </div>
        </div>
      </div>
    </div>
  );
};

export default VehicleDetails;
Enter fullscreen mode Exit fullscreen mode

AI-Powered Event Recommendation (Smart Scheduling)

import * as tf from "@tensorflow/tfjs";

const eventData = [
  { day: 1, eventType: "meeting" },
  { day: 2, eventType: "workout" },
  { day: 3, eventType: "dinner" },
];

const predictEvent = async (day) => {
  const model = tf.sequential();
  model.add(tf.layers.dense({ units: 1, inputShape: [1] }));
  model.compile({ loss: "meanSquaredError", optimizer: "sgd" });

  const inputs = tf.tensor2d(eventData.map((e) => [e.day]));
  const outputs = tf.tensor2d(eventData.map((e) => [e.eventType === "meeting" ? 1 : 0]));

  await model.fit(inputs, outputs, { epochs: 10 });

  const prediction = model.predict(tf.tensor2d([[day]]));
  return prediction.dataSync();
};

predictEvent(4).then((event) => console.log("Predicted Event Type:", event > 0.5 ? "Meeting" : "Other"));
Enter fullscreen mode Exit fullscreen mode

Full code

import React, { useState, useEffect } from "react";
import FullCalendar from "@fullcalendar/react";
import dayGridPlugin from "@fullcalendar/daygrid";
import timeGridPlugin from "@fullcalendar/timegrid";
import interactionPlugin from "@fullcalendar/interaction";
import * as tf from "@tensorflow/tfjs";

const CalendarWithAI = () => {
  const [calendarEvents, setCalendarEvents] = useState([
    { title: "Meeting", start: "2025-01-21", id: "1" },
    { title: "Workout", start: "2025-01-22", id: "2" },
    { title: "Dinner", start: "2025-01-23", id: "3" },
  ]);

  const eventData = [
    { day: 1, eventType: "meeting" },
    { day: 2, eventType: "workout" },
    { day: 3, eventType: "dinner" },
  ];

  const predictEvent = async (day) => {
    const model = tf.sequential();
    model.add(tf.layers.dense({ units: 1, inputShape: [1] }));
    model.compile({ loss: "meanSquaredError", optimizer: "sgd" });

    const inputs = tf.tensor2d(eventData.map((e) => [e.day]));
    const outputs = tf.tensor2d(eventData.map((e) => [e.eventType === "meeting" ? 1 : 0]));

    await model.fit(inputs, outputs, { epochs: 10 });

    const prediction = model.predict(tf.tensor2d([[day]]));
    const eventType = (await prediction.data())[0] > 0.5 ? "Meeting" : "Other";

    return eventType;
  };

  const handleDateSelect = async (selectInfo) => {
    const selectedDay = new Date(selectInfo.startStr).getDate();
    const predictedEvent = await predictEvent(selectedDay);

    const newEvent = {
      id: String(calendarEvents.length + 1),
      title: predictedEvent,
      start: selectInfo.startStr,
    };

    setCalendarEvents([...calendarEvents, newEvent]);
    selectInfo.view.calendar.unselect();
  };

  return (
    <FullCalendar
      plugins={[dayGridPlugin, timeGridPlugin, interactionPlugin]}
      initialView="dayGridMonth"
      selectable={true}
      selectMirror={true}
      events={calendarEvents}
      select={handleDateSelect}
      headerToolbar={{
        left: "prev,next",
        center: "title",
        right: "dayGridMonth,timeGridWeek,timeGridDay",
      }}
      height="auto"
      contentHeight="auto"
      aspectRatio={1.2}
      fixedWeekCount={false}
    />
  );
};

export default CalendarWithAI;
Enter fullscreen mode Exit fullscreen mode

AI-Based Task Prioritization
💡 Reorders tasks dynamically based on deadlines, urgency, and importance.

📝 Implementation

const tasks = [
  { name: "Meeting", deadline: 1, importance: 3 },
  { name: "Workout", deadline: 3, importance: 2 },
];

const prioritizeTasks = (tasks) => {
  return tasks.sort((a, b) => (b.importance / b.deadline) - (a.importance / a.deadline));
};

console.log("Task Prioritization:", prioritizeTasks(tasks));
Enter fullscreen mode Exit fullscreen mode

Full code

import React, { useState, useEffect } from "react";
import FullCalendar from "@fullcalendar/react";
import dayGridPlugin from "@fullcalendar/daygrid";
import timeGridPlugin from "@fullcalendar/timegrid";
import interactionPlugin from "@fullcalendar/interaction";
import * as tf from "@tensorflow/tfjs";

const tasks = [
  { name: "Meeting", deadline: 1, importance: 3 },
  { name: "Workout", deadline: 3, importance: 2 },
];

const prioritizeTasks = (tasks) => {
  return tasks.sort((a, b) => (b.importance / b.deadline) - (a.importance / a.deadline));
};

console.log("Task Prioritization:", prioritizeTasks(tasks));

const CalendarWithAI = () => {
  const [calendarEvents, setCalendarEvents] = useState([
    { title: "Meeting", start: "2025-01-21", id: "1" },
    { title: "Workout", start: "2025-01-22", id: "2" },
    { title: "Dinner", start: "2025-01-23", id: "3" },
  ]);

  const eventData = [
    { day: 1, eventType: "meeting" },
    { day: 2, eventType: "workout" },
    { day: 3, eventType: "dinner" },
  ];

  const predictEvent = async (day) => {
    const model = tf.sequential();
    model.add(tf.layers.dense({ units: 1, inputShape: [1] }));
    model.compile({ loss: "meanSquaredError", optimizer: "sgd" });

    const inputs = tf.tensor2d(eventData.map((e) => [e.day]));
    const outputs = tf.tensor2d(eventData.map((e) => [e.eventType === "meeting" ? 1 : 0]));

    await model.fit(inputs, outputs, { epochs: 10 });

    const prediction = model.predict(tf.tensor2d([[day]]));
    const eventType = (await prediction.data())[0] > 0.5 ? "Meeting" : "Other";

    return eventType;
  };

  const handleDateSelect = async (selectInfo) => {
    const selectedDay = new Date(selectInfo.startStr).getDate();
    const predictedEvent = await predictEvent(selectedDay);

    const newEvent = {
      id: String(calendarEvents.length + 1),
      title: predictedEvent,
      start: selectInfo.startStr,
    };

    setCalendarEvents([...calendarEvents, newEvent]);
    selectInfo.view.calendar.unselect();
  };

  return (
    <FullCalendar
      plugins={[dayGridPlugin, timeGridPlugin, interactionPlugin]}
      initialView="dayGridMonth"
      selectable={true}
      selectMirror={true}
      events={calendarEvents}
      select={handleDateSelect}
      headerToolbar={{
        left: "prev,next",
        center: "title",
        right: "dayGridMonth,timeGridWeek,timeGridDay",
      }}
      height="auto"
      contentHeight="auto"
      aspectRatio={1.2}
      fixedWeekCount={false}
    />
  );
};

export default CalendarWithAI;
Enter fullscreen mode Exit fullscreen mode

AI-Powered Auto Reminders & Notifications
💡 Learns user behavior and predicts when they are likely to forget tasks.

const events = [
  { name: "Meeting", priority: 5 },
  { name: "Workout", priority: 2 },
];

const shouldSendReminder = (event) => event.priority >= 4;

events.forEach((event) => {
  if (shouldSendReminder(event)) console.log(`Reminder: ${event.name} coming up!`);
});
Enter fullscreen mode Exit fullscreen mode
import React, { useState, useEffect } from "react";
import FullCalendar from "@fullcalendar/react";
import dayGridPlugin from "@fullcalendar/daygrid";
import timeGridPlugin from "@fullcalendar/timegrid";
import interactionPlugin from "@fullcalendar/interaction";
import * as tf from "@tensorflow/tfjs";

const tasks = [
  { name: "Meeting", deadline: 1, importance: 3 },
  { name: "Workout", deadline: 3, importance: 2 },
];

const prioritizeTasks = (tasks) => {
  return tasks.sort((a, b) => (b.importance / b.deadline) - (a.importance / a.deadline));
};

console.log("Task Prioritization:", prioritizeTasks(tasks));

const events = [
  { name: "Meeting", priority: 5 },
  { name: "Workout", priority: 2 },
];

const shouldSendReminder = (event) => event.priority >= 4;

events.forEach((event) => {
  if (shouldSendReminder(event)) console.log(`Reminder: ${event.name} coming up!`);
});

const CalendarWithAI = () => {
  const [calendarEvents, setCalendarEvents] = useState([
    { title: "Meeting", start: "2025-01-21", id: "1" },
    { title: "Workout", start: "2025-01-22", id: "2" },
    { title: "Dinner", start: "2025-01-23", id: "3" },
  ]);

  const eventData = [
    { day: 1, eventType: "meeting" },
    { day: 2, eventType: "workout" },
    { day: 3, eventType: "dinner" },
  ];

  const predictEvent = async (day) => {
    const model = tf.sequential();
    model.add(tf.layers.dense({ units: 1, inputShape: [1] }));
    model.compile({ loss: "meanSquaredError", optimizer: "sgd" });

    const inputs = tf.tensor2d(eventData.map((e) => [e.day]));
    const outputs = tf.tensor2d(eventData.map((e) => [e.eventType === "meeting" ? 1 : 0]));

    await model.fit(inputs, outputs, { epochs: 10 });

    const prediction = model.predict(tf.tensor2d([[day]]));
    const eventType = (await prediction.data())[0] > 0.5 ? "Meeting" : "Other";

    return eventType;
  };

  const handleDateSelect = async (selectInfo) => {
    const selectedDay = new Date(selectInfo.startStr).getDate();
    const predictedEvent = await predictEvent(selectedDay);

    const newEvent = {
      id: String(calendarEvents.length + 1),
      title: predictedEvent,
      start: selectInfo.startStr,
    };

    setCalendarEvents([...calendarEvents, newEvent]);
    selectInfo.view.calendar.unselect();
  };

  return (
    <FullCalendar
      plugins={[dayGridPlugin, timeGridPlugin, interactionPlugin]}
      initialView="dayGridMonth"
      selectable={true}
      selectMirror={true}
      events={calendarEvents}
      select={handleDateSelect}
      headerToolbar={{
        left: "prev,next",
        center: "title",
        right: "dayGridMonth,timeGridWeek,timeGridDay",
      }}
      height="auto"
      contentHeight="auto"
      aspectRatio={1.2}
      fixedWeekCount={false}
    />
  );
};

export default CalendarWithAI;
Enter fullscreen mode Exit fullscreen mode

Image description

Top comments (0)