simplified create item. Restructured profile. Simplified availability

This commit is contained in:
jackiettran
2025-08-19 17:28:22 -04:00
parent 99eae4774e
commit 66dc187295
11 changed files with 1317 additions and 872 deletions

View File

@@ -2,15 +2,12 @@ import React, { useState } from "react";
import { useNavigate } from "react-router-dom";
import { useAuth } from "../contexts/AuthContext";
import api from "../services/api";
import AvailabilityCalendar from "../components/AvailabilityCalendar";
import AvailabilitySettings from "../components/AvailabilitySettings";
interface ItemFormData {
name: string;
description: string;
pickUpAvailable: boolean;
localDeliveryAvailable: boolean;
localDeliveryRadius?: number;
shippingAvailable: boolean;
inPlaceUseAvailable: boolean;
pricePerHour?: number;
pricePerDay?: number;
@@ -27,13 +24,18 @@ interface ItemFormData {
rules?: string;
minimumRentalDays: number;
needsTraining: boolean;
unavailablePeriods?: Array<{
id: string;
startDate: Date;
endDate: Date;
startTime?: string;
endTime?: string;
}>;
generalAvailableAfter: string;
generalAvailableBefore: string;
specifyTimesPerDay: boolean;
weeklyTimes: {
sunday: { availableAfter: string; availableBefore: string };
monday: { availableAfter: string; availableBefore: string };
tuesday: { availableAfter: string; availableBefore: string };
wednesday: { availableAfter: string; availableBefore: string };
thursday: { availableAfter: string; availableBefore: string };
friday: { availableAfter: string; availableBefore: string };
saturday: { availableAfter: string; availableBefore: string };
};
}
const CreateItem: React.FC = () => {
@@ -45,9 +47,6 @@ const CreateItem: React.FC = () => {
name: "",
description: "",
pickUpAvailable: false,
localDeliveryAvailable: false,
localDeliveryRadius: 25,
shippingAvailable: false,
inPlaceUseAvailable: false,
pricePerDay: undefined,
replacementCost: 0,
@@ -57,10 +56,21 @@ const CreateItem: React.FC = () => {
city: "",
state: "",
zipCode: "",
country: "",
country: "US",
minimumRentalDays: 1,
needsTraining: false,
unavailablePeriods: [],
generalAvailableAfter: "09:00",
generalAvailableBefore: "17:00",
specifyTimesPerDay: false,
weeklyTimes: {
sunday: { availableAfter: "09:00", availableBefore: "17:00" },
monday: { availableAfter: "09:00", availableBefore: "17:00" },
tuesday: { availableAfter: "09:00", availableBefore: "17:00" },
wednesday: { availableAfter: "09:00", availableBefore: "17:00" },
thursday: { availableAfter: "09:00", availableBefore: "17:00" },
friday: { availableAfter: "09:00", availableBefore: "17:00" },
saturday: { availableAfter: "09:00", availableBefore: "17:00" },
},
});
const [imageFiles, setImageFiles] = useState<File[]>([]);
const [imagePreviews, setImagePreviews] = useState<string[]>([]);
@@ -126,6 +136,24 @@ const CreateItem: React.FC = () => {
}
};
const handleWeeklyTimeChange = (
day: string,
field: "availableAfter" | "availableBefore",
value: string
) => {
setFormData((prev) => ({
...prev,
weeklyTimes: {
...prev.weeklyTimes,
[day]: {
...prev.weeklyTimes[day as keyof typeof prev.weeklyTimes],
[field]: value,
},
},
}));
};
const handleImageChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const files = Array.from(e.target.files || []);
@@ -170,7 +198,12 @@ const CreateItem: React.FC = () => {
<div className="card mb-4">
<div className="card-body">
<div className="mb-3">
<label className="form-label">Upload Images (Max 5)</label>
<label className="form-label mb-0">
Upload Images (Max 5)
</label>
<div className="form-text mb-2">
Have pictures of everything that's included
</div>
<input
type="file"
className="form-control"
@@ -179,9 +212,6 @@ const CreateItem: React.FC = () => {
multiple
disabled={imageFiles.length >= 5}
/>
<div className="form-text">
Upload up to 5 images of your item
</div>
</div>
{imagePreviews.length > 0 && (
@@ -252,6 +282,13 @@ const CreateItem: React.FC = () => {
{/* Location Card */}
<div className="card mb-4">
<div className="card-body">
<div className="mb-3">
<small className="text-muted">
<i className="bi bi-info-circle me-2"></i>
Your address is private. This will only be used to show
renters a general area.
</small>
</div>
<div className="row mb-3">
<div className="col-md-6">
<label htmlFor="address1" className="form-label">
@@ -365,70 +402,12 @@ const CreateItem: React.FC = () => {
onChange={handleChange}
/>
<label className="form-check-label" htmlFor="pickUpAvailable">
Pick-Up
Pick-Up/Drop-off
<div className="small text-muted">
They pick-up the item from your location and they return
the item to your location
You and the renter coordinate pick-up and drop-off
</div>
</label>
</div>
<div className="form-check">
<input
type="checkbox"
className="form-check-input"
id="localDeliveryAvailable"
name="localDeliveryAvailable"
checked={formData.localDeliveryAvailable}
onChange={handleChange}
/>
<label
className="form-check-label d-flex align-items-center"
htmlFor="localDeliveryAvailable"
>
<div>
Local Delivery
{formData.localDeliveryAvailable && (
<span className="ms-2">
(Delivery Radius:
<input
type="number"
className="form-control form-control-sm d-inline-block mx-1"
id="localDeliveryRadius"
name="localDeliveryRadius"
value={formData.localDeliveryRadius || ""}
onChange={handleChange}
onClick={(e) => e.stopPropagation()}
placeholder="25"
min="1"
max="100"
style={{ width: "60px" }}
/>
miles)
</span>
)}
<div className="small text-muted">
You deliver and then pick-up the item when the rental
period ends
</div>
</div>
</label>
</div>
<div className="form-check">
<input
type="checkbox"
className="form-check-input"
id="shippingAvailable"
name="shippingAvailable"
checked={formData.shippingAvailable}
onChange={handleChange}
/>
<label
className="form-check-label"
htmlFor="shippingAvailable"
>
Shipping
</label>
</div>
<div className="form-check">
<input
type="checkbox"
@@ -451,6 +430,24 @@ const CreateItem: React.FC = () => {
</div>
</div>
{/* Availability Card */}
<div className="card mb-4">
<div className="card-body">
<AvailabilitySettings
data={{
generalAvailableAfter: formData.generalAvailableAfter,
generalAvailableBefore: formData.generalAvailableBefore,
specifyTimesPerDay: formData.specifyTimesPerDay,
weeklyTimes: formData.weeklyTimes
}}
onChange={(field, value) => {
setFormData(prev => ({ ...prev, [field]: value }));
}}
onWeeklyTimeChange={handleWeeklyTimeChange}
/>
</div>
</div>
{/* Pricing Card */}
<div className="card mb-4">
<div className="card-body">
@@ -518,9 +515,12 @@ const CreateItem: React.FC = () => {
</div>
<div className="mb-3">
<label htmlFor="replacementCost" className="form-label">
<label htmlFor="replacementCost" className="form-label mb-0">
Replacement Cost *
</label>
<div className="form-text mb-2">
The cost to replace the item if lost
</div>
<div className="input-group">
<span className="input-group-text">$</span>
<input
@@ -535,32 +535,10 @@ const CreateItem: React.FC = () => {
required
/>
</div>
<div className="form-text">
The cost to replace the item if damaged or lost
</div>
</div>
</div>
</div>
{/* Availability Schedule Card */}
<div className="card mb-4">
<div className="card-body">
<p className="text-muted">
Select dates when the item is NOT available for rent
</p>
<AvailabilityCalendar
unavailablePeriods={formData.unavailablePeriods || []}
onPeriodsChange={(periods) =>
setFormData((prev) => ({
...prev,
unavailablePeriods: periods,
}))
}
mode="owner"
/>
</div>
</div>
{/* Rules & Guidelines Card */}
<div className="card mb-4">
<div className="card-body">
@@ -578,7 +556,7 @@ const CreateItem: React.FC = () => {
</label>
</div>
<label htmlFor="rules" className="form-label">
Additional Rules or Guidelines
Additional Rules
</label>
<textarea
className="form-control"
@@ -587,12 +565,12 @@ const CreateItem: React.FC = () => {
rows={3}
value={formData.rules || ""}
onChange={handleChange}
placeholder="Any specific rules or guidelines for renting this item"
placeholder="Any specific rules for renting this item"
/>
</div>
</div>
<div className="d-grid gap-2">
<div className="d-grid gap-2 mb-5">
<button
type="submit"
className="btn btn-primary"