add initial poll scafold

This commit is contained in:
Barry Gitarts 2020-07-23 16:04:22 -04:00
parent 8634e86c06
commit c330e1cb34
6 changed files with 141 additions and 14 deletions

View File

@ -8,6 +8,7 @@ import { SetAccount } from './types'
import Header from './components/Header' import Header from './components/Header'
import CreatePoll from './components/CreatePoll' import CreatePoll from './components/CreatePoll'
import ListPolls from './components/ListPolls' import ListPolls from './components/ListPolls'
import Poll from './components/Poll'
import { MessagesProvider } from './context/messages/context' import { MessagesProvider } from './context/messages/context'
declare global { declare global {
@ -74,7 +75,8 @@ function App() {
<Router> <Router>
<Switch> <Switch>
<Route path="/(|list-polls)" component={ListPolls} /> <Route path="/(|list-polls)" component={ListPolls} />
<Route path="create-poll" component={CreatePoll} /> <Route path="/create-poll" component={CreatePoll} />
<Route path="/poll/:id" component={Poll} />
</Switch> </Switch>
</Router> </Router>
</div> </div>

View File

@ -1,19 +1,21 @@
import React, { Fragment, useEffect, useState, useContext } from 'react' import React, { Fragment, useEffect, useState, useContext } from 'react'
import { Link } from 'react-router-dom'
import classnames from 'classnames' import classnames from 'classnames'
import { import {
gotoPublicChat, gotoPublicChat,
getChatMessages, getChatMessages,
useChatMessages useChatMessages
} from '../utils/status' } from '../utils/status'
import { MessagesContext, IMessagesContext } from '../context/messages/context' import { MessagesContext } from '../context/messages/context'
import { verifySignedMessage } from '../utils/signing' import { verifySignedMessage } from '../utils/signing'
import { Topics, Message, ISignedMessage, IEnrichedMessage, IPollInfo, IFormattedDate } from '../types' import { Topics, Message, ISignedMessage, IPollInfo, IFormattedDate } from '../types'
import Typography from '@material-ui/core/Typography' import Typography from '@material-ui/core/Typography'
import StatusButton from './base/Button' import StatusButton from './base/Button'
import useStyles from '../styles/listPolls' import useStyles from '../styles/listPolls'
import { getFromIpfs } from '../utils/ipfs' import { getFromIpfs } from '../utils/ipfs'
import { POLLS_CHANNEL } from './constants' import { POLLS_CHANNEL } from './constants'
import { getFormattedDate } from '../utils/dates' import { getFormattedDate } from '../utils/dates'
import { getNetwork } from '../utils/network'
async function gotoPolls() { async function gotoPolls() {
await gotoPublicChat(POLLS_CHANNEL) await gotoPublicChat(POLLS_CHANNEL)
@ -24,11 +26,18 @@ async function parseEnrichMessages(messages: Topics, setState: Function) {
const parsed: Topics | undefined = await parseMessages(messages) const parsed: Topics | undefined = await parseMessages(messages)
if (!parsed) return if (!parsed) return
const rawPolls: Message[] = parsed['polls'] const rawPolls: Message[] = parsed['polls']
const polls: Message[] = await enrichMessages(rawPolls) const network = await getNetwork()
const enrichedPolls: Message[] = await enrichMessages(rawPolls)
const polls = enrichedPolls.filter(
p => {
if (!!p.pollInfo && !!p.pollInfo.network) {
return p.pollInfo.network === network
}
})
setState({ ...parsed, polls }) setState({ ...parsed, polls })
} }
async function enrichMessages(messages: Message[]) { async function enrichMessages(messages: Message[]): Promise<Message[]> {
const updated = messages.map(async (message): Promise<Message> => { const updated = messages.map(async (message): Promise<Message> => {
const { sigMsg } = message const { sigMsg } = message
if (!message || !sigMsg || !sigMsg.msg) return message if (!message || !sigMsg || !sigMsg.msg) return message
@ -79,7 +88,6 @@ const isOdd = (num: number): boolean => !!(num % 2)
function TableCards({ polls }: ITableCard) { function TableCards({ polls }: ITableCard) {
const classes: any = useStyles() const classes: any = useStyles()
const { cardText, cellColor } = classes const { cardText, cellColor } = classes
console.log({polls})
return ( return (
<Fragment> <Fragment>
@ -97,7 +105,9 @@ function TableCards({ polls }: ITableCard) {
<Typography className={classnames(cellStyling, classes.cardTitle)}>{title}</Typography> <Typography className={classnames(cellStyling, classes.cardTitle)}>{title}</Typography>
<Typography className={classnames(cellStyling, classes.cardSubTitle)}>{description}</Typography> <Typography className={classnames(cellStyling, classes.cardSubTitle)}>{description}</Typography>
<Typography className={lightText}>{plainText}</Typography> <Typography className={lightText}>{plainText}</Typography>
<Link to={pollUrl} className={classnames(cellStyling, classes.link)}>
<Typography className={classnames(cellStyling, classes.voteNow)}>Vote now</Typography> <Typography className={classnames(cellStyling, classes.voteNow)}>Vote now</Typography>
</Link>
</Fragment> </Fragment>
) )
@ -108,10 +118,8 @@ function TableCards({ polls }: ITableCard) {
function ListPolls() { function ListPolls() {
const [rawMessages] = useChatMessages() const [rawMessages] = useChatMessages()
//const [chatMessages, setChatMessages] = useState()
const [enrichedPolls, setEnrichedPolls] = useState()
const messagesContext = useContext(MessagesContext) const messagesContext = useContext(MessagesContext)
const { dispatchSetPolls, dispatchSetTopics, chatMessages } = messagesContext const { dispatchSetTopics, chatMessages } = messagesContext
const classes: any = useStyles() const classes: any = useStyles()
@ -123,7 +131,6 @@ function ListPolls() {
if (rawMessages && dispatchSetTopics) parseEnrichMessages(rawMessages, dispatchSetTopics) if (rawMessages && dispatchSetTopics) parseEnrichMessages(rawMessages, dispatchSetTopics)
}, [rawMessages]) }, [rawMessages])
console.log({chatMessages, rawMessages, messagesContext})
return ( return (
<Fragment> <Fragment>
<div className={classes.root}> <div className={classes.root}>

View File

@ -0,0 +1,75 @@
import React, { Fragment, useContext } from 'react'
import useStyles from '../styles/poll'
import { useParams } from "react-router-dom"
import { MessagesContext } from '../context/messages/context'
import Typography from '@material-ui/core/Typography'
import TextField from '@material-ui/core/TextField'
import MenuItem from '@material-ui/core/MenuItem'
import { Formik, FormikProps } from 'formik'
type IBallot = {
option: string
}
function Poll() {
const { id } = useParams()
const classes: any = useStyles()
const messagesContext = useContext(MessagesContext)
const { chatMessages } = messagesContext
console.log({chatMessages})
if (!chatMessages) return <Fragment />
const selectedPoll= chatMessages['polls'].find(p => p.messageId === id)
if (!selectedPoll || !selectedPoll.pollInfo) return <Fragment />
const { pollInfo } = selectedPoll
const { description, title, subtitle, pollOptions } = pollInfo
const options = pollOptions.split(',')
// TODO Display ^above data
// TODO Add method to vote
//TODO vote options are drop down menu
// TODO Add method to tabulate votes
console.log({selectedPoll, options})
return (
<Formik
initialValues={{
option: ''
}}
onSubmit={(values) => {
console.log({values})
}}
>
{({
values,
errors,
handleChange,
handleSubmit
}: FormikProps<IBallot>) => {
return (
<form className={classes.root} onSubmit={handleSubmit}>
<Typography className={classes.title}>{title}</Typography>
<Typography className={classes.subtitle}>{subtitle}</Typography>
<Typography className={classes.description}>{description}</Typography>
<TextField
id="option"
name="option"
className={classes.dropDown}
select
label="Select"
value={values.option}
onChange={handleChange}
helperText="Select an option"
>
{options.map((option) => (
<MenuItem key={option} value={option}>
{option}
</MenuItem>
))}
</TextField>
</form>
)}
}
</Formik>
)
}
export default Poll

View File

@ -32,6 +32,14 @@ const useStyles = makeStyles(theme => ({
}, },
voteNow: { voteNow: {
color: theme.palette.primary[500] color: theme.palette.primary[500]
},
link: {
gridColumn: '1 / 49',
padding: 0,
textDecoration: 'none',
'&:hover': {
textDecoration: 'underline'
}
} }
})) }))

38
dapp/src/styles/poll.js Normal file
View File

@ -0,0 +1,38 @@
import { makeStyles } from '@material-ui/core/styles'
const useStyles = makeStyles(theme => ({
root: {
display: 'grid',
gridTemplateColumns: 'repeat(48, [col] 1fr)',
gridColumn: '3 / 45',
[theme.breakpoints.up('md')]: {
gridTemplateRows: '4rem 4rem auto auto 6rem',
gridColumn: '8 / 42',
}
},
title: {
gridColumn: '3 / 45',
fontSize: '3rem'
},
subtitle: {
gridColumn: '2 / 45',
fontSize: '2rem'
},
description: {
gridColumn: '3 / 45',
fontSize: '1rem'
},
dropDown: {
gridColumn: '3 / 45'
},
link: {
gridColumn: '1 / 49',
padding: 0,
textDecoration: 'none',
'&:hover': {
textDecoration: 'underline'
}
}
}))
export default useStyles

View File

@ -33,9 +33,6 @@ export type Message = {
export type Topics = { export type Topics = {
[chat: string]: Message[] [chat: string]: Message[]
} }
export interface IEnrichedMessage extends ISignedMessage {
pollInfo: IPollInfo
}
export type IFormattedDate = { export type IFormattedDate = {
plainText: string, plainText: string,
daysRemaining: number, daysRemaining: number,