Graphical PDS migrator for AT Protocol

fix download button

Changed files
+93 -54
islands
+93 -54
islands/DidPlcProgress.tsx
··· 162 162 const [emailToken, setEmailToken] = useState<string>(""); 163 163 const [hasDownloadedKey, setHasDownloadedKey] = useState(false); 164 164 const [downloadedKeyId, setDownloadedKeyId] = useState<string | null>(null); 165 + const [hasContinuedPastDownload, setHasContinuedPastDownload] = useState( 166 + false, 167 + ); 165 168 166 169 const updateStepStatus = ( 167 170 index: number, ··· 444 447 445 448 try { 446 449 const jsonString = JSON.stringify(keyJson, null, 2); 447 - const blob = new Blob([jsonString], { 448 - type: "application/json", 449 - }); 450 - const url = URL.createObjectURL(blob); 451 - const a = document.createElement("a"); 452 - a.href = url; 453 - a.download = `plc-key-${keyJson.publicKeyDid || "unknown"}.json`; 454 - a.style.display = "none"; 455 - document.body.appendChild(a); 456 - a.click(); 457 - document.body.removeChild(a); 458 - URL.revokeObjectURL(url); 450 + const filename = `plc-key-${keyJson.publicKeyDid || "unknown"}.json`; 451 + 452 + // Create data URL 453 + const dataStr = "data:text/json;charset=utf-8," + 454 + encodeURIComponent(jsonString); 455 + 456 + // Create download link 457 + const downloadAnchorNode = document.createElement("a"); 458 + downloadAnchorNode.setAttribute("href", dataStr); 459 + downloadAnchorNode.setAttribute("download", filename); 460 + 461 + // For Chrome/Firefox compatibility 462 + downloadAnchorNode.style.display = "none"; 463 + document.body.appendChild(downloadAnchorNode); 464 + 465 + // Trigger download 466 + downloadAnchorNode.click(); 467 + 468 + // Cleanup 469 + document.body.removeChild(downloadAnchorNode); 459 470 460 - console.log("Download completed, proceeding to next step..."); 471 + console.log("Download completed, showing continue button..."); 461 472 setHasDownloadedKey(true); 462 473 setDownloadedKeyId(keyJson.publicKeyDid); 463 - 464 - // Automatically proceed to the next step after successful download 465 - setTimeout(() => { 466 - console.log("Auto-proceeding with key:", keyJson.publicKeyDid); 467 - handleStartPlcUpdate(keyJson.publicKeyDid); 468 - }, 1000); 474 + // Keep step 0 in completed state but don't auto-proceed 469 475 } catch (error) { 470 476 console.error("Download failed:", error); 471 477 } ··· 845 851 {/* Key Download Warning */} 846 852 {index === 0 && 847 853 step.status === "completed" && 848 - !hasDownloadedKey && ( 854 + !hasContinuedPastDownload && ( 849 855 <div class="mt-4 space-y-4"> 850 856 <div class="bg-yellow-50 dark:bg-yellow-900/50 p-4 rounded-lg border border-yellow-200 dark:border-yellow-800"> 851 857 <div class="flex items-start"> ··· 893 899 </div> 894 900 895 901 <div class="flex items-center justify-between"> 896 - <button 897 - type="button" 898 - onClick={handleDownload} 899 - class="px-4 py-2 bg-green-600 hover:bg-green-700 text-white rounded-md transition-colors duration-200 flex items-center space-x-2" 900 - > 901 - <svg 902 - class="w-5 h-5" 903 - fill="none" 904 - stroke="currentColor" 905 - viewBox="0 0 24 24" 902 + <div class="flex items-center space-x-3"> 903 + <button 904 + type="button" 905 + onClick={handleDownload} 906 + class="px-4 py-2 bg-green-600 hover:bg-green-700 text-white rounded-md transition-colors duration-200 flex items-center space-x-2" 906 907 > 907 - <path 908 - stroke-linecap="round" 909 - stroke-linejoin="round" 910 - stroke-width="2" 911 - d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" 912 - /> 913 - </svg> 914 - <span>Download Key</span> 915 - </button> 908 + <svg 909 + class="w-5 h-5" 910 + fill="none" 911 + stroke="currentColor" 912 + viewBox="0 0 24 24" 913 + > 914 + <path 915 + stroke-linecap="round" 916 + stroke-linejoin="round" 917 + stroke-width="2" 918 + d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" 919 + /> 920 + </svg> 921 + <span>Download Key</span> 922 + </button> 916 923 917 - <div class="flex items-center text-sm text-red-600 dark:text-red-400"> 918 - <svg 919 - class="w-4 h-4 mr-1" 920 - fill="none" 921 - stroke="currentColor" 922 - viewBox="0 0 24 24" 923 - > 924 - <path 925 - stroke-linecap="round" 926 - stroke-linejoin="round" 927 - stroke-width="2" 928 - d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" 929 - /> 930 - </svg> 931 - Download required to proceed 924 + {hasDownloadedKey && ( 925 + <button 926 + type="button" 927 + onClick={() => { 928 + console.log( 929 + "Continue clicked, proceeding to PLC update", 930 + ); 931 + setHasContinuedPastDownload(true); 932 + handleStartPlcUpdate(keyJson.publicKeyDid); 933 + }} 934 + class="px-4 py-2 bg-green-600 hover:bg-green-700 text-white rounded-md transition-colors duration-200 flex items-center space-x-2" 935 + > 936 + <svg 937 + class="w-5 h-5" 938 + fill="none" 939 + stroke="currentColor" 940 + viewBox="0 0 24 24" 941 + > 942 + <path 943 + stroke-linecap="round" 944 + stroke-linejoin="round" 945 + stroke-width="2" 946 + d="M9 5l7 7-7 7" 947 + /> 948 + </svg> 949 + <span>Continue</span> 950 + </button> 951 + )} 932 952 </div> 953 + 954 + {!hasDownloadedKey && ( 955 + <div class="flex items-center text-sm text-red-600 dark:text-red-400"> 956 + <svg 957 + class="w-4 h-4 mr-1" 958 + fill="none" 959 + stroke="currentColor" 960 + viewBox="0 0 24 24" 961 + > 962 + <path 963 + stroke-linecap="round" 964 + stroke-linejoin="round" 965 + stroke-width="2" 966 + d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" 967 + /> 968 + </svg> 969 + Download required to proceed 970 + </div> 971 + )} 933 972 </div> 934 973 </div> 935 974 )}