Product Reviews
Product reviews with ratings, helpful votes, and review form
Customer Reviews
4.8
Based on 256 reviews
Verified Purchase
Code
<div x-data="{
sortBy: 'recent',
reviews: [
{ id: 1, author: 'John Doe', rating: 5, date: 'Dec 10, 2024', text: 'Amazing product! Highly recommend.', helpful: 12, verified: true },
{ id: 2, author: 'Jane Smith', rating: 4, date: 'Dec 8, 2024', text: 'Great quality, fast shipping.', helpful: 8, verified: true }
]
}" class="bg-white dark:bg-gray-800 rounded-lg shadow-lg p-6">
<div class="flex justify-between items-center mb-6">
<h2 class="text-2xl font-bold text-gray-900 dark:text-white">Customer Reviews</h2>
<select x-model="sortBy" class="px-4 py-2 border rounded-lg dark:bg-gray-700 dark:border-gray-600">
<option value="recent">Most Recent</option>
<option value="helpful">Most Helpful</option>
<option value="highest">Highest Rating</option>
</select>
</div>
<!-- Overall Rating -->
<div class="flex items-center gap-8 mb-8 pb-8 border-b dark:border-gray-700">
<div class="text-center">
<div class="text-5xl font-bold text-gray-900 dark:text-white mb-2">4.8</div>
<div class="flex text-yellow-400 mb-1">
<template x-for="i in 5">
<svg class="w-5 h-5 fill-current" viewBox="0 0 20 20"><path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"/></svg>
</template>
</div>
<p class="text-sm text-gray-600 dark:text-gray-400">Based on 256 reviews</p>
</div>
<div class="flex-1">
<template x-for="stars in [5,4,3,2,1]">
<div class="flex items-center gap-2 mb-1">
<span class="text-sm w-8" x-text="stars + ' ★'"></span>
<div class="flex-1 h-2 bg-gray-200 dark:bg-gray-700 rounded-full overflow-hidden">
<div class="h-full bg-yellow-400" :style="'width: ' + (stars === 5 ? 75 : stars === 4 ? 20 : 5) + '%'"></div>
</div>
<span class="text-sm text-gray-600 dark:text-gray-400 w-12 text-right"
x-text="(stars === 5 ? 192 : stars === 4 ? 51 : 13)"></span>
</div>
</template>
</div>
</div>
<!-- Review List -->
<div class="space-y-6">
<template x-for="review in reviews" :key="review.id">
<div class="border-b dark:border-gray-700 pb-6">
<div class="flex items-start justify-between mb-3">
<div>
<div class="flex items-center gap-2 mb-1">
<span class="font-semibold text-gray-900 dark:text-white" x-text="review.author"></span>
<span x-show="review.verified"
class="text-xs bg-green-100 dark:bg-green-900/20 text-green-700 dark:text-green-400 px-2 py-1 rounded">
Verified Purchase
</span>
</div>
<div class="flex items-center gap-2">
<div class="flex text-yellow-400">
<template x-for="i in review.rating">
<svg class="w-4 h-4 fill-current" viewBox="0 0 20 20"><path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"/></svg>
</template>
</div>
<span class="text-sm text-gray-600 dark:text-gray-400" x-text="review.date"></span>
</div>
</div>
</div>
<p class="text-gray-700 dark:text-gray-300 mb-3" x-text="review.text"></p>
<div class="flex items-center gap-4">
<button class="text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white">
Helpful (<span x-text="review.helpful"></span>)
</button>
<button class="text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white">
Report
</button>
</div>
</div>
</template>
</div>
<!-- Write Review Button -->
<div class="mt-6 text-center">
<button class="px-6 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700">
Write a Review
</button>
</div>
</div>
Wishlist
User wishlist with saved products and quick actions
My Wishlist
Your wishlist is empty
Code
<div x-data="{
wishlistItems: [
{ id: 1, name: 'Modern Desk Lamp', price: 79.99, image: 'https://picsum.photos/100/100?random=30', inStock: true },
{ id: 2, name: 'Ergonomic Chair', price: 299.99, image: 'https://picsum.photos/100/100?random=31', inStock: false }
],
removeFromWishlist(id) {
this.wishlistItems = this.wishlistItems.filter(item => item.id !== id);
}
}" class="bg-white dark:bg-gray-800 rounded-lg shadow p-6">
<h2 class="text-2xl font-bold text-gray-900 dark:text-white mb-6">My Wishlist</h2>
<div class="space-y-4">
<template x-for="item in wishlistItems" :key="item.id">
<div class="flex gap-4 p-4 border dark:border-gray-700 rounded-lg">
<img :src="item.image" :alt="item.name" class="w-24 h-24 object-cover rounded">
<div class="flex-1">
<h3 class="font-semibold text-gray-900 dark:text-white mb-1" x-text="item.name"></h3>
<p class="text-lg font-bold text-gray-900 dark:text-white mb-2"
x-text="'$' + item.price.toFixed(2)"></p>
<p class="text-sm mb-3"
:class="item.inStock ? 'text-green-600' : 'text-red-600'"
x-text="item.inStock ? 'In Stock' : 'Out of Stock'"></p>
<div class="flex gap-2">
<button class="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"
:disabled="!item.inStock">
Add to Cart
</button>
<button @click="removeFromWishlist(item.id)"
class="px-4 py-2 border border-gray-300 dark:border-gray-600 rounded hover:bg-gray-50 dark:hover:bg-gray-700">
Remove
</button>
</div>
</div>
</div>
</template>
<div x-show="wishlistItems.length === 0" class="text-center py-12">
<svg class="w-16 h-16 text-gray-400 mx-auto mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"/>
</svg>
<p class="text-gray-600 dark:text-gray-400">Your wishlist is empty</p>
</div>
</div>
</div>