Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue Displaying the Calendar within vite react app #2522

Open
5 tasks done
nourbenamor2001 opened this issue Feb 26, 2024 · 2 comments
Open
5 tasks done

Issue Displaying the Calendar within vite react app #2522

nourbenamor2001 opened this issue Feb 26, 2024 · 2 comments
Labels

Comments

@nourbenamor2001
Copy link

nourbenamor2001 commented Feb 26, 2024

Check that this is really a bug

  • I confirm

Reproduction link

n/a

Bug description

image
image
image
image

I have requested to display some event data (dummy data, not actual backend api calls) to my react big calendar monthly and agenda cells. But the monthly calendar and the agenda do not show as seen in the images. This might be due to a responsiveness issue, but I doubt it because the Day and Week cells display quite properly. I think it might be in my code, please help me if you have any idea :

import React, { useState, useMemo } from 'react';
import { Calendar, momentLocalizer } from 'react-big-calendar';
import 'react-big-calendar/lib/css/react-big-calendar.css';
import moment from 'moment';
import { bookings } from '../../../data/dummy'; // Import bookings data from dummy.js
import HomeP from '../Home/Home';

const localizer = momentLocalizer(moment);

export default function Schedule() {
  const [showModal, setShowModal] = useState(false);
  const [selectedEvent, setSelectedEvent] = useState(null);

  const events = bookings.map(booking => {
    const start = moment(booking.eventStartDate).toDate();
    const end = moment(booking.eventEndDate).toDate();

    return {
      id: booking.id, // Adding a unique ID for each event
      start,
      end,
      title: booking.eventType,
      data: {
        booking: {
          id: booking.id,
          status: booking.bookingStatus,
          resource: booking.customerName,
          address: booking.eventLocation, // Changed to eventLocation
          packageOrders: booking.packageOrders,
          packageQuantity: booking.packageQuantity,
          discount: booking.discount,
          total: booking.total,
          delivery_needed: booking.delivery_needed // Corrected to delivery_needed
        }
      }
    };
  });

  const handleSelectEvent = (event) => {
    setShowModal(true);
    setSelectedEvent(event);
  };

  const deleteEvent = () => {
    // Implement logic to delete the selected event from your data source
    console.log("Event deleted:", selectedEvent);
    setShowModal(false);
  };

  const confirmEvent = () => {
    // Implement logic to change the status of the selected event to 'Confirmed'
    console.log("Event confirmed:", selectedEvent);
    setShowModal(false);
  };

  const closeModal = () => {
    setShowModal(false);
  };

  const bookingData = selectedEvent?.data?.booking; // Defensive access

  const components = useMemo(
    () => ({
      event: ({event}) => {
        const eventStatus = event?.data?.booking?.status;
        switch (eventStatus) {
          case 'Confirmed':
            return <div style={{ background: '#94A684', height: '100%' }}>{event.title}</div>;
          case 'Pending':
            return <div style={{ background: '#FFC090', height: '100%' }}>{event.title}</div>;
          default:
            return <div></div>;
        }
      },
      agenda: {
        event: ({ event }) => (
          <div>
            <h3>Event Details:</h3>
            <p><strong>Title:</strong> {event.title}</p>
            <p><strong>Customer:</strong>{event.data.booking.resource}</p>
            <p><strong>Status:</strong> {event.data.booking.status}</p>
            <p><strong>Address:</strong> {event.data.booking.address}</p>
            <p><strong>Delivery:</strong> {event.data.booking.delivery_needed ? 'Yes' : 'No'}</p>
            <p><strong>Package Orders:</strong></p>
            <ul>
              {event.data.booking.packageOrders.map((order, index) => (
                <li key={index}>
                  {order} - Quantity: {event.data.booking.packageQuantity[index]}
                </li>
              ))}
            </ul>
            <p><strong>Discount:</strong> {event.data.booking.discount}</p>
            <p><strong>Total:</strong> {event.data.booking.total}</p>
          </div>
        )
      }
    }),
    []
  );

  return (
    <>
    <div style={{ height: '100%', width: '100%',  backgroundColor: "#f8f9fa" }}>
    {console.log(events)}
      <Calendar
        localizer={localizer}
        events={events}
        components={components}
        style={{ margin: '50px' }}
        selectable={true}
     
        onSelectEvent={handleSelectEvent}
      />
      {showModal && (
        <div className="modal" style={{ display: 'block', backgroundColor: "rgba(0,0,0,0.15)", position: 'fixed', top: 0, bottom: 0, left: 0, right: 0 }}>
          <div className="modal-dialog">
            <div className="modal-content">
              <div className="modal-header">
                <h5 className="modal-title">Event Title : {selectedEvent.title}</h5>
                <button type="button" className="btn-close" onClick={closeModal}></button>
              </div>
              <div className="modal-body">
                <p><strong>Status :</strong> {bookingData.status}</p>
                <p><strong>Customer :</strong> {bookingData.resource}</p>
                <p><strong>Location :</strong> {bookingData.address}</p>
                <p><strong>Delivery:</strong> {bookingData.delivery_needed ? 'Yes' : 'No'}</p>
                <p><strong>Package Orders:</strong></p>
                <ul>
                  {bookingData.packageOrders.map((order, index) => (
                    <li key={index}>
                      {order} : {bookingData.packageQuantity[index]}
                    </li>
                  ))}
                </ul>
                <p><strong>Discount:</strong> {bookingData.discount}</p>
                <p><strong>Total :</strong> {bookingData.total}</p>
              </div>
              <div className="modal-footer">
                <button type="button" className="btn btn-danger" onClick={deleteEvent}>Refuse</button>
                {/* Refuse deletes the event */}
                <button type="button" className="btn btn-success" onClick={confirmEvent}>Confirm</button>
                {/* Confirm changes event status to green */}
                <button type="button" className="btn btn-warning" onClick={closeModal}>Cancel</button> 
              </div>
            </div>
          </div>
        </div>
      )}
    </div>
    </>
  );
}


Expected Behavior

I expected the Monthly and Agenda cells to display properly in the frontend, but only the week and day cells properly show. This might be due to me sending data for the agenda and monthly calendar to display.

this is the data :

export const bookings =[
    {
      id:1,
      eventType:"Wedding",
      eventStartDate:"2024/02/24 12:00:00",
      eventEndDate:"2024/02/24 16:00:00",
      eventLocation:"address, City, Country",
      customerName:'Marwa Bouselmi',
      packageOrders:[services[0].packages[0].title,services[1].packages[2].title],
      packageQuantity:[3, 4],
      discount:0.2,
      total:249.80,
      delivery_needed:true,
      bookingStatus:"Pending",
    },
    {
      id:2,
      eventType:"Wedding",
      eventStartDate:"2024/02/23 12:00:00",
      eventEndDate:"2024/02/23 16:00:00",
      eventLocation:"address, City, Country",
      customerName:'Marwa Bouselmi',
      packageOrders:[services[0].packages[1].title, services[1].packages[0].title],
      packageQuantity:[3, 4],
      discount:0.2,
      total:249.80,
      delivery_needed:true,
      bookingStatus:"Confirmed",
    },
    {
      id:3,
      eventType:"Wedding",
      eventStartDate:"2024/03/24 12:00:00",
      eventEndDate:"2024/03/24 16:00:00",
      eventLocation:"address, City, Country",
      customerName:'Marwa Bouselmi',
      packageOrders:[services[0].packages[2].title, services[1].packages[1].title],
      packageQuantity:[3, 4],
      discount:0.2,
      total:249.80,
      delivery_needed:true,
      bookingStatus:"Pending",
    },
];`

Actual Behavior

I tried to console.log the events, and they render properly :
image

I get one warning :
image

react-big-calendar version

1.9.1

React version

18.2.0

Platform/Target and Browser Versions

Windows 10

Validations

  • Read the docs.
  • Check that there isn't already an issue that request the same feature to avoid creating a duplicate.
  • Make sure this is a react-big-calendar issue and not an implementation issue

Would you like to open a PR for this bug?

  • I'm willing to open a PR
@nourbenamor2001
Copy link
Author

I tried fixing the issue by adding a useEffect and parse the date strings using moment.

import React, { useState, useEffect, useMemo } from 'react';
import { Calendar, momentLocalizer } from 'react-big-calendar';
import 'react-big-calendar/lib/css/react-big-calendar.css';
import moment from 'moment';
import { bookings } from '../../../data/dummy'; // Import bookings data from dummy.js

const localizer = momentLocalizer(moment);

export default function Schedule() {
  const [showModal, setShowModal] = useState(false);
  const [selectedEvent, setSelectedEvent] = useState(null);
  const [events, setEvents] = useState([]);

  useEffect(() => {
    const transformedEvents = bookings.map(booking => ({
      id: booking.id,
      start: moment(booking.eventStartDate, "YYYY/MM/DD HH:mm:ss").toDate(),
      end: moment(booking.eventEndDate, "YYYY/MM/DD HH:mm:ss").toDate(),
      title: booking.eventType,
      data: {
        booking: {
          id: booking.id,
          status: booking.bookingStatus,
          resource: booking.customerName,
          address: booking.eventLocation,
          packageOrders: booking.packageOrders,
          packageQuantity: booking.packageQuantity,
          discount: booking.discount,
          total: booking.total,
          delivery_needed: booking.delivery_needed
        }
      }
    }));
    setEvents(transformedEvents);
  }, []); // Empty dependency array ensures this effect runs only once, similar to componentDidMount

  const handleSelectEvent = (event) => {
    setShowModal(true);
    setSelectedEvent(event);
  };

  const deleteEvent = () => {
    // Implement logic to delete the selected event from your data source
    console.log("Event deleted:", selectedEvent);
    setShowModal(false);
  };

  const confirmEvent = () => {
    // Implement logic to change the status of the selected event to 'Confirmed'
    console.log("Event confirmed:", selectedEvent);
    setShowModal(false);
  };

  const closeModal = () => {
    setShowModal(false);
  };

  const bookingData = selectedEvent?.data?.booking; // Defensive access

  const components = useMemo(
    () => ({
      event: ({ event }) => {
        const eventStatus = event?.data?.booking?.status;
        switch (eventStatus) {
          case 'Confirmed':
            return <div style={{ background: '#94A684', height: '100%' }}>{event.title}</div>;
          case 'Pending':
            return <div style={{ background: '#FFC090', height: '100%' }}>{event.title}</div>;
          default:
            return <div></div>;
        }
      },
      agenda: {
        event: ({ event }) => (
          <div>
            <h3>Event Details:</h3>
            <p><strong>Title:</strong> {event.title}</p>
            <p><strong>Customer:</strong>{event.data.booking.resource}</p>
            <p><strong>Status:</strong> {event.data.booking.status}</p>
            <p><strong>Address:</strong> {event.data.booking.address}</p>
            <p><strong>Delivery:</strong> {event.data.booking.delivery_needed ? 'Yes' : 'No'}</p>
            <p><strong>Package Orders:</strong></p>
            <ul>
              {event.data.booking.packageOrders.map((order, index) => (
                <li key={index}>
                  {order} - Quantity: {event.data.booking.packageQuantity[index]}
                </li>
              ))}
            </ul>
            <p><strong>Discount:</strong> {event.data.booking.discount}</p>
            <p><strong>Total:</strong> {event.data.booking.total}</p>
          </div>
        )
      }
    }),
    []
  );

  return (
    <>
      <div style={{ height: '100%', width: '100%', backgroundColor: "#f8f9fa" }}>
        <Calendar
          localizer={localizer}
          events={events}
          components={components}
          style={{ margin: '50px' }}
          selectable={true}
          onSelectEvent={handleSelectEvent}
        />
        {showModal && (
          <div className="modal" style={{ display: 'block', backgroundColor: "rgba(0,0,0,0.15)", position: 'fixed', top: 0, bottom: 0, left: 0, right: 0 }}>
            <div className="modal-dialog">
              <div className="modal-content">
                <div className="modal-header">
                  <h5 className="modal-title">Event Title : {selectedEvent.title}</h5>
                  <button type="button" className="btn-close" onClick={closeModal}></button>
                </div>
                <div className="modal-body">
                  <p><strong>Status :</strong> {bookingData.status}</p>
                  <p><strong>Customer :</strong> {bookingData.resource}</p>
                  <p><strong>Location :</strong> {bookingData.address}</p>
                  <p><strong>Delivery:</strong> {bookingData.delivery_needed ? 'Yes' : 'No'}</p>
                  <p><strong>Package Orders:</strong></p>
                  <ul>
                    {bookingData.packageOrders.map((order, index) => (
                      <li key={index}>
                        {order} : {bookingData.packageQuantity[index]}
                      </li>
                    ))}
                  </ul>
                  <p><strong>Discount:</strong> {bookingData.discount}</p>
                  <p><strong>Total :</strong> {bookingData.total}</p>
                </div>
                <div className="modal-footer">
                  <button type="button" className="btn btn-danger" onClick={deleteEvent}>Refuse</button>
                  {/* Refuse deletes the event */}
                  <button type="button" className="btn btn-success" onClick={confirmEvent}>Confirm</button>
                  {/* Confirm changes event status to green */}
                  <button type="button" className="btn btn-warning" onClick={closeModal}>Cancel</button>
                </div>
              </div>
            </div>
          </div>
        )}
      </div>
    </>
  );
}

But it displays another warning :
image

@cutterbl
Copy link
Collaborator

@nourbenamor2001 Questions like this are best served from our Slack group or StackOverflow.

I see you figured out your date parsing issue (I always suggest that, when using string date values from your datasource, use UTC date/time format YYYY-MM-DDTHH:mm:ssZ. It's fully compliant, and conversion to JS Date is straight forward).

The React warning you received at the end is, as it says, a warning. It does not effect code execution in any way. It's a note from the React team that support will eventually be removed. We have an update for this in the works.

Your standard event replacement object would render an empty div if it did not have certain status. Also, you're doing this when you likely just want to use an eventPropGetter to apply a specific backgroundColor to your event display.

As far as overriding your Agenda Event, we'd really need to see some running code in a CodeSandbox.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants