import React, { useCallback, useEffect, useState } from "react";
import { AppDispatch } from "app/store";
import { useTranslation } from "react-i18next";
import { useDispatch, useSelector } from "react-redux";
import styles from "styles/app.module.scss";
import Footer from "components/footer";
import Header from "components/header";
import {
  listTasksAsync,
  selectCurrentPage,
  selectTasks,
  selectTotal,
  selectTotalPage,
  DIRECTION,
  DisplayInfoType,
  INIT_DISPLAY_INFO,
  SORTABLE_COLUMN,
  selectDisplayInfo,
  changeDisplayInfo,
  getSortColumnAsync,
  selectParamName,
  selectDirection,
  changeParamName,
  changeDirection,
  changeAuthorId,
  changeFileName,
  changeSelectedTask,
  openFilePropertyInfo,
  SortableColumnType,
  changeAssignee,
  listTypistsAsync,
  listTypistGroupsAsync,
  DirectionType,
  selectIsLoading,
  playbackAsync,
  cancelAsync,
  reopenAsync,
  PRIORITY,
  deleteTaskAsync,
  isSortableColumnType,
  isDirectionType,
  getTaskFiltersAsync,
  selectAuthorId,
  selectFilename,
  updateTaskFiltersAsync,
  updateSortColumnAsync,
} from "features/dictation";
import { getTranslationID } from "translation";
import { Task } from "api/api";
import { isAdminUser, isAuthorUser, isTypistUser } from "features/auth";
import { STATUS, LIMIT_TASK_NUM } from "../../features/dictation";
import uploaded from "../../assets/images/uploaded.svg";
import pending from "../../assets/images/pending.svg";
import inprogress from "../../assets/images/inprogress.svg";
import finished from "../../assets/images/finished.svg";
import backup from "../../assets/images/backup.svg";
import lock from "../../assets/images/lock.svg";
import progress_activit from "../../assets/images/progress_activit.svg";
import download from "../../assets/images/download.svg";
import open_in_new from "../../assets/images/open_in_new.svg";
import { DisPlayInfo } from "./displayInfo";
import { ChangeTranscriptionistPopup } from "./changeTranscriptionistPopup";
import { BackupPopup } from "./backupPopup";
import { FilePropertyPopup } from "./filePropertyPopup";
import searchIcon from "../../assets/images/search.svg";

const DictationPage: React.FC = (): JSX.Element => {
  const dispatch: AppDispatch = useDispatch();
  const [t] = useTranslation();

  const isAdmin = isAdminUser();
  const isAuthor = isAuthorUser();
  const isTypist = isTypistUser();
  const isNone = !isAuthor && !isTypist;

  const isDeletableRole = isAdmin || isAuthor;

  // popup制御関係
  const [
    isChangeTranscriptionistPopupOpen,
    setIsChangeTranscriptionistPopupOpen,
  ] = useState(false);
  const [isFilePropertyPopupOpen, setIsFilePropertyPopupOpen] = useState(false);
  const [isBackupPopupOpen, setIsBackupPopupOpen] = useState(false);

  const onChangeTranscriptionistPopupOpen = useCallback(
    (task: Task) => {
      dispatch(changeAssignee({ selected: task.assignees }));
      dispatch(changeSelectedTask({ task }));
      setIsChangeTranscriptionistPopupOpen(true);
    },
    [dispatch, setIsChangeTranscriptionistPopupOpen]
  );

  const onClickFileProperty = useCallback(
    (task: Task) => {
      dispatch(openFilePropertyInfo({ task }));
      setIsFilePropertyPopupOpen(true);
    },
    [dispatch, setIsFilePropertyPopupOpen]
  );
  // 各カラムの表示/非表示
  const displayColumn = useSelector(selectDisplayInfo);

  // フィルターするステータス
  const [filterUploaded, setFilterUploaded] = useState(true);
  const [filterPending, setFilterPending] = useState(true);
  const [filterInProgress, setFilterInProgress] = useState(true);
  const [filterFinished, setFilterFinished] = useState(true);
  const [filterBackup, setFilterBackup] = useState(false);

  // 検索条件の入力値
  const [filterConditionAuthorId, setFilterConditionAuthorId] = useState("");
  const [filterConditionFileName, setFilterConditionFileName] = useState("");

  // ソート対象カラム
  const sortableParamName = useSelector(selectParamName);
  const sortDirection = useSelector(selectDirection);

  // task_filtersテーブルの検索条件
  const authorId = useSelector(selectAuthorId);
  const fileName = useSelector(selectFilename);

  const tasks = useSelector(selectTasks);
  const total = useSelector(selectTotal);
  const totalPage = useSelector(selectTotalPage);
  const currentPage = useSelector(selectCurrentPage);

  const isLoading = useSelector(selectIsLoading);

  // ページネーションのボタンクリック時のアクション
  const getFirstPage = useCallback(() => {
    const filter = getFilter(
      filterUploaded,
      filterInProgress,
      filterPending,
      filterFinished,
      filterBackup
    );
    dispatch(
      listTasksAsync({
        limit: LIMIT_TASK_NUM,
        offset: 0,
        filter,
        direction: sortDirection,
        paramName: sortableParamName,
        authorId,
        fileName,
      })
    );
    dispatch(listTypistsAsync());
    dispatch(listTypistGroupsAsync());
  }, [
    dispatch,
    filterUploaded,
    filterInProgress,
    filterPending,
    filterFinished,
    filterBackup,
    sortDirection,
    sortableParamName,
    authorId,
    fileName,
  ]);

  const getLastPage = useCallback(() => {
    const filter = getFilter(
      filterUploaded,
      filterInProgress,
      filterPending,
      filterFinished,
      filterBackup
    );
    const lastPageOffset = (totalPage - 1) * LIMIT_TASK_NUM;
    dispatch(
      listTasksAsync({
        limit: LIMIT_TASK_NUM,
        offset: lastPageOffset,
        filter,
        direction: sortDirection,
        paramName: sortableParamName,
        authorId,
        fileName,
      })
    );
    dispatch(listTypistsAsync());
    dispatch(listTypistGroupsAsync());
  }, [
    dispatch,
    totalPage,
    filterUploaded,
    filterInProgress,
    filterPending,
    filterFinished,
    filterBackup,
    sortDirection,
    sortableParamName,
    authorId,
    fileName,
  ]);

  const getPrevPage = useCallback(() => {
    const filter = getFilter(
      filterUploaded,
      filterInProgress,
      filterPending,
      filterFinished,
      filterBackup
    );
    const prevPageOffset = (currentPage - 2) * LIMIT_TASK_NUM;
    dispatch(
      listTasksAsync({
        limit: LIMIT_TASK_NUM,
        offset: prevPageOffset,
        filter,
        direction: sortDirection,
        paramName: sortableParamName,
        authorId,
        fileName,
      })
    );
    dispatch(listTypistsAsync());
    dispatch(listTypistGroupsAsync());
  }, [
    dispatch,
    currentPage,
    filterUploaded,
    filterInProgress,
    filterPending,
    filterFinished,
    filterBackup,
    sortDirection,
    sortableParamName,
    authorId,
    fileName,
  ]);

  const getNextPage = useCallback(() => {
    const filter = getFilter(
      filterUploaded,
      filterInProgress,
      filterPending,
      filterFinished,
      filterBackup
    );
    const nextPageOffset = currentPage * LIMIT_TASK_NUM;
    dispatch(
      listTasksAsync({
        limit: LIMIT_TASK_NUM,
        offset: nextPageOffset,
        filter,
        direction: sortDirection,
        paramName: sortableParamName,
        authorId,
        fileName,
      })
    );
    dispatch(listTypistsAsync());
    dispatch(listTypistGroupsAsync());
  }, [
    dispatch,
    currentPage,
    filterUploaded,
    filterInProgress,
    filterPending,
    filterFinished,
    filterBackup,
    sortDirection,
    sortableParamName,
    authorId,
    fileName,
  ]);

  const updateSortColumn = useCallback(
    (paramName: SortableColumnType) => {
      const currentDirection =
        sortableParamName === paramName && sortDirection === DIRECTION.ASC
          ? DIRECTION.DESC
          : DIRECTION.ASC;
      dispatch(changeDirection({ direction: currentDirection }));
      dispatch(changeParamName({ paramName }));

      // ローカルストレージにソート情報を保存する
      localStorage.setItem(
        "sortCriteria",
        `direction:${currentDirection},paramName:${paramName}`
      );

      const filter = getFilter(
        filterUploaded,
        filterInProgress,
        filterPending,
        filterFinished,
        filterBackup
      );

      dispatch(
        listTasksAsync({
          limit: LIMIT_TASK_NUM,
          offset: 0,
          filter,
          direction: currentDirection,
          paramName,
          authorId,
          fileName,
        })
      );
      dispatch(listTypistsAsync());
      dispatch(listTypistGroupsAsync());
    },
    [
      dispatch,
      sortableParamName,
      sortDirection,
      filterUploaded,
      filterInProgress,
      filterPending,
      filterFinished,
      filterBackup,
      authorId,
      fileName,
    ]
  );

  const getFilter = (
    hasUploaded: boolean,
    hasInProgress: boolean,
    hasPending: boolean,
    hasFinished: boolean,
    hasBackup: boolean
  ): string | undefined => {
    const filterStatus = [];
    if (hasUploaded) {
      filterStatus.push(STATUS.UPLOADED);
    }
    if (hasInProgress) {
      filterStatus.push(STATUS.INPROGRESS);
    }
    if (hasPending) {
      filterStatus.push(STATUS.PENDING);
    }
    if (hasFinished) {
      filterStatus.push(STATUS.FINISHED);
    }
    if (hasBackup) {
      filterStatus.push(STATUS.BACKUP);
    }

    if (filterStatus.length === 0) {
      return undefined;
    }
    return filterStatus.join(",");
  };

  // ステータスフィルターの変更時アクション
  const updateFilter = useCallback(
    (
      hasUploaded: boolean,
      hasInProgress: boolean,
      hasPending: boolean,
      hasFinished: boolean,
      hasBackup: boolean
    ) => {
      const filter = getFilter(
        hasUploaded,
        hasInProgress,
        hasPending,
        hasFinished,
        hasBackup
      );

      // フィルターの状態をローカルストレージに保存する
      localStorage.setItem(
        "filterCriteria",
        JSON.stringify({
          Uploaded: hasUploaded,
          InProgress: hasInProgress,
          Pending: hasPending,
          Finished: hasFinished,
          Backup: hasBackup,
        })
      );

      dispatch(
        listTasksAsync({
          limit: LIMIT_TASK_NUM,
          offset: 0,
          filter,
          direction: sortDirection,
          paramName: sortableParamName,
          authorId,
          fileName,
        })
      );
      dispatch(listTypistsAsync());
      dispatch(listTypistGroupsAsync());
    },
    [dispatch, sortDirection, sortableParamName, authorId, fileName]
  );

  const onPlayBack = useCallback(
    async (audioFileId: number) => {
      if (
        /* eslint-disable-next-line no-alert */
        !window.confirm(t(getTranslationID("common.message.dialogConfirm")))
      ) {
        return;
      }
      const { meta } = await dispatch(
        playbackAsync({
          audioFileId,
          direction: sortDirection,
          paramName: sortableParamName,
          filterConditionAuthorId: authorId,
          filterConditionFileName: fileName,
        })
      );
      if (meta.requestStatus === "fulfilled") {
        // ローカルストレージにソート情報を削除する
        localStorage.removeItem("sortCriteria");
        const filter = getFilter(
          filterUploaded,
          filterInProgress,
          filterPending,
          filterFinished,
          filterBackup
        );
        dispatch(
          listTasksAsync({
            limit: LIMIT_TASK_NUM,
            offset: 0,
            filter,
            direction: sortDirection,
            paramName: sortableParamName,
            authorId,
            fileName,
          })
        );
        dispatch(listTypistsAsync());
        dispatch(listTypistGroupsAsync());

        const url = `${import.meta.env.VITE_DESK_TOP_APP_SCHEME
          }:playback?audioId=${audioFileId}`;
        const a = document.createElement("a");
        a.href = url;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
      }
    },
    [
      dispatch,
      filterBackup,
      filterFinished,
      filterInProgress,
      filterPending,
      filterUploaded,
      sortDirection,
      sortableParamName,
      authorId,
      fileName,
      t,
    ]
  );

  const onClosePopup = useCallback(
    (isChanged: boolean) => {
      if (isChanged) {
        const filter = getFilter(
          filterUploaded,
          filterInProgress,
          filterPending,
          filterFinished,
          filterBackup
        );
        dispatch(
          listTasksAsync({
            limit: LIMIT_TASK_NUM,
            offset: 0,
            filter,
            direction: sortDirection,
            paramName: sortableParamName,
            authorId,
            fileName,
          })
        );
      }
      setIsChangeTranscriptionistPopupOpen(false);
    },
    [
      dispatch,
      filterUploaded,
      filterInProgress,
      filterPending,
      filterFinished,
      filterBackup,
      sortDirection,
      sortableParamName,
      authorId,
      fileName,
    ]
  );

  const onCancel = useCallback(
    async (audioFileId: number) => {
      if (
        /* eslint-disable-next-line no-alert */
        !window.confirm(t(getTranslationID("common.message.dialogConfirm")))
      ) {
        return;
      }
      const { meta } = await dispatch(
        cancelAsync({
          audioFileId,
          direction: sortDirection,
          paramName: sortableParamName,
          isTypist,
          filterConditionAuthorId: authorId,
          filterConditionFileName: fileName,
        })
      );
      if (meta.requestStatus === "fulfilled") {
        const filter = getFilter(
          filterUploaded,
          filterInProgress,
          filterPending,
          filterFinished,
          filterBackup
        );
        dispatch(
          listTasksAsync({
            limit: LIMIT_TASK_NUM,
            offset: 0,
            filter,
            direction: sortDirection,
            paramName: sortableParamName,
            authorId,
            fileName,
          })
        );
        dispatch(listTypistsAsync());
        dispatch(listTypistGroupsAsync());
      }
    },
    [
      dispatch,
      filterBackup,
      filterFinished,
      filterInProgress,
      filterPending,
      filterUploaded,
      isTypist,
      sortDirection,
      sortableParamName,
      authorId,
      fileName,
      t,
    ]
  );

  const onReopen = useCallback(
    async (audioFileId: number) => {
      if (
        /* eslint-disable-next-line no-alert */
        !window.confirm(t(getTranslationID("common.message.dialogConfirm")))
      ) {
        return;
      }

      const { meta } = await dispatch(
        reopenAsync({
          audioFileId,
          direction: sortDirection,
          paramName: sortableParamName,
          isTypist,
          filterConditionAuthorId: authorId,
          filterConditionFileName: fileName,
        })
      );

      if (meta.requestStatus === "fulfilled") {
        const filter = getFilter(
          filterUploaded,
          filterInProgress,
          filterPending,
          filterFinished,
          filterBackup
        );
        dispatch(
          listTasksAsync({
            limit: LIMIT_TASK_NUM,
            offset: 0,
            filter,
            direction: sortDirection,
            paramName: sortableParamName,
            authorId,
            fileName,
          })
        );
        dispatch(listTypistsAsync());
        dispatch(listTypistGroupsAsync());
      }
    },
    [
      dispatch,
      filterBackup,
      filterFinished,
      filterInProgress,
      filterPending,
      filterUploaded,
      isTypist,
      sortDirection,
      sortableParamName,
      authorId,
      fileName,
      t,
    ]
  );

  const onCloseBackupPopup = useCallback(() => {
    setIsBackupPopupOpen(false);
  }, []);

  const onClickBackup = useCallback(() => {
    setIsBackupPopupOpen(true);
  }, []);

  const onCloseFilePropertyPopup = useCallback(
    (isChanged: boolean) => {
      if (isChanged) {
        const filter = getFilter(
          filterUploaded,
          filterInProgress,
          filterPending,
          filterFinished,
          filterBackup
        );
        dispatch(
          listTasksAsync({
            limit: LIMIT_TASK_NUM,
            offset: 0,
            filter,
            direction: sortDirection,
            paramName: sortableParamName,
            authorId,
            fileName,
          })
        );
      }
      setIsFilePropertyPopupOpen(false);
    },
    [
      dispatch,
      filterUploaded,
      filterInProgress,
      filterPending,
      filterFinished,
      filterBackup,
      sortDirection,
      sortableParamName,
      authorId,
      fileName,
    ]
  );

  const onChangeFilterConditionFileName = useCallback(
    (e: React.ChangeEvent<HTMLInputElement>) => {
      setFilterConditionFileName(e.target.value.trimStart());
    },
    [setFilterConditionFileName]
  );

  const onChangeFilterConditionAuthorId = useCallback(
    (e: React.ChangeEvent<HTMLInputElement>) => {
      // 先頭に%が入力されるとWAFのルールでブロックされてしまう。
      // Authorの登録時に「_」以外の記号は許可されていないため、「_」と半角英数字以外の文字は除去。
      const correctAuthorId = e.target.value.replace(/[^a-zA-Z0-9_]/g, "");
      setFilterConditionAuthorId(correctAuthorId);
    },
    [setFilterConditionAuthorId]
  );

  const sortIconClass = (
    currentParam: SortableColumnType,
    currentDirection: DirectionType,
    column: SortableColumnType
  ) => {
    if (currentParam !== column) {
      return "";
    }
    if (currentDirection === DIRECTION.DESC) {
      return styles.isActiveZa;
    }
    return styles.isActiveAz;
  };

  const onDeleteTask = useCallback(
    async (audioFileId: number) => {
      if (
        /* eslint-disable-next-line no-alert */
        !window.confirm(t(getTranslationID("common.message.dialogConfirm")))
      ) {
        return;
      }
      const { meta } = await dispatch(
        deleteTaskAsync({
          audioFileId,
        })
      );
      if (meta.requestStatus === "fulfilled") {
        const filter = getFilter(
          filterUploaded,
          filterInProgress,
          filterPending,
          filterFinished,
          filterBackup
        );
        dispatch(
          listTasksAsync({
            limit: LIMIT_TASK_NUM,
            offset: 0,
            filter,
            direction: sortDirection,
            paramName: sortableParamName,
            authorId,
            fileName,
          })
        );
        dispatch(listTypistsAsync());
        dispatch(listTypistGroupsAsync());
      }
    },
    [
      dispatch,
      filterBackup,
      filterFinished,
      filterInProgress,
      filterPending,
      filterUploaded,
      sortDirection,
      sortableParamName,
      authorId,
      fileName,
      t,
    ]
  );

  const requestSearch = useCallback(
    async (e: React.FormEvent<HTMLFormElement>) => {
      e.preventDefault();
      const { meta: taskFilterMeta } = await dispatch(
        updateTaskFiltersAsync({
          filterConditionFileName,
          filterConditionAuthorId,
        })
      );
      const { meta: sortCriteriaMeta } = await dispatch(
        updateSortColumnAsync({
          direction: sortDirection,
          paramName: sortableParamName,
        })
      );
      if (
        taskFilterMeta.requestStatus === "fulfilled" &&
        sortCriteriaMeta.requestStatus === "fulfilled"
      ) {
        const filter = getFilter(
          filterUploaded,
          filterInProgress,
          filterPending,
          filterFinished,
          filterBackup
        );
        dispatch(changeAuthorId({ authorId: filterConditionAuthorId }));
        dispatch(changeFileName({ fileName: filterConditionFileName }));
        // 検索した条件でタスク一覧を取得する
        dispatch(
          listTasksAsync({
            limit: LIMIT_TASK_NUM,
            offset: 0,
            filter,
            direction: sortDirection,
            paramName: sortableParamName,
            authorId: filterConditionAuthorId,
            fileName: filterConditionFileName,
          })
        );
      }
    },
    [
      dispatch,
      filterBackup,
      filterFinished,
      filterInProgress,
      filterPending,
      filterUploaded,
      sortDirection,
      sortableParamName,
      filterConditionAuthorId,
      filterConditionFileName,
    ]
  );

  // 初回読み込み処理
  useEffect(() => {
    (async () => {
      const displayInfoValue = localStorage.getItem("displayInfo");

      let displayInfo: DisplayInfoType;
      if (displayInfoValue) {
        displayInfo = JSON.parse(displayInfoValue);
      } else {
        displayInfo = INIT_DISPLAY_INFO;
        localStorage.setItem("displayInfo", JSON.stringify(displayInfo));
      }

      dispatch(changeDisplayInfo({ column: displayInfo }));

      // フィルター状態をローカルストレージから取得する
      const filterValue = localStorage.getItem("filterCriteria");

      let filter: string | undefined;
      if (filterValue) {
        const parsedFilter = JSON.parse(filterValue);
        setFilterUploaded(parsedFilter.Uploaded);
        setFilterInProgress(parsedFilter.InProgress);
        setFilterPending(parsedFilter.Pending);
        setFilterFinished(parsedFilter.Finished);
        setFilterBackup(parsedFilter.Backup);

        filter = getFilter(
          parsedFilter.Uploaded,
          parsedFilter.InProgress,
          parsedFilter.Pending,
          parsedFilter.Finished,
          parsedFilter.Backup
        );
      } else {
        filter = getFilter(true, true, true, true, false);
        localStorage.setItem(
          "filterCriteria",
          JSON.stringify({
            Uploaded: true,
            InProgress: true,
            Pending: true,
            Finished: true,
            Backup: false,
          })
        );
      }
      // タスクフィルター条件
      const { meta: taskFilterMeta, payload: taskfilterPayload } =
        await dispatch(getTaskFiltersAsync());
      let payloadAuthorId: string | undefined;
      let payloadFileName: string | undefined;
      if (
        taskFilterMeta.requestStatus === "fulfilled" &&
        taskfilterPayload &&
        !("error" in taskfilterPayload)
      ) {
        payloadAuthorId = taskfilterPayload.authorId ?? "";
        payloadFileName = taskfilterPayload.fileName ?? "";

        dispatch(changeAuthorId({ authorId: payloadAuthorId }));
        dispatch(changeFileName({ fileName: payloadFileName }));
        // 初回表示時に検索フォームにtask_filtersテーブルの値を設定する。
        setFilterConditionAuthorId(payloadAuthorId);
        setFilterConditionFileName(payloadFileName);
      }

      // ソート条件
      const { meta: sortCriteriaMeta, payload: sortCriteriaPayload } =
        await dispatch(getSortColumnAsync());
      let direction: DirectionType = "ASC";
      let paramName: SortableColumnType = "JOB_NUMBER";
      if (
        sortCriteriaMeta.requestStatus === "fulfilled" &&
        sortCriteriaPayload &&
        !("error" in sortCriteriaPayload)
      ) {
        // ソート情報をローカルストレージから取得する
        const sortColumnValue = localStorage.getItem("sortCriteria") ?? "";
        if (sortColumnValue === "") {
          direction = sortCriteriaPayload.direction;
          paramName = sortCriteriaPayload.paramName;
        } else {
          // ソート情報をDirectionとParamNameに分割する
          const sortColumn = sortColumnValue?.split(",");
          const localStorageDirection = sortColumn[0].split(":")[1] ?? "";

          const localStorageParamName = sortColumn[1]?.split(":")[1] ?? "";

          // 正常なソート情報がローカルストレージに存在する場合はローカルストレージの情報を使用する
          direction = isDirectionType(localStorageDirection)
            ? localStorageDirection
            : sortCriteriaPayload.direction;
          paramName = isSortableColumnType(localStorageParamName)
            ? localStorageParamName
            : sortCriteriaPayload.paramName;

          dispatch(changeDirection({ direction }));
          dispatch(changeParamName({ paramName }));
        }
      }

      // タスク一覧を取得する
      if (isDirectionType(direction) && isSortableColumnType(paramName)) {
        dispatch(
          listTasksAsync({
            limit: LIMIT_TASK_NUM,
            offset: 0,
            filter,
            direction,
            paramName,
            authorId: payloadAuthorId,
            fileName: payloadFileName,
          })
        );
        dispatch(listTypistsAsync());
        dispatch(listTypistGroupsAsync());
      }
    })();
  }, [dispatch]);

  return (
    <>
      <BackupPopup isOpen={isBackupPopupOpen} onClose={onCloseBackupPopup} />
      <FilePropertyPopup
        isOpen={isFilePropertyPopupOpen}
        onClose={onCloseFilePropertyPopup}
      />
      <ChangeTranscriptionistPopup
        isOpen={isChangeTranscriptionistPopupOpen}
        onClose={onClosePopup}
      />
      <div className={styles.wrap}>
        <Header />
        <main className={styles.main}>
          <div className="">
            <div className={styles.pageHeader}>
              <h1 className={styles.pageTitle}>
                {t(getTranslationID("dictationPage.label.title"))}
              </h1>
            </div>

            <section className={styles.dictation}>
              <div>
                <DisPlayInfo />
                <ul className={styles.menuAction}>
                  <li>
                    <ul className={styles.tableFilter}>
                      <li>
                        {t(getTranslationID("dictationPage.label.filter"))}:
                      </li>
                      <li>
                        <label htmlFor="uploaded">
                          <input
                            id="uploaded"
                            type="checkbox"
                            value="flUploaded"
                            className={styles.formCheck}
                            checked={filterUploaded}
                            disabled={isLoading}
                            onChange={(e) => {
                              setFilterUploaded(e.target.checked);
                              updateFilter(
                                e.target.checked,
                                filterInProgress,
                                filterPending,
                                filterFinished,
                                filterBackup
                              );
                            }}
                          />
                          {t(getTranslationID("dictationPage.label.uploaded"))}
                        </label>
                      </li>
                      <li>
                        <label htmlFor="inProgress">
                          <input
                            id="inProgress"
                            type="checkbox"
                            value="flInProgress"
                            className={styles.formCheck}
                            checked={filterInProgress}
                            disabled={isLoading}
                            onChange={(e) => {
                              setFilterInProgress(e.target.checked);
                              updateFilter(
                                filterUploaded,
                                e.target.checked,
                                filterPending,
                                filterFinished,
                                filterBackup
                              );
                            }}
                          />
                          {t(
                            getTranslationID("dictationPage.label.inProgress")
                          )}
                        </label>
                      </li>
                      <li>
                        <label htmlFor="pending">
                          <input
                            id="pending"
                            type="checkbox"
                            value="flPending"
                            className={styles.formCheck}
                            checked={filterPending}
                            disabled={isLoading}
                            onChange={(e) => {
                              setFilterPending(e.target.checked);
                              updateFilter(
                                filterUploaded,
                                filterInProgress,
                                e.target.checked,
                                filterFinished,
                                filterBackup
                              );
                            }}
                          />
                          {t(getTranslationID("dictationPage.label.pending"))}
                        </label>
                      </li>
                      <li>
                        <label htmlFor="finished">
                          <input
                            id="finished"
                            type="checkbox"
                            value="flFinished"
                            className={styles.formCheck}
                            checked={filterFinished}
                            disabled={isLoading}
                            onChange={(e) => {
                              setFilterFinished(e.target.checked);
                              updateFilter(
                                filterUploaded,
                                filterInProgress,
                                filterPending,
                                e.target.checked,
                                filterBackup
                              );
                            }}
                          />
                          {t(getTranslationID("dictationPage.label.finished"))}
                        </label>
                      </li>
                      <li>
                        <label htmlFor="backup">
                          <input
                            id="backup"
                            type="checkbox"
                            value="flBackup"
                            className={styles.formCheck}
                            checked={filterBackup}
                            disabled={isLoading}
                            onChange={(e) => {
                              setFilterBackup(e.target.checked);
                              updateFilter(
                                filterUploaded,
                                filterInProgress,
                                filterPending,
                                filterFinished,
                                e.target.checked
                              );
                            }}
                          />
                          {t(getTranslationID("dictationPage.label.backup"))}
                        </label>
                      </li>
                    </ul>
                  </li>
                  <li className={styles.floatRight}>
                    <form
                      className={styles.searchBar}
                      onSubmit={(e) => requestSearch(e)}
                    >
                      <input
                        type="text"
                        placeholder={t(
                          getTranslationID("dictationPage.label.fileName")
                        )}
                        value={filterConditionFileName}
                        onChange={(e) => onChangeFilterConditionFileName(e)}
                        className={styles.searchInput}
                      />
                      <input
                        type="text"
                        placeholder={t(
                          getTranslationID("dictationPage.label.authorId")
                        )}
                        value={filterConditionAuthorId}
                        onChange={(e) => onChangeFilterConditionAuthorId(e)}
                        className={styles.searchInput}
                      />

                      {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */}
                      <button
                        type="submit"
                        className={`${styles.menuLink} ${!isLoading ? styles.isActive : ""
                          }`}
                      >
                        <img
                          src={searchIcon}
                          alt="search"
                          className={styles.menuIcon}
                        />
                        {t(getTranslationID("dictationPage.label.search"))}
                      </button>
                    </form>
                  </li>
                </ul>
                <div className={styles.tableWrap}>
                  <table className={`${styles.table} ${styles.dictation}`}>
                    <tr className={styles.tableHeader}>
                      <th className={styles.clm0}>{/** th is empty */}</th>
                      {displayColumn.JobNumber && (
                        <th className={styles.clm1}>
                          {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
                          <a
                            className={`${styles.hasSort} ${sortIconClass(
                              sortableParamName,
                              sortDirection,
                              SORTABLE_COLUMN.JobNumber
                            )}`}
                            onClick={() =>
                              updateSortColumn(SORTABLE_COLUMN.JobNumber)
                            }
                            style={{
                              pointerEvents: isLoading ? "none" : "auto",
                            }}
                          >
                            {t(
                              getTranslationID("dictationPage.label.jobNumber")
                            )}
                          </a>
                        </th>
                      )}
                      {displayColumn.Status && (
                        <th className={styles.clm2}>
                          {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
                          <a
                            className={`${styles.hasSort} ${sortIconClass(
                              sortableParamName,
                              sortDirection,
                              SORTABLE_COLUMN.Status
                            )}`}
                            onClick={() =>
                              updateSortColumn(SORTABLE_COLUMN.Status)
                            }
                            style={{
                              pointerEvents: isLoading ? "none" : "auto",
                            }}
                          >
                            {t(getTranslationID("dictationPage.label.status"))}
                          </a>
                        </th>
                      )}
                      {displayColumn.Priority && (
                        <th className={styles.clm3}>Priority</th>
                      )}
                      {displayColumn.Encryption && (
                        <th className={styles.clm4}>
                          {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
                          <a
                            className={`${styles.hasSort} ${sortIconClass(
                              sortableParamName,
                              sortDirection,
                              SORTABLE_COLUMN.Encryption
                            )}`}
                            onClick={() =>
                              updateSortColumn(SORTABLE_COLUMN.Encryption)
                            }
                            style={{
                              pointerEvents: isLoading ? "none" : "auto",
                            }}
                          >
                            {t(
                              getTranslationID("dictationPage.label.encryption")
                            )}
                          </a>
                        </th>
                      )}
                      {displayColumn.AuthorId && (
                        <th className={styles.clm5}>
                          {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
                          <a
                            className={`${styles.hasSort} ${sortIconClass(
                              sortableParamName,
                              sortDirection,
                              SORTABLE_COLUMN.AuthorId
                            )}`}
                            onClick={() =>
                              updateSortColumn(SORTABLE_COLUMN.AuthorId)
                            }
                            style={{
                              pointerEvents: isLoading ? "none" : "auto",
                            }}
                          >
                            {t(
                              getTranslationID("dictationPage.label.authorId")
                            )}
                          </a>
                        </th>
                      )}
                      {displayColumn.WorkType && (
                        <th className={styles.clm6}>
                          {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
                          <a
                            className={`${styles.hasSort} ${sortIconClass(
                              sortableParamName,
                              sortDirection,
                              SORTABLE_COLUMN.WorkType
                            )}`}
                            onClick={() =>
                              updateSortColumn(SORTABLE_COLUMN.WorkType)
                            }
                            style={{
                              pointerEvents: isLoading ? "none" : "auto",
                            }}
                          >
                            {t(
                              getTranslationID("dictationPage.label.workType")
                            )}
                          </a>
                        </th>
                      )}
                      {displayColumn.FileName && (
                        <th className={styles.clm7}>
                          {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
                          <a
                            className={`${styles.hasSort} ${sortIconClass(
                              sortableParamName,
                              sortDirection,
                              SORTABLE_COLUMN.FileName
                            )}`}
                            onClick={() =>
                              updateSortColumn(SORTABLE_COLUMN.FileName)
                            }
                            style={{
                              pointerEvents: isLoading ? "none" : "auto",
                            }}
                          >
                            {t(
                              getTranslationID("dictationPage.label.fileName")
                            )}
                          </a>
                        </th>
                      )}
                      {displayColumn.FileLength && (
                        <th className={styles.clm8}>
                          {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
                          <a
                            className={`${styles.hasSort} ${sortIconClass(
                              sortableParamName,
                              sortDirection,
                              SORTABLE_COLUMN.FileLength
                            )}`}
                            onClick={() =>
                              updateSortColumn(SORTABLE_COLUMN.FileLength)
                            }
                            style={{
                              pointerEvents: isLoading ? "none" : "auto",
                            }}
                          >
                            {t(
                              getTranslationID("dictationPage.label.fileLength")
                            )}
                          </a>
                        </th>
                      )}
                      {displayColumn.FileSize && (
                        <th className={styles.clm9}>
                          {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
                          <a
                            className={`${styles.hasSort} ${sortIconClass(
                              sortableParamName,
                              sortDirection,
                              SORTABLE_COLUMN.FileSize
                            )}`}
                            onClick={() =>
                              updateSortColumn(SORTABLE_COLUMN.FileSize)
                            }
                            style={{
                              pointerEvents: isLoading ? "none" : "auto",
                            }}
                          >
                            {t(
                              getTranslationID("dictationPage.label.fileSize")
                            )}
                          </a>
                        </th>
                      )}
                      {displayColumn.RecordingStartedDate && (
                        <th className={styles.clm10}>
                          {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
                          <a
                            className={`${styles.hasSort} ${sortIconClass(
                              sortableParamName,
                              sortDirection,
                              SORTABLE_COLUMN.RecordingStartedDate
                            )}`}
                            onClick={() =>
                              updateSortColumn(
                                SORTABLE_COLUMN.RecordingStartedDate
                              )
                            }
                            style={{
                              pointerEvents: isLoading ? "none" : "auto",
                            }}
                          >
                            {t(
                              getTranslationID(
                                "dictationPage.label.recordingStartedDate"
                              )
                            )}
                          </a>
                        </th>
                      )}
                      {displayColumn.RecordingFinishedDate && (
                        <th className={styles.clm11}>
                          {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
                          <a
                            className={`${styles.hasSort} ${sortIconClass(
                              sortableParamName,
                              sortDirection,
                              SORTABLE_COLUMN.RecordingFinishedDate
                            )}`}
                            onClick={() =>
                              updateSortColumn(
                                SORTABLE_COLUMN.RecordingFinishedDate
                              )
                            }
                            style={{
                              pointerEvents: isLoading ? "none" : "auto",
                            }}
                          >
                            {t(
                              getTranslationID(
                                "dictationPage.label.recordingFinishedDate"
                              )
                            )}
                          </a>
                        </th>
                      )}
                      {displayColumn.UploadDate && (
                        <th className={styles.clm12}>
                          {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
                          <a
                            className={`${styles.hasSort} ${sortIconClass(
                              sortableParamName,
                              sortDirection,
                              SORTABLE_COLUMN.UploadDate
                            )}`}
                            onClick={() =>
                              updateSortColumn(SORTABLE_COLUMN.UploadDate)
                            }
                            style={{
                              pointerEvents: isLoading ? "none" : "auto",
                            }}
                          >
                            {t(
                              getTranslationID("dictationPage.label.uploadDate")
                            )}
                          </a>
                        </th>
                      )}
                      {displayColumn.TranscriptionStartedDate && (
                        <th className={styles.clm13}>
                          {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
                          <a
                            className={`${styles.hasSort} ${sortIconClass(
                              sortableParamName,
                              sortDirection,
                              SORTABLE_COLUMN.TranscriptionStartedDate
                            )}`}
                            onClick={() =>
                              updateSortColumn(
                                SORTABLE_COLUMN.TranscriptionStartedDate
                              )
                            }
                            style={{
                              pointerEvents: isLoading ? "none" : "auto",
                            }}
                          >
                            {t(
                              getTranslationID(
                                "dictationPage.label.transcriptionStartedDate"
                              )
                            )}
                          </a>
                        </th>
                      )}
                      {displayColumn.TranscriptionFinishedDate && (
                        <th className={styles.clm14}>
                          {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
                          <a
                            className={`${styles.hasSort} ${sortIconClass(
                              sortableParamName,
                              sortDirection,
                              SORTABLE_COLUMN.TranscriptionFinishedDate
                            )}`}
                            onClick={() =>
                              updateSortColumn(
                                SORTABLE_COLUMN.TranscriptionFinishedDate
                              )
                            }
                            style={{
                              pointerEvents: isLoading ? "none" : "auto",
                            }}
                          >
                            {t(
                              getTranslationID(
                                "dictationPage.label.transcriptionFinishedDate"
                              )
                            )}
                          </a>
                        </th>
                      )}
                      {displayColumn.Transcriptionist && (
                        <th className={styles.clm15}>
                          {t(
                            getTranslationID(
                              "dictationPage.label.transcriptionist"
                            )
                          )}
                        </th>
                      )}
                      {displayColumn.Comment && (
                        <th className={styles.clm16}>
                          {t(getTranslationID("dictationPage.label.comment"))}
                        </th>
                      )}
                      {displayColumn.OptionItem1 && (
                        <th className={styles.op1}>
                          {t(
                            getTranslationID("dictationPage.label.optionItem1")
                          )}
                        </th>
                      )}
                      {displayColumn.OptionItem2 && (
                        <th className={styles.op2}>
                          {t(
                            getTranslationID("dictationPage.label.optionItem2")
                          )}
                        </th>
                      )}
                      {displayColumn.OptionItem3 && (
                        <th className={styles.op3}>
                          {t(
                            getTranslationID("dictationPage.label.optionItem3")
                          )}
                        </th>
                      )}
                      {displayColumn.OptionItem4 && (
                        <th className={styles.op4}>
                          {t(
                            getTranslationID("dictationPage.label.optionItem4")
                          )}
                        </th>
                      )}
                      {displayColumn.OptionItem5 && (
                        <th className={styles.op5}>
                          {t(
                            getTranslationID("dictationPage.label.optionItem5")
                          )}
                        </th>
                      )}
                      {displayColumn.OptionItem6 && (
                        <th className={styles.op6}>
                          {t(
                            getTranslationID("dictationPage.label.optionItem6")
                          )}
                        </th>
                      )}
                      {displayColumn.OptionItem7 && (
                        <th className={styles.op7}>
                          {t(
                            getTranslationID("dictationPage.label.optionItem7")
                          )}
                        </th>
                      )}
                      {displayColumn.OptionItem8 && (
                        <th className={styles.op8}>
                          {t(
                            getTranslationID("dictationPage.label.optionItem8")
                          )}
                        </th>
                      )}
                      {displayColumn.OptionItem9 && (
                        <th className={styles.op9}>
                          {t(
                            getTranslationID("dictationPage.label.optionItem9")
                          )}
                        </th>
                      )}
                      {displayColumn.OptionItem10 && (
                        <th className={styles.op10}>
                          {t(
                            getTranslationID("dictationPage.label.optionItem10")
                          )}
                        </th>
                      )}
                    </tr>
                    {(isChangeTranscriptionistPopupOpen || !isLoading) &&
                      tasks.length !== 0 &&
                      tasks.map((x) => (
                        <tr key={x.audioFileId}>
                          <td className={styles.clm0}>
                            <ul className={styles.menuInTable}>
                              <li>
                                {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
                                <a
                                  className={isNone ? styles.isDisable : ""}
                                  onClick={() => onPlayBack(x.audioFileId)}
                                >
                                  {t(
                                    getTranslationID(
                                      "dictationPage.label.playback"
                                    )
                                  )}
                                </a>
                              </li>
                              <li>
                                {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
                                <a onClick={() => onClickFileProperty(x)}>
                                  {t(
                                    getTranslationID(
                                      "dictationPage.label.fileProperty"
                                    )
                                  )}
                                </a>
                              </li>
                              <li>
                                {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
                                <a
                                  className={
                                    x.status !== STATUS.UPLOADED ||
                                      !(isAdmin || isAuthor)
                                      ? styles.isDisable
                                      : ""
                                  }
                                  onClick={() => {
                                    onChangeTranscriptionistPopupOpen(x);
                                  }}
                                >
                                  {t(
                                    getTranslationID(
                                      "dictationPage.label.changeTranscriptionist"
                                    )
                                  )}
                                </a>
                              </li>
                              <li>
                                {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
                                <a
                                  className={
                                    (x.status === STATUS.INPROGRESS ||
                                      x.status === STATUS.PENDING) &&
                                      (isAdmin || isTypist)
                                      ? ""
                                      : styles.isDisable
                                  }
                                  onClick={() => {
                                    onCancel(x.audioFileId);
                                  }}
                                >
                                  {t(
                                    getTranslationID(
                                      "dictationPage.label.cancelDictation"
                                    )
                                  )}
                                </a>
                              </li>
                              <li>
                                {/* タスクのステータスがFinishedかつ、ログインユーザーがAdminかTypistの場合、Change status to Pendingボタンを活性化する */}
                                {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
                                <a
                                  className={
                                    x.status === STATUS.FINISHED &&
                                      (isAdmin || isTypist)
                                      ? ""
                                      : styles.isDisable
                                  }
                                  onClick={() => {
                                    onReopen(x.audioFileId);
                                  }}
                                >
                                  {t(
                                    getTranslationID(
                                      "dictationPage.label.reopenDictation"
                                    )
                                  )}
                                </a>
                              </li>
                              <li>
                                {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
                                <a
                                  // タスクのステータスがInprogressまたはPending以外の場合、削除ボタンを活性化する
                                  className={
                                    isDeletableRole &&
                                      x.status !== STATUS.INPROGRESS &&
                                      x.status !== STATUS.PENDING
                                      ? ""
                                      : styles.isDisable
                                  }
                                  onClick={() => onDeleteTask(x.audioFileId)}
                                >
                                  {t(
                                    getTranslationID(
                                      "dictationPage.label.deleteDictation"
                                    )
                                  )}
                                </a>
                              </li>
                            </ul>
                          </td>
                          {displayColumn.JobNumber && (
                            <td className={styles.clm1}>{x.jobNumber}</td>
                          )}
                          {displayColumn.Status && (
                            <td className={styles.clm2}>
                              {(() => {
                                switch (x.status) {
                                  case STATUS.UPLOADED:
                                    return (
                                      <img src={uploaded} alt="Uploaded" />
                                    );
                                  case STATUS.PENDING:
                                    return <img src={pending} alt="Pending" />;
                                  case STATUS.FINISHED:
                                    return (
                                      <img src={finished} alt="Finished" />
                                    );
                                  case STATUS.INPROGRESS:
                                    return (
                                      <img src={inprogress} alt="InProgress" />
                                    );
                                  default:
                                    return <img src={backup} alt="Backup" />;
                                }
                              })()}
                              {x.status}
                            </td>
                          )}
                          {displayColumn.Priority && (
                            <td
                              className={styles.clm3}
                              style={{
                                color: x.priority === "01" ? "red" : undefined,
                              }}
                            >
                              {x.priority === "01"
                                ? PRIORITY.HIGH
                                : PRIORITY.NORMAL}
                            </td>
                          )}
                          {displayColumn.Encryption && (
                            <td className={styles.clm4}>
                              {x.isEncrypted ? (
                                <img src={lock} alt="encrypted" />
                              ) : (
                                <>-</>
                              )}
                            </td>
                          )}
                          {displayColumn.AuthorId && (
                            <td className={styles.clm5}>{x.authorId}</td>
                          )}
                          {displayColumn.WorkType && (
                            <td className={styles.clm6}>{x.workType}</td>
                          )}
                          {displayColumn.FileName && (
                            <td className={styles.clm7}>{x.fileName}</td>
                          )}
                          {displayColumn.FileLength && (
                            <td className={styles.clm8}>{x.audioDuration}</td>
                          )}
                          {displayColumn.FileSize && (
                            <td className={styles.clm9}>{x.fileSize}</td>
                          )}
                          {displayColumn.RecordingStartedDate && (
                            <td className={styles.clm10}>
                              {x.audioCreatedDate}
                            </td>
                          )}
                          {displayColumn.RecordingFinishedDate && (
                            <td className={styles.clm11}>
                              {x.audioFinishedDate}
                            </td>
                          )}
                          {displayColumn.UploadDate && (
                            <td className={styles.clm12}>
                              {x.audioUploadedDate}
                            </td>
                          )}
                          {displayColumn.TranscriptionStartedDate && (
                            <td className={styles.clm13}>
                              {x.transcriptionStartedDate}
                            </td>
                          )}
                          {displayColumn.TranscriptionFinishedDate && (
                            <td className={styles.clm14}>
                              {x.transcriptionFinishedDate}
                            </td>
                          )}
                          {displayColumn.Transcriptionist && (
                            <td
                              className={`${styles.txWsline} ${styles.clm15}`}
                            >
                              {x.assignees.map((a, i) => (
                                <>
                                  {a.typistName}
                                  {i !== x.assignees.length - 1 && <br />}
                                </>
                              ))}
                            </td>
                          )}
                          {displayColumn.Comment && (
                            <td className={styles.clm16}>{x.comment}</td>
                          )}
                          {displayColumn.OptionItem1 && (
                            <td className={styles.op1}>
                              {x.optionItemList[0].optionItemValue}
                            </td>
                          )}

                          {displayColumn.OptionItem2 && (
                            <td className={styles.op2}>
                              {x.optionItemList[1].optionItemValue}
                            </td>
                          )}
                          {displayColumn.OptionItem3 && (
                            <td className={styles.op3}>
                              {x.optionItemList[2].optionItemValue}
                            </td>
                          )}
                          {displayColumn.OptionItem4 && (
                            <td className={styles.op4}>
                              {x.optionItemList[3].optionItemValue}
                            </td>
                          )}
                          {displayColumn.OptionItem5 && (
                            <td className={styles.op5}>
                              {x.optionItemList[4].optionItemValue}
                            </td>
                          )}
                          {displayColumn.OptionItem6 && (
                            <td className={styles.op6}>
                              {x.optionItemList[5].optionItemValue}
                            </td>
                          )}
                          {displayColumn.OptionItem7 && (
                            <td className={styles.op7}>
                              {x.optionItemList[6].optionItemValue}
                            </td>
                          )}
                          {displayColumn.OptionItem8 && (
                            <td className={styles.op8}>
                              {x.optionItemList[7].optionItemValue}
                            </td>
                          )}
                          {displayColumn.OptionItem9 && (
                            <td className={styles.op9}>
                              {x.optionItemList[8].optionItemValue}
                            </td>
                          )}
                          {displayColumn.OptionItem10 && (
                            <td className={styles.op10}>
                              {x.optionItemList[9].optionItemValue}
                            </td>
                          )}
                        </tr>
                      ))}
                  </table>
                  {(isChangeTranscriptionistPopupOpen || !isLoading) &&
                    tasks.length === 0 && (
                      <p style={{ margin: "10px", textAlign: "center" }}>
                        {t(getTranslationID("common.message.listEmpty"))}
                      </p>
                    )}
                </div>
                {isLoading && (
                  <img
                    style={{ position: "sticky" }}
                    src={progress_activit}
                    className={styles.icLoading}
                    alt="Loading"
                  />
                )}
                {/** pagenation */}
                <div className={styles.pagenation}>
                  <nav className={styles.pagenationNav}>
                    <span className={styles.pagenationTotal}>{`${total} ${t(
                      getTranslationID("dictationPage.label.title")
                    )}`}</span>
                    {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
                    <a
                      className={`${!isLoading && currentPage !== 1 ? styles.isActive : ""
                        }`}
                      onClick={getFirstPage}
                    >
                      «
                    </a>
                    {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
                    <a
                      className={`${!isLoading && currentPage !== 1 ? styles.isActive : ""
                        }`}
                      onClick={getPrevPage}
                    >
                      ‹
                    </a>
                    {`${currentPage} of ${totalPage}`}
                    {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
                    <a
                      className={`${!isLoading && currentPage < totalPage
                          ? styles.isActive
                          : ""
                        }`}
                      onClick={getNextPage}
                    >
                      ›
                    </a>
                    {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
                    <a
                      className={`${!isLoading && currentPage < totalPage
                          ? styles.isActive
                          : ""
                        }`}
                      onClick={getLastPage}
                    >
                      »
                    </a>
                  </nav>
                </div>
                <ul className={`${styles.menuAction} ${styles.alignRight}`}>
                  <li className={styles.alignLeft}>
                    <a
                      // TODO: 将来的に正式なURLに変更する
                      href="https://download.omsystem.com/pages/odms_download/odms_cloud_desktop/en/"
                      className={`${styles.menuLink} ${styles.isActive}`}
                      target="_blank"
                      rel="noreferrer"
                    >
                      {t(getTranslationID("dictationPage.label.applications"))}
                      <img
                        src={open_in_new}
                        alt=""
                        className={styles.menuIcon}
                      />
                    </a>
                  </li>
                  <li>
                    {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
                    <a
                      onClick={onClickBackup}
                      className={`${styles.menuLink} ${isAdmin ? styles.isActive : ""
                        }`}
                    >
                      <img src={download} alt="" className={styles.menuIcon} />
                      {t(getTranslationID("dictationPage.label.fileBackup"))}
                    </a>
                  </li>
                </ul>
              </div>
            </section>
          </div>
        </main>
        <Footer />
      </div>
    </>
  );
};

export default DictationPage;
