join-group.tsx 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. import { Dispatch, SetStateAction, useCallback } from 'react'
  2. import { useTranslation } from 'react-i18next'
  3. import { InviteViewTypes } from './group-invite'
  4. import getMeta from '@/utils/meta'
  5. import { FetchError, putJSON } from '@/infrastructure/fetch-json'
  6. import useAsync from '@/shared/hooks/use-async'
  7. import classNames from 'classnames'
  8. import { debugConsole } from '@/utils/debugging'
  9. import Notification from '@/shared/components/notification'
  10. export default function JoinGroup({
  11. setView,
  12. }: {
  13. setView: Dispatch<SetStateAction<InviteViewTypes>>
  14. }) {
  15. const { t } = useTranslation()
  16. const expired = getMeta('ol-expired') as boolean
  17. const inviteToken = getMeta('ol-inviteToken') as string
  18. const {
  19. runAsync,
  20. isLoading: isJoining,
  21. isError,
  22. } = useAsync<never, FetchError>()
  23. const notNowBtnClasses = classNames(
  24. 'btn',
  25. 'btn-secondary',
  26. isJoining ? 'disabled' : ''
  27. )
  28. const joinTeam = useCallback(() => {
  29. runAsync(putJSON(`/subscription/invites/${inviteToken}`))
  30. .then(() => {
  31. setView('invite-accepted')
  32. })
  33. .catch(debugConsole.error)
  34. }, [inviteToken, runAsync, setView])
  35. if (!inviteToken) {
  36. return null
  37. }
  38. return (
  39. <>
  40. {isError && (
  41. <Notification
  42. type="error"
  43. content={t('generic_something_went_wrong')}
  44. className="my-3"
  45. />
  46. )}
  47. <div className="text-center">
  48. <p>{t('join_team_explanation')}</p>
  49. {!expired && (
  50. <p>
  51. <a className={notNowBtnClasses} href="/project">
  52. {t('not_now')}
  53. </a>
  54. &nbsp;&nbsp;
  55. <button
  56. className="btn btn-primary"
  57. onClick={() => joinTeam()}
  58. disabled={isJoining}
  59. >
  60. {t('accept_invitation')}
  61. </button>
  62. </p>
  63. )}
  64. </div>
  65. </>
  66. )
  67. }