mirror of
				https://github.com/XRPLF/xrpl-dev-portal.git
				synced 2025-11-04 11:55: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 {
 | 
			
		||||
@@ -1308,3 +1308,74 @@ body,
 | 
			
		||||
    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