Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import React, { Component } from 'react';
- import { connect } from 'react-redux';
- import * as actions from '../../actions';
- import Loading from '../Loading';
- import Poll from './Poll';
- class MyPolls extends Component {
- constructor(props) {
- super(props);
- this.state = {
- skip: 0,
- isLoading: true,
- isLoadingMore: false,
- };
- }
- componentDidMount() {
- this.props.fetchMyPolls(this.state.skip)
- .then(() => {
- setTimeout(() => {
- this.setState({
- skip: this.state.skip + 4,
- isLoading: false
- });
- }, 1000);
- });
- }
- loadMore(skip) {
- this.setState({ isLoadingMore: true });
- setTimeout(() => {
- this.props.fetchMyPolls(skip)
- .then(() => {
- const nextSkip = this.state.skip + 4;
- this.setState({
- skip: nextSkip,
- isLoadingMore: false
- });
- });
- }, 1000);
- }
- renderPolls() {
- return this.props.polls.map(poll => {
- return (
- <Poll
- key={poll._id}
- title={poll.title}
- options={poll.options}
- />
- )
- })
- }
- render() {
- console.log(this.props.polls);
- console.log('skip:', this.state.skip);
- return (
- <div className='center-align container'>
- <h2>My Polls</h2>
- {this.state.isLoading ? <Loading size='big' /> :
- <div
- style={{
- display: 'flex',
- flexWrap: 'wrap',
- justifyContent: 'space-evenly',
- alignItems: 'center',
- alignContent: 'center'
- }}>
- {this.renderPolls()}
- </div>}
- <div className='row'>
- {this.state.isLoadingMore ? <Loading size='small' /> :
- <button
- className='btn red lighten-2 wave-effect waves-light' onClick={() => this.loadMore(this.state.skip)}>
- Load More
- </button>}
- </div>
- </div>
- );
- }
- }
- function mapStateToProps({ polls }) {
- return { polls }
- }
- export default connect(mapStateToProps, actions)(MyPolls);
- import React, { Component } from 'react';
- import { connect } from 'react-redux';
- import { reduxForm, Field, FieldArray, arrayPush } from 'redux-form';
- import * as actions from '../../actions';
- import { withRouter } from 'react-router-dom';
- const cardStyle = {
- width: '500px',
- height: '75px',
- margin: '10px auto',
- display: 'flex',
- alignItems: 'center',
- padding: '10px'
- };
- class NewPoll extends Component {
- constructor(props) {
- super(props);
- this.state = {
- showOptions: false,
- option: '',
- title: ''
- };
- this.onOptionInputChange = this.onOptionInputChange.bind(this);
- this.onAddOption = this.onAddOption.bind(this);
- this.renderOption = this.renderOption.bind(this);
- this.renderOptionCard = this.renderOptionCard.bind(this);
- this.renderTitle = this.renderTitle.bind(this);
- this.renderTitleCard = this.renderTitleCard.bind(this);
- }
- onOptionInputChange(event) {
- this.setState({ option: event.target.value });
- }
- onAddOption() {
- const { dispatch } = this.props;
- dispatch(arrayPush('newPollForm', 'options', this.state.option));
- this.setState({ option: '' });
- }
- renderOption(props) {
- return (
- <ul>
- {props.fields.map((option, index) => (
- <li key={index}>
- <div
- className='card'
- style={cardStyle}>
- <Field
- type='text'
- name={option}
- index={index}
- component={this.renderOptionCard}
- />
- <i
- className='material-icons right'
- onClick={() => props.fields.remove(index)}
- >
- delete
- </i>
- </div>
- <div className='red-text'>
- {props.meta.error }
- </div>
- </li>
- ))}
- </ul>
- );
- }
- renderOptionCard({ index, input }) {
- return (
- <span className='card-title'
- style={{ flex: '1' }}>
- {`${index + 1})`} {input.value}
- </span>
- );
- }
- renderTitle({ input, type, placeholder, meta: { touched, error }}) {
- return (
- <div>
- <div className='input-field inline'>
- <input {...input}
- type={type}
- placeholder={placeholder}
- style={{ width: '350px' }}
- />
- <div className='red-text'>
- {touched && error}
- </div>
- </div>
- <button
- type='text'
- className='red lighten-2 btn waves-effect waves-light'
- onClick={() => {
- this.setState({ title: input.value });
- input.value = '';
- }}
- disabled={!input.value}>
- Add Title
- <i className='material-icons right'>
- add
- </i>
- </button>
- </div>
- )
- }
- renderTitleCard({ input }) {
- return (
- <div
- className='card'
- style={cardStyle}>
- <span className='card-title' style={{ flex: '1' }}>
- <strong><u>{input.value}</u></strong>
- </span>
- <i className='material-icons right' onClick={() => this.setState({ title: '' })}>
- delete
- </i>
- </div>
- )
- }
- onPollSubmit(values) {
- const { history } = this.props;
- this.props.submitPoll(values, history);
- }
- render() {
- return (
- <div className='center-align'>
- <h3>Create a new poll:</h3>
- <form onSubmit={this.props.handleSubmit(this.onPollSubmit.bind(this))}>
- <Field
- type='text'
- placeholder='Title'
- name='title'
- component={this.state.title ? this.renderTitleCard : this.renderTitle}
- />
- <FieldArray
- name='options' component={this.renderOption}
- />
- <div className='row'>
- <div className='inline input-field'>
- <input
- value={this.state.option} onChange={this.onOptionInputChange}
- placeholder='Option'
- style={{ width: '300px' }}
- />
- </div>
- <button
- type='text'
- className='red lighten-2 btn waves-effect waves-light'
- onClick={this.onAddOption}
- disabled={!this.state.option}
- >
- Add Option
- <i className='material-icons right'>
- add
- </i>
- </button>
- </div>
- <button
- type='submit'
- className='teal btn-large waves-effect waves-light'
- >
- Submit
- <i className='material-icons right'>
- send
- </i>
- </button>
- </form>
- </div>
- );
- }
- }
- function validate(values) {
- const errors = {};
- if (!values.title) {
- errors.title = 'You must provide a title';
- }
- if (!values.options || values.options.length < 2) {
- errors.options = { _error: 'You must provide at least 2 options' };
- }
- return errors;
- }
- NewPoll = reduxForm({
- form: 'newPollForm',
- validate
- })(NewPoll);
- export default connect(null, actions)(withRouter(NewPoll));
- export const submitPoll = (values, history) => async dispatch => {
- const res = await axios.post('/api/polls', values);
- history.push('/mypolls');
- dispatch({ type: FETCH_USER, payload: res.data });
- }
- export const fetchMyPolls = (skip) => async dispatch => {
- const res = await axios.get(`/api/mypolls/${skip}`);
- dispatch({ type: FETCH_MY_POLLS, payload: res.data });
- }
- app.post('/api/polls', requireLogin, (req, res) => {
- const { title, options } = req.body;
- const poll = new Poll({
- title,
- options: options.map(option => ({ option: option.trim() })),
- dateCreated: Date.now(),
- _user: req.user.id
- });
- poll.save();
- res.send(req.user);
- });
- app.get('/api/mypolls/:skip', requireLogin, (req, res) => {
- Poll.find({ _user: req.user.id })
- .sort({ dateCreated: -1 })
- .skip(parseInt(req.params.skip))
- .limit(4)
- .then(polls => {
- res.send(polls);
- });
- });
- import { FETCH_MY_POLLS, UPDATE_POLL } from '../actions/types';
- export default function(state = [], action) {
- switch(action.type) {
- case FETCH_MY_POLLS:
- return [ ...state, ...action.payload];
- case UPDATE_POLL:
- return (
- [...state].map(poll => {
- if (poll._id === action.payload._id) {
- return action.payload;
- }
- return poll;
- })
- )
- default:
- return state;
- }
- }
Add Comment
Please, Sign In to add comment