import * as React from 'react'; import ReactMarkdown from 'react-markdown'; import I18n from 'i18n-js'; import NewPostForm from './NewPostForm'; import Spinner from '../common/Spinner'; import { DangerText, SuccessText, } from '../common/CustomTexts'; import Button from '../common/Button'; import IBoard from '../../interfaces/IBoard'; import buildRequestHeaders from '../../helpers/buildRequestHeaders'; import HttpStatus from '../../constants/http_status'; import { POST_APPROVAL_STATUS_APPROVED } from '../../interfaces/IPost'; interface Props { board: IBoard; isLoggedIn: boolean; currentUserFullName: string; isAnonymousFeedbackAllowed: boolean; authenticityToken: string; // Time check anti-spam measure componentRenderedAt: number; } interface State { showForm: boolean; error: string; success: string; isLoading: boolean; title: string; description: string; isSubmissionAnonymous: boolean; // Honeypot anti-spam measure // These fields are honeypots: they are not visibile and must not be filled // dnf = do not fill dnf1: string; dnf2: string; } class NewPost extends React.Component { constructor(props: Props) { super(props); this.state = { showForm: false, error: '', success: '', isLoading: false, title: '', description: '', isSubmissionAnonymous: false, dnf1: '', dnf2: '', }; this.toggleForm = this.toggleForm.bind(this); this.onTitleChange = this.onTitleChange.bind(this); this.onDescriptionChange = this.onDescriptionChange.bind(this); this.submitForm = this.submitForm.bind(this); this.onDnf1Change = this.onDnf1Change.bind(this) this.onDnf2Change = this.onDnf2Change.bind(this) } toggleForm() { this.setState({ showForm: !this.state.showForm, error: '', success: '', isLoading: false, }); } onTitleChange(title: string) { this.setState({ title, error: '', }); } onDescriptionChange(description: string) { this.setState({ description, }); } onDnf1Change(dnf1: string) { this.setState({ dnf1, }); } onDnf2Change(dnf2: string) { this.setState({ dnf2, }); } async submitForm(e: React.FormEvent) { e.preventDefault(); this.setState({ error: '', success: '', isLoading: true, }); const boardId = this.props.board.id; const { authenticityToken, componentRenderedAt } = this.props; const { title, description, isSubmissionAnonymous, dnf1, dnf2 } = this.state; if (title === '') { this.setState({ error: I18n.t('board.new_post.no_title'), isLoading: false, }); return; } try { const res = await fetch('/posts', { method: 'POST', headers: buildRequestHeaders(authenticityToken), body: JSON.stringify({ post: { title, description, board_id: boardId, is_anonymous: isSubmissionAnonymous, dnf1, dnf2, form_rendered_at: componentRenderedAt, }, }), }); const json = await res.json(); this.setState({isLoading: false}); if (res.status === HttpStatus.Created) { if (json.approval_status === POST_APPROVAL_STATUS_APPROVED) { this.setState({ success: I18n.t('board.new_post.submit_success'), }); setTimeout(() => ( window.location.href = `/posts/${json.slug || json.id}` ), 1000); } else { this.setState({ success: I18n.t('board.new_post.submit_pending'), title: '', description: '', showForm: false, }); } } else { this.setState({error: json.error}); } } catch (e) { this.setState({ error: I18n.t('common.errors.unknown') }); } } render() { const { board, isLoggedIn, currentUserFullName, isAnonymousFeedbackAllowed } = this.props; const { showForm, error, success, isLoading, title, description, isSubmissionAnonymous, dnf1, dnf2, } = this.state; return (
{board.name} {board.description} { (isAnonymousFeedbackAllowed && !showForm) &&
{I18n.t('common.words.or')}   { this.toggleForm(); this.setState({ isSubmissionAnonymous: true }); }} className="link" > {I18n.t('board.new_post.submit_anonymous_button').toLowerCase()}
} { showForm ? : null } { isLoading ? : null } { error ? {error} : null } { success ? {success} : null }
); } } export default NewPost;