diff --git a/public/images/app/homepage/join-the-community/community-1.jpg b/public/images/app/homepage/join-the-community/community-1.jpg new file mode 100644 index 00000000..716aaa35 Binary files /dev/null and b/public/images/app/homepage/join-the-community/community-1.jpg differ diff --git a/public/images/app/homepage/join-the-community/community-2.jpg b/public/images/app/homepage/join-the-community/community-2.jpg new file mode 100644 index 00000000..efab48aa Binary files /dev/null and b/public/images/app/homepage/join-the-community/community-2.jpg differ diff --git a/public/images/app/homepage/join-the-community/community-3.jpg b/public/images/app/homepage/join-the-community/community-3.jpg new file mode 100644 index 00000000..12b80c5f Binary files /dev/null and b/public/images/app/homepage/join-the-community/community-3.jpg differ diff --git a/src/app/community/page.js b/src/app/community/page.js index e3040e8f..7c4593d0 100644 --- a/src/app/community/page.js +++ b/src/app/community/page.js @@ -1,9 +1,9 @@ -import SecondaryHero from "@/components/Heroes/SecondaryHero"; +import EcosystemPage from "@/components/CallToActions/EcosystemPage"; +import IconCard from "@/components/Cards/IconCards/IconCard"; import Container from "@/components/Container/Container"; +import SecondaryHero from "@/components/Heroes/SecondaryHero"; +import { Body, Display } from "@/macros/Copy"; import { Col, Row } from "@/macros/Grids"; -import { Display, Body } from "@/macros/Copy"; -import IconCard from "@/components/Cards/IconCards/IconCard"; -import EcosystemPage from "@/components/CallToActions/EcosystemPage"; import meta from "@/components/Meta/Meta"; import seo from "@/data/community/seo"; diff --git a/src/app/page.js b/src/app/page.js index 890daf8b..07bbbd7a 100644 --- a/src/app/page.js +++ b/src/app/page.js @@ -2,11 +2,13 @@ import AlternatingMediaRows from "@/components/AlternatingMediaRows/AlternatingM import AppsCarousel from "@/components/AppsCarousel/AppsCarousel"; import ExploreCard from "@/components/Cards/ExploreCards/ExploreCard"; import ExploreCardsContainer from "@/components/Cards/ExploreCards/ExploreCardsContainer"; +import CommunityCarousel from "@/components/CommunityCarousel/CommunityCarousel"; import EcosytemExplorer from "@/components/Ecosystem/EcosytemExplorer/EcosytemExplorer"; import PrimaryHero from "@/components/Heroes/PrimaryHero"; import Blog from "@/components/Resources/Blog/Blog"; import { ANALYTICS_EVENTS } from "@/constants/analytics"; import { appItems } from "@/data/home/apps-on-celestia"; +import { communityItems } from "@/data/home/community-items"; import { Link } from "@/micros/TertiaryPageMicors/TertiaryPageMicors"; export default async function Home() { @@ -41,6 +43,8 @@ export default async function Home() { + + ( -
+
{title} @@ -121,14 +121,14 @@ const AppsCarousel = ({ items }) => { return (
- +
Apps on Celestia
-
+
{items.map((item) => ( diff --git a/src/components/CommunityCarousel/CommunityCarousel.js b/src/components/CommunityCarousel/CommunityCarousel.js new file mode 100644 index 00000000..60bade9d --- /dev/null +++ b/src/components/CommunityCarousel/CommunityCarousel.js @@ -0,0 +1,145 @@ +"use client"; + +import Container from "@/components/Container/Container"; +import { eventSlides } from "@/data/home/community-items"; +import { Body, Display } from "@/macros/Copy"; +import Icon from "@/macros/Icons/Icon"; +import ArrowLongSVG from "@/macros/SVGs/ArrowLongSVG"; +import { useRef } from "react"; +import Slider from "react-slick"; +import "slick-carousel/slick/slick-theme.css"; +import "slick-carousel/slick/slick.css"; + +const CommunityCard = ({ title, description, icon, url }) => ( + +
{icon && icon}
+
+
{title}
+
{description}
+
+
+); + +const EventSlide = ({ title, image }) => ( +
+
+ {title} +
+
{title}
+
+
+
+); + +const NavigationButtons = ({ sliderRef, className }) => ( +
+ + +
+); + +const CommunityCarousel = ({ items }) => { + const sliderRef = useRef(null); + + const settings = { + dots: false, + infinite: true, + speed: 500, + slidesToShow: 1, + slidesToScroll: 1, + arrows: false, + variableWidth: true, + swipeToSlide: true, + centerMode: false, + centerPadding: "0px", + responsive: [ + { + breakpoint: 1024, + settings: { + variableWidth: false, + adaptiveHeight: true, + centerPadding: "0px", + slidesToShow: 1, + slidesToScroll: 1, + centerMode: true, + }, + }, + { + breakpoint: 768, + settings: { + variableWidth: false, + adaptiveHeight: true, + centerPadding: "12px", + slidesToShow: 1, + slidesToScroll: 1, + centerMode: true, + }, + }, + ], + }; + + return ( +
+ + + Join the community + +
+ + Join the Celestia community online or hang out at one of the grassroots Modular Meetups + + +
+ +
+ {/* Social Links Column */} +
+
+ {items.map((item) => ( + + ))} +
+
+ + {/* Carousel Column */} +
+
+ + {eventSlides.map((slide, index) => ( + + ))} + +
+
+ + {/* Mobile Navigation Buttons */} + +
+
+
+ ); +}; + +export default CommunityCarousel; diff --git a/src/components/EmblaCarousel/EmblaCarousel.js b/src/components/EmblaCarousel/EmblaCarousel.js deleted file mode 100644 index ed16544e..00000000 --- a/src/components/EmblaCarousel/EmblaCarousel.js +++ /dev/null @@ -1,58 +0,0 @@ -import React from "react"; -import { DotButton, useDotButton } from "./EmblaCarouselDotButtons"; -import { - PrevButton, - NextButton, - usePrevNextButtons, -} from "./EmblaCarouselArrowButtons"; -import useEmblaCarousel from "embla-carousel-react"; - -const EmblaCarousel = ({ children, options }) => { - // const { slides, options } = props - const [emblaRef, emblaApi] = useEmblaCarousel(options); - - const { selectedIndex, scrollSnaps, onDotButtonClick } = - useDotButton(emblaApi); - - const { - prevBtnDisabled, - nextBtnDisabled, - onPrevButtonClick, - onNextButtonClick, - } = usePrevNextButtons(emblaApi); - - return ( -
-
-
- {children.map((child, index) => ( -
- {child} -
- ))} -
-
- -
-
- - -
- -
- {scrollSnaps.map((_, index) => ( - onDotButtonClick(index)} - className={"embla__dot".concat( - index === selectedIndex ? " embla__dot--selected" : "" - )} - /> - ))} -
-
-
- ); -}; - -export default EmblaCarousel; diff --git a/src/components/EmblaCarousel/EmblaCarouselArrowButtons.js b/src/components/EmblaCarousel/EmblaCarouselArrowButtons.js deleted file mode 100644 index 4f30ab34..00000000 --- a/src/components/EmblaCarousel/EmblaCarouselArrowButtons.js +++ /dev/null @@ -1,77 +0,0 @@ -import React, { useCallback, useEffect, useState } from "react"; - -export const usePrevNextButtons = (emblaApi, onButtonClick) => { - const [prevBtnDisabled, setPrevBtnDisabled] = useState(true); - const [nextBtnDisabled, setNextBtnDisabled] = useState(true); - - const onPrevButtonClick = useCallback(() => { - if (!emblaApi) return; - emblaApi.scrollPrev(); - if (onButtonClick) onButtonClick(emblaApi); - }, [emblaApi, onButtonClick]); - - const onNextButtonClick = useCallback(() => { - if (!emblaApi) return; - emblaApi.scrollNext(); - if (onButtonClick) onButtonClick(emblaApi); - }, [emblaApi, onButtonClick]); - - const onSelect = useCallback((emblaApi) => { - setPrevBtnDisabled(!emblaApi.canScrollPrev()); - setNextBtnDisabled(!emblaApi.canScrollNext()); - }, []); - - useEffect(() => { - if (!emblaApi) return; - - onSelect(emblaApi); - emblaApi.on("reInit", onSelect).on("select", onSelect); - }, [emblaApi, onSelect]); - - return { - prevBtnDisabled, - nextBtnDisabled, - onPrevButtonClick, - onNextButtonClick, - }; -}; - -export const PrevButton = (props) => { - const { children, ...restProps } = props; - - return ( - - ); -}; - -export const NextButton = (props) => { - const { children, ...restProps } = props; - - return ( - - ); -}; diff --git a/src/components/EmblaCarousel/EmblaCarouselDotButtons.js b/src/components/EmblaCarousel/EmblaCarouselDotButtons.js deleted file mode 100644 index ed2c5526..00000000 --- a/src/components/EmblaCarousel/EmblaCarouselDotButtons.js +++ /dev/null @@ -1,46 +0,0 @@ -import React, { useCallback, useEffect, useState } from "react"; - -export const useDotButton = (emblaApi) => { - const [selectedIndex, setSelectedIndex] = useState(0); - const [scrollSnaps, setScrollSnaps] = useState([]); - - const onDotButtonClick = useCallback( - (index) => { - if (!emblaApi) return; - emblaApi.scrollTo(index); - }, - [emblaApi] - ); - - const onInit = useCallback((emblaApi) => { - setScrollSnaps(emblaApi.scrollSnapList()); - }, []); - - const onSelect = useCallback((emblaApi) => { - setSelectedIndex(emblaApi.selectedScrollSnap()); - }, []); - - useEffect(() => { - if (!emblaApi) return; - - onInit(emblaApi); - onSelect(emblaApi); - emblaApi.on("reInit", onInit).on("reInit", onSelect).on("select", onSelect); - }, [emblaApi, onInit, onSelect]); - - return { - selectedIndex, - scrollSnaps, - onDotButtonClick, - }; -}; - -export const DotButton = (props) => { - const { children, ...restProps } = props; - - return ( - - ); -}; diff --git a/src/components/Nav/data.js b/src/components/Nav/data.js index bc486091..1ef86ed7 100644 --- a/src/components/Nav/data.js +++ b/src/components/Nav/data.js @@ -1,60 +1,62 @@ const MenuData = [ - { - name: 'Learn', - type: 'dropdown', - items: [ - { - name: 'What is Celestia?', - url: '/what-is-celestia/' - }, - { - name: 'Intro to data availability', - url: '/what-is-da/' - }, - { - name: 'Dive into modular', - url: '/learn/' - }, - { - name: 'Read the whitepaper', - url: 'https://arxiv.org/abs/1905.09274' - } - ] - }, { - name: 'Build', - type: 'dropdown', - items: [ - { - name: 'Start with the dev portal', - url: '/build/' - }, - { - name: 'Read the docs', - url: 'https://docs.celestia.org/' - }, - { - name: 'View the GitHub repos', - url: 'https://github.com/celestiaorg' - } - ] - }, { - name: 'Community', - type: 'dropdown', - items: [ - { - name: 'Run a node', - url: '/run-a-light-node/' - }, - { - name: 'Events', - url: '/events/' - }, - { - name: 'Celestia social channels', - url: '/community/' - } - ] - } -] + { + name: "Learn", + type: "dropdown", + items: [ + { + name: "What is Celestia?", + url: "/what-is-celestia/", + }, + { + name: "Intro to data availability", + url: "/what-is-da/", + }, + { + name: "Dive into modular", + url: "/learn/", + }, + { + name: "Read the whitepaper", + url: "https://arxiv.org/abs/1905.09274", + }, + ], + }, + { + name: "Build", + type: "dropdown", + items: [ + { + name: "Start with the dev portal", + url: "/build/", + }, + { + name: "Read the docs", + url: "https://docs.celestia.org/", + }, + { + name: "View the GitHub repos", + url: "https://github.com/celestiaorg", + }, + ], + }, + { + name: "Community", + type: "dropdown", + items: [ + { + name: "Run a node", + url: "/run-a-light-node/", + }, + { + name: "Events", + url: "/events/", + }, + { + name: "Celestia social channels", + url: "/community/", + }, + ], + }, +]; export default MenuData; diff --git a/src/data/home/community-items.js b/src/data/home/community-items.js new file mode 100644 index 00000000..c2f14304 --- /dev/null +++ b/src/data/home/community-items.js @@ -0,0 +1,74 @@ +import CommunityDiscordSVG from "@/macros/SVGs/CommunityDiscordSVG"; +import CommunityForumSVG from "@/macros/SVGs/CommunityForumSVG"; +import CommunityGithubSVG from "@/macros/SVGs/CommunityGithubSVG"; +import CommunityRedditSVG from "@/macros/SVGs/CommunityRedditSVG"; +import CommunityTelegramSVG from "@/macros/SVGs/CommunityTelegramSVG"; +import CommunityXSVG from "@/macros/SVGs/CommunityXSVG"; + +// Social Links +export const communityItems = [ + { + id: "twitter", + title: "X", + description: "Read the latest", + url: "https://twitter.com/CelestiaOrg", + icon: , + label: "Read the latest", + }, + { + id: "discord", + title: "Discord", + description: "Get involved", + url: "https://discord.gg/celestia", + icon: , + label: "Get involved", + }, + { + id: "reddit", + title: "Reddit", + description: "Ask the devs", + url: "https://reddit.com/r/celestia", + icon: , + label: "Ask the devs", + }, + { + id: "github", + title: "Github", + description: "Build with us", + url: "https://github.com/celestiaorg", + icon: , + label: "Build with us", + }, + { + id: "telegram", + title: "Telegram", + description: "Join discussion", + url: "https://t.me/celestiaorg", + icon: , + label: "Join discussion", + }, + { + id: "forum", + title: "Forum", + description: "Read Updates", + url: "https://forum.celestia.org", + icon: , + label: "Read Updates", + }, +]; + +// Community Carousel Event Slides +export const eventSlides = [ + { + title: "Modular Summit 2023", + image: "/images/app/homepage/join-the-community/community-1.jpg", + }, + { + title: "Modular Meetup", + image: "/images/app/homepage/join-the-community/community-2.jpg", + }, + { + title: "Additional Event", + image: "/images/app/homepage/join-the-community/community-3.jpg", + }, +]; diff --git a/src/macros/SVGs/CommunityDiscordSVG.js b/src/macros/SVGs/CommunityDiscordSVG.js new file mode 100644 index 00000000..bfbf7cef --- /dev/null +++ b/src/macros/SVGs/CommunityDiscordSVG.js @@ -0,0 +1,26 @@ +import useThemeColors from "@/utils/useThemeColors"; + +const CommunityDiscordSVG = ({ dark = false, className = "" }) => { + const colors = useThemeColors(); + const primaryColor = dark ? colors.white.DEFAULT : colors.black.DEFAULT; + const secondaryColor = dark ? colors.black.DEFAULT : colors.white.DEFAULT; + + return ( + + + + + + + + + + + + ); +}; + +export default CommunityDiscordSVG; diff --git a/src/macros/SVGs/CommunityForumSVG.js b/src/macros/SVGs/CommunityForumSVG.js new file mode 100644 index 00000000..fcd95970 --- /dev/null +++ b/src/macros/SVGs/CommunityForumSVG.js @@ -0,0 +1,21 @@ +import useThemeColors from "@/utils/useThemeColors"; + +const CommunityForumSVG = ({ dark = false, className = "" }) => { + const colors = useThemeColors(); + const primaryColor = dark ? colors.white.DEFAULT : colors.black.DEFAULT; + const secondaryColor = dark ? colors.black.DEFAULT : colors.white.DEFAULT; + + return ( + + + + + ); +}; + +export default CommunityForumSVG; diff --git a/src/macros/SVGs/CommunityGithubSVG.js b/src/macros/SVGs/CommunityGithubSVG.js new file mode 100644 index 00000000..93847c08 --- /dev/null +++ b/src/macros/SVGs/CommunityGithubSVG.js @@ -0,0 +1,56 @@ +import useThemeColors from "@/utils/useThemeColors"; + +const CommunityGithubSVG = ({ dark = false, className = "" }) => { + const colors = useThemeColors(); + const primaryColor = dark ? colors.white.DEFAULT : colors.black.DEFAULT; + const secondaryColor = dark ? colors.black.DEFAULT : colors.white.DEFAULT; + + return ( + + + + + + + + + + + + + + + + + + + ); +}; + +export default CommunityGithubSVG; diff --git a/src/macros/SVGs/CommunityRedditSVG.js b/src/macros/SVGs/CommunityRedditSVG.js new file mode 100644 index 00000000..9f70bcb0 --- /dev/null +++ b/src/macros/SVGs/CommunityRedditSVG.js @@ -0,0 +1,30 @@ +import useThemeColors from "@/utils/useThemeColors"; + +const CommunityRedditSVG = ({ dark = false, className = "" }) => { + const colors = useThemeColors(); + const primaryColor = dark ? colors.white.DEFAULT : colors.black.DEFAULT; + const secondaryColor = dark ? colors.black.DEFAULT : colors.white.DEFAULT; + + return ( + + + + + + + + + + + + + ); +}; + +export default CommunityRedditSVG; diff --git a/src/macros/SVGs/CommunityTelegramSVG.js b/src/macros/SVGs/CommunityTelegramSVG.js new file mode 100644 index 00000000..4e131750 --- /dev/null +++ b/src/macros/SVGs/CommunityTelegramSVG.js @@ -0,0 +1,32 @@ +import useThemeColors from "@/utils/useThemeColors"; + +const CommunityTelegramSVG = ({ dark = false, className = "" }) => { + const colors = useThemeColors(); + const primaryColor = dark ? colors.white.DEFAULT : colors.black.DEFAULT; + const secondaryColor = dark ? colors.black.DEFAULT : colors.white.DEFAULT; + + return ( + + + + + + + + + + + + + ); +}; + +export default CommunityTelegramSVG; diff --git a/src/macros/SVGs/CommunityXSVG.js b/src/macros/SVGs/CommunityXSVG.js new file mode 100644 index 00000000..ef1b984f --- /dev/null +++ b/src/macros/SVGs/CommunityXSVG.js @@ -0,0 +1,26 @@ +import useThemeColors from "@/utils/useThemeColors"; + +const CommunityXSVG = ({ dark = false, className = "" }) => { + const colors = useThemeColors(); + const primaryColor = dark ? colors.white.DEFAULT : colors.black.DEFAULT; + const secondaryColor = dark ? colors.black.DEFAULT : colors.white.DEFAULT; + + return ( + + + + + + + + + + + + ); +}; + +export default CommunityXSVG; diff --git a/src/macros/SVGs/DropdownArrow.js b/src/macros/SVGs/DropdownArrow.js index b0139c0e..eff2c455 100644 --- a/src/macros/SVGs/DropdownArrow.js +++ b/src/macros/SVGs/DropdownArrow.js @@ -1,28 +1,20 @@ import useThemeColors from "@/utils/useThemeColors"; const DropdownArrow = ({ dark = false, className = "" }) => { - const colors = useThemeColors(); - const fill = dark ? colors.white.DEFAULT : colors.black.DEFAULT; + const colors = useThemeColors(); + const fill = dark ? colors.white.DEFAULT : colors.black.DEFAULT; - return ( - - - - ); + return ( + + + + ); }; export default DropdownArrow; diff --git a/tailwind.config.js b/tailwind.config.js index c56abe2f..53695708 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -31,6 +31,9 @@ module.exports = { ], theme: { extend: { + screens: { + "3xl": "1520px", + }, backgroundImage: { "gradient-radial": "radial-gradient(var(--tw-gradient-stops))", "gradient-conic": "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",