import { useThemeHooks } from "@redocly/theme/core/hooks" import { Link } from "@redocly/theme/components/Link/Link" import { useRef, useState } from "react" type TutorialLanguagesMap = Record interface TutorialMetadataItem { path: string title: string description: string lastModified: string category: string } interface Tutorial { title: string description?: string path: string // External community contribution fields (optional) author?: { name: string; url: string } github?: string externalUrl?: string } interface TutorialSection { id: string title: string description: string tutorials: Tutorial[] showFooter?: boolean } // External community contribution - manually curated with author/repo/demo info interface PinnedExternalTutorial { title: string description: string author: { name: string; url: string } github: string url?: string } // Pinned tutorial entry: // - string: internal path (uses frontmatter title/description) // - object with `path`: internal path with optional description override // - PinnedExternalTutorial: external community contribution with author/repo/demo type PinnedTutorial = string | { path: string; description?: string } | PinnedExternalTutorial const MAX_WHATS_NEW = 3 const MAX_TUTORIALS_PER_SECTION = 6 export const frontmatter = { seo: { title: "Tutorials", description: "Learn how to get started building on the XRP Ledger with these helpful crypto wallet and blockchain tutorials for developers.", }, } const langIcons: Record = { javascript: { src: "/img/logos/javascript.svg", alt: "JavaScript" }, python: { src: "/img/logos/python.svg", alt: "Python" }, java: { src: "/img/logos/java.svg", alt: "Java" }, go: { src: "/img/logos/golang.svg", alt: "Go" }, php: { src: "/img/logos/php.svg", alt: "PHP" }, http: { src: "/img/logos/globe.svg", alt: "HTTP / WebSocket" }, xrpl: { src: "/img/logos/xrp-mark.svg", alt: "XRP Ledger" }, } // ── Section configuration ----------------------------------------------------------- // Categories and their titles are auto-detected by the tutorial-metadata plugin. // Use the config to customize the category titles, add descriptions, change the default category order, and pin tutorials. const sectionConfig: Record = { "whats-new": { title: "What's New", description: "Recently added/updated tutorials to help you build on the XRP Ledger.", }, "get-started": { showFooter: true, title: "Get Started with SDKs", description: "These tutorials walk you through the basics of building a very simple XRP Ledger-connected application using your favorite programming language.", pinned: [ { path: "/docs/tutorials/get-started/get-started-javascript/", description: "Using the xrpl.js client library." }, { path: "/docs/tutorials/get-started/get-started-python/", description: "Using xrpl.py, a pure Python library." }, { path: "/docs/tutorials/get-started/get-started-go/", description: "Using xrpl-go, a pure Go library." }, { path: "/docs/tutorials/get-started/get-started-java/", description: "Using xrpl4j, a pure Java library." }, { path: "/docs/tutorials/get-started/get-started-php/", description: "Using the XRPL_PHP client library." }, { path: "/docs/tutorials/get-started/get-started-http-websocket-apis/", description: "Access the XRP Ledger directly through the APIs of its core server." }, ], }, "tokens": { description: "Create and manage tokens on the XRP Ledger.", pinned: [ { path: "/docs/tutorials/tokens/mpts/issue-a-multi-purpose-token/", description: "Issue new tokens using the v2 fungible token standard." }, { path: "/docs/tutorials/tokens/fungible-tokens/issue-a-fungible-token/", description: "Issue new tokens using the v1 fungible token standard." }, { path: "/docs/tutorials/tokens/nfts/mint-and-burn-nfts-js/", description: "Create new NFTs, retrieve existing tokens, and burn the ones you no longer need." }, "/docs/tutorials/tokens/mpts/sending-mpts-in-javascript/", ], }, "payments": { description: "Transfer XRP and issued currencies using various payment types.", pinned: [ "/docs/tutorials/payments/send-xrp/", "/docs/tutorials/payments/create-trust-line-send-currency-in-javascript/", "/docs/tutorials/payments/send-a-conditional-escrow/", "/docs/tutorials/payments/send-a-timed-escrow/", ], }, "defi": { description: "Trade, provide liquidity, and lend using native XRP Ledger DeFi features.", pinned: [ "/docs/tutorials/defi/dex/create-an-automated-market-maker/", "/docs/tutorials/defi/dex/trade-in-the-decentralized-exchange/", "/docs/tutorials/defi/lending/use-the-lending-protocol/create-a-loan/", "/docs/tutorials/defi/lending/use-single-asset-vaults/create-a-single-asset-vault/", ], }, "best-practices": { description: "Learn recommended patterns for building reliable, secure applications on the XRP Ledger.", pinned: [ "/docs/tutorials/best-practices/api-usage/", ], }, "compliance-features": { title: "Compliance", description: "Implement compliance controls like destination tags, credentials, and permissioned domains.", }, "programmability": { description: "Set up cross-chain bridges and submit interoperability transactions.", }, "advanced-developer-topics": { description: "Explore advanced topics like WebSocket monitoring and testing Devnet features.", }, "sample-apps": { description: "Build complete, end-to-end applications like wallets and credential services.", pinned: [ { title: "XRPL Lending Protocol Demo", description: "A full-stack web application that demonstrates the end-to-end flow of the Lending Protocol and Single Asset Vaults.", author: { name: "Aaditya-T", url: "https://github.com/Aaditya-T" }, github: "https://github.com/Aaditya-T/lending_test", url: "https://lending-test-lovat.vercel.app/", }, ], }, } // ── Components ────────────────────────────────────────────────────────────── function TutorialCard({ tutorial, detectedLanguages, showFooter = false, translate, }: { tutorial: Tutorial detectedLanguages?: string[] showFooter?: boolean translate: (text: string) => string }) { // Get icons from auto-detected languages, or fallback to XRPL icon. const icons = detectedLanguages && detectedLanguages.length > 0 ? detectedLanguages.map((lang) => langIcons[lang]).filter(Boolean) : [langIcons.xrpl] return (
{icons.map((icon, idx) => ( {icon.alt} ))}

{translate(tutorial.title)}

{tutorial.description &&

{translate(tutorial.description)}

}
{showFooter &&
} ) } // Inline meta link used in ContributionCard function MetaLink({ href, icon, label }: { href: string icon: string label: string }) { return (