skip to Main Content

UPDATED CODE BELOW:
enter image description here

After doing a bit of workaround I can drag and drop boxes now however it drops at whatever timeslot is empty first rather dropping to actual timeslot for example, if I drop box to 26th t1 to 27th t2 then it will drop the box to t1 27th instead rather t2 and now lets say I drop to 29th t6 it will drop to 29th t3 as t1 and t2 are full and t3 is empty so does not drop to right timeslot instead drops to whatever timeslot if first empty for that date also once I load website again all the drag boxes I moved goes back to what it was before

updated code below

import React, { useState, useRef } from "react";
import { startOfWeek, endOfWeek, format, addDays, subDays, set } from "date-fns";
import "../assets/css/RunSheetPDF.css";

const DraggableBox = ({
day,
name: initialName,
suburb: initialSuburb,
calendarData,
setCalendarData,
changeName,
setChangeName,
changeSuburb,
setChangeSuburb,
setChangeDay,
setChangeData,
orderData,
setOrderData,
timeSlotIndex // Add the time slot index as a prop
}) => {
const [showTooltip, setShowTooltip] = useState(false);
const boxRef = useRef(null);

const filteredOrders = orderData.order.filter((order) => {
  const orderDate = new Date(order.RequiredDateAndTime).getDate();
  return orderDate === parseInt(day);
  });
const handleDragStart = (e) => {
setShowTooltip(false);
setChangeData(filteredOrders[timeSlotIndex]);
boxRef.current.classList.add("dragging");
};

const handleDragEnd = () => {
boxRef.current.classList.remove("dragging");
};


const handleDragOver = (e) => {
e.preventDefault();
};




  
console.log("Filtered Orders:", filteredOrders);

return (
<div
className="drag-box"
ref={boxRef}
draggable
onDragStart={handleDragStart}
onDragEnd={handleDragEnd}
onDragOver={handleDragOver}
onMouseEnter={() => setShowTooltip(true)}
onMouseLeave={() => setShowTooltip(false)}
style={{
width: "70px",
height: "80px",
textAlign: "center",
backgroundColor: "#F5F5F5",
color: "#333333",
marginTop: "5px",
position: "relative",
cursor: "move", // Set cursor to move when hovering over the box
}}
data-day={day} // Set the day as a dataset attribute
data-name={initialName} // Set the name as a dataset attribute
>
<div style={{ margin: 0, lineHeight: "40px" }}>
{/* Render order details based on time slot index */}
{filteredOrders[timeSlotIndex] && (
<div key={timeSlotIndex}>
{/* Render DelCity */}
<p style={{ margin: 0 }}>{filteredOrders[timeSlotIndex].Id}</p>
{/* Render DelPostalCode */}
<p style={{ margin: 0 }}>{filteredOrders[timeSlotIndex].DelCity}</p>
</div>
)}
</div>
</div>
);
};




const RunSheetPreview = ({
orderData,  
setOrderData,
  selectedDate,

  initialName,
  initialSuburb,
  setShowTooltip,
  }) => {
  const boxRef = useRef(null);
  const [changeName, setChangeName] = useState("");
  const [changeDay, setChangeDay] = useState(null);
  const [changeData, setChangeData] = useState(null);
 
  const [changeSuburb, setChangeSuburb] = useState(null);
  const [selectedDateState, setSelectedDate] = useState(new Date());
  
  const formatDate = (date) => {
  const dateVal = new Date(date);
  const year = dateVal.getFullYear();
  const month = String(dateVal.getMonth() + 1).padStart(2, "0");
  const day = String(dateVal.getDate()).padStart(2, "0");
  return `${year}-${month}-${day}`;
};
const handleDragOver = (e) => {
  e.preventDefault();
  };


   const handleDrop = (e, timeSlotIndex, dayOfMonth, year, month) => {
  e.preventDefault();
  e.stopPropagation();
  
  // Parse the date and update the order data
  let d = { ...changeData };
  d = new Date(d.OrderDate);
  
  const number = e.target.tabIndex.toString();
  console.log("Number:", number);


    const currentYear = e.target.getAttribute('data-year');
  const currentMonth = e.target.getAttribute('data-month');
  console.log("Current Year:", currentYear);
  console.log("Current Month:", currentMonth);
  
  let day = Number(number);
  console.log("Day:", day);
  
  d.setDate(day);
  d.setMonth(currentMonth);
  d.setFullYear(currentYear);
  d = d.toISOString();
  
  let fi = { ...changeData };
  fi.OrderDate = d;
  fi.RequiredDateAndTime = d;
  
  let newDate = new Date(changeData.OrderDate);
  newDate = new Date(currentYear, currentMonth, day, newDate.getHours(), newDate.getMinutes(), newDate.getSeconds());

  // Update the order data
   let newOrderData = orderData.order.filter(item => item !== changeData);

  // Update the order date for the dragged item to its new position
  changeData.OrderDate = newDate.toISOString();
  changeData.RequiredDateAndTime = newDate.toISOString();
  const timeSlot = `t${timeSlotIndex + 1}`;
  console.log("Time Slot:", timeSlot);

  // Push the updated dragged item to the new position
  newOrderData.push({ ...changeData, timeSlot });
 
  // Update the order data state
  //orderData.order = newOrderData; // Update the order data
   setCalendarData(newOrderData);
//   setChangeData(newOrderData[timeSlotIndex]);
  
console.log("Updated order data:", newOrderData);
};

// Remove the filter based on selectedDate
const dateStrings = orderData.order.map((listItem) => {
  const date = new Date(listItem.RequiredDateAndTime);
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, "0");
  const day = String(date.getDate()).padStart(2, "0");
  return `${year}-${month}-${day}`;
});

const initialCalendarData = orderData.order.map((order, index) => {
  const name = order.DelCity;
  const suburb = order.DelPostalCode;
  return {
    day: dateStrings[index], // Use dateStrings array here
    name,
    suburb,
    initialName: name, // Assign the value to initialName
    initialSuburb: suburb, // Assign the value to initialSuburb
  };
});
const [calendarData, setCalendarData] = useState(initialCalendarData);




//console.log("Calendar Data:", calendarData);
//console.log("formatDate Data:", formatDate);
//console.log("filteredOrders Data:", filteredOrders);
//console.log("dateStrings Data:", dateStrings);
//console.log("Order Data:", orderData);
 


const generateCalendar = (timeSlotIndex ) => {
  const startDate = startOfWeek(selectedDate, { weekStartsOn: 0 });
  const endDate = endOfWeek(selectedDate, { weekStartsOn: 0 });

  const rows = [];
  let day = startDate;

  while (day <= endDate) {
const formattedDate = formatDate(day);
    const dateObject = new Date(formattedDate);
const year = dateObject.getFullYear(); // Extract year (e.g., 2024)
const month = dateObject.getMonth() + 1;    
    console.log("Month:", month);
    console.log("Year:", year);
    const dayName = format(day, "EEEE");
    const dayOfMonth = format(day, "d");
console.log("dayofmonth", dayOfMonth);
  
console.log("format date",formattedDate);
    const isTargetDate = dateStrings.includes(formattedDate);

    const ordersForDay = orderData.order.filter(order => {
      const orderDate = new Date(order.RequiredDateAndTime).getDate();
      return orderDate === parseInt(dayOfMonth);
    });
  
      // Find the first available time slot for the current day
      const firstAvailableSlot = ordersForDay.findIndex(order => !order.isAssigned);
  
      const row = (
        <tr key={day}>
          <td className="calendar-cell">
            <div className="day-name">{dayName}</div>
            <div className="day-number">{dayOfMonth}</div>
      
          </td>
          {[...Array(10)].map((_, index) => (
            <td key={index} className={`grid-cell`} data-has-data={ordersForDay[index] ? "true" : "false"} >
              {/* Render DraggableBox only if there is an order for this column */}
              {ordersForDay[index] && (
                <DraggableBox
                  day={parseInt(dayOfMonth)}
                  initialName={ordersForDay[index].DelCity}
                  initialSuburb={ordersForDay[index].DelPostalCode}
                  calendarData={calendarData}
                  setCalendarData={setCalendarData}
                  changeName={changeName}
                  setOrderData={setOrderData} // Pass the setOrderData function
                  setChangeName={setChangeName}
                  changeDay={changeDay}
                  setChangeDay={setChangeDay}
                  changeSuburb={changeSuburb}
                  setChangeSuburb={setChangeSuburb}
                  setChangeData={setChangeData}
                  orderData={orderData}
                  timeSlotIndex={index} 
                />
              )}
              {!ordersForDay[index] && (
                <p
                  style={{
                    height: "90px",
                    display: "flex",
                    alignItems: "center",
                    justifyContent: "center",
                  }}
                  onDragOver={handleDragOver}
                 onDrop={(e) => handleDrop(e, index, parseInt(dayOfMonth), year, month)}

                  tabIndex={dayOfMonth}
                  data-year={year}
                  data-month={month}
                  ></p>
                  )}
                </td>
              ))}
            </tr>
          );
      
          rows.push(row);
      
          day = addDays(day, 1);
        }
      
        return rows;
      };
      
      
      
      const handleNextWeek = () => {
      setSelectedDate(addDays(selectedDate, 7));
      };
      const handlePreviousWeek = () => {
        setSelectedDate(subDays(selectedDate, 7));
};
return (
<div style={{ width: "100%", display: "flex", flexDirection: "column", alignItems: "center", marginTop: "20px" }}>
<div style={{ display: "flex", alignItems: "center", justifyContent: "center", marginBottom: "0px" }}>
<h2 style={{ color: "#333333", margin: 0 }}>{format(startOfWeek(selectedDate), "MMMM d")} - {format(endOfWeek(selectedDate), "MMMM d, yyyy")}</h2>
</div>
<div className="calendar-container">
<table className="calendar-table">
<thead>
<tr>
<th>{/* Empty header cell for labels */}</th>

{[...Array(10)].map((_, index) => (
<th key={index}>t{index + 1}</th>
))}

</tr>
</thead>
<tbody>
{generateCalendar()}
</tbody>
</table>
</div>
</div>
);
};

export default RunSheetPreview;

also the data I am using is just order no so it could be any such as 190, 182 etc and suburb name in the dragbox

2

Answers


  1. The code is as explained in the chat room.

    import React, { useState, useRef } from "react";
    import { startOfWeek, endOfWeek, format, addDays, subDays } from "date-fns";
    import "./RunSheetPDF.css";
    
    const DraggableBox = ({
      day,
      initialName,
      initialSuburb,
      setChangeData,
      orderData,
      timeSlotIndex, // Add the time slot index as a prop
    }) => {
      const [showTooltip, setShowTooltip] = useState(false);
      const boxRef = useRef(null);
    
      const handleDragStart = (e) => {
        setShowTooltip(false);
        setChangeData(filteredOrders[timeSlotIndex]);
        boxRef.current.classList.add("dragging");
      };
    
      const handleDragEnd = () => {
        boxRef.current.classList.remove("dragging");
      };
    
      const filteredOrders = orderData.order.filter((order) => {
        const orderDate = new Date(order.RequiredDateAndTime).getDate();
        return orderDate === parseInt(day);
      });
    
      return (
        <div
          className="drag-box"
          ref={boxRef}
          draggable
          onDragStart={handleDragStart}
          onDragEnd={handleDragEnd}
          onMouseEnter={() => setShowTooltip(true)}
          onMouseLeave={() => setShowTooltip(false)}
          style={{
            height: "80px",
            textAlign: "center",
            backgroundColor: "#F5F5F5",
            color: "#333333",
            marginTop: "5px",
            position: "relative",
            cursor: "move", // Set cursor to move when hovering over the box
          }}
          data-day={day} // Set the day as a dataset attribute
          data-name={initialName} // Set the name as a dataset attribute
        >
          <div style={{ margin: 0, lineHeight: "40px" }}>
            {filteredOrders[timeSlotIndex] && (
              <div key={timeSlotIndex}>
                <p style={{ margin: 0 }} className="el">
                  {filteredOrders[timeSlotIndex].DelCity}
                </p>
                <p style={{ margin: 0 }}>
                  {filteredOrders[timeSlotIndex].DelPostalCode}
                </p>
              </div>
            )}
          </div>
    
          {showTooltip && (
            <div className="tooltip">
              <p style={{ margin: 0 }}>{initialName}</p>
              <p style={{ margin: 0 }}>{initialSuburb}</p>
            </div>
          )}
        </div>
      );
    };
    
    const RunSheetPreview = ({ selectedDate = "2023-08-27", orderData }) => {
      const boxRef = useRef(null);
      const [changeData, setChangeData] = useState(null);
      const [selectedDateState, setSelectedDateState] = useState(new Date());
    
      const formatDate = (date) => {
        const dateVal = new Date(date);
        const year = dateVal.getFullYear();
        const month = String(dateVal.getMonth() + 1).padStart(2, "0");
        const day = String(dateVal.getDate()).padStart(2, "0");
        return `${year}-${month}-${day}`;
      };
    
      const formatDate1 = (date) => {
        const dateVal = new Date(date);
        const year = dateVal.getFullYear();
        const month = String(dateVal.getMonth() + 1).padStart(2, "0");
        const day = String(dateVal.getDate()).padStart(2, "0");
        return `${year}${month}${day}`;
      };
    
      const initialCalendarData = orderData.order.map((order) => ({
        day: 31, // Assuming day 31 is default for all orders, you can change this if needed
        date: order.RequiredDateAndTime,
        name: order.DelCity,
        suburb: order.DelPostalCode,
      }));
    
      // console.log(initialCalendarData);
    
      const [calendarData, setCalendarData] = useState(initialCalendarData);
    
      let filteredOrders = [];
    
      let startDate = startOfWeek(selectedDate, { weekStartsOn: 0 });
      const endDate = endOfWeek(selectedDate, { weekStartsOn: 0 });
    
      while (startDate <= endDate) {
        let fO = [];
        fO = orderData.order.filter(myF);
        startDate = addDays(startDate, 1);
      }
      function myF(order) {
        if (order.RequiredDateAndTime.substring(0, 10) === formatDate(startDate)) {
          filteredOrders.push(order);
        }
      }
    
      const dateStrings = filteredOrders.map((listItem, index) => {
        const date = new Date(listItem.RequiredDateAndTime);
        const day = String(date.getDate()).padStart(2, "0");
        const year = date.getFullYear();
        const month = String(date.getMonth() + 1).padStart(2, "0");
        return `${year}-${month}-${day}`;
      });
    
      const dayStrings = filteredOrders.map((listItem, index) => {
        const date = new Date(listItem.RequiredDateAndTime);
        const day = String(date.getDate()).padStart(2, "0");
        return day;
      });
    
      // dayStrings.map((day) => {
      //   const parsedDay = parseInt(day);
      //   console.log("Parsed Day:", parsedDay); //returns 31
      // });
    
      // console.log("Calendar Data:", calendarData);
      // console.log("formatDate Data:", formatDate);
      // console.log("filteredOrders Data:", filteredOrders);
      // console.log("dayStrings Data:", dayStrings);
      // console.log("dateStrings Data:", dateStrings);
      // console.log("Order Data:", orderData);
      const generateCalendar = () => {
        const startDate = startOfWeek(selectedDate, { weekStartsOn: 0 });
        const endDate = endOfWeek(selectedDate, { weekStartsOn: 0 });
    
        const rows = [];
        let day = startDate;
    
        while (day <= endDate) {
          const cellDate = formatDate1(day);
          const dayName = format(day, "EEEE");
          const dayOfMonth = format(day, "d");
    
          const formattedDate = formatDate(day);
    
          const isTargetDate = dateStrings.includes(formattedDate);
    
          const ordersForDay = filteredOrders.filter((order) => {
            const orderDate = new Date(order.RequiredDateAndTime).getDate();
            return orderDate === parseInt(dayOfMonth);
          });
    
          // Find the first available time slot for the current day
          const firstAvailableSlot = ordersForDay.findIndex(
            (order) => !order.isAssigned
          );
    
          const handleDragOver = (e) => {
            e.preventDefault();
          };
    
          const handleDrop = (e) => {
            e.preventDefault();
            e.stopPropagation();
    
            let d = { ...changeData };
            d = new Date(d.OrderDate);
    
            const number = e.target.tabIndex.toString();
    
            let year = Number(number.substring(0, 4));
    
            let month = number.substring(4).substring(0, 2);
            month =
              Number(month.substring(0, 1)) === 0
                ? Number(month.substring(1)) - 1
                : Number(month) - 1;
    
            let day = number.substring(6);
            day =
              Number(day.substring(0, 1)) === 0
                ? Number(day.substring(1))
                : Number(day);
    
            d.setDate(day);
            d.setMonth(month);
            d.setFullYear(year);
            d = d.toISOString();
    
            let fi = { ...changeData };
            fi.OrderDate = d;
            fi.RequiredDateAndTime = d;
    
            let newOrderData = orderData.order.filter(myFilter);
            function myFilter(item) {
              if (item === changeData) {
                return;
              }
              return item;
            }
            newOrderData.push(fi);
            // console.log(orderData.order);
            orderData.order = newOrderData;
            // console.log(orderData.order);
          };
    
          const row = (
            <tr key={day}>
              <td className="calendar-cell">
                <div className="day-name">{dayName}</div>
                <div className="day-number">{dayOfMonth}</div>
              </td>
              {[...Array(10)].map((_, index) => (
                <td
                  key={index}
                  className={`grid-cell`}
                  data-has-data={ordersForDay[index] ? "true" : "false"}
                >
                  {/* Render DraggableBox only if there is an order for this column */}
                  {ordersForDay[index] ? (
                    <DraggableBox
                      day={parseInt(dayOfMonth)}
                      initialName={ordersForDay[index].DelCity}
                      initialSuburb={ordersForDay[index].DelPostalCode}
                      setChangeData={setChangeData}
                      orderData={orderData}
                      timeSlotIndex={index} // Pass the index of the time slot
                    />
                  ) : (
                    <p
                      style={{
                        height: "90px",
                        display: "flex",
                        alignItems: "center",
                        justifyContent: "center",
                      }}
                      onDragOver={handleDragOver}
                      onDrop={handleDrop}
                      tabIndex={cellDate}
                    ></p>
                  )}
                </td>
              ))}
            </tr>
          );
    
          rows.push(row);
    
          day = addDays(day, 1);
        }
    
        return rows;
      };
    
      const handleNextWeek = () => {
        setSelectedDateState(addDays(selectedDate, 7));
      };
      const handlePreviousWeek = () => {
        setSelectedDateState(subDays(selectedDate, 7));
      };
    
      return (
        <div
          style={{
            width: "100%",
            display: "flex",
            flexDirection: "column",
            alignItems: "center",
            marginTop: "20px",
          }}
        >
          <div
            style={{
              display: "flex",
              alignItems: "center",
              justifyContent: "center",
              marginBottom: "0px",
            }}
          >
            <h2 style={{ color: "#333333", margin: 0 }}>
              {format(startOfWeek(selectedDate), "MMMM d")} -{" "}
              {format(endOfWeek(selectedDate), "MMMM d, yyyy")}
            </h2>
          </div>
          <div className="calendar-container">
            <table className="calendar-table">
              <thead>
                <tr>
                  <th></th> {/* Empty header cell for labels */}
                  {[...Array(10)].map((_, index) => (
                    <th key={index}>t{index + 1}</th>
                  ))}
                </tr>
              </thead>
              <tbody>{generateCalendar()}</tbody>
            </table>
          </div>
        </div>
      );
    };
    
    export default RunSheetPreview;
    
    Login or Signup to reply.
  2. In your handleDrop function, you’re currently calculating the new date based on the day retrieved from the tabIndex attribute of the drop target. Instead, you should use the day of the week provided by the calendar grid cell where the drop occurred. You can calculate the correct date by adding the dayOfMonth value (from the calendar grid cell) to the start date of the week.

    Replace this line

    const day = Number(number);
    

    with this line

    const day = dayOfMonth;
    

    You need to implement functionality to save the modified orderData to a backend server or a local storage solution like localStorage. When the page loads, you should retrieve this saved data and initialize your state with it.
    You can save orderData to localStorage whenever it changes:

    localStorage.setItem('orderData', JSON.stringify(orderData));
    
    useEffect(() => {
      const savedData = JSON.parse(localStorage.getItem('orderData'));
      if (savedData) {
        setOrderData(savedData);
      }
    }, []);
    

    Ensure that changes made to the calendar persist even after a page reload, you should save the modified data to a persistent storage solution such as localStorage or a backend server.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search