Graphical PDS migrator for AT Protocol
1import { useEffect, useState } from "preact/hooks"; 2import { IS_BROWSER } from "fresh/runtime"; 3import { Link } from "../components/Link.tsx"; 4 5/** 6 * The user interface for the ticket component. 7 * @type {User} 8 */ 9interface User { 10 did: string; 11 handle?: string; 12} 13 14/** 15 * The ticket component for the landing page. 16 * @returns The ticket component 17 * @component 18 */ 19export default function Ticket() { 20 const [user, setUser] = useState<User | null>(null); 21 22 useEffect(() => { 23 if (!IS_BROWSER) return; 24 25 const fetchUser = async () => { 26 try { 27 const response = await fetch("/api/me", { 28 credentials: "include", 29 }); 30 if (!response.ok) { 31 throw new Error("Failed to fetch user profile"); 32 } 33 const userData = await response.json(); 34 setUser( 35 userData 36 ? { 37 did: userData.did, 38 handle: userData.handle, 39 } 40 : null 41 ); 42 } catch (error) { 43 console.error("Failed to fetch user:", error); 44 setUser(null); 45 } 46 }; 47 48 fetchUser(); 49 }, []); 50 51 return ( 52 <div class="max-w-4xl mx-auto"> 53 <div class="ticket mb-8 bg-white dark:bg-slate-800 p-6 relative before:absolute before:bg-white dark:before:bg-slate-800 before:-z-10 after:absolute after:inset-0 after:bg-slate-200 dark:after:bg-slate-700 after:-z-20 [clip-path:polygon(0_0,20px_0,100%_0,100%_calc(100%-20px),calc(100%-20px)_100%,0_100%,0_calc(100%-20px),20px_100%)] after:[clip-path:polygon(0_0,20px_0,100%_0,100%_calc(100%-20px),calc(100%-20px)_100%,0_100%,0_calc(100%-20px),20px_100%)]"> 54 <div class="boarding-label text-amber-500 dark:text-amber-400 font-mono font-bold tracking-wider text-sm mb-4"> 55 BOARDING PASS 56 </div> 57 <div class="flex justify-between items-start mb-4"> 58 <h3 class="text-2xl font-mono">WHAT IS AIRPORT?</h3> 59 <div class="text-sm font-mono text-gray-500 dark:text-gray-400"> 60 GATE A1 61 </div> 62 </div> 63 <div class="passenger-info text-slate-600 dark:text-slate-300 font-mono text-sm mb-4"> 64 PASSENGER: {(user?.handle || "UNKNOWN").toUpperCase()} 65 <br /> 66 DESTINATION: NEW PDS 67 </div> 68 <p class="mb-4"> 69 ATP Airport is your digital terminal for AT Protocol account actions. 70 We help you smoothly transfer your PDS account between different 71 providers no lost luggage, just a first-class experience for your 72 data's journey to its new home. 73 </p> 74 <p> 75 Think you might need to migrate in the future but your PDS might be 76 hostile or offline? No worries! You can go to the{" "} 77 <Link 78 href="/ticket-booth" 79 isExternal 80 class="text-blue-600 dark:text-blue-400" 81 > 82 ticket booth 83 </Link>{" "} 84 and get a PLC key to use for account recovery in the future. Soon 85 you'll also be able to go to baggage claim (take the air shuttle to 86 terminal four) and get a downloadable backup of all your current PDS 87 data in case that were to happen. 88 </p> 89 </div> 90 91 <div class="ticket mb-8 bg-white dark:bg-slate-800 p-6 relative before:absolute before:bg-white dark:before:bg-slate-800 before:-z-10 after:absolute after:inset-0 after:bg-slate-200 dark:after:bg-slate-700 after:-z-20 [clip-path:polygon(0_0,20px_0,100%_0,100%_calc(100%-20px),calc(100%-20px)_100%,0_100%,0_calc(100%-20px),20px_100%)] after:[clip-path:polygon(0_0,20px_0,100%_0,100%_calc(100%-20px),calc(100%-20px)_100%,0_100%,0_calc(100%-20px),20px_100%)]"> 92 <div class="boarding-label text-amber-500 dark:text-amber-400 font-mono font-bold tracking-wider text-sm mb-4"> 93 FLIGHT DETAILS 94 </div> 95 <div class="flex justify-between items-start mb-4"> 96 <h3 class="text-2xl font-mono">GET READY TO FLY</h3> 97 <div class="text-sm font-mono text-gray-500 dark:text-gray-400"> 98 SEAT: 1A 99 </div> 100 </div> 101 <div class="passenger-info mb-4 text-slate-600 dark:text-slate-300 font-mono text-sm"> 102 CLASS: FIRST CLASS MIGRATION 103 <br /> 104 FLIGHT: ATP-2024 105 </div> 106 <ol class="list-decimal list-inside space-y-3"> 107 <li>Check in with your current PDS credentials</li> 108 <li>Select your destination PDS</li> 109 <li>Go through security</li> 110 <li>Sit back while we handle your data transfer</li> 111 </ol> 112 <div class="mt-6 text-sm text-gray-600 dark:text-gray-400 border-t border-dashed pt-4 border-slate-200 dark:border-slate-700"> 113 Coming from a Bluesky PDS? This is currently a ONE WAY TICKET because 114 Bluesky doesn't support transfers back yet. Although they claim they 115 will support it in the future, assume you won't be able to. 116 </div> 117 <div class="flight-info mt-6 flex items-center justify-between text-slate-600 dark:text-slate-300 font-mono text-sm"> 118 <div> 119 <div class="text-xs text-gray-500 dark:text-gray-400">FROM</div> 120 <div>CURRENT PDS</div> 121 </div> 122 <div class="text-amber-500 dark:text-amber-400 text-4xl"></div> 123 <div class="content-end"> 124 <div class="text-xs text-gray-500 dark:text-gray-400">TO</div> 125 <div>NEW PDS</div> 126 </div> 127 </div> 128 </div> 129 </div> 130 ); 131}