-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathFeedback.tsx
172 lines (158 loc) · 6.25 KB
/
Feedback.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
import React, { useCallback, useEffect, useState } from 'react';
import { SubmitHandler, FormProvider, useForm } from "react-hook-form";
import { Alert, Container, Row, Col, Button, Form, FormGroup } from 'reactstrap';
import { BsX } from 'react-icons/bs';
import { useHistory } from 'react-router';
import '../../styles/feedback.scss';
import '../../styles/lightMode.scss';
import '../styled/Checkbox';
import '../widgets/CustomRating';
import '../styled/TextField';
import CustomRating from '../widgets/CustomRating';
import Comments from '../widgets/Comments';
import { GlobalButton } from '../styled/Button';
import TextField from '../styled/TextField';
/**
* Types for Feedback component props.
*/
interface FeedbackProps {
/**
* Types of details of the current User. Optional.
*/
user?: {
name?: string,
surname?: string,
}
/**
* Type of the current Charging Session ID. Optional.
*/
sessionId?: number,
/**
* Types for Any other Props. Optional.
*/
[x: string]: any
}
/**
* Types for the react-hook-form.
*
* @remarks
* See {@link https://react-hook-form.com/| react-hook-form documentation} for more details.
*/
type FeedbackInput = {
/**
* Type of Unique ID of the current charging session. Required.
*/
sessionId: number,
/**
* Type of Rating must be between 1 to 5 if rated; 0 by default. Required.
*/
rating: number,
/**
* Type of Four comments are suggested, only one needs to be chosen. Required.
*/
suggestedComment: string,
/**
* Type of any additional comments/remarks that the User may have. Required.
*/
openComment: string,
}
/**
* Feedback component of the web application. All fields of the Feedback Form are optional.
* Constructed using {@link https://react-hook-form.com/api/useformcontext | Form Provider} to pass form context to nested components.
* @param user - Current User details
* @param sessionId - Current session ID
* @returns - Returns Feedback Form with the following widgets:
* 1. {@link src\components\widgets\CustomRating.tsx | "5-bolt" Rating }
* 2. {@link src\components\widgets\Comments.tsx | Suggested Comments }
* 3. {@link src\components\styled\TextField.tsx | Text Field for remarks}
*/
export default function Feedback({ ...props }: FeedbackProps) {
const history = useHistory();
/**
* Default values for the feedback form.
*/
const initialValues = {
sessionId: props.sessionId,
rating: 0,
suggestedComment: '',
openComment: '',
}
/**
* List of Suggested Comments.
*/
const commentValues = [
"I love it!",
"Easy to use",
"Annoying",
"Too much graphics"
]
/**
* React-hook-form.
* @param defaultValues - initial value for each of the fields to be submited; ensures proper form validation.
* @param mode - onBlur runs form validation whenever the input loses focus.
*/
const form = useForm({
defaultValues: { ...initialValues },
mode: "onBlur",
});
/**
* State of the Alert text:
* case 1 - User submits feedback
* case 2 - User does not submit feedback
*/
const [alertText, setAlertText] = useState<string>("Please rate us next time! Your feedback is very important for us :)");
const [quiting, setQuiting] = useState<boolean>(false);
/**
* Submits the Feedback Form. Automatically transfers the User to {@link src\components\pages\Start.tsx | Start page} after timeout.
* @param data - data inputed in the form
*/
const onSubmit: SubmitHandler<FeedbackInput> = useCallback((data) => {
setTimeout(() => {history.push("/")}, 3000);
console.log(data);
},[history])
/**
* Exits the Feedback Form without submission. Automatically transfers the User to {@link src\components\pages\Start.tsx | Start page} after timeout.
*/
const quit = useCallback(() => {
setQuiting(true);
setTimeout(() => {history.push("/")}, 3000);
}, [history]);
const hasFeedback = form.formState.isDirty && Object.keys(form.formState.touchedFields).length !== 0;
/**
* Sets Alert text based on form changed and user's feedback.
*/
useEffect(() => {
if (hasFeedback) {
setAlertText("Thank you for your feedback!")
}
}, [form, alertText, hasFeedback])
return (
<Container className="feedback p-0">
<Alert className={hasFeedback ? "feedbackAlert" : "feedbackAlertBad"} isOpen={form.formState.isSubmitted || quiting} color={hasFeedback ? "success" : "danger"}>{alertText}</Alert>
<Row className={"w-100"}>
<Col className="p-0">
<Button className="exitButton" onClick={quit}><BsX style={{height: "8vh", width: "8vh"}}/></Button>
</Col>
</Row>
<Row className={"h-100"}>
<Col style={{alignSelf: "center", height: "100%"}}>
<FormProvider {...form}>
<Form className={"feedbackForm"} onSubmit={form.handleSubmit(onSubmit)}>
<h1 className={"responsiveText"}>Hey {props.user?.name}, please rate us!</h1>
<FormGroup>
<CustomRating name={"rating"}/>
</FormGroup>
<FormGroup style={{marginTop: "3rem", marginBottom: "3rem"}}>
<Comments name={"suggestedComment"} values={commentValues}/>
</FormGroup>
<FormGroup>
<TextField name={"openComment"}/>
</FormGroup>
<GlobalButton text={"Submit"} type={"submit"} style={{marginTop: "auto"}}/>
</Form>
</FormProvider>
</Col>
</Row>
</Container>
);
}