promo.tsx 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. import styled from '@emotion/styled';
  2. import onboardingServerSideSampling from 'sentry-images/spot/onboarding-server-side-sampling.svg';
  3. import Button from 'sentry/components/button';
  4. import ButtonBar from 'sentry/components/buttonBar';
  5. import EmptyStateWarning from 'sentry/components/emptyStateWarning';
  6. import {t} from 'sentry/locale';
  7. import space from 'sentry/styles/space';
  8. import {SERVER_SIDE_SAMPLING_DOC_LINK} from './utils';
  9. type Props = {
  10. hasAccess: boolean;
  11. onGetStarted: () => void;
  12. onReadDocs: () => void;
  13. };
  14. export function Promo({onGetStarted, onReadDocs, hasAccess}: Props) {
  15. return (
  16. <StyledEmptyStateWarning withIcon={false}>
  17. <img src={onboardingServerSideSampling} />
  18. <Description>
  19. <h3>{t('Set sample rules for your project')}</h3>
  20. <p>
  21. {t(
  22. 'Because every project is different – some need more events from high converting pages, critical API endpoints, or just want to focus on latency issues from the latest release – set multiple sample rules with different sample rates per project so you can keep what you need and drop what you don’t.'
  23. )}
  24. </p>
  25. <Actions gap={1}>
  26. <Button href={SERVER_SIDE_SAMPLING_DOC_LINK} onClick={onReadDocs} external>
  27. {t('Read Docs')}
  28. </Button>
  29. <Button
  30. priority="primary"
  31. onClick={onGetStarted}
  32. disabled={!hasAccess}
  33. title={
  34. hasAccess ? undefined : t('You do not have permission to set up rules')
  35. }
  36. >
  37. {t('Start Setup')}
  38. </Button>
  39. </Actions>
  40. </Description>
  41. </StyledEmptyStateWarning>
  42. );
  43. }
  44. const StyledEmptyStateWarning = styled(EmptyStateWarning)`
  45. align-items: center;
  46. justify-content: center;
  47. flex-direction: column;
  48. gap: ${space(4)};
  49. grid-column: 1/-1;
  50. text-align: center;
  51. img {
  52. width: 320px;
  53. }
  54. && {
  55. display: flex;
  56. padding: ${space(4)};
  57. }
  58. @media (min-width: ${p => p.theme.breakpoints.large}) {
  59. text-align: left;
  60. flex-direction: row;
  61. img {
  62. width: 100%;
  63. max-width: 40%;
  64. min-width: 320px;
  65. }
  66. }
  67. `;
  68. const Actions = styled(ButtonBar)`
  69. justify-content: center;
  70. @media (min-width: ${p => p.theme.breakpoints.large}) {
  71. justify-content: flex-start;
  72. }
  73. `;
  74. const Description = styled('div')`
  75. justify-content: space-between;
  76. @media (min-width: ${p => p.theme.breakpoints.large}) {
  77. padding: ${space(4)};
  78. justify-content: flex-start;
  79. }
  80. p {
  81. font-size: ${p => p.theme.fontSizeLarge};
  82. }
  83. `;