diff --git a/app/academic-forum/page.tsx b/app/academic-forum/page.tsx index 7e02c58..9cdc134 100755 --- a/app/academic-forum/page.tsx +++ b/app/academic-forum/page.tsx @@ -27,9 +27,9 @@ export default function PaperSubmission() {
- + Knowledge Partner: IEEE Blockchain - +
@@ -38,12 +38,15 @@ export default function PaperSubmission() {
- Submission Deadline: August 11, 2025 (23:59 CEST) August 20, 2025 (23:59 CEST) + Submission Deadline:{" "} + August 11, 2025 (23:59 CEST) August 20, 2025 (23:59 + CEST)
- Acceptance Notification: August 15, 2025 August 22, 2025 + Acceptance Notification: August 15, 2025{" "} + August 22, 2025
@@ -53,7 +56,8 @@ export default function PaperSubmission() {
- Academic Track Date: September 12, 2025 + Academic Track Date: September 11, 2025; 13:30 - 17:45 + CEST
@@ -61,12 +65,8 @@ export default function PaperSubmission() { Venue: House of Communication, Munich, Germany
- - @@ -77,10 +77,24 @@ export default function PaperSubmission() {
- We are delighted to announce the Call for Extended Abstracts for the Academic Forum at the 2025 TUM Blockchain Conference. The Academic Forum is hosted in collaboration with the TUM Chair of Network Architectures and Services. We are happy to have IEEE Blockchain as a Knowledge partner inviting selected works for a submission to IEEE Blockchain Technical Briefs. The selected abstracts will be offered to present their work in form of a short talk and/or a poster presentation. + We are delighted to announce the Call for Extended Abstracts for + the Academic Forum at the 2025 TUM Blockchain Conference. The + Academic Forum is hosted in collaboration with the TUM Chair of + Network Architectures and Services. We are happy to have IEEE + Blockchain as a Knowledge partner inviting selected works for a + submission to IEEE Blockchain Technical Briefs. The selected + abstracts will be offered to present their work in form of a + short talk and/or a poster presentation.

- This event invites researchers, academics, and industry professionals to connect and present their latest work in the topics related to the Science of Blockchains. Accepted talks will be showcased through a short presentation at the conference and displayed as posters in the conference area. The posters will remain on display for the entire day of the event, offering an excellent platform for in-depth discussions and networking opportunities. + This event invites researchers, academics, and industry + professionals to connect and present their latest work in the + topics related to the Science of Blockchains. Accepted talks + will be showcased through a short presentation at the conference + and displayed as posters in the conference area. The posters + will remain on display for the entire day of the event, offering + an excellent platform for in-depth discussions and networking + opportunities.
@@ -198,12 +212,8 @@ export default function PaperSubmission() {
- - @@ -212,7 +222,8 @@ export default function PaperSubmission() {
- Abstracts will be reviewed by the listed committee. Accepted papers will be invited to present their work at the conference. + Abstracts will be reviewed by the listed committee. Accepted + papers will be invited to present their work at the conference.
@@ -278,10 +289,22 @@ export default function PaperSubmission() { style={{ listStyleType: "circle" }} className="pl-5 space-y-2" > -
  • Jonas Gebele, TUM, Chair of Software Engineering for Business Information Systems
  • -
  • Burak Oez, TUM, Chair of Software Engineering for Business Information Systems
  • -
  • Fabian Stiehle, TUM, Information System Development and Operation
  • -
  • Kilian Glas, TUM, Chair of Network Architectures and Services
  • +
  • + Jonas Gebele, TUM, Chair of Software Engineering for + Business Information Systems +
  • +
  • + Burak Oez, TUM, Chair of Software Engineering for Business + Information Systems +
  • +
  • + Fabian Stiehle, TUM, Information System Development and + Operation +
  • +
  • + Kilian Glas, TUM, Chair of Network Architectures and + Services +
  • diff --git a/app/agenda/agenda.tsx b/app/agenda/agenda.tsx index f0fd668..e7149d0 100644 --- a/app/agenda/agenda.tsx +++ b/app/agenda/agenda.tsx @@ -28,13 +28,16 @@ export const Agenda: React.FC = ({ sessions, speakers }) => { "Stage 2": "Hopper Stage", "Stage 3": "Nakamoto Stage", "Workshop Room": "Lovelace Room", + Gern: "Gern", }; const STAGE_PRIORITY: Record = { "Stage 3": 0, // Nakamoto — highest priority "Stage 1": 1, // Turing "Stage 2": 2, // Hopper + Gern: 2, // Gern "Workshop Room": 3, // Lovelace + "Lab lounge": 0, // Lab lounge }; const SAME_TIME_WINDOW_MS = 0 * 60 * 1000; // 5 minutes @@ -56,9 +59,38 @@ export const Agenda: React.FC = ({ sessions, speakers }) => { trackFilter === "all" || !trackFilter || trackFilter === item.track; const matchesStage = stageFilter === "all" || !stageFilter || stageFilter === item.room; - const matchesTitle = - !titleFilter.trim() || - item.title.toLowerCase().includes(titleFilter.trim().toLowerCase()); + + const q = titleFilter.trim().toLowerCase(); + + const speakerTextParts: string[] = []; + const rawSpeakers = (item as any).speakers; + if (rawSpeakers && typeof rawSpeakers === "object") { + speakerTextParts.push( + ...Object.keys(rawSpeakers).map((x) => String(x)), + ...Object.values(rawSpeakers).map((x) => String(x)), + ); + } + + const searchableChunks = [ + item.title, + (item as any).subtitle, + (item as any).description, + (item as any).abstract, + (item as any).summary, + item.track, + item.room, + ...(Array.isArray((item as any).tags) ? (item as any).tags : []), + ...(Array.isArray((item as any).keywords) + ? (item as any).keywords + : []), + ...speakerTextParts, + ] + .filter(Boolean) + .map((x) => String(x).toLowerCase()); + + const haystack = searchableChunks.join(" | "); + + const matchesTitle = !q || haystack.includes(q); return matchesDay && matchesTrack && matchesStage && matchesTitle; }); @@ -97,13 +129,13 @@ export const Agenda: React.FC = ({ sessions, speakers }) => {
    - Title + Search setTitleFilter(e.target.value)} - placeholder="Search agenda titles..." + placeholder="Titles, speakers, descriptions…" className="w-full rounded-lg text-white border py-2 px-3 bg-black placeholder-gray-500" />
    @@ -192,28 +224,29 @@ export const Agenda: React.FC = ({ sessions, speakers }) => { /> Any Track - {Tracks.filter( - (track) => track !== "TUM Blockchain Club", - ).map((track, index) => ( - - - {track} - - ))} + {Tracks.filter((track) => track !== "TBC'25").map( + (track, index) => ( + + + {track} + + ), + )} diff --git a/app/workshops/page.tsx b/app/workshops/page.tsx index ee75ece..cf224f2 100644 --- a/app/workshops/page.tsx +++ b/app/workshops/page.tsx @@ -4,13 +4,28 @@ import { Container } from "@/components/container"; import { Text } from "@/components/text"; import { WorkshopsContainer } from "@/components/workshops/WorkshopsContainer"; import { workshopItems } from "@/constants/WorkshopData"; +import { fetchWorkshops, Workshop } from "@/components/service/contentStrapi"; + +export default async function Workshops() { + const workshops: Workshop[] = await fetchWorkshops(); + + const items = workshops.map((e) => ({ + title: e.title, + description: e.description, + backgroundImg: e.backgroundImg?.url || "/workshops/default-workshop.png", + url: e.url, + starttime: e.starttime, + endtime: e.endtime, + room: e.room, + })); -const Workshops = async () => { return (
    - -
    + +
    { > Workshops - +
    ); -}; - -export default Workshops; +} diff --git a/components/header/Header.tsx b/components/header/Header.tsx index 98e3b29..fb65a59 100644 --- a/components/header/Header.tsx +++ b/components/header/Header.tsx @@ -23,18 +23,18 @@ type HeaderLink = { const links: HeaderLink[] = [ { label: "Home", link: "/", showsAtHome: true }, - { label: "Manifesto", link: "/#manifesto", showsAtHome: true }, + // { label: "Manifesto", link: "/#manifesto", showsAtHome: true }, { label: "Speakers", link: "/speakers", showsAtHome: true }, { label: "Sponsors", link: "/#sponsors", showsAtHome: true }, { label: "Academic Forum", link: "/academic-forum", showsAtHome: true }, - { - label: "Apply as Speaker", - link: "https://tally.so/r/w8EB0o", - showsAtHome: true, - }, + // { + // label: "Apply as Speaker", + // link: "https://tally.so/r/w8EB0o", + // showsAtHome: true, + // }, { label: "Side Events", link: "/side-events", showsAtHome: true }, { label: "Agenda", link: "/agenda", showsAtHome: true }, - // { label: "Workshops", link: "/workshops", showsAtHome: true }, + { label: "Workshops", link: "/workshops", showsAtHome: true }, // { label: "Student Grants", link: "#grants", showsAtHome: true }, // { label: "FAQ", link: "#faq", showsAtHome: true }, ]; @@ -88,13 +88,14 @@ export const Sidebar: React.FC = ({ isOpen, onClose }) => { const PRIORITY: string[] = [ "Home", - "Manifesto", + // "Manifesto", "Speakers", "Sponsors", "Academic Forum", "Side Events", "Agenda", - "Apply as Speaker", + "Workshops", + // "Apply as Speaker", ]; function NavDesktop({ items }: { items: HeaderLink[] }) { diff --git a/components/service/contentStrapi.ts b/components/service/contentStrapi.ts index a115f01..699c53b 100644 --- a/components/service/contentStrapi.ts +++ b/components/service/contentStrapi.ts @@ -92,6 +92,21 @@ export interface SideEvent { image?: ProfilePicture | null; } +export interface Workshop { + id: number; + documentId: string; + title: string; + description: string; + url: string; + backgroundImg: ProfilePicture | null; + room: string; + starttime: string; + endtime: string; + createdAt: string; + updatedAt: string; + publishedAt: string; +} + export default Speaker; const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); @@ -277,3 +292,85 @@ const downloadSideEventImage = async (event: SideEvent) => { ); } }; + +export const fetchWorkshops = async (): Promise => { + const token = process.env.STRAPI_API_TOKEN; + if (!token) { + console.warn("STRAPI_API_TOKEN missing; returning empty workshops list"); + return []; + } + + try { + const workshops: Workshop[] = []; + let hasMore = true; + let page = 1; + do { + const res = await axios.get( + `https://strapi.rbg.tum-blockchain.com/api/workshop-25s?sort=starttime:asc&pagination[page]=${page}&pagination[pageSize]=25&populate=backgroundImg`, + { + headers: { + Authorization: `Bearer ${token}`, + }, + }, + ); + const pageData: Workshop[] = res.data.data; + for (const workshop of pageData) { + await downloadWorkshopImage(workshop); + delay(300); + } + workshops.push(...pageData); + hasMore = + res.data.meta.pagination.page < res.data.meta.pagination.pageCount; + page = page + 1; + console.log(`Fetched ${workshops.length} workshops so far...`); + } while (hasMore); + return workshops; + } catch (err) { + console.error("Error fetching workshops from Strapi:", err); + return []; + } +}; + +const downloadWorkshopImage = async (workshop: Workshop) => { + if (!workshop.backgroundImg || !workshop.backgroundImg.url) { + console.warn(`No background image for workshop: ${workshop.title}`); + return; + } + + try { + const dir = path.join(process.cwd(), "public", "workshops25"); + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir, { recursive: true }); + } + + const ext = workshop.backgroundImg.ext || ".webp"; + const fileName = `${workshop.documentId}${ext}`; + const filePath = path.join(dir, fileName); + if (!fs.existsSync(filePath)) { + const res = await axios({ + url: + "https://strapi.rbg.tum-blockchain.com" + workshop.backgroundImg.url, + method: "GET", + responseType: "stream", + }); + const writer = fs.createWriteStream(filePath); + res.data.pipe(writer); + await new Promise((resolve, reject) => { + writer.on("finish", () => resolve()); + writer.on("error", reject); + }); + console.log( + `Downloaded workshop image for ${workshop.title} to ${filePath}`, + ); + const publicUrl = `/workshops25/${fileName}`; + workshop.backgroundImg.url = publicUrl; + } else { + workshop.backgroundImg.url = `/workshops25/${fileName}`; + } + } catch (error) { + console.error( + `Error downloading image for workshop ${workshop.title}:`, + error, + ); + } +}; diff --git a/components/service/contentStrapi_static.ts b/components/service/contentStrapi_static.ts index 383bb1c..5c1f67d 100644 --- a/components/service/contentStrapi_static.ts +++ b/components/service/contentStrapi_static.ts @@ -62,7 +62,8 @@ export const Tracks = [ "Research", "Regulation", "Workshop", - "TUM Blockchain Club", + "TBC'25", + "Academic Forum", // "Sub Events", // "TUM Blockchain Club", ] as const; @@ -72,6 +73,8 @@ export const Stages = [ "Stage 2", "Stage 3", "Workshop Room", + "Gern", + "Lab Lounge", ] as const; export interface Session { diff --git a/components/session/Session.tsx b/components/session/Session.tsx index df44062..dd880c5 100644 --- a/components/session/Session.tsx +++ b/components/session/Session.tsx @@ -11,7 +11,7 @@ import { ClockIcon, SewingPinIcon } from "@radix-ui/react-icons"; import classNames from "classnames"; import Image from "next/image"; import Link from "next/link"; -import React, { useEffect, useRef, useState } from "react"; +import React, { useRef, useState, useLayoutEffect } from "react"; import { contentfulImageLoader } from "@/util/contentfulImageLoader"; import { Clock, MapPin } from "lucide-react"; export type SessionElement = React.ElementRef<"div">; @@ -27,32 +27,50 @@ export const Session = React.forwardRef( const [isLineClampClamped, setIsLineClampClamped] = useState(false); const lineClampRef = useRef(null); - const [active, setActive] = useState(false); - useEffect(() => { - const checkLineClamping = () => { - if (lineClampRef.current) { - const lineClampElement = lineClampRef.current; - setIsLineClampClamped( - lineClampElement.scrollHeight > lineClampElement.clientHeight, - ); - } + const { startTime, endTime } = { + startTime: new Date(session.startTime), + endTime: new Date(session.endTime), + }; + + const LINES = 3; // number of lines to clamp to + + useLayoutEffect(() => { + const measure = () => { + const el = lineClampRef.current; + if (!el) return; + + // remember whether the clamp class is applied + const hadClamp = el.classList.contains(`line-clamp-${LINES}`); + + // temporarily disable clamping to get the real height + el.classList.remove(`line-clamp-${LINES}`); + el.classList.add("line-clamp-none"); + + const cs = window.getComputedStyle(el); + const lineHeight = parseFloat(cs.lineHeight); + const fullHeight = el.getBoundingClientRect().height; + const maxHeight = lineHeight * LINES; + + // restore original class + el.classList.remove("line-clamp-none"); + if (hadClamp) el.classList.add(`line-clamp-${LINES}`); + + setIsLineClampClamped(fullHeight > maxHeight + 0.5); }; - checkLineClamping(); + // measure now and on the next frame (in case layout settles) + measure(); + const raf = requestAnimationFrame(measure); - // Re-check on window resize - window.addEventListener("resize", checkLineClamping); + const onResize = () => measure(); + window.addEventListener("resize", onResize); return () => { - window.removeEventListener("resize", checkLineClamping); + cancelAnimationFrame(raf); + window.removeEventListener("resize", onResize); }; - }, [lineClampRef]); - - const { startTime, endTime } = { - startTime: new Date(session.startTime), - endTime: new Date(session.endTime), - }; + }, []); const speakerMap = new Map( speakers.map((sp) => [sp.name.toLowerCase().trim(), sp]), @@ -63,14 +81,15 @@ export const Session = React.forwardRef( {...divProps} className={classNames( className, - "border w-full flex p-4 flex-col gap-4 bg-gradient-to-b from-black bg-opacity-60", + "border w-full flex p-4 flex-col gap-4 bg-gradient-to-b bg-opacity-60 from-black from-0% via-black via-30% ", { - "to-[#14532d]/60": session.track === "Education", // Dark forest green - "to-[#665200]/60": session.track === "Research", // Deep gold-brown - "to-[#1e3a8a]/40": session.track === "Ecosystem", // Deep blue (Tailwind blue-900) - "to-[#4c0608]/60": session.track === "Regulation", // Deep red / oxblood - "to-[#1a012e]": session.track === "Workshop", // Very dark purple - "to-[#134e4a]/60": session.track === "Application", // Teal-950 (deep cyan-green) + "to-[#06b6d4]/40 to-100%": session.track === "Application", // Cyan + "to-[#1e3a8a]/40 to-100%": session.track === "Ecosystem", // Blue + "to-[#15803d]/40 to-100%": session.track === "Education", // Green + "to-[#7a6a00]/50 to-100%": session.track === "Research", // Olive / brass + "to-[#b91c1c]/40 to-100%": session.track === "Regulation", // Red + "to-[#7c3aed]/30 to-100%": session.track === "Workshop", // Purple + "to-[#f97316]/30 to-100%": session.track === "Academic Forum", // Orange }, )} ref={ref} @@ -111,30 +130,30 @@ export const Session = React.forwardRef( className={classNames( "border rounded-[5px] h-fit col-start-2", { - "border-green-400": session.track === "Education", - "border-yellow-400": session.track === "Research", - "border-blue-400": session.track === "Ecosystem", - "border-amber": session.track === "Research", - "border-[#F87171]": session.track === "Regulation", - "border-[#c084fc]": session.track === "Workshop", - "border-teal-400": session.track === "Application", + "border-[#22d3ee]": session.track === "Application", // Lighter cyan + "border-[#60a5fa]": session.track === "Ecosystem", // Lighter blue + "border-[#4ade80]": session.track === "Education", // Lighter green + "border-[#fde047]": session.track === "Research", // Lighter yellow + "border-[#f87171]": session.track === "Regulation", // Lighter red + "border-[#c4b5fd]": session.track === "Workshop", // Lighter purple + "border-[#fdba74]": session.track === "Academic Forum", // Lighter orange + "gradient-border": session.track === "TBC'25", // Gradient for TBC }, )} > - {session.track === "TUM Blockchain Club" - ? "TBC" - : session.track} + {session.track} )} @@ -266,9 +285,10 @@ export const Session = React.forwardRef( src={details.profile_photo?.url || ""} loader={contentfulImageLoader} alt={details.name} - width={48} - height={48} + width={60} + height={60} className="rounded-full object-cover" + quality={100} /> )} diff --git a/components/workshops/WorkshopItem.tsx b/components/workshops/WorkshopItem.tsx index 6572a3c..88fa34b 100644 --- a/components/workshops/WorkshopItem.tsx +++ b/components/workshops/WorkshopItem.tsx @@ -1,56 +1,148 @@ "use client"; -import { Text } from "@/components/text"; +import React from "react"; import classNames from "classnames"; import Image from "next/image"; import NextLink from "next/link"; -import React from "react"; -import { Button } from "../button"; +import { Text } from "@/components/text"; +import { Button } from "@/components/button"; interface WorkshopModel { title: string; - bgImage: string; - description: string; url: string; + description: string; + backgroundImg: string; + starttime: string; // ISO preferred + endtime: string; // ISO preferred + room: string; } -type WorkshopElement = React.ElementRef<"div">; -export type WorkshopProps = React.ComponentPropsWithoutRef<"div"> & +type WorkshopElement = React.ElementRef<"article">; +export type WorkshopProps = React.ComponentPropsWithoutRef<"article"> & WorkshopModel; -export const Workshop = React.forwardRef( +export const WorkshopItem = React.forwardRef( (props, ref) => { - const { className, bgImage, title, description, url, ...restProps } = props; + const { + className, + title, + description, + url, + backgroundImg, + room, + starttime, + endtime, + ...restProps + } = props; + + // ---------- Time formatting (Europe/Berlin) without “um” ---------- + const start = new Date(starttime); + const end = new Date(endtime); + const valid = !isNaN(start.getTime()) && !isNaN(end.getTime()); + + const dateOnlyOpts: Intl.DateTimeFormatOptions = { + timeZone: "Europe/Berlin", + weekday: "long", + month: "long", + day: "numeric", + }; + const timeOnlyOpts: Intl.DateTimeFormatOptions = { + timeZone: "Europe/Berlin", + hour: "2-digit", + minute: "2-digit", + }; + const keyOpts: Intl.DateTimeFormatOptions = { + timeZone: "Europe/Berlin", + year: "numeric", + month: "2-digit", + day: "2-digit", + }; + + const sameDay = + valid && + new Intl.DateTimeFormat("en-CA", keyOpts).format(start) === + new Intl.DateTimeFormat("en-CA", keyOpts).format(end); + + // DST label + const isBerlinDST = (d: Date) => { + const y = d.getUTCFullYear(); + const lastMarch = new Date(Date.UTC(y, 3, 0)); + const lastSundayMarch = lastMarch.getUTCDate() - lastMarch.getUTCDay(); + const dstStartUTC = new Date(Date.UTC(y, 2, lastSundayMarch, 1, 0, 0)); + const lastOct = new Date(Date.UTC(y, 10, 0)); + const lastSundayOct = lastOct.getUTCDate() - lastOct.getUTCDay(); + const dstEndUTC = new Date(Date.UTC(y, 9, lastSundayOct, 1, 0, 0)); + return ( + d.getTime() >= dstStartUTC.getTime() && + d.getTime() < dstEndUTC.getTime() + ); + }; + const tzLabel = valid ? (isBerlinDST(start) ? "CEST" : "CET") : ""; + + const fmtDate = (d: Date) => d.toLocaleDateString(undefined, dateOnlyOpts); + const fmtTime = (d: Date) => d.toLocaleTimeString([], timeOnlyOpts); + + const dateDisplay = valid + ? sameDay + ? // e.g. "Thursday, September 11 | 10:30 – 11:30 CEST" + `${fmtDate(start)} | ${fmtTime(start)} – ${fmtTime(end)} ${tzLabel}` + : // e.g. "Thursday, September 11 10:30 – Friday, September 12 17:15 CEST" + `${fmtDate(start)} ${fmtTime(start)} – ${fmtDate(end)} ${fmtTime(end)} ${tzLabel}` + : ""; + + // --------------------------------------------------------------- + return ( -
    -
    +
    {title}
    - + + {title} - - {description} - + + {(dateDisplay || room) && ( + + {[dateDisplay, room].filter(Boolean).join(" • ")} + + )} + +
    + + {description} + +
    + - -
    + ); }, ); -Workshop.displayName = "Workshop"; + +WorkshopItem.displayName = "WorkshopItem"; diff --git a/components/workshops/WorkshopsContainer.tsx b/components/workshops/WorkshopsContainer.tsx index 1ff868c..3ac58c9 100644 --- a/components/workshops/WorkshopsContainer.tsx +++ b/components/workshops/WorkshopsContainer.tsx @@ -1,31 +1,39 @@ -"use client"; +// components/workshops/WorkshopsContainer.tsx +// Note: no "use client" — this stays server-rendered unless you add filters later. import React from "react"; -import { Workshop } from "./WorkshopItem"; +import { WorkshopItem } from "./WorkshopItem"; -export interface WorkshopItem { +export interface WorkshopItemModel { title: string; url: string; description: string; backgroundImg: string; + starttime: string; + endtime: string; + room: string; } export interface WorkshopProps { - items: WorkshopItem[]; + items: WorkshopItemModel[]; } export const WorkshopsContainer: React.FC = ({ items }) => { return ( - <> - {items.map((item, index) => ( - +
      + {items.map((item, idx) => ( +
    • + +
    • ))} - +
    ); }; diff --git a/constants/WorkshopData.tsx b/constants/WorkshopData.tsx index 1ae46d0..ba3a91c 100644 --- a/constants/WorkshopData.tsx +++ b/constants/WorkshopData.tsx @@ -1,53 +1,73 @@ +import { title } from "process"; + export const workshopItems = [ + // { + // title: "Solana Superteam Ideathon", + // url: "https://apply.tum-blockchain.com/solana-superteam-ideathon", + // description: + // "Join us for a half-day Ideathon — whether you're new to blockchain or an experienced dev, this Ideathon will be the perfect platform to explore new concepts, collaborate with like-minded individuals, and bring your ideas to life.", + // backgroundImg: "/workshops/solana-workshop.png", + // }, + // { + // title: "XRP Ledger: Everything Is a Payment Away", + // url: "https://apply.tum-blockchain.com/xrpl-workshop", + // description: + // "A hands-on guide to the XRP Ledger, how to get started on it, and its best use cases", + // backgroundImg: "/workshops/xrpl-workshop.png", + // }, + // { + // title: "SUI Developer Workshop", + // url: "https://apply.tum-blockchain.com/sui-workshop", + // description: + // "Join us for an interactive and engaging workshop designed for developers of all experience levels! Whether you’re new to Sui or already familiar, this session will dive into the Sui object model and equip you with the skills to jumpstart and enhance your journey developing on Sui. You’ll learn practical tips, hands-on techniques, and best practices to confidently build on-chain applications. Come ready to code, collaborate, and leave with a deeper understanding of Move and Sui!", + // backgroundImg: "/workshops/sui-workshop.png", + // }, + // { + // title: + // "Wormhole: Deploying native multichain token with customizable security models", + // url: "https://apply.tum-blockchain.com/wormhole-workshop", + // description: + // "The landscape of blockchain technology is evolving rapidly, with cross-chain interoperability becoming a cornerstone of the future. One significant advancement in this space is the deployment of native multichain tokens. Imagine the ability to configure sophisticated security measures, set precise rate limits at the contract level, and select from a variety of deployment models—all tailored to your specific needs.", + // backgroundImg: "/workshops/wormhole-workshop.png", + // }, + // { + // title: "Introduction to Verus and its Unique DApp Model", + // url: "https://apply.tum-blockchain.com/verus-workshop", + // description: + // "Learn how to accomplish everything that's important on blockchain using software you already know, instead of writing new code in a new language you need to learn: Verus protocol-layer functions vs. smart contract architectures", + // backgroundImg: "/workshops/verus-workshop.png", + // }, + // { + // title: + // "DFINITY: Building Cross-Chain Applications with Ethereum and the Internet Computer", + // url: "https://apply.tum-blockchain.com/dfinity-workshop", + // description: + // "Ethereum is the most popular platform to create decentralized applications in the form of smart contracts. Due to Ethereum's popularity and fee model, executing transactions can be quite costly, which limits its usability for applications that require many low-value transactions. On the other hand, the Internet Computer, a blockchain-based platform for the execution of general-purpose smart contracts, makes it possible to send transactions quickly and cheaply. Is it possible to combine both platforms? The answer is yes! As we will show in this workshop, you can build smart contracts that run on the Internet Computer but interact with Ethereum to generate powerful cross-chain applications.", + // backgroundImg: "/workshops/icp-workshop.png", + // }, + // { + // title: "1inch: Mastering Dapp Development with the 1inch DevPortal", + // url: "https://apply.tum-blockchain.com/1inch-workshop", + // description: + // "Take a dive into 1inch API's and features available on 1inch DevPortal. What are the use-cases for such API's? How to start? - These questions will be answered during the workshop", + // backgroundImg: "/workshops/1inch-workshop.png", + // }, { - title: "Solana Superteam Ideathon", - url: "https://apply.tum-blockchain.com/solana-superteam-ideathon", + title: "Solana Superteam Germany Ideathon", + url: "https://apply.tum-blockchain.com/solana-ideathon", description: "Join us for a half-day Ideathon — whether you're new to blockchain or an experienced dev, this Ideathon will be the perfect platform to explore new concepts, collaborate with like-minded individuals, and bring your ideas to life.", backgroundImg: "/workshops/solana-workshop.png", + room: "Lovelace Room", + time: "Fri · 13:30-15:45", }, { - title: "XRP Ledger: Everything Is a Payment Away", - url: "https://apply.tum-blockchain.com/xrpl-workshop", + title: "Ethereum Research Challenge", + url: "https://apply.tum-blockchain.com/ef-research-challenge", description: - "A hands-on guide to the XRP Ledger, how to get started on it, and its best use cases", - backgroundImg: "/workshops/xrpl-workshop.png", - }, - { - title: "SUI Developer Workshop", - url: "https://apply.tum-blockchain.com/sui-workshop", - description: - "Join us for an interactive and engaging workshop designed for developers of all experience levels! Whether you’re new to Sui or already familiar, this session will dive into the Sui object model and equip you with the skills to jumpstart and enhance your journey developing on Sui. You’ll learn practical tips, hands-on techniques, and best practices to confidently build on-chain applications. Come ready to code, collaborate, and leave with a deeper understanding of Move and Sui!", - backgroundImg: "/workshops/sui-workshop.png", - }, - { - title: - "Wormhole: Deploying native multichain token with customizable security models", - url: "https://apply.tum-blockchain.com/wormhole-workshop", - description: - "The landscape of blockchain technology is evolving rapidly, with cross-chain interoperability becoming a cornerstone of the future. One significant advancement in this space is the deployment of native multichain tokens. Imagine the ability to configure sophisticated security measures, set precise rate limits at the contract level, and select from a variety of deployment models—all tailored to your specific needs.", - backgroundImg: "/workshops/wormhole-workshop.png", - }, - { - title: "Introduction to Verus and its Unique DApp Model", - url: "https://apply.tum-blockchain.com/verus-workshop", - description: - "Learn how to accomplish everything that's important on blockchain using software you already know, instead of writing new code in a new language you need to learn: Verus protocol-layer functions vs. smart contract architectures", - backgroundImg: "/workshops/verus-workshop.png", - }, - { - title: - "DFINITY: Building Cross-Chain Applications with Ethereum and the Internet Computer", - url: "https://apply.tum-blockchain.com/dfinity-workshop", - description: - "Ethereum is the most popular platform to create decentralized applications in the form of smart contracts. Due to Ethereum's popularity and fee model, executing transactions can be quite costly, which limits its usability for applications that require many low-value transactions. On the other hand, the Internet Computer, a blockchain-based platform for the execution of general-purpose smart contracts, makes it possible to send transactions quickly and cheaply. Is it possible to combine both platforms? The answer is yes! As we will show in this workshop, you can build smart contracts that run on the Internet Computer but interact with Ethereum to generate powerful cross-chain applications.", - backgroundImg: "/workshops/icp-workshop.png", - }, - { - title: "1inch: Mastering Dapp Development with the 1inch DevPortal", - url: "https://apply.tum-blockchain.com/1inch-workshop", - description: - "Take a dive into 1inch API's and features available on 1inch DevPortal. What are the use-cases for such API's? How to start? - These questions will be answered during the workshop", - backgroundImg: "/workshops/1inch-workshop.png", + "We appreciate your interest in participating in the Ethereum Foundation's Research Challenge at the TUM Blockchain Conference. In this event, you will explore active research problems in the MEV space, then work in groups (max team size is 5) to develop solutions.", + backgroundImg: "/workshops/solana-workshop.png", + room: "Gern", + time: "Thu · 11:00 until Fri · 13:00", }, ]; diff --git a/public/partners/DLT_Talents_logo.png b/public/partners/DLT_Talents_logo.png new file mode 100644 index 0000000..21fd256 Binary files /dev/null and b/public/partners/DLT_Talents_logo.png differ diff --git a/sections/Partners.tsx b/sections/Partners.tsx index 42e02ee..5e7a525 100644 --- a/sections/Partners.tsx +++ b/sections/Partners.tsx @@ -94,13 +94,18 @@ const Partners = () => { { alt: "Frankfurt School", src: "/partners/frankfurt_school_logo.png" }, { alt: "Kryptosphere", src: "/partners/kryptosphere_logo.png" }, { alt: "Superteam Germany", src: "/partners/superteam_de_logo.png" }, - { alt: "Blockchain for Europe", src: "/partners/blockchain_europe_logo.png" }, + { + alt: "Blockchain for Europe", + src: "/partners/blockchain_europe_logo.png", + }, // { alt: "Encode Club", src: "/partners/encode_logo.png" }, { alt: "Blockchain Bayern e.V.", src: "/partners/blockchain_bayern_logo.png", }, { alt: "w3", src: "/partners/w3.png" }, + // { alt: "GTU Blockchain", src: "/partners/gtub_logo_white.png" }, + { alt: "DLT Talents Alumni", src: "/partners/DLT_Talents_logo.png" }, // { alt: "UnternehmerTUM", src: "/partners/UnternehmerTUM.png" }, // { alt: "BAF", src: "/partners/baf.png" }, // { alt: "PretzelDAO", src: "/partners/pretzeldao-logo.png" },