@fortawesome/free-brands-svg-icons#fab JavaScript Examples

The following examples show how to use @fortawesome/free-brands-svg-icons#fab. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: App.js    From lrc-staking-dapp with MIT License 6 votes vote down vote up
library.add(
  far,
  fas,
  faBookReader,
  faArrowLeft,
  faArrowRight,
  faQuestionCircle,
  faCopy,
  faSignOutAlt,
  faEdit,
  faAngleDown,
  faExternalLinkAlt,
  fab,
  faEthereum,
  faTwitter,
  faDiscord,
  faUnlink,
  faSearch,
  faFortAwesome,
  faExchangeAlt,
  faChartPie,
  faGlobe,
  faDonate,
  faDollarSign,
);
Example #2
Source File: Icon.js    From beautiful-react-ui with MIT License 5 votes vote down vote up
// adding fa dependencies
library.add(fas, fab);
Example #3
Source File: FontAwesomeIcon.jsx    From tonic-ui with MIT License 5 votes vote down vote up
library.add(fab);
Example #4
Source File: App.js    From littlelink-server with MIT License 5 votes vote down vote up
library.add(fab, fas, far);
Example #5
Source File: Fontawesome.js    From gatsby-personal-site-template with MIT License 5 votes vote down vote up
library.add(fab, fas)
Example #6
Source File: globalStyle.js    From personal-site with MIT License 5 votes vote down vote up
library.add(fab, faEnvelope, faPaperclip, faExternalLinkAlt, faFire, faCross)
Example #7
Source File: main.js    From minimal-portfolio with GNU General Public License v3.0 5 votes vote down vote up
library.add(fab)
Example #8
Source File: main.js    From CursedChrome with MIT License 5 votes vote down vote up
library.add(fab)
Example #9
Source File: App.js    From dmm-web-app with MIT License 5 votes vote down vote up
library.add(fab);
Example #10
Source File: globalStyle.js    From bartzalewski.com-v2 with MIT License 5 votes vote down vote up
library.add(fab, faEnvelope, faPaperclip, faExternalLinkAlt, faFire, faCross)
Example #11
Source File: index.js    From gatsby-markdown-personal-website with MIT License 5 votes vote down vote up
/* add any additional icon to the library */
library.add(fab, faLaptopCode, faDrawPolygon, faEdit, faEdit, faBullhorn, faMapMarkerAlt, faPhone, faPaperPlane);
Example #12
Source File: navbar.component.js    From hiring-system with GNU General Public License v3.0 5 votes vote down vote up
library.add(fab, faGithub);
Example #13
Source File: icon.js    From React-Messenger-App with MIT License 5 votes vote down vote up
library.add(fas, fab);
Example #14
Source File: layout.js    From blog with Apache License 2.0 5 votes vote down vote up
library.add(fab, fas);
Example #15
Source File: Help.js    From gitconvex with Apache License 2.0 4 votes vote down vote up
export default function Help() {
  library.add(fas, fab);

  const [currentVersion, setCurrentVersion] = useState("");
  const [availableUpdate, setAvailableUpdate] = useState("");
  const [showUpdatePane, setShowUpdatePane] = useState(false);
  const [isLatest, setIsLatest] = useState(false);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(false);

  useEffect(() => {
    setCurrentVersion(CURRENT_VERSION);
  }, []);

  function resetStates() {
    setShowUpdatePane(false);
    setLoading(false);
    setError(false);
    setAvailableUpdate("");
    setIsLatest(false);
  }

  const supportData = [
    {
      label: "reach via discord",
      link: "https://discord.gg/PSd2Cq9",
      icon: ["fab", "discord"],
      color: ["bg-indigo-400", "bg-indigo-500"],
    },
    {
      label: "reach via github",
      link: "https://github.com/neel1996/gitconvex-package/issues",
      icon: ["fab", "github"],
      color: ["bg-gray-800", "bg-gray-700"],
    },
    {
      label: "reach via twitter",
      link: "https://twitter.com/neeldev96",
      icon: ["fab", "twitter"],
      color: ["bg-blue-400", "bg-blue-600"],
    },
  ];

  const contributionData = [
    {
      label: "Gitconvex react project",
      link: "https://github.com/neel1996/gitconvex-ui",
      icon: ["fab", "react"],
      color: ["bg-blue-400"],
      ind: "",
    },
    {
      label: "Gitconvex Go project",
      link: "https://github.com/neel1996/gitconvex-server",
      icon: GoLogo,
      color: ["bg-gray-700"],
      ind: "go",
    },
  ];

  function checkUpdateHandler() {
    resetStates();
    setShowUpdatePane(true);
    setLoading(true);

    const githubEndpoint =
      "https://api.github.com/repos/neel1996/gitconvex/releases/latest";

    axios({
      url: githubEndpoint,
      method: "GET",
      headers: {
        Accept: "application/json",
      },
    })
      .then((res) => {
        const { tag_name } = res.data;
        setLoading(false);

        if (currentVersion === tag_name) {
          setIsLatest(true);
          setAvailableUpdate("");
        } else {
          setAvailableUpdate(tag_name);
        }
      })
      .catch((err) => {
        console.log(err);
      });
  }

  return (
    <div className="w-full h-auto overflow-auto">
      <div className="flex text-5xl text-gray-700 mx-6 my-auto align-middle items-center">
        <FontAwesomeIcon icon={["fas", "question-circle"]}></FontAwesomeIcon>
        <div className="my-5 mx-5 font-sans">Help and Support</div>
      </div>
      <div className="my-4 mx-10">
        <div className="text-2xl font-sans text-gray-900">
          Facing an issue or need any help?
        </div>
        <span className="text-xl text-gray-500 font-medium my-2">
          Before raising an issue, please make sure you have gone through the
        </span>
        <span className="font-mono text-xl mx-2 text-indigo-500 hover:text-indigo-600 hover:font-semibold cursor-pointer">
          <a
            href="https://github.com/neel1996/gitconvex/blob/master/DOCUMENTATION.md"
            target="_blank"
            rel="noopener noreferrer"
          >
            Documentation
          </a>
        </span>
      </div>

      <div className="support-feedback my-10 mx-10">
        <div className="text-2xl font-sans font-semibold">
          Support and Feedback
        </div>

        <div className="my-20 flex justify-center gap-10">
          {supportData.map((data) => {
            return (
              <div key={data.label}>
                <a href={data.link} target="_blank" rel="noopener noreferrer">
                  <div
                    className={`block mx-auto p-6 rounded-lg shadow-md ${data.color[0]} text-white text-center hover:${data.color[1]} hover:shadow-lg`}
                  >
                    <FontAwesomeIcon
                      size="4x"
                      icon={data.icon}
                    ></FontAwesomeIcon>
                    <div className="mx-3 font-sans font-semibold">
                      {data.label}
                    </div>
                  </div>
                </a>
              </div>
            );
          })}
        </div>
      </div>

      <div className="support-feedback my-10 mx-10">
        <div className="text-2xl font-sans font-semibold">Contribution</div>

        <div className="font-sans font-light border-b border-dashed text-center text-gray-600 my-5 break-normal">
          gitconvex is open source and please visit the repo if you are
          interested in contributing to the platform
        </div>
      </div>

      <div className="my-10 flex justify-center gap-10">
        {contributionData.map((data) => {
          return (
            <div key={data.label}>
              <a href={data.link} target="_blank" rel="noopener noreferrer">
                <div
                  className={`block mx-auto p-6 rounded-lg shadow-md ${data.color[0]} text-white text-center hover:shadow-xl`}
                  style={{
                    width: "250px",
                    height: "150px",
                  }}
                >
                  {data.ind !== "go" ? (
                    <FontAwesomeIcon
                      size="4x"
                      icon={data.icon}
                    ></FontAwesomeIcon>
                  ) : (
                    <img
                      src={GoLogo}
                      alt="go-logo"
                      className="text-center mx-auto items-center flex w-20"
                    ></img>
                  )}
                  <div className="mx-3 font-sans font-semibold">
                    {data.label}
                  </div>
                </div>
              </a>
            </div>
          );
        })}
      </div>

      <div className="fixed bottom-0 right-0 mr-6 mb-6 ">
        {showUpdatePane ? (
          <div
            className="bg-white shadow-md block border rounded-lg p-10 text-xl font-sans font-semibold right-0 bottom-0 fixed mr-5"
            style={{
              marginBottom: "120px",
            }}
          >
            <div
              className="relative text-gray-400 text-xl float-right cursor-pointer"
              style={{
                marginTop: "-40px",
                marginRight: "-25px",
                paddingRight: "-15px",
              }}
              onClick={() => {
                resetStates();
              }}
            >
              x
            </div>
            <div className="text-xl font-sans font-semibold text-gray-800 text-center">
              Current Version : {currentVersion}
            </div>
            {loading ? (
              <div className="text-gray-400 font-sans font-light">
                checking for updates...
              </div>
            ) : null}

            {isLatest ? (
              <div className="text-center text-sm font-sans font-light text-gray-600">
                You are using the latest version of gitconvex
              </div>
            ) : null}

            {error ? (
              <div className="text-red-600 font-sans">
                Cannot reach update validation server
              </div>
            ) : null}

            {availableUpdate ? (
              <div className="my-2">
                <div className="text-xl text-gray-800 text-left">
                  New update v{availableUpdate} available.
                </div>
                <div className="p-4 rounded-lg my-2 text-lg font-sans text-center bg-pink-500 text-white">
                  <a
                    href={`https://github.com/neel1996/gitconvex/releases/tag/${availableUpdate}`}
                    target="_blank"
                    rel="noopener noreferrer"
                  >
                    Get Update
                  </a>
                </div>
              </div>
            ) : null}
          </div>
        ) : null}

        <div
          className="bg-indigo-400 shadow-lg w-20 h-20 rounded-full text-center cursor-pointer hover:bg-indigo-300 border-8 border-indigo-200"
          onClick={() => {
            checkUpdateHandler();
          }}
        >
          <div className="flex justify-center items-center align-middle my-auto">
            <FontAwesomeIcon
              icon={["fas", "sync-alt"]}
              className="text-white mt-3"
            ></FontAwesomeIcon>
          </div>
          <div className="font-sans font-light text-indigo-100">Update</div>
        </div>
      </div>
    </div>
  );
}
Example #16
Source File: GitOperationComponent.js    From gitconvex with Apache License 2.0 4 votes vote down vote up
export default function GitOperationComponent(props) {
  library.add(fab);
  const { repoId } = props;
  const { stateChange } = props;

  const [gitTrackedFiles, setGitTrackedFiles] = useState([]);
  const [gitUntrackedFiles, setGitUntrackedFiles] = useState([]);

  const [action, setAction] = useState("");
  const [list, setList] = useState([]);
  const [viewReload, setViewReload] = useState(0);
  const [currentStageItem, setCurrentStageItem] = useState("");
  const [stageItems, setStagedItems] = useState([]);
  const [unStageFailed, setUnStageFailed] = useState(false);
  const [isLoading, setIsLoading] = useState(false);

  useEffect(() => {
    setIsLoading(true);
    setStagedItems([]);
    setCurrentStageItem("");

    const cancelToken = axios.CancelToken;
    const source = cancelToken.source();

    axios({
      url: globalAPIEndpoint,
      method: "POST",
      headers: {
        "Content-type": "application/json",
      },
      cancelToken: source.token,
      data: {
        query: `
            query {
                gitChanges(repoId: "${props.repoId}"){
                  gitUntrackedFiles
                  gitChangedFiles
                  gitStagedFiles
                }
            }
        `,
      },
    })
      .then((res) => {
        if (res.data.data) {
          var apiData = res.data.data.gitChanges;

          setGitTrackedFiles([...apiData.gitChangedFiles]);
          setGitUntrackedFiles([...apiData.gitUntrackedFiles]);
          setStagedItems([...apiData.gitStagedFiles]);

          const apiTrackedFiles = [...apiData.gitChangedFiles];
          const apiUnTrackedFiles = [...apiData.gitUntrackedFiles];

          let componentList = [];

          apiTrackedFiles &&
            apiTrackedFiles.forEach((item) => {
              if (item.split(",").length > 0) {
                const trackedItem = item.split(",")[1];
                componentList.push(trackedItem);
              }
            });

          apiUnTrackedFiles &&
            apiUnTrackedFiles.forEach((item) => {
              if (item) {
                item = item.replace("NO_DIR", "");
                item.split(",")
                  ? componentList.push(item.split(",").join(""))
                  : componentList.push(item);
              }
            });

          setList([...componentList]);
          setIsLoading(false);
        }
      })
      .catch((err) => {
        setIsLoading(false);
      });

    return () => {
      source.cancel();
    };
  }, [props.repoId, viewReload, currentStageItem]);

  const actionButtons = [
    {
      label: "Stage all changes",
      border: "border-indigo-300",
      text: "text-indigo-700",
      bg: "bg-indigo-50",
      hoverBg: "hover:bg-indigo-100",
      key: "stage",
    },
    {
      label: "Commit Changes",
      border: "border-green-300",
      text: "text-green-700",
      bg: "bg-green-50",
      hoverBg: "hover:bg-green-100",
      key: "commit",
    },
    {
      label: "Push to remote",
      border: "border-pink-300",
      text: "text-pink-700",
      bg: "bg-pink-50",
      hoverBg: "hover:bg-pink-100",
      key: "push",
    },
  ];

  const tableColumns = ["CHANGES", "FILE STATUS", "ACTION"];

  function stageGitComponent(stageItem, event) {
    let localViewReload = viewReload + 1;

    event.target.innerHTML = "Staging...";
    event.target.style.backgroundColor = "gray";
    event.target.disabled = true;

    axios({
      url: globalAPIEndpoint,
      method: "POST",
      data: {
        query: `
          mutation {
            stageItem(repoId: "${repoId}", item: "${stageItem}")
          }
        `,
      },
    })
      .then((res) => {
        setViewReload(localViewReload);

        if (res.data.data && !res.data.error) {
          if (res.data.data.stageItem === "ADD_ITEM_SUCCESS") {
            setCurrentStageItem(stageItem);
          }
        }
      })
      .catch((err) => {
        console.log(err);
        setViewReload(localViewReload);
      });
  }

  function getTableData() {
    let tableDataArray = [];

    let statusPill = (status) => {
      if (status === "M") {
        return (
          <div className="rounded w-3/4 mx-auto p-2 text-yellow-600 border-2 border-yellow-200 font-sans font-semibold bg-yellow-50">
            MODIFIED
          </div>
        );
      } else if (status === "D") {
        return (
          <div className="rounded w-3/4 mx-auto p-2 text-red-500 border-2 border-red-200 font-sans font-semibold bg-red-50">
            REMOVED
          </div>
        );
      } else {
        return (
          <div className="rounded w-3/4 mx-auto p-2 text-indigo-600 border-2 border-indigo-200 font-sans font-semibold bg-indigo-50">
            UNTRACKED
          </div>
        );
      }
    };

    let actionButton = (stageItem) => {
      return (
        <div
          className="w-3/4 rounded-md text-white mx-auto cursor-pointer p-2 bg-green-300 text-xl font-sans font-semibold text-center shadow-md hover:bg-green-400 hover:shadow-sm"
          onClick={(event) => {
            stageGitComponent(stageItem, event);
            setUnStageFailed(false);
          }}
          key={`add-btn-${stageItem}`}
        >
          ADD
        </div>
      );
    };

    gitTrackedFiles &&
      gitTrackedFiles.forEach((item) => {
        if (item.split(",").length > 0) {
          const trackedItem = item.split(",")[1];
          tableDataArray.push([
            trackedItem,
            statusPill(item.split(",")[0]),
            actionButton(trackedItem),
          ]);
        }
      });

    gitUntrackedFiles &&
      gitUntrackedFiles.forEach((item) => {
        if (item) {
          item = item.replace("NO_DIR", "");
          item.split(",")
            ? tableDataArray.push([
                item.split(",").join(""),
                statusPill("N"),
                actionButton(item.split(",").join("")),
              ])
            : tableDataArray.push([item, statusPill("N"), actionButton(item)]);
        }
      });
    return tableDataArray;
  }

  function getStagedFilesComponent() {
    function removeStagedItem(item, event) {
      let localViewReload = viewReload + 1;
      stateChange();

      event.target.innerHTML = "removing...";
      event.target.style.backgroundColor = "gray";
      event.target.disabled = true;

      axios({
        url: globalAPIEndpoint,
        method: "POST",
        data: {
          query: `
            mutation{
              removeStagedItem(repoId: "${repoId}", item: "${item}")
            }
          `,
        },
      })
        .then((res) => {
          setViewReload(localViewReload);
          if (res.data.data && !res.data.error) {
            if (res.data.data.removeStagedItem === "STAGE_REMOVE_SUCCESS") {
              let localStagedItems = stageItems;

              localStagedItems = localStagedItems.filter((filterItem) => {
                if (filterItem === item) {
                  return false;
                }
                return true;
              });

              setStagedItems([...localStagedItems]);
            } else {
              setUnStageFailed(true);
            }
          }
        })
        .catch((err) => {
          console.log(err);
          setViewReload(localViewReload);
          setUnStageFailed(true);
        });
    }

    function removeAllStagedItems(event) {
      let localViewReload = viewReload + 1;
      setStagedItems();
      stateChange();

      event.target.innerHTML = "Removing...";
      event.target.style.backgroundColor = "gray";
      event.target.disabled = true;

      axios({
        url: globalAPIEndpoint,
        method: "POST",
        data: {
          query: `
            mutation {
              removeAllStagedItem(repoId: "${repoId}")
            }
          `,
        },
      })
        .then((res) => {
          setViewReload(localViewReload + 1);
          if (res.data.data && !res.data.error) {
            if (
              res.data.data.removeAllStagedItem === "STAGE_ALL_REMOVE_SUCCESS"
            ) {
              setStagedItems([]);
            }
          }
        })
        .catch((err) => {
          console.log(err);
          setViewReload(localViewReload + 1);
        });
    }

    if (stageItems && stageItems.length > 0) {
      return (
        <div className="p-3 my-10 w-full mx-auto border border-blue-100 shadow-md rounded-lg">
          <div className="flex items-center justify-start my-6 w-full">
            <div className="text-4xl font-sans text-gray-800 mx-4">
              Staged Files
            </div>
            <div
              className="p-3 rounded-lg bg-red-400 text-white font-sans font-semibold text-xl cursor-pointer hover:bg-red-500"
              onClick={(event) => {
                removeAllStagedItems(event);
                setUnStageFailed(false);
              }}
            >
              Remove All Items
            </div>
          </div>
          {unStageFailed ? (
            <div className="my-4 mx-auto text-center shadow-md rounded p-4 border border-red-200 text-red-400 font-sans font-semibold">
              Remove item failed. Note that deleted files cannot be removed as a
              single entity. Use
              <i className="border-b border-gray-600 border-dashed mx-2">
                Remove All Items
              </i>
              to perform a complete git reset
            </div>
          ) : null}
          <div className="flex justify-between p-3 bg-indigo-400 rounded my-1 shadow">
            <div className="w-3/4 font-sans font-semibold text-xl text-center text-white border-r-2 border-indigo-300">
              STAGED FILE
            </div>
            <div className="w-1/4 font-sans font-semibold text-xl text-center text-white border-r-2 border-indigo-300">
              ACTION
            </div>
          </div>
          <div
            className="overflow-y-auto w-full my-2"
            style={{ height: "450px" }}
          >
            {stageItems.map((item) => {
              if (item) {
                return (
                  <div
                    className="flex items-center justify-between border-b p-1"
                    key={item}
                  >
                    <div className="w-3/4 pr-6 block px-1 border-r-2 border-gray-300">
                      <div className="git-changed-item overflow-x-auto w-full font-sans ml-1 text-gray-700">
                        {item}
                      </div>
                    </div>
                    <div className="w-1/4 mx-auto">
                      <div
                        className="rounded text-white cursor-pointer w-3/4 mx-auto p-2 my-1 bg-red-400 text-xl font-sans font-semibold text-center shadow-md hover:bg-red-500 hover:shadow-sm"
                        onClick={(event) => {
                          removeStagedItem(item, event);
                          setUnStageFailed(false);
                        }}
                        key={`remove-btn-${item}`}
                      >
                        REMOVE
                      </div>
                    </div>
                  </div>
                );
              }
              return null;
            })}
          </div>
        </div>
      );
    }
  }

  function actionComponent(action) {
    switch (action) {
      case "stage":
        if (list && list.length > 0) {
          return (
            <StageComponent
              repoId={repoId}
              stageComponents={list}
            ></StageComponent>
          );
        } else {
          return (
            <div className="w-1/2 mx-auto my-auto bg-gray-200 p-6 rounded-md">
              <div className="bg-white p-6 font-sans text-3xl font-light text-gray-500 border-b-4 border-dashed rounded-lg shadow-lg border-gray-500 text-center">
                No Changes for staging...
              </div>
            </div>
          );
        }
      case "commit":
        return <CommitComponent repoId={repoId}></CommitComponent>;
      case "push":
        return <PushComponent repoId={repoId}></PushComponent>;
      default:
        return null;
    }
  }

  function noChangesComponent() {
    return (
      <div className="mx-auto my-4 text-center font-sans font-light text-2xl shadow p-6 bg-pink-50 border-b-4 border-pink-400 rounded-lg text-pink-500 border-dashed">
        {!isLoading ? (
          <span>No files changes found in the repo.</span>
        ) : (
          <span className="text-gray-600">Fetching results...</span>
        )}
      </div>
    );
  }

  return (
    <>
      {action ? (
        <div
          className="w-full h-full fixed flex mx-auto my-auto overflow-auto top-0 bottom-0 left-0 right-0"
          id="operation-backdrop"
          style={{ background: "rgba(0,0,0,0.6)", zIndex: "99" }}
          onClick={(event) => {
            if (event.target.id === "operation-backdrop") {
              setAction("");
              let closeViewCount = viewReload + 1;
              setViewReload(closeViewCount);
              setStagedItems([]);
              setGitTrackedFiles([]);
              setGitUntrackedFiles([]);
              setList([]);
            }
          }}
        >
          {actionComponent(action)}
          <div
            className="w-14 h-14 mr-5 mt-6 rounded-full bg-red-500 text-white flex justify-center items-center shadow cursor-pointer fixed right-0 top-0"
            onClick={() => {
              setAction("");
              const localReload = viewReload + 1;
              setViewReload(localReload);
            }}
          >
            <FontAwesomeIcon
              className="flex text-center text-3xl my-auto"
              icon={["fas", "times"]}
            ></FontAwesomeIcon>
          </div>
        </div>
      ) : null}
      <div className="flex justify-between w-full mx-auto items-center my-10">
        {actionButtons.map((item) => {
          const { label, border, text, hoverBg, key, bg } = item;
          return (
            <div
              className={`mx-4 shadow-lg w-1/3 text-center font-sans text-xl font-semibold rounded-lg p-3 border-b-4 rounded-b-xl transition hover:shadow-sm cursor-pointer ${bg} ${border} ${text} ${hoverBg}`}
              key={key}
              onClick={() => setAction(key)}
            >
              {label}
            </div>
          );
        })}
      </div>
      {getTableData() && getTableData().length > 0 ? (
        <div className="w-full shadow-md p-2 rounded-lg border border-blue-50 overflow-auto py-4">
          <div className="flex items-center p-4 bg-gray-100 rounded">
            {tableColumns.map((column, index) => {
              return (
                <div
                  key={column}
                  className={`font-sans font-semibold text-xl text-center text-gray-600 border-r-2 border-white  ${
                    index === 0 ? "w-3/4" : "w-1/4"
                  }`}
                >
                  {column}
                </div>
              );
            })}
          </div>

          <div
            className="block w-full overflow-auto"
            style={{ height: "400px" }}
          >
            <div>
              {isLoading ? (
                <div className="text-center font-sans font-light p-4 text-2xl text-gray-600">
                  Loading modified file items...
                </div>
              ) : (
                <>
                  {getTableData() &&
                    getTableData().map((tableData, index) => {
                      return (
                        <div
                          className="flex justify-between items-center border-b p-2"
                          key={`tableItem-${index}`}
                        >
                          {tableData.map((data, index) => {
                            return (
                              <div
                                key={`${data}-${index}`}
                                title={index === 0 ? data : null}
                                className={`git-changed-item overflow-x-auto mx-auto font-sans text-gray-700 items-center align-middle my-auto border-r-2 border-gray-100 ${
                                  index === 0
                                    ? "w-3/4 text-left"
                                    : "w-1/4 text-center"
                                }`}
                              >
                                {data}
                              </div>
                            );
                          })}
                        </div>
                      );
                    })}
                </>
              )}
            </div>
          </div>
        </div>
      ) : (
        <>{noChangesComponent()}</>
      )}
      <>{stageItems && !isLoading ? getStagedFilesComponent() : null}</>
    </>
  );
}
Example #17
Source File: GitTrackedComponent.js    From gitconvex with Apache License 2.0 4 votes vote down vote up
export default function GitTrackedComponent(props) {
  library.add(fab);
  const [gitDiffFilesState, setGitDiffFilesState] = useState([]);
  const [gitUntrackedFilesState, setGitUntrackedFilesState] = useState([]);
  const [gitStagedFilesState, setGitStagedFilesState] = useState([]);
  const [topMenuItemState, setTopMenuItemState] = useState("File View");
  const topMenuItems = ["File View", "Git Difference", "Git Operations"];
  const [noChangeMarker, setNoChangeMarker] = useState(false);
  const [requestStateChange, setRequestChange] = useState(false);
  const [isLoading, setIsLoading] = useState(false);

  const { dispatch } = useContext(ContextProvider);

  const operationStateChangeHandler = () => {
    setRequestChange(true);
  };

  const memoizedGitDiffView = useMemo(() => {
    return <GitDiffViewComponent repoId={props.repoId}></GitDiffViewComponent>;
  }, [props.repoId]);

  const memoizedGitOperationView = useMemo(() => {
    return (
      <GitOperationComponent
        repoId={props.repoId}
        stateChange={operationStateChangeHandler}
      ></GitOperationComponent>
    );
  }, [props.repoId]);

  useEffect(() => {
    let apiEndPoint = globalAPIEndpoint;
    setRequestChange(false);
    setIsLoading(true);
    setNoChangeMarker(false);

    axios({
      url: apiEndPoint,
      method: "POST",
      headers: {
        "Content-type": "application/json",
      },
      data: {
        query: `
            query {
                gitChanges(repoId: "${props.repoId}"){
                  gitUntrackedFiles
                  gitChangedFiles
                  gitStagedFiles
                }
            }
        `,
      },
    })
      .then((res) => {
        if (res.data.data && !res.data.error) {
          var apiData = res.data.data.gitChanges;
          const {
            gitChangedFiles,
            gitUntrackedFiles,
            gitStagedFiles,
          } = apiData;

          if (
            (gitChangedFiles || gitUntrackedFiles) &&
            (gitChangedFiles.length > 0 || gitUntrackedFiles.length > 0)
          ) {
            setGitDiffFilesState([...gitChangedFiles]);
            setGitUntrackedFilesState([...gitUntrackedFiles]);
            setNoChangeMarker(false);
            setIsLoading(false);

            dispatch({
              type: GIT_TRACKED_FILES,
              payload: gitChangedFiles,
            });

            dispatch({
              type: GIT_ACTION_TRACKED_FILES,
              payload: [...gitChangedFiles],
            });

            dispatch({
              type: GIT_ACTION_UNTRACKED_FILES,
              payload: [...gitUntrackedFiles],
            });
          } else {
            setNoChangeMarker(true);
            if (gitStagedFiles.length === 0) {
              setIsLoading(false);
            }

            if (gitStagedFiles.length > 0) {
              setIsLoading(false);
              setGitStagedFilesState([...gitStagedFiles]);
            }
          }
        } else {
          setIsLoading(false);
        }
      })
      .catch((err) => {
        console.log(err);
        setIsLoading(false);
        setNoChangeMarker(true);
      });
  }, [props.repoId, dispatch, topMenuItemState, requestStateChange]);

  function diffPane() {
    var deletedArtifacts = [];
    var modifiedArtifacts = [];

    if (gitDiffFilesState && gitDiffFilesState.length > 0) {
      gitDiffFilesState.forEach((diffFile, index) => {
        var splitFile = diffFile.split(",");
        var flag = splitFile[0];
        var name = splitFile[1];
        var styleSelector = "p-1 ";
        switch (flag) {
          case "M":
            styleSelector += "text-yellow-900 bg-yellow-100";
            modifiedArtifacts.push(
              <div
                className="flex mx-auto justify-between items-center border-b border-white border-dotted"
                key={name}
              >
                <div
                  className={`git-changed-item ${styleSelector} w-11/12 p-3 overflow-x-auto`}
                  title={name}
                >
                  {name}
                </div>
                <div className="p-2 text-yellow-600 border-2 border-yellow-200 font-sans font-semibold bg-yellow-50 w-1/6 text-center">
                  MODIFIED
                </div>
              </div>
            );
            break;
          case "D":
            styleSelector += "text-red-900 bg-red-200";
            deletedArtifacts.push(
              <div
                className="flex mx-auto justify-between items-center border-b border-white border-dotted"
                key={name}
              >
                <div
                  className={`git-changed-item ${styleSelector} w-11/12 overflow-x-auto p-3`}
                  title={name}
                >
                  {name}
                </div>
                <div className="p-2 text-red-600 border-2 border-red-200 font-sans font-semibold bg-red-50 w-1/6 text-center">
                  DELETED
                </div>
              </div>
            );
            break;
          default:
            styleSelector += "text-indigo-900 bg-indigo-200";
            break;
        }
      });

      return (
        <>
          {modifiedArtifacts} {deletedArtifacts}
        </>
      );
    } else {
      if (isLoading) {
        return (
          <div className="mx-auto w-3/4 my-4 p-2 border-b-4 border-dashed border-pink-300 rounded-md text-center font-sans font-semibold text-xl">
            <span className="text-gray-400">
              Fetching results from the server...
            </span>
          </div>
        );
      }
    }
  }

  function untrackedPane() {
    let untrackedFiles = [];

    untrackedFiles = gitUntrackedFilesState
      .map((entry) => entry)
      .filter((item) => {
        if (item) {
          return true;
        }
        return false;
      });

    return untrackedFiles.map((entry, index) => {
      return (
        <div
          className="flex items-center border-b border-white border-dotted"
          key={`${entry}-${index}`}
        >
          <div
            className="git-changed-item p-3 text-indigo-900 bg-indigo-100 w-11/12 overflow-x-auto"
            title={entry}
          >
            {entry}
          </div>
          <div className="p-2 text-indigo-600 border-2 border-indigo-200 font-sans font-semibold bg-indigo-50 w-1/6 text-center">
            UNTRACKED
          </div>
        </div>
      );
    });
  }

  function menuComponent() {
    const FILE_VIEW = "File View";
    const GIT_DIFFERENCE = "Git Difference";
    const GIT_OPERATIONS = "Git Operations";

    switch (topMenuItemState) {
      case FILE_VIEW:
        if (noChangeMarker && gitStagedFilesState.length) {
          return (
            <div className="mx-auto bg-yellow-100 w-full my-2 p-3 border-dashed rounded-lg shadow border-b-4 border-yellow-400 text-xl font-sans font-semibold text-center text-yellow-600">
              No file changes to display. All changed have been staged
            </div>
          );
        } else if (noChangeMarker) {
          return (
            <div className="mx-auto bg-pink-100 w-full my-2 p-3 border-dashed rounded-lg shadow border-b-4 border-pink-400 text-xl font-sans font-semibold text-center text-pink-600">
              No file changes to display.
            </div>
          );
        } else {
          return (
            <div className="shadow-md rounded-sm my-2 block justify-center mx-auto border border-gray-100">
              {gitDiffFilesState && !isLoading ? (
                diffPane()
              ) : (
                <div className="rounded-lg shadow-md text-center text-indigo-700 text-2xl border-b-4 border-dashed border-indigo-300 p-4 font-sans">
                  Getting file based status...
                </div>
              )}
              {gitUntrackedFilesState && !isLoading ? untrackedPane() : null}
            </div>
          );
        }
      case GIT_DIFFERENCE:
        if (!noChangeMarker) {
          return memoizedGitDiffView;
        }
        break;
      case GIT_OPERATIONS:
        return memoizedGitOperationView;
      default:
        return (
          <div className="text-xl text-center"> Invalid Menu Selector! </div>
        );
    }
  }

  function presentChangeComponent() {
    return (
      <>
        <div className="flex mx-auto my-4 w-11/12 justify-around font-sans font-semibold rounded-sm shadow-md cursor-pointer">
          {topMenuItems.map((item) => {
            let styleSelector = "w-full py-3 px-1 text-center border-r";
            if (item === topMenuItemState) {
              styleSelector = `${styleSelector} bg-blue-100 text-blue-700 border-b border-blue-600`;
            } else {
              styleSelector = `${styleSelector} bg-blue-500 text-white`;
            }
            return (
              <div
                className={`${styleSelector} hover:text-blue-700 hover:bg-blue-100 hover:border-b-2 hover:border-blue-700`}
                key={item}
                onClick={() => {
                  setTopMenuItemState(item);
                  // Resetting branch error in top bar component to prevent the error banner from getting displayed after switching the menu
                  props.resetBranchError();
                }}
              >
                {item}
              </div>
            );
          })}
        </div>
      </>
    );
  }

  return (
    <>
      <style>
        {`
          .git-changed-item::-webkit-scrollbar {
            background: rgba(0, 0, 0, 0);
            width: 10px;
            height: 1px;
            border: solid 1px rgba(0, 0, 0, 0);
          }

          .git-changed-item::-webkit-scrollbar-thumb {
            background: rgba(0, 0, 0, 0);
          }
        `}
      </style>
      {noChangeMarker ? (
        <>
          <div className="w-11/12 mx-auto block my-6">
            {memoizedGitOperationView}
          </div>
          <div className="p-10 rounded-lg border-2 border-gray-100 w-3/4 mx-auto my-20">
            <div>
              <FontAwesomeIcon
                icon={["fab", "creative-commons-zero"]}
                className="flex text-7xl text-center text-gray-200 font-bold mx-auto h-full"
              ></FontAwesomeIcon>
            </div>
            <div className="block font-sans text-5xl text-gray-200 mx-auto text-center">
              "0" changes in repo
            </div>
          </div>
        </>
      ) : (
        <>
          {presentChangeComponent()}
          <div className="w-11/12 mx-auto block my-6"> {menuComponent()} </div>
        </>
      )}
    </>
  );
}
Example #18
Source File: RepoCard.js    From gitconvex with Apache License 2.0 4 votes vote down vote up
export default function RepoCard(props) {
  library.add(fab, fas);
  const { repoData } = props;

  const [repoFooterData, setRepoFooterData] = useState("");
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    setLoading(true);
    let repoId = props.repoData.id;
    const token = axios.CancelToken;
    const source = token.source();

    axios({
      url: globalAPIEndpoint,
      method: "POST",
      headers: {
        "Content-type": "application/json",
      },
      cancelToken: source.token,
      data: {
        query: `
          query 
          {
            gitRepoStatus(repoId:"${repoId}"){
              gitCurrentBranch
              gitTotalCommits
              gitTotalTrackedFiles
            }
          }
        `,
      },
    })
      .then((res) => {
        setLoading(false);
        setRepoFooterData(res.data.data.gitRepoStatus);
      })
      .catch((err) => {
        setLoading(false);
      });

    return () => {
      source.cancel();
    };
  }, [props.repoData.id]);

  const repoName = repoData.repoName;
  var avatar = "";

  if (repoName) {
    if (repoName.split(" ").length > 1) {
      let tempName = repoName.split(" ");
      avatar = tempName[0].substring(0, 1) + tempName[1].substring(0, 1);
      avatar = avatar.toUpperCase();
    } else {
      avatar = repoName.substring(0, 1).toUpperCase();
    }
  }

  return (
    <NavLink
      to={`/dashboard/repository/${repoData.id}`}
      className="mx-10 xl:w-96 lg:w-96 md:w-1/2 bg-indigo-400 border-gray-300 rounded-lg border cursor-pointer block my-6 p-6 shadow-md text-center hover:shadow-xl"
      key={repoData.repoName}
    >
      <div className="bg-indigo-300 rounded text-5xl my-2 py-5 px-10 shadow text-center text-white">
        {avatar}
      </div>
      <div className="border-indigo-300 border-dashed border-b-2 font-sans text-2xl my-4 pb-2 text-white">
        {repoData.repoName}
      </div>
      <div className="rounded-md flex justify-center my-2 mx-auto shadow-sm text-center align-middle w-full">
        {loading || !repoFooterData ? (
          <div className="block mx-auto w-full bg-white rounded">
            <div className="flex mx-auto my-6 text-center justify-center">
              <InfiniteLoader
                loadAnimation={loading || !repoFooterData}
              ></InfiniteLoader>
            </div>
          </div>
        ) : (
          <>
            <div className="bg-white border-indigo-300 flex items-center my-2 p-2 shadow-lg w-1/2 rounded-l-md">
              <FontAwesomeIcon
                className="my-auto"
                icon={["fas", "grip-lines"]}
              ></FontAwesomeIcon>
              <div className="items-center font-sans text-sm mx-2 text-center">
                {repoFooterData && repoFooterData.gitTotalCommits ? (
                  <>{repoFooterData.gitTotalCommits} Commits</>
                ) : (
                  <>0 Commits</>
                )}
              </div>
            </div>
            <div className="bg-white border-indigo-300 flex items-center my-2 p-2 shadow-lg w-1/2">
              <FontAwesomeIcon
                className="my-auto"
                icon={["fas", "file-alt"]}
              ></FontAwesomeIcon>
              <div className="items-center font-sans text-sm mx-2 text-center">
                {repoFooterData && repoFooterData.gitTotalTrackedFiles ? (
                  <>{repoFooterData.gitTotalTrackedFiles} Tracked Files</>
                ) : (
                  <>0 Tracked Files</>
                )}
              </div>
            </div>
            <div className="bg-white border-indigo-300 flex items-center my-2 p-2 shadow-lg w-1/2 rounded-r-md">
              <FontAwesomeIcon
                className="my-auto"
                icon={["fas", "code-branch"]}
              ></FontAwesomeIcon>
              <div className="items-center font-sans text-sm mx-2 text-center font-semibold">
                {repoFooterData && repoFooterData.gitCurrentBranch ? (
                  <>{repoFooterData.gitCurrentBranch}</>
                ) : (
                  <>No Branches Available</>
                )}
              </div>
            </div>
          </>
        )}
      </div>
    </NavLink>
  );
}
Example #19
Source File: FileExplorerComponent.js    From gitconvex with Apache License 2.0 4 votes vote down vote up
export default function FileExplorerComponent(props) {
  library.add(fab, fas);

  const [gitRepoFiles, setGitRepoFiles] = useState([]);
  const [codeViewToggle, setCodeViewToggle] = useState(false);
  const [gitFileBasedCommits, setGitFileBasedCommits] = useState([]);
  const [directoryNavigator, setDirectoryNavigator] = useState([]);
  const [codeViewItem, setCodeViewItem] = useState("");
  const [selectionIndex, setSelectionIndex] = useState(0);
  const [isEmpty, setIsEmpty] = useState(false);
  const [isLoading, setIsLoading] = useState(false);
  const [cwd, setCwd] = useState("");

  const { repoIdState } = props;

  const memoizedCodeFileViewComponent = useMemo(() => {
    return (
      <CodeFileViewComponent
        repoId={repoIdState}
        fileItem={codeViewItem}
        commitMessage={gitFileBasedCommits[selectionIndex]}
      ></CodeFileViewComponent>
    );
  }, [repoIdState, codeViewItem, gitFileBasedCommits, selectionIndex]);

  function filterNullCommitEntries(gitTrackedFiles, gitFileBasedCommit) {
    let localGitCommits = gitFileBasedCommit;
    let localTrackedFiles = gitTrackedFiles.filter((item, index) => {
      if (item) {
        return true;
      } else {
        localGitCommits[index] = "";
        return false;
      }
    });

    localGitCommits = localGitCommits.filter((commit) => commit);

    setGitRepoFiles([...localTrackedFiles]);
    setGitFileBasedCommits([...localGitCommits]);
  }

  useEffect(() => {
    const repoId = props.repoIdState;
    setIsEmpty(false);
    setIsLoading(true);
    axios({
      url: globalAPIEndpoint,
      method: "POST",
      headers: {
        "Content-type": "application/json",
      },
      data: {
        query: `
          query
          {
            gitFolderContent(repoId:"${repoId}", directoryName: ""){
              trackedFiles
              fileBasedCommits   
            }
          }
        `,
      },
    })
      .then((res) => {
        setIsLoading(false);
        const {
          trackedFiles,
          fileBasedCommits,
        } = res.data.data.gitFolderContent;

        if (trackedFiles.length === 0 || fileBasedCommits.length === 0) {
          setIsEmpty(true);
          return;
        }

        if (trackedFiles && fileBasedCommits) {
          filterNullCommitEntries(trackedFiles, fileBasedCommits);
        }
      })
      .catch((err) => {
        console.log(err);
        setIsLoading(false);
      });
  }, [props]);

  function directorySeparatorRemover(directoryPath) {
    if (directoryPath.match(/.\/./gi)) {
      directoryPath = directoryPath.split("/")[
        directoryPath.split("/").length - 1
      ];
    } else if (directoryPath.match(/[^\\]\\[^\\]/gi)) {
      directoryPath = directoryPath.split("\\")[
        directoryPath.split("\\").length - 1
      ];
    } else if (directoryPath.match(/.\\\\./gi)) {
      directoryPath = directoryPath.split("\\\\")[
        directoryPath.split("\\\\").length - 1
      ];
    }

    return directoryPath;
  }

  const fetchFolderContent = (
    directoryName,
    slicePosition,
    sliceIndicator,
    homeIndicator
  ) => {
    if (repoIdState) {
      setGitRepoFiles([]);
      setGitFileBasedCommits([]);
      let localDirNavigator = directoryNavigator;

      if (sliceIndicator) {
        let slicedDirectory = localDirNavigator.slice(0, slicePosition);
        if (slicedDirectory.length > 0) {
          directoryName = slicedDirectory.join("/") + "/" + directoryName;
        }
      }

      setCwd(directoryName);
      setIsLoading(true);

      axios({
        url: globalAPIEndpoint,
        method: "POST",
        headers: {
          "Content-type": "application/json",
        },
        data: {
          query: `
            query
            {
              gitFolderContent(repoId:"${repoIdState}", directoryName: "${directoryName}"){
                trackedFiles
                fileBasedCommits   
              }
            }
          `,
        },
      })
        .then((res) => {
          setIsLoading(false);
          if (res.data.data && !res.data.error) {
            const localFolderContent = res.data.data.gitFolderContent;

            filterNullCommitEntries(
              localFolderContent.trackedFiles,
              localFolderContent.fileBasedCommits
            );

            directoryName = directorySeparatorRemover(directoryName);

            if (homeIndicator) {
              setDirectoryNavigator([]);
              return;
            }

            if (directoryNavigator.length === 0) {
              setDirectoryNavigator([directoryName]);
            } else {
              if (
                sliceIndicator &&
                slicePosition < directoryNavigator.length - 1
              ) {
                const iterator =
                  directoryNavigator.length - (slicePosition + 1);

                for (let i = 0; i < iterator; i++) {
                  localDirNavigator.pop();
                }
                setDirectoryNavigator([...localDirNavigator]);
              } else {
                setDirectoryNavigator([...directoryNavigator, directoryName]);
              }
            }
          } else {
            setIsLoading(false);
            console.log(
              "ERROR: Error occurred while fetching the folder content!"
            );
          }
        })
        .catch((err) => {
          setIsLoading(false);
          if (err) {
            console.log(
              "ERROR: Error occurred while fetching the folder content!",
              err
            );
          }
        });
    }
  };

  const gitTrackedFileComponent = () => {
    var fileIcon;

    if (gitRepoFiles && gitRepoFiles.length > 0) {
      var formattedFiles = [];
      var directoryEntry = [];
      var fileEntry = [];

      gitRepoFiles.forEach(async (entry, index) => {
        const splitEntry = entry.split(":");

        if (splitEntry[1] && splitEntry[1].includes("directory")) {
          let directoryPath = directorySeparatorRemover(splitEntry[0]);

          directoryEntry.push(
            <div
              className="block w-full p-2 border-b border-gray-200"
              key={`directory-key-${uuid()}`}
            >
              <div className="flex cursor-pointer items-center">
                <div className="w-1/6">
                  <FontAwesomeIcon
                    icon={["fas", "folder"]}
                    className="font-sans text-xl"
                  ></FontAwesomeIcon>
                </div>
                <div
                  className="font-sans w-1/2 text-gray-600 text-xl mx-3 hover:text-indigo-400"
                  onClick={(event) => {
                    fetchFolderContent(splitEntry[0], 0, false);
                  }}
                >
                  {directoryPath}
                </div>

                <div className="w-3/5 p-2 overflow-hidden truncate rounded-lg mx-auto text-left bg-green-200 text-green-900">
                  {gitFileBasedCommits[index]}
                </div>
              </div>
            </div>
          );
        } else if (splitEntry[1] && splitEntry[1].includes("File")) {
          if (splitEntry[0] === "LICENSE") {
            fileIcon = require("../../../../../assets/icons/file_type_license.svg");
          } else {
            fileIcon = require("../../../../../assets/icons/" +
              getIconForFile(splitEntry[0]));
          }
          fileEntry.push(
            <div
              className="block w-full p-2 border-b border-gray-200"
              key={`file-key-${uuid()}`}
            >
              <div className="flex items-center align-middle cursor-pointer">
                <div className="w-1/6">
                  <img
                    src={fileIcon.default}
                    style={{
                      width: "26px",
                      filter: "grayscale(30%)",
                    }}
                    alt={fileIcon.default}
                  ></img>
                </div>
                <div
                  className="font-sans w-1/2 text-gray-700 text-xl mx-3 hover:text-indigo-400"
                  onClick={() => {
                    setSelectionIndex(index);
                    if (cwd === "" || cwd === "/") {
                      setCodeViewItem(splitEntry[0]);
                    } else {
                      setCodeViewItem(cwd + "/" + splitEntry[0]);
                    }
                    setCodeViewToggle(true);
                  }}
                >
                  {splitEntry[0]}
                </div>
                <div className="w-3/5 p-2 overflow-hidden truncate rounded-lg mx-auto text-left bg-indigo-200 text-indigo-900">
                  {gitFileBasedCommits[index]}
                </div>
              </div>
            </div>
          );
        }
      });

      formattedFiles.push(directoryEntry);
      formattedFiles.push(fileEntry);

      return (
        <div
          className="block mx-auto justify-center p-2"
          style={{
            color: "#79b8ff",
          }}
          key="repo-key"
        >
          <div className="flex w-full justify-around p-2 mx-auto pb-4 border-b border-blue-400">
            <div className="w-1/6"></div>
            <div className="w-2/4 font-sans font-semibold">
              File / Directory
            </div>
            <div className="w-2/4 font-sans font-semibold">Latest commit</div>
          </div>
          {formattedFiles}
        </div>
      );
    }
  };

  return (
    <>
      {isLoading ? (
        <>
          <div className="flex justify-center mx-auto my-2 w-3/4">
            <div className="w-full mx-auto text-2xl text-center font-sans font-semibold text-gray-700 border-b-2 border-dashed border-gray-400">
              Loading tracked files...
            </div>
          </div>
          <div className="flex mx-auto my-6 text-center justify-center">
            <InfiniteLoader
              loadAnimation={!gitRepoFiles.length}
            ></InfiniteLoader>
          </div>
        </>
      ) : (
        <>
          {codeViewToggle ? (
            <div
              className="fixed flex w-full h-full top-0 left-0 right-0 overflow-auto"
              id="code-view__backdrop"
              style={{ background: "rgba(0,0,0,0.5)", zIndex: 99 }}
              onClick={(event) => {
                if (event.target.id === "code-view__backdrop") {
                  setCodeViewToggle(false);
                }
              }}
            >
              <div
                className="w-14 h-14 mr-5 mt-6 rounded-full bg-red-500 text-white flex justify-center items-center shadow cursor-pointer fixed right-0 top-0"
                onClick={() => {
                  setCodeViewToggle(false);
                }}
              >
                <FontAwesomeIcon
                  className="flex text-center text-3xl my-auto"
                  icon={["fas", "times"]}
                ></FontAwesomeIcon>
              </div>
              <div className="w-full h-full mx-auto my-auto flex mt-4 mb-10">
                {memoizedCodeFileViewComponent}
              </div>
            </div>
          ) : null}

          <div>
            <div
              className="w-1/6 text-gray-600 cursor-pointer border-b-2 border-dashed text-center flex justify-center gap-4 p-3 rounded mx-6 myy-auto items-center align-middle text-xl"
              onClick={() => {
                fetchFolderContent("", 0, false, true);
              }}
            >
              <div>
                <FontAwesomeIcon icon={["fas", "home"]}></FontAwesomeIcon>
              </div>
              <div>Home</div>
              <div className="text-2xl font-sans text-blue-400">./</div>
            </div>
            {directoryNavigator && gitRepoFiles && gitRepoFiles.length > 0 ? (
              <div className="mx-6 p-3 flex font-sans justify-start items-center gap-4">
                <div
                  className="flex p-4 w-3/4 gap-4 items-center break-words overflow-x-auto"
                  id="repoFolderNavigator"
                >
                  {directoryNavigator.map((item, index) => {
                    return (
                      <div
                        className="flex items-center justify-start gap-2"
                        key={item + "-" + index}
                      >
                        <div
                          className={`${
                            index !== directoryNavigator.length - 1
                              ? "text-blue-400 cursor-pointer font-semibold hover:text-blue-500 underline"
                              : ""
                          } text-xl`}
                          onClick={() => {
                            if (index !== directoryNavigator.length - 1) {
                              fetchFolderContent(item, index, true);
                            }
                          }}
                        >
                          {item}
                        </div>
                        <div>/</div>
                      </div>
                    );
                  })}
                </div>
              </div>
            ) : null}

            <div className="block w-11/12 my-6 mx-auto justify-center p-6 rounded-lg bg-white shadow overflow-auto border">
              {!isEmpty ? (
                gitTrackedFileComponent()
              ) : (
                <div className="flex w-3/4 gap-4 mx-auto items-center align-middle justify-center rounded-lg text-gray-500 text-center border-b-4 text-2xl border-dashed p-1 border-gray-300">
                  <div>
                    <FontAwesomeIcon icon={["fas", "unlink"]}></FontAwesomeIcon>
                  </div>
                  <div>No Tracked Files in the directory!</div>
                </div>
              )}
            </div>
          </div>
        </>
      )}
    </>
  );
}
Example #20
Source File: CommitLogComponent.js    From gitconvex with Apache License 2.0 4 votes vote down vote up
export default function RepositoryCommitLogComponent(props) {
  library.add(fab, fas, far);

  const [commitLogs, setCommitLogs] = useState([]);
  const [isCommitEmpty, setIsCommitEmpty] = useState(false);
  const [skipLimit, setSkipLimit] = useState(0);
  const [totalCommitCount, setTotalCommitCount] = useState(0);
  const [isLoading, setIsLoading] = useState(false);
  const [excessCommit, setExcessCommit] = useState(false);
  const [searchKey, setSearchKey] = useState("");
  const [viewReload, setViewReload] = useState(0);
  const [searchWarning, setSearchWarning] = useState(false);
  const [referenceCommitHash, setReferenceCommitHash] = useState("");

  const searchRef = useRef();
  const searchOptionRef = useRef();

  const debouncedSearch = useRef(
    debounce(commitSearchHandler, 1500, { maxWait: 2000 })
  ).current;

  const searchOptions = ["Commit Hash", "Commit Message", "User"];

  useEffect(() => {
    setIsLoading(true);
    setSearchWarning(false);

    axios({
      url: globalAPIEndpoint,
      method: "POST",
      data: {
        query: `
            query {
              gitCommitLogs(repoId: "${props.repoId}", referenceCommit: "") {
                  totalCommits
                  commits{
                      commitTime
                      hash
                      author
                      commitMessage
                      commitFilesCount
                  }  
              }
          }
          `,
      },
    })
      .then((res) => {
        setIsLoading(false);

        if (res.data.data) {
          const { commits, totalCommits } = res.data.data.gitCommitLogs;

          if (totalCommits <= 10) {
            setExcessCommit(false);
          } else {
            setExcessCommit(true);
          }

          setTotalCommitCount(totalCommits);
          if (commits && commits.length > 0) {
            setCommitLogs([...commits]);
            const len = commits.length;
            setReferenceCommitHash(commits[len - 1].hash);
          } else {
            setIsCommitEmpty(true);
          }
        }
      })
      .catch((err) => {
        setIsLoading(false);

        if (err) {
          setIsCommitEmpty(true);
          console.log(err);
        }
      });
  }, [props, viewReload]);

  function fetchCommitLogs() {
    setIsLoading(true);
    setSearchWarning(false);

    let localLimit = 0;
    localLimit = skipLimit + 10;

    setSkipLimit(localLimit);

    axios({
      url: globalAPIEndpoint,
      method: "POST",
      data: {
        query: `
          query{
            gitCommitLogs(repoId:"${props.repoId}", referenceCommit: "${referenceCommitHash}"){
                totalCommits
                commits{
                    commitTime
                    hash
                    author
                    commitMessage
                    commitFilesCount
                }  
            }
        }
          `,
      },
    })
      .then((res) => {
        setIsLoading(false);

        if (totalCommitCount - localLimit <= 10) {
          setExcessCommit(false);
        }

        if (res.data.data) {
          const { commits, totalCommits } = res.data.data.gitCommitLogs;
          setTotalCommitCount(totalCommits);
          if (commits && commits.length > 0) {
            setCommitLogs([...commitLogs, ...commits]);

            const len = commits.length;
            setReferenceCommitHash(commits[len - 1].hash);
          } else {
            setIsCommitEmpty(true);
          }
        }
      })
      .catch((err) => {
        setIsLoading(false);

        if (err) {
          setIsCommitEmpty(true);
          console.log(err);
        }
      });
  }

  function fetchCommitFiles(commitHash, arrowTarget) {
    const parentDivId = `commitLogCard-${commitHash}`;
    const targetDivId = `commitFile-${commitHash}`;

    const targetDiv = document.createElement("div");
    targetDiv.id = targetDivId;

    const parentDiv = document.getElementById(parentDivId);
    parentDiv.append(targetDiv);

    const unmountHandler = () => {
      ReactDOM.unmountComponentAtNode(
        document.getElementById("closeBtn-" + commitHash)
      );
      ReactDOM.unmountComponentAtNode(document.getElementById(targetDivId));
      arrowTarget.classList.remove("hidden");
    };

    ReactDOM.render(
      <CommitLogFileCard
        repoId={props.repoId}
        commitHash={commitHash}
        unmountHandler={unmountHandler}
      ></CommitLogFileCard>,
      document.getElementById(targetDivId)
    );

    const closeArrow = (
      <div
        className="text-center mx-auto text-3xl font-sans font-light text-gray-600 items-center align-middle cursor-pointer"
        onClick={(event) => {
          unmountHandler();
        }}
      >
        <FontAwesomeIcon icon={["fas", "angle-up"]}></FontAwesomeIcon>
      </div>
    );

    const closeBtn = document.createElement("div");
    const closeBtnId = "closeBtn-" + commitHash;
    closeBtn.id = closeBtnId;
    parentDiv.append(closeBtn);

    ReactDOM.render(closeArrow, document.getElementById(closeBtnId));
  }

  function commitSearchHandler() {
    setIsLoading(true);
    setTotalCommitCount(0);
    setCommitLogs([]);
    const searchQuery = searchRef.current.value;
    let searchOption = "";

    switch (searchOptionRef.current.value) {
      case "Commit Hash":
        searchOption = "hash";
        break;
      case "Commit Message":
        searchOption = "message";
        break;
      case "User":
        searchOption = "user";
        break;
      default:
        searchOption = "message";
        break;
    }

    if (searchQuery) {
      axios({
        url: globalAPIEndpoint,
        method: "POST",
        data: {
          query: `
            query{
              searchCommitLogs(repoId:"${props.repoId}",searchType:"${searchOption}",searchKey:"${searchQuery}"){
                hash
                author
                commitTime
                commitMessage
                commitFilesCount
              }
            }
          `,
        },
      })
        .then((res) => {
          if (res.data.data) {
            const { searchCommitLogs } = res.data.data;
            if (searchCommitLogs && searchCommitLogs.length > 0) {
              setIsCommitEmpty(false);
              setExcessCommit(false);
              setCommitLogs([...searchCommitLogs]);
              setTotalCommitCount(searchCommitLogs.length);
              setIsLoading(false);
            } else {
              setIsCommitEmpty(true);
              setCommitLogs([]);
              setTotalCommitCount(0);
              setIsLoading(false);
              setSearchWarning(true);
            }
          }
        })
        .catch((err) => {
          console.log(err);
          setIsLoading(false);
          setCommitLogs([]);
        });
    } else {
      setViewReload(viewReload + 1);
      setIsLoading(false);
    }
  }

  function fallBackComponent(message) {
    return (
      <div className="p-6 rounded-md shadow-sm block justify-center mx-auto my-auto w-3/4 h-full text-center text-2xl text-indigo-500">
        <div className="flex w-full h-full mx-auto my-auto">
          <div className="block my-auto mx-auto bg-white w-full p-6 rounded-lg shadow">
            <div className="text-2xl text-center font-sans font-semibold text-indigo-800 border-b-2 border-dashed border-indigo-500 p-1">
              {message}
            </div>
            {searchWarning ? (
              <div className="my-4 mx-auto rounded shadow p-4 text-center font-sans text-yellow-800 font-light bg-yellow-50 border-b-4  border-dashed border-yellow-200 text-md">
                Make sure if you are searching with the right category and the
                right search query
              </div>
            ) : null}
            {isLoading ? (
              <div className="flex mx-auto my-6 text-center justify-center">
                <InfiniteLoader loadAnimation={isLoading}></InfiniteLoader>
              </div>
            ) : null}
          </div>
        </div>
      </div>
    );
  }

  function searchbarComponent() {
    return (
      <div className="my-4 w-full rounded-lg bg-white shadow-inner flex gap-4 justify-between items-center">
        <select
          defaultValue="default-search"
          id="searchOption"
          ref={searchOptionRef}
          className="w-1/4 flex p-4 items-center bg-indigo-400 text-white cursor-pointer rounded-l-md text-lg font-sans font-semibold outline-none"
        >
          <option value="default-search" hidden disabled>
            Search for...
          </option>
          {searchOptions.map((item) => {
            return (
              <option key={item} value={item}>
                {item}
              </option>
            );
          })}
        </select>

        <div className="w-3/4 rounded-r-md">
          <input
            ref={searchRef}
            type="text"
            className="w-5/6 outline-none text-lg font-light font-sans"
            placeholder="What are you looking for?"
            value={searchKey}
            onChange={(event) => {
              setSearchKey(event.target.value);
              debouncedSearch();
            }}
          />
        </div>
        <div
          className="w-20 bg-gray-200 p-3 mx-auto my-auto text-center rounded-r-lg hover:bg-gray-400 cursor-pointer"
          onClick={() => {
            commitSearchHandler();
          }}
        >
          <FontAwesomeIcon
            icon={["fas", "search"]}
            className="text-3xl text-gray-600"
          ></FontAwesomeIcon>
        </div>
      </div>
    );
  }

  return (
    <>
      {searchbarComponent()}
      {(isCommitEmpty || !commitLogs || !totalCommitCount) && !isLoading
        ? fallBackComponent("No Commit Logs found")
        : null}
      {commitLogs &&
        commitLogs.map((commit) => {
          const {
            hash,
            author,
            commitTime,
            commitMessage,
            commitFilesCount,
          } = commit;

          let commitRelativeTime = relativeCommitTimeCalculator(commitTime);
          const formattedCommitTime = format(
            new Date(commitTime),
            "MMMM dd, yyyy"
          );

          return (
            <div
              id={`commitLogCard-${hash}`}
              className="p-6 rounded-lg block shadow-md justify-center mx-auto my-4 bg-white w-full border-b-8 border-indigo-400"
              key={hash}
            >
              <div className="flex justify-between text-indigo-400">
                <div className="text-2xl font-sans mx-auto">
                  <FontAwesomeIcon
                    icon={["fas", "calendar-alt"]}
                  ></FontAwesomeIcon>
                  <span className="border-b-2 border-dashed mx-2">
                    {formattedCommitTime}
                  </span>
                </div>
                <div className="h-auto p-1 border-r"></div>
                <div className="text-2xl font-sans mx-auto">
                  <FontAwesomeIcon
                    icon={["fab", "slack-hash"]}
                  ></FontAwesomeIcon>
                  <span className="border-b-2 border-dashed mx-2">
                    {hash.substring(0, 7)}
                  </span>
                </div>
                <div className="h-auto p-1 border-r"></div>
                <div className="text-2xl font-sans mx-auto">
                  <FontAwesomeIcon
                    icon={["fas", "user-ninja"]}
                  ></FontAwesomeIcon>
                  <span className="border-b-2 border-dashed mx-2 truncate">
                    {author}
                  </span>
                </div>
              </div>

              <div className="font-sans font-semibold text-2xl my-4 text-gray-500 p-3 flex justify-evenly items-center">
                <div className="w-1/8">
                  <FontAwesomeIcon
                    icon={["fas", "code"]}
                    className="text-3xl"
                  ></FontAwesomeIcon>
                </div>
                <div className="w-5/6 mx-3">{commitMessage}</div>
              </div>

              <div className="w-11/12 flex justify-between mx-auto mt-4 font-sans text-xl text-gray-500">
                <div className="w-1/3 flex justify-center my-auto items-center align-middle">
                  <div>
                    <FontAwesomeIcon icon={["far", "clock"]}></FontAwesomeIcon>
                  </div>
                  <div className="mx-2 border-dashed border-b-4">
                    {commitRelativeTime}
                  </div>
                </div>
                <div
                  className="w-1/3 flex justify-around my-auto font-sans text-3xl font-light pt-10 cursor-pointer text-gray-500"
                  onClick={(event) => {
                    if (commitFilesCount) {
                      event.currentTarget.classList.add("hidden");
                      fetchCommitFiles(hash, event.currentTarget);
                    }
                  }}
                >
                  {commitFilesCount ? (
                    <FontAwesomeIcon
                      icon={["fas", "angle-down"]}
                    ></FontAwesomeIcon>
                  ) : (
                    <FontAwesomeIcon
                      icon={["fas", "dot-circle"]}
                      className="text-xl text-gray-200"
                    ></FontAwesomeIcon>
                  )}
                </div>
                <div className="w-1/3 flex justify-center my-auto items-center align-middle">
                  <div>
                    <FontAwesomeIcon
                      icon={["far", "plus-square"]}
                    ></FontAwesomeIcon>
                  </div>
                  <div className="mx-2 border-dashed border-b-4">
                    {commitFilesCount ? (
                      `${commitFilesCount} Files`
                    ) : (
                      <span className="text-gray-500">No Changed Files</span>
                    )}
                  </div>
                </div>
              </div>
            </div>
          );
        })}
      {excessCommit ? (
        <div
          className="fixed flex bottom-0 right-0 w-16 h-16 mx-auto p-6 rounded-full shadow-md text-center bg-indigo-500 text-white text-2xl mb-6 mr-6 cursor-pointer"
          title="Click to load commits"
          onClick={() => {
            if (commitLogs.length > skipLimit) {
              fetchCommitLogs();
            }
          }}
        >
          <FontAwesomeIcon
            icon={["fas", "angle-double-down"]}
          ></FontAwesomeIcon>
        </div>
      ) : null}
      {isLoading && totalCommitCount ? (
        <div className="my-4 rounded-lg p-3 bg-gray-100 text-lg font-semibold font-sans text-gray-700 text-center mx-auto">
          Loading {totalCommitCount - skipLimit} more commits...
          <div className="flex mx-auto my-6 text-center justify-center">
            <InfiniteLoader loadAnimation={isLoading}></InfiniteLoader>
          </div>
        </div>
      ) : null}
      {!isCommitEmpty && commitLogs.length === 0 && isLoading
        ? fallBackComponent("Loading commits...")
        : null}
    </>
  );
}
Example #21
Source File: RepoLeftPaneComponent.js    From gitconvex with Apache License 2.0 4 votes vote down vote up
export default function RepoLeftPaneComponent(props) {
  library.add(fab, fas);

  let {
    gitRemoteHost,
    gitRemoteData,
    isMultiRemote,
    multiRemoteCount,
    showCommitLogsView,
    actionTrigger,
  } = props;

  useEffect(() => {}, [props]);

  const getRemoteLogo = () => {
    let remoteLogo = "";
    if (gitRemoteHost.match(/github/i)) {
      remoteLogo = (
        <FontAwesomeIcon
          icon={["fab", "github"]}
          className="text-4xl text-center text-pink-500"
        ></FontAwesomeIcon>
      );
    } else if (gitRemoteHost.match(/gitlab/i)) {
      remoteLogo = (
        <FontAwesomeIcon
          icon={["fab", "gitlab"]}
          className="text-4xl text-center text-pink-400"
        ></FontAwesomeIcon>
      );
    } else if (gitRemoteHost.match(/bitbucket/i)) {
      remoteLogo = (
        <FontAwesomeIcon
          icon={["fab", "bitbucket"]}
          className="text-4xl text-center text-pink-400"
        ></FontAwesomeIcon>
      );
    } else if (gitRemoteHost.match(/codecommit/i)) {
      remoteLogo = (
        <FontAwesomeIcon
          icon={["fab", "aws"]}
          className="text-4xl text-center text-pink-400"
        ></FontAwesomeIcon>
      );
    } else {
      remoteLogo = (
        <FontAwesomeIcon
          icon={["fab", "git-square"]}
          className="text-4xl text-center text-pink-400"
        ></FontAwesomeIcon>
      );
    }

    return remoteLogo;
  };

  const remoteUrl = () => {
    let remoteData = "";
    if (gitRemoteData) {
      if (gitRemoteData.match(/(^https)/gi)) {
        remoteData = (
          <a href={gitRemoteData} target="_blank" rel="noopener noreferrer">
            {gitRemoteData}
          </a>
        );
      } else {
        remoteData = <>{gitRemoteData}</>;
      }
    } else {
      remoteData = " ";
    }
    return remoteData;
  };

  return (
    <>
      {props.received ? (
        <div className="border-gray-300 rounded-md border-dotted border-2 block my-6 mx-auto p-1 shadow-sm w-11/12 xl:w-1/2 lg:w-3/4 md:w-11/12 sm:w-11/12">
          <div className="block mx-auto my-6">
            <div className="flex items-center justify-evenly">
              <div className="text-lg text-gray-600 w-1/4">Remote Host</div>
              <div className="flex justify-around items-center align-middle w-1/2">
                <div className="w-3/4 shadow rounded-md border-dashed border cursor-pointer flex items-center justify-center my-auto p-4 align-middle">
                  {gitRemoteHost ? (
                    <div className="mx-2">{getRemoteLogo()}</div>
                  ) : null}
                  <div
                    className={`${
                      gitRemoteHost !== "No Remote Host Available"
                        ? "text-xl border-gray-300 border-dashed border-b text-center text-gray-800 w-3/4"
                        : "text-base font-sans font-light text-gray-600 text-center"
                    }`}
                  >
                    {gitRemoteHost}
                  </div>
                </div>
                <div className="w-1/4">
                  <div
                    id="addRemote"
                    className="rounded-full cursor-pointer items-center h-10 text-2xl mx-auto shadow text-center text-white align-middle w-10 bg-indigo-400 hover:bg-indigo-500"
                    onMouseEnter={(event) => {
                      let popUp = document.createElement("div");
                      popUp.className =
                        "text-gray-600 bg-white border-gray-300 p-2 rounded w-40 text-center border text-sm mt-2 mb-2 -ml-10 absolute";
                      popUp.innerHTML = `Click here to configure remote repo`;
                      event.currentTarget.insertAdjacentElement(
                        "afterend",
                        popUp
                      );
                    }}
                    onMouseLeave={(event) => {
                      if (event.currentTarget.parentNode.children[1]) {
                        event.currentTarget.parentNode.children[1].remove();
                      }
                    }}
                    onClick={() => {
                      actionTrigger(actionType.ADD_REMOTE_REPO);
                    }}
                  >
                    <FontAwesomeIcon
                      icon={faTools}
                      className="text-xl text-center text-white"
                    ></FontAwesomeIcon>
                  </div>
                </div>
              </div>
            </div>

            <div className="remote  flex justify-evenly my-4">
              <div className="text-lg text-gray-600 w-1/4">
                {`${gitRemoteHost} URL`}
              </div>
              <div className="cursor-pointer text-blue-400 break-words w-1/2 hover:text-blue-500">
                {remoteUrl()}
              </div>
            </div>

            {isMultiRemote ? (
              <div className=" flex justify-evenly my-2">
                <div className="font-sans text-gray-800 font-semibold w-1/4 border-dotted border-b-2 border-gray-200">
                  Entry truncated!
                </div>
                <div className="w-1/2 border-dotted border-b-2 border-gray-200">
                  {`Remote repos : ${multiRemoteCount}`}
                </div>
              </div>
            ) : null}
          </div>

          <div className="block my-6 mx-auto">
            <div
              className="p-3 text-gray-600 text-center w-3/4 mx-auto rounded-md shadow-md bg-yellow-200 text-whtie font-sans font-semibold text-xl hover:bg-yellow-100 hover:shadow-sm cursor-pointer transition"
              onClick={(event) => {
                showCommitLogsView();
              }}
            >
              SHOW COMMIT LOGS
            </div>
          </div>
        </div>
      ) : null}
    </>
  );
}
Example #22
Source File: RepositoryDetails.js    From gitconvex with Apache License 2.0 4 votes vote down vote up
export default function RepositoryDetails(props) {
  library.add(fab, fas);
  const [gitRepoStatus, setGitRepoStatus] = useState({});
  const [repoFetchFailed, setRepoFetchFailed] = useState(false);
  const [repoIdState, setRepoIdState] = useState("");
  const [showCommitLogs, setShowCommitLogs] = useState(false);
  const [isMultiRemote, setIsMultiRemote] = useState(false);
  const [multiRemoteCount, setMultiRemoteCount] = useState(0);
  const [backdropToggle, setBackdropToggle] = useState(false);
  const [viewReload, setViewReload] = useState(false);
  const [codeViewToggle, setCodeViewToggle] = useState(false);
  const [selectedBranch, setSelectedBranch] = useState("");
  const [currentBranch, setCurrentBranch] = useState("");
  const [action, setAction] = useState("");
  const [loading, setLoading] = useState(false);

  const closeBackdrop = (toggle) => {
    setBackdropToggle(!toggle);
  };

  const showCommitLogsView = () => {
    setShowCommitLogs(true);
  };

  const actionTrigger = (actionType) => {
    setAction(actionType);
    setBackdropToggle(true);
  };

  const memoizedFolderExplorer = useMemo(() => {
    return (
      <FileExplorerComponent repoIdState={repoIdState}></FileExplorerComponent>
    );
  }, [repoIdState]);

  const memoizedCommitLogComponent = useMemo(() => {
    return (
      <>
        <CommitLogComponent repoId={repoIdState}></CommitLogComponent>
      </>
    );
  }, [repoIdState]);

  const memoizedFetchRemoteComponent = useMemo(() => {
    return (
      <FetchPullActionComponent
        repoId={repoIdState}
        actionType="fetch"
      ></FetchPullActionComponent>
    );
  }, [repoIdState]);

  const memoizedPullRemoteComponent = useMemo(() => {
    return (
      <FetchPullActionComponent
        repoId={repoIdState}
        actionType="pull"
      ></FetchPullActionComponent>
    );
  }, [repoIdState]);

  const memoizedSwitchBranchComponent = useMemo(() => {
    return (
      <SwitchBranchComponent
        repoId={repoIdState}
        branchName={selectedBranch}
        closeBackdrop={closeBackdrop}
        switchReloadView={() => {
          setViewReload(true);
        }}
      ></SwitchBranchComponent>
    );
  }, [repoIdState, selectedBranch]);

  const memoizedBranchListComponent = useMemo(() => {
    return (
      <BranchListComponent
        repoId={repoIdState}
        currentBranch={currentBranch}
      ></BranchListComponent>
    );
  }, [repoIdState, currentBranch]);

  const memoizedAddRemoteRepoComponent = useMemo(() => {
    return (
      <AddRemoteRepoComponent repoId={repoIdState}></AddRemoteRepoComponent>
    );
  }, [repoIdState]);

  useEffect(() => {
    setViewReload(false);
    setCodeViewToggle(false);
    setLoading(true);
    const endpointURL = globalAPIEndpoint;

    if (props.parentProps.location) {
      const repoId = props.parentProps.location.pathname.split(
        "/repository/"
      )[1];

      setRepoIdState(repoId);

      axios({
        url: endpointURL,
        method: "POST",
        headers: {
          "Content-type": "application/json",
        },
        data: {
          query: `
            query
            {
                gitRepoStatus(repoId:"${repoId}"){
                  gitRemoteData
                  gitRemoteHost
                  gitRepoName
                  gitBranchList
                  gitCurrentBranch
                  gitTotalCommits
                  gitLatestCommit
                  gitTotalTrackedFiles    
                }
            }
          `,
        },
      })
        .then((res) => {
          setLoading(false);
          if (res.data && res.data.data && !res.data.error) {
            const localRepoStatus = res.data.data.gitRepoStatus;
            let gitRemoteLocal = localRepoStatus.gitRemoteData;
            setCurrentBranch(localRepoStatus.gitCurrentBranch);
            if (gitRemoteLocal.includes("||")) {
              setIsMultiRemote(true);
              localRepoStatus.gitRemoteData = gitRemoteLocal.split("||")[0];
              setIsMultiRemote(true);
              setMultiRemoteCount(gitRemoteLocal.split("||").length);
            } else {
              setIsMultiRemote(false);
              setMultiRemoteCount(0);
            }
            setGitRepoStatus(localRepoStatus);
          } else {
            setRepoFetchFailed(true);
          }
        })
        .catch((err) => {
          setLoading(false);

          if (err) {
            console.log("API GitStatus error occurred : " + err);
            setRepoFetchFailed(true);
          }
        });
    }
  }, [props.parentProps, viewReload]);

  let {
    gitRemoteData,
    gitRepoName,
    gitBranchList,
    gitCurrentBranch,
    gitRemoteHost,
    gitTotalCommits,
    gitLatestCommit,
  } = gitRepoStatus;

  const switchBranchHandler = (branchName) => {
    setBackdropToggle(true);
    setAction("switchbranch");
    setSelectedBranch(branchName);
  };

  const actionComponentPicker = () => {
    switch (action) {
      case "fetch":
        return memoizedFetchRemoteComponent;
      case "pull":
        return memoizedPullRemoteComponent;
      case "addRemoteRepo":
        return memoizedAddRemoteRepoComponent;
      case "addBranch":
        return <AddBranchComponent repoId={repoIdState}></AddBranchComponent>;
      case "switchbranch":
        return memoizedSwitchBranchComponent;
      case "listBranch":
        return memoizedBranchListComponent;
      default:
        return null;
    }
  };

  return (
    <>
      {loading ? (
        <LoadingHOC
          message="Fetching repo details..."
          loading={loading}
        ></LoadingHOC>
      ) : null}
      {showCommitLogs ? (
        <>
          <div
            className="fixed w-full h-full top-0 left-0 right-0 flex overflow-auto"
            id="commit-log__backdrop"
            style={{ background: "rgba(0,0,0,0.5)", zIndex: 99 }}
            onClick={(event) => {
              if (event.target.id === "commit-log__backdrop") {
                setShowCommitLogs(false);
              }
            }}
          >
            <div
              id="commit-log__cards"
              className="w-full xl:w-3/4 lg:w-5/6 md:w-11/12 sm:w-11/12 h-full block mx-auto my-auto mt-10 mb-10"
            >
              {memoizedCommitLogComponent}
            </div>
            <div
              className="w-14 h-14 mr-5 mt-6 rounded-full bg-red-500 text-white flex justify-center items-center shadow cursor-pointer fixed right-0 top-0"
              onClick={() => {
                setShowCommitLogs(false);
              }}
            >
              <FontAwesomeIcon
                className="flex text-center text-3xl my-auto"
                icon={["fas", "times"]}
              ></FontAwesomeIcon>
            </div>
          </div>
        </>
      ) : null}
      {backdropToggle || codeViewToggle ? (
        <div
          className="flex h-full overflow-auto fixed inset-x-0 top-0 w-full z-40"
          id="repo-backdrop"
          style={{ background: "rgba(0,0,0,0.7)", zIndex: "99" }}
          onClick={(event) => {
            if (event.target.id === "repo-backdrop") {
              setBackdropToggle(false);
              setAction("");
            }
          }}
        >
          <>{action ? actionComponentPicker() : null}</>
          <div
            className="w-14 h-14 mr-5 mt-6 rounded-full bg-red-500 text-white flex justify-center items-center shadow cursor-pointer fixed top-0 right-0"
            onClick={() => {
              setBackdropToggle(false);
              setCodeViewToggle(false);
              setViewReload(true);
              setAction("");
            }}
          >
            <FontAwesomeIcon
              className="flex text-center text-3xl my-auto"
              icon={["fas", "times"]}
            ></FontAwesomeIcon>
          </div>
        </div>
      ) : null}
      <>
        {!loading && gitRepoStatus && !repoFetchFailed ? (
          <div className="overflow-auto rounded-lg justify-evenly h-full mx-auto p-6 w-full">
            <div className="flex px-3 py-2">
              {gitRepoStatus ? (
                <RepoInfoComponent
                  gitRepoName={gitRepoName}
                  gitCurrentBranch={gitCurrentBranch}
                ></RepoInfoComponent>
              ) : null}
            </div>
            <div className="w-full">
              <div className="xl:w-11/12 lg:w-full w-full xl:flex lg:block md:block sm:block my-4 mx-auto justify-around">
                {gitRepoStatus ? (
                  <>
                    <RepoLeftPaneComponent
                      received={true}
                      actionTrigger={actionTrigger}
                      showCommitLogsView={showCommitLogsView}
                      gitRemoteHost={gitRemoteHost}
                      gitRemoteData={gitRemoteData}
                      isMultiRemote={isMultiRemote}
                      multiRemoteCount={multiRemoteCount}
                    ></RepoLeftPaneComponent>
                    <RepoRightPaneComponent
                      received={true}
                      switchBranchHandler={switchBranchHandler}
                      actionTrigger={actionTrigger}
                      gitBranchList={gitBranchList}
                      gitCurrentBranch={gitCurrentBranch}
                      gitLatestCommit={gitLatestCommit}
                      gitTotalCommits={gitTotalCommits}
                    ></RepoRightPaneComponent>
                  </>
                ) : null}
              </div>
            </div>

            {!loading && gitRepoStatus && repoIdState
              ? memoizedFolderExplorer
              : null}
          </div>
        ) : !loading ? (
          <div className="w-full h-full mx-auto text-center flex justify-center items-center">
            <div className="block mx-auto w-11/12">
              <div className="rounded-lg shadow border-2 border-dashed border-pink-400 text-red-300 text-3xl font-sans font-semibold p-4">
                Unable to fetch repo details
              </div>
              <div className="font-sans font-light text-xl my-4 text-gray-600">
                Please check if the repo is a valid git repo. If it is not a git
                repo, delete the entry from "Settings" menu and add the repo
                again by checking "Initialize a new repo" option
              </div>
              <div className="my-10 text-gray-200">
                <FontAwesomeIcon
                  icon={["fas", "unlink"]}
                  size="10x"
                ></FontAwesomeIcon>
              </div>
            </div>
          </div>
        ) : null}
      </>
    </>
  );
}