Graphical PDS migrator for AT Protocol

update main description to chunks

Turtlepaw 9e534f6b 489d05a0

Changed files
+186 -71
islands
+186 -71
islands/DidPlcProgress.tsx
··· 1 - import { useState } from "preact/hooks"; 1 + import { useState, useEffect } from "preact/hooks"; 2 2 import { Link } from "../components/Link.tsx"; 3 3 4 4 interface PlcUpdateStep { ··· 7 7 error?: string; 8 8 } 9 9 10 + // Content chunks for the description 11 + const contentChunks = [ 12 + { 13 + title: "Welcome to Key Management", 14 + subtitle: "BOARDING PASS - SECTION A", 15 + content: ( 16 + <> 17 + <div class="passenger-info text-slate-600 dark:text-slate-300 font-mono text-sm mb-4"> 18 + GATE: KEY-01 • SEAT: DID-1A 19 + </div> 20 + <p class="text-slate-700 dark:text-slate-300 mb-4"> 21 + This tool helps you add a new rotation key to your{" "} 22 + <Link 23 + href="https://web.plc.directory/" 24 + isExternal 25 + class="text-blue-600 dark:text-blue-400" 26 + > 27 + PLC (Public Ledger of Credentials) 28 + </Link> 29 + . Having control of a rotation key gives you sovereignty over your DID 30 + (Decentralized Identifier). 31 + </p> 32 + </> 33 + ), 34 + }, 35 + { 36 + title: "Key Benefits", 37 + subtitle: "BOARDING PASS - SECTION B", 38 + content: ( 39 + <> 40 + <div class="passenger-info text-slate-600 dark:text-slate-300 font-mono text-sm mb-4"> 41 + GATE: KEY-02 • SEAT: DID-1B 42 + </div> 43 + <div class="space-y-4"> 44 + <div class="p-3 bg-white dark:bg-slate-800 rounded-lg border border-slate-200 dark:border-slate-700"> 45 + <h4 class="font-mono font-bold text-amber-500 dark:text-amber-400 mb-2"> 46 + PROVIDER MOBILITY 47 + </h4> 48 + <p class="text-slate-700 dark:text-slate-300"> 49 + Change your PDS without losing your identity, protecting you if 50 + your provider becomes hostile. 51 + </p> 52 + </div> 53 + <div class="p-3 bg-white dark:bg-slate-800 rounded-lg border border-slate-200 dark:border-slate-700"> 54 + <h4 class="font-mono font-bold text-amber-500 dark:text-amber-400 mb-2"> 55 + IDENTITY CONTROL 56 + </h4> 57 + <p class="text-slate-700 dark:text-slate-300"> 58 + Modify your DID document independently of your provider. 59 + </p> 60 + </div> 61 + </div> 62 + </> 63 + ), 64 + }, 65 + { 66 + title: "Technical Overview", 67 + subtitle: "BOARDING PASS - SECTION C", 68 + content: ( 69 + <> 70 + <div class="passenger-info text-slate-600 dark:text-slate-300 font-mono text-sm mb-4"> 71 + GATE: KEY-03 • SEAT: DID-1C 72 + </div> 73 + <div class="p-4 bg-white dark:bg-slate-800 rounded-lg border border-slate-200 dark:border-slate-700"> 74 + <div class="flex items-center mb-3"> 75 + <span class="text-lg mr-2">📝</span> 76 + <h4 class="font-mono font-bold text-amber-500 dark:text-amber-400"> 77 + TECHNICAL DETAILS 78 + </h4> 79 + </div> 80 + <p class="text-slate-700 dark:text-slate-300"> 81 + The rotation key is a did:key that will be added to your PLC 82 + document's rotationKeys array. This process uses the AT Protocol's 83 + PLC operations to update your DID document. 84 + <Link 85 + href="https://web.plc.directory/" 86 + class="block ml-1 text-blue-600 dark:text-blue-400" 87 + isExternal 88 + > 89 + Learn more about did:plc 90 + </Link> 91 + </p> 92 + </div> 93 + </> 94 + ), 95 + }, 96 + ]; 97 + 10 98 export default function PlcUpdateProgress() { 11 99 const [hasStarted, setHasStarted] = useState(false); 100 + const [currentChunkIndex, setCurrentChunkIndex] = useState(0); 12 101 const [steps, setSteps] = useState<PlcUpdateStep[]>([ 13 102 { name: "Generate Rotation Key", status: "pending" }, 14 103 { name: "Start PLC update", status: "pending" }, ··· 507 596 if (!hasStarted) { 508 597 return ( 509 598 <div class="space-y-6"> 510 - <div class="bg-blue-50 dark:bg-blue-900 p-6 rounded-lg border border-blue-200 dark:border-blue-800"> 511 - <h3 class="text-lg font-semibold text-blue-900 dark:text-blue-100 mb-4"> 512 - DID Rotation Key Management 513 - </h3> 599 + <div class="ticket bg-white dark:bg-slate-800 p-6 relative"> 600 + <div class="boarding-label text-amber-500 dark:text-amber-400 font-mono font-bold tracking-wider text-sm mb-2"> 601 + {contentChunks[currentChunkIndex].subtitle} 602 + </div> 603 + 604 + <div class="flex justify-between items-start mb-4"> 605 + <h3 class="text-2xl font-mono text-slate-800 dark:text-slate-200"> 606 + {contentChunks[currentChunkIndex].title} 607 + </h3> 608 + </div> 514 609 515 610 {/* Main Description */} 516 - <div class="prose dark:prose-invert max-w-none mb-6"> 517 - <p class="text-blue-800 dark:text-blue-200 mb-4"> 518 - This tool helps you add a new rotation key to your{" "} 519 - <Link 520 - href="https://web.plc.directory/" 521 - isExternal 522 - class="text-blue-600 dark:text-blue-400" 611 + <div class="mb-6">{contentChunks[currentChunkIndex].content}</div> 612 + 613 + {/* Navigation */} 614 + <div class="mt-8 border-t border-dashed border-slate-200 dark:border-slate-700 pt-4"> 615 + <div class="flex justify-between items-center"> 616 + <button 617 + onClick={() => 618 + setCurrentChunkIndex((prev) => Math.max(0, prev - 1)) 619 + } 620 + class={`px-4 py-2 font-mono text-slate-600 dark:text-slate-400 hover:text-slate-800 dark:hover:text-slate-200 transition-colors duration-200 flex items-center space-x-2 ${ 621 + currentChunkIndex === 0 ? "invisible" : "" 622 + }`} 523 623 > 524 - PLC (Public Ledger of Credentials) 525 - </Link> 526 - . Having control of a rotation key gives you sovereignty over your 527 - DID (Decentralized Identifier). 528 - </p> 624 + <svg 625 + class="w-5 h-5 rotate-180" 626 + fill="none" 627 + stroke="currentColor" 628 + viewBox="0 0 24 24" 629 + > 630 + <path 631 + stroke-linecap="round" 632 + stroke-linejoin="round" 633 + stroke-width="2" 634 + d="M9 5l7 7-7 7" 635 + /> 636 + </svg> 637 + <span>Previous Gate</span> 638 + </button> 529 639 530 - <h4 class="text-blue-900 dark:text-blue-100 font-medium mt-4 mb-2"> 531 - What you can do with a rotation key: 532 - </h4> 533 - <ul class="space-y-2 text-sm text-blue-700 dark:text-blue-300 list-disc pl-5"> 534 - <li> 535 - <span class="font-medium">Move to a different provider:</span> 536 - <br /> 537 - Change your PDS without losing your identity, protecting you if 538 - your provider becomes hostile. 539 - </li> 540 - <li> 541 - <span class="font-medium">Direct DID control:</span> 542 - <br /> 543 - Modify your DID document independently of your provider. 544 - </li> 545 - </ul> 546 - </div> 640 + {currentChunkIndex === contentChunks.length - 1 ? ( 641 + <button 642 + onClick={handleStart} 643 + class="px-6 py-2 bg-amber-500 hover:bg-amber-600 text-white font-mono rounded-md transition-colors duration-200 flex items-center space-x-2" 644 + > 645 + <span>Begin Key Generation</span> 646 + <svg 647 + class="w-5 h-5" 648 + fill="none" 649 + stroke="currentColor" 650 + viewBox="0 0 24 24" 651 + > 652 + <path 653 + stroke-linecap="round" 654 + stroke-linejoin="round" 655 + stroke-width="2" 656 + d="M9 5l7 7-7 7" 657 + /> 658 + </svg> 659 + </button> 660 + ) : ( 661 + <button 662 + onClick={() => 663 + setCurrentChunkIndex((prev) => 664 + Math.min(contentChunks.length - 1, prev + 1) 665 + ) 666 + } 667 + class="px-4 py-2 font-mono text-slate-600 dark:text-slate-400 hover:text-slate-800 dark:hover:text-slate-200 transition-colors duration-200 flex items-center space-x-2" 668 + > 669 + <span>Next Gate</span> 670 + <svg 671 + class="w-5 h-5" 672 + fill="none" 673 + stroke="currentColor" 674 + viewBox="0 0 24 24" 675 + > 676 + <path 677 + stroke-linecap="round" 678 + stroke-linejoin="round" 679 + stroke-width="2" 680 + d="M9 5l7 7-7 7" 681 + /> 682 + </svg> 683 + </button> 684 + )} 685 + </div> 547 686 548 - {/* Technical Note for Developers */} 549 - <div class="mt-6 p-4 bg-gray-50 dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700"> 550 - <h4 class="text-sm font-medium text-gray-900 dark:text-gray-100 mb-2"> 551 - 📝 Technical Note 552 - </h4> 553 - <p class="text-sm text-gray-600 dark:text-gray-400"> 554 - The rotation key is a did:key that will be added to your PLC 555 - document's rotationKeys array. This process uses the AT Protocol's 556 - PLC operations to update your DID document. 557 - <Link 558 - href="https://web.plc.directory/" 559 - class="text-blue-600 dark:text-blue-400 ml-1" 560 - isExternal 561 - > 562 - Learn more about did:plc 563 - </Link> 564 - </p> 687 + {/* Progress Dots */} 688 + <div class="flex justify-center space-x-3 mt-4"> 689 + {contentChunks.map((_, index) => ( 690 + <div 691 + key={index} 692 + class={`h-1.5 w-8 rounded-full transition-colors duration-200 ${ 693 + index === currentChunkIndex 694 + ? "bg-amber-500" 695 + : "bg-slate-200 dark:bg-slate-700" 696 + }`} 697 + /> 698 + ))} 699 + </div> 565 700 </div> 566 - 567 - <button 568 - onClick={handleStart} 569 - class="mt-6 px-6 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-md transition-colors duration-200 flex items-center space-x-2" 570 - > 571 - <span>Start Key Generation</span> 572 - <svg 573 - class="w-5 h-5" 574 - fill="none" 575 - stroke="currentColor" 576 - viewBox="0 0 24 24" 577 - > 578 - <path 579 - stroke-linecap="round" 580 - stroke-linejoin="round" 581 - stroke-width="2" 582 - d="M9 5l7 7-7 7" 583 - /> 584 - </svg> 585 - </button> 586 701 </div> 587 702 </div> 588 703 );