@@ -166,136 +166,28 @@ const StatusIcon = (props: { projectDomain: Domain; isLoading: boolean }) => {
166166 ) ;
167167} ;
168168
169- const DomainConfig = ( {
169+ const DomainItem = ( {
170+ initiallyOpen,
170171 projectDomain,
171- onUpdateStatus,
172+ project,
173+ refresh,
172174} : {
173- projectDomain : Domain ;
174- onUpdateStatus : ( ) => void ;
175- } ) => {
176- const { load : findDomainRegistrar , data : registrar } =
177- trpcClient . domain . findDomainRegistrar . useQuery ( ) ;
178- const cname = extractCname ( projectDomain . domain ) ;
179- useEffect ( ( ) => {
180- if ( cname === "@" ) {
181- findDomainRegistrar ( { domain : projectDomain . domain } ) ;
182- }
183- } , [ projectDomain . domain , cname ] ) ;
184- const publisherHost = useStore ( $publisherHost ) ;
185-
186- const cnameRecord = {
187- // use alias for domain root when supported to avoid conflicting
188- // with MX, NS etc records
189- type : cname === "@" && registrar ?. alias ? "ALIAS" : "CNAME" ,
190- host : cname ,
191- value : `${ projectDomain . cname } .customers.${ publisherHost } ` ,
192- ttl : 300 ,
193- } as const ;
194-
195- const txtRecord = {
196- type : "TXT" ,
197- host : cname === "@" ? "_webstudio_is" : `_webstudio_is.${ cname } ` ,
198- value : projectDomain . expectedTxtRecord ,
199- ttl : 300 ,
200- } as const ;
201-
202- const dnsRecords = [ cnameRecord , txtRecord ] ;
203-
204- return (
205- < >
206- < Text color = "subtle" >
207- < strong > To verify your domain:</ strong >
208- < br />
209- Visit the admin console of your domain registrar (the website you
210- purchased your domain from) and create one < strong > CNAME</ strong > record
211- and one < strong > TXT</ strong > record with the values shown below:
212- </ Text >
213-
214- < Grid
215- gap = { 2 }
216- css = { { gridTemplateColumns : `${ theme . spacing [ 18 ] } 1fr 1fr` } }
217- >
218- < Text color = "subtle" variant = "titles" >
219- TYPE
220- </ Text >
221- < Text color = "subtle" variant = "titles" >
222- NAME
223- </ Text >
224- < Text color = "subtle" variant = "titles" >
225- VALUE
226- </ Text >
227-
228- { dnsRecords . map ( ( record , index ) => (
229- < Fragment key = { index } >
230- < InputEllipsis readOnly value = { record . type } />
231- < InputEllipsis
232- readOnly
233- value = { record . host }
234- suffix = {
235- < CopyToClipboard text = { record . host } >
236- < NestedInputButton type = "button" >
237- < CopyIcon />
238- </ NestedInputButton >
239- </ CopyToClipboard >
240- }
241- />
242- < InputEllipsis
243- readOnly
244- value = { record . value }
245- suffix = {
246- < CopyToClipboard text = { record . value } >
247- < NestedInputButton type = "button" >
248- < CopyIcon />
249- </ NestedInputButton >
250- </ CopyToClipboard >
251- }
252- />
253- </ Fragment >
254- ) ) }
255- </ Grid >
256-
257- < Grid
258- gap = { 2 }
259- align = { "center" }
260- css = { {
261- gridTemplateColumns : `1fr auto 1fr` ,
262- } }
263- >
264- < Separator css = { { alignSelf : "unset" } } />
265- < Text color = "main" > OR</ Text >
266- < Separator css = { { alignSelf : "unset" } } />
267- </ Grid >
268-
269- < Entri
270- dnsRecords = { dnsRecords }
271- domain = { projectDomain . domain }
272- onClose = { ( ) => {
273- // Sometimes Entri modal dialog hangs even if it's successful,
274- // until they fix that, we'll just refresh the status here on every onClose event
275- onUpdateStatus ( ) ;
276- } }
277- />
278- </ >
279- ) ;
280- } ;
281-
282- const DomainItem = ( props : {
283175 initiallyOpen : boolean ;
284176 projectDomain : Domain ;
285- refresh : ( ) => Promise < void > ;
286177 project : Project ;
178+ refresh : ( ) => Promise < void > ;
287179} ) => {
288180 const timeSinceLastUpdateMs =
289- Date . now ( ) - new Date ( props . projectDomain . updatedAt ) . getTime ( ) ;
181+ Date . now ( ) - new Date ( projectDomain . updatedAt ) . getTime ( ) ;
290182
291183 const DAY_IN_MS = 24 * 60 * 60 * 1000 ;
292184
293- const status = props . projectDomain . verified
294- ? ( `VERIFIED_${ props . projectDomain . status } ` as `VERIFIED_${DomainStatus } `)
185+ const status = projectDomain . verified
186+ ? ( `VERIFIED_${ projectDomain . status } ` as `VERIFIED_${DomainStatus } `)
295187 : `UNVERIFIED` ;
296188
297189 const [ isStatusLoading , setIsStatusLoading ] = useState (
298- props . initiallyOpen ||
190+ initiallyOpen ||
299191 status === "VERIFIED_ACTIVE" ||
300192 timeSinceLastUpdateMs > DAY_IN_MS
301193 ? false
@@ -310,16 +202,16 @@ const DomainItem = (props: {
310202 const handleRemoveDomain = async ( ) => {
311203 setIsRemoveInProgress ( true ) ;
312204 const result = await nativeClient . domain . remove . mutate ( {
313- projectId : props . projectDomain . projectId ,
314- domainId : props . projectDomain . domainId ,
205+ projectId : projectDomain . projectId ,
206+ domainId : projectDomain . domainId ,
315207 } ) ;
316208
317209 if ( result . success === false ) {
318210 toast . error ( result . error ) ;
319211 return ;
320212 }
321213
322- await props . refresh ( ) ;
214+ await refresh ( ) ;
323215 } ;
324216
325217 const [ verifyError , setVerifyError ] = useState < string | undefined > ( undefined ) ;
@@ -329,16 +221,16 @@ const DomainItem = (props: {
329221 setIsCheckStateInProgress ( true ) ;
330222
331223 const verifyResult = await nativeClient . domain . verify . mutate ( {
332- projectId : props . projectDomain . projectId ,
333- domainId : props . projectDomain . domainId ,
224+ projectId : projectDomain . projectId ,
225+ domainId : projectDomain . domainId ,
334226 } ) ;
335227
336228 if ( verifyResult . success === false ) {
337229 setVerifyError ( verifyResult . error ) ;
338230 return ;
339231 }
340232
341- await props . refresh ( ) ;
233+ await refresh ( ) ;
342234 } ) ;
343235
344236 const [ updateStatusError , setUpdateStatusError ] = useState <
@@ -350,8 +242,8 @@ const DomainItem = (props: {
350242 setIsCheckStateInProgress ( true ) ;
351243
352244 const updateStatusResult = await nativeClient . domain . updateStatus . mutate ( {
353- projectId : props . projectDomain . projectId ,
354- domain : props . projectDomain . domain ,
245+ projectId : projectDomain . projectId ,
246+ domain : projectDomain . domain ,
355247 } ) ;
356248
357249 setIsStatusLoading ( false ) ;
@@ -361,7 +253,7 @@ const DomainItem = (props: {
361253 return ;
362254 }
363255
364- await props . refresh ( ) ;
256+ await refresh ( ) ;
365257 } ) ;
366258
367259 const onceRef = useRef ( false ) ;
@@ -387,43 +279,69 @@ const DomainItem = (props: {
387279 } ) ;
388280 } , [ status , handleVerify , handleUpdateStatus , isStatusLoading ] ) ;
389281
390- const domainStatus = getStatus ( props . projectDomain ) ;
282+ const domainStatus = getStatus ( projectDomain ) ;
391283
392284 const { isVerifiedActive, text } = getStatusText ( {
393- projectDomain : props . projectDomain ,
285+ projectDomain,
394286 isLoading : false ,
395287 } ) ;
396288
289+ const publisherHost = useStore ( $publisherHost ) ;
290+ const { load : findDomainRegistrar , data : registrar } =
291+ trpcClient . domain . findDomainRegistrar . useQuery ( ) ;
292+ const cname = extractCname ( projectDomain . domain ) ;
293+ useEffect ( ( ) => {
294+ if ( cname === "@" ) {
295+ findDomainRegistrar ( { domain : projectDomain . domain } ) ;
296+ }
297+ } , [ projectDomain . domain , cname ] ) ;
298+ const dnsRecords = [
299+ {
300+ // use alias for domain root when supported to avoid conflicting
301+ // with MX, NS etc records
302+ type : cname === "@" && registrar ?. alias ? "ALIAS" : "CNAME" ,
303+ host : cname ,
304+ value : `${ projectDomain . cname } .customers.${ publisherHost } ` ,
305+ ttl : 300 ,
306+ } as const ,
307+ {
308+ type : "TXT" ,
309+ host : cname === "@" ? "_webstudio_is" : `_webstudio_is.${ cname } ` ,
310+ value : projectDomain . expectedTxtRecord ,
311+ ttl : 300 ,
312+ } as const ,
313+ ] ;
314+
397315 return (
398316 < CollapsibleDomainSection
399317 prefix = {
400318 < DomainCheckbox
401- buildId = { props . projectDomain . latestBuildVirtual ?. buildId }
319+ buildId = { projectDomain . latestBuildVirtual ?. buildId }
402320 defaultChecked = {
403- props . projectDomain . latestBuildVirtual ?. buildId != null &&
404- props . projectDomain . latestBuildVirtual ?. buildId ===
405- props . project . latestBuildVirtual ?. buildId
321+ projectDomain . latestBuildVirtual ?. buildId != null &&
322+ projectDomain . latestBuildVirtual ?. buildId ===
323+ project . latestBuildVirtual ?. buildId
406324 }
407- domain = { props . projectDomain . domain }
325+ domain = { projectDomain . domain }
408326 disabled = { domainStatus !== "VERIFIED_ACTIVE" }
409327 />
410328 }
411- initiallyOpen = { props . initiallyOpen }
412- title = { props . projectDomain . domain }
329+ initiallyOpen = { initiallyOpen }
330+ title = { projectDomain . domain }
413331 suffix = {
414332 < Grid flow = "column" >
415333 < StatusIcon
416334 isLoading = { isStatusLoading }
417- projectDomain = { props . projectDomain }
335+ projectDomain = { projectDomain }
418336 />
419337
420- < Tooltip content = { `Proceed to ${ props . projectDomain . domain } ` } >
338+ < Tooltip content = { `Proceed to ${ projectDomain . domain } ` } >
421339 < IconButton
422340 type = "button"
423341 tabIndex = { - 1 }
424342 disabled = { status !== "VERIFIED_ACTIVE" }
425343 onClick = { ( event ) => {
426- const url = new URL ( `https://${ props . projectDomain . domain } ` ) ;
344+ const url = new URL ( `https://${ projectDomain . domain } ` ) ;
427345 window . open ( url . href , "_blank" ) ;
428346 event . preventDefault ( ) ;
429347 } }
@@ -503,9 +421,76 @@ const DomainItem = (props: {
503421 ) }
504422 </ Grid >
505423
506- < DomainConfig
507- projectDomain = { props . projectDomain }
508- onUpdateStatus = { ( ) => {
424+ < Text color = "subtle" >
425+ < strong > To verify your domain:</ strong >
426+ < br />
427+ Visit the admin console of your domain registrar (the website you
428+ purchased your domain from) and create one < strong > CNAME</ strong > { " " }
429+ record and one < strong > TXT</ strong > record with the values shown
430+ below:
431+ </ Text >
432+
433+ < Grid
434+ gap = { 2 }
435+ css = { { gridTemplateColumns : `${ theme . spacing [ 18 ] } 1fr 1fr` } }
436+ >
437+ < Text color = "subtle" variant = "titles" >
438+ TYPE
439+ </ Text >
440+ < Text color = "subtle" variant = "titles" >
441+ NAME
442+ </ Text >
443+ < Text color = "subtle" variant = "titles" >
444+ VALUE
445+ </ Text >
446+
447+ { dnsRecords . map ( ( record , index ) => (
448+ < Fragment key = { index } >
449+ < InputEllipsis readOnly value = { record . type } />
450+ < InputEllipsis
451+ readOnly
452+ value = { record . host }
453+ suffix = {
454+ < CopyToClipboard text = { record . host } >
455+ < NestedInputButton type = "button" >
456+ < CopyIcon />
457+ </ NestedInputButton >
458+ </ CopyToClipboard >
459+ }
460+ />
461+ < InputEllipsis
462+ readOnly
463+ value = { record . value }
464+ suffix = {
465+ < CopyToClipboard text = { record . value } >
466+ < NestedInputButton type = "button" >
467+ < CopyIcon />
468+ </ NestedInputButton >
469+ </ CopyToClipboard >
470+ }
471+ />
472+ </ Fragment >
473+ ) ) }
474+ </ Grid >
475+
476+ < Grid
477+ gap = { 2 }
478+ align = { "center" }
479+ css = { {
480+ gridTemplateColumns : `1fr auto 1fr` ,
481+ } }
482+ >
483+ < Separator css = { { alignSelf : "unset" } } />
484+ < Text color = "main" > OR</ Text >
485+ < Separator css = { { alignSelf : "unset" } } />
486+ </ Grid >
487+
488+ < Entri
489+ dnsRecords = { dnsRecords }
490+ domain = { projectDomain . domain }
491+ onClose = { ( ) => {
492+ // Sometimes Entri modal dialog hangs even if it's successful,
493+ // until they fix that, we'll just refresh the status here on every onClose event
509494 if ( status === "UNVERIFIED" ) {
510495 startTransition ( async ( ) => {
511496 await handleVerify ( ) ;
0 commit comments