Skip to content

Commit cf0cb2b

Browse files
authored
Merge pull request #7 from DevanshCodes/master
Drag & Drop Funcitonality of various cards in different projects
2 parents 7158c57 + b73ea44 commit cf0cb2b

File tree

4 files changed

+324
-152
lines changed

4 files changed

+324
-152
lines changed

package-lock.json

Lines changed: 63 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"@testing-library/user-event": "^7.1.2",
1010
"node-sass": "^4.14.1",
1111
"react": "^16.13.1",
12+
"react-beautiful-dnd": "^13.0.0",
1213
"react-bootstrap": "^1.0.1",
1314
"react-dom": "^16.13.1",
1415
"react-icons": "^3.10.0",

src/components/projects/projects.js

Lines changed: 150 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,162 @@
11
import React, { Component } from "react";
22
import { Card, Badge } from "react-bootstrap";
33
import "./projects.scss";
4-
import projectInfo from "../../jsonData/projects";
4+
import projectInfo1 from "../../jsonData/projects";
55
import { IconContext } from "react-icons";
66
import { FiPlus } from "react-icons/fi";
7+
import { Droppable, DragDropContext, Draggable } from "react-beautiful-dnd";
78

89
class Projects extends Component {
10+
state = projectInfo1;
11+
constructor(props) {
12+
super(props);
13+
this.onDragEnd = this.onDragEnd.bind(this);
14+
}
15+
onDragEnd = (result) => {
16+
const { destination, source, draggableId } = result;
17+
if (!destination) {
18+
return;
19+
}
20+
if (
21+
destination.droppableId === source.droppableId &&
22+
destination.index === source.index
23+
) {
24+
return;
25+
}
26+
const start = this.state.projects[source.droppableId];
27+
const finish = this.state.projects[destination.droppableId];
28+
29+
if (start === finish) {
30+
const newTopicIds = Array.from(start.topicIds);
31+
newTopicIds.splice(source.index, 1);
32+
newTopicIds.splice(destination.index, 0, draggableId);
33+
34+
const newProject = {
35+
...start,
36+
topicIds: newTopicIds,
37+
};
38+
39+
const newState = {
40+
...this.state,
41+
projects: {
42+
...this.state.projects,
43+
[newProject.id]: newProject
44+
}
45+
}
46+
47+
this.setState(newState);
48+
return
49+
}
50+
51+
//moving from one list to another
52+
53+
const startTopicIds = Array.from(start.topicIds);
54+
startTopicIds.splice(source.index, 1);
55+
const newStart = {
56+
...start,
57+
topicIds: startTopicIds,
58+
};
59+
60+
const finishTopicIds = Array.from(finish.topicIds);
61+
finishTopicIds.splice(destination.index, 0, draggableId);
62+
const newFinish = {
63+
...finish,
64+
topicIds: finishTopicIds,
65+
};
66+
67+
const newState = {
68+
...this.state,
69+
projects: {
70+
...this.state.projects,
71+
[newStart.id]: newStart,
72+
[newFinish.id]: newFinish,
73+
},
74+
};
75+
this.setState(newState);
76+
};
77+
978
render() {
1079
return (
11-
<div className="projectCards">
12-
{projectInfo.projects.map((i) => {
13-
return (
14-
<Card className="projectCard" bg="light" style={{ width: "21rem" }}>
15-
<Card.Header color="#366FF0" className="projectcardheader">
16-
{i.projectName}
17-
</Card.Header>
18-
<div className="cardcontent">
19-
{i.topics.map((j) => {
20-
return (
21-
<Card className="topicscard">
22-
<Card.Title className="topicsheading">
23-
{j.topicName}
24-
</Card.Title>
25-
<Card.Text className="topicdescription">
26-
{j.topicDescription}
27-
</Card.Text>
28-
<div>
29-
{j.topicTags ? (
30-
j.topicTags.map((k) => {
31-
return (
32-
<Badge variant="primary" className="tags">
33-
{k}
34-
</Badge>
35-
);
36-
})
37-
) : (
38-
<Badge variant="primary"></Badge>
39-
)}
40-
</div>
41-
</Card>
42-
);
43-
})}
44-
</div>
45-
<div className="addnewcard">
46-
<IconContext.Provider
47-
value={{ style: { verticalAlign: 'middle' }, className: "reacticon" }}
48-
>
49-
<FiPlus />
50-
</IconContext.Provider>{" "}
51-
Add another discussion
52-
</div>
53-
</Card>
54-
);
55-
})}
56-
</div>
80+
<DragDropContext onDragEnd={this.onDragEnd}>
81+
<div className="projectCards">
82+
{this.state.projectsOrder.map((projectID) => {
83+
const project = this.state.projects[projectID];
84+
return (
85+
<Card
86+
className="projectCard"
87+
bg="light"
88+
style={{ width: "21rem" }}
89+
key={project.id}
90+
>
91+
<Card.Header color="#366FF0" className="projectcardheader">
92+
{project.projectName}
93+
</Card.Header>
94+
<Droppable droppableId={project.id}>
95+
{(provided) => (
96+
<div
97+
className="cardcontent"
98+
ref={provided.innerRef}
99+
{...provided.droppableProps}
100+
>
101+
{project.topicIds.map((topicid, index) => {
102+
const topic = this.state.topics[topicid];
103+
return (
104+
<Draggable draggableId={topic.id} index={index}>
105+
{(provided) => (
106+
<Card
107+
key={topic.id}
108+
className="topicscard"
109+
{...provided.draggableProps}
110+
{...provided.dragHandleProps}
111+
ref={provided.innerRef}
112+
>
113+
<Card.Title className="topicsheading">
114+
{topic.topicName}
115+
</Card.Title>
116+
<Card.Text className="topicdescription">
117+
{topic.topicDescription}
118+
</Card.Text>
119+
<div>
120+
{topic.topicTags ? (
121+
topic.topicTags.map((k) => {
122+
return (
123+
<Badge
124+
variant="primary"
125+
className="tags"
126+
>
127+
{k}
128+
</Badge>
129+
);
130+
})
131+
) : (
132+
<Badge variant="primary"></Badge>
133+
)}
134+
</div>
135+
</Card>
136+
)}
137+
</Draggable>
138+
);
139+
})}
140+
{provided.placeholder}
141+
</div>
142+
)}
143+
</Droppable>
144+
<div className="addnewcard">
145+
<IconContext.Provider
146+
value={{
147+
style: { verticalAlign: "middle" },
148+
className: "reacticon",
149+
}}
150+
>
151+
<FiPlus />
152+
</IconContext.Provider>{" "}
153+
Add another discussion
154+
</div>
155+
</Card>
156+
);
157+
})}
158+
</div>
159+
</DragDropContext>
57160
);
58161
}
59162
}

0 commit comments

Comments
 (0)