replaced vague notes with specific intended use, also fixed modal on top of modal for reviews
This commit is contained in:
@@ -24,7 +24,6 @@ const ReturnStatusModal: React.FC<ReturnStatusModalProps> = ({
|
||||
lost: false,
|
||||
});
|
||||
const [actualReturnDateTime, setActualReturnDateTime] = useState("");
|
||||
const [notes, setNotes] = useState("");
|
||||
const [conditionNotes, setConditionNotes] = useState("");
|
||||
const [photos, setPhotos] = useState<File[]>([]);
|
||||
const [processing, setProcessing] = useState(false);
|
||||
@@ -56,7 +55,6 @@ const ReturnStatusModal: React.FC<ReturnStatusModalProps> = ({
|
||||
lost: false,
|
||||
});
|
||||
setActualReturnDateTime("");
|
||||
setNotes("");
|
||||
setConditionNotes("");
|
||||
setPhotos([]);
|
||||
setError(null);
|
||||
@@ -71,13 +69,13 @@ const ReturnStatusModal: React.FC<ReturnStatusModalProps> = ({
|
||||
|
||||
// Create blob URLs for photo previews and clean them up
|
||||
const photoBlobUrls = useMemo(() => {
|
||||
return photos.map(photo => URL.createObjectURL(photo));
|
||||
return photos.map((photo) => URL.createObjectURL(photo));
|
||||
}, [photos]);
|
||||
|
||||
// Cleanup blob URLs when photos change or component unmounts
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
photoBlobUrls.forEach(url => URL.revokeObjectURL(url));
|
||||
photoBlobUrls.forEach((url) => URL.revokeObjectURL(url));
|
||||
};
|
||||
}, [photoBlobUrls]);
|
||||
|
||||
@@ -202,6 +200,7 @@ const ReturnStatusModal: React.FC<ReturnStatusModalProps> = ({
|
||||
);
|
||||
if (!hasSelection) {
|
||||
setError("Please select at least one return status option");
|
||||
setProcessing(false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -316,7 +315,6 @@ const ReturnStatusModal: React.FC<ReturnStatusModalProps> = ({
|
||||
const data: any = {
|
||||
status: primaryStatus,
|
||||
statusOptions, // Send all selected options
|
||||
notes: notes.trim() || undefined,
|
||||
};
|
||||
|
||||
if (statusOptions.returned_late) {
|
||||
@@ -346,7 +344,6 @@ const ReturnStatusModal: React.FC<ReturnStatusModalProps> = ({
|
||||
lost: false,
|
||||
});
|
||||
setActualReturnDateTime("");
|
||||
setNotes("");
|
||||
setConditionNotes("");
|
||||
setPhotos([]);
|
||||
setError(null);
|
||||
@@ -950,7 +947,7 @@ const ReturnStatusModal: React.FC<ReturnStatusModalProps> = ({
|
||||
>
|
||||
<span className="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
Processing...
|
||||
Submitting...
|
||||
</>
|
||||
) : (
|
||||
"Submit"
|
||||
|
||||
@@ -69,6 +69,18 @@ const ReviewItemModal: React.FC<ReviewItemModalProps> = ({
|
||||
|
||||
if (!show) return null;
|
||||
|
||||
// Show success modal instead of review modal after successful submission
|
||||
if (showSuccessModal) {
|
||||
return (
|
||||
<SuccessModal
|
||||
show={true}
|
||||
onClose={handleSuccessModalClose}
|
||||
title="Thank you for your review!"
|
||||
message={successMessage}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className="modal d-block"
|
||||
@@ -212,13 +224,6 @@ const ReviewItemModal: React.FC<ReviewItemModalProps> = ({
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<SuccessModal
|
||||
show={showSuccessModal}
|
||||
onClose={handleSuccessModalClose}
|
||||
title="Thank you for your review!"
|
||||
message={successMessage}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -69,6 +69,18 @@ const ReviewRenterModal: React.FC<ReviewRenterModalProps> = ({
|
||||
|
||||
if (!show) return null;
|
||||
|
||||
// Show success modal instead of review modal after successful submission
|
||||
if (showSuccessModal) {
|
||||
return (
|
||||
<SuccessModal
|
||||
show={true}
|
||||
onClose={handleSuccessModalClose}
|
||||
title="Thank you for your review!"
|
||||
message={successMessage}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className="modal d-block"
|
||||
@@ -212,13 +224,6 @@ const ReviewRenterModal: React.FC<ReviewRenterModalProps> = ({
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<SuccessModal
|
||||
show={showSuccessModal}
|
||||
onClose={handleSuccessModalClose}
|
||||
title="Thank you for your review!"
|
||||
message={successMessage}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -359,6 +359,14 @@ const Owning: React.FC = () => {
|
||||
<strong>Total:</strong> ${rental.totalAmount}
|
||||
</p>
|
||||
|
||||
{rental.intendedUse && rental.status === "pending" && (
|
||||
<div className="alert alert-light mt-2 mb-2 p-2 small">
|
||||
<strong>Intended Use:</strong>
|
||||
<br />
|
||||
{rental.intendedUse}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{rental.status === "cancelled" &&
|
||||
rental.refundAmount !== undefined && (
|
||||
<div className="alert alert-info mt-2 mb-2 p-2 small">
|
||||
@@ -620,9 +628,7 @@ const Owning: React.FC = () => {
|
||||
onClick={() => toggleAvailability(item)}
|
||||
className="btn btn-sm btn-outline-info"
|
||||
>
|
||||
{item.isAvailable
|
||||
? "Mark Unavailable"
|
||||
: "Mark Available"}
|
||||
{item.isAvailable ? "Mark Unavailable" : "Mark Available"}
|
||||
</button>
|
||||
<button
|
||||
onClick={() => handleDelete(item.id)}
|
||||
|
||||
@@ -17,6 +17,7 @@ const RentItem: React.FC = () => {
|
||||
const [formData, setFormData] = useState({
|
||||
deliveryMethod: "pickup" as "pickup" | "delivery",
|
||||
deliveryAddress: "",
|
||||
intendedUse: "",
|
||||
});
|
||||
|
||||
const [manualSelection, setManualSelection] = useState({
|
||||
@@ -143,6 +144,7 @@ const RentItem: React.FC = () => {
|
||||
endDateTime,
|
||||
deliveryMethod: formData.deliveryMethod,
|
||||
deliveryAddress: formData.deliveryAddress,
|
||||
intendedUse: formData.intendedUse || undefined,
|
||||
totalAmount: totalCost,
|
||||
};
|
||||
} catch (error: any) {
|
||||
@@ -261,6 +263,26 @@ const RentItem: React.FC = () => {
|
||||
</p>
|
||||
)}
|
||||
|
||||
<div className="mb-3">
|
||||
<label htmlFor="intendedUse" className="form-label">
|
||||
What will you use this for?{" "}
|
||||
<span className="text-muted">(Optional)</span>
|
||||
</label>
|
||||
<textarea
|
||||
id="intendedUse"
|
||||
name="intendedUse"
|
||||
className="form-control"
|
||||
rows={3}
|
||||
value={formData.intendedUse}
|
||||
onChange={handleChange}
|
||||
placeholder="Let the owner know how you plan to use their item..."
|
||||
maxLength={500}
|
||||
/>
|
||||
<div className="form-text">
|
||||
{formData.intendedUse.length}/500 characters
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{!manualSelection.startDate ||
|
||||
!manualSelection.endDate ||
|
||||
!getRentalData() ? (
|
||||
|
||||
@@ -232,7 +232,7 @@ export const rentalAPI = {
|
||||
// Return status marking
|
||||
markReturn: (
|
||||
id: string,
|
||||
data: { status: string; actualReturnDateTime?: string; notes?: string }
|
||||
data: { status: string; actualReturnDateTime?: string }
|
||||
) => api.post(`/rentals/${id}/mark-return`, data),
|
||||
reportDamage: (id: string, data: any) =>
|
||||
api.post(`/rentals/${id}/report-damage`, data),
|
||||
|
||||
@@ -152,7 +152,7 @@ export interface Rental {
|
||||
stripeTransferId?: string;
|
||||
deliveryMethod: "pickup" | "delivery";
|
||||
deliveryAddress?: string;
|
||||
notes?: string;
|
||||
intendedUse?: string;
|
||||
rating?: number;
|
||||
review?: string;
|
||||
declineReason?: string;
|
||||
|
||||
Reference in New Issue
Block a user