phone auth, image uploading, address broken up

This commit is contained in:
jackiettran
2025-07-30 19:12:56 -04:00
parent 72d79596ce
commit 7c6c120969
17 changed files with 759 additions and 182 deletions

View File

@@ -3,7 +3,6 @@ import { useNavigate } from "react-router-dom";
import { useAuth } from "../contexts/AuthContext";
import api from "../services/api";
import AvailabilityCalendar from "../components/AvailabilityCalendar";
import AddressAutocomplete from "../components/AddressAutocomplete";
interface ItemFormData {
name: string;
@@ -18,6 +17,12 @@ interface ItemFormData {
pricePerDay?: number;
replacementCost: number;
location: string;
address1: string;
address2: string;
city: string;
state: string;
zipCode: string;
country: string;
latitude?: number;
longitude?: number;
rules?: string;
@@ -49,6 +54,12 @@ const CreateItem: React.FC = () => {
pricePerDay: undefined,
replacementCost: 0,
location: "",
address1: "",
address2: "",
city: "",
state: "",
zipCode: "",
country: "",
minimumRentalDays: 1,
needsTraining: false,
unavailablePeriods: [],
@@ -73,8 +84,21 @@ const CreateItem: React.FC = () => {
// In production, you'd upload to a service like S3
const imageUrls = imagePreviews;
// Construct location from address components
const locationParts = [
formData.address1,
formData.address2,
formData.city,
formData.state,
formData.zipCode,
formData.country
].filter(part => part && part.trim());
const location = locationParts.join(', ');
const response = await api.post("/items", {
...formData,
location,
images: imageUrls,
});
navigate(`/items/${response.data.id}`);
@@ -271,23 +295,99 @@ const CreateItem: React.FC = () => {
</div>
</div>
<h6 className="mb-3">Location *</h6>
<div className="row mb-3">
<div className="col-md-6">
<label htmlFor="address1" className="form-label">
Address Line 1
</label>
<input
type="text"
className="form-control"
id="address1"
name="address1"
value={formData.address1}
onChange={handleChange}
placeholder="123 Main Street"
required
/>
</div>
<div className="col-md-6">
<label htmlFor="address2" className="form-label">
Address Line 2
</label>
<input
type="text"
className="form-control"
id="address2"
name="address2"
value={formData.address2}
onChange={handleChange}
placeholder="Apt, Suite, Unit, etc."
/>
</div>
</div>
<div className="row mb-3">
<div className="col-md-6">
<label htmlFor="city" className="form-label">
City
</label>
<input
type="text"
className="form-control"
id="city"
name="city"
value={formData.city}
onChange={handleChange}
required
/>
</div>
<div className="col-md-3">
<label htmlFor="state" className="form-label">
State
</label>
<input
type="text"
className="form-control"
id="state"
name="state"
value={formData.state}
onChange={handleChange}
placeholder="CA"
required
/>
</div>
<div className="col-md-3">
<label htmlFor="zipCode" className="form-label">
ZIP Code
</label>
<input
type="text"
className="form-control"
id="zipCode"
name="zipCode"
value={formData.zipCode}
onChange={handleChange}
placeholder="12345"
required
/>
</div>
</div>
<div className="mb-3">
<label htmlFor="location" className="form-label">
Location *
<label htmlFor="country" className="form-label">
Country
</label>
<AddressAutocomplete
id="location"
name="location"
value={formData.location}
onChange={(value, lat, lon) => {
setFormData(prev => ({
...prev,
location: value,
latitude: lat,
longitude: lon
}));
}}
placeholder="Address"
<input
type="text"
className="form-control"
id="country"
name="country"
value={formData.country}
onChange={handleChange}
placeholder="United States"
required
/>
</div>
@@ -305,7 +405,10 @@ const CreateItem: React.FC = () => {
/>
<label className="form-check-label" htmlFor="pickUpAvailable">
Pick-Up
<div className="small text-muted">They pick-up the item from your location and they return the item to your location</div>
<div className="small text-muted">
They pick-up the item from your location and they return the
item to your location
</div>
</label>
</div>
<div className="form-check">
@@ -325,24 +428,27 @@ const CreateItem: React.FC = () => {
Local Delivery
{formData.localDeliveryAvailable && (
<span className="ms-2">
(Delivery Radius:
(Delivery Radius:
<input
type="number"
className="form-control form-control-sm d-inline-block mx-1"
id="localDeliveryRadius"
name="localDeliveryRadius"
value={formData.localDeliveryRadius || ''}
value={formData.localDeliveryRadius || ""}
onChange={handleChange}
onClick={(e) => e.stopPropagation()}
placeholder="25"
min="1"
max="100"
style={{ width: '60px' }}
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 className="small text-muted">
You deliver and then pick-up the item when the rental
period ends
</div>
</div>
</label>
</div>
@@ -373,7 +479,9 @@ const CreateItem: React.FC = () => {
htmlFor="inPlaceUseAvailable"
>
In-Place Use
<div className="small text-muted">They use at your location</div>
<div className="small text-muted">
They use at your location
</div>
</label>
</div>
</div>
@@ -387,7 +495,9 @@ const CreateItem: React.FC = () => {
<select
className="form-select"
value={priceType}
onChange={(e) => setPriceType(e.target.value as "hour" | "day")}
onChange={(e) =>
setPriceType(e.target.value as "hour" | "day")
}
>
<option value="hour">Hour</option>
<option value="day">Day</option>
@@ -400,8 +510,14 @@ const CreateItem: React.FC = () => {
type="number"
className="form-control"
id={priceType === "hour" ? "pricePerHour" : "pricePerDay"}
name={priceType === "hour" ? "pricePerHour" : "pricePerDay"}
value={priceType === "hour" ? (formData.pricePerHour || "") : (formData.pricePerDay || "")}
name={
priceType === "hour" ? "pricePerHour" : "pricePerDay"
}
value={
priceType === "hour"
? formData.pricePerHour || ""
: formData.pricePerDay || ""
}
onChange={handleChange}
step="0.01"
min="0"
@@ -429,11 +545,16 @@ const CreateItem: React.FC = () => {
<div className="mb-4">
<h5>Availability Schedule</h5>
<p className="text-muted">Select dates when the item is NOT available for rent</p>
<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 }))
onPeriodsChange={(periods) =>
setFormData((prev) => ({
...prev,
unavailablePeriods: periods,
}))
}
mode="owner"
/>