| 
1 | 1 | import React, { Component } from "react";  | 
2 | 2 | import { Card, Badge } from "react-bootstrap";  | 
3 | 3 | import "./projects.scss";  | 
4 |  | -import projectInfo from "../../jsonData/projects";  | 
 | 4 | +import projectInfo1 from "../../jsonData/projects";  | 
5 | 5 | import { IconContext } from "react-icons";  | 
6 | 6 | import { FiPlus } from "react-icons/fi";  | 
 | 7 | +import { Droppable, DragDropContext, Draggable } from "react-beautiful-dnd";  | 
7 | 8 | 
 
  | 
8 | 9 | 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 | + | 
9 | 78 |  render() {  | 
10 | 79 |  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>  | 
57 | 160 |  );  | 
58 | 161 |  }  | 
59 | 162 | }  | 
 | 
0 commit comments