mirror of
https://github.com/Since-3/Kuma.git
synced 2026-10-12 21:41:17 +00:00
added price range filtering on courses
This commit is contained in:
parent
6aee6a4064
commit
eeb8e89c3c
2 changed files with 53 additions and 8 deletions
|
|
@ -28,6 +28,8 @@ interface FilterValues {
|
||||||
dateTo: string;
|
dateTo: string;
|
||||||
timeFrom: string;
|
timeFrom: string;
|
||||||
timeTo: string;
|
timeTo: string;
|
||||||
|
priceMin: number;
|
||||||
|
priceMax: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CourseFilterProps {
|
interface CourseFilterProps {
|
||||||
|
|
@ -42,6 +44,10 @@ interface CourseFilterProps {
|
||||||
dateTo: string;
|
dateTo: string;
|
||||||
timeFrom: string;
|
timeFrom: string;
|
||||||
timeTo: string;
|
timeTo: string;
|
||||||
|
priceMin: number;
|
||||||
|
priceMax: number;
|
||||||
|
priceRangeMin: number;
|
||||||
|
priceRangeMax: number;
|
||||||
uniqueSports: string[];
|
uniqueSports: string[];
|
||||||
uniqueTrainers: string[];
|
uniqueTrainers: string[];
|
||||||
uniqueRooms: string[];
|
uniqueRooms: string[];
|
||||||
|
|
@ -63,6 +69,10 @@ const CourseFilter: React.FC<CourseFilterProps> = ({
|
||||||
dateTo,
|
dateTo,
|
||||||
timeFrom,
|
timeFrom,
|
||||||
timeTo,
|
timeTo,
|
||||||
|
priceMin,
|
||||||
|
priceMax,
|
||||||
|
priceRangeMin,
|
||||||
|
priceRangeMax,
|
||||||
uniqueSports,
|
uniqueSports,
|
||||||
uniqueTrainers,
|
uniqueTrainers,
|
||||||
uniqueRooms,
|
uniqueRooms,
|
||||||
|
|
@ -78,7 +88,8 @@ const CourseFilter: React.FC<CourseFilterProps> = ({
|
||||||
const [localDateTo, setLocalDateTo] = useState(dateTo);
|
const [localDateTo, setLocalDateTo] = useState(dateTo);
|
||||||
const [localTimeFrom, setLocalTimeFrom] = useState(timeFrom);
|
const [localTimeFrom, setLocalTimeFrom] = useState(timeFrom);
|
||||||
const [localTimeTo, setLocalTimeTo] = useState(timeTo);
|
const [localTimeTo, setLocalTimeTo] = useState(timeTo);
|
||||||
const [priceValue, setPriceValue] = useState([0, 50]);
|
const [localPriceMin, setLocalPriceMin] = useState(priceMin);
|
||||||
|
const [localPriceMax, setLocalPriceMax] = useState(priceMax);
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
|
||||||
// Sync local state when sheet opens
|
// Sync local state when sheet opens
|
||||||
|
|
@ -92,6 +103,8 @@ const CourseFilter: React.FC<CourseFilterProps> = ({
|
||||||
setLocalDateTo(dateTo);
|
setLocalDateTo(dateTo);
|
||||||
setLocalTimeFrom(timeFrom);
|
setLocalTimeFrom(timeFrom);
|
||||||
setLocalTimeTo(timeTo);
|
setLocalTimeTo(timeTo);
|
||||||
|
setLocalPriceMin(priceMin);
|
||||||
|
setLocalPriceMax(priceMax);
|
||||||
}
|
}
|
||||||
setIsOpen(open);
|
setIsOpen(open);
|
||||||
};
|
};
|
||||||
|
|
@ -104,7 +117,9 @@ const CourseFilter: React.FC<CourseFilterProps> = ({
|
||||||
!!dateFrom ||
|
!!dateFrom ||
|
||||||
!!dateTo ||
|
!!dateTo ||
|
||||||
!!timeFrom ||
|
!!timeFrom ||
|
||||||
!!timeTo;
|
!!timeTo ||
|
||||||
|
priceMin !== priceRangeMin ||
|
||||||
|
priceMax !== priceRangeMax;
|
||||||
|
|
||||||
const handleApplyFilters = () => {
|
const handleApplyFilters = () => {
|
||||||
onApplyFilters({
|
onApplyFilters({
|
||||||
|
|
@ -116,6 +131,8 @@ const CourseFilter: React.FC<CourseFilterProps> = ({
|
||||||
dateTo: localDateTo,
|
dateTo: localDateTo,
|
||||||
timeFrom: localTimeFrom,
|
timeFrom: localTimeFrom,
|
||||||
timeTo: localTimeTo,
|
timeTo: localTimeTo,
|
||||||
|
priceMin: localPriceMin,
|
||||||
|
priceMax: localPriceMax,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -128,6 +145,8 @@ const CourseFilter: React.FC<CourseFilterProps> = ({
|
||||||
setLocalDateTo("");
|
setLocalDateTo("");
|
||||||
setLocalTimeFrom("");
|
setLocalTimeFrom("");
|
||||||
setLocalTimeTo("");
|
setLocalTimeTo("");
|
||||||
|
setLocalPriceMin(priceRangeMin);
|
||||||
|
setLocalPriceMax(priceRangeMax);
|
||||||
onReset();
|
onReset();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -213,19 +232,23 @@ const CourseFilter: React.FC<CourseFilterProps> = ({
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* TODO: Price */}
|
{/* Price */}
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
<label className="font-medium">Preis</label>
|
<label className="font-medium">Preis</label>
|
||||||
<Slider
|
<Slider
|
||||||
className="mt-1"
|
className="mt-1"
|
||||||
value={priceValue}
|
value={[localPriceMin, localPriceMax]}
|
||||||
onValueChange={setPriceValue}
|
onValueChange={([min, max]) => {
|
||||||
max={50}
|
setLocalPriceMin(min);
|
||||||
|
setLocalPriceMax(max);
|
||||||
|
}}
|
||||||
|
min={priceRangeMin}
|
||||||
|
max={priceRangeMax}
|
||||||
step={1}
|
step={1}
|
||||||
/>
|
/>
|
||||||
<div className="flex justify-between mt-2">
|
<div className="flex justify-between mt-2">
|
||||||
<span>{priceValue[0]}€</span>
|
<span>{localPriceMin}€</span>
|
||||||
<span>{priceValue[1]}€</span>
|
<span>{localPriceMax}€</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,8 @@ const CourseListView = () => {
|
||||||
const [dateTo, setDateTo] = useState("");
|
const [dateTo, setDateTo] = useState("");
|
||||||
const [timeFrom, setTimeFrom] = useState("");
|
const [timeFrom, setTimeFrom] = useState("");
|
||||||
const [timeTo, setTimeTo] = useState("");
|
const [timeTo, setTimeTo] = useState("");
|
||||||
|
const [priceMin, setPriceMin] = useState<number | null>(null);
|
||||||
|
const [priceMax, setPriceMax] = useState<number | null>(null);
|
||||||
const [deleteMode, setDeleteMode] = useState(false);
|
const [deleteMode, setDeleteMode] = useState(false);
|
||||||
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
||||||
const [courseToDelete, setCourseToDelete] = useState<{ id: string; name: string } | null>(null);
|
const [courseToDelete, setCourseToDelete] = useState<{ id: string; name: string } | null>(null);
|
||||||
|
|
@ -314,6 +316,10 @@ const CourseListView = () => {
|
||||||
if (timeFrom && course.timeFrom < timeFrom) return false;
|
if (timeFrom && course.timeFrom < timeFrom) return false;
|
||||||
if (timeTo && course.timeTo > timeTo) return false;
|
if (timeTo && course.timeTo > timeTo) return false;
|
||||||
|
|
||||||
|
// Price range filter
|
||||||
|
if (priceMin !== null && course.price < priceMin) return false;
|
||||||
|
if (priceMax !== null && course.price > priceMax) return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -338,6 +344,12 @@ const CourseListView = () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Calculate price range from courses
|
||||||
|
const priceRangeMin =
|
||||||
|
courses.length > 0 ? Math.floor(Math.min(...courses.map((c) => c.price))) : 0;
|
||||||
|
const priceRangeMax =
|
||||||
|
courses.length > 0 ? Math.ceil(Math.max(...courses.map((c) => c.price))) : 0;
|
||||||
|
|
||||||
// Get unique sports for filter
|
// Get unique sports for filter
|
||||||
const uniqueSports = Array.from(new Set(courses.map((c) => c.sport)));
|
const uniqueSports = Array.from(new Set(courses.map((c) => c.sport)));
|
||||||
|
|
||||||
|
|
@ -365,6 +377,8 @@ const CourseListView = () => {
|
||||||
!!dateTo,
|
!!dateTo,
|
||||||
!!timeFrom,
|
!!timeFrom,
|
||||||
!!timeTo,
|
!!timeTo,
|
||||||
|
priceMin !== null && priceMin !== priceRangeMin,
|
||||||
|
priceMax !== null && priceMax !== priceRangeMax,
|
||||||
].filter(Boolean).length;
|
].filter(Boolean).length;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -380,6 +394,10 @@ const CourseListView = () => {
|
||||||
dateTo={dateTo}
|
dateTo={dateTo}
|
||||||
timeFrom={timeFrom}
|
timeFrom={timeFrom}
|
||||||
timeTo={timeTo}
|
timeTo={timeTo}
|
||||||
|
priceMin={priceMin ?? priceRangeMin}
|
||||||
|
priceMax={priceMax ?? priceRangeMax}
|
||||||
|
priceRangeMin={priceRangeMin}
|
||||||
|
priceRangeMax={priceRangeMax}
|
||||||
uniqueSports={uniqueSports}
|
uniqueSports={uniqueSports}
|
||||||
uniqueTrainers={uniqueTrainers}
|
uniqueTrainers={uniqueTrainers}
|
||||||
uniqueRooms={uniqueRooms}
|
uniqueRooms={uniqueRooms}
|
||||||
|
|
@ -392,6 +410,8 @@ const CourseListView = () => {
|
||||||
setDateTo(filters.dateTo);
|
setDateTo(filters.dateTo);
|
||||||
setTimeFrom(filters.timeFrom);
|
setTimeFrom(filters.timeFrom);
|
||||||
setTimeTo(filters.timeTo);
|
setTimeTo(filters.timeTo);
|
||||||
|
setPriceMin(filters.priceMin === priceRangeMin ? null : filters.priceMin);
|
||||||
|
setPriceMax(filters.priceMax === priceRangeMax ? null : filters.priceMax);
|
||||||
}}
|
}}
|
||||||
onReset={() => {
|
onReset={() => {
|
||||||
setFilterStatus("all");
|
setFilterStatus("all");
|
||||||
|
|
@ -402,6 +422,8 @@ const CourseListView = () => {
|
||||||
setDateTo("");
|
setDateTo("");
|
||||||
setTimeFrom("");
|
setTimeFrom("");
|
||||||
setTimeTo("");
|
setTimeTo("");
|
||||||
|
setPriceMin(null);
|
||||||
|
setPriceMax(null);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Button variant="outline" className="flex items-center gap-2 relative">
|
<Button variant="outline" className="flex items-center gap-2 relative">
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue