1
- import { ChevronLeft , PlusCircle } from 'lucide-react' ;
1
+ import { ChevronLeft } from 'lucide-react' ;
2
2
import { useNavigate , useParams } from 'react-router-dom' ;
3
3
import { Fragment , useCallback , useEffect , useMemo , useState } from 'react' ;
4
4
5
- import { DialogSelector , Header , LoadingScreen , TextField } from '@/components' ;
5
+ import { DialogSelector , Header , LoadingScreen } from '@/components' ;
6
6
import { Button } from '@/components/ui/button' ;
7
7
import { useShelter , useSupplies , useThrottle } from '@/hooks' ;
8
8
import { group , normalizedCompare } from '@/lib/utils' ;
9
- import { SupplyRow } from './components' ;
9
+ import { SupplyRow , SupplySearch } from './components' ;
10
10
import { IDialogSelectorProps } from '@/components/DialogSelector/types' ;
11
11
import { ISupplyRowItemProps } from './components/SupplyRow/types' ;
12
12
import { ShelterSupplyServices } from '@/service' ;
@@ -25,32 +25,58 @@ const EditShelterSupply = () => {
25
25
const [ filteredSupplies , setFilteredSupplies ] = useState < IUseSuppliesData [ ] > (
26
26
[ ]
27
27
) ;
28
- const [ searchValue , setSearchValue ] = useState < string > ( '' ) ;
28
+ const [ searchedSupplies , setSearchedSupplies ] = useState < IUseSuppliesData [ ] > (
29
+ [ ]
30
+ ) ;
31
+ const shelterSupplyData = useMemo ( ( ) => {
32
+ return ( shelter ?. shelterSupplies ?? [ ] ) . reduce (
33
+ ( prev , current ) => ( { ...prev , [ current . supply . id ] : current } ) ,
34
+ { } as Record < string , IUseShelterDataSupply >
35
+ ) ;
36
+ } , [ shelter ?. shelterSupplies ] ) ;
37
+
38
+ const [ , setSearchSupplies ] = useThrottle < string > (
39
+ {
40
+ throttle : 200 ,
41
+ callback : ( value ) => {
42
+ if ( value ) {
43
+ const filteredSupplies = supplies . filter ( ( s ) =>
44
+ normalizedCompare ( s . name , value )
45
+ ) ;
46
+ setSearchedSupplies ( filteredSupplies ) ;
47
+ } else {
48
+ setSearchedSupplies ( [ ] ) ;
49
+ setSearch ( '' ) ;
50
+ }
51
+ } ,
52
+ } ,
53
+ [ supplies ]
54
+ ) ;
55
+
29
56
const [ , setSearch ] = useThrottle < string > (
30
57
{
31
58
throttle : 400 ,
32
- callback : ( v ) => {
33
- if ( v ) {
34
- setFilteredSupplies (
35
- supplies . filter ( ( s ) => normalizedCompare ( s . name , v ) )
59
+ callback : ( value ) => {
60
+ if ( value ) {
61
+ const filteredSupplies = supplies . filter ( ( s ) =>
62
+ normalizedCompare ( s . name , value )
36
63
) ;
37
- } else setFilteredSupplies ( supplies ) ;
64
+ setFilteredSupplies ( filteredSupplies ) ;
65
+ } else {
66
+ const storedSupplies = supplies . filter ( ( s ) => ! ! shelterSupplyData [ s . id ] ) ;
67
+ setFilteredSupplies ( storedSupplies ) ;
68
+ }
38
69
} ,
39
70
} ,
40
- [ supplies ]
71
+ [ supplies , shelterSupplyData ]
41
72
) ;
42
73
const [ modalOpened , setModalOpened ] = useState < boolean > ( false ) ;
43
74
const [ loadingSave , setLoadingSave ] = useState < boolean > ( false ) ;
44
75
const [ modalData , setModalData ] = useState < Pick <
45
76
IDialogSelectorProps ,
46
77
'value' | 'onSave' | 'quantity'
47
78
> | null > ( ) ;
48
- const shelterSupplyData = useMemo ( ( ) => {
49
- return ( shelter ?. shelterSupplies ?? [ ] ) . reduce (
50
- ( prev , current ) => ( { ...prev , [ current . supply . id ] : current } ) ,
51
- { } as Record < string , IUseShelterDataSupply >
52
- ) ;
53
- } , [ shelter ?. shelterSupplies ] ) ;
79
+
54
80
const supplyGroups = useMemo (
55
81
( ) =>
56
82
group < IUseSuppliesData > ( filteredSupplies ?? [ ] , 'supplyCategory.name' ) ,
@@ -112,8 +138,9 @@ const EditShelterSupply = () => {
112
138
) ;
113
139
114
140
useEffect ( ( ) => {
115
- setFilteredSupplies ( supplies ) ;
116
- } , [ supplies ] ) ;
141
+ const storedSupplies = supplies . filter ( ( s ) => ! ! shelterSupplyData [ s . id ] ) ;
142
+ setFilteredSupplies ( storedSupplies ) ;
143
+ } , [ supplies , shelterSupplyData ] ) ;
117
144
118
145
if ( loading ) return < LoadingScreen /> ;
119
146
@@ -163,27 +190,26 @@ const EditShelterSupply = () => {
163
190
< div className = "p-4 flex flex-col max-w-5xl w-full gap-3 items-start" >
164
191
< h6 className = "text-2xl font-semibold" > Editar itens do abrigo</ h6 >
165
192
< p className = "text-muted-foreground" >
166
- Para cada item da lista abaixo, informe a disponibilidade no abrigo
167
- selecionado
193
+ Antes de adicionar um novo item, confira na busca abaixo se ele já não foi cadastrado.
168
194
</ p >
169
- < Button
170
- variant = "ghost"
171
- className = "flex gap-2 text-blue-500 [&_svg]:stroke-blue-500 font-medium text-lg hover:text-blue-600"
172
- onClick = { ( ) => navigate ( `/abrigo/${ shelterId } /item/cadastrar` ) }
173
- >
174
- < PlusCircle />
175
- Cadastrar novo item
176
- </ Button >
177
195
< div className = "w-full my-2" >
178
- < TextField
179
- label = "Buscar"
180
- value = { searchValue }
181
- onChange = { ( ev ) => {
182
- setSearchValue ( ev . target . value ) ;
183
- setSearch ( ev . target . value ) ;
196
+ < SupplySearch
197
+ supplyItems = { searchedSupplies }
198
+ limit = { 5 }
199
+ onSearch = { ( value ) =>
200
+ setSearchSupplies ( value )
201
+ }
202
+ onSelectItem = { ( item ) => {
203
+ setSearch ( item . name ) ;
204
+ setSearchedSupplies ( [ ] ) ;
184
205
} }
206
+ onAddNewItem = { ( ) => navigate ( `/abrigo/${ shelterId } /item/cadastrar` ) }
185
207
/>
186
208
</ div >
209
+
210
+ < p className = "text-muted-foreground mt-3" >
211
+ Para cada item da lista abaixo, informe a disponibilidade no abrigo selecionado.
212
+ </ p >
187
213
< div className = "flex flex-col gap-2 w-full my-4" >
188
214
{ Object . entries ( supplyGroups ) . map ( ( [ key , values ] , idx ) => {
189
215
const items : ISupplyRowItemProps [ ] = values
0 commit comments