1import React from 'react'; 2import { View, TouchableOpacity, Text, Image } from 'react-native'; 3 4const statusToSubtitle: Record<string, string> = { 5 cancel: 'Cancelled', 6 dismiss: 'Cancelled', 7 error: 'Failed', 8 success: 'Success', 9}; 10 11const providers: Record<string, any> = { 12 facebook: { 13 name: 'Facebook', 14 image: 15 'https://github.com/expo/expo/blob/master/docs/public/static/images/sdk/auth-session/facebook.png?raw=true', 16 color: '#1877F2', 17 }, 18 imgur: { 19 name: 'Imgur', 20 image: 21 'https://github.com/expo/expo/blob/master/docs/public/static/images/sdk/auth-session/imgur.png?raw=true', 22 color: '#1BB76E', 23 }, 24 uber: { 25 name: 'Uber', 26 image: 27 'https://github.com/expo/expo/blob/master/docs/public/static/images/sdk/auth-session/uber.png?raw=true', 28 color: '#000', 29 }, 30 google: { 31 name: 'Google', 32 image: 33 'https://github.com/expo/expo/blob/master/docs/public/static/images/sdk/auth-session/google.png?raw=true', 34 color: '#4285F4', 35 }, 36 google_firebase: { 37 name: 'Google Firebase', 38 image: 39 'https://github.com/expo/expo/blob/master/docs/public/static/images/sdk/auth-session/google.png?raw=true', 40 color: '#4285F4', 41 }, 42 azure: { 43 name: 'Azure', 44 image: 45 'https://github.com/expo/expo/blob/master/docs/public/static/images/sdk/auth-session/azure.png?raw=true', 46 color: '#0089D6', 47 }, 48 fitbit: { 49 name: 'FitBit', 50 image: 51 'https://github.com/expo/expo/blob/master/docs/public/static/images/sdk/auth-session/fitbit.png?raw=true', 52 color: '#00B0B9', 53 }, 54 reddit: { 55 name: 'Reddit', 56 image: 57 'https://github.com/expo/expo/blob/master/docs/public/static/images/sdk/auth-session/reddit.png?raw=true', 58 color: '#FF4500', 59 }, 60 dropbox: { 61 name: 'Dropbox', 62 image: 63 'https://github.com/expo/expo/blob/master/docs/public/static/images/sdk/auth-session/dropbox.png?raw=true', 64 color: '#0061FF', 65 }, 66 coinbase: { 67 name: 'Coinbase', 68 image: 69 'https://github.com/expo/expo/blob/master/docs/public/static/images/sdk/auth-session/coinbase.png?raw=true', 70 color: '#0667D0', 71 }, 72 github: { 73 name: 'Github', 74 image: 75 'https://github.com/expo/expo/blob/master/docs/public/static/images/sdk/auth-session/github.png?raw=true', 76 color: '#181717', 77 }, 78 slack: { 79 name: 'Slack', 80 image: 81 'https://github.com/expo/expo/blob/master/docs/public/static/images/sdk/auth-session/slack.png?raw=true', 82 color: '#4A154B', 83 }, 84 spotify: { 85 name: 'Spotify', 86 image: 87 'https://github.com/expo/expo/blob/master/docs/public/static/images/sdk/auth-session/spotify.png?raw=true', 88 color: '#1ED760', 89 }, 90 strava: { 91 name: 'Strava', 92 image: 93 'https://github.com/expo/expo/blob/master/docs/public/static/images/sdk/auth-session/strava.png?raw=true', 94 color: '#FC4C02', 95 }, 96 twitch: { 97 name: 'Twitch', 98 image: 99 'https://github.com/expo/expo/blob/master/docs/public/static/images/sdk/auth-session/twitch.png?raw=true', 100 color: '#9146FF', 101 }, 102 okta: { 103 name: 'Okta', 104 image: 105 'https://github.com/expo/expo/blob/master/docs/public/static/images/sdk/auth-session/okta.png?raw=true', 106 color: '#007DC1', 107 }, 108 identity4: { 109 name: 'Identity 4', 110 image: 111 'https://github.com/expo/expo/blob/master/docs/public/static/images/sdk/auth-session/identity4.png?raw=true', 112 color: '#F78C40', 113 }, 114}; 115 116function SocialImage({ image }: any) { 117 const size = 48; 118 return ( 119 <Image 120 style={{ 121 width: size, 122 height: size, 123 borderRadius: size / 2, 124 backgroundColor: 'white', 125 resizeMode: 'cover', 126 borderWidth: 1, 127 borderColor: 'white', 128 }} 129 source={image} 130 /> 131 ); 132} 133 134function Card({ style, ...props }: any) { 135 return ( 136 <TouchableOpacity 137 activeOpacity={0.6} 138 style={[ 139 { 140 backgroundColor: 'white', 141 paddingHorizontal: 12, 142 paddingVertical: 8, 143 borderRadius: 5, 144 flexDirection: 'row', 145 alignItems: 'center', 146 shadowColor: '#000', 147 shadowOffset: { 148 width: 0, 149 height: 2, 150 }, 151 shadowOpacity: 0.25, 152 shadowRadius: 3.84, 153 154 elevation: 5, 155 }, 156 style, 157 ]} 158 {...props} 159 /> 160 ); 161} 162 163export default function AuthCard({ 164 name, 165 disabled, 166 status = '', 167 url, 168 onPress, 169}: { 170 name: string; 171 url?: string | null; 172 disabled?: boolean; 173 status?: string; 174 onPress: (color: string) => void; 175}) { 176 const provider = providers[name]; 177 const subtitle = statusToSubtitle[status]; 178 179 return ( 180 <Card 181 disabled={disabled} 182 style={{ backgroundColor: provider.color, opacity: disabled ? 0.6 : 1 }} 183 onPress={() => onPress(provider.color)}> 184 <SocialImage image={{ uri: provider.image }} /> 185 <View style={{ marginLeft: 8 }}> 186 <Text style={{ fontWeight: 'bold', color: 'white' }}> 187 {disabled ? `${provider.name} is disabled` : `Sign In with ${provider.name}`} 188 </Text> 189 {subtitle && ( 190 <Text 191 style={{ 192 opacity: 0.9, 193 marginTop: 2, 194 fontSize: 14, 195 color: 'white', 196 }}> 197 {subtitle} 198 </Text> 199 )} 200 {url && ( 201 <Text 202 style={{ 203 opacity: 0.9, 204 marginTop: 2, 205 fontSize: 14, 206 color: 'white', 207 }}> 208 {url} 209 </Text> 210 )} 211 </View> 212 </Card> 213 ); 214} 215