Skip to content

Commit

Permalink
fix add review
Browse files Browse the repository at this point in the history
  • Loading branch information
moatazeldebsy committed Dec 3, 2024
1 parent 94d52f1 commit 2e393c2
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 39 deletions.
13 changes: 11 additions & 2 deletions src/components/product/AddReview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,17 @@ export const AddReview: React.FC<AddReviewProps> = ({ productId, onReviewSubmit
const [rating, setRating] = useState(5);
const [comment, setComment] = useState('');
const [isSubmitting, setIsSubmitting] = useState(false);
const [error, setError] = useState<string | null>(null);
const { auth, addReview } = useStore();

const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!auth.user) return;

setIsSubmitting(true);
setError(null);

try {
if (!auth.user) throw new Error('User not authenticated');

await addReview({
productId,
userId: auth.user.id,
Expand All @@ -34,6 +36,7 @@ export const AddReview: React.FC<AddReviewProps> = ({ productId, onReviewSubmit
setRating(5);
onReviewSubmit();
} catch (error) {
setError('Failed to submit review. Please try again.');
console.error('Failed to submit review:', error);
} finally {
setIsSubmitting(false);
Expand Down Expand Up @@ -79,6 +82,12 @@ export const AddReview: React.FC<AddReviewProps> = ({ productId, onReviewSubmit
/>
</div>

{error && (
<p className="text-red-600 text-sm" data-testid="review-error">
{error}
</p>
)}

<Button
type="submit"
isLoading={isSubmitting}
Expand Down
35 changes: 30 additions & 5 deletions src/components/product/ProductReviews.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,36 @@
import React, { useState } from 'react';
import React, { useState, useEffect } from 'react';
import { Star } from 'lucide-react';
import { useStore } from '../../store/useStore';
import { AddReview } from './AddReview';
import { Review } from '../../types';

interface ProductReviewsProps {
productId: string;
}

export const ProductReviews: React.FC<ProductReviewsProps> = ({ productId }) => {
const { auth, getProductReviews } = useStore();
const reviews = getProductReviews(productId);
const [refreshKey, setRefreshKey] = useState(0);
const [reviews, setReviews] = useState<Review[]>([]);
const [isLoading, setIsLoading] = useState(true);

const handleReviewSubmit = () => {
setRefreshKey(prev => prev + 1);
useEffect(() => {
const loadReviews = async () => {
try {
const productReviews = await getProductReviews(productId);
setReviews(productReviews);
} catch (error) {
console.error('Failed to load reviews:', error);
} finally {
setIsLoading(false);
}
};

loadReviews();
}, [productId, getProductReviews]);

const handleReviewSubmit = async () => {
const updatedReviews = await getProductReviews(productId);
setReviews(updatedReviews);
};

const StarRating = ({ value }: { value: number }) => (
Expand All @@ -28,6 +45,14 @@ export const ProductReviews: React.FC<ProductReviewsProps> = ({ productId }) =>
</div>
);

if (isLoading) {
return (
<div className="flex justify-center py-8">
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div>
</div>
);
}

return (
<div className="space-y-6" data-testid="product-reviews">
<h2 className="text-2xl font-bold">Customer Reviews</h2>
Expand Down
40 changes: 31 additions & 9 deletions src/database/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { User, Order, Review } from '../types';
interface ShopDB extends DBSchema {
users: {
key: string;
value: User;
value: User & { password: string };
indexes: { 'by-email': string };
};
orders: {
Expand Down Expand Up @@ -36,7 +36,7 @@ const dbPromise = openDB<ShopDB>('shop-db', 1, {
});

export const UserDB = {
create: async (user: Omit<User, 'id'>) => {
create: async (user: Omit<User & { password: string }, 'id'>) => {
const db = await dbPromise;
const id = crypto.randomUUID();
const newUser = { ...user, id };
Expand All @@ -54,6 +54,15 @@ export const UserDB = {
return await db.get('users', id);
},

update: async (id: string, data: Partial<User>) => {
const db = await dbPromise;
const user = await db.get('users', id);
if (!user) throw new Error('User not found');
const updatedUser = { ...user, ...data };
await db.put('users', updatedUser);
return updatedUser;
},

delete: async (id: string) => {
const db = await dbPromise;
await db.delete('users', id);
Expand Down Expand Up @@ -85,21 +94,26 @@ export const OrderDB = {
return await db.getAllFromIndex('orders', 'by-user', userId);
},

update: async (id: string, data: Partial<Order>) => {
const db = await dbPromise;
const order = await db.get('orders', id);
if (!order) throw new Error('Order not found');
const updatedOrder = { ...order, ...data, updatedAt: new Date().toISOString() };
await db.put('orders', updatedOrder);
return updatedOrder;
},

delete: async (id: string) => {
const db = await dbPromise;
await db.delete('orders', id);
}
};

export const ReviewDB = {
create: async (review: Omit<Review, 'id' | 'createdAt'>) => {
create: async (review: Omit<Review, 'id'>) => {
const db = await dbPromise;
const id = crypto.randomUUID();
const newReview = {
...review,
id,
createdAt: new Date().toISOString()
};
const newReview = { ...review, id };
await db.add('reviews', newReview);
return newReview;
},
Expand All @@ -114,13 +128,21 @@ export const ReviewDB = {
return await db.getAllFromIndex('reviews', 'by-product', productId);
},

update: async (id: string, data: Partial<Review>) => {
const db = await dbPromise;
const review = await db.get('reviews', id);
if (!review) throw new Error('Review not found');
const updatedReview = { ...review, ...data };
await db.put('reviews', updatedReview);
return updatedReview;
},

delete: async (id: string) => {
const db = await dbPromise;
await db.delete('reviews', id);
}
};

// Function to clean the database (for development/testing)
export const cleanDatabase = async () => {
const db = await dbPromise;
await db.clear('reviews');
Expand Down
55 changes: 32 additions & 23 deletions src/store/useStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,20 +80,6 @@ export const useStore = create<Store>((set, get) => ({
maxPrice: Number.MAX_SAFE_INTEGER,
sortBy: '',
},
updateProductStock: (productId: string, quantity: number) => {
set((state) => ({
products: state.products.map((product) =>
product.id === productId
? { ...product, stock: Math.max(0, product.stock - quantity) }
: product
),
filteredProducts: state.filteredProducts.map((product) =>
product.id === productId
? { ...product, stock: Math.max(0, product.stock - quantity) }
: product
),
}));
},
setFilters: (newFilters) => {
const currentFilters = get().filters;
const updatedFilters = { ...currentFilters, ...newFilters };
Expand Down Expand Up @@ -133,13 +119,25 @@ export const useStore = create<Store>((set, get) => ({
};
});
},
updateProductStock: (productId: string, quantity: number) => {
set((state) => ({
products: state.products.map((product) =>
product.id === productId
? { ...product, stock: Math.max(0, product.stock - quantity) }
: product
),
filteredProducts: state.filteredProducts.map((product) =>
product.id === productId
? { ...product, stock: Math.max(0, product.stock - quantity) }
: product
),
}));
},

// Cart
cart: [],
addToCart: (product) => {
if (product.stock === 0) {
return;
}
if (product.stock === 0) return;

set((state) => {
const existingItem = state.cart.find((item) => item.id === product.id);
Expand Down Expand Up @@ -324,14 +322,25 @@ export const useStore = create<Store>((set, get) => ({
// Reviews
reviews: [],
addReview: async (review) => {
const newReview = await ReviewDB.create(review);
if (newReview) {
set((state) => ({
reviews: [...state.reviews, newReview],
}));
try {
const newReview = await ReviewDB.create(review);
if (newReview) {
set((state) => ({
reviews: [...state.reviews, newReview],
}));
}
} catch (error) {
console.error('Failed to add review:', error);
throw error;
}
},
getProductReviews: async (productId) => {
return await ReviewDB.findByProduct(productId);
try {
const reviews = await ReviewDB.findByProduct(productId);
return reviews;
} catch (error) {
console.error('Failed to get product reviews:', error);
return [];
}
},
}));

0 comments on commit 2e393c2

Please sign in to comment.