{"version":3,"file":"RecoveryCodeSaveScreen.mjs","sources":["../../../../../../../../../web/src/ui/b2b/screens/RecoveryCodeSaveScreen.tsx"],"sourcesContent":["import { useLingui } from '@lingui/react/macro';\nimport React, { CSSProperties, useMemo } from 'react';\n\nimport Button, { ButtonAnchor } from '../../components/atoms/Button';\nimport CodeContainer from '../../components/atoms/CodeContainer';\nimport Column from '../../components/atoms/Column';\nimport { errorToast } from '../../components/atoms/Toast';\nimport Typography from '../../components/atoms/Typography';\nimport VerticalTransition, { useTimedBoolean } from '../../components/atoms/VerticalTransition';\nimport ButtonColumn from '../../components/molecules/ButtonColumn';\nimport TextColumn from '../../components/molecules/TextColumn';\nimport { useGlobalReducer } from '../GlobalContextProvider';\nimport styles from './RecoveryCodeSaveScreen.module.css';\n\nexport const RecoveryCodeSaveScreen = () => {\n  const [state, dispatch] = useGlobalReducer();\n  const { t } = useLingui();\n\n  // This screen should only be shown if TOTP enrollment is available\n  const { recoveryCodes } = state.mfa.totp.enrollment!;\n\n  const handleContinue = () => {\n    dispatch({ type: 'recovery_code/save_acknowledge' });\n  };\n\n  const fileContent = useMemo(() => {\n    const newline = navigator.platform === 'Win32' ? '\\r\\n' : '\\n';\n    const blob = new Blob([recoveryCodes.join(newline)], { type: 'text/plain' });\n    return URL.createObjectURL(blob);\n  }, [recoveryCodes]);\n\n  const organizationName = state.flowState.organization?.organization_name;\n  const filename = organizationName\n    ? t({ id: 'recoveryCodes.filename.withOrganizationName', message: `${organizationName}-backup-codes` })\n    : t({\n        id: 'recoveryCodes.filename.noOrganizationName',\n        message: 'backup-codes',\n      });\n\n  const [copied, setCopied] = useTimedBoolean(3);\n  const handleCodesCopy = async () => {\n    try {\n      await navigator.clipboard.writeText(recoveryCodes.join('\\n'));\n      setCopied(true);\n    } catch {\n      errorToast({\n        message: t({ id: 'recoveryCodes.save.toast.copyFailed', message: \"Couldn't copy codes to clipboard\" }),\n      });\n    }\n  };\n\n  const maxCodeLength = Math.max(...recoveryCodes.map((code) => code.length));\n\n  return (\n    <Column gap={6}>\n      <TextColumn\n        header={t({ id: 'recoveryCodes.save.title', message: 'Save your backup codes!' })}\n        body={t({\n          id: 'recoveryCodes.save.content',\n          message: 'This is the only time you will be able to access and save your backup codes.',\n        })}\n      />\n\n      <CodeContainer>\n        <Typography font=\"mono\">\n          <ul className={styles.codes} style={{ '--st-max-code-length': maxCodeLength + 'ch' } as CSSProperties}>\n            {recoveryCodes.map((code, i) => (\n              <li key={i}>{code}</li>\n            ))}\n          </ul>\n        </Typography>\n      </CodeContainer>\n\n      <ButtonColumn>\n        {/* eslint-disable-next-line lingui/no-unlocalized-strings */}\n        <ButtonAnchor variant=\"primary\" href={fileContent} download={filename + '.txt'}>\n          <VerticalTransition\n            primary={t({ id: 'recoveryCodes.save.button.download', message: 'Download .txt file' })}\n            secondary={t({ id: 'recoveryCodes.save.button.copied', message: 'Copied!' })}\n            triggered={copied}\n          />\n        </ButtonAnchor>\n        <Button variant=\"outline\" onClick={handleCodesCopy}>\n          {t({ id: 'recoveryCodes.save.button.copyAll', message: 'Copy all to clipboard' })}\n        </Button>\n        <Button variant=\"ghost\" onClick={handleContinue}>\n          {t({ id: 'recoveryCodes.save.button.done', message: 'Done' })}\n        </Button>\n      </ButtonColumn>\n    </Column>\n  );\n};\n"],"names":["RecoveryCodeSaveScreen","state","dispatch","useGlobalReducer","useLingui","recoveryCodes","mfa","totp","enrollment","handleContinue","type","fileContent","useMemo","newline","navigator","platform","blob","Blob","join","URL","createObjectURL","organizationName","flowState","organization","organization_name","filename","copied","setCopied","useTimedBoolean","handleCodesCopy","clipboard","writeText","errorToast","message","maxCodeLength","Math","max","map","code","length","React","Column","gap","TextColumn","header","body","CodeContainer","Typography","font","ul","className","styles","codes","style","i","li","key","ButtonColumn","ButtonAnchor","variant","href","download","VerticalTransition","primary","secondary","triggered","Button","onClick"],"mappings":"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"}