Graphical PDS migrator for AT Protocol

remove alpha, fix mobile button

Changed files
+45 -34
islands
routes
+6 -15
README.md
··· 4 4 5 5 Airport is a web application built with Fresh and Deno that helps users safely migrate and backup their Bluesky PDS data. It provides a user-friendly interface for managing your AT Protocol data. 6 6 7 - ⚠️ **Alpha Status**: Airport is currently in alpha. Please use migration tools at your own risk and avoid using with main accounts during this phase. 8 - 9 7 ## Features 10 8 11 9 - PDS migration between servers ··· 13 11 - User-friendly interface 14 12 - Coming soon: PLC Key retrieval, data backup 15 13 16 - ## Technology Stack 14 + ## Tech Stack 17 15 18 - - [Fresh](https://fresh.deno.dev/) - The next-gen web framework 19 - - [Deno](https://deno.com/) - A modern runtime for JavaScript and TypeScript 20 - - [Tailwind CSS](https://tailwindcss.com/) - For styling 21 - - AT Protocol Integration 16 + - [Fresh](https://fresh.deno.dev/) - Web Framework 17 + - [Deno](https://deno.com/) - Runtime 18 + - [Tailwind](https://tailwindcss.com/) - Styling 22 19 23 - ## Getting Started 20 + ## Development 24 21 25 - ### Prerequisites 26 - 27 - Make sure to install Deno: 22 + Make sure you have Deno installed: 28 23 https://docs.deno.com/runtime/getting_started/installation 29 - 30 - ### Development 31 24 32 25 Start the project in development mode: 33 26 34 27 ``` 35 28 deno task dev 36 29 ``` 37 - 38 - This will watch the project directory and restart as necessary. 39 30 40 31 ## About 41 32
+35
islands/LoginButton.tsx
··· 1 + import { useEffect, useState } from "preact/hooks"; 2 + import { Button } from "../components/Button.tsx"; 3 + 4 + export default function LoginButton() { 5 + const [isMobile, setIsMobile] = useState(true); // Default to mobile for SSR 6 + 7 + useEffect(() => { 8 + const checkMobile = () => { 9 + setIsMobile(globalThis.innerWidth < 640); 10 + }; 11 + 12 + // Check on mount 13 + checkMobile(); 14 + 15 + // Listen for resize events 16 + globalThis.addEventListener('resize', checkMobile); 17 + return () => globalThis.removeEventListener('resize', checkMobile); 18 + }, []); 19 + 20 + return ( 21 + <div class="mt-6 sm:mt-8 text-center w-fit mx-auto"> 22 + <Button 23 + href={isMobile ? undefined : "/login"} 24 + color="blue" 25 + label={isMobile ? "MOBILE NOT SUPPORTED" : "GET STARTED"} 26 + className={isMobile ? "opacity-50 cursor-not-allowed" : "opacity-100 cursor-pointer"} 27 + onClick={(e: MouseEvent) => { 28 + if (isMobile) { 29 + e.preventDefault(); 30 + } 31 + }} 32 + /> 33 + </div> 34 + ); 35 + }
+2 -2
islands/MigrationSetup.tsx
··· 83 83 // Get PDS URL from the current service 84 84 const pdsResponse = await fetch(`/api/resolve-pds?did=${userData.did}`); 85 85 const pdsData = await pdsResponse.json(); 86 - 86 + 87 87 setPassport({ 88 88 did: userData.did, 89 89 handle: userData.handle, ··· 424 424 <div class="text-center mb-4 mt-6"> 425 425 <h3 class="text-2xl font-bold text-red-600 mb-2 tracking-wide">Final Boarding Call</h3> 426 426 <p class="text-gray-700 dark:text-gray-300 mb-2 text-base"> 427 - <span class="font-semibold text-red-500">Warning:</span> This migration process can be <strong>irreversible</strong>.<br />Airport is in <strong>alpha</strong> currently, and we don't recommend it for main accounts. Migrate at your own risk. We reccomend backing up your data before proceeding. 427 + <span class="font-semibold text-red-500">Warning:</span> This migration is <strong>irreversible</strong> if coming from Bluesky servers.<br />Bluesky does not recommend it for main accounts. Migrate at your own risk. We reccomend backing up your data before proceeding. 428 428 </p> 429 429 <p class="text-gray-700 dark:text-gray-300 mb-4 text-base"> 430 430 Please type <span class="font-mono font-bold text-blue-600">MIGRATE</span> below to confirm and proceed.
+2 -17
routes/index.tsx
··· 1 1 import Ticket from "../islands/Ticket.tsx"; 2 2 import AirportSign from "../components/AirportSign.tsx"; 3 3 import SocialLinks from "../islands/SocialLinks.tsx"; 4 - import { Button } from "../components/Button.tsx"; 4 + import LoginButton from "../islands/LoginButton.tsx"; 5 5 6 6 export default function Home() { 7 7 return ( ··· 14 14 <p class="font-mono text-lg sm:text-xl font-bold mb-4 sm:mb-6 mt-0 text-center text-gray-600 dark:text-gray-300"> 15 15 Your terminal for seamless AT Protocol PDS migration and backup. 16 16 </p> 17 - <p class="font-mono mb-4 sm:mb-6 mt-0 text-center text-gray-600 dark:text-gray-300"> 18 - Airport is in <strong>alpha</strong> currently, and we don't recommend it for main accounts. <br/> Please use its migration tools at your own risk. 19 - </p> 20 17 21 18 <Ticket /> 22 19 23 - <div class="mt-6 sm:mt-8 text-center w-fit mx-auto"> 24 - <Button 25 - href="/login" 26 - color="blue" 27 - label="MOBILE NOT SUPPORTED" 28 - className="opacity-50 cursor-not-allowed sm:opacity-100 sm:cursor-pointer" 29 - onClick={(e: MouseEvent) => { 30 - if (globalThis.innerWidth < 640) { 31 - e.preventDefault(); 32 - } 33 - }} 34 - /> 35 - </div> 20 + <LoginButton /> 36 21 <p class="font-mono text-lg sm:text-xl mb-4 mt-4 sm:mb-6 text-center text-gray-600 dark:text-gray-300"> 37 22 Airport is made with love by <a class="text-blue-500 hover:underline" href="https://bsky.app/profile/knotbin.com">Roscoe</a> for <a class="text-blue-500 hover:underline" href="https://sprk.so">Spark</a>, a new short-video platform for AT Protocol. 38 23 </p>