demoEndModal.tsx 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. import React, {useCallback} from 'react';
  2. import {css} from '@emotion/react';
  3. import styled from '@emotion/styled';
  4. import {fetchGuides} from 'sentry/actionCreators/guides';
  5. import {ModalRenderProps} from 'sentry/actionCreators/modal';
  6. import Button from 'sentry/components/button';
  7. import ModalTask from 'sentry/components/onboardingWizard/modalTask';
  8. import {SidebarPanelKey} from 'sentry/components/sidebar/types';
  9. import {IconClose} from 'sentry/icons/iconClose';
  10. import {t} from 'sentry/locale';
  11. import SidebarPanelStore from 'sentry/stores/sidebarPanelStore';
  12. import {Organization} from 'sentry/types';
  13. import useApi from 'sentry/utils/useApi';
  14. import {useNavigate} from 'sentry/utils/useNavigate';
  15. // tour is a string that tells which tour the user is completing in the walkthrough
  16. type Props = ModalRenderProps & {orgSlug: Organization['slug'] | null; tour: string};
  17. export default function DemoEndingModal({tour, closeModal, CloseButton, orgSlug}: Props) {
  18. const api = useApi();
  19. const navigate = useNavigate();
  20. let cardTitle = '',
  21. body = '',
  22. guides = [''],
  23. path = '';
  24. switch (tour) {
  25. case 'issues':
  26. cardTitle = t('Issues Tour');
  27. body = t(
  28. 'Thank you for completing the Issues tour. Learn about other Sentry features by starting another tour.'
  29. );
  30. guides = ['issues_v3', 'issue_stream_v3'];
  31. path = `/organizations/${orgSlug}/issues/`;
  32. break;
  33. case 'performance':
  34. cardTitle = t('Performance Tour');
  35. body = t(
  36. 'Thank you for completing the Performance tour. Learn about other Sentry features by starting another tour.'
  37. );
  38. guides = ['performance', 'transaction_summary', 'transaction_details_v2'];
  39. path = `/organizations/${orgSlug}/performance/`;
  40. break;
  41. case 'releases':
  42. cardTitle = t('Releases Tour');
  43. body = t(
  44. 'Thank you for completing the Releases tour. Learn about other Sentry features by starting another tour.'
  45. );
  46. guides = ['releases_v2', 'react-native-release', 'release-details_v2'];
  47. path = `/organizations/${orgSlug}/releases/`;
  48. break;
  49. case 'tabs':
  50. cardTitle = t('Check out the different tabs');
  51. body = t(
  52. 'Thank you for checking out the different tabs. Learn about other Sentry features by starting another tour.'
  53. );
  54. guides = ['sidebar_v2'];
  55. path = `/organizations/${orgSlug}/projects/`;
  56. break;
  57. default:
  58. }
  59. const sandboxData = window.SandboxData;
  60. const url = sandboxData?.cta?.url || 'https://sentry.io/signup/';
  61. const navigation = useCallback(() => {
  62. navigate(path);
  63. }, [path, navigate]);
  64. async function handleRestart() {
  65. await Promise.all(
  66. guides.map(guide =>
  67. api.requestPromise('/assistant/', {
  68. method: 'PUT',
  69. data: {guide, status: 'restart'},
  70. })
  71. )
  72. );
  73. closeModal?.();
  74. fetchGuides();
  75. navigation();
  76. }
  77. const handleMoreTours = () => {
  78. closeModal?.();
  79. SidebarPanelStore.togglePanel(SidebarPanelKey.OnboardingWizard);
  80. };
  81. return (
  82. <EndModal>
  83. <CloseButton
  84. size="zero"
  85. onClick={() => {
  86. if (closeModal) {
  87. closeModal();
  88. }
  89. }}
  90. icon={<IconClose size="xs" />}
  91. />
  92. <ModalHeader>
  93. <h2> {t('Tour Complete')} </h2>
  94. </ModalHeader>
  95. <ModalTask title={cardTitle} />
  96. <ModalHeader>{body}</ModalHeader>
  97. <ButtonContainer>
  98. <SignUpButton external href={url}>
  99. {sandboxData?.cta?.title || t('Sign up for Sentry')}
  100. </SignUpButton>
  101. <ButtonBar>
  102. <Button onClick={handleMoreTours}>{t('More Tours')} </Button>
  103. <Button onClick={handleRestart}>{t('Restart Tour')}</Button>
  104. </ButtonBar>
  105. </ButtonContainer>
  106. </EndModal>
  107. );
  108. }
  109. export const modalCss = css`
  110. width: 100%;
  111. max-width: 500px;
  112. [role='document'] {
  113. position: relative;
  114. padding: 50px 60px;
  115. }
  116. `;
  117. const EndModal = styled('div')`
  118. display: flex;
  119. flex-direction: column;
  120. gap: 20px;
  121. align-items: center;
  122. `;
  123. const ModalHeader = styled('div')`
  124. p {
  125. font-size: 16px;
  126. text-align: center;
  127. margin: 0;
  128. }
  129. h2 {
  130. font-size: 2em;
  131. margin: 0;
  132. }
  133. `;
  134. const SignUpButton = styled(Button)`
  135. background-color: ${p => p.theme.purple300};
  136. border: none;
  137. color: ${p => p.theme.white};
  138. width: 100%;
  139. `;
  140. const ButtonBar = styled('div')`
  141. display: flex;
  142. flex-direction: row;
  143. gap: 5px;
  144. justify-content: center;
  145. `;
  146. const ButtonContainer = styled('div')`
  147. display: flex;
  148. flex-direction: column;
  149. gap: 10px;
  150. `;