Skip to content

Commit 759d653

Browse files
committed
basic integration with backend and integrated dashboard and ticketDiscussion page
1 parent f13faa0 commit 759d653

File tree

5 files changed

+153
-95
lines changed

5 files changed

+153
-95
lines changed

src/router.js

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import Activity from "./user/Activity/Activity";
2424
import IntegrationsPage from "./user/integrations/IntegrationsPage/IntegrationsPage";
2525
import UserIntegrations from "./user/integrations/UserIntegrations/UserIntegrations";
2626
import TicketDashboard from "../src/user/Admin/Tickets/TicketDashboard";
27-
import TicketDiscussion from "../src/user/Admin/Tickets/TicketDiscussions";
2827

2928
const Router = () => (
3029
<BrowserRouter>
@@ -50,7 +49,6 @@ const Router = () => (
5049
<PrivateRoute exact path="/setup" component={Setup} />
5150
<AdminRoute exact path="/org-settings" component={CommunitySetting} />
5251
<AdminRoute exact path="/activity/:userId" component={Activity} />
53-
<AdminRoute exact path="/tickets" component={TicketDashboard} />
5452
<PrivateRoute exact path="/insight" component={Insight} />
5553
<PrivateRoute exact path="/admin" component={Admin} />
5654
<PrivateRoute exact path="/integrations" component={IntegrationsPage} />
@@ -59,11 +57,7 @@ const Router = () => (
5957
path="/userintegrations"
6058
component={UserIntegrations}
6159
/>
62-
<PrivateRoute
63-
exact
64-
path="/ticketdiscussion"
65-
component={TicketDiscussion}
66-
/>
60+
<PrivateRoute exact path="/tickets" component={TicketDashboard} />
6761
<Route component={NotFound} />
6862
</Switch>
6963
</BrowserRouter>

src/user/Admin/Tickets/NewTicketEditor/index.js

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import React, { Component } from "react";
22
import CancelButton from "@material-ui/icons/ClearOutlined";
33
import SaveButton from "@material-ui/icons/SaveOutlined";
4-
import { ToastContainer, toast } from "react-toastify";
54
import "react-mde/lib/styles/css/react-mde-all.css";
65
import Button from "react-bootstrap/Button";
76
import Form from "react-bootstrap/Form";
87
import * as Showdown from "showdown";
98
import ReactMde from "react-mde";
109
import "./Editor.scss";
10+
import { ToastContainer, toast } from "react-toastify";
1111

1212
class Editor extends Component {
1313
constructor(props) {
@@ -20,18 +20,24 @@ class Editor extends Component {
2020
};
2121
}
2222

23-
// handleSave = () => {
24-
// const { title, content, shortDescription } = this.state;
25-
// const { save } = this.props;
26-
// save(
27-
// {
28-
// title,
29-
// content,
30-
// shortDescription,
31-
// status: "OPEN"
32-
// }
33-
// );
34-
// };
23+
handleSave = () => {
24+
const { title, content, shortDescription } = this.state;
25+
const { save } = this.props;
26+
const newTicket = {
27+
title,
28+
content,
29+
shortDescription,
30+
};
31+
if (newTicket.shortDescription.length < 10) {
32+
toast.error("Short description should be atleast 10 characters long");
33+
} else if (newTicket.content.length < 10) {
34+
toast.error("Ticket content should be atleast 10 characters long");
35+
} else if (newTicket.title.length < 10) {
36+
toast.error("Title should be atleast 10 characters long");
37+
} else {
38+
save(newTicket);
39+
}
40+
};
3541

3642
setContent = (content) => this.setState({ content });
3743

@@ -67,47 +73,55 @@ class Editor extends Component {
6773
<Form.Label className="field-title">Title</Form.Label>
6874
<Form.Control
6975
as="input"
76+
value={title}
77+
maxLength="50"
78+
required={true}
7079
name="ticketTitle"
7180
className="searchbar"
72-
value={title}
7381
onChange={this.setTitle}
74-
maxlength="50"
75-
isInvalid={this.state.shortDescription.length >= 50}
82+
isInvalid={this.state.title.length >= 50}
7683
/>
7784
</Form>
7885
<Form>
7986
<Form.Label className="field-title">Description</Form.Label>
8087
<Form.Control
8188
as="textarea"
82-
name="ticketDescription"
83-
maxlength="100"
89+
maxLength="100"
8490
className="searchbar"
91+
name="ticketDescription"
8592
value={this.state.shortDescription}
8693
onChange={this.setShortDescription}
8794
isInvalid={this.state.shortDescription.length >= 100}
8895
/>
8996
</Form>
90-
<Form>
91-
</Form>
97+
<Form></Form>
9298
<ReactMde
93-
onChange={this.setContent}
9499
value={content}
95-
onTabChange={this.setSelectedTab}
96100
selectedTab={selectedTab}
101+
onChange={this.setContent}
102+
onTabChange={this.setSelectedTab}
97103
generateMarkdownPreview={(markdown) =>
98104
Promise.resolve(converter.makeHtml(markdown))
99105
}
100106
/>
101107
<div className="top-controls">
102-
<Button
103-
// onClick={this.handleSave}
104-
variant="primary"
105-
>
108+
<Button onClick={this.handleSave} variant="primary">
106109
<span className="vc">
107110
<SaveButton /> Save
108111
</span>
109112
</Button>
110113
</div>
114+
<ToastContainer
115+
draggable
116+
rtl={false}
117+
pauseOnHover
118+
closeOnClick
119+
autoClose={5000}
120+
pauseOnFocusLoss
121+
newestOnTop={false}
122+
position="top-right"
123+
hideProgressBar={false}
124+
/>
111125
</div>
112126
);
113127
}

src/user/Admin/Tickets/TicketContent/TicketContent.js

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React, { Component } from "react";
22
import "./TicketContent.scss";
3+
import Moment from 'react-moment'
34
import { Image } from "react-bootstrap";
45
import BadgeElement from './BadgeElement';
56
import { withRouter } from "react-router-dom";
@@ -9,6 +10,12 @@ import userIcon2 from "../../../../assets/images/userIcon2.jpg";
910

1011
class TicketContent extends Component {
1112

13+
handleRowClick = (arg1) => {
14+
console.log("Row Clicked!")
15+
console.log(arg1)
16+
this.props.viewTicket(arg1._id)
17+
}
18+
1219
render() {
1320

1421
const CustomTitle = ({ row }) => (
@@ -21,6 +28,7 @@ class TicketContent extends Component {
2128
const columns = [
2229
{
2330
name: "Title",
31+
grow: 2,
2432
selector: "titler",
2533
sortable: true,
2634
maxWidth: "600px", // when using custom you should use width or maxWidth, otherwise, the table will default to flex grow behavior
@@ -32,19 +40,17 @@ class TicketContent extends Component {
3240
selector: "plot",
3341
wrap: true,
3442
sortable: true,
35-
format: (row) => `${row.content.shortDescription.slice(0, 100)}...`,
43+
format: (row) => `${row.shortDescription.slice(0, 100)}...`,
3644
},
3745
{
3846
name: "Status",
3947
grow: 1,
4048
// eslint-disable-next-line react/no-array-index-key
41-
// cell: (row) => (
42-
// <div>
43-
// {row.genres.map((genre, i) => (
44-
// <BadgeElement ticketState={genre} />
45-
// ))}
46-
// </div>
47-
// ),
49+
cell: (row) => (
50+
<div>
51+
<BadgeElement ticketState={row.status} />
52+
</div>
53+
),
4854
},
4955
{
5056
name: "User",
@@ -63,25 +69,35 @@ class TicketContent extends Component {
6369
// ),
6470
},
6571
{
66-
name: "Created At"
72+
name: "Created At",
73+
cell: (row) => (
74+
<div>
75+
<Moment format="DD MMM YYYY">{row.createdAt}</Moment>
76+
</div>
77+
)
6778
},
6879
{
69-
name: "Comments"
80+
name: "Comments",
81+
sortable: true,
82+
cell: (row) => (
83+
<div>
84+
{row.comments}
85+
</div>
86+
)
7087
}
7188
];
7289

7390
return (
7491
<DataTable
75-
// title={this.state.selectedState}
92+
pagination
7693
columns={columns}
94+
pointerOnHover={true}
95+
highlightOnHover={true}
7796
data={this.props.tickets}
7897
customStyles={customStyles}
79-
pagination
80-
paginationPerPage={Math.floor((window.innerHeight - 220) / 85)}
81-
highlightOnHover={true}
82-
pointerOnHover={true}
8398
paginationRowsPerPageOptions={[]}
8499
onRowClicked={this.handleRowClick}
100+
paginationPerPage={Math.floor((window.innerHeight - 220) / 85)}
85101
/>
86102
);
87103
}

src/user/Admin/Tickets/TicketDashboard.js

Lines changed: 49 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
import React, { Component } from "react";
22
import "./TicketDashboard.scss";
3+
import Axios from "axios";
4+
import { connect } from "react-redux";
35
import Form from "react-bootstrap/Form";
46
import Button from "react-bootstrap/Button";
57
import NewTicketEditor from "./NewTicketEditor";
6-
import data from "../../../assets/jsonData/tickets";
8+
import { BASE_URL } from "../../../actions/baseApi";
9+
import TicketDisscussion from "./TicketDiscussions";
710
import TicketContent from "./TicketContent/TicketContent";
11+
import { getTickets } from "../../../actions/ticketAction";
812
import Navigation from "../../dashboard/navigation/navigation";
913
import SearchOutlinedIcon from "@material-ui/icons/SearchOutlined";
10-
import { connect } from "react-redux";
11-
import { getTickets } from "../../../actions/ticketAction";
12-
1314

1415
class TicketDashboard extends Component {
1516
constructor(props) {
@@ -23,35 +24,40 @@ class TicketDashboard extends Component {
2324
solved: [],
2425
closed: [],
2526
editorMode: false,
27+
viewingTicket: null
2628
};
2729
}
2830

2931
componentWillReceiveProps(nextProps) {
30-
console.log(nextProps.tickets.tickets)
32+
console.log(nextProps.tickets.tickets);
3133
this.setState({
32-
all: nextProps.tickets.tickets
34+
all: nextProps.tickets.tickets,
3335
});
3436
}
3537

36-
componentDidMount() {
37-
setTimeout(() => {
38-
this.props.getTickets();
39-
});
38+
divideAsPerStatus = () => {
4039
this.setState({
41-
open: this.state.all.filter((ele) => ele.genres.indexOf("open") !== -1),
40+
open: this.state.all.filter((ele) => ele.genres.indexOf("OPEN") !== -1),
4241
pending: this.state.all.filter(
43-
(ele) => ele.genres.indexOf("pending") !== -1
42+
(ele) => ele.genres.indexOf("PENDING") !== -1
4443
),
4544
onHold: this.state.all.filter(
46-
(ele) => ele.genres.indexOf("onHold") !== -1
45+
(ele) => ele.genres.indexOf("ON_HOLD") !== -1
4746
),
4847
solved: this.state.all.filter(
49-
(ele) => ele.genres.indexOf("solved") !== -1
48+
(ele) => ele.genres.indexOf("SOLVED") !== -1
5049
),
5150
closed: this.state.all.filter(
52-
(ele) => ele.genres.indexOf("closed") !== -1
51+
(ele) => ele.genres.indexOf("CLOSED") !== -1
5352
),
5453
});
54+
};
55+
56+
componentDidMount() {
57+
setTimeout(() => {
58+
this.props.getTickets();
59+
});
60+
this.divideAsPerStatus();
5561
}
5662

5763
handleSearchBarChange = (e) => {};
@@ -68,6 +74,17 @@ class TicketDashboard extends Component {
6874
});
6975
};
7076

77+
handleCreateNewTicket = async (newTicket) => {
78+
console.log("EXECUTED!")
79+
await Axios.post(`${BASE_URL}/ticket`, newTicket)
80+
};
81+
82+
handleViewTicket = (id) => {
83+
this.setState({
84+
viewingTicket: id
85+
})
86+
}
87+
7188
render() {
7289
const { view } = this.state;
7390
return (
@@ -78,7 +95,7 @@ class TicketDashboard extends Component {
7895
<div className="ticket-details">
7996
<div className="ticket-description">
8097
<div className="dashboard-title">Tickets</div>
81-
{!this.state.editorMode && this.state.all.length && (
98+
{!this.state.editorMode && this.state.all.length && !this.state.viewingTicket && (
8299
<React.Fragment>
83100
<div className="searchbar-container">
84101
<div className="searchbar">
@@ -93,7 +110,9 @@ class TicketDashboard extends Component {
93110
/>
94111
</Form>
95112
</div>
96-
<Button onClick={()=>this.toggleNewTicketEditor(true)}>New Ticket</Button>
113+
<Button onClick={() => this.toggleNewTicketEditor(true)}>
114+
New Ticket
115+
</Button>
97116
</div>
98117
<div className="ticket-status">
99118
<div className="tabs__container">
@@ -124,11 +143,21 @@ class TicketDashboard extends Component {
124143
</div>
125144
</div>
126145
<div className="ticket-content">
127-
<TicketContent tickets={this.state[this.state.view]} />
146+
<TicketContent
147+
viewTicket={this.handleViewTicket}
148+
tickets={this.state[this.state.view]} />
128149
</div>
129150
</React.Fragment>
130151
)}
131-
{this.state.editorMode && <NewTicketEditor cancel={()=>this.toggleNewTicketEditor(false)} />}
152+
{this.state.editorMode && !this.state.viewingTicket && (
153+
<NewTicketEditor
154+
save={this.handleCreateNewTicket}
155+
cancel={() => this.toggleNewTicketEditor(false)}
156+
/>
157+
)}
158+
{this.state.viewingTicket && (
159+
<TicketDisscussion back={this.handleViewTicket} />
160+
)}
132161
</div>
133162
</div>
134163
</div>
@@ -155,4 +184,4 @@ export default connect(mapStateToProps, { getTickets })(TicketDashboard);
155184
// "We require a new integration for slack. I would really appreciate it if some of the developers could look into this matter! Please feel free to reach out to me for more information regarding this!. I would be glad to help!",
156185
// posterUrl:
157186
// "https://images-na.ssl-images-amazon.com/images/M/MV5BMTUwODE3MDE0MV5BMl5BanBnXkFtZTgwNTk1MjI4MzE@._V1_SX300.jpg",
158-
// }
187+
// }

0 commit comments

Comments
 (0)