diff --git a/src/redux/studio-report.js b/src/redux/studio-report.js new file mode 100644 index 000000000..de434f9bc --- /dev/null +++ b/src/redux/studio-report.js @@ -0,0 +1,137 @@ +const keyMirror = require('keymirror'); + +const api = require('../lib/api'); +const {selectIsLoggedIn} = require('./session'); +const {selectStudioId} = require('./studio'); + +const Actions = keyMirror({ + OPEN_STUDIO_REPORT: null, + CLOSE_STUDIO_REPORT: null, + SET_STUDIO_REPORT_STATUS: null, + SET_STUDIO_REPORT_FIELD: null +}); + +const Status = keyMirror({ + IDLE: null, + SUBMITTING: null, + SUBMITTED: null +}); + +const Fields = { + TITLE: 'title', + DESCRIPTION: 'description', + THUMBNAIL: 'thumbnail' +}; + +const Errors = keyMirror({ + GENERIC: null +}); + +const getInitialState = () => ({ + status: Status.IDLE, + field: Fields.TITLE, + error: null, + isOpen: false +}); + +const studioReportReducer = (state, action) => { + if (typeof state === 'undefined') { + state = getInitialState(); + } + + switch (action.type) { + case Actions.OPEN_STUDIO_REPORT: + return { + ...state, + isOpen: true + }; + case Actions.CLOSE_STUDIO_REPORT: + return { + ...state, // Leaves the submitted status to prevent double submission + isOpen: false + }; + case Actions.SET_STUDIO_REPORT_STATUS: + return { + ...state, + status: action.status, + error: typeof action.error === 'undefined' ? null : action.error + }; + case Actions.SET_STUDIO_REPORT_FIELD: + return { + ...state, + field: action.field + }; + default: + return state; + } +}; + +// Selectors +const selectStudioReportField = state => state.studioReport.field; +const selectStudioReportOpen = state => state.studioReport.isOpen; +const selectStudioReportSubmitting = state => state.studioReport.status === Status.SUBMITTING; +const selectStudioReportSubmitted = state => state.studioReport.status === Status.SUBMITTED; +const selectStudioReportError = state => state.studioReport.error; +const selectCanReportStudio = state => !!selectIsLoggedIn(state); // TODO selectIsLoggedIn isn't returning bool? + +// Action Creators +const setReportStatus = (status, error) => ({ + type: Actions.SET_STUDIO_REPORT_STATUS, + status, + error +}); + +const openStudioReport = () => ({ + type: Actions.OPEN_STUDIO_REPORT +}); + +const closeStudioReport = () => ({ + type: Actions.CLOSE_STUDIO_REPORT +}); + +const setStudioReportField = field => ({ + type: Actions.SET_STUDIO_REPORT_FIELD, + field +}); + +const submitStudioReport = () => ((dispatch, getState) => { + dispatch(setReportStatus(Status.SUBMITTING)); + const studioId = selectStudioId(getState()); + const field = selectStudioReportField(getState()); + api({ + host: '', + uri: `/site-api/galleries/all/${studioId}/report/`, + method: 'POST', + useCsrf: true, + formData: { + selected_field: field + } + }, (err, body, res) => { + if (err || (body && body.success === false) || res.statusCode !== 200) { + dispatch(setReportStatus(Status.IDLE, Errors.GENERIC)); + return; + } + dispatch(setReportStatus(Status.SUBMITTED)); + }); +}); + +module.exports = { + Errors, + Fields, + getInitialState, + studioReportReducer, + actions: { + openStudioReport, + closeStudioReport, + setStudioReportField, + submitStudioReport + }, + selectors: { + selectStudioReportField, + selectStudioReportOpen, + selectCanReportStudio, + selectStudioReportSubmitting, + selectStudioReportSubmitted, + selectStudioReportError + } +}; diff --git a/src/views/studio/studio-info.jsx b/src/views/studio/studio-info.jsx index 7a12364db..156e8608d 100644 --- a/src/views/studio/studio-info.jsx +++ b/src/views/studio/studio-info.jsx @@ -9,6 +9,7 @@ import StudioImage from './studio-image.jsx'; import {selectIsLoggedIn} from '../../redux/session'; import {getInfo, getRoles} from '../../redux/studio'; +import StudioReport from './studio-report.jsx'; const StudioInfo = ({ isLoggedIn, studio, onLoadInfo, onLoadRoles @@ -28,6 +29,7 @@ const StudioInfo = ({ + ( + + Reporting + {canReport && ( + Report + )} + {isOpen && ( + + Report Studio Modal + {previouslyReported ? ( + + Submitted the report! + Close + + ) : ( + + handleSetField(e.target.value)} + > + Title + Description + Thumbnail + + {error && ( + + There was an error. Try again later? + error + + )} + + Submit + + Cancel + + )} + + )} + +); + +StudioReport.propTypes = { + canReport: PropTypes.bool, + error: PropTypes.string, + field: PropTypes.string, + isOpen: PropTypes.bool, + isSubmitting: PropTypes.bool, + previouslyReported: PropTypes.bool, + handleOpen: PropTypes.func, + handleClose: PropTypes.func, + handleSetField: PropTypes.func, + handleSubmit: PropTypes.func +}; + +export default connect( + state => ({ + canReport: selectors.selectCanReportStudio(state), + error: selectors.selectStudioReportError(state), + field: selectors.selectStudioReportField(state), + isOpen: selectors.selectStudioReportOpen(state), + isSubmitting: selectors.selectStudioReportSubmitting(state), + previouslyReported: selectors.selectStudioReportSubmitted(state) + }), + { + handleOpen: actions.openStudioReport, + handleClose: actions.closeStudioReport, + handleSetField: actions.setStudioReportField, + handleSubmit: actions.submitStudioReport + } +)(StudioReport); diff --git a/src/views/studio/studio.jsx b/src/views/studio/studio.jsx index c03a7f28d..370a83084 100644 --- a/src/views/studio/studio.jsx +++ b/src/views/studio/studio.jsx @@ -25,6 +25,7 @@ import { } from './lib/redux-modules'; const {getInitialState, studioReducer} = require('../../redux/studio'); +const {studioReportReducer} = require('../../redux/studio-report'); const {commentsReducer} = require('../../redux/comments'); const {studioMutationsReducer} = require('../../redux/studio-mutations'); @@ -77,9 +78,10 @@ render( [curators.key]: curators.reducer, [managers.key]: managers.reducer, [activity.key]: activity.reducer, + comments: commentsReducer, studio: studioReducer, studioMutations: studioMutationsReducer, - comments: commentsReducer + studioReport: studioReportReducer }, { studio: {
error