1
+ /* eslint-disable @nrwl/nx/enforce-module-boundaries */
1
2
import React , { createContext , useContext , useEffect , useMemo , useReducer , useState } from 'react'
2
3
import { TemplateCategory , TemplateExplorerContextType , TemplateExplorerWizardAction , TemplateItem } from '../types/template-explorer-types'
3
4
import { initialState , templateExplorerReducer } from '../reducers/template-explorer-reducer'
4
5
import { metadata , templatesRepository } from '../src/utils/helpers'
5
6
import { AppContext } from '@remix-ui/app'
7
+ import { TemplateExplorerModalPlugin } from 'apps/remix-ide/src/app/plugins/remix-template-explorer-modal'
8
+ import { RemixUiTemplateExplorerModal } from '@remix-ui/template-explorer-modal'
6
9
7
10
export const TemplateExplorerContext = createContext < TemplateExplorerContextType > ( { } as any )
8
11
9
- export const TemplateExplorerProvider = ( { children } : { children : React . ReactNode } ) => {
12
+ export const TemplateExplorerProvider = ( props : { plugin : TemplateExplorerModalPlugin } ) => {
10
13
// const [templateRepository, setTemplateRepository] = useState<TemplateCategory[]>([])
11
14
// const [metadata, setMetadata] = useState<any[]>([])
12
15
// const [selectedTag, setSelectedTag] = useState<string | null>(null)
13
16
// const [recentBump, setRecentBump] = useState<number>(0)
14
17
const [ state , dispatch ] = useReducer ( templateExplorerReducer , initialState )
15
18
const appContext = useContext ( AppContext )
19
+ const { plugin } = props
16
20
17
21
useEffect ( ( ) => {
18
- dispatch ( { type : TemplateExplorerWizardAction . SET_METADATA , payload : metadata } )
19
22
dispatch ( { type : TemplateExplorerWizardAction . SET_TEMPLATE_REPOSITORY , payload : templatesRepository } )
23
+ } , [ ] )
20
24
25
+ useEffect ( ( ) => {
26
+ dispatch ( { type : TemplateExplorerWizardAction . SET_METADATA , payload : metadata } )
21
27
} , [ ] )
22
28
29
+ const setSearchTerm = ( term : string ) => {
30
+ console . log ( 'setSearchTerm' , { term, state } )
31
+ dispatch ( { type : TemplateExplorerWizardAction . SET_SEARCH_TERM , payload : term } )
32
+ }
33
+
23
34
const allTags = useMemo ( ( ) : string [ ] => {
24
35
const tags : string [ ] = [ ]
25
36
@@ -42,7 +53,6 @@ export const TemplateExplorerProvider = ({ children }: { children: React.ReactNo
42
53
return tags . sort ( )
43
54
} , [ ] )
44
55
45
- // Recent templates (before filteredTemplates so it can be referenced later)
46
56
const recentTemplates = useMemo ( ( ) : TemplateItem [ ] => {
47
57
try {
48
58
const raw = typeof window !== 'undefined' ? window . localStorage . getItem ( RECENT_KEY ) : null
@@ -71,21 +81,33 @@ export const TemplateExplorerProvider = ({ children }: { children: React.ReactNo
71
81
}
72
82
} , [ state . selectedTag , state . recentBump ] )
73
83
74
- // Filter templates based on selected tag
75
84
const filteredTemplates = useMemo ( ( ) : TemplateCategory [ ] => {
76
- if ( ! state . selectedTag || ! state . templateRepository || ! Array . isArray ( state . templateRepository ) ) {
77
- return state . templateRepository as TemplateCategory [ ] || [ ]
78
- }
85
+ const repo = ( state . templateRepository as TemplateCategory [ ] ) || [ ]
86
+ if ( ! Array . isArray ( repo ) ) return [ ]
87
+
88
+ const searchTerm = ( state . searchTerm || '' ) . trim ( ) . toLowerCase ( )
89
+ const selectedTag = state . selectedTag
90
+
91
+ return repo
92
+ . map ( ( template : TemplateCategory ) => ( {
93
+ ...template ,
94
+ items : ( template . items || [ ] ) . filter ( ( item : TemplateItem ) => {
95
+ // Filter by search term
96
+ const matchesSearch = ! searchTerm ||
97
+ ( item . displayName || item . value || '' ) . toLowerCase ( ) . includes ( searchTerm )
79
98
80
- return ( state . templateRepository as TemplateCategory [ ] ) . map ( ( template : any ) => ( {
81
- ...template ,
82
- items : template . items . filter ( ( item : any ) =>
83
- item && item . tagList && Array . isArray ( item . tagList ) && item . tagList . includes ( state . selectedTag )
99
+ // Filter by selected tag
100
+ const matchesTag = ! selectedTag ||
101
+ ( item . tagList && item . tagList . includes ( selectedTag ) )
102
+
103
+ return matchesSearch && matchesTag
104
+ } )
105
+ } ) )
106
+ . filter ( ( template : TemplateCategory ) =>
107
+ template && template . items && template . items . length > 0
84
108
)
85
- } ) ) . filter ( ( template : any ) => template && template . items && template . items . length > 0 )
86
- } , [ state . selectedTag ] )
109
+ } , [ state . selectedTag , state . searchTerm , state . templateRepository ] )
87
110
88
- // Dedupe templates across the whole page and avoid showing ones already in recents
89
111
const dedupedTemplates = useMemo ( ( ) : TemplateCategory [ ] => {
90
112
const recentSet = new Set < string > ( ( recentTemplates || [ ] ) . map ( ( t : any ) => t && t . value ) )
91
113
const seen = new Set < string > ( )
@@ -131,9 +153,15 @@ export const TemplateExplorerProvider = ({ children }: { children: React.ReactNo
131
153
}
132
154
}
133
155
156
+ const contextValue = { templateRepository : state . templateRepository , metadata : state . metadata , selectedTag : state . selectedTag , recentTemplates, filteredTemplates, dedupedTemplates, handleTagClick, clearFilter, addRecentTemplate, RECENT_KEY , allTags, plugin, setSearchTerm }
157
+
134
158
return (
135
- < TemplateExplorerContext . Provider value = { { templateRepository : state . templateRepository , metadata : state . metadata , selectedTag : state . selectedTag , recentTemplates, filteredTemplates, dedupedTemplates, handleTagClick, clearFilter, addRecentTemplate, RECENT_KEY , allTags } } >
136
- { children }
159
+ < TemplateExplorerContext . Provider value = { contextValue } >
160
+ < RemixUiTemplateExplorerModal
161
+ appState = { appContext . appState }
162
+ dispatch = { appContext . appStateDispatch }
163
+ plugin = { plugin }
164
+ />
137
165
</ TemplateExplorerContext . Provider >
138
166
)
139
167
}
0 commit comments