Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
ErroReportModal.component.tsx 6.33 KiB
/* eslint-disable jsx-a11y/label-has-associated-control */
import { useAppSelector } from '@/redux/hooks/useAppSelector';
import { Button } from '@/shared/Button';
import { Input } from '@/shared/Input';
import React from 'react';
import { currentErrorDataSelector } from '@/redux/modal/modal.selector';
import { sendReport } from '@/utils/error-report/sendErrorReport';
import { ONE_THOUSAND } from '@/constants/common';
import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
import { closeModal } from '@/redux/modal/modal.slice';

export const ErrorReportModal: React.FC = () => {
  const dispatch = useAppDispatch();
  const errorData = useAppSelector(currentErrorDataSelector);

  function getValue(nullableVale: string | null | undefined): string {
    if (!nullableVale) {
      return '';
    }
    return nullableVale;
  }

  const url = getValue(errorData?.url);
  const browser = getValue(errorData?.browser);
  const comment = getValue(errorData?.comment);
  const login = getValue(errorData?.login);
  const email = getValue(errorData?.email);
  const javaStacktrace = getValue(errorData?.javaStacktrace);
  const stacktrace = getValue(errorData?.stacktrace);
  const version = getValue(errorData?.version);
  const timestamp = errorData ? errorData.timestamp : Math.floor(+new Date() / ONE_THOUSAND);

  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  const [errorDataToSend, setValue] = React.useState({
    url,
    browser,
    comment,
    login,
    email,
    javaStacktrace,
    stacktrace,
    version,
    timestamp,
  });

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>): void => {
    const { name, checked } = e.target;
    let { value } = e.target;
    setValue(errorData2 => {
      if (name === 'login') {
        const loginValue = checked ? login : '';
        const emailValue = checked ? email : '';

        return { ...errorData2, login: loginValue, email: emailValue };
      }
      if (name === 'url') {
        value = checked ? url : '';
      }
      if (name === 'browser') {
        value = checked ? browser : '';
      }
      if (name === 'version') {
        value = checked ? version : '';
      }
      return { ...errorData2, [name]: value };
    });
  };

  const handleSubmit = async (e: React.FormEvent<HTMLFormElement>): Promise<void> => {
    e.preventDefault();
    await dispatch(sendReport(errorDataToSend));
    dispatch(closeModal());
  };

  return (
    <div className="w-[800px] border border-t-[#E1E0E6] bg-white">
      <form onSubmit={handleSubmit} className="p-4">
        <p className="my-4">
          If you agree to submit the following information to the minerva maintainers please uncheck
          all boxes that might contain sensitive data.
        </p>
        <label className="mb-1 mt-4 block text-sm" htmlFor="comment">
          <span className="font-semibold">Add comment</span> (max 1000 characters):
        </label>
        <Input
          type="textarea"
          name="comment"
          id="comment"
          onChange={handleChange}
          value={errorDataToSend.comment}
          className="mb-4 text-sm font-medium text-font-400"
        />
        <div className="grid grid-cols-[15px_743px] gap-2">
          <label className="flex-1 text-sm font-semibold" htmlFor="url">
            <Input
              styleVariant="primaryWithoutFull"
              id="url"
              name="url"
              type="checkbox"
              onChange={handleChange}
              checked={errorDataToSend.url !== ''}
              className="flex-1 align-bottom text-sm font-semibold"
            />
          </label>
          <label className="block border border-transparent bg-cultured px-2 py-2.5 text-sm font-medium outline-none hover:border-greyscale-600 focus:border-greyscale-600">
            {url}
          </label>
          <label className="block text-sm font-semibold">
            <Input
              styleVariant="primaryWithoutFull"
              id="browser"
              name="browser"
              type="checkbox"
              onChange={handleChange}
              checked={errorDataToSend.browser !== ''}
              className="flex-1 align-bottom text-sm font-semibold"
            />
          </label>
          <label className="block border border-transparent bg-cultured px-2 py-2.5 text-sm font-medium outline-none hover:border-greyscale-600 focus:border-greyscale-600">
            {browser}
          </label>
          <label className="block text-sm font-semibold">
            <Input
              id="login"
              name="login"
              type="checkbox"
              onChange={handleChange}
              checked={errorDataToSend.login !== ''}
              styleVariant="primaryWithoutFull"
              className="flex-1 align-bottom text-sm font-semibold"
            />
          </label>
          <label className="block border border-transparent bg-cultured px-2 py-2.5 text-sm font-medium outline-none hover:border-greyscale-600 focus:border-greyscale-600">
            {login} (email: {email})
          </label>
          <label className="block text-sm font-semibold">
            <Input
              styleVariant="primaryWithoutFull"
              id="version"
              name="version"
              type="checkbox"
              onChange={handleChange}
              checked={errorDataToSend.version !== ''}
              className="flex-1 align-bottom text-sm font-semibold"
            />
          </label>
          <label className="block border border-transparent bg-cultured px-2 py-2.5 text-sm font-medium outline-none hover:border-greyscale-600 focus:border-greyscale-600">
            Minerva {version}
          </label>
        </div>

        <div className="my-4 block max-h-20 overflow-auto border border-transparent bg-cultured px-2 py-2.5 text-sm font-medium outline-none hover:border-greyscale-600 focus:border-greyscale-600">
          Stacktrace:
          <pre>{errorDataToSend.stacktrace}</pre>
        </div>
        <div className="my-4 block max-h-20 overflow-auto border border-transparent bg-cultured px-2 py-2.5 text-sm font-medium outline-none hover:border-greyscale-600 focus:border-greyscale-600">
          Backend stacktrace:
          <pre>{errorDataToSend.javaStacktrace}</pre>
        </div>

        <Button type="submit" className="w-full justify-center text-base font-medium">
          Submit
        </Button>
      </form>
    </div>
  );
};