Skip to content
This repository has been archived by the owner on Aug 17, 2024. It is now read-only.

Commit

Permalink
✨ add status and date to proposal page (#612)
Browse files Browse the repository at this point in the history
  • Loading branch information
bpetetot authored Jul 15, 2019
1 parent b605173 commit 5a32ef1
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 70 deletions.
12 changes: 12 additions & 0 deletions src/helpers/firebase.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import firebase from 'firebase/app'

import { lgf, mdf } from './date'

export const isTimestamp = date => !!date && date instanceof firebase.firestore.Timestamp

export const toDate = (timestamp) => {
Expand All @@ -8,3 +10,13 @@ export const toDate = (timestamp) => {
}
return timestamp
}

export const formatTimestamp = (timestamp, format = 'large') => {
switch (format) {
case 'medium':
return mdf(toDate(timestamp))
case 'large':
default:
return lgf(toDate(timestamp))
}
}
76 changes: 45 additions & 31 deletions src/screens/organizer/components/talkSelection/talkSelection.jsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,33 @@
import React, { Fragment } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import Badge from 'components/badge'

import styles from './talkSelection.module.css'

const TalkSelection = ({
onChange, state, emailStatus, isDeliberationDone,
}) => (
<Fragment>
<div>
{isDeliberationDone && state === 'accepted' && (
<Badge success outline>
Accepted proposal
</Badge>
)}
{isDeliberationDone && state === 'rejected' && (
<Badge error outline>
Rejected proposal
</Badge>
)}
{isDeliberationDone && state === 'confirmed' && <Badge success>Confirmed by speaker</Badge>}
{isDeliberationDone && state === 'declined' && <Badge error>Declined by speaker</Badge>}
</div>
<div className={styles.wrapper}>
{isDeliberationDone && (
<div>
{state === 'accepted' && (
<Badge success outline>
Accepted proposal
</Badge>
)}
{state === 'rejected' && (
<Badge error outline>
Rejected proposal
</Badge>
)}
{state === 'confirmed' && <Badge success>Confirmed by speaker</Badge>}
{state === 'declined' && <Badge error>Declined by speaker</Badge>}
</div>
)}

{!isDeliberationDone && (
<select
className={styles.selector}
onChange={onChange}
onClick={e => e.stopPropagation()}
defaultValue={state}
Expand All @@ -30,26 +36,34 @@ const TalkSelection = ({
Deliberate...
</option>
<option key="accepted" value="accepted">
Accept proposal
Accepted proposal
</option>
<option key="rejected" value="rejected">
Reject proposal
Rejected proposal
</option>
</select>
)}
<div style={{ marginLeft: '1em' }}>
{emailStatus && emailStatus === 'delivered' && (<Badge success outline>Delivered</Badge>)}
</div>
<div>
{emailStatus && emailStatus === 'sending' && (<Badge warning outline>Sending...</Badge>)}
</div>
<div>
{emailStatus && emailStatus === 'sent' && (<Badge warning outline>Sent</Badge>)}
</div>
<div>
{ (!emailStatus || emailStatus === 'none') && (<Badge outline>No email</Badge>)}
</div>
</Fragment>

{emailStatus && emailStatus !== 'none' && (
<div className={styles.email}>
{emailStatus === 'sending' && (
<Badge light outline>
Sending email...
</Badge>
)}
{emailStatus === 'sent' && (
<Badge info outline>
Email sent
</Badge>
)}
{emailStatus === 'delivered' && (
<Badge success outline>
Email delivered
</Badge>
)}
</div>
)}
</div>
)

TalkSelection.propTypes = {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.wrapper {
display: flex;
}

.selector {
min-width: 150px;
}

.email {
margin-left: 1em;
}
1 change: 1 addition & 0 deletions src/screens/organizer/proposal/proposal.container.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const mapStore = (store, props, { router }) => {
loaded: !!proposal && !!event,
proposal,
eventId,
deliberationActive: !!event && event.deliberationActive,
load: () => {
store.dispatch('@@ui/ON_LOAD_PROPOSAL')
store.dispatch('@@ui/ON_LOAD_EVENT')
Expand Down
6 changes: 4 additions & 2 deletions src/screens/organizer/proposal/proposal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,24 @@ import Actions from './actions'

import './proposal.css'

const Proposal = ({ eventId, proposal }) => (
const Proposal = ({ eventId, proposal, deliberationActive }) => (
<div className="proposal">
<Actions className="proposal-actions" eventId={eventId} proposalId={proposal.id} title={proposal.title} />
<Ratings className="proposal-ratings" eventId={eventId} proposal={proposal} />
<Speakers className="proposal-speakers" eventId={eventId} proposal={proposal} />
<Talk className="proposal-talk" eventId={eventId} proposal={proposal} />
<Talk className="proposal-talk" eventId={eventId} proposal={proposal} deliberationActive={deliberationActive} />
</div>
)

Proposal.propTypes = {
eventId: PropTypes.string.isRequired,
proposal: PropTypes.objectOf(PropTypes.any),
deliberationActive: PropTypes.bool,
}

Proposal.defaultProps = {
proposal: {},
deliberationActive: false,
}

export default Proposal
11 changes: 0 additions & 11 deletions src/screens/organizer/proposal/talk/talk.css

This file was deleted.

64 changes: 38 additions & 26 deletions src/screens/organizer/proposal/talk/talk.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,45 @@ import React from 'react'
import PropTypes from 'prop-types'
import cn from 'classnames'

import { withSizes } from 'styles/utils'
import Badge from 'components/badge'
import Markdown from 'components/markdown'
import { FormatBadge, CategoryBadge } from 'screens/components/event/badges'
import './talk.css'
import TalkSelection from 'screens/organizer/components/talkSelection'
import { formatTimestamp } from 'helpers/firebase'

const Talk = ({ eventId, proposal, className }) => (
import styles from './talk.module.css'

const Talk = ({
eventId, proposal, deliberationActive, isMobile, className,
}) => (
<div className={cn(className, 'card')}>
<h2>{proposal.title} </h2>
<div className="proposal-talk-badges">
<FormatBadge
outline
pill
light
eventId={eventId}
formatId={proposal.formats}
/>
<CategoryBadge
outline
pill
light
eventId={eventId}
categoryId={proposal.categories}
/>
<Badge outline pill light>
{proposal.level}
</Badge>
<Badge outline pill light>
{proposal.language}
</Badge>
<div className={styles.title}>
<h2>{proposal.title}</h2>
<div>
{!isMobile && deliberationActive && (
<div>
<TalkSelection proposalId={proposal.id} />
</div>
)}
</div>
</div>
<div className={styles.metadata}>
<div className={styles.badges}>
<FormatBadge outline pill light eventId={eventId} formatId={proposal.formats} />
<CategoryBadge outline pill light eventId={eventId} categoryId={proposal.categories} />
<Badge outline pill light>
{proposal.level}
</Badge>
<Badge outline pill light>
{proposal.language}
</Badge>
</div>
<div>
<small>Submitted on {formatTimestamp(proposal.createTimestamp)}</small>
</div>
</div>
<div className="proposal-talk-info">
<div className={styles.infos}>
<Markdown source={proposal.abstract} />
{proposal.references && <h3>References</h3>}
<Markdown source={proposal.references} />
Expand All @@ -46,11 +54,15 @@ Talk.propTypes = {
eventId: PropTypes.string.isRequired,
proposal: PropTypes.objectOf(PropTypes.any),
className: PropTypes.string,
deliberationActive: PropTypes.bool,
isMobile: PropTypes.bool,
}

Talk.defaultProps = {
proposal: {},
deliberationActive: false,
isMobile: false,
className: undefined,
}

export default Talk
export default withSizes(Talk)
32 changes: 32 additions & 0 deletions src/screens/organizer/proposal/talk/talk.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
.title {
display: flex;
justify-content: space-between;
}

.metadata {
display: flex;
justify-content: space-between;
margin-bottom: 2em;
}

.badges > * {
margin-right: 0.5em;
}

.infos > h3 {
margin-top: 3em;
}

@media only screen and (max-width: 480px) {
.metadata {
flex-direction: column;
}

.badges {
margin-bottom: 1em;
}

.infos > h3 {
margin-top: 2em;
}
}

0 comments on commit 5a32ef1

Please sign in to comment.