Add MUI theming and an axios interceptor
This commit is contained in:
143
webui/auth0-templates/page.js
Normal file
143
webui/auth0-templates/page.js
Normal file
@@ -0,0 +1,143 @@
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import { loadStripe } from '@stripe/stripe-js';
|
||||
import { Elements } from '@stripe/react-stripe-js';
|
||||
import PaymentForm from './components/PaymentForm';
|
||||
import './globals.css';
|
||||
|
||||
const stripePromise = loadStripe('');
|
||||
|
||||
const products = [
|
||||
{ id: '1', name: 'Premium Widget', price: 2999, description: 'High-quality widget for professionals' },
|
||||
{ id: '2', name: 'Standard Widget', price: 1999, description: 'Reliable widget for everyday use' },
|
||||
{ id: '3', name: 'Basic Widget', price: 999, description: 'Entry-level widget for beginners' }
|
||||
];
|
||||
|
||||
export default function Home() {
|
||||
const [selectedProduct, setSelectedProduct] = useState(null);
|
||||
const [clientSecret, setClientSecret] = useState('');
|
||||
const [orderId, setOrderId] = useState('');
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const handleProductSelect = async (product) => {
|
||||
setLoading(true);
|
||||
setSelectedProduct(product);
|
||||
|
||||
const newOrderId = Math.floor(Math.random() * 10000).toString();
|
||||
setOrderId(newOrderId);
|
||||
|
||||
try {
|
||||
const response = await fetch('https://impr.ink/api/stripe/create-payment-intent', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
amount: product.price,
|
||||
orderId: newOrderId
|
||||
}),
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.clientSecret) {
|
||||
setClientSecret(data.clientSecret);
|
||||
} else {
|
||||
console.error('Error creating payment intent:', data.error);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error:', error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handlePaymentSuccess = () => {
|
||||
setSelectedProduct(null);
|
||||
setClientSecret('');
|
||||
setOrderId('');
|
||||
};
|
||||
|
||||
const handleBackToProducts = () => {
|
||||
setSelectedProduct(null);
|
||||
setClientSecret('');
|
||||
setOrderId('');
|
||||
};
|
||||
|
||||
const appearance = {
|
||||
theme: 'stripe',
|
||||
variables: {
|
||||
colorPrimary: '#0570de',
|
||||
colorBackground: '#ffffff',
|
||||
colorText: '#30313d',
|
||||
colorDanger: '#df1b41',
|
||||
fontFamily: 'Ideal Sans, system-ui, sans-serif',
|
||||
spacingUnit: '2px',
|
||||
borderRadius: '4px',
|
||||
},
|
||||
};
|
||||
|
||||
const options = {
|
||||
clientSecret,
|
||||
appearance,
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="container">
|
||||
<header>
|
||||
<h1>🛍️ Stripe Payment Demo</h1>
|
||||
<p>Select a product to purchase</p>
|
||||
</header>
|
||||
|
||||
{!selectedProduct ? (
|
||||
<div className="products">
|
||||
<h2>Products</h2>
|
||||
<div className="product-grid">
|
||||
{products.map((product) => (
|
||||
<div key={product.id} className="product-card">
|
||||
<h3>{product.name}</h3>
|
||||
<p className="description">{product.description}</p>
|
||||
<p className="price">${(product.price / 100).toFixed(2)}</p>
|
||||
<button
|
||||
onClick={() => handleProductSelect(product)}
|
||||
disabled={loading}
|
||||
className="select-btn"
|
||||
>
|
||||
{loading ? 'Loading...' : 'Select'}
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="checkout">
|
||||
<div className="order-summary">
|
||||
<h2>Order Summary</h2>
|
||||
<div className="order-details">
|
||||
<p><strong>Product:</strong> {selectedProduct.name}</p>
|
||||
<p><strong>Order ID:</strong> {orderId}</p>
|
||||
<p><strong>Amount:</strong> ${(selectedProduct.price / 100).toFixed(2)}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{clientSecret && (
|
||||
<Elements options={options} stripe={stripePromise}>
|
||||
<PaymentForm
|
||||
onSuccess={handlePaymentSuccess}
|
||||
orderId={orderId}
|
||||
/>
|
||||
</Elements>
|
||||
)}
|
||||
|
||||
<button
|
||||
onClick={handleBackToProducts}
|
||||
className="back-btn"
|
||||
>
|
||||
← Back to Products
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user