Skip to content

Commit

Permalink
Making the information about not-verified email address more persiste…
Browse files Browse the repository at this point in the history
…nt and visible on multiple places.
  • Loading branch information
krulis-martin committed Oct 5, 2021
1 parent e2e57d0 commit ccfd6ce
Show file tree
Hide file tree
Showing 11 changed files with 128 additions and 64 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';

import ResendVerificationEmail from '../../../containers/ResendVerificationEmailContainer';
import Callout from '../../widgets/Callout';
import Button, { TheButtonGroup } from '../../widgets/TheButton';
import { RefreshIcon } from '../../icons';

const NotVerifiedEmailCallout = ({ userId, refreshUser }) => (
<Callout variant="warning">
<h3>
<FormattedMessage id="app.editUser.emailStillNotVerifiedTitle" defaultMessage="Email Address Is Not Verified" />
</h3>
<p>
<FormattedMessage
id="app.editUser.emailStillNotVerified"
defaultMessage="Your email addres has not been verified yet. ReCodEx needs to rely on vaild addresses since many notifications are sent via email. You may send yourself a validation email using the button below and then use a link from that email to verify its acceptance. Please validate your address as soon as possible."
/>
</p>
<p>
<FormattedMessage
id="app.editUser.isEmailAlreadyVefiried"
defaultMessage="If you have just verified your email and still see the message, please refresh the page."
/>
</p>
<TheButtonGroup className="mb-2">
<ResendVerificationEmail userId={userId} />
<Button variant="outline-secondary" onClick={refreshUser}>
<RefreshIcon gapRight />
<FormattedMessage id="generic.refresh" defaultMessage="Refresh" />
</Button>
</TheButtonGroup>
</Callout>
);

NotVerifiedEmailCallout.propTypes = {
userId: PropTypes.string.isRequired,
refreshUser: PropTypes.func.isRequired,
};

export default NotVerifiedEmailCallout;
2 changes: 2 additions & 0 deletions src/components/Users/NotVerifiedEmailCallout/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import NotVerifiedEmailCallout from './NotVerifiedEmailCallout';
export default NotVerifiedEmailCallout;
1 change: 1 addition & 0 deletions src/components/Users/UsersName/NotVerified.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const NotVerified = ({ userId, currentUserId }) => {
<OverlayTrigger
trigger="click"
rootClose={true}
placement="bottom"
overlay={
<Popover id={userId}>
<Popover.Title>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,15 @@ const EditUserSettingsForm = ({
<FormattedMessage id="app.editUserSettings.emailsTitle" defaultMessage="Email Notifications" />:
</h4>

{!user.isVerified && (
<Callout variant="warning">
<FormattedMessage
id="app.editUserSettings.emailStillNotVerifiedTitle"
defaultMessage="Your email address is not verified, so no notifications will be sent regardless your personal settings."
/>
</Callout>
)}

{isStudentRole(user.privateData.role) && (
<>
<Field
Expand Down
2 changes: 1 addition & 1 deletion src/components/widgets/Sidebar/UserPanel/UserPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class UserPanel extends Component {
size={small ? 32 : 42}
/>
) : (
<UserName currentUserId={''} {...user} isVerified />
<UserName currentUserId={user.id} {...user} />
)}
</div>

Expand Down
45 changes: 23 additions & 22 deletions src/locales/cs.json
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@
"app.changePassword.tokenExpired": "Vaše heslo nemůže být změněno - Váš token pravděpodobně vypršel nebo máte nesprávný formát URL.",
"app.changePassword.tokenExpiresIn": "Token vyprší za:",
"app.changePasswordForm.changePassword": "Změnit heslo",
"app.changePasswordForm.email": "Email:",
"app.changePasswordForm.email": "E-mail:",
"app.changePasswordForm.failed": "Změna hesla selhala.",
"app.changePasswordForm.oldPassword": "Staré heslo:",
"app.changePasswordForm.password": "Nové heslo:",
Expand Down Expand Up @@ -217,7 +217,7 @@
"app.createGroup.makeMeAdmin": "Chci být administrátorem skupiny",
"app.createGroup.publicStats": "Studenti mohou vidět dosažené body ostatních",
"app.createGroup.threshold": "Minimální procentuální hranice potřebná ke splnění tohoto kurzu:",
"app.createUserForm.validation.emailTaken": "Tato emailová adresa již patří jinému uživateli.",
"app.createUserForm.validation.emailTaken": "Tato e-mailová adresa již patří jinému uživateli.",
"app.createUserForm.validation.emptyPassword": "Heslo nemůže zůstat prázdné.",
"app.dashboard.memberOf": "Skupiny, ve kterých jste členem",
"app.dashboard.sisGroupsStudent": "Přihlásit se do skupin asociovaných s kurzy ze SISu UK",
Expand Down Expand Up @@ -548,8 +548,8 @@
"app.editTestsTest.pointsPercentage": "Body v procentech:",
"app.editTestsTest.testUsedInExpression": "použit ve výrazu",
"app.editTestsTest.weight": "Váha testu:",
"app.editUser.emailStillNotVerified": "Vaše emailová adresa dosud nebyla ověřena. ReCodEx se potřebuje spolehnout na platnost adres, protože řada notifikací je zasílána emailem. Pomocí tlačítka níže si můžete nechat opětovně zaslat ověřovací email. Ten obsahuje odkaz, který potvrzuje platnost adresy. Prosíme, ověřte vaši adresu co nejdříve.",
"app.editUser.emailStillNotVerifiedTitle": "Emailová adresa není ověřena",
"app.editUser.emailStillNotVerified": "Vaše e-mailová adresa dosud nebyla ověřena. ReCodEx se potřebuje spolehnout na platnost adres, protože řada notifikací je zasílána e-mailem. Pomocí tlačítka níže si můžete nechat opětovně zaslat ověřovací e-mail. Ten obsahuje odkaz, který potvrzuje platnost adresy. Prosíme, ověřte vaši adresu co nejdříve.",
"app.editUser.emailStillNotVerifiedTitle": "E-mailová adresa není ověřena",
"app.editUser.isEmailAlreadyVefiried": "Pokud jste právě ověřili vaši adresu a stále vidíte tuto hlášku, prosím občerstvěte stránku.",
"app.editUser.makeLocal": "Vytvořit lokální účet",
"app.editUser.title": "Upravit uživatelský profil",
Expand All @@ -562,9 +562,9 @@
"app.editUserProfile.passwordTitle": "Změna hesla",
"app.editUserProfile.titlesAfterName": "Tituly za jménem:",
"app.editUserProfile.titlesBeforeName": "Tituly před jménem:",
"app.editUserProfile.validation.emailNotValid": "Emailová adresa není platná.",
"app.editUserProfile.validation.emailTaken": "Tento email je již zabrán jiným uživatelem nebo je shodný s vaší starou adresou.",
"app.editUserProfile.validation.emptyEmail": "Emailová adresa nemůže být prázdná.",
"app.editUserProfile.validation.emailNotValid": "E-mailová adresa není platná.",
"app.editUserProfile.validation.emailTaken": "Tento e-mail je již zabrán jiným uživatelem nebo je shodný s vaší starou adresou.",
"app.editUserProfile.validation.emptyEmail": "E-mailová adresa nemůže být prázdná.",
"app.editUserProfile.validation.emptyFirstName": "Jméno nemůže být prázdné.",
"app.editUserProfile.validation.emptyLastName": "Příjmení nemůže být prázdné.",
"app.editUserProfile.validation.emptyNewPassword": "Nové heslo nemůže být prázdné pokud si měníte heslo.",
Expand All @@ -585,7 +585,8 @@
"app.editUserSettings.defaultPage.dashboard": "Přehled",
"app.editUserSettings.defaultPage.home": "Domovská stránka (o ReCodExu)",
"app.editUserSettings.defaultPage.instance": "Detail instance",
"app.editUserSettings.emailsTitle": "Oznámení emailem",
"app.editUserSettings.emailStillNotVerifiedTitle": "Vaše e-mailová adresa nebyla verifikována, takže žádné notifikační maily nebudou zasílány bez ohledu na vaše osobní nastavení.",
"app.editUserSettings.emailsTitle": "Oznámení e-mailem",
"app.editUserSettings.failed": "Uložení uživatelského profilu se nezdařilo.",
"app.editUserSettings.newAssignmentEmails": "Nově zadaná úloha",
"app.editUserSettings.openedSidebar": "Postraní panel je ve výchozím stavu rozbalený.",
Expand All @@ -595,13 +596,13 @@
"app.editUserSettings.title": "Změnit nastavení",
"app.editUserSettings.useGravatar": "Používat službu Gravatar pro zobrazování avatarů ostatních uživatelů.",
"app.editUserSettings.vimMode": "Použít rozložení kláves editoru VIM pro editor zdrojového kódu.",
"app.emailVerification.failed": "Tato emailová adresa nemůže být ověřena.",
"app.emailVerification.progress": "Postup ověřování emailu",
"app.emailVerification.failed": "Tato e-mailová adresa nemůže být ověřena.",
"app.emailVerification.progress": "Postup ověřování e-mailu",
"app.emailVerification.requestAnotherLink": "Prosíme požádejte o (další) odkaz s unikátním tokenem.",
"app.emailVerification.title": "Ověření emailu",
"app.emailVerification.tokenExpired": "Emailová adresa nyní nemůže být ověřena - váš token vypršel nebo používáte špatnou URL.",
"app.emailVerification.verified": "Emailová adresa byla ověřena.",
"app.emailVerification.waiting": "Emailová adresa je právě ověřována.",
"app.emailVerification.title": "Ověření e-mailu",
"app.emailVerification.tokenExpired": "E-mailová adresa nyní nemůže být ověřena - váš token vypršel nebo používáte špatnou URL.",
"app.emailVerification.verified": "E-mailová adresa byla ověřena.",
"app.emailVerification.waiting": "E-mailová adresa je právě ověřována.",
"app.environmentsList.noEnvironments": "žádná běhová prostředí",
"app.evaluationDetail.buildSucceeded": "Kompilace:",
"app.evaluationDetail.evaluatedAt": "Vyhodnoceno:",
Expand Down Expand Up @@ -1205,7 +1206,7 @@
"app.registrationForm.processing": "Probíhá vytváření účtu...",
"app.registrationForm.success": "Váš účet byl vytvořen.",
"app.registrationForm.title": "Vytvořte si účet v ReCodExu",
"app.registrationForm.validation.emailAlreadyTaken": "Tato emailová adresa je již zabraná jiným uživatelem.",
"app.registrationForm.validation.emailAlreadyTaken": "Tato e-mailová adresa je již zabraná jiným uživatelem.",
"app.registrationForm.validation.emailIsNotAnEmail": "E-mailová adresa není zadána správně.",
"app.registrationForm.validation.emptyEmail": "E-mailová adresa nemůže být prázdná.",
"app.registrationForm.validation.emptyFirstName": "Jméno nemůže být prázdné.",
Expand All @@ -1220,9 +1221,9 @@
"app.relocateGroupForm.success": "Skupina přemístěna",
"app.removeFromGroup.confirm": "Opravdu chcete odstranit uživatele z této skupiny?",
"app.resendEmailVerification.failed": "Opětovné odeslání selhalo. Prosíme opakujte akci později",
"app.resendEmailVerification.resend": "Znovu odeslat ověřovací email",
"app.resendEmailVerification.resending": "Odesílání emailu...",
"app.resendEmailVerification.resent": "Email byl úspěšně odeslán",
"app.resendEmailVerification.resend": "Znovu odeslat ověřovací e-mail",
"app.resendEmailVerification.resending": "Odesílání e-mailu...",
"app.resendEmailVerification.resent": "E-mail byl úspěšně odeslán",
"app.resetPassword.email": "E-mailová adresa:",
"app.resetPassword.failed": "Reset hesla se nezdařil. Prosíme, zkontrolujte Vaší mailovou adresu.",
"app.resetPassword.processing": "Resetování hesla...",
Expand Down Expand Up @@ -1499,7 +1500,7 @@
"app.submissionFailures.resolveMaxLengthExceeded": "Délka poznámky byla překročena.",
"app.submissionFailures.resolveNote": "Poznámka k řešení problému:",
"app.submissionFailures.resolveTitle": "Vyřešit chybu",
"app.submissionFailures.sendEmail": "Poslat email",
"app.submissionFailures.sendEmail": "Poslat e-mail",
"app.submissionFailures.title": "Neúspěšná odevzdání",
"app.submissionStatus.accepted": "Toto řešení bylo označeno jako akceptované vedoucím skupiny.",
"app.submissions.testResultsTable.correctness": "Správnost odevzdaného řešení (rozhodnutí sudího)",
Expand Down Expand Up @@ -1603,9 +1604,9 @@
"app.users.takeOver": "Přihlásit jako",
"app.users.title": "Seznam všech uživatelů",
"app.users.userCreatedAt": "Uživatel vytvořen",
"app.usersName.notVerified.title": "Tento účet nemá ověřenou emailovou adresu.",
"app.usersName.notVerified.title": "Tento účet nemá ověřenou e-mailovou adresu.",
"app.usersStats.description": "Body získané ve skupině {name}.",
"app.usersname.notVerified.description": "Tento uživatel si neověřil svou emailovou adresu přes aktivační odkaz, který mu byl na tuto adresu zaslán.",
"app.usersname.notVerified.description": "Tento uživatel si neověřil svou e-mailovou adresu přes aktivační odkaz, který mu byl na tuto adresu zaslán.",
"diff": "Sudí binárních dat",
"generic.accessDenied": "Nemáte oprávnění vidět tuto stránku. Pokud došlo k přesměrování na tuto stránku po kliknutí na zdánlivě legitimní odkaz nebo tlačítko, prosíme nahlaste chybu.",
"generic.acknowledge": "Beru na vědomí",
Expand All @@ -1629,7 +1630,7 @@
"generic.discussion": "Diskuse",
"generic.edit": "Editovat",
"generic.effectiveRole": "Efektivní role",
"generic.email": "Email",
"generic.email": "E-mail",
"generic.enable": "Povolit",
"generic.errorMessage": "Chybová hláška",
"generic.explain": "vysvětlit",
Expand Down
1 change: 1 addition & 0 deletions src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,7 @@
"app.editUserSettings.defaultPage.dashboard": "Dashboard",
"app.editUserSettings.defaultPage.home": "Home page (about)",
"app.editUserSettings.defaultPage.instance": "Instance overview",
"app.editUserSettings.emailStillNotVerifiedTitle": "Your email address is not verified, so no notifications will be sent regardless your personal settings.",
"app.editUserSettings.emailsTitle": "Email Notifications",
"app.editUserSettings.failed": "Cannot save profile settings.",
"app.editUserSettings.newAssignmentEmails": "New exercise assigned",
Expand Down
10 changes: 9 additions & 1 deletion src/pages/Dashboard/Dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { Link } from 'react-router-dom';
import Button, { TheButtonGroup } from '../../components/widgets/TheButton';
import Page from '../../components/layout/Page';
import { UserNavigation } from '../../components/layout/Navigation';
import NotVerifiedEmailCallout from '../../components/Users/NotVerifiedEmailCallout';
import Box from '../../components/widgets/Box';
import Callout from '../../components/widgets/Callout';
import StudentsListContainer from '../../containers/StudentsListContainer';
Expand All @@ -17,7 +18,7 @@ import GroupsNameContainer from '../../containers/GroupsNameContainer';
import AssignmentsTableContainer from '../../containers/AssignmentsTableContainer';
import ShadowAssignmentsTableContainer from '../../containers/ShadowAssignmentsTableContainer';

import { fetchUserIfNeeded } from '../../redux/modules/users';
import { fetchUserIfNeeded, fetchUser } from '../../redux/modules/users';
import { fetchAllGroups } from '../../redux/modules/groups';
import { fetchRuntimeEnvironments } from '../../redux/modules/runtimeEnvironments';

Expand Down Expand Up @@ -61,6 +62,7 @@ class Dashboard extends Component {
supervisor,
memberGroups,
fetchManyGroupsStatus,
refreshUser,
links: { GROUP_INFO_URI_FACTORY, GROUP_DETAIL_URI_FACTORY },
} = this.props;

Expand All @@ -78,6 +80,10 @@ class Dashboard extends Component {
<div>
<UserNavigation userId={user.id} canEdit isLoggedInUser />

{user && !user.isVerified && (
<NotVerifiedEmailCallout userId={user.id} refreshUser={() => refreshUser(user.id)} />
)}

<FetchManyResourceRenderer fetchManyStatus={fetchManyGroupsStatus}>
{() => (
<>
Expand Down Expand Up @@ -228,6 +234,7 @@ Dashboard.propTypes = {
supervisor: PropTypes.bool,
superadmin: PropTypes.bool,
loadAsync: PropTypes.func.isRequired,
refreshUser: PropTypes.func.isRequired,
userId: PropTypes.string,
memberGroups: PropTypes.object.isRequired,
fetchManyGroupsStatus: PropTypes.string,
Expand All @@ -251,6 +258,7 @@ export default withLinks(
},
(dispatch, { match: { params } }) => ({
loadAsync: userId => Dashboard.loadAsync(params, dispatch, { userId }),
refreshUser: userId => dispatch(fetchUser(userId)),
})
)(injectIntl(Dashboard))
);
42 changes: 5 additions & 37 deletions src/pages/EditUser/EditUser.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { connect } from 'react-redux';
import { FormattedMessage, injectIntl } from 'react-intl';
import { FormattedMessage } from 'react-intl';
import { Row, Col } from 'react-bootstrap';
import { defaultMemoize } from 'reselect';

Expand All @@ -17,12 +17,11 @@ import {
import { getUser, isLoggedAsSuperAdmin } from '../../redux/selectors/users';
import Page from '../../components/layout/Page';
import { UserNavigation } from '../../components/layout/Navigation';
import NotVerifiedEmailCallout from '../../components/Users/NotVerifiedEmailCallout';
import Button, { TheButtonGroup } from '../../components/widgets/TheButton';
import Callout from '../../components/widgets/Callout';
import { LocalIcon, TransferIcon, EditUserIcon, RefreshIcon } from '../../components/icons';
import { LocalIcon, TransferIcon, EditUserIcon } from '../../components/icons';
import { isStudentRole } from '../../components/helpers/usersRoles';
import AllowUserButtonContainer from '../../containers/AllowUserButtonContainer';
import ResendVerificationEmail from '../../containers/ResendVerificationEmailContainer';

import EditUserProfileForm from '../../components/forms/EditUserProfileForm';
import EditUserSettingsForm from '../../components/forms/EditUserSettingsForm';
Expand Down Expand Up @@ -72,7 +71,6 @@ class EditUser extends Component {
lastToken,
takeOver,
refreshUser,
intl: { locale },
} = this.props;
return (
<Page
Expand Down Expand Up @@ -113,36 +111,7 @@ class EditUser extends Component {
)}

{data && data.id === loggedUserId && !data.isVerified && (
<Callout variant="warning">
<h3>
<FormattedMessage
id="app.editUser.emailStillNotVerifiedTitle"
defaultMessage="Email Address Is Not Verified"
/>
</h3>
<p>
<FormattedMessage
id="app.editUser.emailStillNotVerified"
defaultMessage="Your email addres has not been verified yet. ReCodEx needs to rely on vaild addresses since many notifications are sent via email. You may send yourself a validation email using the button below and then use a link from that email to verify its acceptance. Please validate your address as soon as possible."
/>
</p>
<p>
<FormattedMessage
id="app.editUser.isEmailAlreadyVefiried"
defaultMessage="If you have just verified your email and still see the message, please refresh the page."
/>
</p>
<p className="em-margin-vertical">
<ResendVerificationEmail
userId={data.id}
locale={locale /* a hack that enforce component refresh on locale change */}
/>
<Button variant="outline-secondary" onClick={refreshUser}>
<RefreshIcon gapRight />
<FormattedMessage id="generic.refresh" defaultMessage="Refresh" />
</Button>
</p>
</Callout>
<NotVerifiedEmailCallout userId={data.id} refreshUser={refreshUser} />
)}

<Row>
Expand Down Expand Up @@ -225,7 +194,6 @@ EditUser.propTypes = {
generateToken: PropTypes.func.isRequired,
setRole: PropTypes.func.isRequired,
takeOver: PropTypes.func.isRequired,
intl: PropTypes.object,
};

export default connect(
Expand Down Expand Up @@ -265,4 +233,4 @@ export default connect(
setRole: role => dispatch(setRole(userId, role)),
takeOver: userId => dispatch(takeOver(userId)),
})
)(injectIntl(EditUser));
)(EditUser);
Loading

0 comments on commit ccfd6ce

Please sign in to comment.