add initial poll scafold
This commit is contained in:
parent
8634e86c06
commit
c330e1cb34
|
@ -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>
|
||||||
|
|
|
@ -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}>
|
||||||
|
|
|
@ -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
|
|
@ -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'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue