TutorialCard.tsx 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import { css } from '@emotion/css';
  2. import React, { FC, MouseEvent } from 'react';
  3. import { GrafanaTheme } from '@grafana/data';
  4. import { Icon, stylesFactory, useTheme } from '@grafana/ui';
  5. import store from 'app/core/store';
  6. import { TutorialCardType } from '../types';
  7. import { cardContent, cardStyle, iconStyle } from './sharedStyles';
  8. interface Props {
  9. card: TutorialCardType;
  10. }
  11. export const TutorialCard: FC<Props> = ({ card }) => {
  12. const theme = useTheme();
  13. const styles = getStyles(theme, card.done);
  14. return (
  15. <a className={styles.card} onClick={(event: MouseEvent<HTMLAnchorElement>) => handleTutorialClick(event, card)}>
  16. <div className={cardContent}>
  17. <div className={styles.type}>{card.type}</div>
  18. <div className={styles.heading}>{card.done ? 'complete' : card.heading}</div>
  19. <h4 className={styles.cardTitle}>{card.title}</h4>
  20. <div className={styles.info}>{card.info}</div>
  21. <Icon className={iconStyle(theme, card.done)} name={card.icon} size="xxl" />
  22. </div>
  23. </a>
  24. );
  25. };
  26. const handleTutorialClick = (event: MouseEvent<HTMLAnchorElement>, card: TutorialCardType) => {
  27. event.preventDefault();
  28. const isSet = store.get(card.key);
  29. if (!isSet) {
  30. store.set(card.key, true);
  31. }
  32. window.open(`${card.href}?utm_source=grafana_gettingstarted`, '_blank');
  33. };
  34. const getStyles = stylesFactory((theme: GrafanaTheme, complete: boolean) => {
  35. return {
  36. card: css`
  37. ${cardStyle(theme, complete)}
  38. width: 460px;
  39. min-width: 460px;
  40. @media only screen and (max-width: ${theme.breakpoints.xl}) {
  41. min-width: 368px;
  42. }
  43. @media only screen and (max-width: ${theme.breakpoints.lg}) {
  44. min-width: 272px;
  45. }
  46. `,
  47. type: css`
  48. color: ${theme.colors.textBlue};
  49. text-transform: uppercase;
  50. `,
  51. heading: css`
  52. text-transform: uppercase;
  53. color: ${theme.colors.textBlue};
  54. margin-bottom: ${theme.spacing.sm};
  55. `,
  56. cardTitle: css`
  57. margin-bottom: ${theme.spacing.md};
  58. `,
  59. info: css`
  60. margin-bottom: ${theme.spacing.md};
  61. `,
  62. status: css`
  63. display: flex;
  64. justify-content: flex-end;
  65. `,
  66. };
  67. });