mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-10-29 18:14:34 +08:00
* 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>
245 lines
7.1 KiB
TypeScript
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);
|