mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2024-11-23 23:57:55 -05:00
Studio reporting using legacy endpoint
This commit is contained in:
parent
40b531fe7b
commit
2f5a01eb1e
4 changed files with 237 additions and 1 deletions
137
src/redux/studio-report.js
Normal file
137
src/redux/studio-report.js
Normal file
|
@ -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
|
||||
}
|
||||
};
|
|
@ -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 = ({
|
|||
<StudioDescription />
|
||||
<StudioFollow />
|
||||
<StudioImage />
|
||||
<StudioReport />
|
||||
<Debug
|
||||
label="Studio Info"
|
||||
data={studio}
|
||||
|
|
95
src/views/studio/studio-report.jsx
Normal file
95
src/views/studio/studio-report.jsx
Normal file
|
@ -0,0 +1,95 @@
|
|||
/* eslint-disable react/jsx-no-bind */
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {connect} from 'react-redux';
|
||||
|
||||
import {
|
||||
Fields,
|
||||
actions,
|
||||
selectors
|
||||
} from '../../redux/studio-report';
|
||||
|
||||
const StudioReport = ({
|
||||
canReport,
|
||||
error,
|
||||
field,
|
||||
isOpen,
|
||||
isSubmitting,
|
||||
previouslyReported,
|
||||
handleSetField,
|
||||
handleOpen,
|
||||
handleClose,
|
||||
handleSubmit
|
||||
}) => (
|
||||
<div>
|
||||
<h3>Reporting</h3>
|
||||
{canReport && (
|
||||
<button onClick={handleOpen}>Report</button>
|
||||
)}
|
||||
{isOpen && (
|
||||
<div style={{padding: '1rem', margin: '1rem', border: '1px solid green'}}>
|
||||
<div>Report Studio Modal</div>
|
||||
{previouslyReported ? (
|
||||
<React.Fragment>
|
||||
<div>Submitted the report!</div>
|
||||
<button onClick={handleClose}>Close</button>
|
||||
</React.Fragment>
|
||||
) : (
|
||||
<React.Fragment>
|
||||
<select
|
||||
value={field}
|
||||
onChange={e => handleSetField(e.target.value)}
|
||||
>
|
||||
<option value={Fields.TITLE}>Title</option>
|
||||
<option value={Fields.DESCRIPTION}>Description</option>
|
||||
<option value={Fields.THUMBNAIL}>Thumbnail</option>
|
||||
</select>
|
||||
{error && (
|
||||
<div>
|
||||
<div>There was an error. Try again later?</div>
|
||||
<div><code><pre>error</pre></code></div>
|
||||
</div>
|
||||
)}
|
||||
<button
|
||||
disabled={isSubmitting}
|
||||
onClick={handleSubmit}
|
||||
>
|
||||
Submit
|
||||
</button>
|
||||
<button onClick={handleClose}>Cancel</button>
|
||||
</React.Fragment>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
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);
|
|
@ -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: {
|
||||
|
|
Loading…
Reference in a new issue