Download index.html from vdimsa/api-test: direct link, hf CLI and curl.
- Browser
- Download file 13.5 kB
-
https://huggingface.co/spaces/vdimsa/api-test/resolve/main/index.html
- Command line
-
hf download hf://spaces/vdimsa/api-test/index.html
-
curl -L -o index.html https://huggingface.co/spaces/vdimsa/api-test/resolve/main/index.html
13.5 kB
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Deraah Product API Tester</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| .fade-in { | |
| animation: fadeIn 0.3s ease-in-out; | |
| } | |
| @keyframes fadeIn { | |
| from { opacity: 0; transform: translateY(10px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| .product-card { | |
| transition: all 0.3s ease; | |
| } | |
| .product-card:hover { | |
| transform: translateY(-5px); | |
| box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1); | |
| } | |
| .input-focus { | |
| transition: all 0.3s ease; | |
| } | |
| .input-focus:focus { | |
| border-color: #8b5cf6; | |
| box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.2); | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-50 min-h-screen"> | |
| <div class="container mx-auto px-4 py-12"> | |
| <div class="max-w-3xl mx-auto"> | |
| <!-- Header --> | |
| <div class="text-center mb-10"> | |
| <h1 class="text-4xl font-bold text-purple-800 mb-2">Deraah Product API Tester</h1> | |
| <p class="text-lg text-gray-600">Enter a SKU to fetch live product information</p> | |
| </div> | |
| <!-- Search Form --> | |
| <div class="bg-white rounded-xl shadow-md p-6 mb-8"> | |
| <form id="productForm" class="space-y-4"> | |
| <div> | |
| <label for="sku" class="block text-sm font-medium text-gray-700 mb-1">Product SKU</label> | |
| <div class="relative"> | |
| <input | |
| type="text" | |
| id="sku" | |
| name="sku" | |
| placeholder="e.g. 10411131442000-8050" | |
| class="w-full px-4 py-3 rounded-lg border border-gray-300 input-focus focus:outline-none" | |
| required | |
| > | |
| <div class="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none hidden" id="loadingSpinner"> | |
| <i class="fas fa-spinner fa-spin text-purple-600"></i> | |
| </div> | |
| </div> | |
| <p class="mt-1 text-sm text-gray-500">Enter a valid product SKU</p> | |
| </div> | |
| <button | |
| type="submit" | |
| class="w-full bg-purple-600 hover:bg-purple-700 text-white font-medium py-3 px-4 rounded-lg transition duration-300 flex items-center justify-center" | |
| > | |
| <i class="fas fa-search mr-2"></i> Fetch Product | |
| </button> | |
| </form> | |
| </div> | |
| <!-- Error Message --> | |
| <div id="errorAlert" class="hidden bg-red-50 border-l-4 border-red-500 p-4 mb-8 rounded-lg"> | |
| <div class="flex"> | |
| <div class="flex-shrink-0"> | |
| <i class="fas fa-exclamation-circle text-red-500"></i> | |
| </div> | |
| <div class="ml-3"> | |
| <p class="text-sm text-red-700" id="errorMessage">Product not found. Please check the SKU and try again.</p> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Authentication Error --> | |
| <div id="authErrorAlert" class="hidden bg-yellow-50 border-l-4 border-yellow-500 p-4 mb-8 rounded-lg"> | |
| <div class="flex"> | |
| <div class="flex-shrink-0"> | |
| <i class="fas fa-exclamation-triangle text-yellow-500"></i> | |
| </div> | |
| <div class="ml-3"> | |
| <p class="text-sm text-yellow-700" id="authErrorMessage">Authentication required. Please contact support.</p> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Product Card --> | |
| <div id="productContainer" class="hidden"> | |
| <div class="product-card bg-white rounded-xl shadow-md overflow-hidden fade-in"> | |
| <div class="md:flex"> | |
| <div class="md:flex-shrink-0 md:w-1/3"> | |
| <img id="productImage" class="h-48 w-full object-cover md:h-full" src="" alt="Product image"> | |
| </div> | |
| <div class="p-8 md:w-2/3"> | |
| <div class="flex justify-between items-start"> | |
| <div> | |
| <h2 id="productName" class="text-2xl font-bold text-gray-800 mb-2"></h2> | |
| <span id="availabilityBadge" class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium hidden"> | |
| <span class="w-2 h-2 mr-2 rounded-full bg-green-500"></span> | |
| Available | |
| </span> | |
| </div> | |
| <div id="productPrice" class="text-xl font-semibold text-purple-700"></div> | |
| </div> | |
| <p id="productDescription" class="mt-4 text-gray-600"></p> | |
| <div class="mt-6"> | |
| <div class="flex items-center"> | |
| <span class="text-gray-500 mr-2">SKU:</span> | |
| <span id="productSku" class="font-medium text-gray-700"></span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| document.addEventListener('DOMContentLoaded', function() { | |
| const form = document.getElementById('productForm'); | |
| const errorAlert = document.getElementById('errorAlert'); | |
| const authErrorAlert = document.getElementById('authErrorAlert'); | |
| const productContainer = document.getElementById('productContainer'); | |
| const loadingSpinner = document.getElementById('loadingSpinner'); | |
| form.addEventListener('submit', async function(e) { | |
| e.preventDefault(); | |
| const sku = document.getElementById('sku').value.trim(); | |
| if (!sku) { | |
| showError('Please enter a SKU'); | |
| return; | |
| } | |
| // Show loading spinner | |
| loadingSpinner.classList.remove('hidden'); | |
| // Hide previous results and errors | |
| errorAlert.classList.add('hidden'); | |
| authErrorAlert.classList.add('hidden'); | |
| productContainer.classList.add('hidden'); | |
| try { | |
| // Call our backend API route | |
| const response = await fetch(`/api/products`, { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| 'Accept': 'application/json' | |
| }, | |
| body: JSON.stringify({ sku: sku }) | |
| }); | |
| // Check response status first | |
| if (response.status === 401 || response.status === 403) { | |
| throw new Error('AUTH_REQUIRED'); | |
| } | |
| // Check if response is JSON | |
| const contentType = response.headers.get('content-type'); | |
| if (!contentType || !contentType.includes('application/json')) { | |
| const text = await response.text(); | |
| if (text.includes('<html') || text.includes('<!DOCTYPE html')) { | |
| throw new Error('AUTH_REQUIRED'); | |
| } | |
| throw new Error('Invalid response format from server'); | |
| } | |
| const productData = await response.json(); | |
| if (!response.ok || productData.error) { | |
| throw new Error(productData.message || 'Failed to fetch product'); | |
| } | |
| if (!productData || Object.keys(productData).length === 0) { | |
| throw new Error('Product not found'); | |
| } | |
| // Display product data | |
| displayProduct(productData); | |
| } catch (error) { | |
| console.error('Fetch error:', error); | |
| if (error.message === 'AUTH_REQUIRED') { | |
| showAuthError('Authentication required. Please contact support.'); | |
| } else { | |
| showError(error.message || 'An error occurred while fetching product data. Please try again.'); | |
| } | |
| } finally { | |
| loadingSpinner.classList.add('hidden'); | |
| } | |
| }); | |
| function showError(message) { | |
| document.getElementById('errorMessage').textContent = message; | |
| errorAlert.classList.remove('hidden'); | |
| productContainer.classList.add('hidden'); | |
| authErrorAlert.classList.add('hidden'); | |
| } | |
| function showAuthError(message) { | |
| document.getElementById('authErrorMessage').textContent = message; | |
| authErrorAlert.classList.remove('hidden'); | |
| productContainer.classList.add('hidden'); | |
| errorAlert.classList.add('hidden'); | |
| } | |
| function displayProduct(product) { | |
| // Set product details | |
| document.getElementById('productName').textContent = product.name || 'No name available'; | |
| document.getElementById('productDescription').textContent = product.shortDescription || product.description || 'No description available'; | |
| // Format price with currency | |
| if (product.price && product.currency) { | |
| const formattedPrice = new Intl.NumberFormat(undefined, { | |
| style: 'currency', | |
| currency: product.currency | |
| }).format(product.price); | |
| document.getElementById('productPrice').textContent = formattedPrice; | |
| } else if (product.price) { | |
| document.getElementById('productPrice').textContent = `$${product.price.toFixed(2)}`; | |
| } else { | |
| document.getElementById('productPrice').textContent = 'Price not available'; | |
| } | |
| document.getElementById('productSku').textContent = product.sku || product.id || ''; | |
| // Set product image | |
| const productImage = document.getElementById('productImage'); | |
| if (product.images && product.images.length > 0) { | |
| productImage.src = product.images[0]; | |
| productImage.alt = product.name || 'Product image'; | |
| } else if (product.image) { | |
| productImage.src = product.image; | |
| productImage.alt = product.name || 'Product image'; | |
| } else { | |
| productImage.src = 'https://via.placeholder.com/400x300?text=No+Image+Available'; | |
| productImage.alt = 'No image available'; | |
| } | |
| // Set availability | |
| const availabilityBadge = document.getElementById('availabilityBadge'); | |
| if (product.available || product.inStock) { | |
| availabilityBadge.classList.remove('hidden'); | |
| } else { | |
| availabilityBadge.classList.add('hidden'); | |
| } | |
| // Show product container | |
| productContainer.classList.remove('hidden'); | |
| } | |
| }); | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=vdimsa/api-test" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |