Skip to content

Instantly share code, notes, and snippets.

@gcmatheusj
Created July 18, 2019 17:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gcmatheusj/26058e4a40bec7e6b8e5e14990010dc3 to your computer and use it in GitHub Desktop.
Save gcmatheusj/26058e4a40bec7e6b8e5e14990010dc3 to your computer and use it in GitHub Desktop.
import React, { Fragment } from 'react';
import { withFormik, FormikProps, FieldArray } from 'formik';
import * as Yup from 'yup';
import styled from 'styled-components';
import { History } from 'history';
import AddPollMutation from './AddPollMutation';
import withToast from '../HOC/withToast';
import Header from '../common/Header/Header';
import Input from '../common/Input';
import TextArea from '../common/TextArea';
import { ReactComponent as CancelMinus } from '../../icons/cancel_minus.svg';
import { ReactComponent as Topic } from '../../icons/topic.svg';
import { ReactComponent as School } from '../../icons/school.svg';
import { ReactComponent as Poll } from '../../icons/poll.svg';
import { ReactComponent as AddIcon } from '../../icons/add.svg';
interface FormValues {
topics: string[];
question: string;
answers: string[];
}
interface FormProps {
initialTopics?: string[];
initialQuestion?: string;
initialAnswers?: string[];
history: History;
showToast(): void;
}
const Question = (props: FormikProps<FormValues>) => {
const { values, errors, touched, handleChange, handleBlur, handleSubmit, isSubmitting } = props;
console.log('errors ->', errors);
console.log('values ->', values);
return (
<Wrapper>
<Header text="Create Poll" />
<ScrollWrapper>
<ScrollContent>
<CardWrapper>
<Form onSubmit={handleSubmit}>
<FieldArray
name="topics"
render={arrayHelpers => (
<div>
{values.topics.map((topic, index) => (
<Fragment key={index}>
<InputBox>
<TopicIcon />
<InputWrapper>
<Input placeholder="Topic" name={`topics.${index}`} full style={{}} />
<div style={{ width: 10 }} />
{index === 0 ? (
<AddIcon onClick={() => arrayHelpers.insert(index + 1, '')} />
) : (
<CancelMinus onClick={() => arrayHelpers.remove(index)} />
)}
</InputWrapper>
<ErrorLabel>{errors && errors.topics && errors.topics[index]}</ErrorLabel>
</InputBox>
</Fragment>
))}
</div>
)}
/>
<TextAreaBox>
<QuestionIcon />
<StyledTextArea
placeholder="Write a question"
full
height={150}
name="question"
onChange={handleChange}
onBlur={handleBlur}
value={values.question}
/>
<ErrorLabel>{errors && errors.question}</ErrorLabel>
</TextAreaBox>
<FieldArray
name="answers"
render={arrayHelpers => (
<div>
<div style={{ height: 20 }} />
{values.answers.map((answer, index) => (
<Fragment key={index}>
<InputBox>
<AnswerIcon />
<InputWrapper>
<Input placeholder={`Answer ${index + 1}`} name={`answers.${index}`} full style={{}} />
<div style={{ width: 10 }} />
<CancelMinus onClick={() => arrayHelpers.remove(index)} />
</InputWrapper>
<ErrorLabel>{errors && errors.answers && errors.answers[index]}</ErrorLabel>
</InputBox>
</Fragment>
))}
<AddButton onClick={() => arrayHelpers.insert(values.answers.length + 1, '')}>
<ButtonText>Add Answer</ButtonText>
</AddButton>
</div>
)}
/>
<RowCenter>
<AnswerWrapper type="submit">
<ButtonText>Submit Poll</ButtonText>
</AnswerWrapper>
</RowCenter>
</Form>
</CardWrapper>
</ScrollContent>
</ScrollWrapper>
<NavigationSpacing />
</Wrapper>
);
};
const ErrorLabel = styled.p`
color: red;
font-size: 12px;
`;
const InputWrapper = styled.div`
display: flex;
flex-direction: row;
width: 100%;
height: 100%;
align-items: center;
`;
const Wrapper = styled.div`
display: flex;
flex-direction: column;
background: #eeeff1;
justify-content: flex-start;
height: 100vh;
overflow: scroll;
`;
const NavigationSpacing = styled.div`
margin-top: 60px;
`;
const ScrollWrapper = styled.div`
position: relative;
overflow: hidden;
width: 100%;
height: 100%;
`;
const ScrollContent = styled.div`
position: absolute;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
overflow: scroll;
padding-top: 64px;
`;
const CardWrapper = styled.div`
background: #fff;
padding: 0 10px 20px 10px;
`;
const InputBox = styled.div`
width: 100%;
height: 70px;
position: relative;
padding-bottom: 30px;
`;
const TopicIcon = styled(Topic)`
position: absolute;
top: 11px;
left: 10px;
`;
const Form = styled.form`
padding-top: 15px;
`;
const TextAreaBox = styled.div`
position: relative;
margin-right: 28px;
height: 170px;
`;
const QuestionIcon = styled(School)`
position: absolute;
top: 11px;
left: 10px;
`;
const StyledTextArea = styled(TextArea)`
padding-left: 26px;
padding-top: 7.5px;
font-size: 16px;
`;
const AnswerIcon = styled(Poll)`
position: absolute;
top: 11px;
left: 10px;
`;
const RowCenter = styled.div`
display: flex;
flex-direction: row;
align-items: center;
width: 100%;
justify-content: center;
`;
const ButtonText = styled.p`
font-size: 14px;
color: #4169e1;
font-weight: medium;
text-align: center;
`;
const AnswerWrapper = styled.button`
width: 140px;
height: 30px;
border: 2px solid #4169e1;
border-radius: 20px;
display: flex;
justify-content: center;
align-items: center;
margin-top: 20px;
background: transparent;
`;
const AddButton = styled.div`
width: 120px;
height: 20px;
border: 2px solid #4169e1;
border-radius: 20px;
display: flex;
justify-content: center;
align-items: center;
margin-top: 10px;
margin-right: auto;
`;
const CreateQuestion = withFormik<FormProps, FormValues>({
mapPropsToValues: props => ({
topics: props.initialTopics || [''],
question: props.initialQuestion || '',
answers: props.initialAnswers || ['', ''],
}),
validationSchema: Yup.object().shape({
topics: Yup.array().of(Yup.string().required('Topic is required')),
question: Yup.string().required('Question is required'),
answers: Yup.array().of(Yup.string().required('Answer is required')),
}),
handleSubmit({ topics, question, answers }: FormValues, { props, setSubmitting, setErrors }) {
console.log(props);
let options = [];
// @ts-ignore
answers.map(answer => (options = [...options, { text: answer, points: 0 }]));
const input = {
topics,
question,
answers: options,
responses: 0,
owner: '5d2619d38983dfae91976811',
};
const onCompleted = () => {
props.history.push('/home');
};
const onError = () => {
props.showToast();
};
AddPollMutation.commit(input, onCompleted, onError);
},
})(Question);
export default withToast(CreateQuestion);
import React from 'react';
import { ToastContainer, toast } from 'react-toastify';
import ToastContext from './ToastContext';
const Toast = props => {
const handleToast = () => {
toast.error('Message here');
};
return (
<React.Fragment>
<ToastContext.Provider
value={{
showToast: handleToast,
}}
>
<ToastContainer
position="top-right"
autoClose={3000}
hideProgressBar={false}
newestOnTop={false}
closeOnClick
rtl={false}
pauseOnHover
/>
{props.children}
</ToastContext.Provider>
</React.Fragment>
);
};
export default Toast;
import * as React from 'react';
const ToastContext = React.createContext({
showToast: args => {},
});
export default ToastContext;
import { useContext } from 'react';
import ToastContext from '../Toast/ToastContext';
const useToast = () => {
const toastContext = useContext(ToastContext);
return {
showToast: toastContext.showToast,
};
};
export default useToast;
import React from 'react';
import useToast from '../Hooks/useToast';
const withToast = WrappedComponent => {
return function ToastWrapper(props) {
const { showToast } = useToast();
return <WrappedComponent showToast={showToast} {...props} />;
};
};
export default withToast;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment