diff --git a/containers/EcosystemGrid/EcosystemGrid.jsx b/containers/EcosystemGrid/EcosystemGrid.jsx index 5f45143..976c658 100644 --- a/containers/EcosystemGrid/EcosystemGrid.jsx +++ b/containers/EcosystemGrid/EcosystemGrid.jsx @@ -1,4 +1,5 @@ -import React, { useState, useContext } from "react"; +import React, { useState, useContext, useEffect } from "react"; +import Image from "next/image"; import styles from "./EcosystemGrid.module.scss"; import { RiTwitterXLine } from "react-icons/ri"; import { FaTelegramPlane } from "react-icons/fa"; @@ -391,11 +392,35 @@ const ecosystemData = [ const EcosystemGrid = () => { const [activeTag, setActiveTag] = useState("Artificial Intelligence (AI)"); - const filtered = ecosystemData.filter((item) => - item.tags.includes(activeTag) - ); + const [filteredItems, setFilteredItems] = useState([]); + const [highlightItems, setHighlightItems] = useState([]); + const [isFading, setIsFading] = useState(false); const { theme, setTheme } = useContext(ThemeContext); + useEffect(() => { + setIsFading(true); + let unfadeTimeout; + const fadeTimeout = setTimeout(() => { + const allFiltered = ecosystemData.filter((item) => + item.tags.includes(activeTag) + ); + + const highlights = allFiltered.filter((item) => item.image); + const nonHighlights = allFiltered.filter((item) => !item.image); + + setHighlightItems(highlights); + setFilteredItems(nonHighlights); + unfadeTimeout = setTimeout(() => { + setIsFading(false); + }, 50); + }, 500); + + return () => { + clearTimeout(fadeTimeout); + if (unfadeTimeout) clearTimeout(unfadeTimeout); + }; + }, [activeTag]); + return (
@@ -412,33 +437,31 @@ const EcosystemGrid = () => { ))}
-
- {filtered - .filter((item) => item.image) - .map((item, idx) => ( -
- {item.name} -
- {/* {item.name} */} - +
+ {highlightItems.map((item, idx) => ( +
+ {item.name} +
+ { } aspectRatio={true} /> - - - -

{item.description}

-
- { - window.open(item.website, "_blank"); - }} - > - - - {item.telegram && ( - { - window.open(item.telegram, "_blank"); - }} - > - - - )} - - {item.twitter && ( - { - window.open(item.twitter, "_blank"); - }} - > - - - )} -
-
-
- ))} -
- -
- {filtered - .filter((item) => !item.image) - .map((item, idx) => ( -
- {item.name} + +

{item.description}

{ )}
- ))} +
+ ))} +
+ +
+ {filteredItems.map((item, idx) => ( +
+ {item.name} +

{item.description}

+
+ { + window.open(item.website, "_blank"); + }} + > + + + {item.telegram && ( + { + window.open(item.telegram, "_blank"); + }} + > + + + )} + + {item.twitter && ( + { + window.open(item.twitter, "_blank"); + }} + > + + + )} +
+
+ ))}
); diff --git a/containers/EcosystemGrid/EcosystemGrid.module.scss b/containers/EcosystemGrid/EcosystemGrid.module.scss index 1899280..5b58a38 100644 --- a/containers/EcosystemGrid/EcosystemGrid.module.scss +++ b/containers/EcosystemGrid/EcosystemGrid.module.scss @@ -126,3 +126,22 @@ gap: 1rem; font-size: 1.1rem; } + +.highlightWrapper, .cardGrid { + position: relative; + transition: opacity 0.5s ease-in-out; +} + +.highlightWrapper.fade, .cardGrid.fade { + opacity: 0; +} + +.highlightCard, .card { + transition: all 0.5s ease-in-out; + opacity: 1; +} + +.highlightCard.fade, .card.fade { + opacity: 0; + transform: translateY(20px); +} diff --git a/containers/Faq-container/FaqContainer.jsx b/containers/Faq-container/FaqContainer.jsx index ca54376..d633e3d 100644 --- a/containers/Faq-container/FaqContainer.jsx +++ b/containers/Faq-container/FaqContainer.jsx @@ -8,7 +8,7 @@ import Styles from "./FaqContainer.module.scss"; // optional props: type = "main" | "pricing" function FAQContainer({ type = "main" }) { - const [isOpen, setIsOpen] = useState(0); + const [isOpen, setIsOpen] = useState(null); const [faqs, setFaqs] = useState([]); useEffect(() => { @@ -25,7 +25,8 @@ function FAQContainer({ type = "main" }) { })(); } return () => {}; - }, []); + }, [type]); + return (
- {isOpen === index && ( -
-

-
- )} +
+

+
))}
-

Lets Talk !

+

Lets Talk!

- Didn’t find what you were looking for?
Our team is happy to + Didn't find what you were looking for?
Our team is happy to help.{" "}


diff --git a/containers/Faq-container/FaqContainer.module.scss b/containers/Faq-container/FaqContainer.module.scss index 1046707..294291e 100644 --- a/containers/Faq-container/FaqContainer.module.scss +++ b/containers/Faq-container/FaqContainer.module.scss @@ -43,10 +43,21 @@ font-size: 1rem; line-height: 160%; letter-spacing: 0%; - color: #a3aab8; + color: var(--answer-text-color, #4d4d4d); a { color: #a286f8; } + max-height: 0; + overflow: hidden; + opacity: 0; + transform: translateY(-20px); + transition: all 0.3s ease-in-out; + } + + .answerBox.open { + max-height: 500px; + opacity: 1; + transform: translateY(0); } } } @@ -103,3 +114,5 @@ } } } + + diff --git a/containers/Header/Header.jsx b/containers/Header/Header.jsx index b61754e..02ccec1 100644 --- a/containers/Header/Header.jsx +++ b/containers/Header/Header.jsx @@ -1,4 +1,4 @@ -import React, { useContext, useEffect, useState } from "react"; +import React, { useContext, useEffect, useRef, useState } from "react"; import { RiCloseLine, RiMenuFill } from "react-icons/ri"; import Styles from "./header.module.scss"; @@ -39,7 +39,6 @@ const links = [ path: "", href: "https://docs.lighthouse.storage/lighthouse-1/", }, - { title: "Contact us", path: "", @@ -49,9 +48,9 @@ const links = [ function Header({ style }) { const [toggleMenu, setToggleMenu] = useState(false); - const [scrollTop, setScrollTop] = useState(); - const [scrolling, setScrolling] = useState(); - const [currentRoute, setCurrentRoute] = useState(); + const [scrollTop, setScrollTop] = useState(0); + const [scrolling, setScrolling] = useState(false); + const [currentRoute, setCurrentRoute] = useState(""); const { theme, setTheme } = useContext(ThemeContext); const _navigate = useRouter(); @@ -59,18 +58,47 @@ function Header({ style }) { setCurrentRoute(_navigate?.route); }, [_navigate]); + const prevScrollRef = useRef(scrollTop); + useEffect(() => { const onScroll = (e) => { - setScrollTop(e.target.documentElement.scrollTop); - setScrolling(e.target.documentElement.scrollTop > scrollTop); + const newScrollTop = e.target.documentElement.scrollTop; + setScrollTop(newScrollTop); + setScrolling(newScrollTop > prevScrollRef.current); + // This is done to close the mobile menu when scrolling + if (Math.abs(newScrollTop - prevScrollRef.current) > 50) { + setToggleMenu(false); + } + prevScrollRef.current = newScrollTop; }; window.addEventListener("scroll", onScroll); return () => window.removeEventListener("scroll", onScroll); - }, [scrollTop]); + }, []); useEffect(() => { + if (toggleMenu) { + document.body.classList.add('menu-open'); + } else { + document.body.classList.remove('menu-open'); + } + + return () => { + document.body.classList.remove('menu-open'); + }; + }, [toggleMenu]); + + const handleLinkClick = (link) => { setToggleMenu(false); - }, [scrolling]); + if (link.path.length > 0) { + _navigate.push(link.path); + } else if (link.href) { + window.open(link.href, "_blank", "noopener,noreferrer"); + } + }; + + const toggleTheme = () => { + setTheme(theme === "light" ? "dark" : "light"); + }; return (
@@ -78,12 +106,45 @@ function Header({ style }) {
{ - _navigate.push("/"); - }} + onClick={() => _navigate.push("/")} > brandLogo
+
+
+ { + if (e.key === "Enter" || e.key === " ") { + toggleTheme(); + } + }} + > + {theme === "light" ? ( + + ) : ( + + )} + + {toggleMenu ? ( + setToggleMenu(false)} + /> + ) : ( + setToggleMenu(true)} + /> + )} + +
{links.map((link, index) => ( @@ -94,7 +155,7 @@ function Header({ style }) { className={currentRoute === link.path ? Styles.active : ""} onClick={(e) => { e.preventDefault(); - _navigate.push(link.path); + handleLinkClick(link); }} > {link.title} @@ -120,27 +181,18 @@ function Header({ style }) { className="ptr" tabIndex={0} role="button" - aria-label={`Switch to ${ - theme === "light" ? "dark" : "light" - } mode`} + aria-label={`Switch to ${theme === "light" ? "dark" : "light" + } mode`} onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { - setTheme(theme === "light" ? "dark" : "light"); + toggleTheme(); } }} > {theme === "light" ? ( - { - setTheme("dark"); - }} - /> + ) : ( - { - setTheme("light"); - }} - /> + )}
-
- {toggleMenu ? ( - { - setToggleMenu(false); - }} - > - ) : ( - { - setToggleMenu(true); - }} - > - )} - - {toggleMenu && ( -
- {links.map((link, index) => ( -

- {link.path.length > 0 ? ( - { - e.preventDefault(); - _navigate.push(link.path); - }} - > - {link.title} - - ) : ( - - {link.title} - - )} -

- ))} - - -
- )} + {link.title} + {link.path.length === 0 && } + +

+ ))} + +
); diff --git a/containers/Header/header.module.scss b/containers/Header/header.module.scss index 4eb7ee0..e64d7c3 100644 --- a/containers/Header/header.module.scss +++ b/containers/Header/header.module.scss @@ -46,7 +46,7 @@ border-bottom: 1.5px solid rgb(255, 255, 255); } } - } + }> .buttonContainer { @include flex-centered; @@ -99,20 +99,7 @@ } .MobileMenu { - display: flex; - justify-content: flex-start; - align-items: flex-end; - flex-direction: column; - text-align: end; - background-color: #000000; - padding: 1em; - position: absolute; - top: 20px; - right: 0; - margin-top: 1rem; - min-width: 230px; - border-radius: 5px; - box-shadow: 1px 6px 11px 0px rgb(255 69 129 / 52%); + display: none; p { margin: 0.5rem 0.5rem; @@ -120,24 +107,182 @@ } } +@media screen and (max-width: 1200px) { + .Header { + .infoContainer { + padding: 0 2rem; + + .logoContainer { + margin-right: 1rem; + + .imageBox { + width: 120px; + min-height: 50px; + } + } + + .linksContainer { + flex-wrap: wrap; + justify-content: center; + gap: 0.5rem; + + p { + margin: 0 0.5rem; + + a { + font-size: 0.8rem; + } + } + } + + .buttonContainer { + gap: 0.5rem; + + span { + font-size: 1.2rem; + } + + button { + padding: 0.4rem 1.5rem; + font-size: 0.9rem; + } + } + } + } +} + @media screen and (max-width: 800px) { .Header { + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: 1000; + background-color: var(--clr-bg-black); + .navbarMobileMenu { display: flex; + align-items: center; + gap: 1rem; margin-left: 10px; + position: relative; + z-index: 1002; + + svg { + width: 24px; + height: 24px; + } } .infoContainer { + padding: 1rem; + position: relative; + z-index: 1001; + display: flex; + justify-content: space-between; + align-items: center; + .linksContainer, - button { + .buttonContainer { display: none; } + + .logoContainer { + .imageBox { + width: 100px; + min-height: 40px; + } + } } - - .navbar__link__logo p { - font-size: 20px; - font-family: var(--font-sans); - margin: 0px 0px; + + .MobileMenu { + position: fixed; + top: 80px; + left: 10px; + right: 10px; + max-width: calc(100% - 20px); + max-height: calc(100vh - 120px); + background-color: var(--clr-bg-black); + border-radius: 10px; + padding: 1rem; + display: flex; + flex-direction: column; + align-items: center; + overflow: hidden; + z-index: 1000; + box-shadow: 0 4px 20px rgba(0,0,0,0.3); + opacity: 0; + visibility: hidden; + transform: translateY(-30px) scale(0.95); + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + + &.open { + opacity: 1; + visibility: visible; + transform: translateY(0) scale(1); + } + + p { + width: 100%; + text-align: center; + margin: 0.5rem 0; + opacity: 0; + transform: translateY(20px); + transition: all 0.3s ease-out; + + a { + display: block; + padding: 0.75rem; + font-size: 1rem; + color: white; + text-decoration: none; + text-align: left; + border-radius: 5px; + + &:hover { + background-color: rgba(255,255,255,0.1); + } + + svg { + margin-left: 0.5rem; + vertical-align: middle; + } + } + } + + button { + width: 90%; + margin: 1rem auto; + padding: 0.75rem; + font-size: 1rem; + opacity: 0; + transform: translateY(20px); + transition: all 0.3s ease-out; + } + + &.open { + p { + opacity: 1; + transform: translateY(0); + &:nth-child(1) { transition-delay: 0.1s; } + &:nth-child(2) { transition-delay: 0.15s; } + &:nth-child(3) { transition-delay: 0.2s; } + &:nth-child(4) { transition-delay: 0.25s; } + &:nth-child(5) { transition-delay: 0.3s; } + &:nth-child(6) { transition-delay: 0.35s; } + &:nth-child(7) { transition-delay: 0.4s; } + } + + button { + opacity: 1; + transform: translateY(0); + transition-delay: 0.45s; + } + } } } + + body.menu-open { + overflow: hidden; + } } diff --git a/containers/LighthouseSuit/LighthouseSuit.module.scss b/containers/LighthouseSuit/LighthouseSuit.module.scss index 6bead53..f50c09e 100644 --- a/containers/LighthouseSuit/LighthouseSuit.module.scss +++ b/containers/LighthouseSuit/LighthouseSuit.module.scss @@ -27,7 +27,7 @@ .description { margin-bottom: 1rem; font-weight: 400; - color: #A3AAB8; + color: var(--answer-text-color, #4d4d4d); } .learnMore { @@ -77,7 +77,7 @@ .featureDescription { font-weight: 400; - color: #A3AAB8; + color: var(--answer-text-color, #4d4d4d); font-size: 0.9rem; } } diff --git a/utils/services/theme.js b/utils/services/theme.js index 36ee513..bccae84 100644 --- a/utils/services/theme.js +++ b/utils/services/theme.js @@ -39,6 +39,11 @@ const ThemeProperties = [ dark: `url("/wavePattern_dark.svg")`, light: `url("/wavePattern_light.svg")`, }, + { + property: "--answer-text-color", + dark: "#a3aab8", + light: "#4d4d4d", + }, ]; export const themeChanger = (theme) => {