import { useState } from 'react' ; import { useIdeContext } from 'src/helpers/hooks/useIdeContext' ; import { cadPackageConfigs } from 'src/components/CadPackage/CadPackage' ; import OutBound from 'src/components/OutBound/OutBound' ; import { prepareEncodedUrl , makeExternalUrl } from './helpers' ; import { copyTextToClipboard } from 'src/helpers/clipboard' ; import { useRender } from 'src/components/IdeWrapper/useRender' ; import { toast } from '@redwoodjs/web/toast' ; const ExternalScript = ( ) => { const { state , thunkDispatch } = useIdeContext ( ) ; const handleRender = useRender ( ) ; const [ rawUrl , setRawUrl ] = useState ( '' ) ; const [ script , setScript ] = useState ( '' ) ; const [ asyncState , setAsyncState ] = useState < 'INIT' | 'SUCCESS' | 'ERROR' | 'LOADING' > ( 'INIT' ) ; const cadName = cadPackageConfigs [ state . ideType ] . label ; const onPaste = async ( { clipboardData , } ) => { const url = clipboardData . getData ( 'Text' ) ; processUserUrl ( url ) ; } ; const onChange = async ( { target , } ) => setRawUrl ( target . value ) ; const onKeyDown = async ( { key , target } ) => key === 'Enter' && processUserUrl ( target . value ) ; async function processUserUrl ( url ) { setRawUrl ( url ) ; try { setAsyncState ( 'LOADING' ) ; const response = await fetch ( prepareEncodedUrl ( url ) ) ; if ( response . status === 404 ) throw new Error ( "couldn't find script" ) ; const script2 = await response . text ( ) ; if ( script2 . startsWith ( '<!DOCTYPE html>' ) ) throw new Error ( 'got html document, not a script' ) ; setScript ( script2 ) ; setAsyncState ( 'SUCCESS' ) ; } catch ( e ) { setAsyncState ( 'ERROR' ) ; toast . error ( "We had trouble with you're URL, are you sure it was correct?" ) ; } } const onCopyRender = ( ) => { copyTextToClipboard ( makeExternalUrl ( rawUrl ) ) ; thunkDispatch ( { type : 'updateCode' , payload : script } ) ; setTimeout ( handleRender ) ; } ; return ( < div className = "p-4" > < p className = "text-sm pb-4 border-b border-gray-700" > Paste an external url containing a { cadName } script to generate a new CadHub url for this resource . { ' ' } < OutBound className = "underline text-gray-500" to = "https://learn.cadhub.xyz/docs/general-cadhub/external-resource-url" > Learn more < /OutBound>{' '} about this feature . < /p> { [ 'INIT' , 'ERROR' ] . includes ( asyncState ) && ( < > < p className = "mt-4" > Paste url < /p> < input className = "p-1 text-xs border border-ch-purple-450 w-full" value = { rawUrl } onChange = { onChange } onPaste = { onPaste } onKeyDown = { onKeyDown } / > < />)} { asyncState === 'ERROR' && ( < p className = "text-sm text-red-800" > That didn 't work, try again.</p>)} { asyncState === 'LOADING' && ( < div className = "h-10 relative" > < div className = "inset-0 absolute flex items-center justify-center" > < div className = "h-6 w-6 bg-pink-600 rounded-full animate-ping" > < /div> < /div> < /div>)} { asyncState === 'SUCCESS' && ( < > < input value = { makeExternalUrl ( rawUrl ) . replace ( /^.+:\/\//g , '' ) } readOnly className = "py-1 px-2 mt-4 text-xs border border-ch-purple-450 w-full" / > < button className = "w-full bg-ch-purple-450 hover:bg-ch-purple-400 py-1 text-gray-300" onClick = { ( ) => copyTextToClipboard ( makeExternalUrl ( rawUrl ) ) } > Copy URL < /button> < div className = "flex flex-col gap-2 pt-2" > < button className = "bg-gray-500 hover:bg-gray-600 p-1 px-2 text-gray-200" onClick = { onCopyRender } > Copy & amp ; Render < /button> < button className = "bg-gray-500 hover:bg-gray-600 p-1 px-2 text-gray-200" onClick = { ( ) => { setAsyncState ( 'INIT' ) ; setRawUrl ( '' ) ; setScript ( '' ) ; } } > Create another URL < /button> < /div> < />)} < /div>); } ; export default ExternalScript ;