{"version":3,"sources":["../src/feedback/index.tsx"],"sourcesContent":["import {\n  Button,\n  Modal,\n  ModalProps,\n  Portal,\n  Typography,\n  useAlert,\n  useModal,\n} from \"matsuri-ui\";\nimport { type Logger } from \"@datadog/browser-logs\";\nimport {\n  MatsuriFormsQuestion,\n  MatsuriFormsQuestionProvider,\n  MatsuriFormsTextQuestionProps,\n  useMatsuriForms,\n} from \"matsuri-forms-sdk\";\nimport { PropsWithChildren, createContext, useContext, useState } from \"react\";\nimport FeedbackIconBase from \"@mui/icons-material/Feedback\";\nimport { MultipleTextQuestion } from \"./MultipleTextQuestion\";\nimport { SelectQuestion } from \"./SelectQuestion\";\nimport { getRandomId } from \"./getRandomId\";\n\n/**\n * これはワークアラウンドです。\n * これを行わずに、MuiIconをそのまま使うと、トランスパイル後のコードで次のようなエラーが発生し、コンポーネントを描画できなくなります。\n * `Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.`\n * 関連リンク：\n * https://stackoverflow.com/questions/72008357/mui-icons-used-in-shared-react-component-library-wont-render-error-element-ty\n * https://github.com/mui/material-ui/issues/35535\n */\nconst normalizeIcon = <T,>(Icon: T): T => {\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access\n  return ((Icon as any).default ? (Icon as any).default : Icon) as T;\n};\nconst FeedbackIcon = normalizeIcon(FeedbackIconBase);\n\nconst getFormId = () => {\n  return globalThis.M2M_COMPONENTS_ENV === \"production\"\n    ? \"01GWRQ1MRS7PE29XGRETFZ6D7Y\"\n    : \"01GTBSYMGPMX91E96P007SXEMH\";\n};\n\ninterface TextQuestionContextValue {\n  userId?: string;\n  userName?: string;\n  serviceName?: string;\n  url?: string;\n  id?: string;\n}\n\nconst TextQuestionContext = createContext<TextQuestionContextValue>({});\n\nconst TextQuestion = (props: MatsuriFormsTextQuestionProps) => {\n  const context = useContext(TextQuestionContext);\n  return (\n    <input\n      value={context[props.title as keyof TextQuestionContextValue]}\n      type=\"hidden\"\n      name={props.name}\n    />\n  );\n};\n\ninterface FeedbackProviderModalProps\n  extends Partial<ModalProps>, FeedbackProviderProps {}\n\nconst FeedbackProviderModal = (props: FeedbackProviderModalProps) => {\n  const { questions, submit } = useMatsuriForms(getFormId(), {\n    dev: globalThis.M2M_COMPONENTS_ENV !== \"production\",\n  });\n\n  const { throwAlert } = useAlert();\n\n  const [status, setStatus] = useState<\"started\" | \"sending\" | \"completed\">(\n    \"started\",\n  );\n\n  const id = getRandomId();\n\n  return (\n    <Modal\n      backdrop\n      width={600}\n      maxWidth={600}\n      header={<Typography variant=\"h3\">フィードバックを送信</Typography>}\n      body={\n        status === \"completed\" ? (\n          <div\n            style={{\n              display: \"grid\",\n              gap: 32,\n            }}\n          >\n            <Typography>\n              レポートを送信しました。ありがとうございます。\n            </Typography>\n            <Typography color=\"textSecondary\" variant=\"caption\" as=\"p\">\n              お送りいただいたフィードバックは、問題の解決とサービスの改善に役立てさせていただきます。\n            </Typography>\n            <Button\n              color=\"primary\"\n              variant=\"filled\"\n              onClick={() => {\n                props.onClose?.();\n              }}\n            >\n              閉じる\n            </Button>\n          </div>\n        ) : (\n          <form\n            style={{\n              display: \"grid\",\n              gap: 24,\n            }}\n            onSubmit={async (event) => {\n              event.preventDefault();\n              setStatus(\"sending\");\n              const { error } = await submit(event.currentTarget);\n\n              /**\n               * 以下、対応が行われるまでは取れる値だけ送る\n               * https://github.com/matsuri-tech/matsuri-forms-manager-front/issues/265\n               */\n              const input = {\n                id,\n                userId: props.userId,\n                userName: props.userName,\n                serviceName: props.serviceName,\n                url: window.location.href,\n              };\n              throwAlert(error, {\n                ignoreSuccess: true,\n                errorMessage: {\n                  reason: \"サーバー側のエラーの可能性があります。\",\n                  action:\n                    \"しばらく時間を空けて試すか、開発チームへお問い合わせください。\",\n                  happend: \"フィードバックの送信に失敗しました。\",\n                },\n                onSuccess: () => {\n                  props.datadogLogs?.logger?.info?.(\n                    `Feedback: ${id} by ${props.userId}`,\n                    {\n                      input,\n                    },\n                  );\n\n                  window.setTimeout(() => {\n                    setStatus(\"completed\");\n                  }, 2000);\n                },\n                onError: () => {\n                  props.datadogLogs?.logger?.error?.(\n                    `Failed Feedback: ${input.id} by ${input.userId}`,\n                    { input, error },\n                  );\n\n                  window.setTimeout(() => {\n                    setStatus(\"started\");\n                  }, 2000);\n                },\n              });\n            }}\n          >\n            <TextQuestionContext.Provider\n              value={{\n                userId: props.userId,\n                userName: props.userName,\n                serviceName: props.serviceName,\n                url: window.location.href,\n                id,\n              }}\n            >\n              <MatsuriFormsQuestionProvider\n                renderSelect={SelectQuestion}\n                renderMultilineText={MultipleTextQuestion}\n                renderText={TextQuestion}\n              >\n                {questions.map((question) => {\n                  return (\n                    <MatsuriFormsQuestion {...question} key={question.id} />\n                  );\n                })}\n              </MatsuriFormsQuestionProvider>\n            </TextQuestionContext.Provider>\n            <div>\n              <Button\n                type=\"submit\"\n                color=\"primary\"\n                variant=\"filled\"\n                disabled={status === \"sending\"}\n                fullWidth\n              >\n                送信\n              </Button>\n              <Typography\n                variant=\"caption\"\n                style={{\n                  float: \"right\",\n                }}\n              >\n                {status === \"sending\" ? \"送信中...\" : undefined}\n                &nbsp;\n              </Typography>\n            </div>\n          </form>\n        )\n      }\n      {...props}\n    />\n  );\n};\n\ninterface FeedbackProviderProps {\n  userId?: string;\n  userName?: string;\n  serviceName: string;\n  datadogLogs?: {\n    logger: Logger;\n  };\n}\n\nexport const FeedbackProvider = ({\n  children,\n  ...modalProps\n}: PropsWithChildren<FeedbackProviderProps>) => {\n  const [open] = useModal(FeedbackProviderModal, {\n    enableClickOutside: true,\n    disableClose: false,\n  });\n  return (\n    <div>\n      {children}\n      <Portal>\n        <Button\n          style={{\n            position: \"fixed\",\n            bottom: 16,\n            right: 16,\n          }}\n          onClick={() => {\n            open(modalProps);\n          }}\n          type=\"button\"\n          icon={<FeedbackIcon />}\n          color=\"secondary\"\n          variant=\"filled\"\n          rounded\n        />\n      </Portal>\n    </div>\n  );\n};\n"],"mappings":"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","names":[]}