diff --git a/.next/package.json b/.next/package.json
new file mode 100644
index 00000000..7156107e
--- /dev/null
+++ b/.next/package.json
@@ -0,0 +1 @@
+{"type": "commonjs"}
\ No newline at end of file
diff --git a/.next/prerender-manifest.js b/.next/prerender-manifest.js
new file mode 100644
index 00000000..d8030945
--- /dev/null
+++ b/.next/prerender-manifest.js
@@ -0,0 +1 @@
+self.__PRERENDER_MANIFEST="{\"preview\":{\"previewModeId\":\"process.env.__NEXT_PREVIEW_MODE_ID\",\"previewModeSigningKey\":\"process.env.__NEXT_PREVIEW_MODE_SIGNING_KEY\",\"previewModeEncryptionKey\":\"process.env.__NEXT_PREVIEW_MODE_ENCRYPTION_KEY\"}}"
\ No newline at end of file
diff --git a/.next/routes-manifest.json b/.next/routes-manifest.json
new file mode 100644
index 00000000..5213896a
--- /dev/null
+++ b/.next/routes-manifest.json
@@ -0,0 +1 @@
+{"version":3,"pages404":true,"caseSensitive":false,"basePath":"","redirects":[{"source":"/:path+/","destination":"/:path+","internal":true,"statusCode":308,"regex":"^(?:/((?:[^/]+?)(?:/(?:[^/]+?))*))/$"}],"headers":[],"dynamicRoutes":[],"staticRoutes":[{"page":"/","regex":"^/(?:/)?$","routeKeys":{},"namedRegex":"^/(?:/)?$"},{"page":"/404","regex":"^/404(?:/)?$","routeKeys":{},"namedRegex":"^/404(?:/)?$"},{"page":"/build","regex":"^/build(?:/)?$","routeKeys":{},"namedRegex":"^/build(?:/)?$"},{"page":"/careers","regex":"^/careers(?:/)?$","routeKeys":{},"namedRegex":"^/careers(?:/)?$"},{"page":"/community","regex":"^/community(?:/)?$","routeKeys":{},"namedRegex":"^/community(?:/)?$"},{"page":"/ecosystem","regex":"^/ecosystem(?:/)?$","routeKeys":{},"namedRegex":"^/ecosystem(?:/)?$"},{"page":"/events","regex":"^/events(?:/)?$","routeKeys":{},"namedRegex":"^/events(?:/)?$"},{"page":"/faq","regex":"^/faq(?:/)?$","routeKeys":{},"namedRegex":"^/faq(?:/)?$"},{"page":"/glossary","regex":"^/glossary(?:/)?$","routeKeys":{},"namedRegex":"^/glossary(?:/)?$"},{"page":"/glossary/block-header","regex":"^/glossary/block\\-header(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/block\\-header(?:/)?$"},{"page":"/glossary/block-producer","regex":"^/glossary/block\\-producer(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/block\\-producer(?:/)?$"},{"page":"/glossary/block-space","regex":"^/glossary/block\\-space(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/block\\-space(?:/)?$"},{"page":"/glossary/blockchain-cluster","regex":"^/glossary/blockchain\\-cluster(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/blockchain\\-cluster(?:/)?$"},{"page":"/glossary/composability","regex":"^/glossary/composability(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/composability(?:/)?$"},{"page":"/glossary/consensus","regex":"^/glossary/consensus(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/consensus(?:/)?$"},{"page":"/glossary/consensus-algorithm","regex":"^/glossary/consensus\\-algorithm(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/consensus\\-algorithm(?:/)?$"},{"page":"/glossary/consensus-layer","regex":"^/glossary/consensus\\-layer(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/consensus\\-layer(?:/)?$"},{"page":"/glossary/cosmos-sdk","regex":"^/glossary/cosmos\\-sdk(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/cosmos\\-sdk(?:/)?$"},{"page":"/glossary/cross-chain-interoperability","regex":"^/glossary/cross\\-chain\\-interoperability(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/cross\\-chain\\-interoperability(?:/)?$"},{"page":"/glossary/da","regex":"^/glossary/da(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/da(?:/)?$"},{"page":"/glossary/dac","regex":"^/glossary/dac(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/dac(?:/)?$"},{"page":"/glossary/das","regex":"^/glossary/das(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/das(?:/)?$"},{"page":"/glossary/data-availability","regex":"^/glossary/data\\-availability(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/data\\-availability(?:/)?$"},{"page":"/glossary/data-availability-committee","regex":"^/glossary/data\\-availability\\-committee(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/data\\-availability\\-committee(?:/)?$"},{"page":"/glossary/data-availability-layer","regex":"^/glossary/data\\-availability\\-layer(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/data\\-availability\\-layer(?:/)?$"},{"page":"/glossary/data-availability-sampling","regex":"^/glossary/data\\-availability\\-sampling(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/data\\-availability\\-sampling(?:/)?$"},{"page":"/glossary/data-throughput","regex":"^/glossary/data\\-throughput(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/data\\-throughput(?:/)?$"},{"page":"/glossary/data-withholding-attack","regex":"^/glossary/data\\-withholding\\-attack(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/data\\-withholding\\-attack(?:/)?$"},{"page":"/glossary/dispute-resolution","regex":"^/glossary/dispute\\-resolution(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/dispute\\-resolution(?:/)?$"},{"page":"/glossary/ee","regex":"^/glossary/ee(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/ee(?:/)?$"},{"page":"/glossary/execution","regex":"^/glossary/execution(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/execution(?:/)?$"},{"page":"/glossary/execution-environment","regex":"^/glossary/execution\\-environment(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/execution\\-environment(?:/)?$"},{"page":"/glossary/execution-layer","regex":"^/glossary/execution\\-layer(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/execution\\-layer(?:/)?$"},{"page":"/glossary/fee-market","regex":"^/glossary/fee\\-market(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/fee\\-market(?:/)?$"},{"page":"/glossary/fork","regex":"^/glossary/fork(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/fork(?:/)?$"},{"page":"/glossary/fork-choice-rule","regex":"^/glossary/fork\\-choice\\-rule(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/fork\\-choice\\-rule(?:/)?$"},{"page":"/glossary/full-node","regex":"^/glossary/full\\-node(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/full\\-node(?:/)?$"},{"page":"/glossary/honest-majority-assumption","regex":"^/glossary/honest\\-majority\\-assumption(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/honest\\-majority\\-assumption(?:/)?$"},{"page":"/glossary/honest-minority-assumption","regex":"^/glossary/honest\\-minority\\-assumption(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/honest\\-minority\\-assumption(?:/)?$"},{"page":"/glossary/inter-cluster-communication","regex":"^/glossary/inter\\-cluster\\-communication(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/inter\\-cluster\\-communication(?:/)?$"},{"page":"/glossary/intra-cluster-communication","regex":"^/glossary/intra\\-cluster\\-communication(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/intra\\-cluster\\-communication(?:/)?$"},{"page":"/glossary/isr","regex":"^/glossary/isr(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/isr(?:/)?$"},{"page":"/glossary/light-client","regex":"^/glossary/light\\-client(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/light\\-client(?:/)?$"},{"page":"/glossary/light-node","regex":"^/glossary/light\\-node(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/light\\-node(?:/)?$"},{"page":"/glossary/liveness","regex":"^/glossary/liveness(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/liveness(?:/)?$"},{"page":"/glossary/modular-blockchain","regex":"^/glossary/modular\\-blockchain(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/modular\\-blockchain(?:/)?$"},{"page":"/glossary/modular-stack","regex":"^/glossary/modular\\-stack(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/modular\\-stack(?:/)?$"},{"page":"/glossary/monolithic-blockchain","regex":"^/glossary/monolithic\\-blockchain(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/monolithic\\-blockchain(?:/)?$"},{"page":"/glossary/namespaced-merkle-tree","regex":"^/glossary/namespaced\\-merkle\\-tree(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/namespaced\\-merkle\\-tree(?:/)?$"},{"page":"/glossary/nmt","regex":"^/glossary/nmt(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/nmt(?:/)?$"},{"page":"/glossary/node","regex":"^/glossary/node(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/node(?:/)?$"},{"page":"/glossary/off-chain-data-availability","regex":"^/glossary/off\\-chain\\-data\\-availability(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/off\\-chain\\-data\\-availability(?:/)?$"},{"page":"/glossary/on-chain-data-availability","regex":"^/glossary/on\\-chain\\-data\\-availability(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/on\\-chain\\-data\\-availability(?:/)?$"},{"page":"/glossary/optimistic-rollup","regex":"^/glossary/optimistic\\-rollup(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/optimistic\\-rollup(?:/)?$"},{"page":"/glossary/oru","regex":"^/glossary/oru(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/oru(?:/)?$"},{"page":"/glossary/pay-for-data","regex":"^/glossary/pay\\-for\\-data(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/pay\\-for\\-data(?:/)?$"},{"page":"/glossary/peer-to-peer-network","regex":"^/glossary/peer\\-to\\-peer\\-network(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/peer\\-to\\-peer\\-network(?:/)?$"},{"page":"/glossary/pfb","regex":"^/glossary/pfb(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/pfb(?:/)?$"},{"page":"/glossary/proof-of-stake","regex":"^/glossary/proof\\-of\\-stake(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/proof\\-of\\-stake(?:/)?$"},{"page":"/glossary/qgb","regex":"^/glossary/qgb(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/qgb(?:/)?$"},{"page":"/glossary/rollup","regex":"^/glossary/rollup(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/rollup(?:/)?$"},{"page":"/glossary/safety","regex":"^/glossary/safety(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/safety(?:/)?$"},{"page":"/glossary/scalability","regex":"^/glossary/scalability(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/scalability(?:/)?$"},{"page":"/glossary/sequencer","regex":"^/glossary/sequencer(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/sequencer(?:/)?$"},{"page":"/glossary/settlement","regex":"^/glossary/settlement(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/settlement(?:/)?$"},{"page":"/glossary/settlement-layer","regex":"^/glossary/settlement\\-layer(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/settlement\\-layer(?:/)?$"},{"page":"/glossary/sharding","regex":"^/glossary/sharding(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/sharding(?:/)?$"},{"page":"/glossary/shared-security","regex":"^/glossary/shared\\-security(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/shared\\-security(?:/)?$"},{"page":"/glossary/slashing","regex":"^/glossary/slashing(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/slashing(?:/)?$"},{"page":"/glossary/smart-contract","regex":"^/glossary/smart\\-contract(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/smart\\-contract(?:/)?$"},{"page":"/glossary/social-consensus","regex":"^/glossary/social\\-consensus(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/social\\-consensus(?:/)?$"},{"page":"/glossary/sovereign-application","regex":"^/glossary/sovereign\\-application(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/sovereign\\-application(?:/)?$"},{"page":"/glossary/sovereign-blockchain","regex":"^/glossary/sovereign\\-blockchain(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/sovereign\\-blockchain(?:/)?$"},{"page":"/glossary/sovereign-rollup","regex":"^/glossary/sovereign\\-rollup(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/sovereign\\-rollup(?:/)?$"},{"page":"/glossary/state-transition-fraud-proof","regex":"^/glossary/state\\-transition\\-fraud\\-proof(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/state\\-transition\\-fraud\\-proof(?:/)?$"},{"page":"/glossary/synchrony-assumption","regex":"^/glossary/synchrony\\-assumption(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/synchrony\\-assumption(?:/)?$"},{"page":"/glossary/the-data-availability-problem","regex":"^/glossary/the\\-data\\-availability\\-problem(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/the\\-data\\-availability\\-problem(?:/)?$"},{"page":"/glossary/throughput","regex":"^/glossary/throughput(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/throughput(?:/)?$"},{"page":"/glossary/transaction-throughput","regex":"^/glossary/transaction\\-throughput(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/transaction\\-throughput(?:/)?$"},{"page":"/glossary/trust-minimized-bridge","regex":"^/glossary/trust\\-minimized\\-bridge(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/trust\\-minimized\\-bridge(?:/)?$"},{"page":"/glossary/trusted-bridge","regex":"^/glossary/trusted\\-bridge(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/trusted\\-bridge(?:/)?$"},{"page":"/glossary/validator","regex":"^/glossary/validator(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/validator(?:/)?$"},{"page":"/glossary/validator-set","regex":"^/glossary/validator\\-set(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/validator\\-set(?:/)?$"},{"page":"/glossary/validity-proof","regex":"^/glossary/validity\\-proof(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/validity\\-proof(?:/)?$"},{"page":"/glossary/validium","regex":"^/glossary/validium(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/validium(?:/)?$"},{"page":"/glossary/volition","regex":"^/glossary/volition(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/volition(?:/)?$"},{"page":"/glossary/zk-rollup","regex":"^/glossary/zk\\-rollup(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/zk\\-rollup(?:/)?$"},{"page":"/glossary/zkr","regex":"^/glossary/zkr(?:/)?$","routeKeys":{},"namedRegex":"^/glossary/zkr(?:/)?$"},{"page":"/learn","regex":"^/learn(?:/)?$","routeKeys":{},"namedRegex":"^/learn(?:/)?$"},{"page":"/press","regex":"^/press(?:/)?$","routeKeys":{},"namedRegex":"^/press(?:/)?$"},{"page":"/resources","regex":"^/resources(?:/)?$","routeKeys":{},"namedRegex":"^/resources(?:/)?$"},{"page":"/run-a-light-node","regex":"^/run\\-a\\-light\\-node(?:/)?$","routeKeys":{},"namedRegex":"^/run\\-a\\-light\\-node(?:/)?$"},{"page":"/technology","regex":"^/technology(?:/)?$","routeKeys":{},"namedRegex":"^/technology(?:/)?$"},{"page":"/what-is-celestia","regex":"^/what\\-is\\-celestia(?:/)?$","routeKeys":{},"namedRegex":"^/what\\-is\\-celestia(?:/)?$"},{"page":"/what-is-tia","regex":"^/what\\-is\\-tia(?:/)?$","routeKeys":{},"namedRegex":"^/what\\-is\\-tia(?:/)?$"},{"page":"/{MarkdownRemark.frontmatter__slug}","regex":"^/\\{MarkdownRemark\\.frontmatter__slug\\}(?:/)?$","routeKeys":{},"namedRegex":"^/\\{MarkdownRemark\\.frontmatter__slug\\}(?:/)?$"}],"dataRoutes":[],"rsc":{"header":"RSC","varyHeader":"RSC, Next-Router-State-Tree, Next-Router-Prefetch","prefetchHeader":"Next-Router-Prefetch","didPostponeHeader":"x-nextjs-postponed","contentTypeHeader":"text/x-component","suffix":".rsc","prefetchSuffix":".prefetch.rsc"},"rewrites":[]}
\ No newline at end of file
diff --git a/src/components/header.js b/src/components/header.js
index 6b159eb9..6c91ff01 100644
--- a/src/components/header.js
+++ b/src/components/header.js
@@ -74,10 +74,35 @@ const navigation = [
},
],
},
- {
- text: "Run a node",
- url: "/run-a-light-node/",
- type: "internal",
+ {
+ text: "Community",
+ url: "",
+ submenus: [
+ {
+ text: "Run a node",
+ subtext: "Directly verify",
+ url: "/run-a-light-node/",
+ icon: "menu/technology-svg.svg",
+ type: "internal",
+ class: "plausible-event-name=Light_Node_Button--Header",
+ },
+ {
+ text: "Events",
+ subtext: "Celestia community events",
+ url: "/events/",
+ icon: "menu/documentation.svg",
+ type: "internal",
+ class: "plausible-event-name=Events_Button--Header",
+ },
+ {
+ text: "Social",
+ subtext: "Celestia community socials",
+ url: "/community/",
+ icon: "menu/forum.svg",
+ type: "external",
+ class: "",
+ },
+ ],
},
];
diff --git a/src/components/imageComponent.js b/src/components/imageComponent.js
index 7a7d5428..11f12824 100644
--- a/src/components/imageComponent.js
+++ b/src/components/imageComponent.js
@@ -38,7 +38,7 @@ const Image = (props) => {
const imageData = getImage(image.node.childImageSharp);
- return ;
+ return ;
};
export default Image;
diff --git a/src/components/modules/event-card.js b/src/components/modules/event-card.js
new file mode 100644
index 00000000..6ded67cb
--- /dev/null
+++ b/src/components/modules/event-card.js
@@ -0,0 +1,69 @@
+import React from "react";
+import Image from "../imageComponent";
+
+const EventCard = ({ title, description, date, location, url, image }) => {
+ const truncateDescription = (text, limit) => {
+ if (text.length <= limit) return text;
+ return text.slice(0, limit).trim() + "...";
+ };
+
+ return (
+
+
+
+
+
{title}
+
{truncateDescription(description, 240)}
+
+
+
+
+
+
+
+ {date}
+
+
+
+
+ {location}
+
+
+
+
+
+
+
+ );
+};
+
+export default EventCard;
diff --git a/src/components/modules/event-list.js b/src/components/modules/event-list.js
new file mode 100644
index 00000000..617566d9
--- /dev/null
+++ b/src/components/modules/event-list.js
@@ -0,0 +1,59 @@
+import React from "react";
+import EventCard from "./event-card";
+import { eventData } from "../../datas/events/event-data";
+import { formatDateRange } from "../../utils/date-utils";
+
+const EventList = ({ eventsNumber, hasEventType, isNotFeatured, pastEvents }) => {
+ const getFilteredEvents = (count) => {
+ let filteredEvents = eventData;
+ const currentDate = new Date();
+ currentDate.setHours(0, 0, 0, 0); // Set to start of day for accurate comparison
+
+ // Filter events based on hasEventType if provided
+ if (hasEventType) {
+ filteredEvents = filteredEvents.filter((event) => event.eventType === hasEventType);
+ }
+
+ // Exclude featured events if isNotFeatured is true
+ if (isNotFeatured) {
+ filteredEvents = filteredEvents.filter((event) => !event.featured);
+ }
+
+ // Filter for past events or future/current events based on pastEvents prop
+ if (pastEvents) {
+ filteredEvents = filteredEvents.filter((event) => new Date(event.endDate || event.startDate) < currentDate);
+ } else {
+ filteredEvents = filteredEvents.filter((event) => new Date(event.startDate) >= currentDate);
+ }
+
+ // Sort events by date
+ const sortedEvents = filteredEvents.sort((a, b) => {
+ return pastEvents
+ ? new Date(b.startDate) - new Date(a.startDate) // Descending order for past events
+ : new Date(a.startDate) - new Date(b.startDate); // Ascending order for future events
+ });
+
+ // Return the specified number of events, or all if count is not provided
+ return count ? sortedEvents.slice(0, count) : sortedEvents;
+ };
+
+ const filteredEvents = getFilteredEvents(eventsNumber || null);
+
+ return (
+
+ {filteredEvents.map((event) => (
+
+ ))}
+
+ );
+};
+
+export default EventList;
diff --git a/src/components/modules/featured-event.js b/src/components/modules/featured-event.js
new file mode 100644
index 00000000..25ddd34c
--- /dev/null
+++ b/src/components/modules/featured-event.js
@@ -0,0 +1,96 @@
+import React from "react";
+import { eventData } from "../../datas/events/event-data";
+import Image from "../imageComponent";
+import { formatDateRange } from "../../utils/date-utils"; // Import the formatDateRange function
+
+const FeaturedEvent = () => {
+ const getFeaturedEvents = () => eventData.filter((event) => event.featured);
+ const featuredEvents = getFeaturedEvents();
+
+ const truncateDescription = (text, limit) => {
+ if (text.length <= limit) return text;
+ return text.slice(0, limit).trim() + "...";
+ };
+
+ return (
+
+ {featuredEvents.map((featuredEvent) => {
+ return (
+
+
+
+
+ {featuredEvent.category.map((tag, index) => (
+
+ {tag}
+
+ ))}
+
+
+
{featuredEvent.title}
+
+
+
+
+
+ {formatDateRange(featuredEvent.startDate, featuredEvent.endDate)}
+
+
+
+
+ {featuredEvent.location}
+
+
+
+
+
{truncateDescription(featuredEvent.description, 225)}
+
+
+
+
+
+ );
+ })}
+
+ );
+};
+
+export default FeaturedEvent;
diff --git a/src/datas/events/event-data.js b/src/datas/events/event-data.js
new file mode 100644
index 00000000..d8a721a2
--- /dev/null
+++ b/src/datas/events/event-data.js
@@ -0,0 +1,194 @@
+export const eventData = [
+ {
+ id: 1,
+ eventType: "celestia", // celestia, community
+ image: "events/rejected.png", // use 1200x800px image for cover image (3:2 ratio)
+ title: "Rejected",
+ description: "",
+ startDate: "2024-11-11", // date format: yy/mm/dd
+ endDate: "",
+ location: "Bangkok",
+ category: ["", ""],
+ url: "https://lu.ma/23mphcvd",
+ featured: true,
+ },
+ {
+ id: 2,
+ eventType: "celestia", // celestia, community
+ image: "events/modular-bangkok.png", // use 1200x800px image for cover image (3:2 ratio)
+ title: "Modular Bangkok",
+ description: "",
+ startDate: "2024-11-10",
+ endDate: "",
+ location: "Bangkok",
+ category: ["", ""],
+ url: "https://lu.ma/3elvoqpy",
+ featured: false,
+ },
+ {
+ id: 3,
+ eventType: "celestia", // celestia, community
+ image: "events/coworking.png", // use 1200x800px image for cover image (3:2 ratio)
+ title: "Celestia co-working cafe",
+ description: "",
+ startDate: "2024-11-12",
+ endDate: "2024-11-15",
+ location: "Bangkok",
+ category: ["", ""],
+ url: "https://lu.ma/2qzkjf9d",
+ featured: false,
+ },
+ {
+ id: 4,
+ eventType: "celestia", // celestia, community
+ image: "events/modular-summit-3.png", // use 1200x800px image for cover image (3:2 ratio)
+ title: "Modular Summit 3.0",
+ description: "",
+ startDate: "2024-07-11",
+ endDate: "2024-07-13",
+ location: "Brussels",
+ category: ["", ""],
+ url: "https://modularsummit.dev/",
+ featured: false,
+ },
+ {
+ id: 7,
+ eventType: "celestia", // celestia, community
+ image: "events/modular-day-2.png", // use 1200x800px image for cover image (3:2 ratio)
+ title: "Modular Day",
+ description: "",
+ startDate: "2024-02-28",
+ endDate: "",
+ location: "Denver",
+ category: ["", ""],
+ url: "https://lu.ma/ModularDayETHDenver",
+ featured: false,
+ },
+ {
+ id: 8,
+ eventType: "celestia", // celestia, community
+ image: "events/mod-acc.png", // use 1200x800px image for cover image (3:2 ratio)
+ title: "Modular Acceleration",
+ description: "",
+ startDate: "2024-03-01",
+ endDate: "",
+ location: "Denver",
+ category: ["", ""],
+ url: "https://lu.ma/modacc",
+ featured: false,
+ },
+ {
+ id: 10,
+ eventType: "community", // celestia, community
+ image: "events/modular-meetup-istanbul-4.png", // use 1200x800px image for cover image (3:2 ratio)
+ title: "Celestia Modular Meetup | Istanbul - 4",
+ description: "",
+ startDate: "2024-06-07",
+ endDate: "",
+ location: "Istanbul",
+ category: ["", ""],
+ url: "https://lu.ma/isyha9lz",
+ featured: false,
+ },
+ {
+ id: 11,
+ eventType: "community", // celestia, community
+ image: "events/modular-meetup-istanbul-3.png", // use 1200x800px image for cover image (3:2 ratio)
+ title: "Celestia Modular Meetup | Istanbul - 3",
+ description: "",
+ startDate: "2024-05-03",
+ endDate: "",
+ location: "Istanbul",
+ category: ["", ""],
+ url: "https://lu.ma/Modular-Meetup-Istanbul-3",
+ featured: false,
+ },
+ {
+ id: 12,
+ eventType: "community", // celestia, community
+ image: "events/modular-meetup-istanbul-2.png", // use 1200x800px image for cover image (3:2 ratio)
+ title: "Celestia Modular Meetup | Istanbul - 2",
+ description: "",
+ startDate: "2024-03-30",
+ endDate: "",
+ location: "Istanbul",
+ category: ["", ""],
+ url: "https://lu.ma/CelestiaModularMeetupIstanbul2",
+ featured: false,
+ },
+ {
+ id: 13,
+ eventType: "community", // celestia, community
+ image: "events/modular-meetup-istanbul.png", // use 1200x800px image for cover image (3:2 ratio)
+ title: "Celestia Modular Meetup | Istanbul",
+ description: "",
+ startDate: "2024-02-25",
+ endDate: "",
+ location: "Istanbul",
+ category: ["", ""],
+ url: "https://lu.ma/ModularMeetupIstanbul",
+ featured: false,
+ },
+ {
+ id: 14,
+ eventType: "community", // celestia, community
+ image: "events/modular-meetup-santiago-de-compostela.png", // use 1200x800px image for cover image (3:2 ratio)
+ title: "Modular Meetup Santiago de Compostela",
+ description: "",
+ startDate: "2024-06-28",
+ endDate: "",
+ location: "Santiago",
+ category: ["", ""],
+ url: "https://docs.google.com/forms/d/e/1FAIpQLSfBUQhgoLJXKinWDxdTkrg_ovSJmoXXI8pnvjsyMuC4zV-Qxg/viewform",
+ featured: false,
+ },
+ {
+ id: 15,
+ eventType: "community", // celestia, community
+ image: "events/modular-meetup-rio-de-janeiro.png", // use 1200x800px image for cover image (3:2 ratio)
+ title: "Modular Meetup Rio de Janeiro",
+ description: "",
+ startDate: "2024-02-14",
+ endDate: "",
+ location: "Rio de Janeiro",
+ category: ["", ""],
+ url: "https://lu.ma/pevt1mzf",
+ featured: false,
+ },
+ {
+ id: 16,
+ eventType: "celestia", // celestia, community
+ image: "events/modular-day.png", // use 1200x800px image for cover image (3:2 ratio)
+ title: "Modular Day",
+ description: "",
+ startDate: "2023-11-13",
+ endDate: "",
+ location: "Istanbul",
+ category: ["", ""],
+ url: "https://lu.ma/modularday",
+ featured: false,
+ },
+ {
+ id: 17,
+ eventType: "celestia", // celestia, community
+ image: "events/game-space.png", // use 1200x800px image for cover image (3:2 ratio)
+ title: "B3 Game Space",
+ description: "",
+ startDate: "2024-11-12",
+ endDate: "",
+ location: "Bangkok",
+ category: ["", ""],
+ url: "https://lu.ma/qblylm6i",
+ featured: false,
+ },
+];
+
+export const submitButton = {
+ label: "Submit your Event",
+ url: "https://forms.gle/R9ws9oAmd61MxAqu7",
+};
+
+export const viewAllButton = {
+ label: "View Past Events",
+ url: "/past-events",
+};
diff --git a/src/datas/events/seoContent.js b/src/datas/events/seoContent.js
new file mode 100644
index 00000000..39b337d1
--- /dev/null
+++ b/src/datas/events/seoContent.js
@@ -0,0 +1,6 @@
+export const seoContent = {
+ title: "Events | celestia.org",
+ ogTitle: "Events | celestia.org",
+ description: "Hangout with the Celestia community IRL or online.",
+ image: "/celestia-default-og-image.jpg",
+};
diff --git a/src/images/events/coworking.png b/src/images/events/coworking.png
new file mode 100644
index 00000000..7ed1ee9f
Binary files /dev/null and b/src/images/events/coworking.png differ
diff --git a/src/images/events/event-1.png b/src/images/events/event-1.png
new file mode 100644
index 00000000..3be447f3
Binary files /dev/null and b/src/images/events/event-1.png differ
diff --git a/src/images/events/game-space.png b/src/images/events/game-space.png
new file mode 100644
index 00000000..294b5e5a
Binary files /dev/null and b/src/images/events/game-space.png differ
diff --git a/src/images/events/mod-acc.png b/src/images/events/mod-acc.png
new file mode 100644
index 00000000..42293365
Binary files /dev/null and b/src/images/events/mod-acc.png differ
diff --git a/src/images/events/modular-bangkok.png b/src/images/events/modular-bangkok.png
new file mode 100644
index 00000000..cee64b10
Binary files /dev/null and b/src/images/events/modular-bangkok.png differ
diff --git a/src/images/events/modular-day-2.png b/src/images/events/modular-day-2.png
new file mode 100644
index 00000000..883bd5a8
Binary files /dev/null and b/src/images/events/modular-day-2.png differ
diff --git a/src/images/events/modular-day.png b/src/images/events/modular-day.png
new file mode 100644
index 00000000..aaf644fd
Binary files /dev/null and b/src/images/events/modular-day.png differ
diff --git a/src/images/events/modular-meetup-istanbul-2.png b/src/images/events/modular-meetup-istanbul-2.png
new file mode 100644
index 00000000..50678fc3
Binary files /dev/null and b/src/images/events/modular-meetup-istanbul-2.png differ
diff --git a/src/images/events/modular-meetup-istanbul-3.png b/src/images/events/modular-meetup-istanbul-3.png
new file mode 100644
index 00000000..0663fcc3
Binary files /dev/null and b/src/images/events/modular-meetup-istanbul-3.png differ
diff --git a/src/images/events/modular-meetup-istanbul-4.png b/src/images/events/modular-meetup-istanbul-4.png
new file mode 100644
index 00000000..9bbeced0
Binary files /dev/null and b/src/images/events/modular-meetup-istanbul-4.png differ
diff --git a/src/images/events/modular-meetup-istanbul.png b/src/images/events/modular-meetup-istanbul.png
new file mode 100644
index 00000000..dd6a2526
Binary files /dev/null and b/src/images/events/modular-meetup-istanbul.png differ
diff --git a/src/images/events/modular-meetup-rio-de-janeiro.png b/src/images/events/modular-meetup-rio-de-janeiro.png
new file mode 100644
index 00000000..a9cb68eb
Binary files /dev/null and b/src/images/events/modular-meetup-rio-de-janeiro.png differ
diff --git a/src/images/events/modular-meetup-santiago-de-compostela.png b/src/images/events/modular-meetup-santiago-de-compostela.png
new file mode 100644
index 00000000..57fe0a06
Binary files /dev/null and b/src/images/events/modular-meetup-santiago-de-compostela.png differ
diff --git a/src/images/events/modular-summit-3.png b/src/images/events/modular-summit-3.png
new file mode 100644
index 00000000..33ca0210
Binary files /dev/null and b/src/images/events/modular-summit-3.png differ
diff --git a/src/images/events/placeholder-1.png b/src/images/events/placeholder-1.png
new file mode 100644
index 00000000..b6d62fc6
Binary files /dev/null and b/src/images/events/placeholder-1.png differ
diff --git a/src/images/events/rejected.png b/src/images/events/rejected.png
new file mode 100644
index 00000000..cdd847ca
Binary files /dev/null and b/src/images/events/rejected.png differ
diff --git a/src/pages/events.js b/src/pages/events.js
new file mode 100644
index 00000000..c2fc7217
--- /dev/null
+++ b/src/pages/events.js
@@ -0,0 +1,67 @@
+import * as React from "react";
+import { Link } from "gatsby";
+import { FooterBoxes } from "../datas/glossary/content";
+import Layout from "../components/layout";
+import { seoContent } from "../datas/events/seoContent";
+import Seo from "../components/seo";
+import FeaturedEvent from "../components/modules/featured-event";
+import EventList from "../components/modules/event-list";
+import { submitButton, viewAllButton } from "../datas/events/event-data";
+
+const EventsPage = () => {
+ return (
+
+
+
+
+
+
+
Events
+
Hangout with the Celestia community IRL or online.
+
+
+
+
+
+
+
+
+
+
+ {viewAllButton.label}
+
+
+
+
+
+
+
+
+ );
+};
+
+export default EventsPage;
diff --git a/src/pages/past-events.js b/src/pages/past-events.js
new file mode 100644
index 00000000..c5218640
--- /dev/null
+++ b/src/pages/past-events.js
@@ -0,0 +1,30 @@
+import * as React from "react";
+import { FooterBoxes } from "../datas/glossary/content";
+import Layout from "../components/layout";
+import { seoContent } from "../datas/glossary/seoContent";
+import Seo from "../components/seo";
+import EventList from "../components/modules/event-list";
+
+const PastEventsPage = () => {
+ return (
+
+
+
+
+ );
+};
+
+export default PastEventsPage;
diff --git a/src/scss/main.scss b/src/scss/main.scss
index 0e8710f1..b744de28 100644
--- a/src/scss/main.scss
+++ b/src/scss/main.scss
@@ -40,6 +40,7 @@
@import "pages/page-run-a-node.scss";
@import "pages/page-what-is-tia.scss";
@import "pages/page-faq.scss";
+@import "pages/page-events.scss";
@import "components/technology.scss";
diff --git a/src/scss/pages/page-events.scss b/src/scss/pages/page-events.scss
new file mode 100644
index 00000000..6b81aa89
--- /dev/null
+++ b/src/scss/pages/page-events.scss
@@ -0,0 +1,380 @@
+.events-page {
+ min-height: 60vw;
+ position: relative;
+ z-index: 1;
+ @include media-breakpoint-down(md) {
+ min-height: 520px;
+ }
+
+ .hero {
+ padding-top: 20px;
+ padding-bottom: 0px;
+ .main {
+ margin-bottom: 30px;
+ }
+ .text {
+ font-family: $ruberoid;
+ font-weight: 500;
+ font-size: 18px;
+ color: #000000;
+ letter-spacing: 0.22px;
+ line-height: 26px;
+ max-width: 608px;
+ text-wrap: balance;
+ margin-bottom: 0px;
+
+ @include media-breakpoint-down(md) {
+ font-size: 14px;
+ line-height: 21px;
+ width: 100%;
+ }
+ }
+ }
+ .featured-event {
+ padding-top: 40px;
+ padding-bottom: 37px;
+
+ .event-description {
+ margin-top: 16px;
+ margin-bottom: 16px;
+ }
+ }
+ .event-list {
+ padding-top: 0px;
+ padding-bottom: 0px;
+ }
+
+ .event-card {
+ border-radius: 8px;
+ background-color: #fff;
+ box-shadow: 0 2px 2px rgba(0, 0, 0, 0.03);
+ display: flex;
+ flex-direction: column;
+ min-width: 100%;
+ width: 100%;
+ padding: 8px;
+ border: 1px solid #e3e3e3;
+ }
+
+ .event-image {
+ border-radius: 8px;
+ background-color: #ebebeb;
+ width: 100%;
+ background-size: cover;
+ background-position: center;
+ height: auto;
+ aspect-ratio: 3/2;
+
+ img {
+ object-fit: cover;
+ }
+ }
+
+ .event-content {
+ display: flex;
+ width: 100%;
+ flex-direction: column;
+ padding: 0 28px 12px;
+ justify-content: space-between;
+ flex-grow: 1;
+ }
+
+ .event-title {
+ font: 700 24px $ruberoid, sans-serif;
+ color: #000;
+ margin-bottom: 0;
+ &.small {
+ font-size: 24px;
+ line-height: 33px;
+ }
+ }
+
+ .event-description {
+ font: 400 12px/17px $inter, -apple-system, Roboto, Helvetica, sans-serif;
+ color: #000;
+ &.small {
+ font-size: 12px;
+ line-height: 17px;
+ }
+ }
+
+ .divider {
+ min-height: 1px;
+ width: 100%;
+ border: 1px solid #ececec;
+ margin-bottom: 24px;
+ &.small {
+ margin-top: 12px;
+ }
+ }
+
+ .event-details {
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ align-items: start;
+ justify-content: flex-start;
+ font-size: 14px;
+ gap: 20px 20px;
+ }
+
+ .event-info {
+ display: flex;
+ gap: 10px;
+ font-family: $inter, sans-serif;
+ color: #000;
+ font-weight: 600;
+ line-height: 24px;
+ }
+
+ .event-date,
+ .event-location {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ }
+
+ .icon {
+ width: 16px;
+ height: 16px;
+ margin-bottom: 3px;
+ }
+
+ .small-button {
+ padding: 10px 16px;
+ font-size: 14px;
+ line-height: 19px;
+ letter-spacing: 0.2px;
+ }
+
+ @media (max-width: 991px) {
+ .event-card {
+ max-width: 100%;
+ }
+ }
+
+ .event-list-container {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ width: 100%;
+ gap: 13px;
+ }
+
+ @include media-breakpoint-down(xl) {
+ .event-list-container {
+ grid-template-columns: repeat(2, 1fr);
+ }
+ }
+
+ @include media-breakpoint-down(md) {
+ .event-list-container {
+ grid-template-columns: 1fr;
+ }
+ }
+
+ .featured-events-grid {
+ display: grid;
+ grid-template-columns: 1fr;
+ grid-template-rows: auto;
+ gap: 10px;
+ }
+
+ .featured-event-container {
+ display: flex;
+ border-radius: 8px;
+ background-color: #fff;
+ box-shadow: 0 2px 2px rgba(0, 0, 0, 0.03);
+ width: 100%;
+ justify-content: space-between;
+ align-items: center;
+ flex-wrap: wrap;
+ padding: 8px;
+ border: 1px solid #e3e3e3;
+ .event-content {
+ display: flex;
+ min-width: 240px;
+ flex-direction: column;
+ justify-content: space-between;
+ flex: 1;
+ flex-basis: 50%;
+ }
+ }
+
+ .event-banner {
+ border-radius: 8px;
+ background-color: #ebebeb;
+ width: 100%;
+ flex-basis: 50%;
+ min-height: 400px;
+ aspect-ratio: 3/2;
+
+ @include media-breakpoint-down(xl) {
+ min-height: auto;
+ flex-basis: 100%;
+ }
+ img {
+ object-fit: cover;
+ }
+ }
+
+ .event-content {
+ min-width: 240px;
+ padding: 24px 44px 24px;
+ @include media-breakpoint-down(md) {
+ max-width: 100%;
+ padding: 20px;
+ }
+ @include media-breakpoint-down(sm) {
+ padding: 20px 10px;
+ }
+ &.small {
+ padding: 16px 12px;
+ }
+ }
+
+ .event-tags {
+ display: flex;
+ width: 100%;
+ align-items: flex-start;
+ gap: 12px;
+ color: #414141;
+ text-transform: uppercase;
+ flex-wrap: wrap;
+ font: 500 12px/24px $inter, -apple-system, Roboto, Helvetica, sans-serif;
+ margin-bottom: 20px;
+ }
+
+ .tag {
+ border-radius: 48px;
+ background-color: #e9e9e9;
+ padding: 0 8px;
+ }
+
+ .event-info {
+ display: flex;
+ width: 100%;
+ flex-direction: column;
+ color: #000;
+ }
+
+ .event-title {
+ font: 700 52px/1.1em $ruberoid, sans-serif;
+ }
+
+ .event-description {
+ font: 400 16px/26px $inter, -apple-system, Roboto, Helvetica, sans-serif;
+ }
+
+ .event-details {
+ border-color: #ececec;
+ border-top-width: 1px;
+ display: flex;
+ width: 100%;
+ align-items: flex-start;
+ justify-content: flex-start;
+ flex-wrap: wrap;
+ }
+
+ .event-meta {
+ display: flex;
+ align-items: center;
+ gap: 20px;
+ color: #000;
+ font: 600 14px/24px $inter, -apple-system, Roboto, Helvetica, sans-serif;
+ }
+
+ .eventDate,
+ .eventLocation {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ }
+
+ .read-more-btn {
+ border-radius: 6px;
+ background-color: #000;
+ color: #fff;
+ text-align: center;
+ letter-spacing: 0.2px;
+ width: 122px;
+ padding: 10px 16px;
+ font: 700 16px $ruberoid, sans-serif;
+ border: none;
+ cursor: pointer;
+ }
+
+ @media (max-width: 991px) {
+ .featured-event {
+ max-width: 100%;
+ }
+
+ .event-tags {
+ max-width: 100%;
+ white-space: initial;
+ }
+
+ .event-info {
+ max-width: 100%;
+ }
+
+ .event-title {
+ max-width: 100%;
+ font-size: 32px;
+ }
+
+ .event-description {
+ max-width: 100%;
+ }
+
+ .event-details {
+ max-width: 100%;
+ gap: 20px 100px;
+ }
+ }
+
+ .community-events-section {
+ padding-top: 60px;
+ padding-bottom: 0px;
+
+ @include media-breakpoint-down(md) {
+ padding-top: 10px;
+ }
+
+ .event-section-tiltle {
+ margin-bottom: 40px;
+ @include media-breakpoint-up(md) {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ align-items: center;
+ }
+
+ @include media-breakpoint-down(sm) {
+ display: block;
+ }
+ }
+ }
+ .submit-event-button {
+ padding: 10px 16px;
+ background: #ffffff;
+ border: 1px solid #e3e3e3;
+ box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.03);
+ border-radius: 8px;
+ height: fit-content;
+
+ font-family: $ruberoid;
+ font-weight: 700;
+ font-size: 14px;
+ line-height: 19px;
+ letter-spacing: 0.2px;
+ color: #000;
+ transition: background-color 0.3s ease;
+ &:hover {
+ background: #f1f1f1;
+ color: #000;
+ }
+ i {
+ line-height: 19px;
+ }
+ }
+}
diff --git a/src/utils/date-utils.js b/src/utils/date-utils.js
new file mode 100644
index 00000000..5c4c38ad
--- /dev/null
+++ b/src/utils/date-utils.js
@@ -0,0 +1,26 @@
+export function formatDateRange(startDate, endDate) {
+ const start = new Date(startDate);
+ const end = endDate ? new Date(endDate) : null;
+
+ const monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
+
+ if (!end) {
+ return `${monthNames[start.getMonth()]} ${start.getDate()}, ${start.getFullYear()}`;
+ }
+
+ if (start.getTime() === end.getTime()) {
+ return `${monthNames[start.getMonth()]} ${start.getDate()}, ${start.getFullYear()}`;
+ }
+
+ if (start.getMonth() === end.getMonth() && start.getFullYear() === end.getFullYear()) {
+ return `${monthNames[start.getMonth()]} ${start.getDate()} - ${end.getDate()}, ${start.getFullYear()}`;
+ }
+
+ if (start.getFullYear() === end.getFullYear()) {
+ return `${monthNames[start.getMonth()]} ${start.getDate()} - ${monthNames[end.getMonth()]} ${end.getDate()}, ${start.getFullYear()}`;
+ }
+
+ return `${monthNames[start.getMonth()]} ${start.getDate()}, ${start.getFullYear()} - ${
+ monthNames[end.getMonth()]
+ } ${end.getDate()}, ${end.getFullYear()}`;
+}