diff --git a/src/contents/safety.tsx b/src/contents/safety.tsx index e4dd9c55d81c7fbc04d6cc9d7585158e88632642..2950a1cba308fe5015b7b73ad19c529b94ab180d 100644 --- a/src/contents/safety.tsx +++ b/src/contents/safety.tsx @@ -43,27 +43,37 @@ export function Safety() { </div> <div className="col"> <section id="ChecksH" className="section"> - <div id="Checks"><H2 text="Check-Ins"/></div> + <div id="Check-Ins"><H2 text="Check-Ins"/></div> </section> </div> <div className="col"> <section id="LabH" className="section"> - <div id="Lab"><H2 text="Our Lab"/></div> + <div id="Our Lab"><H2 text="Our Lab"/></div> </section> </div> <div className="col"> <section id="BiosafetyH" className="section"> <div id="Biosafety"><H2 text="Biosafety"/></div> - <div id="BS1"><h3>Mechanism</h3> </div> - <div id="BS2"><h3>Delivery</h3> </div> + <section id="Biosafety1"> + <div id="Biosafety1H"><h3>Mechanism</h3> </div> + </section> + <section id="Biosafety2"> + <div id="Biosafety2H"><h3>Delivery</h3> </div> + </section> </section> </div> <div className="col"> <section id="BiosecurityH" className="section"> <div id="Biosecurity"><H2 text="Biosecurity"/></div> - <div id="BSec1"><h3>Our Project</h3> </div> - <div id="BSec2"><h3>Risk Assesment</h3> </div> - <div id="BSec3"><h3>Managing Risks</h3> </div> + <section id="Biosecurity1"> + <div id="Biosecurity1H"><h3>Our Project</h3> </div> + </section> + <section id="Biosecurity2"> + <div id="Biosecurity2H"><h3>Risk Assesment</h3> </div> + </section> + <section id="Biosecurity3"> + <div id="Biosecurity3H"><h3>Managing Risks</h3> </div> + </section> </section> </div> <div className="col"> diff --git a/src/pages.ts b/src/pages.ts index 52613be5d1229ddc13bd148f980881a513fe4a81..5e1ffcaff4543227e0e676c8bc99f23a384a9dd9 100644 --- a/src/pages.ts +++ b/src/pages.ts @@ -17,10 +17,11 @@ Team, Impressum, Example, - igemBielefeld + igemBielefeld, + HpSidebar, + SafetySidebar } from "./contents"; - -import { DescSidebar, SafetySidebar, NoSidebar, EngSide } from "./contents"; +import { DescSidebar, NoSidebar, EngSide } from "./contents"; import { IBIE, JUDGEH, PRODESC, SUPH, PARTH, ENGH, HOMEH, HPH, SPONH, RESH, ATTH, CONTH, DESCH, EXPH, IMPH, NOTEH, SAFEH, TEAMH } from "./contents"; interface Base { @@ -105,7 +106,7 @@ const Pages: (Page | Folder)[] = [ path: "/human-practices", component: HumanPractices, header: HPH, - navlist: NoSidebar + navlist: HpSidebar }, @@ -357,7 +358,7 @@ export const NavPages: (Page | PageRef | Folder)[] = [ path: "/human-practices", component: HumanPractices, header: HPH, - navlist: NoSidebar + navlist: HpSidebar }, { name: "Feedback and Implementation", diff --git a/src/sidebars/hpS.tsx b/src/sidebars/hpS.tsx index 2b4a10768683263916f3ebdf3f1fa62a70e3fd0f..9c37197bcbbc6c9ab1c93ce48af33f5448422ebd 100644 --- a/src/sidebars/hpS.tsx +++ b/src/sidebars/hpS.tsx @@ -1,11 +1,13 @@ -import Sidebar from "../components/Sidebar"; + + export function HpSidebar(){ + + return( <div className="col-2 d-none d-lg-block"> - <div className="sticky-top"> - <Sidebar nums={["Overview", "Timeline", "Inspiration", "Methods", "Analysis", "Reflection", "Implementation"]}></Sidebar> - </div> + </div> ) -} \ No newline at end of file +} + diff --git a/src/sidebars/safeS.tsx b/src/sidebars/safeS.tsx index db45ffbbc80f29c2d311d68dfc49a147d6187465..69308c7afef6e623cbbc1686ce6e1c9bb43bb2ea 100644 --- a/src/sidebars/safeS.tsx +++ b/src/sidebars/safeS.tsx @@ -1,185 +1,23 @@ -import { useEffect } from "react"; -import { NewHighlight, Highlight } from "../utils/Highlight-functions"; -import { ScrollLink } from "../components/ScrollLink"; -import { openAndCloseAndScroll } from "../utils/openAndScroll"; -export function SafetySidebar() { - let numsBig = ["RoleH", "ChecksH", "LabH", "BiosafetyH", "BiosecurityH", "BioethicsH"]; - let numsSub = ["BS1", "BS2"]; +import { createSidebar } from "../utils/createSidebar"; - useEffect(() => { - window.addEventListener('scroll', handleScroll); - return () => window.removeEventListener('scroll', handleScroll); - }, []); - const handleScroll = () => { - for (let idx in numsSub) { - const item = numsSub[idx]; - let ind = numsSub.findIndex((e) => e === item); - let subdi = "newsubtitle" + ind; +export function SafetySidebar(){ - NewHighlight( - { el: document.getElementById(item) }, - { subtitle: document.getElementById(subdi) } - ); - } - - for (let idx in numsBig) { - const item = numsBig[idx]; - let ind = numsBig.findIndex((e) => e === item); - let subdi = "subtitle" + ind; - - Highlight( - { el: document.getElementById(item) }, - { subtitle: document.getElementById(subdi) } - ); - } - }; - - return ( - <div className="col-2 d-none d-lg-block"> - <br /> - <div className="sticky-top"> - <nav className="sidebar"> - <div> - <a - onClick={openAndCloseAndScroll({ - it: "tab-Role", - scrollTarget: "Role", - close: ["Bioethics", "Biosafety", "Biosecurity"], - })} - > - <div id="subtitle0" className="detail-sideitem"> - <div id="parent-Role" className="sideitem"> - <summary>Role in iGem</summary> - </div> - </div> - </a> - </div> - - <div> - <a - onClick={openAndCloseAndScroll({ - it: "tab-Checks", - scrollTarget: "Checks", - close: ["Bioethics", "Biosafety", "Biosecurity"], - })} - > - <div id="subtitle1" className="detail-sideitem"> - <div id="parent-Checks" className="sideitem"> - <summary>Check-Ins</summary> - </div> - </div> - </a> - </div> - - <div> - <a - onClick={openAndCloseAndScroll({ - it: "tab-Lab", - scrollTarget: "Lab", - close: ["Bioethics", "Biosafety", "Biosecurity"], - })} - > - <div id="subtitle2" className="detail-sideitem"> - <div id="parent-Lab" className="sideitem"> - <summary>Our Lab</summary> - </div> - </div> - </a> - </div> - - <div> - <div className="detail-sideitem" id="subtitle3"> - <div id="parent-Biosafety" className="sideitem"> - <a - onClick={openAndCloseAndScroll({ - it: "tab-Biosafety", - scrollTarget: "Biosafety", - close: ["Bioethics", "Biosecurity"], - })} - > - <summary>Biosafety</summary> - </a> - <span id="tab-Biosafety" className="sidesubtab" style={{ display: "none" }}> - <ul> - <li id="newsubtitle0"> - <ScrollLink label="Mechanism" targetId="BS1" /> - </li> - <li id="newsubtitle1"> - <ScrollLink label="Delivery" targetId="BS2" /> - </li> - </ul> - </span> - </div> - </div> - </div> - - <div> - <div className="detail-sideitem" id="subtitle4"> - <div id="parent-Biosecurity" className="sideitem"> - <a - onClick={openAndCloseAndScroll({ - it: "tab-Biosecurity", - scrollTarget: "Biosecurity", - close: ["Biosafety", "Bioethics"], - })} - > - <summary>Biosecurity</summary> - </a> - <span id="tab-Biosecurity" className="sidesubtab" style={{ display: "none" }}> - <ul> - <li> - <ScrollLink label="Our Project" targetId="BSec1" /> - </li> - <li> - <ScrollLink label="Risk Assesment" targetId="BSec2" /> - </li> - <li> - <ScrollLink label="Managing Risks" targetId="BSec3" /> - </li> - </ul> - </span> - </div> - </div> - </div> - - <div> - <div className="detail-sideitem" id="subtitle5"> - <div id="parent-Bioethics" className="sideitem"> - <a - onClick={openAndCloseAndScroll({ - it: "tab-Bioethics", - scrollTarget: "Bioethics", - close: ["Biosafety", "Biosecurity"], - })} - > - <summary>Bioethics</summary> - </a> - <span id="tab-Bioethics" className="sidesubtab" style={{ display: "none" }}> - <ul> - <li> - <ScrollLink label="Gene Therapy" targetId="BE1" /> - </li> - <li> - <ScrollLink label="Primary Cells" targetId="BE2" /> - </li> - <li> - <ScrollLink label="Consent and Guidelines" targetId="BE3" /> - </li> - </ul> - </span> - </div> - </div> - </div> - </nav> - <br /> - <div className="col" style={{ display: "flex", alignItems: "right" }}> - <a href="#" className="backtotop"> - Back to Top ↑ - </a> + let sidebar = createSidebar(tabs); + return( + <div className="col-2 d-none d-lg-block"> + {sidebar} </div> - </div> - </div> - ); + ) } + + +const tabs = [ + { tab: "Role" }, + { tab: "Check-Ins"}, + { tab: "Our Lab" }, + // { tab: "Biosafety", subtabs: ["Mechanism", "Delivery"] }, + { tab: "Biosecurity", subtabs: ["Our Project", "Risk Assessment", "Managing Risks"] }, + { tab: "Bioethics", subtabs: ["Gene Therapy", "Primary Cells", "Consent and Guidelines"] }, + ]; \ No newline at end of file diff --git a/src/utils/Highlight-functions.ts b/src/utils/Highlight-functions.ts index 2085c5810b12b53668e4055147acec8ef684af3b..058224800f52a02e4f6a1e4a78f4302e99f1bcb3 100644 --- a/src/utils/Highlight-functions.ts +++ b/src/utils/Highlight-functions.ts @@ -1,10 +1,10 @@ export function NewHighlight({el}: {el: HTMLElement | null}, {subtitle}:{subtitle: HTMLElement | null}){ let TopDistance = 150; - console.log("Starting highlight check...") + /* console.log("Starting highlight check...") console.log("here come el...") console.log(el) console.log("here comes subtitle...") - console.log(subtitle) + console.log(subtitle) */ if (el != null && subtitle != null){ /* console.log("here comes el...") console.log(el) @@ -39,12 +39,12 @@ export function NewHighlight({el}: {el: HTMLElement | null}, {subtitle}:{subtitl if (el.getBoundingClientRect().top < TopDistance + 1 && el.getBoundingClientRect().bottom > TopDistance){ if(subtitle.childNodes[0] != undefined){ - console.log("if true: "); - console.log(subtitle.childNodes[0]); + /* console.log("if true: "); + console.log(subtitle.childNodes[0]); */ (subtitle.childNodes[0] as HTMLElement).classList.add("active-sideitem"); if(subtitle.childNodes[0].childNodes[1] != undefined){ - console.log("test: ") - console.log(subtitle.childNodes[0].childNodes[1]); + /* console.log("test: ") + console.log(subtitle.childNodes[0].childNodes[1]); */ (subtitle.childNodes[0].childNodes[1] as HTMLElement).style.display = "block"; } } @@ -54,12 +54,12 @@ export function NewHighlight({el}: {el: HTMLElement | null}, {subtitle}:{subtitl subtitle.style.backgroundColor = ""; subtitle.classList.remove("subtitle-active"); if(subtitle.childNodes[0] != undefined){ - console.log("if true: "); - console.log(subtitle.childNodes[0]); + /* console.log("if true: "); + console.log(subtitle.childNodes[0]); */ (subtitle.childNodes[0] as HTMLElement).classList.remove("active-sideitem"); if(subtitle.childNodes[0].childNodes[1] != undefined){ - console.log("test: ") - console.log(subtitle.childNodes[0].childNodes[1]); + /* console.log("test: ") + console.log(subtitle.childNodes[0].childNodes[1]); */ (subtitle.childNodes[0].childNodes[1] as HTMLElement).style.display = "none"; } } diff --git a/src/utils/createSidebar.tsx b/src/utils/createSidebar.tsx new file mode 100644 index 0000000000000000000000000000000000000000..f57c857fffda10f2c9322b4ae2be84f17d9c02e1 --- /dev/null +++ b/src/utils/createSidebar.tsx @@ -0,0 +1,174 @@ +import { useEffect, useState } from "react"; +import { ScrollLink } from "../components/ScrollLink"; +import { Highlight, NewHighlight } from "./Highlight-functions"; +import { stringToSlug } from "./stringToSlug"; + +// Funktion zur Erstellung der Sidebar +export function createSidebar(tabs: Array<{ tab: string; subtabs?: Array<string> }>) { + const { numsBig, numsSub } = deriveTabsData(tabs); + + const [openTab, setOpenTab] = useState<string | null>(null); + + + useEffect(() => { + const handleScroll = () => { + numsBig.forEach((item, ind) => { + const element = document.getElementById(item); + const subtitleElement = document.getElementById(`subtitle${ind}`); + if (element && subtitleElement) { + Highlight({ el: element }, { subtitle: subtitleElement }); + } + }); + + numsSub.forEach((item, ind) => { + const element = document.getElementById(item); + const subtitleElement = document.getElementById(`newsubtitle${ind}`); + if (element && subtitleElement) { + NewHighlight({ el: element }, { subtitle: subtitleElement }); + } + }); + }; + + window.addEventListener("scroll", handleScroll); + return () => window.removeEventListener("scroll", handleScroll); + }, [numsBig, numsSub, openTab]); + + const scrolling = (tab: string) => { + const targetElement = document.getElementById(tab); + if (targetElement) { + //console.log(`Scrolling to element with ID: ${tab}`); + + // Get the position of the element relative to the document + const elementRect = targetElement.getBoundingClientRect(); + const elementTop = elementRect.top + window.scrollY; + + // Calculate the middle of the viewport + const viewportHeight = window.innerHeight; + const scrollOffset = elementTop - (viewportHeight / 5 - targetElement.offsetHeight / 2); + /* + console.log(`Element Top: ${elementTop}`); + console.log(`Viewport Height: ${viewportHeight}`); + console.log(`Scroll Offset: ${scrollOffset}`); */ + + window.scrollTo({ + top: scrollOffset, + behavior: "smooth" + }); + } else { + console.error(`Scroll target element not found for ID: ${tab}`); + } + } + + const toggleTab = (tab: string) => { + setOpenTab(openTab === tab ? null : tab); + // console.log(`Status of tab ${tab} is ${openTab}`) + }; + + const toggleTabAndScroll = (tab: string) => { + setOpenTab(openTab === tab ? null : tab); + // onsole.log(`Status of tab ${tab} is ${openTab}`) + scrolling(tab) + }; + let subtitlenumber = 0; + return ( + <> + <br /> + <div className="sticky-top"> + <nav className="sidebar"> + {tabs.map((tab, index) => { + const tabId = `tab-${tab.tab}`; + const parentId = `parent-${tab.tab}`; + const subtitleId = `subtitle${index}`; + + return ( + <div key={index}> + + <div id={subtitleId} className="detail-sideitem"> + <div id={parentId} className="sideitem"> + <a + onClick={() => { + // console.log(`Clicked on Tab ${tab.tab} with tab-name tab-${tab.tab} and parent parent-${tab.tab}`); + toggleTab(tab.tab); + // Close other tabs when a new tab is opened + tabs.forEach((t) => { + if (t.tab !== tab.tab) { + document.getElementById(`tab-${t.tab}`)!.style.display = "none"; + document.getElementById(`parent-${t.tab}`)!.classList.remove("active-sideitem"); + } + }); + // Show or hide the selected tab + document.getElementById(tabId)!.style.display = openTab === tab.tab ? "block" : "none"; + document.getElementById(parentId)!.classList.toggle("active-sideitem"); + }} + > + <summary>{tab.tab}</summary> + </a> + {tab.subtabs && ( + <span + id={tabId} + className="sidesubtab" + style={{ display: openTab === tab.tab ? "block" : "none" }} + > + <ul> + {tab.subtabs.map((subtab, subIndex) => { + const subTabId = `newsubtitle${subtitlenumber}`; + /* console.log(`Old subtitlenumber is ${subtitlenumber}`) */ + subtitlenumber = subtitlenumber + 1; + /* console.log(`New subtitlenumber is ${subtitlenumber}`) + console.log(`Made subtab newsubtitle${subtitlenumber} that will link to ${tab.tab}${subIndex + 1}H`) */ + return ( + <li key={subtitlenumber} id={subTabId}> + <ScrollLink label={subtab} targetId={`${tab.tab}${subIndex + 1}H`} /> + </li> + ); + })} + </ul> + </span> + )} + </div> + </div> + + + + </div> + ); + })} + </nav> + <br /> + <div className="col" style={{ display: "flex", alignItems: "right" }}> + <a href="#" className="backtotop"> + Back to Top ↑ + </a> + </div> + </div> + </> + ); + } + + + + +function deriveTabsData(tabs: Array<{ tab: string; subtabs?: Array<string> }>) { + let numsBig: string[] = []; + let numsSub: string[] = []; + + tabs.forEach((tab) => { + let bigslugname = stringToSlug(tab.tab); + numsBig.push(bigslugname); + if (tab.subtabs) { + tab.subtabs.forEach(( subIndex) => { + let tabname = `${tab.tab}${subIndex + 1}`; + let slugname = stringToSlug(tabname); + numsSub.push(slugname); + }); + } + }); + + return { numsBig, numsSub }; + } + + + + + + \ No newline at end of file