From e326b7e2540f3a3b9973c88f336081a081f33c25 Mon Sep 17 00:00:00 2001
From: Liliana Sanfilippo <liliana.sanfilippo@uni-bielefeld.de>
Date: Mon, 23 Sep 2024 01:02:26 +0200
Subject: [PATCH] openElement

---
 src/App/App.tsx             |   5 +-
 src/utils/TabNavigation.tsx |  49 +++++++++++------
 src/utils/openElement.ts    | 102 +++++++++++++++++++-----------------
 src/utils/useNavigation.ts  |  52 ++++++++----------
 4 files changed, 111 insertions(+), 97 deletions(-)

diff --git a/src/App/App.tsx b/src/App/App.tsx
index e8bff3de..098917d3 100644
--- a/src/App/App.tsx
+++ b/src/App/App.tsx
@@ -22,15 +22,18 @@ import { Villbuttonrow } from "../components/Buttons.tsx";
 import "../utils/Highlight-functions.js";
 import "./LoadingScreen.css";
 import { useScroll, motion } from "framer-motion";
+import { useNavigation } from "../utils/useNavigation.ts";
 
 const App = () => {
+  const { isLoading, setIsLoading, goToPagesAndOpenTab, goToPageWithTabAndScroll } = useNavigation();
+  
   const { scrollYProgress } = useScroll({
     offset: ["start start", "end end"],
   });
 
   window.scrollTo(0, 0);
 
-  const [isLoading, setIsLoading] = useState(true);
+
 
   const pathMapping = getPathMapping();
   const currentPath =
diff --git a/src/utils/TabNavigation.tsx b/src/utils/TabNavigation.tsx
index 9ddbb7bf..23bb5504 100644
--- a/src/utils/TabNavigation.tsx
+++ b/src/utils/TabNavigation.tsx
@@ -1,26 +1,24 @@
-import { useEffect } from 'react';
-import { useLocation } from 'react-router-dom';
+import { useEffect, useState } from 'react';
+import { useNavigate, useLocation } from 'react-router-dom';
 import { openFromOtherPage } from './openFromOtherpAge';
 
+// Funktion, um den Haupttab zu öffnen
 export const openTab = (tabId: string) => {
-  // Hide all tabs
   const tabs = document.querySelectorAll('.tabcontent');
   tabs.forEach((tab) => {
     (tab as HTMLElement).style.display = 'none';
   });
 
-  // Show the selected tab
   const selectedTab = document.getElementById(tabId);
   if (selectedTab) {
     selectedTab.style.display = 'block';
   }
 };
 
+// Funktion, um verschachtelte Tabs zu öffnen
 export const openNestedTab = (parentTabId: string, childTabId: string) => {
-  // Open parent tab
   openTab(parentTabId);
 
-  // Open child tab inside parent tab
   const nestedTabs = document.querySelectorAll(`#${parentTabId} .nested-tabcontent`);
   nestedTabs.forEach((tab) => {
     (tab as HTMLElement).style.display = 'none';
@@ -32,6 +30,7 @@ export const openNestedTab = (parentTabId: string, childTabId: string) => {
   }
 };
 
+// Funktion, um zu einem bestimmten Bereich (z.B. Collapse) zu scrollen
 export const handleScrollToCollapse = (collapseId: string) => {
   const collapseElement = document.getElementById(collapseId);
   if (collapseElement) {
@@ -46,38 +45,56 @@ export const handleScrollToCollapse = (collapseId: string) => {
   }
 };
 
-export const TabNavigation = () => {
+// Custom Hook zur zentralen Tab-Navigation
+export const useTabNavigation = () => {
+  const navigate = useNavigate();
   const location = useLocation();
+  const [activeTab, setActiveTab] = useState<string | null>(null);
+  const [activeSubTab, setActiveSubTab] = useState<string | null>(null);
+
+  // Tab-Wechsel und URL-Update
+  const handleTabChange = (tabId: string, subTabId?: string) => {
+    setActiveTab(tabId);
+    setActiveSubTab(subTabId || null);
+
+    // URL entsprechend aktualisieren
+    let newUrl = `${location.pathname}?tab=${tabId}`;
+    if (subTabId) {
+      newUrl += `&subTab=${subTabId}`;
+    }
+    navigate(newUrl, { replace: true });
+  };
 
   useEffect(() => {
     const params = new URLSearchParams(location.search);
-    const collapseId = params.get('collapseId');
     const tabId = params.get('tab');
-    const subTabId = params.get('subTab'); // Neues Parameter für verschachtelte Tabs
+    const subTabId = params.get('subTab');
+    const collapseId = params.get('collapseId');
 
-    // Open the tab specified by tabId (and subTab if nested)
+    // Öffne Haupt- und ggf. verschachtelten Tab
     if (tabId) {
       if (subTabId) {
-        // If subTab is provided, open the nested tab
         openNestedTab(tabId, subTabId);
       } else {
-        // Otherwise, just open the main tab
         openTab(tabId);
       }
     }
 
-    // Scroll to the section specified by collapseId after opening the tab
+    // Scrollen zu einem bestimmten Collapsible-Element
     if (collapseId) {
       handleScrollToCollapse(collapseId);
     }
 
-    // Open the tab from another page
+    // Tab von einer anderen Seite öffnen (falls definiert)
     if (tabId) {
       openFromOtherPage(tabId)({ currentTarget: document.getElementById(tabId)! });
     }
+
+    setActiveTab(tabId);
+    setActiveSubTab(subTabId || null);
   }, [location.search]);
 
-  return 
+  return { activeTab, activeSubTab, handleTabChange };
 };
 
-export default TabNavigation;
+
diff --git a/src/utils/openElement.ts b/src/utils/openElement.ts
index a4fbaeaa..19ac2f1a 100644
--- a/src/utils/openElement.ts
+++ b/src/utils/openElement.ts
@@ -1,52 +1,56 @@
 export function openElement({
-    elementToOpen, 
-    classToHide,  /* tabcontent */
-    elementToClose,   
-    buttonClass, /* = "tablinks" */ 
-    eventTargetClass = "active"
-  }: {
-    elementToOpen: string,
-    classToHide: string, 
-    classToClose?: string, 
-    elementToClose?: string, 
-    buttonClass?: string, 
-    eventTargetClass?: string
-  }) {
-    const openElement = (event: React.MouseEvent<HTMLElement, MouseEvent>) => {
-      let i, elementsToHide, elementsToClose, tabLinks;
-  
-      // Hide all elements with the classToHide (e.g., "tabcontent")
-      elementsToHide = document.getElementsByClassName(classToHide);
-      for (i = 0; i < elementsToHide.length; i++) {
-        (elementsToHide[i] as HTMLElement).style.display = "none";
+  elementToOpen, 
+  classToHide,  /* tabcontent */
+  elementToClose,   
+  buttonClass, /* = "tablinks" */ 
+  eventTargetClass = "active",
+  handleTabChange  /* Hier handleTabChange als Parameter einfügen */
+}: {
+  elementToOpen: string,
+  classToHide: string, 
+  classToClose?: string, 
+  elementToClose?: string, 
+  buttonClass?: string, 
+  eventTargetClass?: string,
+  handleTabChange: (tabId: string, subTabId?: string) => void  /* Neuer Parameter für die Tab-Änderungslogik */
+}) {
+  const openElement = (event: React.MouseEvent<HTMLElement, MouseEvent>) => {
+    let i, elementsToHide, elementsToClose, tabLinks;
+
+    // Hide all elements with the classToHide (e.g., "tabcontent")
+    elementsToHide = document.getElementsByClassName(classToHide);
+    for (i = 0; i < elementsToHide.length; i++) {
+      (elementsToHide[i] as HTMLElement).style.display = "none";
+    }
+
+    // If elementToClose is provided, hide these elements too (optional)
+    if (elementToClose) {
+      elementsToClose = document.getElementsByClassName(elementToClose);
+      for (i = 0; i < elementsToClose.length; i++) {
+        (elementsToClose[i] as HTMLElement).style.display = "none";
       }
-  
-      // If elementToClose is provided, hide these elements too (optional)
-      if (elementToClose) {
-        elementsToClose = document.getElementsByClassName(elementToClose);
-        for (i = 0; i < elementsToClose.length; i++) {
-          (elementsToClose[i] as HTMLElement).style.display = "none";
-        }
+    }
+
+    // Clear the "active" class from elements with the buttonClass (e.g., "tablinks")
+    if (buttonClass) {
+      tabLinks = document.getElementsByClassName(buttonClass);
+      for (i = 0; i < tabLinks.length; i++) {
+        tabLinks[i].className = tabLinks[i].className.replace(` ${eventTargetClass}`, "");
       }
-  
-      // Clear the "active" class from elements with the buttonClass (e.g., "tablinks")
-      if (buttonClass) {
-        tabLinks = document.getElementsByClassName(buttonClass);
-        for (i = 0; i < tabLinks.length; i++) {
-          tabLinks[i].className = tabLinks[i].className.replace(` ${eventTargetClass}`, "");
-        }
-      }
-  
-      // Display the element to open (elementToOpen, e.g., a city tab or content section)
-      const element = document.getElementById(elementToOpen);
-      if (element) {
-        element.style.display = "block";
-      }
-  
-      // Add the "active" class to the clicked element
-      event.currentTarget.className += ` ${eventTargetClass}`;
-    };
-  
-    return openElement;
-  }
-  
\ No newline at end of file
+    }
+
+    // Display the element to open (elementToOpen, e.g., a city tab or content section)
+    const element = document.getElementById(elementToOpen);
+    if (element) {
+      element.style.display = "block";
+    }
+
+    // Add the "active" class to the clicked element
+    event.currentTarget.className += ` ${eventTargetClass}`;
+
+    // Rufe handleTabChange auf, um die URL entsprechend anzupassen
+    handleTabChange(elementToOpen);  // Hier wird die Tab-Änderung und URL-Update durchgeführt
+  };
+
+  return openElement;
+}
diff --git a/src/utils/useNavigation.ts b/src/utils/useNavigation.ts
index d3796381..39f76f7d 100644
--- a/src/utils/useNavigation.ts
+++ b/src/utils/useNavigation.ts
@@ -1,58 +1,48 @@
-import { useNavigate } from "react-router-dom";
+import { useNavigate, useLocation } from "react-router-dom";
+import { useState, useEffect, useRef } from "react";
 
 export const useNavigation = () => {
     const navigate = useNavigate();
+    const location = useLocation();
+    const previousPath = useRef(location.pathname);
+    const [isLoading, setIsLoading] = useState(false);
+    
 
     const goToPagesAndOpenTab = (tabId: string, path: string) => {
-        navigate(`${path}?tab=${tabId}`);
-    };
-
-    const goToTextsAndOpenCollapsible = (collapseId: string, path: string) => {
-        navigate(`${path}?collapseId=${collapseId}`);
-    };
-
-    const goToPageWithTabAndCollapsible = ({ path, tabId, collapseId }: { path: string, tabId: string, collapseId?: string }) => {
-        let url = `${path}?tab=${tabId}`;
-        if (collapseId) {
-            url += `&collapseId=${collapseId}`;
+        if (previousPath.current !== path) {
+            setIsLoading(true);
         }
-        navigate(url);
-    };
-
-    const goToPageWithNestedTabs = ({ path, tabId, subTabId, collapseId }: { path: string, tabId: string, subTabId?: string, collapseId?: string }) => {
-        let url = `${path}?tab=${tabId}`;
-        if (subTabId) {
-            url += `&subTab=${subTabId}`;
-        }
-        if (collapseId) {
-            url += `&collapseId=${collapseId}`;
-        }
-        navigate(url);
+        navigate(`${path}?tab=${tabId}`);
+        setTimeout(() => setIsLoading(false), 500);
     };
 
-    // Erweiterte Funktion, die auch zu einer bestimmten ID innerhalb eines Tabs scrollen kann
     const goToPageWithTabAndScroll = ({ path, tabId, scrollToId }: { path: string, tabId: string, scrollToId?: string }) => {
+        if (previousPath.current !== path) {
+            setIsLoading(true);
+        }
         let url = `${path}?tab=${tabId}`;
         if (scrollToId) {
             url += `&scrollTo=${scrollToId}`;
         }
         navigate(url);
-
-        // Führe nach der Navigation das Scrollen aus
         setTimeout(() => {
+            setIsLoading(false);
             if (scrollToId) {
                 const element = document.getElementById(scrollToId);
                 if (element) {
-                    // Berechne die Scroll-Position, um das Element in der Mitte zu setzen
                     const viewportHeight = window.innerHeight;
                     const targetPosition = element.getBoundingClientRect().top + window.pageYOffset;
                     const scrollToPosition = targetPosition - viewportHeight / 2 + element.clientHeight / 2;
-
                     window.scrollTo({ top: scrollToPosition, behavior: "smooth" });
                 }
             }
-        }, 500); // Verzögere das Scrollen, um sicherzustellen, dass der Tab geladen ist
+        }, 500);
     };
 
-    return { goToPagesAndOpenTab, goToTextsAndOpenCollapsible, goToPageWithTabAndCollapsible, goToPageWithNestedTabs, goToPageWithTabAndScroll };
+
+    useEffect(() => {
+        previousPath.current = location.pathname;
+    }, [location.pathname]);
+
+    return { isLoading, setIsLoading, goToPagesAndOpenTab, goToPageWithTabAndScroll };
 };
-- 
GitLab