mirror of
https://github.com/XRPLF/xrpl-dev-portal.git
synced 2025-11-03 19:35:50 +00:00
Refactor payments and index pages to integrate BenefitsSection component
- Replaced the manual benefits list in the index page with the BenefitsSection component for improved maintainability. - Added BenefitsSection to the payments page, showcasing embedded payment use cases with new card data. - Updated ProjectCards component to support optional button text for enhanced project presentation. - Introduced new CSS styles for embedded payments icons and battle-tested project cards for better visual consistency.
This commit is contained in:
@@ -2,6 +2,7 @@ import React, { useState } from "react";
|
||||
import { useThemeHooks } from "@redocly/theme/core/hooks";
|
||||
import { AdvantagesSection } from "shared/components/advantages-section";
|
||||
import { ProjectCards } from "shared/components/project-cards";
|
||||
import { BenefitsSection } from "shared/components/benefits-section";
|
||||
|
||||
export const frontmatter = {
|
||||
seo: {
|
||||
@@ -104,6 +105,63 @@ const PaymentsPage: React.FC = () => {
|
||||
},
|
||||
];
|
||||
|
||||
const embeddedPaymentsCards = [
|
||||
{
|
||||
id: 'digital-wallets',
|
||||
title: 'Digital Wallets',
|
||||
description: 'Offer fast, low-fee stablecoin payments between users and applications.',
|
||||
},
|
||||
{
|
||||
id: 'cross-border-remittance',
|
||||
title: 'Cross-Border Remittance',
|
||||
description: 'Use secure payment channels and the most optimal liquidity pathways for global remittances with RLUSD.',
|
||||
},
|
||||
{
|
||||
id: 'regulated-foreign-exchange',
|
||||
title: 'Regulated Foreign Exchange',
|
||||
description: 'Tap into a set of fiat-backed stablecoins, instantaneous swaps for efficient Foreign Exchange.',
|
||||
},
|
||||
{
|
||||
id: 'merchant-settlement',
|
||||
title: 'Merchant Settlement',
|
||||
description: 'Settle daily payments across assets using escrow or checks with compliance-focused features.',
|
||||
},
|
||||
{
|
||||
id: 'b2b-payment-rails',
|
||||
title: 'B2B Payment Rails',
|
||||
description: 'Build programmable payment flows with conditions and real-time data feeds.',
|
||||
},
|
||||
{
|
||||
id: 'compliance-first-payment-acceptance',
|
||||
title: 'Compliance-First Payment Acceptance',
|
||||
description: 'Add Deposit Authorization and whitelisting to comply with AML and KYC workflows.',
|
||||
},
|
||||
];
|
||||
|
||||
const battleTestedProjects = [
|
||||
{
|
||||
id: "coinpayments",
|
||||
label: "CoinPayments",
|
||||
url: "#",
|
||||
description: "CoinPayments uses XRPL's fast and low-cost payment rails to enable merchants to accept digital assets globally with near-instant settlement and minimal transaction fees.",
|
||||
buttonText: "Case Study"
|
||||
},
|
||||
{
|
||||
id: "ripple",
|
||||
label: "Ripple",
|
||||
url: "#",
|
||||
description: "Ripple Payments enables crypto companies, payment service providers and fintech to facilitate real-time cross-border payments using stablecoins, digital assets and local currencies — with XRPL as a foundational transaction layer.",
|
||||
buttonText: "Case Study"
|
||||
},
|
||||
{
|
||||
id: "fiipay",
|
||||
label: "FiiPay",
|
||||
url: "#",
|
||||
description: "FiiPay connects XRPL-based crypto wallets to point-of-sale terminals, allowing customers to pay with RLUSD or XRP while helping merchants save costs on card processing fees.",
|
||||
buttonText: "Case Study"
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<main className="use-case-payments">
|
||||
<section className="use-case-payments__hero">
|
||||
@@ -140,13 +198,29 @@ const PaymentsPage: React.FC = () => {
|
||||
useLinks={false}
|
||||
className="payments-advantages-spacing"
|
||||
/>
|
||||
|
||||
<ProjectCards
|
||||
title="Enterprise-Grade Stablecoins, Issued Natively on XRPL"
|
||||
projects={paymentProjects}
|
||||
showCarousel={false}
|
||||
className="mt-12 px-0"
|
||||
/>
|
||||
<BenefitsSection
|
||||
title="Unlock New Business Models with Embedded Payments"
|
||||
description="XRPL Payments supports modern fintech use cases with plug-and-play APIs or partner-led deployments."
|
||||
cards={embeddedPaymentsCards}
|
||||
showImages={true}
|
||||
className="embedded-payments-section px-0"
|
||||
listId="embedded-payments-list"
|
||||
/>
|
||||
|
||||
<ProjectCards
|
||||
title="Payments Solution, Battle-Tested by Industry Leaders"
|
||||
projects={battleTestedProjects}
|
||||
showCarousel={false}
|
||||
className="battle-tested-section px-0"
|
||||
/>
|
||||
|
||||
|
||||
</main>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { useThemeHooks } from '@redocly/theme/core/hooks';
|
||||
import { Link } from '@redocly/theme/components/Link/Link';
|
||||
import { BenefitsSection } from 'shared/components/benefits-section';
|
||||
|
||||
export const frontmatter = {
|
||||
seo: {
|
||||
@@ -147,23 +148,12 @@ export default function Index() {
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse col-sm-8 p-0">
|
||||
<h3 className="h4 h2-sm">{translate('Why developers choose the XRP Ledger')}</h3>
|
||||
<h6 className="eyebrow mb-3">{translate('Benefits')}</h6>
|
||||
</div>
|
||||
<ul className="mt-10 card-grid card-grid-3xN" id="benefits-list">
|
||||
{cards.map(card => (
|
||||
<li className="col ls-none" key={card.id}>
|
||||
<img id={card.id} alt={card.title + ' Icon'} />
|
||||
<h4 className="mt-3 mb-0 h5">{translate(card.title)}</h4>
|
||||
<p className="mt-6-until-sm mt-3 mb-0">
|
||||
{typeof card.description === 'string' ? translate(card.description) : card.description}
|
||||
</p>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
<BenefitsSection
|
||||
eyebrow="Benefits"
|
||||
title="Why developers choose the XRP Ledger"
|
||||
cards={cards}
|
||||
showImages={true}
|
||||
/>
|
||||
<section className="container-new py-26">
|
||||
<div className="d-flex flex-column-reverse col-sm-8 p-0">
|
||||
<h3 className="h4 h2-sm">
|
||||
|
||||
55
shared/components/benefits-section.tsx
Normal file
55
shared/components/benefits-section.tsx
Normal file
@@ -0,0 +1,55 @@
|
||||
import React from "react";
|
||||
import { useThemeHooks } from "@redocly/theme/core/hooks";
|
||||
|
||||
export interface BenefitCard {
|
||||
id: string;
|
||||
title: string;
|
||||
description: React.ReactNode | string;
|
||||
}
|
||||
|
||||
export interface BenefitsSectionProps {
|
||||
eyebrow?: string;
|
||||
title: string;
|
||||
description?: string;
|
||||
cards: BenefitCard[];
|
||||
className?: string;
|
||||
showImages?: boolean;
|
||||
listId?: string;
|
||||
}
|
||||
|
||||
export const BenefitsSection: React.FC<BenefitsSectionProps> = ({
|
||||
eyebrow,
|
||||
title,
|
||||
description,
|
||||
cards,
|
||||
className = "",
|
||||
showImages = true,
|
||||
listId = "benefits-list",
|
||||
}) => {
|
||||
const { useTranslate } = useThemeHooks();
|
||||
const { translate } = useTranslate();
|
||||
|
||||
return (
|
||||
<section className={`container-new py-26 ${className}`}>
|
||||
<div className="d-flex flex-column-reverse col-lg-10 col-sm-8 p-0">
|
||||
<h3 className="h4 h2-sm">{translate(title)}</h3>
|
||||
{eyebrow && <h6 className="eyebrow mb-3">{translate(eyebrow)}</h6>}
|
||||
</div>
|
||||
{description && (
|
||||
<p className="mt-6 mb-0 col-lg-8 col-sm-8 p-0">{translate(description)}</p>
|
||||
)}
|
||||
<ul className="mt-10 card-grid card-grid-3xN" id={listId}>
|
||||
{cards.map(card => (
|
||||
<li className="col ls-none" key={card.id}>
|
||||
{showImages && <img id={card.id} alt={card.title + ' Icon'} />}
|
||||
<h4 className="mt-3 mb-0 h5">{translate(card.title)}</h4>
|
||||
<p className="mt-6-until-sm mt-3 mb-0">
|
||||
{typeof card.description === 'string' ? translate(card.description) : card.description}
|
||||
</p>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -6,6 +6,7 @@ interface Project {
|
||||
label: string;
|
||||
url: string;
|
||||
description?: string; // New optional field for payments page
|
||||
buttonText?: string; // Optional button text for battle-tested cards
|
||||
}
|
||||
|
||||
interface ProjectCardsProps {
|
||||
@@ -51,6 +52,11 @@ const ProjectCard = ({ project, index, showCarousel = true }: {
|
||||
})()}
|
||||
</div>
|
||||
)}
|
||||
{!showCarousel && project.buttonText && (
|
||||
<div className="project-button">
|
||||
<a href={project.url} className="btn-arrow battle-tested-arrow">{translate(project.buttonText)}</a>
|
||||
</div>
|
||||
)}
|
||||
</a>
|
||||
);
|
||||
};
|
||||
|
||||
File diff suppressed because one or more lines are too long
BIN
static/img/uses/payments/b2b-payment.png
Normal file
BIN
static/img/uses/payments/b2b-payment.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 946 B |
BIN
static/img/uses/payments/compliance.png
Normal file
BIN
static/img/uses/payments/compliance.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
static/img/uses/payments/cross-border.png
Normal file
BIN
static/img/uses/payments/cross-border.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
static/img/uses/payments/digital-wallet.png
Normal file
BIN
static/img/uses/payments/digital-wallet.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 964 B |
BIN
static/img/uses/payments/merchant-settlement.png
Normal file
BIN
static/img/uses/payments/merchant-settlement.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.0 KiB |
BIN
static/img/uses/payments/regulated.png
Normal file
BIN
static/img/uses/payments/regulated.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
@@ -89,6 +89,33 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Payments page specific embedded payments icons
|
||||
#embedded-payments-list {
|
||||
#digital-wallets {
|
||||
content: url("../img/uses/payments/digital-wallet.png");
|
||||
}
|
||||
|
||||
#cross-border-remittance {
|
||||
content: url("../img/uses/payments/cross-border.png");
|
||||
}
|
||||
|
||||
#regulated-foreign-exchange {
|
||||
content: url("../img/uses/payments/regulated.png");
|
||||
}
|
||||
|
||||
#merchant-settlement {
|
||||
content: url("../img/uses/payments/merchant-settlement.png");
|
||||
}
|
||||
|
||||
#b2b-payment-rails {
|
||||
content: url("../img/uses/payments/b2b-payment.png");
|
||||
}
|
||||
|
||||
#compliance-first-payment-acceptance {
|
||||
content: url("../img/uses/payments/compliance.png");
|
||||
}
|
||||
}
|
||||
|
||||
.cta {
|
||||
position: absolute;
|
||||
|
||||
|
||||
@@ -1083,6 +1083,9 @@ body,
|
||||
background-color: transparent;
|
||||
white-space: normal;
|
||||
box-sizing: border-box;
|
||||
.card-title{
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.security-card::before {
|
||||
@@ -1150,7 +1153,6 @@ body,
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.advantage-item {
|
||||
position: relative;
|
||||
padding-left: 20px;
|
||||
@@ -1161,7 +1163,6 @@ body,
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
color: #7919FF;
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
}
|
||||
@@ -1226,7 +1227,6 @@ body,
|
||||
position: relative;
|
||||
padding: 32px;
|
||||
.project-description {
|
||||
padding: 0 1rem;
|
||||
text-align: left; /* Changed from center to left */
|
||||
|
||||
.first-word {
|
||||
@@ -1307,4 +1307,75 @@ body,
|
||||
&.even::before {
|
||||
background: linear-gradient(90deg, #4BB7FF -0.32%, #32E685 30.61%);
|
||||
}
|
||||
}
|
||||
|
||||
/* Battle-tested section styles */
|
||||
.use-case-payments .battle-tested-section {
|
||||
h4.eyebrow {
|
||||
font-size: 28px !important;
|
||||
}
|
||||
|
||||
.payments-project-card {
|
||||
/* Override styles for battle-tested cards */
|
||||
min-height: 384px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.project-logo img {
|
||||
/* Placeholder images - use standard sizing */
|
||||
width: 120px;
|
||||
height: 60px;
|
||||
background-color: #333;
|
||||
border-radius: 8px;
|
||||
content: "";
|
||||
}
|
||||
|
||||
.project-description {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.project-button {
|
||||
margin-top: auto;
|
||||
padding-top: 32px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
.battle-tested-arrow {
|
||||
color: #9A52FF;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
background: none !important;
|
||||
|
||||
&::after {
|
||||
position: relative;
|
||||
top: -1px;
|
||||
display: inline-block;
|
||||
content: url('../img/icons/arrow-right-purple.svg');
|
||||
margin-left: 8px;
|
||||
transition: transform 0.3s ease-out;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
background: none !important;
|
||||
|
||||
&::after {
|
||||
transform: translateX(4px);
|
||||
}
|
||||
}
|
||||
|
||||
&:focus {
|
||||
background: none !important;
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user