1
+ import { useState } from 'react' ;
1
2
import { useQuery } from '@apollo/client' ;
2
3
import { useParams } from 'react-router-dom' ;
3
- import { Box , Flex , HStack , Link , Text } from '@chakra-ui/react' ;
4
+ import { Box , Flex , HStack , Input , Link , Text } from '@chakra-ui/react' ;
4
5
5
6
import { getCookbookUrl } from '../utils/urlUtils' ;
6
- import { GET_COOKBOOK_RECIPES } from '../graphql/queries' ;
7
+ import { GET_COOKBOOK_INFO , GET_COOKBOOK_RECIPES } from '../graphql/queries' ;
7
8
import { GET_USER_RECIPES_VARIABLES } from '../graphql/variables' ;
9
+ import { PAGE_QUERY_POLL_INTERVAL_IN_MS } from '../lib/constants' ;
8
10
import ViewCookbookSnippetsError from '../components/ViewCookbookSnippets/ViewCookbookSnippetsError' ;
9
11
import ViewCookbookSnippetsLoading from '../components/ViewCookbookSnippets/ViewCookbookSnippetsLoading' ;
10
12
import ViewCookbookSnippetsEmpty from '../components/ViewCookbookSnippets/ViewCookbookSnippetsEmpty' ;
@@ -14,72 +16,110 @@ import AvatarAndName from '../components/AvatarAndName';
14
16
import PrivacyAndVotes from '../components/PrivacyAndVotes' ;
15
17
import FormattedDate from '../components/FormattedDate' ;
16
18
import SnippetResults from '../components/SnippetResults/SnippetResults' ;
19
+ import SnippetResultsLoading from '../components/SnippetResults/SnippetResultsLoading' ;
17
20
18
21
export default function ViewCookbookSnippets ( ) {
19
22
const params = useParams ( ) ;
23
+ const [ searchTerm , setSearchTerm ] = useState ( '' ) ;
20
24
21
- const { data, loading, error } = useQuery ( GET_COOKBOOK_RECIPES , {
25
+ const {
26
+ data : cookbookInfoData ,
27
+ loading : cookbookInfoLoading ,
28
+ error : cookbookInfoError ,
29
+ } = useQuery ( GET_COOKBOOK_INFO , {
30
+ pollInterval : PAGE_QUERY_POLL_INTERVAL_IN_MS ,
31
+ variables : {
32
+ cookbookId : Number ( params . cookbookId ) ,
33
+ } ,
34
+ } ) ;
35
+
36
+ const {
37
+ data : cookbookSnippetData ,
38
+ loading : cookbookSnippetLoading ,
39
+ error : cookbookSnippetError ,
40
+ } = useQuery ( GET_COOKBOOK_RECIPES , {
41
+ pollInterval : PAGE_QUERY_POLL_INTERVAL_IN_MS ,
22
42
variables : {
23
43
cookbookId : Number ( params . cookbookId ) ,
24
44
...GET_USER_RECIPES_VARIABLES ,
45
+ name : searchTerm || null ,
46
+ } ,
47
+ context : {
48
+ debounceKey : 'view-cookbook-snippets' ,
25
49
} ,
26
50
} ) ;
27
51
28
- const cookbook = data ?. cookbook ;
52
+ const cookbook = cookbookInfoData ?. cookbook ;
53
+ const snippets = cookbookSnippetData ?. cookbook ?. recipes || [ ] ;
29
54
30
- if ( loading ) {
31
- return < ViewCookbookSnippetsLoading /> ;
32
- }
33
-
34
- if ( error || ! cookbook ) {
55
+ if ( cookbookInfoError || cookbook === null || cookbookSnippetError ) {
35
56
return < ViewCookbookSnippetsError /> ;
36
57
}
37
58
38
59
return (
39
60
< Box h = "full" >
40
61
{ /* INFO SECTION */ }
41
- < HStack
42
- alignItems = "center"
43
- bg = "neutral.25"
44
- _dark = { { bg : 'base.dark' } }
45
- h = "74px"
46
- w = "full"
47
- spacing = "space_16"
48
- >
49
- < BackButton />
62
+ { cookbookInfoLoading ? (
63
+ < ViewCookbookSnippetsLoading />
64
+ ) : (
65
+ < HStack
66
+ alignItems = "center"
67
+ bg = "neutral.25"
68
+ _dark = { { bg : 'base.dark' } }
69
+ h = "74px"
70
+ w = "full"
71
+ spacing = "space_16"
72
+ >
73
+ < BackButton />
50
74
51
- < Flex alignItems = "center" gridGap = "space_8" >
52
- < Text size = "sm" fontWeight = "bold" noOfLines = { 1 } >
53
- < Link
54
- isExternal
55
- variant = "subtle"
75
+ < Flex alignItems = "center" gridGap = "space_8" >
76
+ < Text size = "sm" fontWeight = "bold" noOfLines = { 1 } >
77
+ < Link
78
+ isExternal
79
+ variant = "subtle"
56
80
_focus = { { boxShadow : 'none' } }
57
- href = { getCookbookUrl ( cookbook . id ) }
58
- >
59
- { cookbook . name }
60
- </ Link >
61
- </ Text >
62
- < FavoriteCookbook
63
- isSubscribed = { cookbook . isSubscribed }
64
- cookbookId = { cookbook . id }
65
- />
66
- </ Flex >
81
+ href = { getCookbookUrl ( cookbook . id ) }
82
+ >
83
+ { cookbook . name }
84
+ </ Link >
85
+ </ Text >
86
+ < FavoriteCookbook
87
+ isSubscribed = { cookbook . isSubscribed }
88
+ cookbookId = { cookbook . id }
89
+ />
90
+ </ Flex >
67
91
68
- < AvatarAndName owner = { cookbook . owner } />
92
+ < AvatarAndName owner = { cookbook . owner } />
69
93
70
- < PrivacyAndVotes
71
- isPublic = { cookbook . isPublic }
72
- upvotes = { cookbook . upvotes }
73
- downvotes = { cookbook . downvotes }
74
- />
94
+ < PrivacyAndVotes
95
+ isPublic = { cookbook . isPublic }
96
+ upvotes = { cookbook . upvotes }
97
+ downvotes = { cookbook . downvotes }
98
+ />
99
+
100
+ < FormattedDate timestamp = { cookbook . creationTimestampMs } />
75
101
76
- < FormattedDate timestamp = { cookbook . creationTimestampMs } />
77
- </ HStack >
102
+ < Flex w = "full" flex = { 1 } justifyContent = "flex-end" >
103
+ < Input
104
+ minWidth = "200px"
105
+ maxWidth = "500px"
106
+ justifySelf = "flex-end"
107
+ mr = "space_16"
108
+ placeholder = "Search on this cookbook"
109
+ value = { searchTerm }
110
+ onChange = { ( e ) => setSearchTerm ( e . target . value ) }
111
+ />
112
+ </ Flex >
113
+ </ HStack >
114
+ ) }
78
115
79
- { ! cookbook . recipes || cookbook . recipes . length === 0 ? (
116
+ { /* eslint-disable-next-line no-nested-ternary */ }
117
+ { cookbookSnippetLoading ? (
118
+ < SnippetResultsLoading />
119
+ ) : snippets . length === 0 ? (
80
120
< ViewCookbookSnippetsEmpty />
81
121
) : (
82
- < SnippetResults results = { cookbook . recipes } />
122
+ < SnippetResults results = { snippets } />
83
123
) }
84
124
</ Box >
85
125
) ;
0 commit comments