Created
July 18, 2019 17:19
-
-
Save gcmatheusj/26058e4a40bec7e6b8e5e14990010dc3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as React from 'react'; | |
const ToastContext = React.createContext({ | |
showToast: args => {}, | |
}); | |
export default ToastContext; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useContext } from 'react'; | |
import ToastContext from '../Toast/ToastContext'; | |
const useToast = () => { | |
const toastContext = useContext(ToastContext); | |
return { | |
showToast: toastContext.showToast, | |
}; | |
}; | |
export default useToast; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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