11'use client' ;
22
33import { Id , type SpaceStorageEntry } from '@graphprotocol/hypergraph' ;
4- import { useSpaces } from '@graphprotocol/hypergraph-react' ;
4+ import { useHypergraphApp , useHypergraphAuth , useSpaces } from '@graphprotocol/hypergraph-react' ;
55import { Dialog , DialogBackdrop , DialogPanel , DialogTitle } from '@headlessui/react' ;
66import { WarningIcon , XIcon } from '@phosphor-icons/react' ;
77import { createFormHook , useStore } from '@tanstack/react-form' ;
@@ -158,15 +158,63 @@ type SchemaSpaceSelectProps = {
158158 ) : void ;
159159} ;
160160function SchemaSpaceSelect ( { id, name, spaceSelected } : Readonly < SchemaSpaceSelectProps > ) {
161- const { data : privateSpaces = [ ] } = useSpaces ( { mode : 'private' } ) ;
162- const { data : publicSpaces = [ ] } = useSpaces ( { mode : 'public' } ) ;
161+ const { redirectToConnect } = useHypergraphApp ( ) ;
162+ const { authenticated } = useHypergraphAuth ( ) ;
163+ const { data : publicSpaces = [ ] , isPending } = useSpaces ( { mode : 'public' } ) ;
163164
164165 const field = useFieldContext < string > ( ) ;
165166 const value = useStore ( field . store , ( state ) => state . value ) ;
166167 const errors = useStore ( field . store , ( state ) => state . meta . errors ) ;
167168 const touched = useStore ( field . store , ( state ) => state . meta . isTouched ) ;
168169 const hasErrors = errors . length > 0 && touched ;
169170
171+ if ( ! authenticated ) {
172+ return (
173+ < button
174+ type = "button"
175+ className = "rounded-full bg-slate-900 flex items-center justify-center px-3 py-1.5 text-sm font-semibold text-white shadow-xs ring-1 ring-white/10 ring-inset hover:bg-white/10 cursor-pointer w-full"
176+ onClick = { ( ) =>
177+ redirectToConnect ( {
178+ storage : localStorage ,
179+ connectUrl : 'https://connect.geobrowser.io/' ,
180+ successUrl : `${ window . location . origin } /authenticate-callback` ,
181+ redirectFn ( url : URL ) {
182+ window . location . href = url . toString ( ) ;
183+ } ,
184+ } )
185+ }
186+ >
187+ Sign in to Geo Account
188+ </ button >
189+ ) ;
190+ }
191+ if ( ! isPending && publicSpaces . length === 0 ) {
192+ return (
193+ < div className = "w-full flex flex-col gap-y-2" >
194+ < p className = "text-sm text-gray-700 dark:text-gray-300" >
195+ Schemas need to be published to a public Space you have granted access to this app
196+ </ p >
197+ < p className = "text-xs text-gray-700 dark:text-gray-300" > Reconnect to Geo connect and connect public spaces</ p >
198+ < button
199+ type = "button"
200+ className = "rounded-full bg-slate-900 flex items-center justify-center px-3 py-1.5 text-sm font-semibold text-white shadow-xs ring-1 ring-white/10 ring-inset hover:bg-white/10 cursor-pointer w-full"
201+ onClick = { ( ) =>
202+ redirectToConnect ( {
203+ storage : localStorage ,
204+ connectUrl : 'https://connect.geobrowser.io/' ,
205+ successUrl : `${ window . location . origin } /authenticate-callback` ,
206+ redirectFn ( url : URL ) {
207+ window . location . href = url . toString ( ) ;
208+ } ,
209+ } )
210+ }
211+ >
212+ Connect Spaces
213+ </ button >
214+ </ div >
215+ ) ;
216+ }
217+
170218 return (
171219 < div className = "relative flex flex-col gap-y-2 w-full" >
172220 < fieldset
@@ -179,38 +227,6 @@ function SchemaSpaceSelect({ id, name, spaceSelected }: Readonly<SchemaSpaceSele
179227 < legend className = "mt-1 text-sm/6 text-gray-600 dark:text-gray-400" >
180228 Select the Space to publish your Hypergraph shema to.
181229 </ legend >
182- { privateSpaces . map ( ( privateSpace ) => (
183- < label
184- key = { privateSpace . id }
185- aria-label = { privateSpace . name || privateSpace . id }
186- aria-description = { `space-${ privateSpace . id } ` }
187- className = "group flex border border-gray-200 p-4 first:rounded-tl-md first:rounded-tr-md last:rounded-br-md last:rounded-bl-md focus:outline-hidden has-checked:relative has-checked:border-indigo-200 has-checked:bg-indigo-50 dark:border-gray-700 dark:has-checked:border-indigo-800 dark:has-checked:bg-indigo-500/10 w-full cursor-pointer"
188- >
189- < input
190- value = { privateSpace . id }
191- checked = { privateSpace . id === value }
192- onChange = { ( e ) => {
193- const checked = e . target . checked ;
194- if ( checked ) {
195- field . handleChange ( privateSpace . id ) ;
196- spaceSelected ( privateSpace ) ;
197- }
198- } }
199- name = { name }
200- type = "radio"
201- className = "relative mt-0.5 size-4 shrink-0 appearance-none rounded-full border border-gray-300 bg-white before:absolute before:inset-1 before:rounded-full before:bg-white not-checked:before:hidden checked:border-indigo-600 checked:bg-indigo-600 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600 disabled:border-gray-300 disabled:bg-gray-100 disabled:before:bg-gray-400 dark:border-white/10 dark:bg-white/5 dark:checked:border-indigo-500 dark:checked:bg-indigo-500 dark:focus-visible:outline-indigo-500 dark:disabled:border-white/5 dark:disabled:bg-white/10 dark:disabled:before:bg-white/20 forced-colors:appearance-auto forced-colors:before:hidden"
202- />
203- < span className = "ml-3 flex flex-col gap-y-1" >
204- < span className = "flex items-center gap-x-2 text-sm font-medium text-gray-900 group-has-checked:text-indigo-900 dark:text-white dark:group-has-checked:text-indigo-300" >
205- { privateSpace . name || privateSpace . id }
206- < SpaceVisibilityTag visibility = "public" />
207- </ span >
208- < span className = "block text-sm text-gray-500 group-has-checked:text-indigo-700 dark:text-gray-400 dark:group-has-checked:text-indigo-300/75" >
209- { privateSpace . name != null ? < InlineCode > { privateSpace . id } </ InlineCode > : null }
210- </ span >
211- </ span >
212- </ label >
213- ) ) }
214230 { publicSpaces . map ( ( publicSpace ) => (
215231 < label
216232 key = { publicSpace . id }
@@ -235,7 +251,6 @@ function SchemaSpaceSelect({ id, name, spaceSelected }: Readonly<SchemaSpaceSele
235251 < span className = "ml-3 flex flex-col gap-y-1" >
236252 < span className = "flex items-center gap-x-2 text-sm font-medium text-gray-900 group-has-checked:text-indigo-900 dark:text-white dark:group-has-checked:text-indigo-300" >
237253 { publicSpace . name || publicSpace . id }
238- < SpaceVisibilityTag visibility = "public" />
239254 </ span >
240255 < span className = "block text-sm text-gray-500 group-has-checked:text-indigo-700 dark:text-gray-400 dark:group-has-checked:text-indigo-300/75" >
241256 { publicSpace . name != null ? < InlineCode > { publicSpace . id } </ InlineCode > : null }
@@ -248,27 +263,3 @@ function SchemaSpaceSelect({ id, name, spaceSelected }: Readonly<SchemaSpaceSele
248263 </ div >
249264 ) ;
250265}
251-
252- type SpaceVisibility = 'public' | 'private' ;
253-
254- function SpaceVisibilityTag ( { visibility } : Readonly < { visibility : SpaceVisibility } > ) {
255- if ( visibility === 'private' ) {
256- return (
257- < span className = "inline-flex items-center gap-x-1.5 rounded-md px-2 py-1 text-xs font-medium text-gray-900 inset-ring inset-ring-gray-200 dark:text-white dark:inset-ring-white/10" >
258- < svg viewBox = "0 0 6 6" aria-hidden = "true" className = "size-1.5 fill-red-500 dark:fill-red-400" >
259- < circle r = { 3 } cx = { 3 } cy = { 3 } />
260- </ svg >
261- Private
262- </ span >
263- ) ;
264- }
265-
266- return (
267- < span className = "inline-flex items-center gap-x-1.5 rounded-md px-2 py-1 text-xs font-medium text-gray-900 inset-ring inset-ring-gray-200 dark:text-white dark:inset-ring-white/10" >
268- < svg viewBox = "0 0 6 6" aria-hidden = "true" className = "size-1.5 fill-green-500 dark:fill-green-400" >
269- < circle r = { 3 } cx = { 3 } cy = { 3 } />
270- </ svg >
271- Public
272- </ span >
273- ) ;
274- }
0 commit comments