All files / Rindu/components/RouterButtons RouterButtons.tsx

7.69% Statements 3/39
0% Branches 0/14
0% Functions 0/5
7.89% Lines 3/38

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 12419x   19x   19x                                                                                                                                                                                                                                              
import { ReactElement, useEffect, useRef, useState } from "react";
 
import { useRouter } from "next/router";
 
import { AngleBrackect } from "components/icons";
 
interface HistoryState {
  key: string;
}
 
export default function RouterButtons(): ReactElement {
  const router = useRouter();
  const [disableForwardButton, setDisableForwardButton] = useState(true);
  const [disableBackButton, setDisableBackButton] = useState(true);
  const userPosition = useRef(0);
 
  useEffect(() => {
    sessionStorage.setItem("history", JSON.stringify([]));
    userPosition.current = 0;
  }, []);
 
  useEffect(() => {
    const historyValue = (history.state as HistoryState).key;
    const historyFromSessionStorage = sessionStorage.getItem("history");
    const prevValue = historyFromSessionStorage
      ? (JSON.parse(historyFromSessionStorage) as string[])
      : [];
 
    Iif (
      userPosition.current !== 0 &&
      prevValue.at(userPosition.current - 1) &&
      historyValue === prevValue.at(userPosition.current - 1)
    ) {
      userPosition.current--;
      setDisableForwardButton(false);
      setDisableBackButton(userPosition.current === 0);
      return;
    }
    const newValue = [...prevValue, historyValue];
 
    Iif (newValue.length > 1) {
      setDisableBackButton(false);
    }
    setDisableForwardButton(prevValue[userPosition.current + 2] === undefined);
 
    Iif (
      prevValue.length > 1 &&
      prevValue[userPosition.current + 1] === historyValue
    ) {
      userPosition.current++;
      return;
    }
 
    sessionStorage.setItem("history", JSON.stringify(newValue));
 
    Iif (newValue.length === 1) return;
    userPosition.current++;
 
    Iif (
      newValue.length - 1 > userPosition.current &&
      historyValue !== newValue.at(userPosition.current)
    ) {
      setDisableForwardButton(true);
      const slicedPrevValue = prevValue.slice(0, userPosition.current);
      sessionStorage.setItem(
        "history",
        JSON.stringify([...slicedPrevValue, historyValue])
      );
    }
  }, [router.asPath]);
 
  return (
    <div>
      <button
        type="button"
        onClick={(e) => {
          e.stopPropagation();
          window.history.back();
        }}
        disabled={disableBackButton}
        className="back"
        aria-label="Go back"
      >
        <AngleBrackect angle="less" />
      </button>
      <button
        type="button"
        onClick={(e) => {
          e.stopPropagation();
          window.history.forward();
        }}
        disabled={disableForwardButton}
        className="forward"
        aria-label="Go forward"
      >
        <AngleBrackect angle="greater" />
      </button>
      <style jsx>{`
        div {
          display: flex;
        }
        button {
          display: flex;
          align-items: center;
          background-color: rgba(0, 0, 0, 0.7);
          border: none;
          border-radius: 50%;
          color: #fff;
          height: 32px;
          justify-content: center;
          position: relative;
          width: 32px;
          margin-right: 16px;
          cursor: pointer;
        }
        button:disabled {
          cursor: not-allowed;
          opacity: 0.6;
        }
      `}</style>
    </div>
  );
}