mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2024-12-18 11:32:29 -05:00
adds force account rename page
This commit is contained in:
parent
bc9680cb6f
commit
2f7e12bd0c
4 changed files with 383 additions and 6 deletions
|
@ -14,9 +14,11 @@ const Types = keyMirror({
|
||||||
|
|
||||||
const banGoodListPaths = [
|
const banGoodListPaths = [
|
||||||
'/accounts/banned-response',
|
'/accounts/banned-response',
|
||||||
|
'/accounts/bad-username',
|
||||||
'/community_guidelines',
|
'/community_guidelines',
|
||||||
'/privacy_policy',
|
'/privacy_policy',
|
||||||
'/terms_of_use'
|
'/terms_of_use',
|
||||||
|
'/accounts/update_username'
|
||||||
];
|
];
|
||||||
|
|
||||||
module.exports.Status = keyMirror({
|
module.exports.Status = keyMirror({
|
||||||
|
@ -70,7 +72,11 @@ const handleSessionResponse = (dispatch, body) => {
|
||||||
body.user.banned &&
|
body.user.banned &&
|
||||||
banGoodListPaths.every(goodPath => window.location.pathname.indexOf(goodPath) === -1)
|
banGoodListPaths.every(goodPath => window.location.pathname.indexOf(goodPath) === -1)
|
||||||
) {
|
) {
|
||||||
window.location = '/accounts/banned-response/';
|
if(body.user.banned_status === 'far_banned'){
|
||||||
|
window.location = '/accounts/bad-username/';
|
||||||
|
} else {
|
||||||
|
window.location = '/accounts/banned-response/';
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
} else if (
|
} else if (
|
||||||
body.flags &&
|
body.flags &&
|
||||||
|
|
|
@ -424,10 +424,10 @@
|
||||||
"title": "micro:bit"
|
"title": "micro:bit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "banned-splash",
|
"name": "bad-username-splash",
|
||||||
"pattern": "^/accounts/banned-response/?(\\?.*)?$",
|
"pattern": "^/accounts/bad-username/?(\\?.*)?$",
|
||||||
"routeAlias": "/accounts/banned-response/?$",
|
"routeAlias": "/accounts/bad-username/?$",
|
||||||
"view": "banned-splash/banned-splash",
|
"view": "bad-username-splash/bad-username-splash",
|
||||||
"title": "Account Blocked"
|
"title": "Account Blocked"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
246
src/views/bad-username-splash/bad-username-splash.jsx
Normal file
246
src/views/bad-username-splash/bad-username-splash.jsx
Normal file
|
@ -0,0 +1,246 @@
|
||||||
|
/* eslint-disable */
|
||||||
|
const injectIntl = require('react-intl').injectIntl;
|
||||||
|
// const intlShape = require('react-intl').intlShape;
|
||||||
|
// const FormattedMessage = require('react-intl').FormattedMessage;
|
||||||
|
const React = require('react');
|
||||||
|
const FormattedMessage = require('react-intl').FormattedMessage;
|
||||||
|
import {connect} from 'react-redux';
|
||||||
|
import {selectBannedUser, selectHasFetchedSession} from '../../redux/session';
|
||||||
|
const messageActions = require('../../redux/messages.js');
|
||||||
|
const JoinFlowStep = require('../../components/join-flow/join-flow-step.jsx');
|
||||||
|
const FormikInput = require('../../components/formik-forms/formik-input.jsx');
|
||||||
|
import {Formik} from 'formik';
|
||||||
|
const PropTypes = require('prop-types');
|
||||||
|
|
||||||
|
const Page = require('../../components/page/www/page.jsx');
|
||||||
|
const render = require('../../lib/render.jsx');
|
||||||
|
const api = require('../../lib/api');
|
||||||
|
import bannedIcon from './blocked-account.svg';
|
||||||
|
|
||||||
|
require('../../components/extension-landing/extension-landing.scss');
|
||||||
|
require('./bad-username-splash.scss');
|
||||||
|
|
||||||
|
const BannedSplash = ({hasSession, user, adminMessages, getAdminMessages}) => {
|
||||||
|
|
||||||
|
const [unauthorizedError, setUnauthorizedError] = React.useState(false)
|
||||||
|
const [badUsernameError, setBadUsernameError] = React.useState(false)
|
||||||
|
const [apiError, setAPIError] = React.useState(false)
|
||||||
|
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (user && user.username && user.token){
|
||||||
|
getAdminMessages(user.username, user.token);
|
||||||
|
}
|
||||||
|
}, [user]);
|
||||||
|
|
||||||
|
const handleUpdateUsernameUnbanSubmit = (formData, formikBag) => {
|
||||||
|
setUnauthorizedError(false)
|
||||||
|
setBadUsernameError(false)
|
||||||
|
setAPIError(false)
|
||||||
|
formikBag.setSubmitting(false); // formik makes us do this ourselves
|
||||||
|
|
||||||
|
console.log("attempting submit!")
|
||||||
|
api({
|
||||||
|
host: '',
|
||||||
|
uri: '/accounts/update_username/',
|
||||||
|
method: 'post',
|
||||||
|
useCsrf: true,
|
||||||
|
json: {
|
||||||
|
new_username: formData.newUsername,
|
||||||
|
username: formData.username,
|
||||||
|
password: formData.password
|
||||||
|
}
|
||||||
|
}, (err, body, res) => {
|
||||||
|
if(res.body.error === "Unauthorized"){
|
||||||
|
setUnauthorizedError("error message for unauthorized access")
|
||||||
|
}
|
||||||
|
else if(res.body.error === "Invalid username"){
|
||||||
|
setBadUsernameError("error message for invalid username")
|
||||||
|
}
|
||||||
|
else if(res.body.error){
|
||||||
|
setAPIError("error message for API error")
|
||||||
|
} else{
|
||||||
|
window.location = '/';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasSession && (!user || !user.banned)){
|
||||||
|
window.location = '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user && user.banned){
|
||||||
|
return (<div id="bad-username-splash">
|
||||||
|
<div id="force-account-rename">
|
||||||
|
<div id="force-account-rename-inner">
|
||||||
|
<div
|
||||||
|
id="force-account-rename-text"
|
||||||
|
className="col"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
<img
|
||||||
|
className="banned-icon"
|
||||||
|
src={bannedIcon}
|
||||||
|
/>
|
||||||
|
<h1 className="inline"><FormattedMessage id="renameAccount.accountBlocked"/></h1>
|
||||||
|
</span>
|
||||||
|
<h3><FormattedMessage id="renameAccount.toRecover"/></h3>
|
||||||
|
<p><FormattedMessage id="renameAccount.yourScratchAccount"/></p>
|
||||||
|
<p><FormattedMessage id="renameAccount.privacyIssue"/></p>
|
||||||
|
<p><FormattedMessage id="renameAccount.thingsToAvoid"/></p>
|
||||||
|
</div>
|
||||||
|
<div className="col">
|
||||||
|
<Formik
|
||||||
|
initialValues={{
|
||||||
|
newUsername: '',
|
||||||
|
newUsernameConfirm: '',
|
||||||
|
username: user.username,
|
||||||
|
password: ''
|
||||||
|
}}
|
||||||
|
validateOnBlur={true}
|
||||||
|
validateOnChange={false}
|
||||||
|
onSubmit={handleUpdateUsernameUnbanSubmit}
|
||||||
|
>
|
||||||
|
{({
|
||||||
|
errors,
|
||||||
|
handleSubmit,
|
||||||
|
isSubmitting,
|
||||||
|
setFieldError,
|
||||||
|
setFieldTouched,
|
||||||
|
setFieldValue,
|
||||||
|
// touched,
|
||||||
|
validateField,
|
||||||
|
values
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<JoinFlowStep
|
||||||
|
description={<FormattedMessage id="renameAccount.makeSure"/>}
|
||||||
|
innerClassName="change-username-inner"
|
||||||
|
outerClassName="change-username-outer"
|
||||||
|
title={<FormattedMessage id="renameAccount.changeYourUsername" values={{communityGuidelinesLink: <a href="/community_guidelines"><FormattedMessage id="renameAccount.communityGuidelines"/></a>}}/>}
|
||||||
|
waiting={isSubmitting}
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
nextButton={<FormattedMessage id="renameAccount.change"/>}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<FormikInput
|
||||||
|
autoCapitalize="off"
|
||||||
|
autoComplete="off"
|
||||||
|
autoCorrect="off"
|
||||||
|
error={errors.newUsername}
|
||||||
|
id="newUsername"
|
||||||
|
name="newUsername"
|
||||||
|
placeholder={'Type your new username'}
|
||||||
|
spellCheck={false}
|
||||||
|
// toolTip={this.state.focused === 'username' && !touched.username &&
|
||||||
|
// this.props.intl.formatMessage({id: 'registration.usernameAdviceShort'})}
|
||||||
|
/* eslint-disable react/jsx-no-bind */
|
||||||
|
validate={validateUsername}
|
||||||
|
validationClassName="validation-left validation-full-width-input"
|
||||||
|
/* eslint-disable react/jsx-no-bind */
|
||||||
|
onBlur={() => validateField('newUsername')}
|
||||||
|
onChange={e => {
|
||||||
|
setFieldValue('newUsername', e.target.value.substring(0, 30));
|
||||||
|
setFieldTouched('newUsername');
|
||||||
|
setFieldError('newUsername', null);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<FormikInput
|
||||||
|
autoCapitalize="off"
|
||||||
|
autoComplete="off"
|
||||||
|
autoCorrect="off"
|
||||||
|
className={'join-flow-input'}
|
||||||
|
error={errors.newUsernameConfirm || badUsernameError}
|
||||||
|
id="newUsernameConfirm"
|
||||||
|
name="newUsernameConfirm"
|
||||||
|
placeholder={'Type your new username again'}
|
||||||
|
spellCheck={false}
|
||||||
|
validationClassName="validation-left validation-full-width-input"
|
||||||
|
onChange={e => {
|
||||||
|
setFieldValue('newUsernameConfirm', e.target.value.substring(0, 30));
|
||||||
|
setFieldTouched('newUsernameConfirm');
|
||||||
|
setFieldError('newUsernameConfirm', null);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<FormikInput
|
||||||
|
autoCapitalize="off"
|
||||||
|
autoComplete="off"
|
||||||
|
autoCorrect="off"
|
||||||
|
className={'join-flow-input'}
|
||||||
|
id="password"
|
||||||
|
name="password"
|
||||||
|
placeholder={'Enter your password'}
|
||||||
|
spellCheck={false}
|
||||||
|
error={unauthorizedError || apiError}
|
||||||
|
validationClassName="validation-left validation-full-width-input"
|
||||||
|
onChange={e => {
|
||||||
|
setFieldValue('password', e.target.value);
|
||||||
|
setFieldTouched('password');
|
||||||
|
setFieldError('password', null);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</JoinFlowStep>);
|
||||||
|
}}
|
||||||
|
</Formik>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="admin-message-list">
|
||||||
|
<div id="admin-message-list-title">
|
||||||
|
<b><FormattedMessage id="renameAccount.pastNotifications"/></b>
|
||||||
|
</div>
|
||||||
|
{adminMessages.map(message => (
|
||||||
|
<div
|
||||||
|
className="admin-message"
|
||||||
|
key={message.id}
|
||||||
|
>
|
||||||
|
<div className="admin-message-date">
|
||||||
|
{new Date(message.datetime_created).toDateString()}
|
||||||
|
</div>
|
||||||
|
{/* // eslint-disable-next-line react/no-danger */}
|
||||||
|
<div dangerouslySetInnerHTML={{__html: message.message}} />
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return <div />;
|
||||||
|
};
|
||||||
|
|
||||||
|
BannedSplash.propTypes = {
|
||||||
|
user: PropTypes.shape({
|
||||||
|
username: PropTypes.string,
|
||||||
|
banned: PropTypes.bool,
|
||||||
|
token: PropTypes.string
|
||||||
|
}),
|
||||||
|
hasSession: PropTypes.bool,
|
||||||
|
adminMessages: PropTypes.arrayOf(PropTypes.shape({
|
||||||
|
id: PropTypes.number.isRequired,
|
||||||
|
datetimeCreated: PropTypes.string.isRequired,
|
||||||
|
message: PropTypes.string.isRequired
|
||||||
|
})),
|
||||||
|
getAdminMessages: PropTypes.func
|
||||||
|
};
|
||||||
|
|
||||||
|
const ConnectedBannedSplash = connect(
|
||||||
|
state => ({
|
||||||
|
user: selectBannedUser(state),
|
||||||
|
hasSession: selectHasFetchedSession(state),
|
||||||
|
adminMessages: state.messages.messages && state.messages.messages.admin
|
||||||
|
}),
|
||||||
|
dispatch => ({
|
||||||
|
getAdminMessages: (username, token) => {
|
||||||
|
dispatch(messageActions.getAdminMessages(
|
||||||
|
username, token, 0
|
||||||
|
));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)(BannedSplash);
|
||||||
|
|
||||||
|
|
||||||
|
const WrappedBannedSplash = injectIntl(ConnectedBannedSplash);
|
||||||
|
|
||||||
|
render(<Page><WrappedBannedSplash /></Page>, document.getElementById('app'),
|
||||||
|
{messages: messageActions.messagesReducer});
|
125
src/views/bad-username-splash/bad-username-splash.scss
Normal file
125
src/views/bad-username-splash/bad-username-splash.scss
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
@import "../../colors";
|
||||||
|
@import "../../frameless";
|
||||||
|
|
||||||
|
.validation-left {
|
||||||
|
transform: translate(-20.5rem, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media #{$intermediate-and-smaller} {
|
||||||
|
.validation-full-width-input {
|
||||||
|
box-sizing: border-box;
|
||||||
|
transform: unset;
|
||||||
|
margin-bottom: .75rem;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.inline{
|
||||||
|
display:inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
#bad-username-splash{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#force-account-rename{
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
#force-account-rename-inner{
|
||||||
|
max-width: 1094px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
@media only screen and (max-width: 800px) {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
|
input{
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
background-color: #575E75;
|
||||||
|
.col{
|
||||||
|
padding: 40px;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#admin-message-list{
|
||||||
|
display: inline-block;
|
||||||
|
padding: 25px;
|
||||||
|
max-width: 1094px;
|
||||||
|
|
||||||
|
#admin-message-list-title{
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-message{
|
||||||
|
text-align: left;
|
||||||
|
.admin-message-date{
|
||||||
|
color: #575E75;
|
||||||
|
font-size: 12px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
text-align: left;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 16px;
|
||||||
|
background-color: #E5F0FF;
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#force-account-rename-text{
|
||||||
|
h1, h3, p{
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty{
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
|
.admin-message{
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.banned-message-box{
|
||||||
|
margin: 20px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.join-flow-outer-content{
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 16px;
|
||||||
|
color: #575e75;
|
||||||
|
max-width: 468px;
|
||||||
|
min-height: auto !important;
|
||||||
|
@media only screen and (max-width: 800px) {
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.banned-icon{
|
||||||
|
margin-right: 10px;
|
||||||
|
padding-top: 10px;
|
||||||
|
margin-bottom: -3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-flush-bottom-button{
|
||||||
|
background-color: #855CD6;
|
||||||
|
}
|
||||||
|
.modal-flush-bottom-button:hover{
|
||||||
|
background-color: #855CD6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.join-flow-outer-content{
|
||||||
|
border: solid 4px #818698;
|
||||||
|
border-radius: 21px;
|
||||||
|
}
|
Loading…
Reference in a new issue