feat(client): add local instructions for rdb courses (#59184)

Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
This commit is contained in:
Tom
2025-03-11 04:21:02 -05:00
committed by GitHub
parent fd0c4dbd05
commit 63a4729e9d
12 changed files with 552 additions and 118 deletions
@@ -509,6 +509,28 @@
"learn-more": "Learn more about <0>Gitpod workspaces.</0>",
"logout-warning": "If you log out of freeCodeCamp before you complete the entire {{course}} course, your progress will not be saved to your freeCodeCamp account."
},
"local": {
"intro": "This course runs in a virtual Linux machine on your computer. To run the course, you first need to download each of the following if you don't already have them:",
"download-vscode": "<0>VS Code</0> and the <1>Dev Containers</1> extension",
"heading": "Then, follow these instructions to start the course:",
"step-1": "Open a terminal and clone the RDB Alpha repo if you don't already have it with <0>git clone https://github.com/freeCodeCamp/rdb-alpha</0>",
"step-2": "Navigate to the <0>rdb-alpha</0> directory in the terminal with <1>cd rdb-alpha</1>, and open VS Code with <2>code .</2>",
"sub-step-heading": "If you want to save your progress to your freeCodeCamp account, do the following:",
"sub-step-1": "Generate a user token if you don't already have one:",
"generate-token-btn": "Generate User Token",
"sub-step-2": "Copy your user token:",
"copy-token-btn": "Copy User Token",
"logout-warning": "If you log out of freeCodeCamp before you complete the entire {{course}} course, your user token will be deleted and your progress will not be saved to your freeCodeCamp account.",
"sub-step-3": "In the VS Code that opened, find and open the file named <0>Dockerfile</0>. At the bottom of the file, paste your token in as the value for the <1>CODEROAD_WEBHOOK_TOKEN</1> variable. It should look like this: <2>ENV CODEROAD_WEBHOOK_TOKEN=your-token-here</2>",
"step-3": "Open the command palette in VS Code by expanding the \"View\" menu and clicking \"Command Palette...\" and enter <0>Dev Containers: Rebuild and Reopen in Container</0> in the input.",
"step-4": "A new VS Code window will open and begin building the Docker image. It will take several minutes the first time.",
"step-5": "Once it is finished building, open the command palette again and enter <0>CodeRoad: Start</0> to open CodeRoad.",
"step-6": "In the CodeRoad window, click \"Start New Tutorial\" and then the \"URL\" tab at the top.",
"step-7": "Copy the course URL below, paste it in the URL input, and click \"Load\".",
"copy-url": "Copy Course URL",
"step-8": "Click \"Start\" to begin.",
"step-9": "Follow the instructions in CodeRoad to complete the course. Note: You may need to restart the terminal once for terminal settings to take effect and the tests to pass."
},
"step-1": "Step 1: Complete the project",
"step-2": "Step 2: Submit your code",
"submit-public-url": "When you have completed the project, save all the required files into a public repository and submit the URL to it below.",
@@ -918,6 +940,12 @@
"generate-exam-error": "An error occurred trying to generate your exam.",
"cert-not-found": "The certification {{certSlug}} does not exist.",
"reset-editor-layout": "Your editor layout has been reset.",
"user-token-generated": "A user token was created for you.",
"user-token-generate-error": "Something went wrong trying to generate a user token for you.",
"user-token-copied": "User token copied to clipboard.",
"user-token-copy-error": "Something went wrong trying to copy your token.",
"course-url-copied": "Course URL copied to clipboard.",
"course-url-copy-error": "Something went wrong trying to copy the course URL.",
"ms": {
"transcript": {
"link-err-1": "Please include a Microsoft transcript URL in the request.",
@@ -11,6 +11,8 @@ export enum FlashMessages {
CodeSaveError = 'flash.code-save-error',
CodeSaveLess = 'flash.code-save-less',
CompleteProjectFirst = 'flash.complete-project-first',
CourseUrlCopied = 'flash.course-url-copied',
CourseUrlCopyError = 'flash.course-url-copy-error',
DeleteTokenErr = 'flash.delete-token-err',
EmailValid = 'flash.email-valid',
GenerateExamError = 'flash.generate-exam-error',
@@ -66,6 +68,10 @@ export enum FlashMessages {
UsernameUpdated = 'flash.username-updated',
UsernameUsed = 'flash.username-used',
UserNotCertified = 'flash.user-not-certified',
UserTokenCopied = 'flash.user-token-copied',
UserTokenCopyError = 'flash.user-token-copy-error',
UserTokenGenerated = 'flash.user-token-generated',
UserTokenGenerateError = 'flash.user-token-generate-error',
WrongName = 'flash.wrong-name',
WrongUpdating = 'flash.wrong-updating',
WentWrong = 'flash.went-wrong'
@@ -4,25 +4,34 @@ import React from 'react';
import { useFeature } from '@growthbook/growthbook-react';
import { useTranslation } from 'react-i18next';
import { Button } from '@freecodecamp/ui';
import { challengeTypes } from '../../../../shared/config/challenge-types';
interface CodeAllyButtonProps {
text: string;
challengeType: number;
onClick: () => void;
}
export function CodeAllyButton(props: CodeAllyButtonProps): JSX.Element | null {
export function CodeAllyButton({
challengeType,
onClick
}: CodeAllyButtonProps): JSX.Element | null {
const codeAllyDisabledFeature = useFeature('codeally_disabled');
const { t } = useTranslation();
const text =
challengeType === challengeTypes.codeAllyCert
? t('buttons.click-start-project')
: t('buttons.click-start-course');
return (
<Button
onClick={codeAllyDisabledFeature.on ? () => {} : props.onClick}
onClick={codeAllyDisabledFeature.on ? () => {} : onClick}
disabled={codeAllyDisabledFeature.on}
variant='primary'
block={true}
>
<span className='sr-only'>, {t('aria.opens-new-window')}</span>
{props.text}&nbsp;&nbsp;
{text}&nbsp;&nbsp;
<FontAwesomeIcon icon={faExternalLinkAlt} />
</Button>
);
@@ -0,0 +1,39 @@
import React from 'react';
import { Trans } from 'react-i18next';
import { Alert, Spacer } from '@freecodecamp/ui';
interface RdbGitpodContinueAlertProps {
course: string;
}
function RdbGitpodContinueAlert({
course
}: RdbGitpodContinueAlertProps): JSX.Element {
return (
<Alert variant='info'>
<Trans values={{ course }} i18nKey='learn.gitpod.continue-project'>
<a
href='https://gitpod.io/workspaces'
rel='noopener noreferrer'
target='_blank'
>
placeholder
</a>
</Trans>
<Spacer size='m' />
<Trans i18nKey='learn.gitpod.learn-more'>
<a
href='https://forum.freecodecamp.org/t/using-gitpod-in-the-curriculum/668669'
rel='noopener noreferrer'
target='_blank'
>
placeholder
</a>
</Trans>
</Alert>
);
}
RdbGitpodContinueAlert.displayName = 'RdbGitpodContinueAlert';
export default RdbGitpodContinueAlert;
@@ -0,0 +1,42 @@
import React from 'react';
import { Trans, useTranslation } from 'react-i18next';
function RdbGitpodInstructions(): JSX.Element {
const { t } = useTranslation();
return (
<div className='ca-description'>
<p>{t('learn.gitpod.intro')}</p>
<ol>
<li>
<Trans i18nKey='learn.gitpod.step-1'>
<a
href='https://github.com/join'
rel='noopener noreferrer'
target='_blank'
title={t('learn.source-code-link')}
>
placeholder
</a>
</Trans>
</li>
<li>{t('learn.gitpod.step-2')}</li>
<li>{t('learn.gitpod.step-3')}</li>
<li>
{t('learn.gitpod.step-4')}
<ul>
<li>{t('learn.gitpod.step-5')}</li>
<li>{t('learn.gitpod.step-6')}</li>
<li>{t('learn.gitpod.step-7')}</li>
<li>{t('learn.gitpod.step-8')}</li>
</ul>
</li>
<li>{t('learn.gitpod.step-9')}</li>
</ol>
</div>
);
}
RdbGitpodInstructions.displayName = 'RdbGitpodInstructions';
export default RdbGitpodInstructions;
@@ -0,0 +1,23 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Alert } from '@freecodecamp/ui';
interface RdbGitpodLogoutAlertProps {
course: string;
}
function RdbGitpodLogoutAlert({
course
}: RdbGitpodLogoutAlertProps): JSX.Element {
const { t } = useTranslation();
return (
<Alert variant='danger'>
{t('learn.gitpod.logout-warning', { course })}
</Alert>
);
}
RdbGitpodLogoutAlert.displayName = 'RdbGitpodLogoutAlert';
export default RdbGitpodLogoutAlert;
@@ -0,0 +1,212 @@
import React from 'react';
import { connect } from 'react-redux';
import { Trans, useTranslation } from 'react-i18next';
import { Spacer, Button } from '@freecodecamp/ui';
import { postUserToken } from '../../../utils/ajax';
import { createFlashMessage } from '../../../components/Flash/redux';
import { FlashMessages } from '../../../components/Flash/redux/flash-messages';
import {
isSignedInSelector,
userTokenSelector
} from '../../../redux/selectors';
import { updateUserToken } from '../../../redux/actions';
import { Link } from '../../../components/helpers';
import RdbLocalLogoutAlert from './rdb-local-logout-alert';
const mapStateToProps = (state: unknown) => ({
isSignedIn: isSignedInSelector(state),
userToken: userTokenSelector(state) as string | null
});
const mapDispatchToProps = {
createFlashMessage,
updateUserToken
};
interface RdbLocalInstructionsProps {
course: string;
createFlashMessage: typeof createFlashMessage;
isSignedIn: boolean;
updateUserToken: (arg0: string) => void;
url: string;
userToken: string | null;
}
function RdbLocalInstructions({
course,
createFlashMessage,
isSignedIn,
updateUserToken,
url,
userToken
}: RdbLocalInstructionsProps): JSX.Element {
const { t } = useTranslation();
const coderoadTutorial = `https://raw.githubusercontent.com/${url}/main/tutorial.json`;
const generateUserToken = async () => {
const createUserTokenResponse = await postUserToken();
const { data = { userToken: null } } = createUserTokenResponse;
if (data?.userToken) {
updateUserToken(data.userToken);
createFlashMessage({
type: 'success',
message: FlashMessages.UserTokenGenerated
});
} else {
createFlashMessage({
type: 'danger',
message: FlashMessages.UserTokenGenerateError
});
}
};
const copyUserToken = () => {
navigator.clipboard.writeText(userToken ?? '').then(
() => {
createFlashMessage({
type: 'success',
message: FlashMessages.UserTokenCopied
});
},
() => {
createFlashMessage({
type: 'danger',
message: FlashMessages.UserTokenCopyError
});
}
);
};
const copyUrl = () => {
navigator.clipboard.writeText(coderoadTutorial ?? '').then(
() => {
createFlashMessage({
type: 'success',
message: FlashMessages.CourseUrlCopied
});
},
() => {
createFlashMessage({
type: 'danger',
message: FlashMessages.CourseUrlCopyError
});
}
);
};
return (
<div className='ca-description'>
<p>{t('learn.local.intro')}</p>
<ul>
<li>
<Link external={true} to='https://docs.docker.com/engine/'>
Docker Engine
</Link>
</li>
<li>
<Trans i18nKey='learn.local.download-vscode'>
<Link external={true} to='https://code.visualstudio.com/download'>
placeholder
</Link>
<Link
external={true}
to='https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers'
>
placeholder
</Link>
</Trans>
</li>
<li>
<Link external={true} to='https://git-scm.com/downloads'>
Git
</Link>
</li>
</ul>
<Spacer size='m' />
<p>{t('learn.local.heading')}</p>
<ol>
<li>
<Trans i18nKey='learn.local.step-1'>
<code>placeholder</code>
</Trans>
</li>
<li>
<Trans i18nKey='learn.local.step-2'>
<code>placeholder</code>
<code>placeholder</code>
<code>placeholder</code>
</Trans>
</li>
{isSignedIn && (
<>
<Spacer size='s' />
<p>{t('learn.local.sub-step-heading')}</p>
<ol>
<li>{t('learn.local.sub-step-1')}</li>
<Spacer size='xxs' />
<Button
disabled={!!userToken}
block={true}
onClick={() => void generateUserToken()}
>
{t('learn.local.generate-token-btn')}
</Button>
<Spacer size='xs' />
<li>{t('learn.local.sub-step-2')}</li>
<Spacer size='xxs' />
<Button
disabled={!userToken}
block={true}
onClick={copyUserToken}
>
{t('learn.local.copy-token-btn')}
</Button>
<Spacer size='xs' />
<li>
<Trans i18nKey='learn.local.sub-step-3'>
<code>placeholder</code>
<code>placeholder</code>
<code>placeholder</code>
</Trans>
</li>
<Spacer size='xs' />
<RdbLocalLogoutAlert course={course} />
</ol>
<Spacer size='s' />
</>
)}
<li>
<Trans i18nKey='learn.local.step-3'>
<code>placeholder</code>
</Trans>
</li>
<li>{t('learn.local.step-4')}</li>
<li>
<Trans i18nKey='learn.local.step-5'>
<code>placeholder</code>
</Trans>
</li>
<li>{t('learn.local.step-6')}</li>
<li>{t('learn.local.step-7')}</li>
<Spacer size='xxs' />
<Button block={true} onClick={copyUrl}>
{t('learn.local.copy-url')}
</Button>
<Spacer size='xs' />
<li>{t('learn.local.step-8')}</li>
<li>{t('learn.local.step-9')}</li>
</ol>
</div>
);
}
RdbLocalInstructions.displayName = 'RdbLocalInstructions';
export default connect(
mapStateToProps,
mapDispatchToProps
)(RdbLocalInstructions);
@@ -0,0 +1,23 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Alert } from '@freecodecamp/ui';
interface RdbLocalLogoutAlertProps {
course: string;
}
function RdbLocalLogoutAlert({
course
}: RdbLocalLogoutAlertProps): JSX.Element {
const { t } = useTranslation();
return (
<Alert variant='danger'>
{t('learn.local.logout-warning', { course })}
</Alert>
);
}
RdbLocalLogoutAlert.displayName = 'RdbLocalLogoutAlert';
export default RdbLocalLogoutAlert;
@@ -0,0 +1,32 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Spacer } from '@freecodecamp/ui';
import ChallengeHeading from '../components/challenge-heading';
import PrismFormatted from '../components/prism-formatted';
interface RdbStep1InstructionsProps {
instructions: string;
isCompleted: boolean;
}
function RdbStep1Instructions({
instructions,
isCompleted
}: RdbStep1InstructionsProps): JSX.Element {
const { t } = useTranslation();
return (
<>
<ChallengeHeading heading={t('learn.step-1')} isCompleted={isCompleted} />
<Spacer size='m' />
<div className='ca-description'>{t('learn.runs-in-vm')}</div>
<Spacer size='m' />
<PrismFormatted text={instructions} />
</>
);
}
RdbStep1Instructions.displayName = 'RdbStep1Instructions';
export default RdbStep1Instructions;
@@ -0,0 +1,33 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Spacer } from '@freecodecamp/ui';
import ChallengeHeading from '../components/challenge-heading';
import PrismFormatted from '../components/prism-formatted';
interface RdbStep2InstructionsProps {
notes: string;
isCompleted: boolean;
}
function RdbStep2Instructions({
isCompleted,
notes
}: RdbStep2InstructionsProps): JSX.Element {
const { t } = useTranslation();
return (
<>
<ChallengeHeading heading={t('learn.step-2')} isCompleted={isCompleted} />
<Spacer size='m' />
<div className='ca-description'>{t('learn.submit-public-url')}</div>
<Spacer size='m' />
<PrismFormatted text={notes} />
</>
);
}
RdbStep2Instructions.displayName = 'RdbStep2Instructions';
export default RdbStep2Instructions;
+95 -114
View File
@@ -3,17 +3,17 @@ import { graphql } from 'gatsby';
import React, { useEffect, useRef } from 'react';
import Helmet from 'react-helmet';
import type { TFunction } from 'i18next';
import { Trans, withTranslation } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import type { Dispatch } from 'redux';
import { createSelector } from 'reselect';
import { Container, Col, Row, Alert, Spacer } from '@freecodecamp/ui';
import { Container, Col, Row, Spacer } from '@freecodecamp/ui';
import { useFeature } from '@growthbook/growthbook-react';
// Local Utilities
import LearnLayout from '../../../components/layouts/learn';
import ChallengeTitle from '../components/challenge-title';
import ChallengeHeading from '../components/challenge-heading';
import PrismFormatted from '../components/prism-formatted';
import { challengeTypes } from '../../../../../shared/config/challenge-types';
import CompletionModal from '../components/completion-modal';
@@ -48,9 +48,16 @@ import { FlashMessages } from '../../../components/Flash/redux/flash-messages';
import { SuperBlocks } from '../../../../../shared/config/curriculum';
import { CodeAllyDown } from '../../../components/growth-book/codeally-down';
import { postUserToken } from '../../../utils/ajax';
import { CodeAllyButton } from '../../../components/growth-book/codeally-button';
import RdbGitpodContinueAlert from './rdb-gitpod-continue-alert';
import RdbGitpodInstructions from './rdb-gitpod-instructions';
import RdbGitpodLogoutAlert from './rdb-gitpod-logout-alert';
import RdbLocalInstructions from './rdb-local-instructions';
import RdbStep1Instructions from './rdb-step-1-instructions';
import RdbStep2Instructions from './rdb-step-2-instructions';
import './codeally.css';
import { CodeAllyButton } from '../../../components/growth-book/codeally-button';
// Redux
const mapStateToProps = createSelector(
@@ -125,7 +132,8 @@ function ShowCodeAlly(props: ShowCodeAllyProps) {
notes,
superBlock,
title,
translationPending
translationPending,
url
}
}
},
@@ -261,6 +269,8 @@ function ShowCodeAlly(props: ShowCodeAllyProps) {
}
};
const gitpodDeprecated = useFeature('gitpod-deprecated').on;
return (
<Hotkeys containerRef={container}>
<LearnLayout>
@@ -280,121 +290,92 @@ function ShowCodeAlly(props: ShowCodeAllyProps) {
<Spacer size='m' />
<PrismFormatted text={description} />
<Spacer size='m' />
<div className='ca-description'>
<p>{t('learn.gitpod.intro')}</p>
<ol>
<li>
<Trans i18nKey='learn.gitpod.step-1'>
<a
href='https://github.com/join'
rel='noopener noreferrer'
target='_blank'
title={t('learn.source-code-link')}
>
placeholder
</a>
</Trans>
</li>
<li>{t('learn.gitpod.step-2')}</li>
<li>{t('learn.gitpod.step-3')}</li>
<li>
{t('learn.gitpod.step-4')}
<ul>
<li>{t('learn.gitpod.step-5')}</li>
<li>{t('learn.gitpod.step-6')}</li>
<li>{t('learn.gitpod.step-7')}</li>
<li>{t('learn.gitpod.step-8')}</li>
</ul>
</li>
<li>{t('learn.gitpod.step-9')}</li>
</ol>
</div>
<Spacer size='m' />
{isSignedIn && challengeType === challengeTypes.codeAllyCert && (
{gitpodDeprecated ? (
<>
<div className='ca-description'>
{t('learn.complete-both-steps')}
</div>
<hr />
<RdbLocalInstructions course={title} url={url} />
<Spacer size='m' />
<ChallengeHeading
heading={t('learn.step-1')}
isCompleted={isPartiallyCompleted || isCompleted}
/>
<Spacer size='m' />
<div className='ca-description'>{t('learn.runs-in-vm')}</div>
<Spacer size='m' />
<PrismFormatted text={instructions} />
{isSignedIn &&
challengeType === challengeTypes.codeAllyCert && (
<>
<div className='ca-description'>
{t('learn.complete-both-steps')}
</div>
<hr />
<Spacer size='m' />
<RdbStep1Instructions
instructions={instructions}
isCompleted={isPartiallyCompleted || isCompleted}
/>
<hr />
<Spacer size='m' />
<RdbStep2Instructions
isCompleted={isCompleted}
notes={notes}
/>
<Spacer size='m' />
<SolutionForm
challengeType={challengeType}
description={description}
onSubmit={handleSubmit}
updateSolutionForm={updateSolutionFormValues}
/>
</>
)}
</>
) : (
<>
<RdbGitpodInstructions />
<Spacer size='m' />
{isSignedIn &&
challengeType === challengeTypes.codeAllyCert ? (
<>
<div className='ca-description'>
{t('learn.complete-both-steps')}
</div>
<hr />
<Spacer size='m' />
<RdbStep1Instructions
instructions={instructions}
isCompleted={isPartiallyCompleted || isCompleted}
/>
<Spacer size='m' />
<RdbGitpodContinueAlert course={title} />
{isSignedIn && <RdbGitpodLogoutAlert course={title} />}
<CodeAllyButton
challengeType={challengeType}
//eslint-disable-next-line @typescript-eslint/no-misused-promises
onClick={startCourse}
/>
<hr />
<Spacer size='m' />
<RdbStep2Instructions
isCompleted={isCompleted}
notes={notes}
/>
<Spacer size='m' />
<SolutionForm
challengeType={challengeType}
description={description}
onSubmit={handleSubmit}
updateSolutionForm={updateSolutionFormValues}
/>
</>
) : (
<>
<RdbGitpodContinueAlert course={title} />
{isSignedIn && <RdbGitpodLogoutAlert course={title} />}
<CodeAllyButton
challengeType={challengeType}
//eslint-disable-next-line @typescript-eslint/no-misused-promises
onClick={startCourse}
/>
</>
)}
<Spacer size='xxs' />
</>
)}
<Alert variant='info'>
<Trans
values={{ course: title }}
i18nKey='learn.gitpod.continue-project'
>
<a
href='https://gitpod.io/workspaces'
rel='noopener noreferrer'
target='_blank'
>
placeholder
</a>
</Trans>
<Spacer size='m' />
<Trans i18nKey='learn.gitpod.learn-more'>
<a
href='https://forum.freecodecamp.org/t/using-gitpod-in-the-curriculum/668669'
rel='noopener noreferrer'
target='_blank'
>
placeholder
</a>
</Trans>
</Alert>
{isSignedIn && (
<Alert variant='danger'>
{t('learn.gitpod.logout-warning', { course: title })}
</Alert>
)}
<CodeAllyButton
text={
challengeType === challengeTypes.codeAllyCert
? t('buttons.click-start-project')
: t('buttons.click-start-course')
}
// `this.startCourse` being an async callback is acceptable
//eslint-disable-next-line @typescript-eslint/no-misused-promises
onClick={startCourse}
/>
{isSignedIn && challengeType === challengeTypes.codeAllyCert && (
<>
<hr />
<Spacer size='m' />
<ChallengeHeading
heading={t('learn.step-2')}
isCompleted={isCompleted}
/>
<Spacer size='m' />
<div className='ca-description'>
{t('learn.submit-public-url')}
</div>
<Spacer size='m' />
<PrismFormatted text={notes} />
<Spacer size='m' />
<SolutionForm
challengeType={challengeType}
description={description}
onSubmit={handleSubmit}
updateSolutionForm={updateSolutionFormValues}
/>
</>
)}
<Spacer size='xxs' />
<ProjectToolPanel />
<br />
<Spacer size='m' />
+6
View File
@@ -25,6 +25,8 @@ const toneUrls = {
[FlashMessages.CodeSaveError]: TRY_AGAIN,
[FlashMessages.CodeSaveLess]: TRY_AGAIN,
[FlashMessages.CompleteProjectFirst]: TRY_AGAIN,
[FlashMessages.CourseUrlCopied]: CHAL_COMP,
[FlashMessages.CourseUrlCopyError]: TRY_AGAIN,
[FlashMessages.DeleteTokenErr]: TRY_AGAIN,
[FlashMessages.EmailValid]: CHAL_COMP,
[FlashMessages.GenerateExamError]: TRY_AGAIN,
@@ -80,6 +82,10 @@ const toneUrls = {
[FlashMessages.UsernameUpdated]: CHAL_COMP,
[FlashMessages.UsernameUsed]: TRY_AGAIN,
[FlashMessages.UserNotCertified]: TRY_AGAIN,
[FlashMessages.UserTokenCopied]: CHAL_COMP,
[FlashMessages.UserTokenCopyError]: TRY_AGAIN,
[FlashMessages.UserTokenGenerated]: CHAL_COMP,
[FlashMessages.UserTokenGenerateError]: TRY_AGAIN,
[FlashMessages.WrongName]: TRY_AGAIN,
[FlashMessages.WrongUpdating]: TRY_AGAIN,
[FlashMessages.WentWrong]: TRY_AGAIN