This commit is contained in:
Your Name committed 2026-06-21 07:04:03 -04:00
1 parent f7ac94ca0d
commit 335f3b4f59
41 files changed
+809 -413

No files matched your search

+26 -26
View File
@@ -79,29 +79,29 @@ export default function ProductReviews({ productId }: { productId: number }) {
const visibleReviews = filteredReviews.slice(0, visibleCount)
return (
<div className="pt-16 border-t border-spa-stone/10 space-y-12">
<div className="pt-16 border-t border-pop-black/10 space-y-12">
<div className="flex flex-col md:flex-row gap-12 items-start">
{/* Summary */}
<div className="w-full md:w-1/3 bg-spa-light p-8 rounded-3xl text-center space-y-4">
<div className="w-full md:w-1/3 bg-pop-bg p-8 rounded-3xl text-center space-y-4">
<h2 className="text-3xl font-bold text-pop-black">{t('product.reviews')}</h2>
<div className="text-6xl font-black text-spa-forest">{avgRating}</div>
<div className="text-6xl font-black text-pop-pink">{avgRating}</div>
<div className="flex justify-center gap-1">
{[1, 2, 3, 4, 5].map(star => (
<Star key={star} className={`w-5 h-5 ${star <= Number(avgRating) ? 'fill-orange-400 text-orange-400' : 'text-spa-stone/30 fill-spa-stone/10'}`} />
<Star key={star} className={`w-5 h-5 ${star <= Number(avgRating) ? 'fill-orange-400 text-orange-400' : 'text-pop-black/30 fill-pop-black/10'}`} />
))}
</div>
<p className="text-spa-stone text-sm">{reviews.length} reviews</p>
<p className="text-pop-black/60 text-sm">{reviews.length} reviews</p>
</div>
{/* List & Form */}
<div className="w-full md:w-2/3 space-y-8">
{customer ? (
<form onSubmit={handleSubmit} className="bg-spa-light p-6 rounded-3xl border border-spa-stone/10 shadow-sm space-y-4">
<form onSubmit={handleSubmit} className="bg-pop-bg p-6 rounded-3xl border border-pop-black/10 shadow-sm space-y-4">
<h3 className="font-bold text-pop-black">Write a Review</h3>
<div className="flex gap-2">
{[1, 2, 3, 4, 5].map(star => (
<button type="button" key={star} onClick={() => setRating(star)} className="focus:outline-none">
<Star className={`w-8 h-8 ${star <= rating ? 'fill-orange-400 text-orange-400' : 'text-spa-stone/30 fill-spa-stone/10 hover:text-orange-300'}`} />
<Star className={`w-8 h-8 ${star <= rating ? 'fill-orange-400 text-orange-400' : 'text-pop-black/30 fill-pop-black/10 hover:text-orange-300'}`} />
</button>
))}
</div>
@@ -109,21 +109,21 @@ export default function ProductReviews({ productId }: { productId: number }) {
value={comment}
onChange={e => setComment(e.target.value)}
placeholder="Share your experience with this scent..."
className="w-full bg-spa-light/50 border border-spa-stone/20 rounded-xl p-4 text-sm focus:outline-none focus:border-spa-forest/50 focus:ring-2 focus:ring-spa-forest/20 transition-all"
className="w-full bg-pop-bg/50 border border-pop-black/20 rounded-xl p-4 text-sm focus:outline-none focus:border-pop-pink/50 focus:ring-2 focus:ring-pop-pink/20 transition-all text-pop-black placeholder:text-pop-black/50"
rows={3}
/>
<button
type="submit"
disabled={submitting}
className="px-6 py-2.5 bg-spa-forest text-spa-light text-sm font-bold tracking-widest uppercase rounded-full hover:bg-spa-stone transition-all disabled:opacity-50"
className="px-6 py-2.5 bg-pop-pink text-pop-bg text-sm font-bold tracking-widest uppercase rounded-full hover:bg-pop-black transition-all disabled:opacity-50"
>
{submitting ? 'Submitting...' : 'Submit Review'}
</button>
</form>
) : (
<div className="bg-spa-light p-6 rounded-3xl text-center border border-dashed border-spa-stone/30">
<p className="text-spa-stone text-sm mb-2">Login to write a review</p>
<button onClick={() => window.location.href='/track'} className="text-spa-forest font-bold text-sm tracking-widest uppercase hover:underline">Go to Login</button>
<div className="bg-pop-bg p-6 rounded-3xl text-center border border-dashed border-pop-black/30">
<p className="text-pop-black/60 text-sm mb-2">Login to write a review</p>
<button onClick={() => window.location.href='/track'} className="text-pop-pink font-bold text-sm tracking-widest uppercase hover:underline">Go to Login</button>
</div>
)}
@@ -135,8 +135,8 @@ export default function ProductReviews({ productId }: { productId: number }) {
onClick={() => { setFilterRating(null); setVisibleCount(3); }}
className={`flex-shrink-0 px-4 py-1.5 rounded-full text-xs font-bold transition-all border ${
filterRating === null
? 'bg-spa-stone text-spa-light border-spa-stone'
: 'bg-spa-light text-spa-stone border-spa-stone/20 hover:border-spa-stone/50'
? 'bg-pop-black text-pop-bg border-pop-black'
: 'bg-pop-bg text-pop-black border-pop-black/20 hover:border-pop-black/50'
}`}
>
All ({reviews.length})
@@ -150,11 +150,11 @@ export default function ProductReviews({ productId }: { productId: number }) {
onClick={() => { setFilterRating(star); setVisibleCount(3); }}
className={`flex-shrink-0 flex items-center gap-1 px-4 py-1.5 rounded-full text-xs font-bold transition-all border ${
filterRating === star
? 'bg-spa-stone text-spa-light border-spa-stone'
: 'bg-spa-light text-spa-stone border-spa-stone/20 hover:border-spa-stone/50'
? 'bg-pop-black text-pop-bg border-pop-black'
: 'bg-pop-bg text-pop-black border-pop-black/20 hover:border-pop-black/50'
}`}
>
{star} <Star className={`w-3 h-3 ${filterRating === star ? 'fill-white text-spa-light' : 'fill-orange-400 text-orange-400'}`} /> ({count})
{star} <Star className={`w-3 h-3 ${filterRating === star ? 'fill-white text-pop-bg' : 'fill-orange-400 text-orange-400'}`} /> ({count})
</button>
);
})}
@@ -162,19 +162,19 @@ export default function ProductReviews({ productId }: { productId: number }) {
)}
{loading ? (
<p className="text-spa-stone animate-pulse text-sm">Loading reviews...</p>
<p className="text-pop-black/60 animate-pulse text-sm">Loading reviews...</p>
) : reviews.length === 0 ? (
<p className="text-spa-stone/60 text-sm italic">No reviews yet. Be the first to share your thoughts!</p>
<p className="text-pop-black/60 text-sm italic">No reviews yet. Be the first to share your thoughts!</p>
) : visibleReviews.length === 0 ? (
<p className="text-spa-stone/60 text-sm italic">No reviews found for this rating.</p>
<p className="text-pop-black/60 text-sm italic">No reviews found for this rating.</p>
) : (
visibleReviews.map(review => (
<div key={review.id} className="border-b border-spa-stone/10 pb-6 last:border-0">
<div key={review.id} className="border-b border-pop-black/10 pb-6 last:border-0">
<div className="flex items-center gap-3 mb-2">
{review.customer?.pictureUrl ? (
<img src={review.customer.pictureUrl} className="w-10 h-10 rounded-full object-cover" />
) : (
<div className="w-10 h-10 rounded-full bg-spa-stone/20 flex items-center justify-center text-spa-light font-bold">
<div className="w-10 h-10 rounded-full bg-pop-black/20 flex items-center justify-center text-pop-bg font-bold">
{(review.customerName || 'A')[0].toUpperCase()}
</div>
)}
@@ -182,13 +182,13 @@ export default function ProductReviews({ productId }: { productId: number }) {
<p className="font-bold text-pop-black text-sm">{review.customerName}</p>
<div className="flex gap-0.5">
{[1, 2, 3, 4, 5].map(star => (
<Star key={star} className={`w-3 h-3 ${star <= review.rating ? 'fill-orange-400 text-orange-400' : 'text-spa-stone/30'}`} />
<Star key={star} className={`w-3 h-3 ${star <= review.rating ? 'fill-orange-400 text-orange-400' : 'text-pop-black/30'}`} />
))}
</div>
</div>
<span className="ml-auto text-xs text-spa-stone/50">{new Date(review.createdAt).toLocaleDateString()}</span>
<span className="ml-auto text-xs text-pop-black/50">{new Date(review.createdAt).toLocaleDateString()}</span>
</div>
{review.comment && <p className="text-spa-stone text-sm ml-13 leading-relaxed">{review.comment}</p>}
{review.comment && <p className="text-pop-black/60 text-sm ml-13 leading-relaxed">{review.comment}</p>}
</div>
))
)}
@@ -197,7 +197,7 @@ export default function ProductReviews({ productId }: { productId: number }) {
<div className="text-center pt-4">
<button
onClick={() => setVisibleCount(prev => prev + 5)}
className="px-6 py-2.5 border border-spa-stone/20 text-spa-stone text-xs font-bold tracking-widest uppercase rounded-full hover:border-spa-stone hover:text-pop-black transition-all bg-spa-light"
className="px-6 py-2.5 border border-pop-black/20 text-pop-black/60 text-xs font-bold tracking-widest uppercase rounded-full hover:border-pop-black hover:text-pop-black transition-all bg-pop-bg"
>
Show More Reviews
</button>