{"version":3,"file":"PasskeyRegistrationSuccess.mjs","sources":["../../../../../../../../../../web/src/ui/b2c/screens/Passkey/PasskeyRegistrationSuccess.tsx"],"sourcesContent":["import { useLingui } from '@lingui/react/macro';\nimport { logger } from '@stytch/core';\nimport { errorToStytchError, StytchEventType, WebAuthnRegistration } from '@stytch/core/public';\nimport React, { useState } from 'react';\n\nimport Button from '../../../components/atoms/Button';\nimport Column from '../../../components/atoms/Column';\nimport { errorToast } from '../../../components/atoms/Toast';\nimport Typography from '../../../components/atoms/Typography';\nimport ButtonColumn from '../../../components/molecules/ButtonColumn';\nimport ErrorText from '../../../components/molecules/ErrorText';\nimport { useStytchUser } from '../../../hooks/useStytchUser';\nimport { AppScreens, useEventCallback, useGlobalReducer, useStytch } from '../../GlobalContextProvider';\nimport { EditableRow, EditableRowState } from './EditableRow';\nimport styles from './PasskeyRegistrationSuccess.module.css';\n\n// TODO: Add some type of device icon once we have better insight into that.\n// const deviceTypeToIcon: Partial<Record<Device, React.JSX.Element>> = {\n//   [Device.DESKTOP]: <Computer />,\n//   [Device.MOBILE]: <Mobile />,\n// };\n\ntype OptimisticUpdate = {\n  registrations: WebAuthnRegistration[];\n  update: Promise<unknown>;\n};\n\nexport const PasskeyRegistrationSuccess = () => {\n  const { t } = useLingui();\n  const stytchClient = useStytch();\n  const user = useStytchUser();\n\n  const [optimisticRegistrations, setOptimisticRegistrations] = useState<OptimisticUpdate>();\n  const webAuthnRegistrations = optimisticRegistrations?.registrations ?? user?.webauthn_registrations;\n\n  const [editableRowState, setEditableRowState] = useState<EditableRowState>({ type: 'viewing' });\n\n  const onEvent = useEventCallback();\n  const [, dispatch] = useGlobalReducer();\n\n  const onSetUpANewPasskey = async () => {\n    await optimisticRegistrations?.update;\n    dispatch({ type: 'transition', screen: AppScreens.PasskeyRegistrationStart });\n  };\n\n  const onDone = async () => {\n    await optimisticRegistrations?.update;\n    onEvent({ type: StytchEventType.PasskeyDone, data: {} });\n  };\n\n  const startOptimisticUpdate = (registrations: WebAuthnRegistration[], update: Promise<unknown>) => {\n    const prevEditableRowState = { ...editableRowState };\n\n    setOptimisticRegistrations({ registrations, update });\n    setEditableRowState({ type: 'viewing' });\n\n    update\n      .catch((error) => {\n        logger.error(error);\n        errorToast({ message: errorToStytchError(error).message });\n        setEditableRowState(prevEditableRowState);\n      })\n      .then(() => {\n        setOptimisticRegistrations(undefined);\n      });\n  };\n\n  const deleteReg = (id: string) => {\n    if (!user) return;\n\n    startOptimisticUpdate(\n      user.webauthn_registrations.filter((r) => r.webauthn_registration_id !== id),\n      stytchClient.user.deleteWebauthnRegistration(id),\n    );\n  };\n\n  const updateReg = (id: string, name: string) => {\n    if (!user) return;\n\n    startOptimisticUpdate(\n      user.webauthn_registrations.map((r) => (r.webauthn_registration_id === id ? { ...r, name } : r)),\n      stytchClient.webauthn.update({ webauthn_registration_id: id, name }).then(() => stytchClient.user.get()),\n    );\n  };\n\n  return (\n    <Column gap={6}>\n      <Typography variant=\"header\">\n        {t({\n          id: 'passkey.registrationSuccess.title',\n          message: 'Passkey successfully created!',\n        })}\n      </Typography>\n\n      {webAuthnRegistrations && webAuthnRegistrations.length > 0 && (\n        <Column gap={4}>\n          <Typography weight=\"medium\">\n            {t({\n              id: 'passkey.registrationSuccess.existingPasskeys',\n              message: 'Existing Passkeys',\n            })}\n          </Typography>\n\n          <Column className={styles.existing}>\n            {webAuthnRegistrations.map((registration: WebAuthnRegistration) => (\n              // TODO: Add some type of device icon once we have better insight into that.\n              // deviceTypeToIcon[determineDeviceType(registration.user_agent)]\n              <EditableRow\n                className={styles.passkeyRow}\n                key={registration.webauthn_registration_id}\n                id={registration.webauthn_registration_id}\n                name={registration.name}\n                state={editableRowState}\n                updateState={setEditableRowState}\n                handleEdit={updateReg}\n              />\n            ))}\n          </Column>\n        </Column>\n      )}\n\n      <ButtonColumn>\n        {editableRowState.type === 'deleting' ? (\n          <>\n            <Button\n              variant=\"destructive\"\n              onClick={() => {\n                deleteReg(editableRowState.id);\n              }}\n            >\n              {t({\n                id: 'button.delete',\n                message: 'Delete',\n              })}\n            </Button>\n\n            <ErrorText\n              // alert role to ensure this gets read out when the row delete button is clicked\n              role=\"alert\"\n            >\n              {t({\n                id: 'passkey.registrationSuccess.deleteWarning',\n                message: 'Once deleted, the passkey cannot be restored.',\n              })}\n            </ErrorText>\n\n            <Button\n              variant=\"ghost\"\n              onClick={() => {\n                setEditableRowState({ type: 'viewing' });\n              }}\n            >\n              {t({\n                id: 'button.cancel',\n                message: 'Cancel',\n              })}\n            </Button>\n          </>\n        ) : (\n          <>\n            <Button variant=\"primary\" disabled={editableRowState.type === 'editing'} onClick={onSetUpANewPasskey}>\n              {t({\n                id: 'passkey.registrationSuccess.setupAnother',\n                message: 'Set up another Passkey',\n              })}\n            </Button>\n\n            <Button variant=\"ghost\" disabled={editableRowState.type === 'editing'} onClick={onDone}>\n              {t({\n                id: 'button.done',\n                message: 'Done',\n              })}\n            </Button>\n          </>\n        )}\n      </ButtonColumn>\n    </Column>\n  );\n};\n"],"names":["PasskeyRegistrationSuccess","useLingui","stytchClient","useStytch","user","useStytchUser","optimisticRegistrations","setOptimisticRegistrations","useState","webAuthnRegistrations","registrations","webauthn_registrations","editableRowState","setEditableRowState","type","onEvent","useEventCallback","dispatch","useGlobalReducer","onSetUpANewPasskey","update","screen","AppScreens","PasskeyRegistrationStart","onDone","StytchEventType","PasskeyDone","data","startOptimisticUpdate","prevEditableRowState","catch","error","logger","errorToast","message","errorToStytchError","then","undefined","deleteReg","id","filter","r","webauthn_registration_id","deleteWebauthnRegistration","updateReg","name","map","webauthn","get","React","Column","gap","Typography","variant","length","weight","className","styles","existing","registration","EditableRow","passkeyRow","key","state","updateState","handleEdit","ButtonColumn","Button","onClick","ErrorText","role","disabled"],"mappings":"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"}