import { runInAction } from "mobx"; import { observer } from "mobx-react"; import { ChangeEvent, FormEvent, FC, ReactNode, Component, Children, isValidElement, cloneElement, useEffect, useRef, useId } from "react"; import { withTranslation, WithTranslation } from "react-i18next"; import styled, { DefaultTheme, withTheme } from "styled-components"; import sendFeedback from "../../Models/sendFeedback"; import ViewState from "../../ReactViewModels/ViewState"; import Box from "../../Styled/Box"; import Button, { RawButton } from "../../Styled/Button"; import Checkbox from "../../Styled/Checkbox"; import { GLYPHS, StyledIcon } from "../../Styled/Icon"; import Input, { StyledTextArea } from "../../Styled/Input"; import Spacing from "../../Styled/Spacing"; import Text from "../../Styled/Text"; import parseCustomMarkdownToReact, { parseCustomMarkdownToReactWithOptions } from "../Custom/parseCustomMarkdownToReact"; import { WithViewState, withViewState } from "../Context"; import { applyTranslationIfExists } from "../../Language/languageHelpers"; interface IProps extends WithTranslation, WithViewState { theme: DefaultTheme; } interface IState { name: string; email: string; comment: string; isSending: boolean; sendShareURL: boolean; commentIsValid: boolean; } @observer class FeedbackForm extends Component { static displayName = "FeedbackForm"; state: IState = { isSending: false, sendShareURL: true, name: "", email: "", comment: "", commentIsValid: false }; escKeyListener: (e: any) => void; constructor(props: IProps) { super(props); this.escKeyListener = (e) => { if (e.keyCode === 27) { this.onDismiss(); } }; this.onDismiss = this.onDismiss.bind(this); this.updateName = this.updateName.bind(this); this.updateEmail = this.updateEmail.bind(this); this.updateComment = this.updateComment.bind(this); this.onSubmit = this.onSubmit.bind(this); this.changeSendShareUrl = this.changeSendShareUrl.bind(this); } getInitialState() { return { isSending: false, sendShareURL: true, name: "", email: "", comment: "" }; } componentDidMount() { window.addEventListener("keydown", this.escKeyListener, true); this.setState({ commentIsValid: this.props.viewState.terria.configParameters.feedbackMinLength === 0 }); } componentWillUnmount() { window.removeEventListener("keydown", this.escKeyListener, true); } resetState() { this.setState(this.getInitialState()); } onDismiss() { runInAction(() => { this.props.viewState.feedbackFormIsVisible = false; }); this.resetState(); } updateName(e: ChangeEvent) { this.setState({ name: e.target.value }); } updateEmail(e: ChangeEvent) { this.setState({ email: e.target.value }); } updateComment(e: ChangeEvent) { this.setState({ comment: e.target.value }); if ( this.state.comment.replace(/\s+/g, " ").length >= this.props.viewState.terria.configParameters.feedbackMinLength! ) { this.setState({ commentIsValid: true }); } else { this.setState({ commentIsValid: false }); } } changeSendShareUrl(_e: ChangeEvent) { this.setState((prevState: IState) => ({ sendShareURL: !prevState.sendShareURL })); } onSubmit(e: FormEvent) { e.preventDefault(); if ( this.state.comment.length >= this.props.viewState.terria.configParameters.feedbackMinLength! ) { this.setState({ isSending: true }); sendFeedback({ terria: this.props.viewState.terria, name: this.state.name, email: this.state.email, sendShareURL: this.state.sendShareURL, comment: this.state.comment })!.then((succeeded: boolean) => { if (succeeded) { this.setState({ isSending: false, comment: "" }); runInAction(() => { this.props.viewState.feedbackFormIsVisible = false; }); } else { this.setState({ isSending: false }); } }); } } render() { const { t, i18n, viewState, theme } = this.props; const preamble = parseCustomMarkdownToReact( applyTranslationIfExists( viewState.terria.configParameters.feedbackPreamble || "translate#feedback.feedbackPreamble", i18n ) ); const postamble = viewState.terria.configParameters.feedbackPostamble ? parseCustomMarkdownToReact( applyTranslationIfExists( viewState.terria.configParameters.feedbackPostamble, i18n ) ) : undefined; return ( {t("feedback.title")}
{preamble}