Skip to content

Instantly share code, notes, and snippets.

@adrianhajdin
Created September 29, 2021 17:28
Show Gist options
  • Select an option

  • Save adrianhajdin/5fea42c89bd78da47eee1d30c740bf5a to your computer and use it in GitHub Desktop.

Select an option

Save adrianhajdin/5fea42c89bd78da47eee1d30c740bf5a to your computer and use it in GitHub Desktop.

Revisions

  1. adrianhajdin created this gist Sep 29, 2021.
    81 changes: 81 additions & 0 deletions Poll.jsx
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,81 @@

    import React, { useState, useEffect, useContext } from "react";
    import Modal from 'react-modal';
    import { Line } from 'rc-progress';
    import { Text } from 'react-native';

    import chatContext, {controlMessageEnum} from './ChatContext';
    import { PollContext } from './PollContext';
    import styles from './pollStyles';

    const Poll = () => {
    const { question, setQuestion, answers: voteData, setAnswers, isModalOpen, setIsModalOpen } = useContext(PollContext)
    const { sendControlMessage } = useContext(chatContext);
    const [totalVotes, setTotalVotes] = useState(0);
    const [voted, setVoted] = useState(false);

    useEffect(() => {
    if(voteData.length > 0){
    setTotalVotes(voteData.map(item => item.votes).reduce((prev, next) => prev + next));
    }
    }, [voteData])

    const submitVote = (e, item) => {
    if(voted === false) {
    const newAnswers = voteData.map((answer) => {
    if(answer.option === item.option) {
    return { ...answer, votes: answer.votes + 1 }
    } else {
    return answer;
    }
    });

    setAnswers(newAnswers);
    sendControlMessage(controlMessageEnum.initiatePoll, { question, answers: newAnswers })
    setTotalVotes(totalVotes + 1);
    setVoted((prevVoted) => !prevVoted);
    }
    };

    const closeModal = () => {
    setIsModalOpen(false);
    setTotalVotes(0);
    setVoted(false);
    setQuestion('');
    setAnswers([
    { option: '', votes: 0 },
    { option: '', votes: 0 },
    { option: '', votes: 0 },
    { option: '', votes: 0 }
    ]);
    }

    return (
    <Modal
    isOpen={isModalOpen}
    onRequestClose={closeModal}
    style={styles.customStyles}
    contentLabel="Poll Modal"
    >
    <div>
    <h1>{question}</h1>
    <div style={styles.flexColumn}>
    {voteData && voteData.map((item, i) => !voted ? (
    <button style={styles.button} key={i} onClick={(e) => submitVote(e, item)}>
    {item.option}
    </button>
    ) : (
    <div style={styles.flexCenter}>
    <h2 style={styles.mr20}>{item.option}</h2>
    <Line percent={(item.votes / totalVotes) * 100} strokeWidth="5" trailWidth="3" />
    <p style={styles.ml20}>{item.votes}</p>
    </div>
    ))}
    </div>
    <h3>Total Votes: {totalVotes}</h3>
    </div>
    </Modal>
    );
    }

    export default Poll;
    30 changes: 30 additions & 0 deletions PollContext.jsx
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,30 @@
    import { createContext } from 'react';
    import React, { useState } from 'react';

    export const PollContext = createContext();

    const PollProvider = (props) => {
    const [question, setQuestion] = useState('');
    const [isModalOpen, setIsModalOpen] = useState(false);
    const [answers, setAnswers] = useState([
    { option: '', votes: 0 },
    { option: '', votes: 0 },
    { option: '', votes: 0 },
    { option: '', votes: 0 }
    ]);

    return (
    <PollContext.Provider value={{
    answers,
    setAnswers,
    question,
    setQuestion,
    isModalOpen,
    setIsModalOpen
    }}>
    {props.children}
    </PollContext.Provider>
    );
    };

    export default PollProvider;
    33 changes: 33 additions & 0 deletions pollStyles.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,33 @@
    export default {
    button: {
    border: 'none',
    cursor: 'pointer',
    margin: '10px 0',
    outline: 'none',
    padding: '15px',
    fontWeight: 'bold',
    },
    customStyles: {
    content: {
    width: '50%',
    top: '50%',
    left: '50%',
    right: 'auto',
    bottom: 'auto',
    marginRight: '-50%',
    transform: 'translate(-50%, -50%)'
    }
    },
    flexColumn: {
    display: 'flex', flexDirection: 'column'
    },
    flexCenter: {
    display: 'flex', alignItems: 'center'
    },
    mr20: {
    marginRight: '20px'
    },
    ml20: {
    marginLeft: '20px'
    }
    }