Spaces:
Sleeping
Sleeping
File size: 4,612 Bytes
b5e3a76 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
<!-- static/ui/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Electronics Store</title>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@tailwindcss/typography/dist/typography.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
</head>
<body class="bg-gray-100">
<div id="app" class="container mx-auto px-4 py-8">
<h1 class="text-4xl font-bold mb-8 text-gray-800">Electronics Store</h1>
<!-- Filters -->
<div class="mb-6 flex gap-4">
<select v-model="selectedCategory" class="p-2 border rounded-lg">
<option value="">All Categories</option>
<option v-for="category in categories" :value="category">{{ category }}</option>
</select>
<select v-model="sortBy" class="p-2 border rounded-lg">
<option value="price-asc">Price: Low to High</option>
<option value="price-desc">Price: High to Low</option>
<option value="rating">Rating</option>
</select>
</div>
<!-- Products Grid -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<div v-for="product in filteredProducts"
class="bg-white rounded-lg shadow-md p-6 hover:shadow-lg transition-shadow">
<h2 class="text-xl font-semibold mb-2">{{ product.name }}</h2>
<div class="text-sm text-gray-600 mb-4">Category: {{ product.category }}</div>
<div class="mb-4">
<h3 class="font-semibold mb-2">Specifications:</h3>
<ul class="text-sm">
<li v-for="(value, key) in product.specs" class="mb-1">
{{ key }}: {{ value }}
</li>
</ul>
</div>
<div class="flex justify-between items-center mt-4">
<div class="text-2xl font-bold text-green-600">${{ product.price }}</div>
<div class="text-sm">
<span class="text-yellow-500">★</span>
{{ product.rating }}
</div>
</div>
<div class="mt-4 text-sm" :class="{'text-red-500': product.stock < 10, 'text-green-500': product.stock >= 10}">
{{ product.stock }} in stock
</div>
</div>
</div>
</div>
<script>
const { createApp, ref, computed } = Vue
createApp({
setup() {
const products = ref([])
const selectedCategory = ref('')
const sortBy = ref('price-asc')
// Fetch products from API
fetch('/api/electronics/products')
.then(response => response.json())
.then(data => products.value = data)
const categories = computed(() => {
return [...new Set(products.value.map(p => p.category))]
})
const filteredProducts = computed(() => {
let filtered = [...products.value]
if (selectedCategory.value) {
filtered = filtered.filter(p => p.category === selectedCategory.value)
}
switch (sortBy.value) {
case 'price-asc':
filtered.sort((a, b) => a.price - b.price)
break
case 'price-desc':
filtered.sort((a, b) => b.price - a.price)
break
case 'rating':
filtered.sort((a, b) => b.rating - a.rating)
break
}
return filtered
})
return {
products,
categories,
selectedCategory,
sortBy,
filteredProducts
}
}
}).mount('#app')
</script>
</body>
</html> |