254 lines
8.9 KiB
TypeScript
254 lines
8.9 KiB
TypeScript
"use client";
|
|
import AnimatedContainer from "@components/AnimatedConainer/AnimatedContainer";
|
|
import ProductItem, { FindResultsViewMode } from "@core/app/components/ProductItem/ProductItem";
|
|
import { PublicServicesResults } from "@models/Service.model";
|
|
import { useEffect, useState } from "react";
|
|
import { searchPublicServices } from "./Find.Service";
|
|
import { HEADER_WIDGETS, useHeaderStore } from "@core/Store/Header.Store";
|
|
import Filters from "@core/app/components/Home/Filters/Filters";
|
|
import { useEventHandlerStore, EVENT_TYPES } from "@core/Store/EventHandler.Store";
|
|
import { useAlert } from "@core/Store/Alert.Store";
|
|
import { Breadcrumbs, ButtonGroup, IconButton } from "@mui/material";
|
|
import Link from "next/link";
|
|
import GridViewOutlinedIcon from "@mui/icons-material/GridViewOutlined";
|
|
import SplitscreenOutlinedIcon from "@mui/icons-material/SplitscreenOutlined";
|
|
import FilterAltIcon from "@mui/icons-material/FilterAlt";
|
|
import Pagination from "@mui/material/Pagination";
|
|
import useWindowSize from "@core/app/hooks/WindowSize";
|
|
import { ScrollToTop } from "@core/app/components/ScrollTop";
|
|
import DefaultLoginAction from "@core/app/components/LoginAction/DefaultLoginAction";
|
|
|
|
export default function FindPage() {
|
|
const headerState = useHeaderStore();
|
|
const eventHandler = useEventHandlerStore();
|
|
const alert = useAlert();
|
|
|
|
const [windowWidth] = useWindowSize();
|
|
|
|
const [filterPage, setFilterPage] = useState<number>(1);
|
|
const [filterCompany, setFilterCompany] = useState<string>("");
|
|
const [filterCategory, setFilterCategory] = useState<string>("");
|
|
const [filterLocation, setFilterLocation] = useState<string>("");
|
|
const [filterPriceFrom, setFilterPriceFrom] = useState<number | null>(null);
|
|
const [filterPriceTo, setFilterPriceTo] = useState<number | null>(null);
|
|
const [filterDurationFrom, setFilterDurationFrom] = useState<number | null>(null);
|
|
const [filterDurationTo, setFilterDurationTo] = useState<number | null>(null);
|
|
|
|
const [viewMode, setViewMode] = useState<FindResultsViewMode>("card");
|
|
const [filterVisible, setFilterVisible] = useState<boolean>(true);
|
|
|
|
const [services, setServices] = useState<PublicServicesResults>({
|
|
data: [],
|
|
page: filterPage,
|
|
pages: 0,
|
|
});
|
|
|
|
const getFilter = () => {
|
|
let filter = {};
|
|
|
|
if (filterCompany) {
|
|
filter = { ...filter, ...{ companyId: filterCompany } };
|
|
}
|
|
|
|
if (filterCategory) {
|
|
filter = { ...filter, ...{ categoryId: parseInt(filterCategory) } };
|
|
}
|
|
|
|
if (filterLocation) {
|
|
filter = { ...filter, ...{ block: filterLocation } };
|
|
}
|
|
|
|
if (filterPriceFrom) {
|
|
filter = { ...filter, ...{ priceFrom: filterPriceFrom } };
|
|
}
|
|
|
|
if (filterPriceTo) {
|
|
filter = { ...filter, ...{ priceTo: filterPriceTo } };
|
|
}
|
|
|
|
if (filterDurationFrom) {
|
|
filter = { ...filter, ...{ lengthFrom: filterDurationFrom } };
|
|
}
|
|
|
|
if (filterDurationTo) {
|
|
filter = { ...filter, ...{ lengthTo: filterDurationTo } };
|
|
}
|
|
return filter;
|
|
};
|
|
|
|
const cargarServicios = () => {
|
|
eventHandler.setEventType(EVENT_TYPES.LOADING);
|
|
|
|
const data = getFilter();
|
|
|
|
searchPublicServices({
|
|
...{
|
|
query: headerState.publicFindText,
|
|
page: filterPage,
|
|
limit: 20,
|
|
},
|
|
...data,
|
|
})
|
|
.then((res) => {
|
|
setServices(res);
|
|
})
|
|
.catch((error) => {
|
|
alert.showError(error.format());
|
|
})
|
|
.finally(() => {
|
|
headerState.setPublicFindTrigger(false);
|
|
eventHandler.setEventType(EVENT_TYPES.SLEEP);
|
|
});
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (headerState.publicFindTrigger) {
|
|
cargarServicios();
|
|
}
|
|
}, [
|
|
headerState.publicFindTrigger,
|
|
filterCompany,
|
|
filterCategory,
|
|
filterLocation,
|
|
filterPriceFrom,
|
|
filterPriceTo,
|
|
filterDurationFrom,
|
|
filterDurationTo,
|
|
filterPage,
|
|
]);
|
|
|
|
useEffect(() => {
|
|
if (windowWidth < 850) {
|
|
setFilterVisible(false);
|
|
return;
|
|
}
|
|
|
|
setFilterVisible(true);
|
|
}, [windowWidth]);
|
|
|
|
useEffect(() => {
|
|
if (windowWidth < 850) {
|
|
setViewMode("grid");
|
|
return;
|
|
}
|
|
|
|
setViewMode("card");
|
|
headerState.setActiveWidget(HEADER_WIDGETS.PUBLIC_FIND);
|
|
}, []);
|
|
|
|
const handleChange = (event: React.ChangeEvent<unknown>, value: number) => {
|
|
setFilterPage(value);
|
|
headerState.setPublicFindTrigger(true);
|
|
};
|
|
|
|
return (
|
|
<AnimatedContainer
|
|
color="#aeaeae"
|
|
minSize={150}
|
|
maxSize={500}
|
|
items={10}
|
|
style={{
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
justifyContent: "center",
|
|
alignItems: "center",
|
|
}}
|
|
>
|
|
<ScrollToTop />
|
|
<DefaultLoginAction />
|
|
<div
|
|
className="homeCentered"
|
|
style={{
|
|
display: "flex",
|
|
justifyContent: "space-between",
|
|
paddingLeft: "40px",
|
|
}}
|
|
>
|
|
<Breadcrumbs
|
|
aria-label="breadcrumb"
|
|
sx={{
|
|
"& .MuiBreadcrumbs-separator": {
|
|
color: "inherit",
|
|
},
|
|
marginTop: "15px",
|
|
}}
|
|
>
|
|
<Link href="/">Inicio</Link>
|
|
<span>Buscar servicios</span>
|
|
</Breadcrumbs>
|
|
<ButtonGroup
|
|
variant="outlined"
|
|
aria-label="Basic button group"
|
|
sx={{ marginTop: "10px", marginRight: "30px" }}
|
|
>
|
|
{windowWidth < 850 && (
|
|
<IconButton onClick={() => setFilterVisible(!filterVisible)}>
|
|
<FilterAltIcon
|
|
sx={{ color: filterVisible ? "var(--wine-red)" : "ineherit" }}
|
|
/>
|
|
</IconButton>
|
|
)}
|
|
<IconButton onClick={() => setViewMode("card")}>
|
|
<GridViewOutlinedIcon
|
|
sx={{ color: viewMode === "card" ? "var(--wine-red)" : "ineherit" }}
|
|
/>
|
|
</IconButton>
|
|
<IconButton onClick={() => setViewMode("grid")}>
|
|
<SplitscreenOutlinedIcon
|
|
sx={{ color: viewMode === "grid" ? "var(--wine-red)" : "ineherit" }}
|
|
/>
|
|
</IconButton>
|
|
</ButtonGroup>
|
|
</div>
|
|
<div
|
|
className="homeCentered"
|
|
style={{
|
|
paddingTop: "10px",
|
|
paddingLeft: "37px",
|
|
paddingRight: "0px",
|
|
paddingBottom: "0px",
|
|
display: "flex",
|
|
flexDirection: "row",
|
|
justifyContent: "start",
|
|
gap: "20px",
|
|
minHeight: "700px",
|
|
}}
|
|
>
|
|
<Filters
|
|
onFilter={cargarServicios}
|
|
setFilterCompany={setFilterCompany}
|
|
setFilterCategory={setFilterCategory}
|
|
setFilterLocation={setFilterLocation}
|
|
setFilterDurationFrom={setFilterDurationFrom}
|
|
setFilterDurationTo={setFilterDurationTo}
|
|
setFilterPriceFrom={setFilterPriceFrom}
|
|
setFilterPriceTo={setFilterPriceTo}
|
|
visible={filterVisible}
|
|
/>
|
|
<div
|
|
style={{
|
|
padding: "0px 0px 40px 0px",
|
|
display: "flex",
|
|
flexDirection: viewMode === "card" ? "row" : "column",
|
|
justifyContent: "start",
|
|
gap: "20px",
|
|
flexWrap: "wrap",
|
|
}}
|
|
>
|
|
{services.data.map((service) => (
|
|
<ProductItem
|
|
product={service}
|
|
key={service.id}
|
|
width={260}
|
|
viewMode={viewMode}
|
|
/>
|
|
))}
|
|
</div>
|
|
</div>
|
|
<div style={{ display: "flex", justifyContent: "center", marginBottom: "20px" }}>
|
|
<Pagination count={services.pages} variant="outlined" onChange={handleChange} />
|
|
</div>
|
|
</AnimatedContainer>
|
|
);
|
|
}
|