Skip to content

Commit

Permalink
Merge pull request #33 from atlp-rwanda/fix-productImages
Browse files Browse the repository at this point in the history
code refactory
  • Loading branch information
MnorbertVii authored Jul 17, 2024
2 parents 9fd1282 + 5d03846 commit 9ea5435
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 36 deletions.
54 changes: 40 additions & 14 deletions src/Components/SingleProduct/Sproduct.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
import React, { useState, useEffect } from "react";

import mainproduct1 from "../../asset/images/Products/0ce8299f7b1c845d575f949b244ea238.jpg";
import mainproduct2 from "../../asset/images/Products/529d198d51183b1643323dd26b8db71d (1).jpg";
import mainproduct4 from "../../asset/images/Products/529d198d51183b1643323dd26b8db71d.jpg";
import mainproduct3 from "../../asset/images/Products/f8c69bc0404ff0b6158cab028ac8e632.jpg";
import heart from "../../asset/images/heart 1.svg";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faMinus, faPlus } from "@fortawesome/free-solid-svg-icons";
Expand Down Expand Up @@ -39,7 +34,7 @@ const Sproduct: React.FC<{ productId: string }> = ({ productId }) => {
const userData: any = useAuthUser();
const [isLoading, setLoading] = useState<boolean>(false);
const userId = userData ? userData.userId : "";

const [showFullDescription, setShowFullDescription] = useState<boolean>(false);
const getUserIdFromToken = (): string | null => {
const token = localStorage.getItem('token');
if (!token) return null;
Expand Down Expand Up @@ -217,11 +212,18 @@ const Sproduct: React.FC<{ productId: string }> = ({ productId }) => {
const images = typeof product.image === 'string' ? JSON.parse(product.image) : product.image;

return (
<div className='flex justify-center md:flex-row lg:flex-col items-center flex-col pt-40'>
<div className='flex justify-center md:flex-row lg:flex-col items-center flex-col pt-32'>
<div className='flex justify-center gap-5 md:flex-row md:w-4/5 flex-col'>
<div className="grid grid-cols-1 justify-center p-5 gap-y-5 items-center md:w-[70%]">
<div className='flex justify-center items-center relative'>
<img src={selectedImage} alt="Selected product" className='min-w-[300px] max-w-[100%] sm:h-[300px] w-full md:w-[95%] md:h-[400px] h-[200px] object-cover' />
<div className="w-full">
<img
src={selectedImage}
alt="Selected product"
className='min-w-[300px] max-w-[100%] sm:h-[300px] w-full md:w-[95%] md:h-[350px] h-[160px] object-cover'
/>
</div>

<div className="absolute bottom-4 translate-x-6 left-6">
<div className='flex justify-center mt-4'>
{images && images.map((image: string, index: number) => (
Expand Down Expand Up @@ -250,12 +252,12 @@ const Sproduct: React.FC<{ productId: string }> = ({ productId }) => {
src={image}
alt={`Thumbnail ${index + 1}`}
onClick={() => handleImageClick(image)}
className="cursor-pointer w-full md:w-[100%] rounded-md h-[10vh] md:h-[15vh] object-cover"
className="cursor-pointer w-full md:w-[70%] rounded-md h-[10vh] md:h-[15vh] object-fill"
/>
))}
</div>
</div> <div className='md:w-1/3 w-full'>
<div className='flex flex-col gap-6 p-5 mt-10'>
<div className='flex flex-col gap-4 p-5 mt-10'>
<h1><span className='text-[#E4A951]'>Stock</span> : <span className='font-extrabold text-blue-700'>{product.Vendor?.storeName}</span></h1>
<h1 className='font-extrabold text-xl'>{product.name}</h1>
<div className='bg-[#D9D9D9] p-2 rounded-md text-sm w-28 text-center font-bold'>{product.quantity} IN STOCK</div>
Expand All @@ -278,9 +280,26 @@ const Sproduct: React.FC<{ productId: string }> = ({ productId }) => {
</div>
</div>
<div>
<h2 className='text-[#E4A951]'>Description</h2>
<p>{product.description}</p>
</div>
<h2 className="text-[#E4A951]">Description</h2>
{product.description ? (
showFullDescription ? (
<p>{product.description}</p>
) : (
<div className="flex flex-col">
<p>{product.description.slice(0, 50)}...</p>
<button
onClick={() => setShowFullDescription(!showFullDescription)}
className="text-[#E4A951]"
>
{showFullDescription ? 'Show Less' : 'Show More'}
</button>
</div>
)
) : (
<p>No description available.</p>
)}
</div>

<div className='flex-container flex gap-4 w-full justify-center'>
<div className="flex gap-4 border-2 justify-around items-center rounded-lg p-2 md:w-[180px] bg-[#F7F7F7] font-bold">
<h3 className="">Quantity</h3>
Expand All @@ -303,7 +322,14 @@ const Sproduct: React.FC<{ productId: string }> = ({ productId }) => {
</button>
</div>
</div>
<button onClick={handleAddToCart} disabled={isButtonDisabled} className={`bg-[#E4A951] p-3 rounded-lg w-full ${isLoadingCart ? ' cursor-not-allowed' : 'cursor-pointer'}`}>{isLoadingCart ? 'Adding ...' : 'Add to Cart'}</button>
<button
onClick={handleAddToCart}
disabled={isButtonDisabled || isLoadingCart}
className={`bg-orange-400 p-3 rounded-lg w-full ${isButtonDisabled || isLoadingCart ? 'cursor-not-allowed opacity-50' : 'cursor-pointer'}`}
>
{isLoadingCart ? 'Adding ...' : 'Add to Cart'}
</button>

</div>
</div>
</div>
Expand Down
20 changes: 11 additions & 9 deletions src/Components/SingleProduct/reviews.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ const Review: React.FC<{ productId: string }> = ({ productId }) => {

const dispatch = useDispatch();
const { loading: isLoading, error } = useSelector((state: any) => state.reviews);

const API_URL:any = `${process.env.BACKEND_API_URL}`;
useEffect(() => {
fetch(`http://localhost:5000/getfeedback/${productId}`)
fetch(`${API_URL}/getfeedback/${productId}`)
.then(response => response.json())
.then(data => setReviews(data.ratings || [])) // Ensure default to empty array
.then(data => setReviews(data.ratings || []))
.catch(error => console.error('Error fetching reviews:', error));
}, [productId]);

Expand Down Expand Up @@ -85,7 +85,7 @@ const Review: React.FC<{ productId: string }> = ({ productId }) => {
ratingScore: 0,
});

fetch(`http://localhost:5000/getfeedback/${productId}`)
fetch(`${API_URL}/getfeedback/${productId}`)
.then(response => response.json())
.then(data => setReviews(data.ratings || [])) // Ensure default to empty array
.catch(error => console.error('Error fetching reviews:', error));
Expand Down Expand Up @@ -116,9 +116,10 @@ const Review: React.FC<{ productId: string }> = ({ productId }) => {
</div>
</div>
{showContent && (
<div className="md:ml-0 py-4">
<div className="bg-[#F9FAFB] mt-7 p-2.5 grid md:grid-cols-2 grid-cols-1 justify-between w- md:w-full">
<p className="md:w-3/4 w-full">How will you rate this product?</p>
<div className="flex justify-center">
<div className="md:ml-0 py-4 w-4/5 flex flex-col justify-center ">
<div className="bg-[#F9FAFB] mt-7 p-2.5 grid md:grid-cols-2 grid-cols-1 justify-between md:w-full">
<p className="md:w-w-full w-full">How will you rate this product?</p>
<div className="mr-0 md:mr-4">
<StarRating
rating={ratingScore}
Expand All @@ -129,7 +130,7 @@ const Review: React.FC<{ productId: string }> = ({ productId }) => {
</div>
<form
onSubmit={handleFormSubmit}
className="py-4 flex flex-col items-center gap-4 justify-center md:w-3/5 w-full"
className="py-4 flex flex-col items-center gap-4 justify-center md:w-full w-full"
>
<input
type="text"
Expand All @@ -149,14 +150,15 @@ const Review: React.FC<{ productId: string }> = ({ productId }) => {
></textarea>
<button
type="submit"
className="bg-blue-900 text-white font-extrabold p-3 md:w-1/2 w-full rounded-lg"
className=" bg-orange-400 text-white font-extrabold p-3 md:w-1/2 w-full rounded-lg"
disabled={isLoading}
>
{isLoading ? 'Submitting...' : 'Submit Feedback'}
</button>
{error && <p className="text-red-500 mt-2">{error}</p>}
</form>
</div>
</div>
)}
{isLoading ? (
Array(visibleReviews).fill(0).map((_, index) => (
Expand Down
4 changes: 2 additions & 2 deletions src/Redux/Action/reviews.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { createAsyncThunk } from '@reduxjs/toolkit';
import axios from 'axios';

const API_URL:any = `${process.env.BACKEND_API_URL}`;
export const fetchReviews = createAsyncThunk(
'reviews/fetchReviews',
async (productId, { rejectWithValue }) => {
try {
const apiUrl = `http://localhost:5000/getfeedback/${productId}`;
const apiUrl = `${API_URL}/getfeedback/${productId}`;
const response = await axios.get(apiUrl);
return response.data;
} catch (error:any) {
Expand Down
14 changes: 7 additions & 7 deletions src/Redux/Action/singleProduct.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ export interface ProductState {
status: 'idle' | 'loading' | 'succeeded' | 'failed';
error: string | null;
}

const API_URL:any = `${process.env.BACKEND_API_URL}`;
export const submitReview = createAsyncThunk(
'reviews/submitReview',
async ({ productId, data }: { productId: string; data: ReviewData }, { rejectWithValue }) => {
try {
const apiUrl = `http://localhost:5000/addfeedback/${productId}`;
const apiUrl = `${API_URL}/addfeedback/${productId}`;
const token = localStorage.getItem('token');
const config = {
headers: {
Expand Down Expand Up @@ -77,7 +77,7 @@ export const addToCart = createAsyncThunk(
'cart/addToCart',
async (cartItem: { userId: string; productId: string; quantity: number; price: number }) => {
try {
const apiUrl = "http://localhost:5000/addcart";
const apiUrl = `${API_URL}/addcart`;
const response = await axios.post(apiUrl, cartItem);

const existingToastId = toast.isActive("error to add cart");
Expand Down Expand Up @@ -120,7 +120,7 @@ export const fetchCart = createAsyncThunk(
"cart/viewCart",
async(userId: string) => {
try {
const apiUrl =`http://localhost:5000/products/${userId}`;
const apiUrl =`${API_URL}/products/${userId}`;
const response = await axios.get(apiUrl);
return response.data
}catch(error: any) {
Expand All @@ -132,7 +132,7 @@ export const fetchProductDetails = createAsyncThunk(
'product/fetchProductDetails',
async (productId:string, { rejectWithValue }) => {
try {
const apiUrl = `http://localhost:5000/readProduct/${productId}`;
const apiUrl = `${API_URL}/readProduct/${productId}`;

const response = await axios.get(apiUrl);
console.log("response")
Expand All @@ -147,7 +147,7 @@ export const fetchReviews = createAsyncThunk(
'product/fetchProductDetail',
async (productId, { rejectWithValue }) => {
try {
const apiUrl = `http://localhost:5000/getfeedback/${productId}`;
const apiUrl = `${API_URL}/getfeedback/${productId}`;
const response = await axios.get(apiUrl);
return response.data;
} catch (error:any) {
Expand All @@ -160,7 +160,7 @@ export const fetchSimilarProducts = createAsyncThunk(
'products/fetchSimilarProducts',
async (productId: string, { rejectWithValue }) => {
try {
const apiUrl = `http://localhost:5000/similarproducts/${productId}`;
const apiUrl = `${API_URL}/similarproducts/${productId}`;
const response = await axios.get<Product[]>(apiUrl);
return response.data;
} catch (error:any) {
Expand Down
8 changes: 4 additions & 4 deletions src/Redux/Action/wishlist.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import axios from 'axios';
import { createAsyncThunk } from '@reduxjs/toolkit';

const API_URL = 'http://localhost:5000/toWishlist';
const API_URL:any = `${process.env.BACKEND_API_URL}`;
const API_URLs = `${API_URL}/toWishlist`;

export const addToWishlist = createAsyncThunk(
'wishlist/addToWishlist',
async (wishlistItem: { userId: string; productId: string; price: number }, { rejectWithValue }) => {
try {
const response = await axios.post(API_URL, wishlistItem);
const response = await axios.post(API_URLs, wishlistItem);
return response.data;
} catch (error: any) {
return rejectWithValue(error.response.data);
Expand All @@ -21,7 +21,7 @@ export const fetchWishlist = createAsyncThunk(
'wishlist/fetchWishlist',
async (userId: string, { rejectWithValue }) => {
try {
const response = await axios.get(`${API_URL}/${userId}`);
const response = await axios.get(`${API_URLs}/${userId}`);
return response.data;
} catch (error: any) {
return rejectWithValue(error.response.data);
Expand Down
1 change: 1 addition & 0 deletions src/Redux/Reducer/wishlistslice.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const wishlistSlice = createSlice({
})
.addCase(fetchWishlist.rejected, (state, action) => {
state.status = 'failed';
//@ts-ignore
state.error = action.error.message;
});
},
Expand Down

0 comments on commit 9ea5435

Please sign in to comment.