@@ -5,7 +5,138 @@ import classNames from 'classnames';
55import { useCallback , useEffect , useRef } from 'react' ;
66import Input from 'apps/web/src/components/Input' ;
77import { createPortal } from 'react-dom' ;
8- import Link from 'next/link' ;
8+
9+ type SearchCategory = {
10+ category : string ;
11+ subCategories : SubCategory [ ] ;
12+ } ;
13+
14+ type SubCategory = {
15+ label : string ;
16+ href : string ;
17+ icon : string ;
18+ iconRotation ?: string ;
19+ onClick ?: ( ) => void ;
20+ } ;
21+
22+ const searchCategories : SearchCategory [ ] = [
23+ {
24+ category : 'Quickstart' ,
25+ subCategories : [
26+ {
27+ label : 'npm create onchain' ,
28+ href : '' ,
29+ icon : 'copy' ,
30+ onClick : ( ) => {
31+ const copyCreateOnchain = async ( ) => {
32+ try {
33+ await navigator . clipboard . writeText ( 'npm create onchain' ) ;
34+ } catch ( error ) {
35+ console . error ( 'Failed to copy to clipboard' , error ) ;
36+ }
37+ } ;
38+ void copyCreateOnchain ( ) ;
39+ } ,
40+ } ,
41+ ] ,
42+ } ,
43+ {
44+ category : 'Templates' ,
45+ subCategories : [
46+ {
47+ label : 'Launch an AI agent' ,
48+ href : 'https://replit.com/@CoinbaseDev/CDP-AgentKit#README.md' ,
49+ icon : 'diagonalUpArrow' ,
50+ } ,
51+ {
52+ label : 'Build an onchain store' ,
53+ href : 'https://onchain-commerce-template.vercel.app/' ,
54+ icon : 'diagonalUpArrow' ,
55+ } ,
56+ {
57+ label : 'Integrate crypto payments' ,
58+ href : 'https://replit.com/@KevinLeffew1/buy-me-a-coffee?v=1#README.md' ,
59+ icon : 'diagonalUpArrow' ,
60+ } ,
61+ ] ,
62+ } ,
63+ {
64+ category : 'Tools' ,
65+ subCategories : [
66+ {
67+ label : 'AgentKit' ,
68+ href : '/developers/agentkit' ,
69+ icon : 'backArrow' ,
70+ iconRotation : 'rotate-180' ,
71+ } ,
72+ {
73+ label : 'Base Appchains' ,
74+ href : '/developers/appchains' ,
75+ icon : 'backArrow' ,
76+ iconRotation : 'rotate-180' ,
77+ } ,
78+ {
79+ label : 'MiniKit' ,
80+ href : '/developers/minikit' ,
81+ icon : 'backArrow' ,
82+ iconRotation : 'rotate-180' ,
83+ } ,
84+ {
85+ label : 'OnchainKit' ,
86+ href : '/developers/onchainkit' ,
87+ icon : 'backArrow' ,
88+ iconRotation : 'rotate-180' ,
89+ } ,
90+ {
91+ label : 'Smart Wallet' ,
92+ href : '/developers/smartwallet' ,
93+ icon : 'backArrow' ,
94+ iconRotation : 'rotate-180' ,
95+ } ,
96+ {
97+ label : 'Verifications' ,
98+ href : '/developers/verifications' ,
99+ icon : 'backArrow' ,
100+ iconRotation : 'rotate-180' ,
101+ } ,
102+ ] ,
103+ } ,
104+ {
105+ category : 'Guides' ,
106+ subCategories : [
107+ {
108+ label : 'Onboard any users' ,
109+ href : '/developers/guides/onboarding' ,
110+ icon : 'diagonalUpArrow' ,
111+ } ,
112+ {
113+ label : 'Accept crypto payments' ,
114+ href : '/developers/guides/payments' ,
115+ icon : 'diagonalUpArrow' ,
116+ } ,
117+ {
118+ label : 'Launch AI Agents' ,
119+ href : '/developers/guides/agents' ,
120+ icon : 'diagonalUpArrow' ,
121+ } ,
122+ {
123+ label : 'Decentralized social features' ,
124+ href : '/developers/guides/social' ,
125+ icon : 'diagonalUpArrow' ,
126+ } ,
127+ {
128+ label : 'Defi your app' ,
129+ href : '/developers/guides/defi' ,
130+ icon : 'diagonalUpArrow' ,
131+ } ,
132+ {
133+ label : 'Remove first-timer friction' ,
134+ href : '/developers/guides/gasless' ,
135+ icon : 'diagonalUpArrow' ,
136+ } ,
137+ ] ,
138+ } ,
139+ ] ;
9140
10141export function SearchModal ( {
11142 isOpen,
@@ -22,17 +153,6 @@ export function SearchModal({
22153 }
23154 } , [ isOpen ] ) ;
24155
25- const handleCopyCreateOnchain = useCallback ( ( ) => {
26- const copyCreateOnchain = async ( ) => {
27- try {
28- await navigator . clipboard . writeText ( 'npm create onchain' ) ;
29- } catch ( error ) {
30- console . error ( 'Failed to copy to clipboard' , error ) ;
31- }
32- } ;
33- void copyCreateOnchain ( ) ;
34- } , [ ] ) ;
35-
36156 const handleSearchInputFocus = useCallback ( ( ) => {
37157 setIsOpen ( true ) ;
38158 } , [ setIsOpen ] ) ;
@@ -74,97 +194,48 @@ export function SearchModal({
74194 ) }
75195 placeholder = "Search tools or templates to get started"
76196 />
77- < div className = "flex flex-col gap-4 pt-4" >
78- < div className = "flex flex-col items-start justify-center" >
79- < div className = "w-full px-4 py-2 text-sm uppercase text-gray-muted" > Quickstart</ div >
80- < button
81- type = "button"
82- className = { classNames (
83- 'group' ,
84- 'w-full rounded-xl px-4 py-2' ,
85- 'font-mono text-white' ,
86- 'flex items-center justify-between' ,
87- 'hover:bg-dark-palette-backgroundAlternate active:bg-dark-palette-secondary' ,
88- ) }
89- onClick = { handleCopyCreateOnchain }
90- >
91- < span > npm create onchain</ span >
92- < div className = "opacity-0 transition-opacity group-hover:opacity-100" >
93- < Icon name = "copy" width = "16" height = "16" />
197+ < div className = "flex w-full flex-col gap-4 pt-4" >
198+ < div className = "justify-cente flex w-full flex-col items-start" >
199+ { searchCategories . map ( ( searchCategory ) => (
200+ < div key = { searchCategory . category } className = "w-full" >
201+ < div className = "w-full px-4 py-2 text-sm uppercase text-gray-muted" >
202+ { searchCategory . category }
203+ </ div >
204+ { searchCategory . subCategories . map ( ( subCategory ) => (
205+ < button
206+ key = { subCategory . label }
207+ type = "button"
208+ className = { classNames (
209+ 'group' ,
210+ 'w-full rounded-xl px-4 py-2' ,
211+ {
212+ 'font-mono' : searchCategory . category === 'Quickstart' ,
213+ } ,
214+ 'text-white' ,
215+ 'flex items-center justify-between' ,
216+ 'hover:bg-dark-palette-backgroundAlternate active:bg-dark-palette-secondary' ,
217+ ) }
218+ onClick = {
219+ subCategory . href ? ( ) => window . open ( subCategory . href ) : subCategory ?. onClick
220+ }
221+ >
222+ < span > { subCategory . label } </ span >
223+ < div
224+ className = { classNames (
225+ 'opacity-0 transition-opacity group-hover:opacity-100' ,
226+ subCategory ?. iconRotation ,
227+ ) }
228+ >
229+ < Icon name = { subCategory . icon } width = "16" height = "16" />
230+ </ div >
231+ </ button >
232+ ) ) }
94233 </ div >
95- </ button >
96- </ div >
97- < div className = "flex flex-col items-start justify-center" >
98- < div className = "w-full px-4 py-2 text-sm uppercase text-gray-muted" >
99- Start with a Template
100- </ div >
101- < ModalEntry
102- label = "Launch an AI agent"
103- icon = "diagonalUpArrow"
104- href = "https://replit.com/@CoinbaseDev/CDP-AgentKit#README.md"
105- />
106- < ModalEntry
107- label = "Build an onchain store"
108- icon = "diagonalUpArrow"
109- href = "https://onchain-commerce-template.vercel.app/"
110- />
111- </ div >
112- < div className = "flex flex-col items-start justify-center" >
113- < div className = "w-full px-4 py-2 text-sm uppercase text-gray-muted" > Tools</ div >
114- < ModalEntry
115- label = "AgentKit"
116- icon = "backArrow"
117- rotateIcon = "rotate-180"
118- href = "/developers/agent-kit"
119- />
120- < ModalEntry
121- label = "Base Wallet"
122- icon = "backArrow"
123- rotateIcon = "rotate-180"
124- href = "/developers/base-wallet"
125- />
126- < ModalEntry
127- label = "Base App Chains"
128- icon = "backArrow"
129- rotateIcon = "rotate-180"
130- href = "/developers/app-chains"
131- />
234+ ) ) }
132235 </ div >
133236 </ div >
134237 </ div >
135238 </ div > ,
136239 document . body ,
137240 ) ;
138241}
139-
140- function ModalEntry ( {
141- label,
142- icon,
143- rotateIcon,
144- href,
145- } : {
146- label : string ;
147- icon : string ;
148- rotateIcon ?: string ;
149- href : string ;
150- } ) {
151- return (
152- < Link
153- href = { href }
154- className = { classNames (
155- 'group' ,
156- 'w-full rounded-xl px-4 py-2' ,
157- 'font-mono text-white' ,
158- 'flex items-center justify-between' ,
159- 'hover:bg-dark-palette-backgroundAlternate active:bg-dark-palette-secondary' ,
160- ) }
161- >
162- < span > { label } </ span >
163- < div
164- className = { classNames ( 'opacity-0 transition-opacity group-hover:opacity-100' , rotateIcon ) }
165- >
166- < Icon name = { icon } width = "16" height = "16" />
167- </ div >
168- </ Link >
169- ) ;
170- }
0 commit comments