condition check gallery
This commit is contained in:
@@ -2,13 +2,14 @@ import React, { useState, useEffect } from "react";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import { useAuth } from "../contexts/AuthContext";
|
||||
import api from "../services/api";
|
||||
import { Item, Rental } from "../types";
|
||||
import { Item, Rental, ConditionCheck } from "../types";
|
||||
import { rentalAPI, conditionCheckAPI } from "../services/api";
|
||||
import { getPublicImageUrl } from "../services/uploadService";
|
||||
import ReviewRenterModal from "../components/ReviewRenterModal";
|
||||
import RentalCancellationModal from "../components/RentalCancellationModal";
|
||||
import DeclineRentalModal from "../components/DeclineRentalModal";
|
||||
import ConditionCheckModal from "../components/ConditionCheckModal";
|
||||
import ConditionCheckViewerModal from "../components/ConditionCheckViewerModal";
|
||||
import ReturnStatusModal from "../components/ReturnStatusModal";
|
||||
|
||||
const Owning: React.FC = () => {
|
||||
@@ -63,6 +64,11 @@ const Owning: React.FC = () => {
|
||||
checkType: string;
|
||||
} | null>(null);
|
||||
const [availableChecks, setAvailableChecks] = useState<any[]>([]);
|
||||
const [conditionChecks, setConditionChecks] = useState<ConditionCheck[]>([]);
|
||||
const [showConditionCheckViewer, setShowConditionCheckViewer] =
|
||||
useState(false);
|
||||
const [selectedConditionCheck, setSelectedConditionCheck] =
|
||||
useState<ConditionCheck | null>(null);
|
||||
const [showReturnStatusModal, setShowReturnStatusModal] = useState(false);
|
||||
const [rentalForReturn, setRentalForReturn] = useState<Rental | null>(null);
|
||||
|
||||
@@ -72,6 +78,12 @@ const Owning: React.FC = () => {
|
||||
fetchAvailableChecks();
|
||||
}, [user]);
|
||||
|
||||
useEffect(() => {
|
||||
if (ownerRentals.length > 0) {
|
||||
fetchConditionChecks();
|
||||
}
|
||||
}, [ownerRentals]);
|
||||
|
||||
const fetchListings = async () => {
|
||||
if (!user) return;
|
||||
|
||||
@@ -145,6 +157,28 @@ const Owning: React.FC = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const fetchConditionChecks = async () => {
|
||||
try {
|
||||
const allChecks: ConditionCheck[] = [];
|
||||
for (const rental of ownerRentals) {
|
||||
try {
|
||||
const response = await conditionCheckAPI.getConditionChecks(
|
||||
rental.id
|
||||
);
|
||||
if (response.data.conditionChecks) {
|
||||
allChecks.push(...response.data.conditionChecks);
|
||||
}
|
||||
} catch (err) {
|
||||
// Skip rentals with no condition checks
|
||||
}
|
||||
}
|
||||
setConditionChecks(allChecks);
|
||||
} catch (err) {
|
||||
console.error("Failed to fetch condition checks:", err);
|
||||
setConditionChecks([]);
|
||||
}
|
||||
};
|
||||
|
||||
// Owner functionality handlers
|
||||
const handleAcceptRental = async (rentalId: string) => {
|
||||
try {
|
||||
@@ -252,7 +286,12 @@ const Owning: React.FC = () => {
|
||||
|
||||
const handleConditionCheckSuccess = () => {
|
||||
fetchAvailableChecks();
|
||||
alert("Condition check submitted successfully!");
|
||||
fetchConditionChecks();
|
||||
};
|
||||
|
||||
const handleViewConditionCheck = (check: ConditionCheck) => {
|
||||
setSelectedConditionCheck(check);
|
||||
setShowConditionCheckViewer(true);
|
||||
};
|
||||
|
||||
const getAvailableChecksForRental = (rentalId: string) => {
|
||||
@@ -263,6 +302,11 @@ const Owning: React.FC = () => {
|
||||
);
|
||||
};
|
||||
|
||||
const getCompletedChecksForRental = (rentalId: string) => {
|
||||
if (!Array.isArray(conditionChecks)) return [];
|
||||
return conditionChecks.filter((check) => check.rentalId === rentalId);
|
||||
};
|
||||
|
||||
// Filter owner rentals - exclude cancelled (shown in Rental History)
|
||||
const allOwnerRentals = ownerRentals
|
||||
.filter((r) => ["pending", "confirmed", "active"].includes(r.status))
|
||||
@@ -307,14 +351,19 @@ const Owning: React.FC = () => {
|
||||
{allOwnerRentals.map((rental) => (
|
||||
<div key={rental.id} className="col-md-6 col-lg-4 mb-4">
|
||||
<div className="card h-100">
|
||||
{rental.item?.imageFilenames && rental.item.imageFilenames[0] && (
|
||||
<img
|
||||
src={getPublicImageUrl(rental.item.imageFilenames[0])}
|
||||
className="card-img-top"
|
||||
alt={rental.item.name}
|
||||
style={{ height: "200px", objectFit: "contain", backgroundColor: "#f8f9fa" }}
|
||||
/>
|
||||
)}
|
||||
{rental.item?.imageFilenames &&
|
||||
rental.item.imageFilenames[0] && (
|
||||
<img
|
||||
src={getPublicImageUrl(rental.item.imageFilenames[0])}
|
||||
className="card-img-top"
|
||||
alt={rental.item.name}
|
||||
style={{
|
||||
height: "200px",
|
||||
objectFit: "contain",
|
||||
backgroundColor: "#f8f9fa",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<div className="card-body">
|
||||
<h5 className="card-title text-dark">
|
||||
{rental.item ? rental.item.name : "Item Unavailable"}
|
||||
@@ -472,6 +521,34 @@ const Owning: React.FC = () => {
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Condition Check Status */}
|
||||
{getCompletedChecksForRental(rental.id).length > 0 && (
|
||||
<div className="mb-2">
|
||||
{getCompletedChecksForRental(rental.id).map(
|
||||
(check) => (
|
||||
<button
|
||||
key={`${rental.id}-${check.checkType}-status`}
|
||||
className="btn btn-link text-success small p-0 text-decoration-none d-block"
|
||||
onClick={() => handleViewConditionCheck(check)}
|
||||
>
|
||||
{check.checkType === "pre_rental_owner"
|
||||
? "Pre-Rental Condition"
|
||||
: check.checkType === "rental_start_renter"
|
||||
? "Rental Start Condition"
|
||||
: check.checkType === "rental_end_renter"
|
||||
? "Rental End Condition"
|
||||
: "Post-Rental Condition"}
|
||||
<small className="text-muted ms-2">
|
||||
{new Date(
|
||||
check.createdAt
|
||||
).toLocaleDateString()}
|
||||
</small>
|
||||
</button>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Condition Check Buttons */}
|
||||
{getAvailableChecksForRental(rental.id).map((check) => (
|
||||
<button
|
||||
@@ -483,8 +560,8 @@ const Owning: React.FC = () => {
|
||||
>
|
||||
<i className="bi bi-camera me-2" />
|
||||
{check.checkType === "pre_rental_owner"
|
||||
? "Submit Pre-Rental Check"
|
||||
: "Submit Post-Rental Check"}
|
||||
? "Submit Pre-Rental Condition"
|
||||
: "Submit Post-Rental Condition"}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
@@ -533,7 +610,11 @@ const Owning: React.FC = () => {
|
||||
src={getPublicImageUrl(item.imageFilenames[0])}
|
||||
className="card-img-top"
|
||||
alt={item.name}
|
||||
style={{ height: "200px", objectFit: "contain", backgroundColor: "#f8f9fa" }}
|
||||
style={{
|
||||
height: "200px",
|
||||
objectFit: "contain",
|
||||
backgroundColor: "#f8f9fa",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<div className="card-body">
|
||||
@@ -712,6 +793,16 @@ const Owning: React.FC = () => {
|
||||
onSubmitSuccess={handleReturnStatusMarked}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Condition Check Viewer Modal */}
|
||||
<ConditionCheckViewerModal
|
||||
show={showConditionCheckViewer}
|
||||
onHide={() => {
|
||||
setShowConditionCheckViewer(false);
|
||||
setSelectedConditionCheck(null);
|
||||
}}
|
||||
conditionCheck={selectedConditionCheck}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user