This commit is contained in:
2024-06-20 18:35:04 +05:00
parent 9630f42a08
commit 07d460ea27
17 changed files with 567 additions and 244 deletions
+1
View File
@@ -13,6 +13,7 @@
"@react-three/drei": "^9.105.6",
"@react-three/fiber": "^8.16.6",
"@types/react-router-dom": "^5.3.3",
"@uidotdev/usehooks": "^2.4.1",
"gsap": "^3.12.5",
"ky": "^1.3.0",
"react": "^18.2.0",
+49 -4
View File
@@ -1,11 +1,56 @@
import { apartmentsApi } from "./urls";
import ky from "ky";
async function getApartments(token: string | null) {
// const token =
// "1000.04c54423a172cff4f2075ef60dc46403.b4a66d1663ed3b39fa86c9b28dbed2fa";
async function getApartments(
token: string | null,
roveHomeFilters: string[],
apartmentTypeFilters: string[],
viewFilters: string[],
totalAreaFilter: number[],
floorFilter: number[],
sortBy: string | undefined,
page: number,
perPage: number
) {
const roveHomeQuery =
roveHomeFilters.length !== 0
? `rove_home=${roveHomeFilters.join(",")}`
: "";
const apartmentQuery =
apartmentTypeFilters.length !== 0
? `apartment_type=${apartmentTypeFilters.join(",")}`
: "";
const viewQuery =
viewFilters.length !== 0 ? `views=${viewFilters.join(",")}` : "";
const totalAreaSliderQuery =
totalAreaFilter.length !== 0
? `total_area_between=${totalAreaFilter[0]},${totalAreaFilter[1]}`
: "";
const floorQuery =
floorFilter.length !== 0
? `floor_between=${floorFilter[0]},${floorFilter[1]}`
: "";
const res = await ky.get(apartmentsApi, {
const sortByQuery = sortBy ? `sort_by=${sortBy}` : "";
const pageQuery = `page=${page}`;
const perPageQuery = `per_page=${perPage}`;
const query = [
apartmentQuery,
roveHomeQuery,
totalAreaSliderQuery,
floorQuery,
viewQuery,
sortByQuery,
pageQuery,
perPageQuery,
]
.filter((q) => q.length !== 0)
.join("&");
const url = `${apartmentsApi}?${query}`;
const res = await ky.get(url, {
headers: {
Authorization: `Zoho-oauthtoken ${token}`,
},
+2 -1
View File
@@ -6,10 +6,11 @@ async function updateAccessToken() {
try {
const res = await ky.get(updateAccessTokenApi);
res.json().then((data) => {
return res.json().then((data) => {
const accessToken = (data as IUpdateAccessToken).accessToken;
localStorage.setItem("ACCESS_TOKEN", accessToken);
return accessToken;
});
} catch (error) {
console.log("error", error);
@@ -10,12 +10,12 @@ import Switch from "../../Switch";
import ResetIcon from "../../icons/ResetIcon";
import { useSwipeable } from "react-swipeable";
import {
initialApartmentTypeCheckboxes,
initialRoveHomeCheckboxes,
initialAparmentTypeCheckboxes,
initialSliders,
initialSwitchers,
} from "../../../consts/initialSearchFilters";
import { initialViewCheckboxes } from "../../../consts/initialMasterplanFilters";
initialViewCheckboxes,
initialRoveHomeCheckboxes,
} from "../../../consts/initialMasterplanFilters";
const SearchFiltersModal = () => {
// const [viewCheckboxes, setViewCheckboxes] = useState<ICheckbox[]>(
@@ -119,7 +119,7 @@ const SearchFiltersModal = () => {
const handleOnResetClick = () => {
setMultirangeSliders(initialSliders);
setViewCheckboxes(initialViewCheckboxes);
setApartmentTypeCheckboxes(initialApartmentTypeCheckboxes);
setApartmentTypeCheckboxes(initialAparmentTypeCheckboxes);
setRoveHomeTypeCheckboxes(initialRoveHomeCheckboxes);
setSwitchers(initialSwitchers);
};
@@ -1,7 +1,6 @@
import { useEffect, useState } from "react";
import { useEffect } from "react";
import LayoutCard from "./LayoutCard";
import SortButton from "./SortButton";
import { initialSortList } from "../../consts/initialSearchPage";
import SearchIcon from "../icons/SearchIcon";
import Button from "../Button";
import FilterIcon from "../icons/FilterIcon";
@@ -9,19 +8,112 @@ import useModal from "../../store/useModal";
import { MobileModalWrapper } from "../modals/mobile/MobileModalWrapper";
import SearchFiltersModal from "../modals/mobile/SearchFiltersModal";
import { getApartments } from "../../api/apartments";
import { IApartmentsRes, InfoRes } from "../../types/apartmentsRes";
import { IAparmentRes, IApartmentsRes } from "../../types/apartmentsRes";
import { updateAccessToken } from "../../api/updateAccessToken";
import useApartments from "../../store/useApartments";
import useSearchFilters from "../../store/useSearchFilters";
import { ICheckbox } from "../../types/checkbox";
import { IMultirangeSlider } from "../../types/multirangeSlider";
import { useDebounce } from "@uidotdev/usehooks";
import { ISwitcher } from "../../types/switcher";
import { initialSliders } from "../../consts/initialMasterplanFilters";
import { ISort } from "../../types/sortType";
const getFilteredApartments = async (
zohoToken: string | null,
setApartments: (apartments: IAparmentRes[]) => void,
roveHomeTypeCheckboxes: ICheckbox[],
apartmentTypeCheckboxes: ICheckbox[],
multirangeSliders: IMultirangeSlider[],
switchers: ISwitcher[],
viewCheckboxes: ICheckbox[],
sortList: ISort[],
page: number,
perPage: number
) => {
const roveHomeFilters = roveHomeTypeCheckboxes
.filter((chx) => chx.selected)
.map((chx) => chx.value);
const apartmentTypeFilters = apartmentTypeCheckboxes
.filter((chx) => chx.selected)
.map((chx) => chx.value);
const viewFilters = viewCheckboxes
.filter((chx) => chx.selected)
.map((chx) => chx.value);
const sortBy = sortList.find((sortType) => sortType.isSelected)?.value;
const totalAreaSlider = multirangeSliders.find(
(sld) => sld.title === "Total Area"
);
const totalAreaFilter = [
totalAreaSlider?.startValue,
totalAreaSlider?.endValue,
] as number[];
const isNotFirstFloor = switchers.find(
(swch) => swch.isSwitched && swch.title === "Not the first floor"
);
const isNotTopFloor = switchers.find(
(swch) => swch.isSwitched && swch.title === "Not the top floor"
);
const initialFloorSlider = initialSliders.find(
(sld) => sld.title === "Floor"
) as IMultirangeSlider;
// если значение ввода в границах слайдера
const maxFloor = initialFloorSlider?.maxValue;
const minFloor = initialFloorSlider?.minValue;
const floorSlider = multirangeSliders.find(
(sld) => sld.title === "Floor"
) as IMultirangeSlider;
const startFloorValue = isNotFirstFloor
? Math.max(minFloor + 1, floorSlider.startValue)
: floorSlider.startValue;
const endFloorValue = isNotTopFloor
? Math.min(maxFloor - 1, floorSlider?.endValue)
: floorSlider?.endValue;
const floorFilter = [startFloorValue, endFloorValue];
const res = await getApartments(
zohoToken,
roveHomeFilters,
apartmentTypeFilters,
viewFilters,
totalAreaFilter,
floorFilter,
sortBy,
page,
perPage
).then((data) => {
const apartmentsData = (data as IApartmentsRes).apartments;
setApartments(apartmentsData);
});
return res;
};
const LayoutOptions = () => {
const [sortList, setSortList] = useState(initialSortList);
const { apartments, setApartments } = useApartments();
const [infoRes, setInfoRes] = useState<InfoRes>(null);
const { setModal } = useModal();
const { roveHomeTypeCheckboxes, apartmentTypeCheckboxes, multirangeSliders } =
useSearchFilters();
const {
roveHomeTypeCheckboxes,
apartmentTypeCheckboxes,
multirangeSliders,
viewCheckboxes,
switchers,
sortList,
setSortList,
page,
setPerPage,
setPage,
perPage,
} = useSearchFilters();
const debouncedSliders = useDebounce(multirangeSliders, 300);
const handleOnSortClick = (sortId: string) => {
const updatedSortList = sortList.map((sort) => {
@@ -39,39 +131,58 @@ const LayoutOptions = () => {
);
};
function handleOnShowMoreBtnClick(): void {
const nextPage = page + 1;
setPage(nextPage);
// setPerPage(nextPage);
}
useEffect(() => {
const zohoToken = localStorage.getItem("ACCESS_TOKEN");
getApartments(zohoToken)
.then((data) => {
const apartmentsData = (data as IApartmentsRes).apartments;
console.log("apartmentsData", apartmentsData);
setApartments(apartmentsData);
})
.catch((error) => {
const errorStatus = error.response.status;
getFilteredApartments(
zohoToken,
setApartments,
roveHomeTypeCheckboxes,
apartmentTypeCheckboxes,
debouncedSliders,
switchers,
viewCheckboxes,
sortList,
page,
perPage
).catch((error) => {
const errorStatus = error.response.status;
if (errorStatus === 401) {
updateAccessToken();
const zohoToken = localStorage.getItem("ACCESS_TOKEN");
getApartments(zohoToken).then((data) => {
const apartmentsData = (data as unknown as IApartmentsRes)
.apartments;
setApartments(apartmentsData);
});
}
});
}, [setApartments]);
useEffect(() => {
console.log("apartments", apartments);
if (errorStatus === 401) {
updateAccessToken().then((token) => {
if (token) {
getFilteredApartments(
token,
setApartments,
roveHomeTypeCheckboxes,
apartmentTypeCheckboxes,
debouncedSliders,
switchers,
viewCheckboxes,
sortList,
page,
perPage
);
}
});
}
});
}, [
setApartments,
roveHomeTypeCheckboxes,
apartmentTypeCheckboxes,
multirangeSliders,
apartments,
debouncedSliders,
switchers,
viewCheckboxes,
sortList,
page,
perPage,
]);
return (
@@ -101,7 +212,10 @@ const LayoutOptions = () => {
<LayoutCard apartmentCard={apartment} key={apartment.id} />
))}
</div>
<div className="bg-white rounded-lg mt-4 py-[10px] flex justify-center select-none cursor-pointer items-center gap-2">
<div
className="bg-white rounded-lg mt-4 py-[10px] flex justify-center select-none cursor-pointer items-center gap-2"
onClick={handleOnShowMoreBtnClick}
>
<SearchIcon /> Show 12 more apartments
</div>
</section>
@@ -3,16 +3,33 @@ import ResetIcon from "../icons/ResetIcon";
import Checkbox from "../Checkbox";
import Switch from "../Switch";
import MultiRangeSlider from "../MultiRangeSlider";
import useSearchFilters from "../../store/useSearchFilters";
import {
initialApartmentTypeCheckboxes,
initialViewCheckboxes,
initialAparmentTypeCheckboxes,
initialSliders,
initialSwitchers,
initialRoveHomeCheckboxes,
} from "../../consts/initialSearchFilters";
import useSearchFilters from "../../store/useSearchFilters";
import { initialViewCheckboxes } from "../../consts/initialMasterplanFilters";
import { useState } from "react";
import { ICheckbox } from "../../types/checkbox";
} from "../../consts/initialMasterplanFilters";
// import { IMultirangeSlider } from "../../types/multirangeSlider";
// function updateSlider(switcherTitle: string, sliders: IMultirangeSlider[]) {
// if(switcherTitle === 'Not the first floor'){
// const updatedSlider = sliders.map((sld) => {
// if(sld.title === 'Floor'){
// const floorSlider = initialSliders.find(sld1 => sld1.title === 'Floor');
// const minValue = floorSlider?.minValue;
// const isValueEqualMinValue = sld.minValue === minValue;
// //Если значение равно минимальному значение, то уменьшаем минимальное значение
// if(isValueEqualMinValue){
// return {...sld, startValue: minValue, minValue: minValue}
// }
// return
// }
// return sld
// })
// }
// }
const SidebarFilters = () => {
const {
@@ -24,12 +41,10 @@ const SidebarFilters = () => {
setApartmentTypeCheckboxes,
roveHomeTypeCheckboxes,
setRoveHomeTypeCheckboxes,
viewCheckboxes,
setViewCheckboxes,
} = useSearchFilters();
const [viewCheckboxes, setViewCheckboxes] = useState<ICheckbox[]>(
initialViewCheckboxes
);
const handleOnCheckboxApartmentClick = (checkboxId: string) => {
const updatedCheckboxes = apartmentTypeCheckboxes.map((cbox) => {
if (checkboxId !== cbox.id) return cbox;
@@ -89,7 +104,7 @@ const SidebarFilters = () => {
const handleOnResetClick = () => {
setViewCheckboxes(initialViewCheckboxes);
setApartmentTypeCheckboxes(initialApartmentTypeCheckboxes);
setApartmentTypeCheckboxes(initialAparmentTypeCheckboxes);
setRoveHomeTypeCheckboxes(initialRoveHomeCheckboxes);
setMultirangeSliders(initialSliders);
setSwitchers(initialSwitchers);
@@ -1,5 +1,6 @@
import { useState, useEffect } from "react";
import { initialSortList, layoutsCards } from "../../consts/initialSearchPage";
import { layoutsCards } from "../../consts/initialSearchPage";
import { initialSortList } from "../../consts/initialMasterplanFilters";
import useSearchFilters from "../../store/useSearchFilters";
import SearchIcon from "../icons/SearchIcon";
import SortButton from "../searchPage/SortButton";
+77 -14
View File
@@ -1,5 +1,6 @@
import { ICheckbox } from "../types/checkbox";
import { IMultirangeSlider } from "../types/multirangeSlider";
import { ISort } from "../types/sortType";
import { ISwitcher } from "../types/switcher";
const initialSliders: IMultirangeSlider[] = [
@@ -15,8 +16,8 @@ const initialSliders: IMultirangeSlider[] = [
{
minValue: 341,
startValue: 341,
endValue: 891,
maxValue: 891,
endValue: 1058,
maxValue: 1058,
title: "Total Area",
unit: "Sqrt",
id: "2",
@@ -24,27 +25,38 @@ const initialSliders: IMultirangeSlider[] = [
{
minValue: 5,
startValue: 5,
endValue: 81,
maxValue: 81,
endValue: 31,
maxValue: 31,
title: "Floor",
id: "3",
},
];
const initialAparmentTypeCheckboxes: ICheckbox[] = [
{ title: "Studio Flex", id: "1", disabled: true, selected: false },
{ title: "Studio", id: "2", selected: false },
{ title: "1 Bedroom", id: "3", selected: false },
{ title: "2 Bedroom", id: "4", selected: false },
{
title: "Studio Flex",
id: "1",
disabled: false,
selected: false,
value: "Studio Flex",
},
{ title: "Studio", id: "2", selected: false, value: "Studio Squared" },
{ title: "1 Bedroom", id: "3", selected: false, value: "1 BR Squared" },
{ title: "2 Bedroom", id: "4", selected: false, value: "2 BR Squared" },
];
const initialViewCheckboxes: ICheckbox[] = [
{ title: "Burj Khalifa", id: "1", disabled: true, selected: false },
{ title: "Amenties", id: "2", selected: false },
{ title: "Downtown", id: "3", selected: false },
{ title: "Canal", id: "4", selected: false },
{ title: "Business Bay", id: "5", selected: false },
{ title: "Park", id: "6", selected: false },
{ title: "Burj Khalifa", id: "1", selected: false, value: "BK" },
{ title: "Amenties", id: "2", selected: false, value: "Amenities" },
{ title: "Downtown", id: "3", selected: false, value: "DT" },
{ title: "Canal", id: "4", selected: false, value: "Canal" },
{ title: "Business Bay", id: "5", selected: false, value: "Business Bay" },
{
title: "Park",
id: "6",
selected: false,
value: "Partial Park,Park Facing",
},
];
const initialSwitchers: ISwitcher[] = [
@@ -52,9 +64,60 @@ const initialSwitchers: ISwitcher[] = [
{ id: "2", title: "Not the top floor", isSwitched: false },
];
const initialRoveHomeCheckboxes: ICheckbox[] = [
{
title: "Downtown",
id: "1",
disabled: false,
selected: false,
value: "Rove Home Downtown",
},
{
title: "Marasi Drive",
id: "2",
selected: false,
value: "Rove Home Marasi Drive",
},
{
title: "Dubai Marina",
id: "3",
selected: false,
value: "Rove Home Dubai Marina",
},
];
const initialSortList: ISort[] = [
{
id: "1",
title: "Ascending price",
isSelected: true,
value: "asc_price",
},
{
id: "2",
title: "Decreasing price",
isSelected: false,
value: "decr_price",
},
{
id: "3",
title: "Ascending Squares",
isSelected: false,
value: "asc_sqr",
},
{
id: "4",
title: "Ascending Floor",
isSelected: false,
value: "asc_floor",
},
];
export {
initialAparmentTypeCheckboxes,
initialSliders,
initialSwitchers,
initialViewCheckboxes,
initialRoveHomeCheckboxes,
initialSortList,
};
-57
View File
@@ -1,57 +0,0 @@
import { ICheckbox } from "../types/checkbox";
import { IMultirangeSlider } from "../types/multirangeSlider";
import { ISwitcher } from "../types/switcher";
const initialSliders: IMultirangeSlider[] = [
{
minValue: 1048888,
startValue: 1048888,
endValue: 2408888,
maxValue: 2408888,
title: "Cost",
unit: "AED",
id: "1",
},
{
minValue: 341,
startValue: 341,
endValue: 891,
maxValue: 891,
title: "Total Area",
unit: "Sqrt",
id: "2",
},
{
minValue: 5,
startValue: 5,
endValue: 81,
maxValue: 81,
title: "Floor",
id: "3",
},
];
const initialApartmentTypeCheckboxes: ICheckbox[] = [
{ title: "Studio Flex", id: "1", selected: false },
{ title: "Studio", id: "2", selected: false },
{ title: "1 Bedroom", id: "3", selected: false },
{ title: "2 Bedroom", id: "4", selected: false },
];
const initialRoveHomeCheckboxes: ICheckbox[] = [
{ title: "Downtown", id: "1", disabled: false, selected: false },
{ title: "Marasi Drive", id: "2", selected: false },
{ title: "Dubai Marina", id: "3", selected: false },
];
const initialSwitchers: ISwitcher[] = [
{ id: "1", title: "Not the first floor", isSwitched: false },
{ id: "2", title: "Not the top floor", isSwitched: false },
];
export {
initialApartmentTypeCheckboxes,
initialSliders,
initialSwitchers,
initialRoveHomeCheckboxes,
};
+1 -25
View File
@@ -1,5 +1,4 @@
import { ILayoutCard } from "../types/layoutCard";
import { ISort } from "../types/sortType";
const layoutsCards: ILayoutCard[] = [
{
@@ -136,27 +135,4 @@ const layoutsCards: ILayoutCard[] = [
},
];
const initialSortList: ISort[] = [
{
id: "1",
title: "Ascending price",
isSelected: true,
},
{
id: "2",
title: "Decreasing price",
isSelected: false,
},
{
id: "3",
title: "Ascending Squares",
isSelected: false,
},
{
id: "4",
title: "Ascending Floor",
isSelected: false,
},
];
export { initialSortList, layoutsCards };
export { layoutsCards };
+1 -1
View File
@@ -4,7 +4,7 @@ import Button from "../components/Button";
import Footer from "../components/Footer";
import TrashIcon from "../components/icons/TrashIcon";
import SortButton from "../components/searchPage/SortButton";
import { initialSortList } from "../consts/initialSearchPage";
import { initialSortList } from "../consts/initialMasterplanFilters";
import { ILayoutCard } from "../types/layoutCard";
import Switch from "../components/Switch";
import { ISwitcher } from "../types/switcher";
+22 -8
View File
@@ -1,18 +1,26 @@
import { create } from "zustand";
import { ICheckbox } from "../types/checkbox";
import {
initialApartmentTypeCheckboxes,
initialRoveHomeCheckboxes,
initialAparmentTypeCheckboxes,
initialSliders,
initialSwitchers,
} from "../consts/initialSearchFilters";
initialViewCheckboxes,
initialRoveHomeCheckboxes,
initialSortList,
} from "../consts/initialMasterplanFilters";
import { IMultirangeSlider } from "../types/multirangeSlider";
import { ISwitcher } from "../types/switcher";
import { initialViewCheckboxes } from "../consts/initialMasterplanFilters";
import { ISort } from "../types/sortType";
interface Store {
apartmentTypeCheckboxes: ICheckbox[];
viewCheckboxes: ICheckbox[];
sortList: ISort[];
page: number;
perPage: number;
setPage: (page: number) => void;
setPerPage: (perPage: number) => void;
setSortList: (sortList: ISort[]) => void;
setApartmentTypeCheckboxes: (typeCheckboxes: ICheckbox[]) => void;
setViewCheckboxes: (checkboxes: ICheckbox[]) => void;
roveHomeTypeCheckboxes: ICheckbox[];
@@ -24,19 +32,25 @@ interface Store {
}
const useSearchFilters = create<Store>((set) => ({
apartmentTypeCheckboxes: initialApartmentTypeCheckboxes,
apartmentTypeCheckboxes: initialAparmentTypeCheckboxes,
viewCheckboxes: initialViewCheckboxes,
roveHomeTypeCheckboxes: initialRoveHomeCheckboxes,
multirangeSliders: initialSliders,
switchers: initialSwitchers,
sortList: initialSortList,
page: 1,
perPage: 12,
setPerPage: (perPage) => set(() => ({ perPage: perPage })),
setPage: (page) => set(() => ({ page: page })),
setSortList: (sortList) => set(() => ({ sortList: sortList })),
setApartmentTypeCheckboxes: (typeCheckboxes) =>
set(() => ({ apartmentTypeCheckboxes: typeCheckboxes })),
setViewCheckboxes: (typeCheckboxes) =>
set(() => ({ viewCheckboxes: typeCheckboxes })),
roveHomeTypeCheckboxes: initialRoveHomeCheckboxes,
setRoveHomeTypeCheckboxes: (typeCheckboxes) =>
set(() => ({ roveHomeTypeCheckboxes: typeCheckboxes })),
multirangeSliders: initialSliders,
setMultirangeSliders: (multirangeSliders) =>
set(() => ({ multirangeSliders: multirangeSliders })),
switchers: initialSwitchers,
setSwitchers: (switchers) => set(() => ({ switchers: switchers })),
}));
+1
View File
@@ -3,6 +3,7 @@ interface ICheckbox {
id: string;
disabled?: boolean;
selected: boolean;
value: string;
}
export type { ICheckbox };
+1
View File
@@ -2,6 +2,7 @@ interface ISort {
id: string;
title: string;
isSelected: boolean;
value: string;
}
export type { ISort };
+5
View File
@@ -884,6 +884,11 @@
"@typescript-eslint/types" "7.6.0"
eslint-visitor-keys "^3.4.3"
"@uidotdev/usehooks@^2.4.1":
version "2.4.1"
resolved "https://registry.yarnpkg.com/@uidotdev/usehooks/-/usehooks-2.4.1.tgz#4b733eaeae09a7be143c6c9ca158b56cc1ea75bf"
integrity sha512-1I+RwWyS+kdv3Mv0Vmc+p0dPYH0DTRAo04HLyXReYBL9AeseDWUJyi4THuksBJcu9F0Pih69Ak150VDnqbVnXg==
"@ungap/structured-clone@^1.2.0":
version "1.2.0"
resolved "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz"
-1
View File
@@ -24,7 +24,6 @@ app.use(json());
app.use(morgan("combined", { stream: accessLogStream }));
app.use("/apartments", apartmentsRoute);
app.use("/updateAccessToken", updateAccessToken);
app.listen(port, () => {
+226 -82
View File
@@ -2,12 +2,28 @@ import { Router } from "express";
import { aparmentsApi, searchApartmentApi } from "../consts.js";
import { logger } from "../utils/logger.js";
interface IApartment {
Floor: number;
Property_Status: string;
Unit_Type: string;
Project_Name: string;
Suite_Area_Sqft: number;
Balcony_Area_Sqft: number;
No_Of_Bedrooms: number;
Unit_No: string;
id: string;
Total_Area_Sqft: number;
No_of_Bathrooms: number;
Property_Name: string;
Unit_View: string;
}
const router = Router();
async function getAllApartments(
page: number,
accessToken: string,
apartments: any[]
apartments: IApartment[]
) {
const response = await fetch(`${aparmentsApi}&page=${page}&per_page=200`, {
headers: {
@@ -31,109 +47,237 @@ async function getAllApartments(
return await getAllApartments(page + 1, accessToken, updatedApartment);
}
function filterApartments(
apartments: IApartment[],
roveHome?: string[],
apartmentType?: string[],
costBetween?: string[],
totalAreaBetween?: string[],
floorBetween?: string[],
views?: string[]
) {
const filteredApartments = apartments
.filter((apart) => {
// Rove home filter
if (!roveHome || roveHome.length === 0) {
return true;
}
if (roveHome.some((rove) => rove === apart.Project_Name)) {
return true;
}
return false;
})
.filter((apart) => {
// Apartment type filter
if (!apartmentType || apartmentType.length === 0) {
return true;
}
if (apartmentType.some((rove) => rove === apart.Unit_Type)) {
return true;
}
return false;
})
.filter((apart) => {
// Cost between filter еще не доступен тк нет цен
if (!costBetween || costBetween.length === 0) {
return true;
}
const leftCost = Number(costBetween[0]);
const rightCost = Number(costBetween[1]);
return true;
// if (costBetween.some((rove) => rove === apart.Unit_Type)) {
// return true;
// }
// return false;
})
.filter((apart) => {
// Total area filter
if (!totalAreaBetween || totalAreaBetween.length === 0) {
return true;
}
const leftArea = Number(totalAreaBetween[0]);
const rightArea = Number(totalAreaBetween[1]);
if (
(leftArea <= apart.Total_Area_Sqft &&
rightArea >= apart.Total_Area_Sqft) ||
(leftArea >= apart.Total_Area_Sqft &&
rightArea <= apart.Total_Area_Sqft)
) {
return true;
}
return false;
})
.filter((apart) => {
// Views filter
if (!views || views.length === 0) {
return true;
}
//view "Canal" "Amenities"
// Canal / Amenities
// разделение по / с пробелом и без
const apartViews = apart.Unit_View.split(" / ").join("/").split("/");
for (let i = 0; i < apartViews.length; i++) {
// Удаление Corner-
const withoutCorner =
apartViews[i].split("-").length > 1
? apartViews[i].split("-")[1]
: apartViews[i];
//удаление View
const withoutView = withoutCorner.replace(" View", "");
if (views.some((view) => view === withoutView)) {
return true;
}
}
return false;
})
.filter((apart) => {
// Floor filter
if (!floorBetween || floorBetween.length === 0) {
return true;
}
const leftFloor = Number(floorBetween[0]);
const rightFloor = Number(floorBetween[1]);
if (
(leftFloor <= apart.Floor && rightFloor >= apart.Floor) ||
(leftFloor >= apart.Floor && rightFloor <= apart.Floor)
) {
return true;
}
return false;
});
return filteredApartments;
}
router.get("/", async (req, res) => {
const accessToken = req?.headers?.authorization;
const {
per_page: perPage = 20,
page = 10,
per_page = 20,
page = 1,
rove_home = "",
apartment_type = "",
cost_between = "",
total_area_between = "",
floor_between = "",
views = "",
sort_by = "",
} = req.query;
let api = aparmentsApi;
if (!accessToken)
return res
.status(401)
.json({ message: "Отсутсвует access token", code: 401 });
try {
const allApartments = await getAllApartments(1, accessToken, []);
const filteredApartments = allApartments.slice(
page as number,
perPage as number
);
const roveHomeFilter = (rove_home as string)
.split(",")
.filter((rove) => rove !== "");
const apartmentTypeFilter = (apartment_type as string)
.split(",")
.filter((rove) => rove !== "");
const costBetweenFilter = (cost_between as string)
.split(",")
.filter((cost) => cost !== "");
const totalAreaBetween = (total_area_between as string)
.split(",")
.filter((area) => area !== "");
const viewsFilter = (views as string)
.split(",")
.filter((view) => view !== "");
const floorBetweenFilter = (floor_between as string)
.split(",")
.filter((floor) => floor !== "");
res.status(200).json({
message: "ok",
apartments: filteredApartments,
code: 200,
});
if (!accessToken)
return res
.status(401)
.json({ message: "Отсутсвует access token", code: 401 });
try {
const allApartments = await getAllApartments(1, accessToken, []);
const filteredApartments = filterApartments(
allApartments,
roveHomeFilter,
apartmentTypeFilter,
costBetweenFilter,
totalAreaBetween,
floorBetweenFilter,
viewsFilter
);
const sortedApartments = [...filteredApartments].sort((a, b) => {
if (sort_by === "asc_price") {
return 1;
}
if (sort_by === "decr_price") {
return 1;
}
if (sort_by === "asc_sqr") {
return a.Total_Area_Sqft - b.Total_Area_Sqft;
}
if (sort_by === "asc_floor") {
return a.Floor - b.Floor;
}
return 1;
});
const slicedApartments = sortedApartments.slice(
((page as number) - 1) * (per_page as number),
per_page as number
);
console.log("slicedApartments", slicedApartments);
res.status(200).json({
message: "ok",
apartments: slicedApartments,
code: 200,
});
return;
} catch (error) {
if (
(error as Error).message === "invalid oauth token" ||
(error as Error).message === "INVALID_TOKEN"
) {
console.log("error", error);
logger.error(error);
return res
.status(401)
.json({ message: "Неправильный токен или токен устарел", code: 401 });
}
return;
} catch (error) {
if (
(error as Error).message === "invalid oauth token" ||
(error as Error).message === "INVALID_TOKEN"
) {
console.log("error", error);
logger.error(error);
return res
.status(401)
.json({ message: "Неправильный токен или токен устарел", code: 401 });
return res.status(500).json({ message: "Server Error", code: 500 });
}
console.log("error", error);
} catch (error) {
logger.error(error);
return res.status(500).json({ message: "Server Error", code: 500 });
console.log("error", error);
}
});
// router.get("/", async (req, res) => {
// const accessToken = req.headers.authorization;
// const { perPage, criteria } = req.query;
// let api = perPage || criteria ? searchApartmentApi : aparmentsApi;
// if (criteria) {
// api = `${api}&criteria=${criteria}`;
// }
// console.log("api", api);
// if (!accessToken)
// return res
// .status(401)
// .json({ message: "Отсутсвует access token", code: 401 });
// try {
// const apartments = await fetch(api, {
// headers: {
// Authorization: accessToken,
// },
// });
// const result = await apartments.json();
// if (result?.code && result?.code === "INVALID_TOKEN") {
// return res.status(401).json({ code: 401, message: "INVALID_TOKEN" });
// }
// res.status(200).json({ message: "ok", apartments: result, code: 200 });
// return;
// } catch (error) {
// if ((error as Error).message === "invalid oauth token") {
// console.log("error", error);
// logger.error(error);
// return res
// .status(401)
// .json({ message: "Неправильный токен или токен устарел", code: 401 });
// }
// console.log("error", error);
// logger.error(error);
// return res.status(500).json({ message: "Server Error", code: 500 });
// }
// });
const apartmentsRoute = router;
export default apartmentsRoute;