Write on the margins of the internet. Powered by the AT Protocol. margin.at
extension web atproto comments
at main 99 lines 2.6 kB view raw
1import { useState } from "react"; 2import { useNavigate, useSearchParams, Link } from "react-router-dom"; 3import { useAuth } from "../context/AuthContext"; 4import Composer from "../components/Composer"; 5 6export default function New() { 7 const { isAuthenticated, loading } = useAuth(); 8 const navigate = useNavigate(); 9 const [searchParams] = useSearchParams(); 10 11 const initialUrl = searchParams.get("url") || ""; 12 13 let initialSelector = null; 14 const selectorParam = searchParams.get("selector"); 15 if (selectorParam) { 16 try { 17 initialSelector = JSON.parse(selectorParam); 18 } catch (e) { 19 console.error("Failed to parse selector:", e); 20 } 21 } 22 23 const legacyQuote = searchParams.get("quote") || ""; 24 if (legacyQuote && !initialSelector) { 25 initialSelector = { 26 type: "TextQuoteSelector", 27 exact: legacyQuote, 28 }; 29 } 30 31 const [url, setUrl] = useState(initialUrl); 32 33 if (loading) { 34 return ( 35 <div className="new-page"> 36 <div className="loading-spinner" /> 37 </div> 38 ); 39 } 40 41 if (!isAuthenticated) { 42 return ( 43 <div className="new-page"> 44 <div className="card" style={{ textAlign: "center", padding: "48px" }}> 45 <h2>Sign in to create annotations</h2> 46 <p style={{ color: "var(--text-secondary)", marginTop: "8px" }}> 47 You need to be logged in with your Bluesky account 48 </p> 49 <Link 50 to="/login" 51 className="btn btn-primary" 52 style={{ marginTop: "24px" }} 53 > 54 Sign in with Bluesky 55 </Link> 56 </div> 57 </div> 58 ); 59 } 60 61 const handleSuccess = () => { 62 navigate("/home"); 63 }; 64 65 return ( 66 <div className="new-page"> 67 <div className="page-header"> 68 <h1 className="page-title">New Annotation</h1> 69 <p className="page-description">Write in the margins of the web</p> 70 </div> 71 72 {!initialUrl && ( 73 <div className="url-input-wrapper"> 74 <input 75 type="url" 76 value={url} 77 onChange={(e) => setUrl(e.target.value)} 78 placeholder="https://example.com/article" 79 className="url-input" 80 required 81 /> 82 </div> 83 )} 84 85 <div className="card"> 86 <Composer 87 url={ 88 (url || initialUrl) && !/^(?:f|ht)tps?:\/\//.test(url || initialUrl) 89 ? `https://${url || initialUrl}` 90 : url || initialUrl 91 } 92 selector={initialSelector} 93 onSuccess={handleSuccess} 94 onCancel={() => navigate(-1)} 95 /> 96 </div> 97 </div> 98 ); 99}