messages and reviews

This commit is contained in:
jackiettran
2025-07-17 00:16:01 -04:00
parent aa3adc58ca
commit 1dbe821e70
21 changed files with 1981 additions and 102 deletions

View File

@@ -3,6 +3,8 @@ import { Link } from 'react-router-dom';
import { useAuth } from '../contexts/AuthContext';
import { rentalAPI } from '../services/api';
import { Rental } from '../types';
import ReviewModal from '../components/ReviewModal';
import ConfirmationModal from '../components/ConfirmationModal';
const MyRentals: React.FC = () => {
const { user } = useAuth();
@@ -10,6 +12,11 @@ const MyRentals: React.FC = () => {
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [activeTab, setActiveTab] = useState<'active' | 'past'>('active');
const [showReviewModal, setShowReviewModal] = useState(false);
const [selectedRental, setSelectedRental] = useState<Rental | null>(null);
const [showCancelModal, setShowCancelModal] = useState(false);
const [rentalToCancel, setRentalToCancel] = useState<string | null>(null);
const [cancelling, setCancelling] = useState(false);
useEffect(() => {
fetchRentals();
@@ -26,17 +33,37 @@ const MyRentals: React.FC = () => {
}
};
const cancelRental = async (rentalId: string) => {
if (!window.confirm('Are you sure you want to cancel this rental?')) return;
const handleCancelClick = (rentalId: string) => {
setRentalToCancel(rentalId);
setShowCancelModal(true);
};
const confirmCancelRental = async () => {
if (!rentalToCancel) return;
setCancelling(true);
try {
await rentalAPI.updateRentalStatus(rentalId, 'cancelled');
await rentalAPI.updateRentalStatus(rentalToCancel, 'cancelled');
fetchRentals(); // Refresh the list
setShowCancelModal(false);
setRentalToCancel(null);
} catch (err: any) {
alert('Failed to cancel rental');
} finally {
setCancelling(false);
}
};
const handleReviewClick = (rental: Rental) => {
setSelectedRental(rental);
setShowReviewModal(true);
};
const handleReviewSuccess = () => {
fetchRentals(); // Refresh to show the review has been added
alert('Thank you for your review!');
};
// Filter rentals based on status
const activeRentals = rentals.filter(r =>
['pending', 'confirmed', 'active'].includes(r.status)
@@ -175,16 +202,25 @@ const MyRentals: React.FC = () => {
{rental.status === 'pending' && (
<button
className="btn btn-sm btn-danger"
onClick={() => cancelRental(rental.id)}
onClick={() => handleCancelClick(rental.id)}
>
Cancel
</button>
)}
{rental.status === 'completed' && !rental.rating && (
<button className="btn btn-sm btn-primary">
<button
className="btn btn-sm btn-primary"
onClick={() => handleReviewClick(rental)}
>
Leave Review
</button>
)}
{rental.status === 'completed' && rental.rating && (
<div className="text-success small">
<i className="bi bi-check-circle-fill me-1"></i>
Reviewed ({rental.rating}/5)
</div>
)}
</div>
</div>
</div>
@@ -193,6 +229,33 @@ const MyRentals: React.FC = () => {
))}
</div>
)}
{selectedRental && (
<ReviewModal
show={showReviewModal}
onClose={() => {
setShowReviewModal(false);
setSelectedRental(null);
}}
rental={selectedRental}
onSuccess={handleReviewSuccess}
/>
)}
<ConfirmationModal
show={showCancelModal}
onClose={() => {
setShowCancelModal(false);
setRentalToCancel(null);
}}
onConfirm={confirmCancelRental}
title="Cancel Rental"
message="Are you sure you want to cancel this rental? This action cannot be undone."
confirmText="Yes, Cancel Rental"
cancelText="Keep Rental"
confirmButtonClass="btn-danger"
loading={cancelling}
/>
</div>
);
};