made components that create and edit item can share, started item detail changes, listings provide more views

This commit is contained in:
jackiettran
2025-08-20 17:06:47 -04:00
parent ddd27a59f9
commit b624841350
13 changed files with 1008 additions and 982 deletions

View File

@@ -1,6 +1,6 @@
import React, { useState, useEffect } from 'react';
import { Rental } from '../types';
import { rentalAPI } from '../services/api';
import React, { useState, useEffect } from "react";
import { Rental } from "../types";
import { rentalAPI } from "../services/api";
interface ItemReviewsProps {
itemId: string;
@@ -20,24 +20,25 @@ const ItemReviews: React.FC<ItemReviewsProps> = ({ itemId }) => {
// Fetch all rentals for this item
const response = await rentalAPI.getMyListings();
const allRentals: Rental[] = response.data;
// Filter for completed rentals with reviews for this specific item
const itemReviews = allRentals.filter(
rental => rental.itemId === itemId &&
rental.status === 'completed' &&
rental.rating &&
rental.review
(rental) =>
rental.itemId === itemId &&
rental.status === "completed" &&
rental.rating &&
rental.review
);
setReviews(itemReviews);
// Calculate average rating
if (itemReviews.length > 0) {
const sum = itemReviews.reduce((acc, r) => acc + (r.rating || 0), 0);
setAverageRating(sum / itemReviews.length);
}
} catch (error) {
console.error('Failed to fetch reviews:', error);
console.error("Failed to fetch reviews:", error);
} finally {
setLoading(false);
}
@@ -49,7 +50,7 @@ const ItemReviews: React.FC<ItemReviewsProps> = ({ itemId }) => {
{[1, 2, 3, 4, 5].map((star) => (
<i
key={star}
className={`bi ${star <= rating ? 'bi-star-fill' : 'bi-star'}`}
className={`bi ${star <= rating ? "bi-star-fill" : "bi-star"}`}
></i>
))}
</span>
@@ -72,16 +73,18 @@ const ItemReviews: React.FC<ItemReviewsProps> = ({ itemId }) => {
return (
<div className="mb-4">
<h5>Reviews</h5>
{reviews.length === 0 ? (
<p className="text-muted">No reviews yet. Be the first to rent and review this item!</p>
<p className="text-muted">Be the first to rent and review this item!</p>
) : (
<>
<div className="mb-3">
<div className="d-flex align-items-center gap-2">
{renderStars(Math.round(averageRating))}
<span className="fw-bold">{averageRating.toFixed(1)}</span>
<span className="text-muted">({reviews.length} {reviews.length === 1 ? 'review' : 'reviews'})</span>
<span className="text-muted">
({reviews.length} {reviews.length === 1 ? "review" : "reviews"})
</span>
</div>
</div>
@@ -96,18 +99,27 @@ const ItemReviews: React.FC<ItemReviewsProps> = ({ itemId }) => {
src={rental.renter.profileImage}
alt={`${rental.renter.firstName} ${rental.renter.lastName}`}
className="rounded-circle"
style={{ width: '32px', height: '32px', objectFit: 'cover' }}
style={{
width: "32px",
height: "32px",
objectFit: "cover",
}}
/>
) : (
<div
<div
className="rounded-circle bg-secondary d-flex align-items-center justify-content-center"
style={{ width: '32px', height: '32px' }}
style={{ width: "32px", height: "32px" }}
>
<i className="bi bi-person-fill text-white" style={{ fontSize: '0.8rem' }}></i>
<i
className="bi bi-person-fill text-white"
style={{ fontSize: "0.8rem" }}
></i>
</div>
)}
<div>
<strong>{rental.renter?.firstName} {rental.renter?.lastName}</strong>
<strong>
{rental.renter?.firstName} {rental.renter?.lastName}
</strong>
<div className="small">
{renderStars(rental.rating || 0)}
</div>
@@ -128,4 +140,4 @@ const ItemReviews: React.FC<ItemReviewsProps> = ({ itemId }) => {
);
};
export default ItemReviews;
export default ItemReviews;