Skip to main content
Glama
skyrmionz

ChatGPT Interactive Components Examples

by skyrmionz
checkout.html12.8 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif; padding: 20px; background: #f5f5f5; color: #333; } body.dark-mode { background: #1a1a1a; color: #e0e0e0; } .container { max-width: 600px; margin: 0 auto; } .header { display: flex; align-items: center; gap: 16px; margin-bottom: 24px; padding: 20px; background: white; border-radius: 12px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); } body.dark-mode .header { background: #2a2a2a; } .target-logo { width: 48px; height: 48px; background: linear-gradient(135deg, #cc0000 0%, #ff0000 100%); border-radius: 50%; display: flex; align-items: center; justify-content: center; box-shadow: 0 2px 8px rgba(204, 0, 0, 0.3); position: relative; flex-shrink: 0; } .target-logo::before { content: ''; position: absolute; width: 33px; height: 33px; border-radius: 50%; background: white; } .target-logo::after { content: ''; position: absolute; width: 18px; height: 18px; border-radius: 50%; background: #cc0000; } h1 { font-size: 24px; color: #333; } body.dark-mode h1 { color: #e0e0e0; } .section { background: white; padding: 24px; border-radius: 12px; margin-bottom: 16px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); } body.dark-mode .section { background: #2a2a2a; } .section-title { font-size: 18px; font-weight: 600; margin-bottom: 16px; color: #333; } body.dark-mode .section-title { color: #e0e0e0; } .info-box { background: #f9f9f9; padding: 16px; border-radius: 8px; border-left: 4px solid #cc0000; } body.dark-mode .info-box { background: #1a1a1a; } .info-box p { margin-bottom: 8px; color: #666; font-size: 14px; } body.dark-mode .info-box p { color: #999; } .info-box p:last-child { margin-bottom: 0; } .info-box strong { color: #333; } body.dark-mode .info-box strong { color: #e0e0e0; } .cart-items { margin-bottom: 16px; } .cart-item { display: flex; gap: 16px; padding: 16px; background: #f9f9f9; border-radius: 8px; margin-bottom: 12px; } body.dark-mode .cart-item { background: #1a1a1a; } .cart-item-image { width: 80px; height: 80px; object-fit: contain; border-radius: 8px; background: white; flex-shrink: 0; } body.dark-mode .cart-item-image { background: #2a2a2a; } .cart-item-info { flex: 1; } .cart-item-title { font-size: 14px; font-weight: 600; margin-bottom: 8px; color: #333; } body.dark-mode .cart-item-title { color: #e0e0e0; } .cart-item-price { font-size: 18px; font-weight: 700; color: #cc0000; } .order-summary { border-top: 2px solid #e0e0e0; padding-top: 16px; } body.dark-mode .order-summary { border-top-color: #444; } .summary-row { display: flex; justify-content: space-between; margin-bottom: 12px; font-size: 14px; } .summary-row.total { font-size: 20px; font-weight: 700; color: #333; padding-top: 12px; border-top: 1px solid #e0e0e0; } body.dark-mode .summary-row.total { color: #e0e0e0; border-top-color: #444; } .btn-primary { width: 100%; padding: 16px; background: linear-gradient(135deg, #cc0000 0%, #ff0000 100%); color: white; border: none; border-radius: 8px; font-size: 18px; font-weight: 600; cursor: pointer; transition: transform 0.1s, box-shadow 0.2s; } .btn-primary:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(204, 0, 0, 0.3); } .btn-primary:disabled { opacity: 0.6; cursor: not-allowed; transform: none; } .loading-btn { display: flex; align-items: center; justify-content: center; gap: 8px; } .btn-spinner { display: inline-block; width: 16px; height: 16px; border: 2px solid rgba(255, 255, 255, 0.3); border-top-color: white; border-radius: 50%; animation: spin 0.8s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } .success-screen { text-align: center; padding: 40px 20px; } .success-icon { width: 100px; height: 100px; margin: 0 auto 24px; background: linear-gradient(135deg, #00c853 0%, #00e676 100%); border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 64px; color: white; animation: scaleIn 0.3s ease-out; } @keyframes scaleIn { from { transform: scale(0); } to { transform: scale(1); } } .success-title { font-size: 28px; font-weight: 700; margin-bottom: 16px; color: #333; } body.dark-mode .success-title { color: #e0e0e0; } .success-message { font-size: 16px; color: #666; margin-bottom: 24px; } body.dark-mode .success-message { color: #999; } .order-number { background: #e3f2fd; padding: 16px; border-radius: 8px; margin-top: 24px; } body.dark-mode .order-number { background: #1a3a52; } .order-number p { font-size: 14px; color: #1976d2; } body.dark-mode .order-number p { color: #64b5f6; } .order-number strong { font-size: 18px; } .loading { text-align: center; padding: 40px; } .loading-spinner { display: inline-block; width: 40px; height: 40px; border: 4px solid rgba(204, 0, 0, 0.2); border-top-color: #cc0000; border-radius: 50%; animation: spin 0.8s linear infinite; margin-bottom: 16px; } </style> </head> <body> <div id="loading" class="loading"> <div class="loading-spinner"></div> <p>Loading checkout...</p> </div> <div id="checkout-content" style="display: none;"> <div class="container"> <div class="header"> <div class="target-logo"></div> <h1>Checkout</h1> </div> <!-- Cart Items --> <div class="section"> <div class="section-title">Order Summary</div> <div id="cart-items" class="cart-items"></div> <div class="order-summary"> <div class="summary-row"> <span>Subtotal</span> <span id="subtotal">$0.00</span> </div> <div class="summary-row"> <span>Shipping</span> <span>FREE</span> </div> <div class="summary-row"> <span>Tax</span> <span id="tax">$0.00</span> </div> <div class="summary-row total"> <span>Total</span> <span id="total">$0.00</span> </div> </div> </div> <!-- Shipping Address --> <div class="section"> <div class="section-title">Shipping Address</div> <div class="info-box"> <p><strong>Lauren Bailey</strong></p> <p>123 Main Street</p> <p>San Francisco, CA 94102</p> <p>United States</p> </div> </div> <!-- Payment Method --> <div class="section"> <div class="section-title">Payment Method</div> <div class="info-box"> <p><strong>Visa •••• 4242</strong></p> <p>Expires 12/25</p> </div> </div> <!-- Complete Purchase Button --> <div class="section"> <button class="btn-primary" id="complete-btn" onclick="completePurchase()"> Complete Purchase </button> </div> </div> </div> <!-- Success Screen --> <div id="success-content" style="display: none;"> <div class="container"> <div class="section success-screen"> <div class="success-icon">✓</div> <div class="success-title">Order Confirmed!</div> <div class="success-message">Thank you for your purchase. Your order has been successfully placed and will be shipped to your address.</div> <div class="order-number"> <p><strong>Order Number:</strong> <strong id="order-id"></strong></p> <p style="margin-top: 8px;">You'll receive a confirmation email shortly at <strong>laurenbailey@gmail.com</strong></p> </div> </div> </div> </div> <script> // Apply dark mode const theme = window.openai?.theme || 'light'; if (theme === 'dark') { document.body.classList.add('dark-mode'); } let cartItems = []; let checkInterval; function initializeCheckout() { const toolOutput = window.openai?.toolOutput || {}; const items = toolOutput.cart_items || []; if (items.length > 0 || toolOutput.initialized) { clearInterval(checkInterval); cartItems = items; console.log('Checkout loaded with items:', items); // Hide loading document.getElementById('loading').style.display = 'none'; document.getElementById('checkout-content').style.display = 'block'; renderCartItems(); } } function renderCartItems() { const container = document.getElementById('cart-items'); container.innerHTML = ''; let subtotal = 0; cartItems.forEach(item => { const imageUrl = item.thumbnail || item.image || item.img || 'https://via.placeholder.com/80x80?text=Product'; const title = item.title || item.name || item.product_title || 'Product'; const price = parseFloat(item.price || item.current_price || 0); const quantity = item.quantity || 1; const itemTotal = price * quantity; subtotal += itemTotal; const itemEl = document.createElement('div'); itemEl.className = 'cart-item'; itemEl.innerHTML = ` <img src="${imageUrl}" alt="${title}" class="cart-item-image" onerror="this.src='https://via.placeholder.com/80x80?text=Product'"> <div class="cart-item-info"> <div class="cart-item-title">${title}</div> <div style="font-size: 14px; color: #666; margin-bottom: 8px;">Qty: ${quantity}</div> <div class="cart-item-price">$${itemTotal.toFixed(2)}</div> </div> `; container.appendChild(itemEl); }); // Calculate totals const tax = subtotal * 0.0875; // 8.75% tax const total = subtotal + tax; document.getElementById('subtotal').textContent = `$${subtotal.toFixed(2)}`; document.getElementById('tax').textContent = `$${tax.toFixed(2)}`; document.getElementById('total').textContent = `$${total.toFixed(2)}`; } async function completePurchase() { const btn = document.getElementById('complete-btn'); btn.disabled = true; btn.innerHTML = '<div class="loading-btn"><div class="btn-spinner"></div> Processing...</div>'; // Simulate payment processing await new Promise(resolve => setTimeout(resolve, 2000)); // Generate order number const orderNumber = 'TGT-' + Math.random().toString(36).substring(2, 11).toUpperCase(); document.getElementById('order-id').textContent = orderNumber; // Show success screen document.getElementById('checkout-content').style.display = 'none'; document.getElementById('success-content').style.display = 'block'; } // Check for data every 200ms checkInterval = setInterval(initializeCheckout, 200); initializeCheckout(); </script> </body> </html>

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/skyrmionz/chatgpt-mcp-server-interactive-components'

If you have feedback or need assistance with the MCP directory API, please join our Discord server