frontend client for gemstone. decentralised workplace app
at main 4.3 kB view raw
1import { GmstnLogoColor } from "@/components/icons/gmstn/GmstnLogoColor"; 2import { Text } from "@/components/primitives/Text"; 3import { useFacet } from "@/lib/facet"; 4import { lighten } from "@/lib/facet/src/lib/colors"; 5import { useOAuthSetter, useOAuthValue } from "@/providers/OAuthProvider"; 6import { useCurrentPalette } from "@/providers/ThemeProvider"; 7import { Agent } from "@atproto/api"; 8import { ArrowRight } from "lucide-react-native"; 9import { useState } from "react"; 10import { Pressable, TextInput, View } from "react-native"; 11 12export const Login = () => { 13 const { semantic } = useCurrentPalette(); 14 const { atoms, typography } = useFacet(); 15 const [atprotoHandle, setAtprotoHandle] = useState(""); 16 const oAuth = useOAuthValue(); 17 const setOAuth = useOAuthSetter(); 18 const providedOAuthClient = oAuth.client; 19 20 const handlePress = async () => { 21 const session = await providedOAuthClient.signIn(atprotoHandle); 22 23 const agent = new Agent(session); 24 setOAuth({ 25 session, 26 agent, 27 client: providedOAuthClient, 28 isLoading: false, 29 }); 30 }; 31 32 const handleSubmit = () => { 33 handlePress() 34 .then() 35 .catch((e: unknown) => { 36 console.log(e); 37 }); 38 }; 39 40 return ( 41 <View 42 style={{ 43 flex: 1, 44 flexDirection: "column", 45 alignItems: "center", 46 justifyContent: "center", 47 gap: 16, 48 }} 49 > 50 <View style={{ alignItems: "center" }}> 51 <View style={{ padding: 8, paddingLeft: 12, paddingTop: 12 }}> 52 <GmstnLogoColor height={36} width={36} /> 53 </View> 54 <Text 55 style={[ 56 typography.sizes.xl, 57 typography.weights.byName.medium, 58 ]} 59 > 60 Gemstone 61 </Text> 62 </View> 63 <View style={{ gap: 10 }}> 64 <TextInput 65 style={[{ 66 flex: 1, 67 borderWidth: 1, 68 borderColor: semantic.border, 69 borderRadius: atoms.radii.lg, 70 paddingHorizontal: 14, 71 paddingVertical: 12, 72 marginRight: 8, 73 fontSize: 16, 74 color: semantic.text 75 }, typography.weights.byName.light]} 76 value={atprotoHandle} 77 onChangeText={setAtprotoHandle} 78 placeholder="alice.bsky.social" 79 onSubmitEditing={handleSubmit} 80 placeholderTextColor={semantic.textPlaceholder} 81 /> 82 <Pressable onPress={handleSubmit}> 83 {({ hovered }) => ( 84 <View 85 style={{ 86 backgroundColor: hovered 87 ? lighten(semantic.primary, 7) 88 : semantic.primary, 89 flexDirection: "row", 90 gap: 4, 91 alignItems: "center", 92 justifyContent: "center", 93 paddingVertical: 10, 94 borderRadius: atoms.radii.lg, 95 }} 96 > 97 <Text 98 style={[ 99 { color: semantic.textInverse }, 100 typography.weights.byName.normal, 101 ]} 102 > 103 Log in with ATProto 104 </Text> 105 <ArrowRight 106 height={16} 107 width={16} 108 color={semantic.textInverse} 109 /> 110 </View> 111 )} 112 </Pressable> 113 </View> 114 </View> 115 ); 116};