|
| 1 | +import Typography from '@mui/material/Typography'; |
| 2 | +import React, { CSSProperties, useRef, useState } from 'react'; |
| 3 | +import { |
| 4 | + CalenderIcon, |
| 5 | + CloseIcon, |
| 6 | + FeedbackIcon, |
| 7 | + IdeaIcon, |
| 8 | + QuestionIcon, |
| 9 | + SuccessIcon |
| 10 | +} from '../../icons'; |
| 11 | +import { CULTURED } from '../../theme'; |
| 12 | +import { CustomTooltip } from '../CustomTooltip'; |
| 13 | +import { ModalCard } from '../ModalCard'; |
| 14 | +import { |
| 15 | + ActionWrapper, |
| 16 | + CloseButton, |
| 17 | + Container, |
| 18 | + FeedbackButton, |
| 19 | + FeedbackForm, |
| 20 | + FeedbackMessage, |
| 21 | + FeedbackMiniIcon, |
| 22 | + FeedbackOptionButton, |
| 23 | + FeedbackOptions, |
| 24 | + FeedbackSubmitButton, |
| 25 | + FeedbackTextArea, |
| 26 | + HelperWrapper, |
| 27 | + InnerComponentWrapper, |
| 28 | + StyledCheckbox, |
| 29 | + StyledLink, |
| 30 | + StyledTextArea |
| 31 | +} from './style'; |
| 32 | + |
| 33 | +const tooltipContent = ( |
| 34 | + <p> |
| 35 | + Some account and system information may be sent to Layer5. We will use it to fix problems and |
| 36 | + improve our services, subject to our{' '} |
| 37 | + <StyledLink target="_blank" href="https://layer5.io/company/legal/privacy"> |
| 38 | + Privacy Policy |
| 39 | + </StyledLink>{' '} |
| 40 | + and{' '} |
| 41 | + <StyledLink target="_blank" href="https://layer5.io/company/legal/terms-of-service"> |
| 42 | + Terms of Service |
| 43 | + </StyledLink> |
| 44 | + . We may email you for more information or updates. |
| 45 | + </p> |
| 46 | +); |
| 47 | + |
| 48 | +interface FeedbackDataItem { |
| 49 | + icon: JSX.Element; |
| 50 | + label: string; |
| 51 | + placeholder?: string; |
| 52 | + isTextInput: boolean; |
| 53 | + innerComponent?: JSX.Element; |
| 54 | +} |
| 55 | + |
| 56 | +const feedbackData: FeedbackDataItem[] = [ |
| 57 | + { |
| 58 | + icon: <FeedbackIcon />, |
| 59 | + label: 'Issue', |
| 60 | + placeholder: 'I’m having an issue with...', |
| 61 | + isTextInput: true |
| 62 | + }, |
| 63 | + { |
| 64 | + icon: <IdeaIcon />, |
| 65 | + label: 'Suggestion', |
| 66 | + placeholder: 'I have a suggestion about...', |
| 67 | + isTextInput: true |
| 68 | + }, |
| 69 | + { |
| 70 | + icon: <CalenderIcon />, |
| 71 | + label: 'Meet Request', |
| 72 | + isTextInput: false, |
| 73 | + innerComponent: ( |
| 74 | + <div |
| 75 | + style={{ |
| 76 | + display: 'flex', |
| 77 | + flexDirection: 'column', |
| 78 | + alignItems: 'center', |
| 79 | + justifyContent: 'space-between', |
| 80 | + height: '137px', |
| 81 | + color: 'black' |
| 82 | + }} |
| 83 | + > |
| 84 | + <Typography style={{ lineHeight: '2.5', textAlign: 'center' }}> |
| 85 | + Need help or have more feedback than fits here? |
| 86 | + <br /> Meet with us. |
| 87 | + </Typography> |
| 88 | + <StyledLink |
| 89 | + target="_blank" |
| 90 | + href="https://calendar.google.com/calendar/appointments/schedules/AcZssZ3pmcApaDP4xd8hvG5fy8ylxuFxD3akIRc5vpWJ60q-HemQi80SFFAVftbiIsq9pgiA2o8yvU56" |
| 91 | + > |
| 92 | + Select a time convenient for you. |
| 93 | + </StyledLink> |
| 94 | + </div> |
| 95 | + ) |
| 96 | + } |
| 97 | +]; |
| 98 | + |
| 99 | +interface FeedbackComponentProps { |
| 100 | + onSubmit: (data: { label: string; message: string }) => void; |
| 101 | + containerStyles?: CSSProperties; |
| 102 | + feedbackOptionStyles?: CSSProperties; |
| 103 | +} |
| 104 | + |
| 105 | +const FeedbackComponent: React.FC<FeedbackComponentProps> = ({ |
| 106 | + onSubmit, |
| 107 | + containerStyles, |
| 108 | + feedbackOptionStyles |
| 109 | +}) => { |
| 110 | + const [isOpen, setIsOpen] = useState<boolean>(false); |
| 111 | + const [submitted, setSubmitted] = useState<boolean>(false); |
| 112 | + const [category, setCategory] = useState<FeedbackDataItem | undefined>(); |
| 113 | + const [messageValue, setMessageValue] = useState<string | undefined>(); |
| 114 | + const feedbackTextRef = useRef<HTMLTextAreaElement>(null); |
| 115 | + const [isChecked, setIsChecked] = useState<boolean>(false); |
| 116 | + |
| 117 | + const handleCheckboxChange = (event: React.ChangeEvent<HTMLInputElement>) => { |
| 118 | + setIsChecked(event.target.checked); |
| 119 | + }; |
| 120 | + |
| 121 | + const handleFeedback = () => { |
| 122 | + setIsOpen(!isOpen); |
| 123 | + setCategory(feedbackData[0]); |
| 124 | + setSubmitted(false); |
| 125 | + setMessageValue(''); |
| 126 | + }; |
| 127 | + |
| 128 | + const handleSubmit = () => { |
| 129 | + setSubmitted(true); |
| 130 | + if (messageValue && isChecked) { |
| 131 | + onSubmit({ label: category?.label || '', message: messageValue }); |
| 132 | + } |
| 133 | + setTimeout(() => { |
| 134 | + setIsOpen(false); |
| 135 | + setCategory(undefined); |
| 136 | + setSubmitted(false); |
| 137 | + setMessageValue(''); |
| 138 | + }, 2000); |
| 139 | + }; |
| 140 | + |
| 141 | + return ( |
| 142 | + <Container isOpen={isOpen} style={containerStyles}> |
| 143 | + {submitted ? ( |
| 144 | + <FeedbackMessage isOpen={isOpen}> |
| 145 | + <SuccessIcon width={'32'} height={'32'} /> |
| 146 | + We got your concern. Thank you! |
| 147 | + </FeedbackMessage> |
| 148 | + ) : ( |
| 149 | + <> |
| 150 | + <FeedbackButton onClick={handleFeedback}>Feedback</FeedbackButton> |
| 151 | + |
| 152 | + <ModalCard |
| 153 | + onClose={() => {}} |
| 154 | + open={true} |
| 155 | + closeComponent={ |
| 156 | + <CloseButton onClick={() => setIsOpen(false)}> |
| 157 | + <CloseIcon width={'30'} height={'30'} fill={CULTURED} /> |
| 158 | + </CloseButton> |
| 159 | + } |
| 160 | + actions={ |
| 161 | + <div |
| 162 | + style={{ |
| 163 | + display: 'flex', |
| 164 | + alignItems: 'center' |
| 165 | + }} |
| 166 | + > |
| 167 | + <ActionWrapper> |
| 168 | + <StyledCheckbox checked={isChecked} onChange={handleCheckboxChange} /> |
| 169 | + <Typography style={{ color: 'white', fontSize: '12px', height: '15px' }}> |
| 170 | + We may email you for more information or updates |
| 171 | + </Typography> |
| 172 | + </ActionWrapper> |
| 173 | + <FeedbackSubmitButton |
| 174 | + type="submit" |
| 175 | + disabled={!(messageValue && isChecked)} |
| 176 | + isOpen={!(messageValue && isChecked)} |
| 177 | + onClick={handleSubmit} |
| 178 | + > |
| 179 | + Send |
| 180 | + </FeedbackSubmitButton> |
| 181 | + </div> |
| 182 | + } |
| 183 | + leftHeaderIcon={<FeedbackIcon />} |
| 184 | + title="Feedback" |
| 185 | + helpArea={ |
| 186 | + <CustomTooltip placement="top" title={tooltipContent} arrow> |
| 187 | + <HelperWrapper> |
| 188 | + <QuestionIcon width={'30'} height={'30'} /> |
| 189 | + </HelperWrapper> |
| 190 | + </CustomTooltip> |
| 191 | + } |
| 192 | + helpText={'Help'} |
| 193 | + content={ |
| 194 | + <FeedbackForm> |
| 195 | + <FeedbackOptions> |
| 196 | + {feedbackData?.map((item) => ( |
| 197 | + <FeedbackOptionButton |
| 198 | + key={item.label} |
| 199 | + style={feedbackOptionStyles} |
| 200 | + type="button" |
| 201 | + onClick={() => { |
| 202 | + setCategory(item); |
| 203 | + }} |
| 204 | + isOpen={category?.label === item.label} |
| 205 | + > |
| 206 | + <FeedbackMiniIcon>{item.icon}</FeedbackMiniIcon> |
| 207 | + <Typography>{item.label}</Typography> |
| 208 | + </FeedbackOptionButton> |
| 209 | + ))} |
| 210 | + </FeedbackOptions> |
| 211 | + {category?.isTextInput ? ( |
| 212 | + <FeedbackTextArea> |
| 213 | + <StyledTextArea |
| 214 | + value={messageValue || ''} |
| 215 | + onChange={(e) => { |
| 216 | + setMessageValue(e.target.value); |
| 217 | + }} |
| 218 | + ref={feedbackTextRef} |
| 219 | + required |
| 220 | + placeholder={category.placeholder} |
| 221 | + rows={5} |
| 222 | + cols={30} |
| 223 | + /> |
| 224 | + </FeedbackTextArea> |
| 225 | + ) : ( |
| 226 | + <InnerComponentWrapper>{category?.innerComponent}</InnerComponentWrapper> |
| 227 | + )} |
| 228 | + </FeedbackForm> |
| 229 | + } |
| 230 | + ></ModalCard> |
| 231 | + </> |
| 232 | + )} |
| 233 | + </Container> |
| 234 | + ); |
| 235 | +}; |
| 236 | + |
| 237 | +export default FeedbackComponent; |
0 commit comments