index.tsx 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import React from "react";
  2. import styled, { DefaultTheme } from "styled-components";
  3. import toast from "react-hot-toast";
  4. import { useConfig } from "src/hocs/config";
  5. import { ConfigActionType } from "src/reducer/reducer";
  6. enum ButtonType {
  7. PRIMARY = "PRIMARY",
  8. SECONDARY = "BLURPLE",
  9. DANGER = "DANGER",
  10. SUCCESS = "SEAGREEN",
  11. WARNING = "ORANGE",
  12. }
  13. function getButtonStatus(status: keyof typeof ButtonType, theme: DefaultTheme) {
  14. return theme[ButtonType[status]];
  15. }
  16. const StyledModalWrapper = styled.div`
  17. position: absolute;
  18. top: 0;
  19. left: 0;
  20. width: 100%;
  21. height: 100%;
  22. background: rgba(0, 0, 0, 0.5);
  23. z-index: 5;
  24. display: flex;
  25. justify-content: center;
  26. align-items: center;
  27. `;
  28. const StyledInput = styled.input`
  29. background: ${({ theme }) => theme.BACKGROUND_TERTIARY};
  30. color: ${({ theme }) => theme.INTERACTIVE_NORMAL};
  31. outline: none;
  32. border: none;
  33. border-radius: 5px;
  34. padding: 10px;
  35. margin: 10px 0;
  36. display: block;
  37. width: 100%;
  38. `;
  39. const StyledButton = styled.button<{ status: keyof typeof ButtonType }>`
  40. background: ${({ status, theme }) => getButtonStatus(status, theme)};
  41. color: #ffffff;
  42. padding: 8px 16px;
  43. min-width: 60px;
  44. margin-right: 10px;
  45. @media only screen and (max-width: 768px) {
  46. font-size: 18px;
  47. }
  48. `;
  49. export const Modal = ({ visible, setVisible }) => {
  50. const { json, settings, dispatch } = useConfig();
  51. const inputRef = React.useRef<HTMLInputElement | null>(null);
  52. const fetchJSON = () => {
  53. fetch(inputRef.current!.value)
  54. .then((res) => res.json())
  55. .then((json) => {
  56. dispatch({
  57. type: ConfigActionType.SET_JSON,
  58. payload: JSON.stringify(json),
  59. });
  60. setVisible(false);
  61. })
  62. .catch((err) => toast.error(err.message));
  63. };
  64. const cancel = () => {
  65. setVisible(false);
  66. };
  67. return (
  68. visible && (
  69. <StyledModalWrapper>
  70. <div>
  71. <h2>Import JSON from URL</h2>
  72. <div>
  73. <StyledInput
  74. ref={inputRef}
  75. type="url"
  76. placeholder="URL of JSON to fetch"
  77. />
  78. <StyledButton status="PRIMARY" onClick={fetchJSON}>
  79. Import
  80. </StyledButton>
  81. <StyledButton status="DANGER" onClick={cancel}>
  82. Cancel
  83. </StyledButton>
  84. </div>
  85. </div>
  86. </StyledModalWrapper>
  87. )
  88. );
  89. };