1+ /* eslint-disable @nrwl/nx/enforce-module-boundaries */
12import React , { createContext , useContext , useEffect , useMemo , useReducer , useState } from 'react'
23import { TemplateCategory , TemplateExplorerContextType , TemplateExplorerWizardAction , TemplateItem } from '../types/template-explorer-types'
34import { initialState , templateExplorerReducer } from '../reducers/template-explorer-reducer'
45import { metadata , templatesRepository } from '../src/utils/helpers'
56import { 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'
69
710export const TemplateExplorerContext = createContext < TemplateExplorerContextType > ( { } as any )
811
9- export const TemplateExplorerProvider = ( { children } : { children : React . ReactNode } ) => {
12+ export const TemplateExplorerProvider = ( props : { plugin : TemplateExplorerModalPlugin } ) => {
1013 // const [templateRepository, setTemplateRepository] = useState<TemplateCategory[]>([])
1114 // const [metadata, setMetadata] = useState<any[]>([])
1215 // const [selectedTag, setSelectedTag] = useState<string | null>(null)
1316 // const [recentBump, setRecentBump] = useState<number>(0)
1417 const [ state , dispatch ] = useReducer ( templateExplorerReducer , initialState )
1518 const appContext = useContext ( AppContext )
19+ const { plugin } = props
1620
1721 useEffect ( ( ) => {
18- dispatch ( { type : TemplateExplorerWizardAction . SET_METADATA , payload : metadata } )
1922 dispatch ( { type : TemplateExplorerWizardAction . SET_TEMPLATE_REPOSITORY , payload : templatesRepository } )
23+ } , [ ] )
2024
25+ useEffect ( ( ) => {
26+ dispatch ( { type : TemplateExplorerWizardAction . SET_METADATA , payload : metadata } )
2127 } , [ ] )
2228
29+ const setSearchTerm = ( term : string ) => {
30+ console . log ( 'setSearchTerm' , { term, state } )
31+ dispatch ( { type : TemplateExplorerWizardAction . SET_SEARCH_TERM , payload : term } )
32+ }
33+
2334 const allTags = useMemo ( ( ) : string [ ] => {
2435 const tags : string [ ] = [ ]
2536
@@ -42,7 +53,6 @@ export const TemplateExplorerProvider = ({ children }: { children: React.ReactNo
4253 return tags . sort ( )
4354 } , [ ] )
4455
45- // Recent templates (before filteredTemplates so it can be referenced later)
4656 const recentTemplates = useMemo ( ( ) : TemplateItem [ ] => {
4757 try {
4858 const raw = typeof window !== 'undefined' ? window . localStorage . getItem ( RECENT_KEY ) : null
@@ -71,21 +81,33 @@ export const TemplateExplorerProvider = ({ children }: { children: React.ReactNo
7181 }
7282 } , [ state . selectedTag , state . recentBump ] )
7383
74- // Filter templates based on selected tag
7584 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 )
7998
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
84108 )
85- } ) ) . filter ( ( template : any ) => template && template . items && template . items . length > 0 )
86- } , [ state . selectedTag ] )
109+ } , [ state . selectedTag , state . searchTerm , state . templateRepository ] )
87110
88- // Dedupe templates across the whole page and avoid showing ones already in recents
89111 const dedupedTemplates = useMemo ( ( ) : TemplateCategory [ ] => {
90112 const recentSet = new Set < string > ( ( recentTemplates || [ ] ) . map ( ( t : any ) => t && t . value ) )
91113 const seen = new Set < string > ( )
@@ -131,9 +153,15 @@ export const TemplateExplorerProvider = ({ children }: { children: React.ReactNo
131153 }
132154 }
133155
156+ const contextValue = { templateRepository : state . templateRepository , metadata : state . metadata , selectedTag : state . selectedTag , recentTemplates, filteredTemplates, dedupedTemplates, handleTagClick, clearFilter, addRecentTemplate, RECENT_KEY , allTags, plugin, setSearchTerm }
157+
134158 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+ />
137165 </ TemplateExplorerContext . Provider >
138166 )
139167}
0 commit comments