Skip to content

Commit 0d1cdf1

Browse files
author
ci-bot
committed
fix styles. add logo update helpers.tsx
1 parent 4eaee65 commit 0d1cdf1

File tree

13 files changed

+636
-305
lines changed

13 files changed

+636
-305
lines changed
24 KB
Loading

libs/remix-ui/app/src/lib/remix-app/remix-app.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,9 @@ const RemixApp = (props: IRemixAppUi) => {
5959
okFn: () => { },
6060
cancelLabel: 'Default Cancel Label',
6161
cancelFn: () => { },
62-
width: '892px',
63-
height: '768px'
62+
width: '640px',
63+
height: '720px',
64+
showModal: true
6465
}
6566
})
6667

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
import React, { createContext, useContext, useEffect, useMemo, useReducer, useState } from 'react'
2+
import { TemplateCategory, TemplateExplorerContextType, TemplateExplorerWizardAction, TemplateItem } from '../types/template-explorer-types'
3+
import { initialState, templateExplorerReducer } from '../reducers/template-explorer-reducer'
4+
import { metadata, templatesRepository } from '../src/utils/helpers'
5+
import { AppContext } from '@remix-ui/app'
6+
7+
export const TemplateExplorerContext = createContext<TemplateExplorerContextType>({} as any)
8+
9+
export const TemplateExplorerProvider = ({ children }: { children: React.ReactNode }) => {
10+
// const [templateRepository, setTemplateRepository] = useState<TemplateCategory[]>([])
11+
// const [metadata, setMetadata] = useState<any[]>([])
12+
// const [selectedTag, setSelectedTag] = useState<string | null>(null)
13+
// const [recentBump, setRecentBump] = useState<number>(0)
14+
const [state, dispatch] = useReducer(templateExplorerReducer, initialState)
15+
const appContext = useContext(AppContext)
16+
17+
useEffect(() => {
18+
dispatch({ type: TemplateExplorerWizardAction.SET_METADATA, payload: metadata })
19+
dispatch({ type: TemplateExplorerWizardAction.SET_TEMPLATE_REPOSITORY, payload: templatesRepository })
20+
21+
}, [])
22+
23+
const allTags = useMemo((): string[] => {
24+
const tags: string[] = []
25+
26+
if (state.templateRepository && Array.isArray(state.templateRepository)) {
27+
state.templateRepository.forEach((template: any) => {
28+
if (template && template.items && Array.isArray(template.items)) {
29+
template.items.forEach((item: any) => {
30+
if (item && item.tagList && Array.isArray(item.tagList)) {
31+
item.tagList.forEach((tag: string) => {
32+
if (typeof tag === 'string' && !tags.includes(tag)) {
33+
tags.push(tag)
34+
}
35+
})
36+
}
37+
})
38+
}
39+
})
40+
}
41+
42+
return tags.sort()
43+
}, [])
44+
45+
// Recent templates (before filteredTemplates so it can be referenced later)
46+
const recentTemplates = useMemo((): TemplateItem[] => {
47+
try {
48+
const raw = typeof window !== 'undefined' ? window.localStorage.getItem(RECENT_KEY) : null
49+
const list: string[] = raw ? JSON.parse(raw) : []
50+
const items: TemplateItem[] = []
51+
if (Array.isArray(state.templateRepository)) {
52+
list.forEach((val) => {
53+
for (const group of state.templateRepository as any[]) {
54+
if (group && Array.isArray(group.items)) {
55+
const found = group.items.find((it: any) => it && it.value === val)
56+
if (found) {
57+
items.push(found)
58+
break
59+
}
60+
}
61+
}
62+
})
63+
}
64+
//tag filter
65+
const filtered = state.selectedTag
66+
? items.filter((it: any) => it && Array.isArray(it.tagList) && it.tagList.includes(state.selectedTag))
67+
: items
68+
return filtered
69+
} catch (e) {
70+
return []
71+
}
72+
}, [state.selectedTag, state.recentBump])
73+
74+
// Filter templates based on selected tag
75+
const filteredTemplates = useMemo((): TemplateCategory[] => {
76+
if (!state.selectedTag || !state.templateRepository || !Array.isArray(state.templateRepository)) {
77+
return state.templateRepository as TemplateCategory[] || []
78+
}
79+
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)
84+
)
85+
})).filter((template: any) => template && template.items && template.items.length > 0)
86+
}, [state.selectedTag])
87+
88+
// Dedupe templates across the whole page and avoid showing ones already in recents
89+
const dedupedTemplates = useMemo((): TemplateCategory[] => {
90+
const recentSet = new Set<string>((recentTemplates || []).map((t: any) => t && t.value))
91+
const seen = new Set<string>()
92+
const makeUniqueItems = (items: any[]) => {
93+
const unique: any[] = []
94+
for (const it of items || []) {
95+
const val = it && it.value
96+
if (!val) continue
97+
if (recentSet.has(val)) continue
98+
if (seen.has(val)) continue
99+
seen.add(val)
100+
unique.push(it)
101+
}
102+
return unique
103+
}
104+
return (filteredTemplates || []).map((group: any) => ({
105+
...group,
106+
items: makeUniqueItems(group && group.items ? group.items : [])
107+
})).filter((g: any) => g && g.items && g.items.length > 0)
108+
}, [filteredTemplates, recentTemplates])
109+
110+
const handleTagClick = (tag: string) => {
111+
dispatch({ type: TemplateExplorerWizardAction.SET_SELECTED_TAG, payload: state.selectedTag === tag ? null : tag })
112+
}
113+
114+
const clearFilter = () => {
115+
dispatch({ type: TemplateExplorerWizardAction.SET_SELECTED_TAG, payload: null })
116+
}
117+
118+
const RECENT_KEY = 'remix.recentTemplates'
119+
120+
const addRecentTemplate = (template: TemplateItem) => {
121+
try {
122+
const raw = typeof window !== 'undefined' ? window.localStorage.getItem(RECENT_KEY) : null
123+
const list: string[] = raw ? JSON.parse(raw) : []
124+
const filtered = list.filter((v) => v !== template.value)
125+
filtered.unshift(template.value)
126+
const trimmed = filtered.slice(0, 4)
127+
if (typeof window !== 'undefined') window.localStorage.setItem(RECENT_KEY, JSON.stringify(trimmed))
128+
dispatch({ type: TemplateExplorerWizardAction.SET_RECENT_BUMP, payload: state.recentBump + 1 })
129+
} catch (e) {
130+
131+
}
132+
}
133+
134+
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}
137+
</TemplateExplorerContext.Provider>
138+
)
139+
}
Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,49 @@
11
import React from 'react'
2-
import { TemplateExplorerWizardState, TemplateExplorerWizardSteps } from '../types/template-explorer-types'
2+
import { MetadataType, TemplateExplorerWizardAction, TemplateExplorerWizardState, TemplateExplorerWizardSteps } from '../types/template-explorer-types'
3+
import { metadata, templatesRepository } from '../src/utils/helpers'
34

4-
const initialState: TemplateExplorerWizardState = {
5+
export const initialState: TemplateExplorerWizardState = {
56
steps: TemplateExplorerWizardSteps.SELECT_TEMPLATE,
67
workspaceTemplateChosen: '',
78
workspaceTemplateGroupChosen: '',
89
workspaceName: '',
910
defaultWorkspaceName: '',
1011
topLeftNagivationName: '',
11-
initializeAsGitRepo: false
12+
initializeAsGitRepo: false,
13+
workspaceGeneratedWithAi: false,
14+
searchTerm: '',
15+
metadata: metadata as MetadataType,
16+
templateRepository: templatesRepository,
17+
selectedTag: null
1218
}
1319

1420
export const templateExplorerReducer = (state: TemplateExplorerWizardState, action: any) => {
1521
switch (action.type) {
16-
case 'SET_TEMPLATE_EXPLORER':
22+
case TemplateExplorerWizardAction.SET_WORKSPACE_TEMPLATE:
1723
return action.payload
24+
case TemplateExplorerWizardAction.SET_WORKSPACE_TEMPLATE_WIZARD_STEP:
25+
return action.payload
26+
case TemplateExplorerWizardAction.SET_WORKSPACE_TEMPLATE_GROUP:
27+
return action.payload
28+
case TemplateExplorerWizardAction.SET_WORKSPACE_NAME:
29+
return action.payload
30+
case TemplateExplorerWizardAction.SET_DEFAULT_WORKSPACE_NAME:
31+
return action.payload
32+
case TemplateExplorerWizardAction.SET_TOP_LEFT_NAVIGATION_NAME:
33+
return action.payload
34+
case TemplateExplorerWizardAction.SET_INITIALIZE_AS_GIT_REPO:
35+
return action.payload
36+
case TemplateExplorerWizardAction.SET_WORKSPACE_GENERATED_WITH_AI:
37+
return action.payload
38+
case TemplateExplorerWizardAction.END_WORKSPACE_WIZARD:
39+
return action.payload
40+
case TemplateExplorerWizardAction.SET_SELECTED_TAG: {
41+
return { ...state, selectedTag: action.payload }
42+
}
43+
case TemplateExplorerWizardAction.CLEAR_SELECTED_TAG: {
44+
return { ...state, selectedTag: null }
45+
}
46+
default:
47+
return state
1848
}
1949
}

libs/remix-ui/template-explorer-modal/src/components/template-explorer-body.tsx

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import React from 'react'
2-
import { TopCard, TopCardProps } from './topCard'
2+
import { TopCard } from './topCard'
3+
import { TopCardProps } from '../../types/template-explorer-types'
34
import { TemplateExplorer } from './template-explorer'
5+
import { TopCards } from './topCards'
46

57
export interface TemplateExplorerBodyProps {
68
topCards: TopCardProps[]
@@ -10,15 +12,9 @@ export interface TemplateExplorerBodyProps {
1012
export function TemplateExplorerBody({ topCards, plugin }: TemplateExplorerBodyProps) {
1113
return (
1214
<section>
13-
<div className="title">
14-
{/* {props.appState.genericModalState.title && props.appState.genericModalState.title} {props.appState.genericModalState.title} */}
15-
<div className="d-flex flex-row gap-3 mx-auto">
16-
{topCards.map((card) => (
17-
<TopCard key={card.title} {...card} />
18-
))}
19-
</div>
20-
</div>
21-
<div className="body">
15+
<TopCards />
16+
<div className="body overflow-y-hidden">
17+
<label className="text-dark fs-5">Workspace Templates</label>
2218
<TemplateExplorer plugin={plugin} />
2319
</div>
2420
</section>

0 commit comments

Comments
 (0)