Whenever I drag a different YV_Class component into a YV_Quarter that has already had a class dragged into it, the class that was already inside the YV_Quarter gets removed. enter image description here
import { useDrag } from "react-dnd";
import { removeCourse, YV_DataContext } from './YV_DataContext.jsx';
import { useContext } from "react";
// num: ELEC_ENG 195-0
// name: Special Topics in Electrical Engineering
export default function YV_Class({ id, year, semester, num, name }) { // add id
const testData = useContext(YV_DataContext);
const [{ isDragging }, drag, dragPreview] = useDrag(() => ({
type: 'COURSE',
item: () => {
return {item, num, name};
}, // issue: the num and name don't change on new drag
isDragging: () => {
if (year && semester) {
removeCourse({"num": num, "name": name});
}
},
collect: (monitor) => ({
isDragging: monitor.isDragging()
})
}));
return (
<div ref={dragPreview} style={{ opacity: isDragging ? 0.5 : 1 }}>
<div
// role="Handle"
ref={drag}
className="bg-blue-200 rounded-lg p-4"
>
<p>{num}</p>
<p>{name}</p>
</div>
</div>
);
}
import { useDrop } from "react-dnd";
import { addCourse } from './YV_DataContext.jsx';
import YV_Class from "./YV_Class";
// on drop, remove course from previous location
// how to store previous location (year, semester)?
//
// courseList: [{num, name}, {num, name}... ]
export default function YV_Quarter({ year, semester, courseList }) {
const [{ isOver }, drop] = useDrop(() => ({
accept: 'COURSE',
drop: (course) => {
addCourse(year, semester, course);
},
canDrop: (item) => {
for (let i in courseList) {
if (courseList[i].num === item.num) {
return false;
}
}
return true;
},
collect: (monitor) => ({
isOver: monitor.isOver()
})
}));
return (
<div
ref={drop}
role={'Dustbin'}
style={{ backgroundColor: isOver ? 'red' : 'white' }}
className="container p-3 m-auto h-auto flex flex-col gap-4 bg-yellow-400"
>
{
courseList.map((course, i) => (
<YV_Class key={i} id={course.id} year={year} semester={semester} num={course.num} name={course.name}/>
))
}
</div>
);
}
import { createContext } from "react";
import fourYearPlan from '../assets/four-year-plan.json';
let planData = fourYearPlan;
const YV_DataContext = createContext(planData);
// year: string ("2022-2023")
// semester: string ("FALL", "WINTER", "SPRING")
// course: object ({num, name})
function addCourse(year, semester, course) {
planData[year][semester].push(course);
}
function removeCourse(course) {
iterate(planData, course);
}
function iterate(obj, course) {
// console.log(`course: ${JSON.stringify(course)}`);
let objKeys = Object.keys(obj);
loop: for (let i in objKeys) {
let key = objKeys[i];
if (typeof obj[key] === 'object' && !Array.isArray(obj[key]) && obj[key] !== null) {
iterate(obj[key], course);
}
else if (Array.isArray(obj[key])) {
for (let item of obj[key]) {console.log(item)};
const courseIndex = obj[key].findIndex((arrCourse) => {
return arrCourse.num === course.num;
});
console.log(courseIndex);
if (courseIndex > -1) {
obj[key].splice(courseIndex, 1);
break loop;
}
}
}
}
export {
YV_DataContext, addCourse, removeCourse
}
YV_Classes dragged from here:
import { useState } from "react";
import YV_Class from "../years-view/YV_Class";
import courselist from "../assets/class-list.json";
// courseList: [{num, name}, {num, name}... ]
const searchCourseList = courselist.map((course) => (
{
num: `${course["SUBJECT"].toUpperCase()} ${course["CLASSDESCR"]["CATALOG_NBR"]}`,
name: course["CLASSDESCR"]["COURSE_TITLE"]
}
))
export default function CourseSearch() {
// querying
const [query, setQuery] = useState("");
function handleQuery(e) {
e.preventDefault();
setQuery(e.target.value);
}
// code for sorting
/*
const handleDragEnd = (e) => {
const { active, over } = e;
if (active.id !== over.id) {
setdraggableIDs((draggableIDs) => {
const oldIndex = draggableIDs.indexOf(active.id);
const newIndex = draggableIDs.indexOf(over.id);
return arrayMove(draggableIDs, oldIndex, newIndex);
});
}
}
*/
return (
<>
<div className="mt-5 grid grid-rows-[5%,95%] gap-3">
<div className="">
<input
name="classSearch"
placeholder="Search for a class..."
value={query}
onChange={handleQuery}
className="w-full"
/>
</div>
<div className="bg-red-400 pt-3 flex flex-col gap-4 no-scrollbar overflow-auto">
{searchCourseList.map(({ num, name }, id) => {
if (num.includes(query.toUpperCase())) {
return (<YV_Class key={id} num={num} name={name}/>);
}
else { return null }
})}
</div>
</div>
</>
);
}
I think the issue is with YV_Class, since I fire the removeCourse() function inside isDragging, but num and name remain the same across different YV_Classes when dragging for some reason. Not sure though.