Skip to content

Commit

Permalink
Merge pull request #17 from AlbuquerqueRafael/feat/filters-2
Browse files Browse the repository at this point in the history
feat: Adição do componente de filtros
  • Loading branch information
fagundesjg authored May 9, 2024
2 parents 384fc8d + 0555f27 commit 359b2a1
Show file tree
Hide file tree
Showing 13 changed files with 779 additions and 3,633 deletions.
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v18.19.1
3,932 changes: 334 additions & 3,598 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"react-hook-form": "^7.51.4",
"react-input-mask": "^2.0.4",
"react-router-dom": "^6.23.0",
"react-select": "^5.8.0",
"tailwind-merge": "^2.3.0",
"tailwindcss-animate": "^1.0.7",
"yup": "^1.4.0",
Expand Down
5 changes: 5 additions & 0 deletions src/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,9 @@
margin: 0;
padding: 0;
}

#root {
max-width: 100vw;
overflow-x: hidden;
}
}
1 change: 1 addition & 0 deletions src/hooks/usePaginatedQuery/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export interface IPaginatedResponse<T = any> {
page: number;
perPage: number;
results: T[];
filters?: any
}
10 changes: 10 additions & 0 deletions src/hooks/useShelters/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,13 @@ export interface IUseSheltersDataSupplyData {
supply: { name: string };
priority: number;
}

export interface IUseShelterSearchParams {
priority: number | undefined;
supplies: string[] | undefined;
supplyCategories: number[] | undefined;
search: string | undefined;
filterAvailableShelter: boolean;
filterUnavailableShelter: boolean;
waitingShelterAvailability: boolean;
}
65 changes: 56 additions & 9 deletions src/hooks/useShelters/useShelters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { AxiosRequestConfig } from 'axios';

import { api } from '@/api';
import { IServerResponse } from '@/types';
import { PaginatedQueryPath } from '../usePaginatedQuery/paths';
import { IPaginatedResponse } from '../usePaginatedQuery/types';
import { IUseSheltersData } from './types';

Expand All @@ -14,14 +13,40 @@ const useShelters = () => {
page: 1,
perPage: 20,
results: [],
filters: {
search: '',
priority: undefined,
supplies: [],
supplyCategories: [],
filterAvailableShelter: false,
filterUnavailableShelter: false,
waitingShelterAvailability: false
}
});

const refresh = useCallback(
const resetSearch = () => {
const params = {
search: '',
priority: undefined,
supplies: [],
supplyCategories: [],
filterAvailableShelter: false,
filterUnavailableShelter: false,
waitingShelterAvailability: false,
page: 1,
perPage: 20,
}
search({
params: params,
});
}

const search = useCallback(
(config: AxiosRequestConfig<any> = {}, append: boolean = false) => {
if (!append) setLoading(true);
api
.get<IServerResponse<IPaginatedResponse<IUseSheltersData>>>(
PaginatedQueryPath.Shelters,
.get<IServerResponse<any>>(
'/shelters/search',
{
...config,
params: {
Expand All @@ -37,23 +62,45 @@ const useShelters = () => {
...prev,
...data.data,
results: [...prev.results, ...data.data.results],
filters: {
search: '',
priority: config.params.priority,
supplies: config.params.supplies ?? [],
supplyCategories: config.params.supplyCategories ?? [],
filterAvailableShelter: config.params.filterAvailableShelter ?? false,
filterUnavailableShelter: config.params.filterUnavailableShelter ?? false,
waitingShelterAvailability: config.params.waitingShelterAvailability ?? false,
}
}));
} else {
setData(data.data);
setData((prev) => ({
...prev,
...data.data,
results: [...data.data.results],
filters: {
search: config.params.search,
priority: config.params.priority,
supplies: config.params.supplies ?? [],
supplyCategories: config.params.supplyCategories ?? [],
filterAvailableShelter: config.params.filterAvailableShelter ?? false,
filterUnavailableShelter: config.params.filterUnavailableShelter ?? false,
waitingShelterAvailability: config.params.waitingShelterAvailability ?? false,
}
}));
}
})
.finally(() => {
if (!append) setLoading(false);
if(!append) setLoading(false);
});
},
[]
);

useEffect(() => {
refresh();
}, [refresh]);
resetSearch();
}, []);

return { data, loading, refresh };
return { data, loading, search, resetSearch };
};

export { useShelters };
84 changes: 58 additions & 26 deletions src/pages/Home/Home.tsx
Original file line number Diff line number Diff line change
@@ -1,72 +1,86 @@
import { Fragment, useCallback, useContext, useMemo, useState } from 'react';
import {
RotateCw,
CircleAlert,
Search,
Loader,
LogOutIcon,
Heart,
} from 'lucide-react';
import { RotateCw, CircleAlert, Search, Loader, ListFilter, LogOutIcon, Heart } from 'lucide-react';

import { Alert, Header, NoFoundSearch, ShelterListItem } from '@/components';
import { Input } from '@/components/ui/input';
import { useShelters, useThrottle } from '@/hooks';
import { Button } from '@/components/ui/button';
import { SessionContext } from '@/contexts';
import { Filter } from './components/Filter';
import { IUseShelterSearchParams } from '@/hooks/useShelters/types';

const alertDescription =
'Você pode consultar a lista de abrigos disponíveis. Ver e editar os itens que necessitam de doações.';

const Home = () => {
const { data: shelters, loading, refresh } = useShelters();
const { data: shelters, loading, search, resetSearch } = useShelters();
const {
loading: loadingSession,
refreshSession,
session,
} = useContext(SessionContext);
const [searchValue, setSearchValue] = useState<string>('');
const [isModalOpen, setOpenModal] = useState<boolean>(false);
const [, setSearch] = useThrottle<string>(
{
throttle: 400,
callback: (v) => {
const params = {
search: `address:contains:${v},name:contains:${v}`,
or: 'true',
...shelters.filters,
search: v ? v : '',
page: shelters.page,
perPage: shelters.perPage,
};
refresh({
params: v ? params : {},

search({
params: params,
});
},
},
[]
);

const clearSearch = () => {
setSearchValue('');
resetSearch();
}

const hasMore = useMemo(
() => shelters.page * shelters.perPage < shelters.count,
[shelters.page, shelters.perPage, shelters.count]
);

const closeModal = () => {
setOpenModal(false);
}

const handleSearch = (values: IUseShelterSearchParams) => {
setOpenModal(false);
setSearchValue(values.search ?? '');
search({
params: {
...values
}
});
}

const handleFetchMore = useCallback(() => {
const params = {
...shelters.filters,
page: shelters.page + 1,
perPage: shelters.perPage,
search: searchValue ? searchValue : '',
};

if (searchValue)
Object.assign(params, {
search: `address:contains:${searchValue},name:contains:${searchValue}`,
or: 'true',
});
search({
params: params,
}, true);

refresh(
{
params,
},
true
);
}, [refresh, searchValue, shelters.page, shelters.perPage]);
}, [search, searchValue, shelters.filters, shelters.page, shelters.perPage]);

return (
<div className="flex flex-col h-screen items-center">
{isModalOpen && <Filter handleSearch={handleSearch} isModalOpen={isModalOpen} closeModal={closeModal} filters={shelters.filters} />}
<Header
title="SOS Rio Grande do Sul"
endAdornment={
Expand All @@ -80,7 +94,7 @@ const Home = () => {
loading={loading}
variant="ghost"
size="sm"
onClick={() => refresh()}
onClick={() => search()}
className="disabled:bg-red-500 hover:bg-red-400"
>
<RotateCw size={20} className="stroke-white" />
Expand Down Expand Up @@ -126,6 +140,24 @@ const Home = () => {
<Search name="search" size="20" className="stroke-zinc-300" />
</div>
</div>
<div className="flex flex-row">
<Button variant="ghost" size="sm"
className="flex gap-2 items-center [&_svg]:stroke-blue-500"
onClick={() => setOpenModal(true)}>
<ListFilter className="h-5 w-5" />
<h1 className="font-semibold text-[16px] text-blue-500">
Filtros
</h1>
</Button>
<Button variant="ghost" size="sm"
className="flex gap-2 items-center [&_svg]:stroke-blue-500"
onClick={() => clearSearch()}>
<CircleAlert className="h-5 w-5" />
<h1 className="font-semibold text-[16px] text-blue-500">
Limpar Filtros
</h1>
</Button>
</div>
<main className="flex flex-col gap-4">
{loading ? (
<Loader className="justify-self-center self-center w-5 h-5 animate-spin" />
Expand Down
Loading

0 comments on commit 359b2a1

Please sign in to comment.