Write on the margins of the internet. Powered by the AT Protocol. margin.at
extension web atproto comments
at main 105 lines 3.5 kB view raw
1import React, { useState } from "react"; 2import { useNavigate, useSearchParams, Link } from "react-router-dom"; 3import { useStore } from "@nanostores/react"; 4import { $user } from "../../store/auth"; 5import Composer from "../../components/feed/Composer"; 6import type { Selector } from "../../types"; 7 8export default function NewAnnotationPage() { 9 const user = useStore($user); 10 const navigate = useNavigate(); 11 const [searchParams] = useSearchParams(); 12 13 const initialUrl = searchParams.get("url") || ""; 14 15 let initialSelector: Selector | null = null; 16 const selectorParam = searchParams.get("selector"); 17 if (selectorParam) { 18 try { 19 initialSelector = JSON.parse(selectorParam); 20 } catch (e) { 21 console.error("Failed to parse selector:", e); 22 } 23 } 24 25 const legacyQuote = searchParams.get("quote") || ""; 26 if (legacyQuote && !initialSelector) { 27 initialSelector = { 28 type: "TextQuoteSelector", 29 exact: legacyQuote, 30 }; 31 } 32 33 const [url, setUrl] = useState(initialUrl); 34 35 if (!user) { 36 return ( 37 <div className="max-w-sm mx-auto py-16 px-4"> 38 <div className="bg-white dark:bg-surface-900 rounded-xl ring-1 ring-black/5 dark:ring-white/5 p-6 text-center"> 39 <h2 className="text-xl font-bold text-surface-900 dark:text-white mb-2"> 40 Sign in to create 41 </h2> 42 <p className="text-surface-500 dark:text-surface-400 text-sm mb-5"> 43 You need a Bluesky account 44 </p> 45 <Link 46 to="/login" 47 className="block w-full py-2.5 px-4 bg-primary-600 hover:bg-primary-700 text-white font-medium rounded-lg transition-colors" 48 > 49 Sign in with Bluesky 50 </Link> 51 </div> 52 </div> 53 ); 54 } 55 56 const handleSuccess = () => { 57 navigate("/home"); 58 }; 59 60 return ( 61 <div className="max-w-2xl mx-auto pb-20"> 62 <div className="mb-6 text-center sm:text-left"> 63 <h1 className="text-2xl font-display font-bold text-surface-900 dark:text-white mb-1"> 64 New Annotation 65 </h1> 66 <p className="text-surface-500 dark:text-surface-400"> 67 Write in the margins of the web 68 </p> 69 </div> 70 71 {!initialUrl && ( 72 <div className="mb-4"> 73 <label 74 htmlFor="url-input" 75 className="block text-sm font-medium text-surface-700 dark:text-surface-300 mb-1.5" 76 > 77 URL to annotate 78 </label> 79 <input 80 id="url-input" 81 type="url" 82 value={url} 83 onChange={(e) => setUrl(e.target.value)} 84 placeholder="https://example.com/article" 85 className="w-full p-3 bg-white dark:bg-surface-900 border border-surface-200 dark:border-surface-700 rounded-lg text-surface-900 dark:text-white placeholder:text-surface-400 dark:placeholder:text-surface-500 focus:ring-2 focus:ring-primary-500/20 focus:border-primary-500 dark:focus:border-primary-400 outline-none transition-all" 86 required 87 /> 88 </div> 89 )} 90 91 <div className="bg-white dark:bg-surface-900 rounded-xl ring-1 ring-black/5 dark:ring-white/5 p-5"> 92 <Composer 93 url={ 94 (url || initialUrl) && !/^(?:f|ht)tps?:\/\//.test(url || initialUrl) 95 ? `https://${url || initialUrl}` 96 : url || initialUrl 97 } 98 selector={initialSelector} 99 onSuccess={handleSuccess} 100 onCancel={() => navigate(-1)} 101 /> 102 </div> 103 </div> 104 ); 105}