206 lines
6.5 KiB
TypeScript
206 lines
6.5 KiB
TypeScript
import React from "react";
|
|
import { Link } from "react-router";
|
|
|
|
interface PricingFormProps {
|
|
pricePerHour: number | string;
|
|
pricePerDay: number | string;
|
|
pricePerWeek: number | string;
|
|
pricePerMonth: number | string;
|
|
replacementCost: number | string;
|
|
selectedPricingUnit: string;
|
|
showAdvancedPricing: boolean;
|
|
enabledTiers: {
|
|
hour: boolean;
|
|
day: boolean;
|
|
week: boolean;
|
|
month: boolean;
|
|
};
|
|
onChange: (
|
|
e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>
|
|
) => void;
|
|
onPricingUnitChange: (e: React.ChangeEvent<HTMLSelectElement>) => void;
|
|
onToggleAdvancedPricing: () => void;
|
|
onTierToggle: (tier: string) => void;
|
|
}
|
|
|
|
const PricingForm: React.FC<PricingFormProps> = ({
|
|
pricePerHour,
|
|
pricePerDay,
|
|
pricePerWeek,
|
|
pricePerMonth,
|
|
replacementCost,
|
|
selectedPricingUnit,
|
|
showAdvancedPricing,
|
|
enabledTiers,
|
|
onChange,
|
|
onPricingUnitChange,
|
|
onToggleAdvancedPricing,
|
|
onTierToggle,
|
|
}) => {
|
|
// Map pricing unit to field name and label
|
|
const pricingUnitMap: Record<
|
|
string,
|
|
{ field: string; label: string; value: number | string }
|
|
> = {
|
|
hour: { field: "pricePerHour", label: "Hour", value: pricePerHour },
|
|
day: { field: "pricePerDay", label: "Day", value: pricePerDay },
|
|
week: { field: "pricePerWeek", label: "Week", value: pricePerWeek },
|
|
month: { field: "pricePerMonth", label: "Month", value: pricePerMonth },
|
|
};
|
|
|
|
// When advanced pricing is on, show ALL 4 options
|
|
// When advanced pricing is off, show only the 3 non-selected options
|
|
const advancedPricingOptions = showAdvancedPricing
|
|
? Object.entries(pricingUnitMap)
|
|
: Object.entries(pricingUnitMap).filter(
|
|
([key]) => key !== selectedPricingUnit
|
|
);
|
|
|
|
const selectedUnit = pricingUnitMap[selectedPricingUnit];
|
|
|
|
return (
|
|
<div className="card mb-4">
|
|
<div className="card-body">
|
|
<h5 className="card-title">Pricing</h5>
|
|
<p className="text-muted small mb-3">
|
|
{showAdvancedPricing ? (
|
|
"Set multiple pricing tiers for flexible rental rates."
|
|
) : (
|
|
<>
|
|
Village Share charges a 10% Community Upkeep Fee to help keep us
|
|
running.{" "}
|
|
<Link to="/faq" target="_blank">
|
|
Calculate what you can earn here
|
|
</Link>
|
|
</>
|
|
)}
|
|
</p>
|
|
|
|
{/* Pricing Unit Dropdown - Only show when advanced pricing is OFF */}
|
|
{!showAdvancedPricing && (
|
|
<>
|
|
<div className="mb-3">
|
|
<label htmlFor="pricingUnit" className="form-label">
|
|
Pricing Unit
|
|
</label>
|
|
<select
|
|
className="form-select"
|
|
id="pricingUnit"
|
|
value={selectedPricingUnit}
|
|
onChange={onPricingUnitChange}
|
|
>
|
|
<option value="hour">Hour</option>
|
|
<option value="day">Day</option>
|
|
<option value="week">Week</option>
|
|
<option value="month">Month</option>
|
|
</select>
|
|
</div>
|
|
|
|
{/* Primary Price Input */}
|
|
<div className="mb-3">
|
|
<label htmlFor={selectedUnit.field} className="form-label mb-0">
|
|
Price per {selectedUnit.label}
|
|
</label>
|
|
<div className="input-group">
|
|
<span className="input-group-text">$</span>
|
|
<input
|
|
type="number"
|
|
className="form-control"
|
|
id={selectedUnit.field}
|
|
name={selectedUnit.field}
|
|
value={selectedUnit.value}
|
|
onChange={onChange}
|
|
step="0.01"
|
|
min="0"
|
|
placeholder="0.00"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</>
|
|
)}
|
|
|
|
{/* Advanced Pricing Toggle */}
|
|
<div className="mb-3">
|
|
<button
|
|
type="button"
|
|
className="btn btn-link p-0 text-decoration-none"
|
|
onClick={onToggleAdvancedPricing}
|
|
>
|
|
{showAdvancedPricing ? "▼" : "▶"} Advanced Pricing
|
|
</button>
|
|
</div>
|
|
|
|
{/* Advanced Pricing Section */}
|
|
{showAdvancedPricing && (
|
|
<div className="border rounded p-3 mb-3 bg-light">
|
|
<p className="text-muted small mb-3">
|
|
Set multiple pricing tiers. Check the boxes for the tiers you want
|
|
to use.
|
|
</p>
|
|
{advancedPricingOptions.map(([key, { field, label, value }]) => (
|
|
<div className="mb-3" key={key}>
|
|
<div className="form-check mb-2">
|
|
<input
|
|
className="form-check-input"
|
|
type="checkbox"
|
|
id={`enable-${key}`}
|
|
checked={enabledTiers[key as keyof typeof enabledTiers]}
|
|
onChange={() => onTierToggle(key)}
|
|
/>
|
|
<label className="form-check-label" htmlFor={`enable-${key}`}>
|
|
Price per {label}
|
|
</label>
|
|
</div>
|
|
<div className="input-group">
|
|
<span className="input-group-text">$</span>
|
|
<input
|
|
type="number"
|
|
className="form-control"
|
|
id={field}
|
|
name={field}
|
|
value={value}
|
|
onChange={onChange}
|
|
step="0.01"
|
|
min="0"
|
|
placeholder="0.00"
|
|
disabled={!enabledTiers[key as keyof typeof enabledTiers]}
|
|
/>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
)}
|
|
|
|
<hr className="my-4" />
|
|
|
|
{/* Replacement Cost */}
|
|
<div className="mb-3">
|
|
<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
|
|
type="number"
|
|
className="form-control"
|
|
id="replacementCost"
|
|
name="replacementCost"
|
|
value={replacementCost}
|
|
onChange={onChange}
|
|
step="0.01"
|
|
min="0"
|
|
placeholder="0"
|
|
required
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default PricingForm;
|