alternative tangled frontend (extremely wip)
at main 117 lines 5.0 kB view raw
1import { 2 LucideAtSign, 3 LucideCircleUserRound, 4 LucideInfo, 5 LucideLogIn, 6} from "lucide-react"; 7import { useState } from "react"; 8import { Button } from "@/components/Animated/Button"; 9import { UnderlineLink } from "@/components/Animated/UnderlinedLink"; 10import { Loading } from "@/components/Icons/Loading"; 11import { useOAuthClient } from "@/lib/oauth"; 12 13export const SignIn = () => { 14 const [handle, setHandle] = useState(""); 15 const isValidHandle = handle.includes("."); 16 const client = useOAuthClient(); 17 18 if (!client) return <Loading />; 19 20 const handleOAuthContinue = () => { 21 localStorage.setItem("handle", handle); 22 const doOAuth = async () => { 23 try { 24 await client.signIn(handle, { 25 ui_locales: "en", 26 signal: new AbortController().signal, 27 }); 28 29 console.log("Never executed"); 30 } catch (err) { 31 console.log( 32 'The user aborted the authorization process by navigating "back"', 33 ); 34 } 35 }; 36 37 doOAuth().catch((e: unknown) => { 38 console.error( 39 "Something went wrong while trying to do OAuth handover.", 40 ); 41 console.error(e); 42 }); 43 }; 44 45 const loginIcon = <LucideLogIn height={16} width={16} />; 46 47 return ( 48 <div className="bg-surface0 border-surface1 m-36 flex max-w-1/4 flex-col items-center rounded-md border-1 px-6 py-4"> 49 <LucideCircleUserRound 50 height={24} 51 width={24} 52 className="mt-4 mb-1" 53 /> 54 <h2 className="text-xl font-semibold tracking-wide">Sign In</h2> 55 <p className="text-subtext m-4"> 56 Continue with an{" "} 57 <UnderlineLink 58 href="https://atproto.com" 59 underlineColor="bg-accent" 60 className="text-accent" 61 > 62 Atmosphere 63 </UnderlineLink>{" "} 64 account 65 </p> 66 <div className="w-full"> 67 <div className="flex items-center gap-0.5"> 68 <p className="p-0.5">Handle</p> 69 <div className="group relative"> 70 <LucideInfo 71 className="text-accent cursor-pointer" 72 height={14} 73 width={14} 74 /> 75 <div className="bg-surface1 pointer-events-none absolute bottom-full left-1/2 mb-2 w-64 -translate-x-1/2 rounded-lg px-3 py-2 text-sm opacity-0 transition-opacity group-hover:pointer-events-auto group-hover:opacity-100"> 76 If you have a Bluesky, Blacksky, Tangled, or any 77 other ATProto account, you can use that account's 78 handle. 79 <div className="border-t-surface1 absolute top-full left-1/2 -translate-x-1/2 border-4 border-transparent" /> 80 </div> 81 </div> 82 </div> 83 <div className="border-surface1 group has-[:focus]:border-accent flex items-center overflow-hidden rounded-sm border transition-all"> 84 <LucideAtSign 85 className="text-subtext group-has-[:focus]:text-accent h-full w-max px-2 transition-all" 86 height={16} 87 width={16} 88 /> 89 <div className="bg-surface1 group-has-[:focus]:bg-accent w-px self-stretch transition-all" /> 90 <input 91 placeholder="akshay.tngl.sh" 92 className="peer w-full rounded-tr-sm rounded-br-sm p-1 py-2 pl-2 transition-all focus:outline-0" 93 onChange={(e) => setHandle(e.target.value)} 94 /> 95 </div> 96 </div> 97 <Button 98 label="Continue" 99 icon={loginIcon} 100 iconPosition="right" 101 className="hover:bg-accent/90 hover:text-crust hover:disabled:bg-surface1 hover:disabled:text-text bg-accent text-crust disabled:bg-surface1 disabled:text-text m-2 mt-6 mb-2 flex w-full cursor-pointer items-center justify-center gap-2 rounded-sm p-2 transition-all disabled:cursor-not-allowed" 102 disabled={!isValidHandle} 103 labelClassName="" 104 iconClassName="" 105 underlineClassName="bg-crust" 106 onClick={handleOAuthContinue} 107 iconTransitions={{ duration: 0.2, ease: "easeInOut" }} 108 iconVariants={{ 109 active: { 110 x: [0, 5, -5, 0], 111 opacity: [1, 0, 0, 1], 112 }, 113 }} 114 /> 115 </div> 116 ); 117};