first commit
This commit is contained in:
@@ -0,0 +1,253 @@
|
||||
"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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user