geist-org / geist-ui

A design system for building modern websites and applications.
https://geist-ui.dev
MIT License
4.32k stars 333 forks source link

React App. Geist Type error when trying to display image on hover. @geist-ui/react@2.2.5 #856

Open mclaughlin111 opened 6 months ago

mclaughlin111 commented 6 months ago

Bug report 🐞

Version & Environment

Chrome: 121.0.6167.184 (Official Build) (x86_64) @geist-ui/react@2.2.5

Expected Behaviour

The behavior I expect is for a thumbnail image of a file in a file tree to show on mouse hover of each requisite file. Images held in an identical folder structure under Public. (Public > Assets > Semester 1 >) is where my images are

Actual results (or Errors)

I got an error: On mouse over, I get this type error.

ERROR _geist_ui_reactWEBPACK_IMPORTED_MODULE_1__.Image is not a constructor TypeError: _geist_ui_reactWEBPACK_IMPORTED_MODULE_1__.Image is not a constructor at handleMouseEnter (http://localhost:3000/main.bd4c8beaf00e38c77e11.hot-update.js:66:17) at onMouseEnter (http://localhost:3000/main.bd4c8beaf00e38c77e11.hot-update.js:155:31) at HTMLUnknownElement.callCallback (http://localhost:3000/static/js/bundle.js:26981:18) at Object.invokeGuardedCallbackDev (http://localhost:3000/static/js/bundle.js:27025:20) at invokeGuardedCallback (http://localhost:3000/static/js/bundle.js:27082:35) at invokeGuardedCallbackAndCatchFirstError (http://localhost:3000/static/js/bundle.js:27096:29) at executeDispatch (http://localhost:3000/static/js/bundle.js:31239:7) at processDispatchQueueItemsInOrder (http://localhost:3000/static/js/bundle.js:31265:11) at processDispatchQueue (http://localhost:3000/static/js/bundle.js:31276:9) at dispatchEventsForPlugins (http://localhost:3000/static/js/bundle.js:31285:7)

import React, { useState } from "react";
import { Page, Text, Tree, useToasts, Image } from "@geist-ui/react";
import fileStructure from "../fileStructure.json";
import { LuCheck } from "react-icons/lu";
import '../filetree.css';

const Filetree = () => {
  const { setToast } = useToasts();
  const [thumbnailUrl, setThumbnailUrl] = useState("");

  const handleDownload = (path) => {
    console.log(`File clicked: ${path}`);

    const fileName = path.split('/').pop();
    const downloadUrl = process.env.PUBLIC_URL + "/" + path;

    const anchor = document.createElement("a");
    anchor.href = downloadUrl;
    anchor.download = fileName;

    document.body.appendChild(anchor);
    anchor.click();

    document.body.removeChild(anchor);

    setToast({
      text: `Downloading file: ${fileName}`,
      delay: 4000,
      actions: [
        {
          name: <LuCheck />,
          passive: true,
          handler: (event, cancel) => cancel()
        }
      ]
    });
  };

  const handleMouseEnter = (path) => {
    const fileNameWithoutExtension = path.split('/').pop().replace(/\.[^/.]+$/, "");
    const thumbnailPath = process.env.PUBLIC_URL + `/Assets/semester 1/thumbnail_${fileNameWithoutExtension}.png`;

    const img = new Image();

    img.onload = () => {
      setThumbnailUrl(thumbnailPath);
    };

    img.onerror = (error) => {
      console.error(`Error loading thumbnail: ${error.message}`);
    };

    // Setting the src after attaching onload and onerror handlers
    img.src = thumbnailPath;
  };

  const handleMouseLeave = () => {
    setThumbnailUrl("");
  };

  const renderTree = (files, parentPath = "") => {
    return files.map((file) => {
      const filePath = parentPath ? `${parentPath}/${file.name}` : file.name;
      const isPdf = file.name.toLowerCase().endsWith(".pdf");
      const isWav = file.name.toLowerCase().endsWith(".wav");

      if (file.type === "directory") {
        return (
          <Tree.Folder
            key={filePath}
            name={file.name}
            icon={
              isPdf ? (
                <span style={{ color: "red" }}>📄</span>
              ) : isWav ? (
                <span style={{ color: "green" }}>🔊</span>
              ) : (
                <span style={{ color: "blue" }}>📂</span>
              )
            }
            open={true}
          >
            {renderTree(file.files, filePath)}
          </Tree.Folder>
        );
      } else {
        return (
          <Tree.File
            key={filePath}
            name={file.name}
            onClick={() => handleDownload(filePath)}
            icon={
              isPdf ? (
                <span style={{ color: "red" }}>📄</span>
              ) : isWav ? (
                <span style={{ color: "green" }}>🔊</span>
              ) : (
                <span style={{ color: "blue" }}>📄</span>
              )
            }
            onMouseEnter={() => handleMouseEnter(filePath)}
            onMouseLeave={handleMouseLeave}
          />
        );
      }
    });
  };

  return (
    <>
    <div>
      {thumbnailUrl && <img src={thumbnailUrl} alt="Thumbnail" className="thumbnail" />}
    </div>
    <Page>
      <Text h1>Coursework File Tree</Text>
      <Tree className="tree" open>
        {renderTree(fileStructure)}
      </Tree>
      <Image width="280px" height="160px" src={process.env.PUBLIC_URL + '/Assets/semester 1/Encountering Music History/thumbnail_MUS1031_CourseworkEssay.png'} />

    </Page>
    </>
  );
};

export default Filetree;