From 8f7da9abc56840fcd27486fa9a1535f16217d65e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Tam=C3=A1s?= Date: Fri, 17 Jan 2025 18:22:06 +0100 Subject: [PATCH] Fix scroll links broken due traling slash changes --- next.config.mjs | 24 ++-- src/app/learn/beginners/layout.js | 62 ++++------ src/components/Accordion/GlossaryAccordion.js | 116 +++--------------- 3 files changed, 55 insertions(+), 147 deletions(-) diff --git a/next.config.mjs b/next.config.mjs index 23d14da7..bffb76dc 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -3,7 +3,7 @@ const nextConfig = { pageExtensions: ["js", "jsx", "ts", "tsx"], output: "export", distDir: "dist", - images: { unoptimized: true }, // comment out if using vercel or other service with backend support + images: { unoptimized: true }, trailingSlash: true, async redirects() { return redirects; @@ -12,48 +12,48 @@ const nextConfig = { const redirects = [ { - source: "/learn/first-principles/modular-blockchains-and-first-principles", - destination: "/learn/beginners/modular-blockchains-and-first-principles", + source: "/learn/first-principles/modular-blockchains-and-first-principles/", + destination: "/learn/beginners/modular-blockchains-and-first-principles/", permanent: true, }, { - source: "/learn/values-of-modular-blockchains/modular-blockchains-are-user-first", - destination: "/learn/beginners/modular-blockchains-are-user-first", + source: "/learn/values-of-modular-blockchains/modular-blockchains-are-user-first/", + destination: "/learn/beginners/modular-blockchains-are-user-first/", permanent: true, }, { source: "/learn/basics-of-modular-blockchains/modular-and-monolithic-blockchains/", - destination: "/learn/intermediates/modular-and-monolithic-blockchains", + destination: "/learn/intermediates/modular-and-monolithic-blockchains/", permanent: true, }, { source: "/learn/basics-of-modular-blockchains/benefits-of-modular-blockchains/", - destination: "/learn/intermediates/benefits-of-modular-blockchains", + destination: "/learn/intermediates/benefits-of-modular-blockchains/", permanent: true, }, { source: "/learn/modular-architectures/the-modular-stack/", - destination: "/learn/intermediates/the-modular-stack", + destination: "/learn/intermediates/the-modular-stack/", permanent: true, }, { source: "/learn/modular-software/the-differences-of-modular-software/", - destination: "/learn/intermediates/the-differences-of-modular-software", + destination: "/learn/intermediates/the-differences-of-modular-software/", permanent: true, }, { source: "/learn/sovereign-rollups/an-introduction/", - destination: "/learn/intermediates/sovereign-rollups-an-introduction", + destination: "/learn/intermediates/sovereign-rollups-an-introduction/", permanent: true, }, { source: "/learn/sovereign-rollups/misconceptions/", - destination: "/learn/intermediates/sovereign-rollups-misconceptions", + destination: "/learn/intermediates/sovereign-rollups-misconceptions/", permanent: true, }, { source: "/learn/modular-settlement-layers/settlement-in-the-modular-stack/", - destination: "/learn/intermediates/settlement-in-the-modular-stack", + destination: "/learn/intermediates/settlement-in-the-modular-stack/", permanent: true, }, ]; diff --git a/src/app/learn/beginners/layout.js b/src/app/learn/beginners/layout.js index 40dda39f..122613df 100644 --- a/src/app/learn/beginners/layout.js +++ b/src/app/learn/beginners/layout.js @@ -2,40 +2,32 @@ import TertiaryHero from "@/components/Heroes/TertiaryHero"; import TabNavigation from "@/components/TabNavigation/TabNavigation"; export default function BeginnersLayout({ children }) { - const routeTabNavigation = { - "Modular blockchains for beginners": - "/learn/beginners/modular-blockchains-for-beginners", - "The modular stack": "/learn/beginners/the-modular-stack", - "Values of modular blockchains": - "/learn/beginners/modular-blockchains-are-user-first", - "First Principles": - "/learn/beginners/modular-blockchains-and-first-principles", - }; + const routeTabNavigation = { + "Modular blockchains for beginners": "/learn/beginners/modular-blockchains-for-beginners", + "The modular stack": "/learn/beginners/the-modular-stack", + "Values of modular blockchains": "/learn/beginners/modular-blockchains-are-user-first", + "First Principles": "/learn/beginners/modular-blockchains-and-first-principles", + }; - return ( - <> - - That’s pretty much what everyone says about their new blockchain - tech. So, why care about modular blockchains? Why is this time - different? -
-
- We could write a whole book about all the fantastic things that - modular blockchains can do. But most people don’t have time to read - a whole book, so we wrote this short article instead to give you the - big picture. - - } - /> - -
{children}
-
- - ); + return ( + <> + + That’s pretty much what everyone says about their new blockchain tech. So, why care about modular blockchains? Why is this + time different? +
+
+ We could write a whole book about all the fantastic things that modular blockchains can do. But most people don’t have time to + read a whole book, so we wrote this short article instead to give you the big picture. + + } + /> + +
{children}
+
+ + ); } diff --git a/src/components/Accordion/GlossaryAccordion.js b/src/components/Accordion/GlossaryAccordion.js index 3e882910..b45bc143 100644 --- a/src/components/Accordion/GlossaryAccordion.js +++ b/src/components/Accordion/GlossaryAccordion.js @@ -2,7 +2,6 @@ import React, { useState, useEffect } from "react"; import { useRouter } from "next/navigation"; import Container from "@/components/Container/Container"; -import Accordion from "@/components/Accordion/Accordion"; import { Display, Body, Heading } from "@/macros/Copy"; import HeadingWithSuperscript from "@/micros/HeadingWithSuperscript/HeadingWithSuperscript"; import { Col, Row } from "@/macros/Grids"; @@ -10,13 +9,9 @@ import Icon from "@/macros/Icons/Icon"; import SearchInput from "@/macros/Forms/SearchInput"; import Link from "next/link"; import PrimaryButton from "@/macros/Buttons/PrimaryButton"; -import FacebookSVG from "@/macros/SVGs/FacebookSVG"; -import XTwitterSVG from "@/macros/SVGs/XTwitterSVG"; -import EmailAltSVG from "@/macros/SVGs/EmailAltSVG"; -import CopySVG from "@/macros/SVGs/CopySVG"; import { usePathname } from "next/navigation"; -const GlossaryAccordion = ({ glossaryData }) => { +const GlossaryDirectory = ({ glossaryData }) => { const router = useRouter(); const pathname = usePathname(); const [searchTerm, setSearchTerm] = useState(""); @@ -39,8 +34,7 @@ const GlossaryAccordion = ({ glossaryData }) => { const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split(""); - // Group glossary data by the first letter of each term's title - const groupedData = alphabet.reduce((acc, letter) => { + const groupedTerms = alphabet.reduce((acc, letter) => { const terms = filteredData.filter((term) => term.title[0].toUpperCase() === letter); if (terms.length > 0) { acc[letter] = terms; @@ -48,61 +42,28 @@ const GlossaryAccordion = ({ glossaryData }) => { return acc; }, {}); - // Initialize accordion state with unique IDs and open/close status - const [accordionState, setAccordionState] = useState( - glossaryData.reduce((acc, term) => { - acc[term.slug] = { ...term, isOpen: false }; - return acc; - }, {}) - ); - - const toggleAccordion = (id) => { - setAccordionState((prevState) => ({ - ...prevState, - [id]: { - ...prevState[id], - isOpen: !prevState[id].isOpen, - }, - })); - - const isOpen = !accordionState[id].isOpen; - if (isOpen) { - router.push(`/glossary/${id}`, { - scroll: false, - shallow: true, - }); - } else { - router.push(`/glossary`, { scroll: false, shallow: true }); - } - }; const clearSearch = () => { setSearchTerm(""); - router.push(`/glossary`, { + router.push(`/glossary/`, { scroll: false, shallow: true, }); }; - // Initial load effect to open and scroll to the term from URL if present + // Simplified scroll to term effect useEffect(() => { - const term = pathname.split("/").pop(); - if (term && accordionState[term]) { - // Open the specified accordion - setAccordionState((prevState) => ({ - ...prevState, - [term]: { ...prevState[term], isOpen: true }, - })); - - // Scroll to the accordion element smoothly + const term = pathname.split("/").filter(Boolean).pop(); + if (term) { setTimeout(() => { const element = document.getElementById(`accordion-${term}`); - const scrollIntoView = element?.getBoundingClientRect().top < 0 || element?.getBoundingClientRect().top > window.innerHeight; + if (element) { + const scrollIntoView = element.getBoundingClientRect().top < 0 || element.getBoundingClientRect().top > window.innerHeight; - // if element is not in view, scroll to it - if (scrollIntoView) { - element.scrollIntoView({ behavior: "smooth", block: "center" }); + if (scrollIntoView) { + element.scrollIntoView({ behavior: "smooth", block: "center" }); + } } - }, 100); // Delay to ensure DOM is fully ready + }, 100); } }, [pathname]); @@ -120,7 +81,7 @@ const GlossaryAccordion = ({ glossaryData }) => {
{alphabet.map((letter) => { - const isDisabled = !groupedData[letter]; + const isDisabled = !groupedTerms[letter]; return ( { - {Object.keys(groupedData).map((letter) => ( + {Object.keys(groupedTerms).map((letter) => ( @@ -163,7 +124,7 @@ const GlossaryAccordion = ({ glossaryData }) => { - {groupedData[letter].map((term) => ( + {groupedTerms[letter].map((term) => (
@@ -199,49 +160,4 @@ const GlossaryAccordion = ({ glossaryData }) => { ); }; -const ShareIcons = ({ slug }) => { - const socialLinks = [ - { - url: `https://twitter.com/intent/tweet?url=https://celestia.org/glossary/${slug}`, - Icon: , - IconHover: , - text: "Share on Twitter/X", - }, - { - url: `mailto:?subject=Check out Celestia&body=Check out Celestia: https://celestia.org/glossary/${slug}`, - Icon: , - IconHover: , - text: "Share via Email", - }, - { - url: `https://www.facebook.com/sharer/sharer.php?u=https://celestia.org/glossary/${slug}`, - Icon: , - IconHover: , - text: "Share on Facebook", - }, - { - onClick: () => { - navigator.clipboard.writeText(`https://celestia.org/glossary/${slug}`); - }, - Icon: , - IconHover: , - text: "Copy link", - }, - ]; - - return ( -
- {socialLinks.map((link, index) => { - const Tag = link.url ? "a" : "button"; - - return ( - - - - ); - })} -
- ); -}; - -export default GlossaryAccordion; +export default GlossaryDirectory;