Files
freeCodeCamp/client/src/client-only-routes/show-settings.tsx
T
Radi TotevandOliver Eyton-Williams e17e57aba5 feat: update keyboard shortcuts client endpoint (#46378)
* feat: update keyboard shortcuts client endpoint

* Update client/src/redux/settings/settings-sagas.js

Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>

* Update putUpdateMyKeyboardShortcuts return type

* Use new saga in shortcuts-modal

Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
2022-07-01 11:38:06 -07:00

245 lines
7.1 KiB
TypeScript

import { Grid } from '@freecodecamp/react-bootstrap';
import React, { useRef } from 'react';
import Helmet from 'react-helmet';
import { useTranslation } from 'react-i18next';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import envData from '../../../config/env.json';
import { createFlashMessage } from '../components/Flash/redux';
import { Loader, Spacer } from '../components/helpers';
import Certification from '../components/settings/certification';
import About from '../components/settings/about';
import DangerZone from '../components/settings/danger-zone';
import Email from '../components/settings/email';
import Honesty from '../components/settings/honesty';
import Internet from '../components/settings/internet';
import Portfolio from '../components/settings/portfolio';
import Privacy from '../components/settings/privacy';
import { Themes } from '../components/settings/theme';
import UserToken from '../components/settings/user-token';
import {
signInLoadingSelector,
userSelector,
isSignedInSelector,
hardGoTo as navigate,
userTokenSelector
} from '../redux';
import { User } from '../redux/prop-types';
import {
submitNewAbout,
updateMyHonesty,
updateMyPortfolio,
updateMyQuincyEmail,
updateMySound,
updateMyTheme,
updateMyKeyboardShortcuts,
updateUserFlag,
verifyCert
} from '../redux/settings';
const { apiLocation } = envData;
// TODO: update types for actions
interface ShowSettingsProps {
createFlashMessage: typeof createFlashMessage;
isSignedIn: boolean;
navigate: (location: string) => void;
showLoading: boolean;
submitNewAbout: () => void;
toggleNightMode: (theme: Themes) => void;
toggleSoundMode: (sound: boolean) => void;
toggleKeyboardShortcuts: (keyboardShortcuts: boolean) => void;
updateInternetSettings: () => void;
updateIsHonest: () => void;
updatePortfolio: () => void;
updateQuincyEmail: (isSendQuincyEmail: boolean) => void;
user: User;
verifyCert: () => void;
path?: string;
userToken: string | null;
}
const mapStateToProps = createSelector(
signInLoadingSelector,
userSelector,
isSignedInSelector,
userTokenSelector,
(showLoading: boolean, user: User, isSignedIn, userToken: string | null) => ({
showLoading,
user,
isSignedIn,
userToken
})
);
const mapDispatchToProps = {
createFlashMessage,
navigate,
submitNewAbout,
toggleNightMode: (theme: Themes) => updateMyTheme({ theme }),
toggleSoundMode: (sound: boolean) => updateMySound({ sound }),
toggleKeyboardShortcuts: (keyboardShortcuts: boolean) =>
updateMyKeyboardShortcuts({ keyboardShortcuts }),
updateInternetSettings: updateUserFlag,
updateIsHonest: updateMyHonesty,
updatePortfolio: updateMyPortfolio,
updateQuincyEmail: (sendQuincyEmail: boolean) =>
updateMyQuincyEmail({ sendQuincyEmail }),
verifyCert
};
export function ShowSettings(props: ShowSettingsProps): JSX.Element {
const { t } = useTranslation();
const {
createFlashMessage,
isSignedIn,
submitNewAbout,
toggleNightMode,
toggleSoundMode,
toggleKeyboardShortcuts,
user: {
completedChallenges,
email,
is2018DataVisCert,
isApisMicroservicesCert,
isJsAlgoDataStructCert,
isBackEndCert,
isDataVisCert,
isFrontEndCert,
isInfosecQaCert,
isQaCertV7,
isInfosecCertV7,
isFrontEndLibsCert,
isFullStackCert,
isRespWebDesignCert,
isSciCompPyCertV7,
isDataAnalysisPyCertV7,
isMachineLearningPyCertV7,
isRelationalDatabaseCertV8,
isEmailVerified,
isHonest,
sendQuincyEmail,
username,
about,
picture,
points,
theme,
sound,
keyboardShortcuts,
location,
name,
githubProfile,
linkedin,
twitter,
website,
portfolio
},
navigate,
showLoading,
updateQuincyEmail,
updateInternetSettings,
updatePortfolio,
updateIsHonest,
verifyCert,
userToken
} = props;
const isSignedInRef = useRef(isSignedIn);
if (showLoading) {
return <Loader fullScreen={true} />;
}
if (!isSignedInRef.current) {
navigate(`${apiLocation}/signin`);
return <Loader fullScreen={true} />;
}
return (
<>
<Helmet title={`${t('buttons.settings')} | freeCodeCamp.org`} />
<Grid>
<main>
<Spacer size={2} />
<h1 className='text-center' style={{ overflowWrap: 'break-word' }}>
{t('settings.for', { username: username })}
</h1>
<About
about={about}
currentTheme={theme}
location={location}
name={name}
picture={picture}
points={points}
sound={sound}
keyboardShortcuts={keyboardShortcuts}
submitNewAbout={submitNewAbout}
toggleNightMode={toggleNightMode}
toggleSoundMode={toggleSoundMode}
toggleKeyboardShortcuts={toggleKeyboardShortcuts}
username={username}
/>
<Spacer />
<Privacy />
<Spacer />
<Email
email={email}
isEmailVerified={isEmailVerified}
sendQuincyEmail={sendQuincyEmail}
updateQuincyEmail={updateQuincyEmail}
/>
<Spacer />
<Internet
githubProfile={githubProfile}
linkedin={linkedin}
twitter={twitter}
updateInternetSettings={updateInternetSettings}
website={website}
/>
<Spacer />
{/* @ts-expect-error Portfolio types mismatch */}
<Portfolio portfolio={portfolio} updatePortfolio={updatePortfolio} />
<Spacer />
<Honesty isHonest={isHonest} updateIsHonest={updateIsHonest} />
<Spacer />
<Certification
completedChallenges={completedChallenges}
createFlashMessage={createFlashMessage}
is2018DataVisCert={is2018DataVisCert}
isApisMicroservicesCert={isApisMicroservicesCert}
isBackEndCert={isBackEndCert}
isDataAnalysisPyCertV7={isDataAnalysisPyCertV7}
isDataVisCert={isDataVisCert}
isFrontEndCert={isFrontEndCert}
isFrontEndLibsCert={isFrontEndLibsCert}
isFullStackCert={isFullStackCert}
isHonest={isHonest}
isInfosecCertV7={isInfosecCertV7}
isInfosecQaCert={isInfosecQaCert}
isJsAlgoDataStructCert={isJsAlgoDataStructCert}
isMachineLearningPyCertV7={isMachineLearningPyCertV7}
isQaCertV7={isQaCertV7}
isRelationalDatabaseCertV8={isRelationalDatabaseCertV8}
isRespWebDesignCert={isRespWebDesignCert}
isSciCompPyCertV7={isSciCompPyCertV7}
username={username}
verifyCert={verifyCert}
/>
{userToken && (
<>
<Spacer />
<UserToken />
</>
)}
<Spacer />
<DangerZone />
</main>
</Grid>
</>
);
}
ShowSettings.displayName = 'ShowSettings';
export default connect(mapStateToProps, mapDispatchToProps)(ShowSettings);