pricing tiers
This commit is contained in:
@@ -18,6 +18,8 @@ interface ItemFormData {
|
||||
inPlaceUseAvailable: boolean;
|
||||
pricePerHour?: number | string;
|
||||
pricePerDay?: number | string;
|
||||
pricePerWeek?: number | string;
|
||||
pricePerMonth?: number | string;
|
||||
replacementCost: number | string;
|
||||
address1: string;
|
||||
address2: string;
|
||||
@@ -28,7 +30,6 @@ interface ItemFormData {
|
||||
latitude?: number;
|
||||
longitude?: number;
|
||||
rules?: string;
|
||||
minimumRentalDays: number;
|
||||
needsTraining: boolean;
|
||||
generalAvailableAfter: string;
|
||||
generalAvailableBefore: string;
|
||||
@@ -53,12 +54,19 @@ const EditItem: React.FC = () => {
|
||||
const [success, setSuccess] = useState(false);
|
||||
const [imageFiles, setImageFiles] = useState<File[]>([]);
|
||||
const [imagePreviews, setImagePreviews] = useState<string[]>([]);
|
||||
const [priceType, setPriceType] = useState<"hour" | "day">("day");
|
||||
const [acceptedRentals, setAcceptedRentals] = useState<Rental[]>([]);
|
||||
const [userAddresses, setUserAddresses] = useState<Address[]>([]);
|
||||
const [selectedAddressId, setSelectedAddressId] = useState<string>("");
|
||||
const [addressesLoading, setAddressesLoading] = useState(true);
|
||||
|
||||
const [selectedPricingUnit, setSelectedPricingUnit] = useState<string>("day");
|
||||
const [showAdvancedPricing, setShowAdvancedPricing] = useState<boolean>(false);
|
||||
const [enabledPricingTiers, setEnabledPricingTiers] = useState({
|
||||
hour: false,
|
||||
day: false,
|
||||
week: false,
|
||||
month: false,
|
||||
});
|
||||
|
||||
// Reference to LocationForm geocoding function
|
||||
const geocodeLocationRef = useRef<(() => Promise<boolean>) | null>(null);
|
||||
const [formData, setFormData] = useState<ItemFormData>({
|
||||
@@ -76,7 +84,6 @@ const EditItem: React.FC = () => {
|
||||
zipCode: "",
|
||||
country: "US",
|
||||
rules: "",
|
||||
minimumRentalDays: 1,
|
||||
needsTraining: false,
|
||||
generalAvailableAfter: "09:00",
|
||||
generalAvailableBefore: "17:00",
|
||||
@@ -119,13 +126,6 @@ const EditItem: React.FC = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the price type based on available pricing
|
||||
if (item.pricePerHour) {
|
||||
setPriceType("hour");
|
||||
} else if (item.pricePerDay) {
|
||||
setPriceType("day");
|
||||
}
|
||||
|
||||
// Convert item data to form data format
|
||||
setFormData({
|
||||
name: item.name,
|
||||
@@ -134,6 +134,8 @@ const EditItem: React.FC = () => {
|
||||
inPlaceUseAvailable: item.inPlaceUseAvailable || false,
|
||||
pricePerHour: item.pricePerHour || "",
|
||||
pricePerDay: item.pricePerDay || "",
|
||||
pricePerWeek: item.pricePerWeek || "",
|
||||
pricePerMonth: item.pricePerMonth || "",
|
||||
replacementCost: item.replacementCost || "",
|
||||
address1: item.address1 || "",
|
||||
address2: item.address2 || "",
|
||||
@@ -144,7 +146,6 @@ const EditItem: React.FC = () => {
|
||||
latitude: item.latitude,
|
||||
longitude: item.longitude,
|
||||
rules: item.rules || "",
|
||||
minimumRentalDays: item.minimumRentalDays,
|
||||
needsTraining: item.needsTraining || false,
|
||||
generalAvailableAfter: item.availableAfter || "09:00",
|
||||
generalAvailableBefore: item.availableBefore || "17:00",
|
||||
@@ -164,6 +165,40 @@ const EditItem: React.FC = () => {
|
||||
if (item.images && item.images.length > 0) {
|
||||
setImagePreviews(item.images);
|
||||
}
|
||||
|
||||
// Determine which pricing unit to select based on existing data
|
||||
// Priority: hour -> day -> week -> month (first one with a value)
|
||||
if (item.pricePerHour) {
|
||||
setSelectedPricingUnit("hour");
|
||||
} else if (item.pricePerDay) {
|
||||
setSelectedPricingUnit("day");
|
||||
} else if (item.pricePerWeek) {
|
||||
setSelectedPricingUnit("week");
|
||||
} else if (item.pricePerMonth) {
|
||||
setSelectedPricingUnit("month");
|
||||
} else {
|
||||
setSelectedPricingUnit("day"); // Default to day if no pricing is set
|
||||
}
|
||||
|
||||
// Set enabled tiers based on which prices are populated
|
||||
setEnabledPricingTiers({
|
||||
hour: !!(item.pricePerHour && Number(item.pricePerHour) > 0),
|
||||
day: !!(item.pricePerDay && Number(item.pricePerDay) > 0),
|
||||
week: !!(item.pricePerWeek && Number(item.pricePerWeek) > 0),
|
||||
month: !!(item.pricePerMonth && Number(item.pricePerMonth) > 0),
|
||||
});
|
||||
|
||||
// Auto-expand advanced section if multiple pricing tiers are set
|
||||
const pricingTiersSet = [
|
||||
item.pricePerHour,
|
||||
item.pricePerDay,
|
||||
item.pricePerWeek,
|
||||
item.pricePerMonth,
|
||||
].filter((price) => price && Number(price) > 0).length;
|
||||
|
||||
if (pricingTiersSet > 1) {
|
||||
setShowAdvancedPricing(true);
|
||||
}
|
||||
} catch (err: any) {
|
||||
setError(err.response?.data?.message || "Failed to fetch item");
|
||||
} finally {
|
||||
@@ -240,6 +275,12 @@ const EditItem: React.FC = () => {
|
||||
pricePerHour: formData.pricePerHour
|
||||
? parseFloat(formData.pricePerHour.toString())
|
||||
: undefined,
|
||||
pricePerWeek: formData.pricePerWeek
|
||||
? parseFloat(formData.pricePerWeek.toString())
|
||||
: undefined,
|
||||
pricePerMonth: formData.pricePerMonth
|
||||
? parseFloat(formData.pricePerMonth.toString())
|
||||
: undefined,
|
||||
replacementCost: formData.replacementCost
|
||||
? parseFloat(formData.replacementCost.toString())
|
||||
: 0,
|
||||
@@ -360,6 +401,21 @@ const EditItem: React.FC = () => {
|
||||
}));
|
||||
};
|
||||
|
||||
const handlePricingUnitChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
setSelectedPricingUnit(e.target.value);
|
||||
};
|
||||
|
||||
const handleToggleAdvancedPricing = () => {
|
||||
setShowAdvancedPricing((prev) => !prev);
|
||||
};
|
||||
|
||||
const handleTierToggle = (tier: string) => {
|
||||
setEnabledPricingTiers((prev) => ({
|
||||
...prev,
|
||||
[tier]: !prev[tier as keyof typeof prev],
|
||||
}));
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="container mt-5">
|
||||
@@ -445,13 +501,18 @@ const EditItem: React.FC = () => {
|
||||
/>
|
||||
|
||||
<PricingForm
|
||||
priceType={priceType}
|
||||
pricePerHour={formData.pricePerHour || ""}
|
||||
pricePerDay={formData.pricePerDay || ""}
|
||||
pricePerWeek={formData.pricePerWeek || ""}
|
||||
pricePerMonth={formData.pricePerMonth || ""}
|
||||
replacementCost={formData.replacementCost}
|
||||
minimumRentalDays={formData.minimumRentalDays}
|
||||
onPriceTypeChange={setPriceType}
|
||||
selectedPricingUnit={selectedPricingUnit}
|
||||
showAdvancedPricing={showAdvancedPricing}
|
||||
enabledTiers={enabledPricingTiers}
|
||||
onChange={handleChange}
|
||||
onPricingUnitChange={handlePricingUnitChange}
|
||||
onToggleAdvancedPricing={handleToggleAdvancedPricing}
|
||||
onTierToggle={handleTierToggle}
|
||||
/>
|
||||
|
||||
<div className="card mb-4">
|
||||
|
||||
Reference in New Issue
Block a user