diff --git a/content/index.page.tsx b/content/index.page.tsx new file mode 100644 index 0000000000..e251894d0d --- /dev/null +++ b/content/index.page.tsx @@ -0,0 +1,256 @@ +import * as React from 'react'; +import { useTranslate } from '@portal/hooks'; + +const cards = [ + { + id: 'public', + title: 'Public and Decentralized', + description: 'Open source, open to anyone to build on, maintained by the community', + }, + { + id: 'streamlined', + title: 'Streamlined Development', + description: 'Intentional innovations, tools and documentation reduce time to market', + }, + { id: 'performance', title: 'High Performance', description: 'Thousands of transactions settled in seconds' }, + { + id: 'low-cost', + title: 'Low Cost', + description: + "At fractions of a penny per transaction, costs are inexpensive enough to enable a wide variety of blockchain use cases", + }, + { + id: 'community', + title: 'Motivated Community', + description: 'Companies, developers, validators, and users work together to make the XRP Ledger better every day', + }, + { + id: 'reliability', + title: 'Proven Reliability', + description: '10+ years of error-free, uninterrupted performance over more than 63 million ledgers', + }, +]; + +const cards2 = [ + { + href: 'decentralized-exchange.html', + title: 'Decentralized Exchange', + description: + 'A high-performance decentralized peer-to-peer multi-currency exchange built directly into the blockchain', + }, + { + href: 'cross-currency-payments.html', + title: 'Cross-Currency Payments', + description: 'Atomically settle multi-hop payments that cross currency or national boundaries with ease', + }, + { + href: 'payment-channels.html', + title: "Payment
Channels", + description: 'Batched micropayments with unlimited speed, secured with XRP', + }, + { + href: 'multi-signing.html', + title: 'Multi-Signing', + description: 'Flexible options for custody and security of on-ledger accounts', + }, + { + href: 'tokens.html', + title: 'Tokens', + description: + 'All currencies other than XRP can be represented in the XRP Ledger as tokens, sometimes called “IOUs”', + }, +]; + +const cards3 = [ + { + href: 'get-started.html', + title: 'Quickstart', + description: 'Access everything you need to get started working with the XRPL', + }, + { href: 'tutorials.html', title: 'Guided Tutorials', description: 'Follow step-by-step guides for frequent tasks' }, + { href: 'concepts.html', title: 'XRPL Fundamentals', description: 'Read about the XRPL’s foundational concepts' }, + { + href: 'client-libraries.html', + title: 'Choose a Language', + description: 'Find tools, documentation, and sample code in Python, Java, Javascript, or use HTTP APIs', + }, + { href: 'uses.html', title: 'Get Inspired', description: 'See what your peers have built on the XRPL' }, +]; + +const features = [ + { + chip: 'In Development', + title: 'Smart Contracts', + description: + "Hooks are small, efficient WebAssembly modules designed specifically for the XRPL. Check out the hooks amendment and public testnet that enable smart contract functionality.", + href: 'https://hooks-testnet.xrpl-labs.com/', + }, + { + chip: 'Enabled', + title: 'Non-Fungible Tokens', + description: + "Lower fees, faster transactions, and custom token functionality make the XRPL ideally suited for building an ecosystem for NFTs. Explore the XRP Ledger's NFT capabilities.", + href: 'non-fungible-tokens.html', + }, +]; + +const target = { prefix: '' }; // TODO: fixme + +export default function Index() { + const { translate } = useTranslate(); + + return ( +
+
+
+
+ X +
+
+
+

+ {translate('The Blockchain')} +
+ {translate('Built for Business')} +

+
{translate('XRPL | XRP Ledger')}
+
+ + {translate('Start Building')} + +
+
+
+ + +
+
+
+

{translate('The XRP Ledger: The Blockchain Built for Business')}

+
+ {translate( + 'The XRP Ledger (XRPL) is a decentralized, public blockchain led by a global community of businesses and developers looking to solve problems and create value.' + )} +
+

+ {translate( + 'Proven reliable over more than a decade of error-free functioning, the XRPL offers streamlined development, low transaction costs, high performance, and sustainability. So you can build with confidence–and move your most critical projects forward.' + )} +

+
+
+
+
+

{translate('Why developers choose the XRP Ledger')}

+
{translate('Benefits')}
+
+
    + {cards.map(card => ( +
  • + {card.title +

    {card.title}

    +

    {card.description}

    +
  • + ))} +
+
+
+
+

+ {translate( + 'Activate the proven potential of the XRP Ledger and find a trusted foundation for your next innovation' + )} +

+
{translate('Powerful Features')}
+
+
+ {cards2.map(card => ( + +
+

{card.title}

+

{card.description}

+
+
 
+
+ ))} +
+
+
+
+

{translate('Choose a path, and bring your project to life on the XRP Ledger')}

+
{translate('Where to Start')}
+
+
+ {cards3.map(card => ( + +
+

{card.title}

+

{card.description}

+
+
 
+
+ ))} +
+
+
+
+ + +
+

{translate('Our Shared Vision for XRPL’s Future')}

+

+ {translate( + "Together, we're building the greenest infrastructure to drive blockchain innovation that doesn't sacrifice utility or performance, to bring the developer community's vision to life." + )} +

+ + {translate('Learn More')} + +
+
+
+
+
+

+ {translate('Explore what the community is building to enable new features and use cases on XRPL')} +

+
{translate('Preview New Features')}
+
+
    + {features.map(feat => ( +
  • + + {feat.chip} + +

    {feat.title}

    +

    {feat.description}

    +
  • + ))} +
+
+
+
+ +
+
+

+ {translate('Join the Community ')} +
+ {translate(' at XRPL.org')} +

+
+

+ {translate('Connect at XRPL.org, a community by and for the developers ')} +
+ {translate(' and entrepeneurs who rely on the XRPL.')} +

+ + {translate('Get Involved')} + +
+
+
+
+
+ ); +} diff --git a/convert-template.cjs b/convert-template.cjs new file mode 100644 index 0000000000..208cc2c240 --- /dev/null +++ b/convert-template.cjs @@ -0,0 +1,92 @@ +/** + * THis is very hacky script to convert jinja templates to jsx. + * It doesn't cover all cases yet. I tested it for index page only. + */ + +const fs = require('fs'); +const path = require('path'); + +const HtmlToJsx = require('htmltojsx'); + +const fileName = process.argv[2]; +const pageName = path.basename(fileName, '.html.jinja').replace('page-', '').replace('home', 'index'); + +const outputFileName = 'content/' + pageName + '.page.tsx'; + +const componentName = pageName.substring(0, 1).toUpperCase() + pageName.substring(1); + +const content = fs.readFileSync(fileName, 'utf8'); + +const mainBlockOffset = content.indexOf('{% block main %}'); +const mainBlockEndOffset = content.indexOf('{% endblock %}', mainBlockOffset); +const mainBlock = content.substring(mainBlockOffset + 16, mainBlockEndOffset); + +const classes = content.match(/{% block mainclasses %}(.+?){% endblock %}/)?.[1] || ''; + +const setStatements = mainBlock.match(/{% set ([\w\d]+) = ((.|\n)+?)%}/g); +const sets = setStatements.map(setStatement => { + const setStatementParts = setStatement.split(' = '); + const setStatementName = setStatementParts[0].replace('{% set ', ''); + const setStatementValue = setStatementParts[1].replace(/%}/g, ''); + return { + name: setStatementName, + value: setStatementValue.replace(/_\("(.+?)"\)/g, '"$1"'), + }; +}); + +const mainBlockWithoutSets = mainBlock.replace(/{% set ([\w\d]+) = ((.|\n)+?)%}/g, ''); + +const replacedJinja = mainBlockWithoutSets + .replace(/{%/g, '$$$$') + .replace(/%}/g, '$$$$') + .replace(/{{/g, '$$$$') + .replace(/}}/g, '$$$$'); + +const HtmlToJsxInst = new HtmlToJsx({ + createClass: false, + indent: ' ', +}); +const jsx = HtmlToJsxInst.convert(replacedJinja); + +// replace trans + +// replace $$ for card in cards3 $$ +const jsxWithReplacedForLoops = jsx + .replace(/\$\$ for ([\w\d]+) in ([\w\d]+) \$\$/g, ' { $2.map($1 => (') + .replace(/\$\$ endfor \$\$/g, ')) }') + .replace(/="\$\$(\w+\.\w+)\$\$"/g, '={$1}') + .replace(/="\$\$(\w+\.\w+)\$\$\$\$(\w+\.\w+)\$\$"/g, '={$1 + $2}') + .replace(/="\$\$(\w+\.\w+)\$\$(.+?)"/g, '={$1 + "$2"}') + .replace(/\$\$(\w+\.\w+)\$\$/g, '{$1}') + .replace(/]*?)src="(.*?)"/g, ' { + if (match1.indexOf('
') > -1) { + const parts = match1.split('
'); + return parts.map(part => '{translate(' + JSON.stringify(part) + ')}').join('
' + '\n'); + } + return '{translate(' + JSON.stringify(match1) + ')}'; + } +); + +const output = `import * as React from 'react'; +import { useTranslate } from '@portal/hooks'; + +${sets.map(set => `const ${set.name} = ${set.value};`).join('\n\n')} + +const target= {prefix: ''}; // TODO: fixme + +export default function ${componentName}() { + const { translate } = useTranslate(); + + return ( +
+ ${jsxWithReplacedTranslate} +
+ ) +} +`; + +fs.writeFileSync(outputFileName, output, 'utf8');