@oxyhq/services 15.0.0 → 17.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (280) hide show
  1. package/lib/commonjs/index.js +25 -55
  2. package/lib/commonjs/index.js.map +1 -1
  3. package/lib/commonjs/ui/client.js +0 -14
  4. package/lib/commonjs/ui/client.js.map +1 -1
  5. package/lib/commonjs/ui/components/OxyAccountDialog.js +764 -0
  6. package/lib/commonjs/ui/components/OxyAccountDialog.js.map +1 -0
  7. package/lib/commonjs/ui/components/OxyProvider.js +11 -6
  8. package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
  9. package/lib/commonjs/ui/components/OxySignInButton.js +10 -21
  10. package/lib/commonjs/ui/components/OxySignInButton.js.map +1 -1
  11. package/lib/commonjs/ui/components/ProfileButton.js +25 -112
  12. package/lib/commonjs/ui/components/ProfileButton.js.map +1 -1
  13. package/lib/commonjs/ui/components/RequireOxyAuth.js +299 -0
  14. package/lib/commonjs/ui/components/RequireOxyAuth.js.map +1 -0
  15. package/lib/commonjs/ui/context/OxyContext.js +106 -2
  16. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  17. package/lib/commonjs/ui/hooks/mutations/mutationKeys.js +1 -1
  18. package/lib/commonjs/ui/hooks/mutations/useAccountMutations.js +10 -10
  19. package/lib/commonjs/ui/hooks/mutations/useAccountMutations.js.map +1 -1
  20. package/lib/commonjs/ui/hooks/queries/queryKeys.js +1 -1
  21. package/lib/commonjs/ui/hooks/queries/useAccountQueries.js +7 -8
  22. package/lib/commonjs/ui/hooks/queries/useAccountQueries.js.map +1 -1
  23. package/lib/commonjs/ui/hooks/useAuth.js +19 -30
  24. package/lib/commonjs/ui/hooks/useAuth.js.map +1 -1
  25. package/lib/commonjs/ui/hooks/useSwitchableAccounts.js +37 -267
  26. package/lib/commonjs/ui/hooks/useSwitchableAccounts.js.map +1 -1
  27. package/lib/commonjs/ui/index.js +5 -40
  28. package/lib/commonjs/ui/index.js.map +1 -1
  29. package/lib/commonjs/ui/navigation/accountDialogManager.js +91 -0
  30. package/lib/commonjs/ui/navigation/accountDialogManager.js.map +1 -0
  31. package/lib/commonjs/ui/navigation/routes.js +0 -2
  32. package/lib/commonjs/ui/navigation/routes.js.map +1 -1
  33. package/lib/commonjs/ui/screens/ConnectedAppsScreen.js +17 -18
  34. package/lib/commonjs/ui/screens/ConnectedAppsScreen.js.map +1 -1
  35. package/lib/commonjs/ui/screens/ManageAccountScreen.js +4 -3
  36. package/lib/commonjs/ui/screens/ManageAccountScreen.js.map +1 -1
  37. package/lib/commonjs/ui/session/createSessionClient.js +10 -2
  38. package/lib/commonjs/ui/session/createSessionClient.js.map +1 -1
  39. package/lib/module/index.js +20 -17
  40. package/lib/module/index.js.map +1 -1
  41. package/lib/module/ui/client.js +1 -2
  42. package/lib/module/ui/client.js.map +1 -1
  43. package/lib/module/ui/components/OxyAccountDialog.js +761 -0
  44. package/lib/module/ui/components/OxyAccountDialog.js.map +1 -0
  45. package/lib/module/ui/components/OxyProvider.js +11 -6
  46. package/lib/module/ui/components/OxyProvider.js.map +1 -1
  47. package/lib/module/ui/components/OxySignInButton.js +10 -21
  48. package/lib/module/ui/components/OxySignInButton.js.map +1 -1
  49. package/lib/module/ui/components/ProfileButton.js +26 -112
  50. package/lib/module/ui/components/ProfileButton.js.map +1 -1
  51. package/lib/module/ui/components/RequireOxyAuth.js +294 -0
  52. package/lib/module/ui/components/RequireOxyAuth.js.map +1 -0
  53. package/lib/module/ui/context/OxyContext.js +107 -3
  54. package/lib/module/ui/context/OxyContext.js.map +1 -1
  55. package/lib/module/ui/hooks/mutations/mutationKeys.js +1 -1
  56. package/lib/module/ui/hooks/mutations/useAccountMutations.js +8 -8
  57. package/lib/module/ui/hooks/mutations/useAccountMutations.js.map +1 -1
  58. package/lib/module/ui/hooks/queries/queryKeys.js +1 -1
  59. package/lib/module/ui/hooks/queries/useAccountQueries.js +5 -6
  60. package/lib/module/ui/hooks/queries/useAccountQueries.js.map +1 -1
  61. package/lib/module/ui/hooks/useAuth.js +19 -30
  62. package/lib/module/ui/hooks/useAuth.js.map +1 -1
  63. package/lib/module/ui/hooks/useSwitchableAccounts.js +38 -267
  64. package/lib/module/ui/hooks/useSwitchableAccounts.js.map +1 -1
  65. package/lib/module/ui/index.js +1 -5
  66. package/lib/module/ui/index.js.map +1 -1
  67. package/lib/module/ui/navigation/accountDialogManager.js +81 -0
  68. package/lib/module/ui/navigation/accountDialogManager.js.map +1 -0
  69. package/lib/module/ui/navigation/routes.js +0 -2
  70. package/lib/module/ui/navigation/routes.js.map +1 -1
  71. package/lib/module/ui/screens/ConnectedAppsScreen.js +19 -20
  72. package/lib/module/ui/screens/ConnectedAppsScreen.js.map +1 -1
  73. package/lib/module/ui/screens/ManageAccountScreen.js +4 -3
  74. package/lib/module/ui/screens/ManageAccountScreen.js.map +1 -1
  75. package/lib/module/ui/session/createSessionClient.js +10 -2
  76. package/lib/module/ui/session/createSessionClient.js.map +1 -1
  77. package/lib/typescript/commonjs/index.d.ts +6 -13
  78. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  79. package/lib/typescript/commonjs/ui/client.d.ts +0 -4
  80. package/lib/typescript/commonjs/ui/client.d.ts.map +1 -1
  81. package/lib/typescript/commonjs/ui/components/OxyAccountDialog.d.ts +35 -0
  82. package/lib/typescript/commonjs/ui/components/OxyAccountDialog.d.ts.map +1 -0
  83. package/lib/typescript/commonjs/ui/components/OxyProvider.d.ts +2 -2
  84. package/lib/typescript/commonjs/ui/components/OxyProvider.d.ts.map +1 -1
  85. package/lib/typescript/commonjs/ui/components/OxySignInButton.d.ts.map +1 -1
  86. package/lib/typescript/commonjs/ui/components/ProfileButton.d.ts +11 -23
  87. package/lib/typescript/commonjs/ui/components/ProfileButton.d.ts.map +1 -1
  88. package/lib/typescript/commonjs/ui/components/RequireOxyAuth.d.ts +55 -0
  89. package/lib/typescript/commonjs/ui/components/RequireOxyAuth.d.ts.map +1 -0
  90. package/lib/typescript/commonjs/ui/context/OxyContext.d.ts +13 -1
  91. package/lib/typescript/commonjs/ui/context/OxyContext.d.ts.map +1 -1
  92. package/lib/typescript/commonjs/ui/hooks/mutations/useAccountMutations.d.ts +4 -4
  93. package/lib/typescript/commonjs/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
  94. package/lib/typescript/commonjs/ui/hooks/queries/useAccountQueries.d.ts +6 -7
  95. package/lib/typescript/commonjs/ui/hooks/queries/useAccountQueries.d.ts.map +1 -1
  96. package/lib/typescript/commonjs/ui/hooks/useAuth.d.ts.map +1 -1
  97. package/lib/typescript/commonjs/ui/hooks/useSwitchableAccounts.d.ts +13 -152
  98. package/lib/typescript/commonjs/ui/hooks/useSwitchableAccounts.d.ts.map +1 -1
  99. package/lib/typescript/commonjs/ui/index.d.ts +2 -5
  100. package/lib/typescript/commonjs/ui/index.d.ts.map +1 -1
  101. package/lib/typescript/commonjs/ui/navigation/accountDialogManager.d.ts +49 -0
  102. package/lib/typescript/commonjs/ui/navigation/accountDialogManager.d.ts.map +1 -0
  103. package/lib/typescript/commonjs/ui/navigation/routes.d.ts +1 -1
  104. package/lib/typescript/commonjs/ui/navigation/routes.d.ts.map +1 -1
  105. package/lib/typescript/commonjs/ui/screens/ConnectedAppsScreen.d.ts.map +1 -1
  106. package/lib/typescript/commonjs/ui/screens/ManageAccountScreen.d.ts +1 -1
  107. package/lib/typescript/commonjs/ui/screens/ManageAccountScreen.d.ts.map +1 -1
  108. package/lib/typescript/commonjs/ui/session/createSessionClient.d.ts +9 -2
  109. package/lib/typescript/commonjs/ui/session/createSessionClient.d.ts.map +1 -1
  110. package/lib/typescript/commonjs/ui/types/navigation.d.ts +9 -0
  111. package/lib/typescript/commonjs/ui/types/navigation.d.ts.map +1 -1
  112. package/lib/typescript/commonjs/ui/utils/storageHelpers.d.ts +7 -7
  113. package/lib/typescript/module/index.d.ts +6 -13
  114. package/lib/typescript/module/index.d.ts.map +1 -1
  115. package/lib/typescript/module/ui/client.d.ts +0 -4
  116. package/lib/typescript/module/ui/client.d.ts.map +1 -1
  117. package/lib/typescript/module/ui/components/OxyAccountDialog.d.ts +35 -0
  118. package/lib/typescript/module/ui/components/OxyAccountDialog.d.ts.map +1 -0
  119. package/lib/typescript/module/ui/components/OxyProvider.d.ts +2 -2
  120. package/lib/typescript/module/ui/components/OxyProvider.d.ts.map +1 -1
  121. package/lib/typescript/module/ui/components/OxySignInButton.d.ts.map +1 -1
  122. package/lib/typescript/module/ui/components/ProfileButton.d.ts +11 -23
  123. package/lib/typescript/module/ui/components/ProfileButton.d.ts.map +1 -1
  124. package/lib/typescript/module/ui/components/RequireOxyAuth.d.ts +55 -0
  125. package/lib/typescript/module/ui/components/RequireOxyAuth.d.ts.map +1 -0
  126. package/lib/typescript/module/ui/context/OxyContext.d.ts +13 -1
  127. package/lib/typescript/module/ui/context/OxyContext.d.ts.map +1 -1
  128. package/lib/typescript/module/ui/hooks/mutations/useAccountMutations.d.ts +4 -4
  129. package/lib/typescript/module/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
  130. package/lib/typescript/module/ui/hooks/queries/useAccountQueries.d.ts +6 -7
  131. package/lib/typescript/module/ui/hooks/queries/useAccountQueries.d.ts.map +1 -1
  132. package/lib/typescript/module/ui/hooks/useAuth.d.ts.map +1 -1
  133. package/lib/typescript/module/ui/hooks/useSwitchableAccounts.d.ts +13 -152
  134. package/lib/typescript/module/ui/hooks/useSwitchableAccounts.d.ts.map +1 -1
  135. package/lib/typescript/module/ui/index.d.ts +2 -5
  136. package/lib/typescript/module/ui/index.d.ts.map +1 -1
  137. package/lib/typescript/module/ui/navigation/accountDialogManager.d.ts +49 -0
  138. package/lib/typescript/module/ui/navigation/accountDialogManager.d.ts.map +1 -0
  139. package/lib/typescript/module/ui/navigation/routes.d.ts +1 -1
  140. package/lib/typescript/module/ui/navigation/routes.d.ts.map +1 -1
  141. package/lib/typescript/module/ui/screens/ConnectedAppsScreen.d.ts.map +1 -1
  142. package/lib/typescript/module/ui/screens/ManageAccountScreen.d.ts +1 -1
  143. package/lib/typescript/module/ui/screens/ManageAccountScreen.d.ts.map +1 -1
  144. package/lib/typescript/module/ui/session/createSessionClient.d.ts +9 -2
  145. package/lib/typescript/module/ui/session/createSessionClient.d.ts.map +1 -1
  146. package/lib/typescript/module/ui/types/navigation.d.ts +9 -0
  147. package/lib/typescript/module/ui/types/navigation.d.ts.map +1 -1
  148. package/lib/typescript/module/ui/utils/storageHelpers.d.ts +7 -7
  149. package/package.json +4 -4
  150. package/src/index.ts +23 -28
  151. package/src/ui/client.ts +0 -4
  152. package/src/ui/components/OxyAccountDialog.tsx +760 -0
  153. package/src/ui/components/OxyProvider.tsx +12 -6
  154. package/src/ui/components/OxySignInButton.tsx +10 -21
  155. package/src/ui/components/ProfileButton.tsx +23 -126
  156. package/src/ui/components/RequireOxyAuth.tsx +266 -0
  157. package/src/ui/context/OxyContext.tsx +146 -7
  158. package/src/ui/hooks/mutations/mutationKeys.ts +1 -1
  159. package/src/ui/hooks/mutations/useAccountMutations.ts +8 -8
  160. package/src/ui/hooks/queries/queryKeys.ts +1 -1
  161. package/src/ui/hooks/queries/useAccountQueries.ts +8 -9
  162. package/src/ui/hooks/useAuth.ts +19 -31
  163. package/src/ui/hooks/useSwitchableAccounts.ts +42 -376
  164. package/src/ui/index.ts +2 -5
  165. package/src/ui/navigation/accountDialogManager.ts +84 -0
  166. package/src/ui/navigation/routes.ts +1 -5
  167. package/src/ui/screens/ConnectedAppsScreen.tsx +23 -24
  168. package/src/ui/screens/ManageAccountScreen.tsx +3 -2
  169. package/src/ui/session/createSessionClient.ts +9 -1
  170. package/src/ui/types/navigation.ts +9 -0
  171. package/src/ui/utils/storageHelpers.ts +7 -7
  172. package/lib/commonjs/ui/components/AccountMenu.js +0 -598
  173. package/lib/commonjs/ui/components/AccountMenu.js.map +0 -1
  174. package/lib/commonjs/ui/components/AccountMenuButton.js +0 -135
  175. package/lib/commonjs/ui/components/AccountMenuButton.js.map +0 -1
  176. package/lib/commonjs/ui/components/AccountSwitcher.js +0 -780
  177. package/lib/commonjs/ui/components/AccountSwitcher.js.map +0 -1
  178. package/lib/commonjs/ui/components/AnotherDeviceQR.js +0 -116
  179. package/lib/commonjs/ui/components/AnotherDeviceQR.js.map +0 -1
  180. package/lib/commonjs/ui/components/ProfileMenu.js +0 -518
  181. package/lib/commonjs/ui/components/ProfileMenu.js.map +0 -1
  182. package/lib/commonjs/ui/components/SignInAccountChooser.js +0 -189
  183. package/lib/commonjs/ui/components/SignInAccountChooser.js.map +0 -1
  184. package/lib/commonjs/ui/components/SignInModal.js +0 -600
  185. package/lib/commonjs/ui/components/SignInModal.js.map +0 -1
  186. package/lib/commonjs/ui/hooks/useOxyAuthSession.js +0 -501
  187. package/lib/commonjs/ui/hooks/useOxyAuthSession.js.map +0 -1
  188. package/lib/commonjs/ui/hooks/usePasswordSignIn.js +0 -170
  189. package/lib/commonjs/ui/hooks/usePasswordSignIn.js.map +0 -1
  190. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +0 -51
  191. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +0 -1
  192. package/lib/commonjs/ui/screens/OxyAuthScreen.js +0 -312
  193. package/lib/commonjs/ui/screens/OxyAuthScreen.js.map +0 -1
  194. package/lib/commonjs/utils/deviceFlowSignIn.js +0 -109
  195. package/lib/commonjs/utils/deviceFlowSignIn.js.map +0 -1
  196. package/lib/module/ui/components/AccountMenu.js +0 -593
  197. package/lib/module/ui/components/AccountMenu.js.map +0 -1
  198. package/lib/module/ui/components/AccountMenuButton.js +0 -130
  199. package/lib/module/ui/components/AccountMenuButton.js.map +0 -1
  200. package/lib/module/ui/components/AccountSwitcher.js +0 -774
  201. package/lib/module/ui/components/AccountSwitcher.js.map +0 -1
  202. package/lib/module/ui/components/AnotherDeviceQR.js +0 -110
  203. package/lib/module/ui/components/AnotherDeviceQR.js.map +0 -1
  204. package/lib/module/ui/components/ProfileMenu.js +0 -514
  205. package/lib/module/ui/components/ProfileMenu.js.map +0 -1
  206. package/lib/module/ui/components/SignInAccountChooser.js +0 -183
  207. package/lib/module/ui/components/SignInAccountChooser.js.map +0 -1
  208. package/lib/module/ui/components/SignInModal.js +0 -591
  209. package/lib/module/ui/components/SignInModal.js.map +0 -1
  210. package/lib/module/ui/hooks/useOxyAuthSession.js +0 -495
  211. package/lib/module/ui/hooks/useOxyAuthSession.js.map +0 -1
  212. package/lib/module/ui/hooks/usePasswordSignIn.js +0 -165
  213. package/lib/module/ui/hooks/usePasswordSignIn.js.map +0 -1
  214. package/lib/module/ui/screens/AccountSwitcherScreen.js +0 -48
  215. package/lib/module/ui/screens/AccountSwitcherScreen.js.map +0 -1
  216. package/lib/module/ui/screens/OxyAuthScreen.js +0 -306
  217. package/lib/module/ui/screens/OxyAuthScreen.js.map +0 -1
  218. package/lib/module/utils/deviceFlowSignIn.js +0 -106
  219. package/lib/module/utils/deviceFlowSignIn.js.map +0 -1
  220. package/lib/typescript/commonjs/ui/components/AccountMenu.d.ts +0 -47
  221. package/lib/typescript/commonjs/ui/components/AccountMenu.d.ts.map +0 -1
  222. package/lib/typescript/commonjs/ui/components/AccountMenuButton.d.ts +0 -26
  223. package/lib/typescript/commonjs/ui/components/AccountMenuButton.d.ts.map +0 -1
  224. package/lib/typescript/commonjs/ui/components/AccountSwitcher.d.ts +0 -46
  225. package/lib/typescript/commonjs/ui/components/AccountSwitcher.d.ts.map +0 -1
  226. package/lib/typescript/commonjs/ui/components/AnotherDeviceQR.d.ts +0 -34
  227. package/lib/typescript/commonjs/ui/components/AnotherDeviceQR.d.ts.map +0 -1
  228. package/lib/typescript/commonjs/ui/components/ProfileMenu.d.ts +0 -49
  229. package/lib/typescript/commonjs/ui/components/ProfileMenu.d.ts.map +0 -1
  230. package/lib/typescript/commonjs/ui/components/SignInAccountChooser.d.ts +0 -29
  231. package/lib/typescript/commonjs/ui/components/SignInAccountChooser.d.ts.map +0 -1
  232. package/lib/typescript/commonjs/ui/components/SignInModal.d.ts +0 -28
  233. package/lib/typescript/commonjs/ui/components/SignInModal.d.ts.map +0 -1
  234. package/lib/typescript/commonjs/ui/hooks/useOxyAuthSession.d.ts +0 -105
  235. package/lib/typescript/commonjs/ui/hooks/useOxyAuthSession.d.ts.map +0 -1
  236. package/lib/typescript/commonjs/ui/hooks/usePasswordSignIn.d.ts +0 -31
  237. package/lib/typescript/commonjs/ui/hooks/usePasswordSignIn.d.ts.map +0 -1
  238. package/lib/typescript/commonjs/ui/screens/AccountSwitcherScreen.d.ts +0 -11
  239. package/lib/typescript/commonjs/ui/screens/AccountSwitcherScreen.d.ts.map +0 -1
  240. package/lib/typescript/commonjs/ui/screens/OxyAuthScreen.d.ts +0 -22
  241. package/lib/typescript/commonjs/ui/screens/OxyAuthScreen.d.ts.map +0 -1
  242. package/lib/typescript/commonjs/utils/deviceFlowSignIn.d.ts +0 -97
  243. package/lib/typescript/commonjs/utils/deviceFlowSignIn.d.ts.map +0 -1
  244. package/lib/typescript/module/ui/components/AccountMenu.d.ts +0 -47
  245. package/lib/typescript/module/ui/components/AccountMenu.d.ts.map +0 -1
  246. package/lib/typescript/module/ui/components/AccountMenuButton.d.ts +0 -26
  247. package/lib/typescript/module/ui/components/AccountMenuButton.d.ts.map +0 -1
  248. package/lib/typescript/module/ui/components/AccountSwitcher.d.ts +0 -46
  249. package/lib/typescript/module/ui/components/AccountSwitcher.d.ts.map +0 -1
  250. package/lib/typescript/module/ui/components/AnotherDeviceQR.d.ts +0 -34
  251. package/lib/typescript/module/ui/components/AnotherDeviceQR.d.ts.map +0 -1
  252. package/lib/typescript/module/ui/components/ProfileMenu.d.ts +0 -49
  253. package/lib/typescript/module/ui/components/ProfileMenu.d.ts.map +0 -1
  254. package/lib/typescript/module/ui/components/SignInAccountChooser.d.ts +0 -29
  255. package/lib/typescript/module/ui/components/SignInAccountChooser.d.ts.map +0 -1
  256. package/lib/typescript/module/ui/components/SignInModal.d.ts +0 -28
  257. package/lib/typescript/module/ui/components/SignInModal.d.ts.map +0 -1
  258. package/lib/typescript/module/ui/hooks/useOxyAuthSession.d.ts +0 -105
  259. package/lib/typescript/module/ui/hooks/useOxyAuthSession.d.ts.map +0 -1
  260. package/lib/typescript/module/ui/hooks/usePasswordSignIn.d.ts +0 -31
  261. package/lib/typescript/module/ui/hooks/usePasswordSignIn.d.ts.map +0 -1
  262. package/lib/typescript/module/ui/screens/AccountSwitcherScreen.d.ts +0 -11
  263. package/lib/typescript/module/ui/screens/AccountSwitcherScreen.d.ts.map +0 -1
  264. package/lib/typescript/module/ui/screens/OxyAuthScreen.d.ts +0 -22
  265. package/lib/typescript/module/ui/screens/OxyAuthScreen.d.ts.map +0 -1
  266. package/lib/typescript/module/utils/deviceFlowSignIn.d.ts +0 -97
  267. package/lib/typescript/module/utils/deviceFlowSignIn.d.ts.map +0 -1
  268. package/src/ui/components/AccountMenu.tsx +0 -645
  269. package/src/ui/components/AccountMenuButton.tsx +0 -126
  270. package/src/ui/components/AccountSwitcher.tsx +0 -751
  271. package/src/ui/components/AnotherDeviceQR.tsx +0 -119
  272. package/src/ui/components/ProfileMenu.tsx +0 -564
  273. package/src/ui/components/SignInAccountChooser.tsx +0 -162
  274. package/src/ui/components/SignInModal.tsx +0 -530
  275. package/src/ui/hooks/useOxyAuthSession.ts +0 -635
  276. package/src/ui/hooks/usePasswordSignIn.ts +0 -207
  277. package/src/ui/screens/AccountSwitcherScreen.tsx +0 -43
  278. package/src/ui/screens/OxyAuthScreen.tsx +0 -324
  279. package/src/utils/__tests__/deviceFlowSignIn.test.ts +0 -231
  280. package/src/utils/deviceFlowSignIn.ts +0 -152
@@ -1,162 +0,0 @@
1
- import type React from 'react';
2
- import { View, Text, TouchableOpacity, StyleSheet, ActivityIndicator } from 'react-native';
3
- import { Ionicons } from '@expo/vector-icons';
4
- import { useTheme } from '@oxyhq/bloom/theme';
5
- import Avatar from './Avatar';
6
- import { useI18n } from '../hooks/useI18n';
7
- import type { SwitchableAccount } from '../hooks/useSwitchableAccounts';
8
-
9
- export interface SignInAccountChooserProps {
10
- /** Accounts available on this device / in the caller's graph, current first. */
11
- accounts: SwitchableAccount[];
12
- /** Selecting a row — the active account continues, others switch into. */
13
- onSelectAccount: (account: SwitchableAccount) => void;
14
- /** "Use another account" → reveal the sign-in options (password / QR / add). */
15
- onUseAnother: () => void;
16
- /** The account id currently being switched into (shows a per-row spinner). */
17
- pendingAccountId?: string | null;
18
- /** Disables every row while a selection is in flight. */
19
- disabled?: boolean;
20
- }
21
-
22
- /**
23
- * Google-style account chooser (React Native). Lists every account the user can
24
- * continue as — device sign-ins + linked graph accounts, from
25
- * {@link SwitchableAccount} — plus a "Use another account" affordance. Rendered
26
- * as the FRONT screen of the sign-in surfaces (`SignInModal` web,
27
- * `OxyAuthScreen` native) whenever accounts exist; selecting a row funnels into
28
- * the SAME `switchToAccount` path the account switcher uses. When no accounts
29
- * exist the surfaces skip this and show the sign-in options directly.
30
- *
31
- * Presentational + chrome-agnostic (no modal/sheet wrapper, no data fetching) so
32
- * both containers reuse it and it is unit-testable in isolation.
33
- */
34
- export const SignInAccountChooser: React.FC<SignInAccountChooserProps> = ({
35
- accounts,
36
- onSelectAccount,
37
- onUseAnother,
38
- pendingAccountId,
39
- disabled,
40
- }) => {
41
- const { colors } = useTheme();
42
- const { t } = useI18n();
43
-
44
- return (
45
- <View style={styles.container}>
46
- {accounts.map((account) => {
47
- const isPending = pendingAccountId === account.accountId;
48
- const secondary = account.email;
49
- return (
50
- <TouchableOpacity
51
- key={account.accountId}
52
- accessibilityRole="button"
53
- accessibilityLabel={t('signin.chooser.continueAs', { name: account.displayName })}
54
- accessibilityState={{ selected: account.isCurrent, disabled: Boolean(disabled) }}
55
- onPress={() => onSelectAccount(account)}
56
- disabled={disabled}
57
- activeOpacity={0.7}
58
- style={[
59
- styles.row,
60
- { borderColor: colors.border },
61
- account.isCurrent && { backgroundColor: colors.primarySubtle, borderColor: colors.primarySubtle },
62
- disabled && !isPending && styles.rowDisabled,
63
- ]}
64
- >
65
- <Avatar uri={account.avatarUrl} name={account.displayName} size={44} />
66
- <View style={styles.info}>
67
- <Text style={[styles.name, { color: colors.text }]} numberOfLines={1}>
68
- {account.displayName}
69
- </Text>
70
- {secondary ? (
71
- <Text style={[styles.secondary, { color: colors.textSecondary }]} numberOfLines={1}>
72
- {secondary}
73
- </Text>
74
- ) : null}
75
- </View>
76
- {isPending ? (
77
- <ActivityIndicator size="small" color={colors.primary} />
78
- ) : account.isCurrent ? (
79
- <View style={[styles.currentPill, { backgroundColor: colors.card }]}>
80
- <Ionicons name="checkmark" size={14} color={colors.primary} />
81
- <Text style={[styles.currentPillText, { color: colors.primary }]}>
82
- {t('signin.chooser.signedIn')}
83
- </Text>
84
- </View>
85
- ) : (
86
- <Ionicons name="chevron-forward" size={20} color={colors.textSecondary} />
87
- )}
88
- </TouchableOpacity>
89
- );
90
- })}
91
-
92
- <TouchableOpacity
93
- accessibilityRole="button"
94
- accessibilityLabel={t('signin.chooser.useAnother')}
95
- onPress={onUseAnother}
96
- disabled={disabled}
97
- activeOpacity={0.7}
98
- style={[styles.row, { borderColor: colors.border }, disabled && styles.rowDisabled]}
99
- >
100
- <View style={[styles.addIcon, { backgroundColor: colors.backgroundSecondary }]}>
101
- <Ionicons name="person-add-outline" size={20} color={colors.textSecondary} />
102
- </View>
103
- <View style={styles.info}>
104
- <Text style={[styles.name, { color: colors.text }]}>{t('signin.chooser.useAnother')}</Text>
105
- </View>
106
- <Ionicons name="chevron-forward" size={20} color={colors.textSecondary} />
107
- </TouchableOpacity>
108
- </View>
109
- );
110
- };
111
-
112
- const styles = StyleSheet.create({
113
- container: {
114
- width: '100%',
115
- gap: 8,
116
- },
117
- row: {
118
- flexDirection: 'row',
119
- alignItems: 'center',
120
- gap: 12,
121
- borderWidth: 1,
122
- borderRadius: 14,
123
- paddingHorizontal: 14,
124
- paddingVertical: 12,
125
- },
126
- rowDisabled: {
127
- opacity: 0.5,
128
- },
129
- info: {
130
- flex: 1,
131
- minWidth: 0,
132
- },
133
- name: {
134
- fontSize: 15,
135
- fontWeight: '600',
136
- },
137
- secondary: {
138
- fontSize: 13,
139
- marginTop: 2,
140
- },
141
- currentPill: {
142
- flexDirection: 'row',
143
- alignItems: 'center',
144
- gap: 3,
145
- paddingHorizontal: 8,
146
- paddingVertical: 3,
147
- borderRadius: 999,
148
- },
149
- currentPillText: {
150
- fontSize: 12,
151
- fontWeight: '600',
152
- },
153
- addIcon: {
154
- width: 44,
155
- height: 44,
156
- borderRadius: 22,
157
- alignItems: 'center',
158
- justifyContent: 'center',
159
- },
160
- });
161
-
162
- export default SignInAccountChooser;
@@ -1,530 +0,0 @@
1
- /**
2
- * SignInModal — web-first centered sign-in modal.
3
- *
4
- * Two phases, Google-style:
5
- * 1. Account chooser (FRONT screen, shown when the device/user already has
6
- * accounts): pick an account to continue as — one tap switches through the
7
- * SAME `switchToAccount` path the account switcher uses — or "Use another
8
- * account" to reveal the sign-in options.
9
- * 2. Sign-in options: the first-party password flow (identifier → password →
10
- * optional 2FA, `usePasswordSignIn`) as the PRIMARY action, with the
11
- * cross-app device flow (same-device deep-link + "sign in on another device"
12
- * QR) as a SECONDARY option below an "or" divider.
13
- *
14
- * When there are no accounts the modal opens straight on the sign-in options.
15
- * The device-flow machinery lives in the shared `useOxyAuthSession` hook (the
16
- * native `OxyAuthScreen` consumes it too — neither container re-implements the
17
- * transport). Animates with a fade + scale; per-phase content cross-fades and
18
- * respects reduced motion.
19
- */
20
-
21
- import type React from 'react';
22
- import { useState, useEffect, useCallback } from 'react';
23
- import { View, Text, TextInput, TouchableOpacity, StyleSheet, Modal, Linking, AccessibilityInfo } from 'react-native';
24
- import Animated, {
25
- useSharedValue,
26
- useAnimatedStyle,
27
- withTiming,
28
- FadeIn,
29
- } from 'react-native-reanimated';
30
- import { useSafeAreaInsets } from 'react-native-safe-area-context';
31
- import { useTheme } from '@oxyhq/bloom/theme';
32
- import { Button } from '@oxyhq/bloom/button';
33
- import { Loading } from '@oxyhq/bloom/loading';
34
- import { toast } from '@oxyhq/bloom';
35
- import { Ionicons } from '@expo/vector-icons';
36
- import { isDev, logger as loggerUtil } from '@oxyhq/core';
37
- import { useOxy } from '../context/OxyContext';
38
- import OxyLogo from './OxyLogo';
39
- import AnotherDeviceQR from './AnotherDeviceQR';
40
- import SignInAccountChooser from './SignInAccountChooser';
41
- import { useSwitchableAccounts, type SwitchableAccount } from '../hooks/useSwitchableAccounts';
42
- import { useI18n } from '../hooks/useI18n';
43
- import { useOxyAuthSession, OXY_ACCOUNTS_WEB_URL } from '../hooks/useOxyAuthSession';
44
- import { usePasswordSignIn } from '../hooks/usePasswordSignIn';
45
-
46
- // Store for modal visibility with subscription support
47
- let modalVisible = false;
48
- let setModalVisibleCallback: ((visible: boolean) => void) | null = null;
49
- const visibilityListeners = new Set<(visible: boolean) => void>();
50
-
51
- export const showSignInModal = () => {
52
- modalVisible = true;
53
- setModalVisibleCallback?.(true);
54
- for (const listener of visibilityListeners) listener(true);
55
- };
56
-
57
- export const hideSignInModal = () => {
58
- modalVisible = false;
59
- setModalVisibleCallback?.(false);
60
- for (const listener of visibilityListeners) listener(false);
61
- };
62
-
63
- export const isSignInModalVisible = () => modalVisible;
64
-
65
- /** Subscribe to modal visibility changes */
66
- export const subscribeToSignInModal = (listener: (visible: boolean) => void): (() => void) => {
67
- visibilityListeners.add(listener);
68
- return () => visibilityListeners.delete(listener);
69
- };
70
-
71
- const SignInModal: React.FC = () => {
72
- const [visible, setVisible] = useState(false);
73
- const insets = useSafeAreaInsets();
74
- const theme = useTheme();
75
-
76
- // Register the imperative visibility callback.
77
- useEffect(() => {
78
- setModalVisibleCallback = setVisible;
79
- return () => {
80
- setModalVisibleCallback = null;
81
- };
82
- }, []);
83
-
84
- if (!visible) return null;
85
-
86
- // Mounting the content only while visible preserves the session-created-on-open
87
- // / cleaned-up-on-close behaviour and resets the phase state on every reopen.
88
- return <SignInModalContent theme={theme} insets={insets} />;
89
- };
90
-
91
- interface SignInModalContentProps {
92
- theme: ReturnType<typeof useTheme>;
93
- insets: ReturnType<typeof useSafeAreaInsets>;
94
- }
95
-
96
- const SignInModalContent: React.FC<SignInModalContentProps> = ({ theme, insets }) => {
97
- const { oxyServices, handleWebSession, clientId, switchToAccount } = useOxy();
98
- const { t } = useI18n();
99
- const { accounts } = useSwitchableAccounts();
100
-
101
- // Phase: the chooser is the front screen whenever accounts exist AND the user
102
- // has not tapped "Use another account" this session.
103
- const [useAnother, setUseAnother] = useState(false);
104
- const [switchingId, setSwitchingId] = useState<string | null>(null);
105
- const showChooser = !useAnother && accounts.length > 0;
106
-
107
- const { qrData, qrPayload, isLoading, error, isWaiting, openSameDeviceApproval, retry } = useOxyAuthSession(
108
- oxyServices,
109
- clientId,
110
- handleWebSession,
111
- { onSignedIn: hideSignInModal },
112
- );
113
-
114
- // First-party password sign-in — the PRIMARY option once past the chooser.
115
- const pw = usePasswordSignIn({ onSignedIn: hideSignInModal });
116
-
117
- // Entrance animation (respects reduced motion).
118
- const opacity = useSharedValue(0);
119
- const scale = useSharedValue(0.96);
120
- // biome-ignore lint/correctness/useExhaustiveDependencies: opacity/scale are Reanimated SharedValues (stable refs), not deps; runs once on mount.
121
- useEffect(() => {
122
- let cancelled = false;
123
- AccessibilityInfo.isReduceMotionEnabled().then((reduced) => {
124
- if (cancelled) return;
125
- const duration = reduced ? 0 : 250;
126
- opacity.value = withTiming(1, { duration });
127
- scale.value = withTiming(1, { duration });
128
- });
129
- return () => {
130
- cancelled = true;
131
- };
132
- }, []);
133
-
134
- const backdropStyle = useAnimatedStyle(() => ({ opacity: opacity.value }));
135
- const contentStyle = useAnimatedStyle(() => ({
136
- opacity: opacity.value,
137
- transform: [{ scale: scale.value }],
138
- }));
139
-
140
- const handleClose = useCallback(() => hideSignInModal(), []);
141
- const handleCreateAccount = useCallback(() => Linking.openURL(OXY_ACCOUNTS_WEB_URL), []);
142
-
143
- const handleSelectAccount = useCallback(async (account: SwitchableAccount) => {
144
- // The active account is already signed in — selecting it just continues.
145
- if (account.isCurrent) {
146
- hideSignInModal();
147
- return;
148
- }
149
- if (switchingId) return;
150
- setSwitchingId(account.accountId);
151
- try {
152
- await switchToAccount(account.accountId);
153
- hideSignInModal();
154
- } catch (switchError) {
155
- if (isDev()) {
156
- loggerUtil.warn('SignInModal: switch account failed', { component: 'SignInModal' }, switchError as unknown);
157
- }
158
- toast.error(t('accountSwitcher.toasts.switchFailed') || 'Failed to switch account');
159
- } finally {
160
- setSwitchingId(null);
161
- }
162
- }, [switchingId, switchToAccount, t]);
163
-
164
- const title = showChooser ? t('signin.chooser.title') : 'Sign in to Oxy';
165
- const subtitle = showChooser
166
- ? t('signin.chooser.subtitle')
167
- : 'Continue with your Oxy identity to sign in securely.';
168
-
169
- return (
170
- <Modal visible transparent animationType="none" statusBarTranslucent onRequestClose={handleClose}>
171
- <Animated.View style={[styles.backdrop, { backgroundColor: theme.colors.overlay }, backdropStyle]}>
172
- <TouchableOpacity style={StyleSheet.absoluteFill} onPress={handleClose} activeOpacity={1} />
173
-
174
- <Animated.View
175
- style={[
176
- styles.card,
177
- { backgroundColor: theme.colors.card, paddingTop: insets.top + 28, paddingBottom: insets.bottom + 24 },
178
- contentStyle,
179
- ]}
180
- >
181
- <TouchableOpacity
182
- style={[styles.closeButton, { backgroundColor: theme.colors.backgroundSecondary }]}
183
- onPress={handleClose}
184
- accessibilityRole="button"
185
- accessibilityLabel="Close sign in"
186
- >
187
- <Ionicons name="close" size={22} color={theme.colors.textSecondary} />
188
- </TouchableOpacity>
189
-
190
- {/* Branded header */}
191
- <View style={styles.header}>
192
- <OxyLogo variant="icon" size={52} />
193
- <Text className="text-foreground" style={styles.title}>{title}</Text>
194
- <Text className="text-muted-foreground" style={styles.subtitle}>{subtitle}</Text>
195
- </View>
196
-
197
- {showChooser ? (
198
- <Animated.View key="chooser" entering={FadeIn.duration(180)} style={styles.phase}>
199
- <SignInAccountChooser
200
- accounts={accounts}
201
- onSelectAccount={handleSelectAccount}
202
- onUseAnother={() => setUseAnother(true)}
203
- pendingAccountId={switchingId}
204
- disabled={switchingId !== null}
205
- />
206
- </Animated.View>
207
- ) : (
208
- <Animated.View key="signIn" entering={FadeIn.duration(180)} style={styles.phase}>
209
- {/* Back to the chooser when accounts exist. */}
210
- {accounts.length > 0 && (
211
- <TouchableOpacity
212
- onPress={() => setUseAnother(false)}
213
- accessibilityRole="button"
214
- style={styles.backRow}
215
- >
216
- <Ionicons name="chevron-back" size={18} color={theme.colors.textSecondary} />
217
- <Text style={[styles.backText, { color: theme.colors.textSecondary }]}>{t('signin.chooser.title')}</Text>
218
- </TouchableOpacity>
219
- )}
220
-
221
- {/* PRIMARY — first-party password sign-in. Always usable; the
222
- device-flow loading/error state below never gates it. */}
223
- <View style={styles.form}>
224
- {pw.step === 'identifier' && (
225
- <TextInput
226
- style={[styles.input, { borderColor: theme.colors.border, color: theme.colors.text, backgroundColor: theme.colors.backgroundSecondary }]}
227
- value={pw.identifier}
228
- onChangeText={pw.setIdentifier}
229
- onSubmitEditing={pw.submitIdentifier}
230
- placeholder="Username or email"
231
- placeholderTextColor={theme.colors.textSecondary}
232
- autoCapitalize="none"
233
- autoCorrect={false}
234
- keyboardType="email-address"
235
- returnKeyType="next"
236
- accessibilityLabel="Username or email"
237
- />
238
- )}
239
-
240
- {pw.step === 'password' && (
241
- <>
242
- <Text style={[styles.contextText, { color: theme.colors.textSecondary }]}>{pw.identifier}</Text>
243
- <TextInput
244
- style={[styles.input, { borderColor: theme.colors.border, color: theme.colors.text, backgroundColor: theme.colors.backgroundSecondary }]}
245
- value={pw.password}
246
- onChangeText={pw.setPassword}
247
- onSubmitEditing={pw.submitPassword}
248
- placeholder="Password"
249
- placeholderTextColor={theme.colors.textSecondary}
250
- secureTextEntry
251
- autoCapitalize="none"
252
- autoCorrect={false}
253
- returnKeyType="go"
254
- accessibilityLabel="Password"
255
- />
256
- </>
257
- )}
258
-
259
- {pw.step === 'twoFactor' && (
260
- <TextInput
261
- style={[styles.input, { borderColor: theme.colors.border, color: theme.colors.text, backgroundColor: theme.colors.backgroundSecondary }]}
262
- value={pw.code}
263
- onChangeText={pw.setCode}
264
- onSubmitEditing={pw.submitTwoFactor}
265
- placeholder={pw.useBackupCode ? 'Backup code' : '6-digit code'}
266
- placeholderTextColor={theme.colors.textSecondary}
267
- autoCapitalize="none"
268
- autoCorrect={false}
269
- keyboardType={pw.useBackupCode ? 'default' : 'number-pad'}
270
- returnKeyType="go"
271
- accessibilityLabel={pw.useBackupCode ? 'Backup code' : 'Two-factor code'}
272
- />
273
- )}
274
-
275
- <Button
276
- variant="primary"
277
- onPress={
278
- pw.step === 'identifier' ? pw.submitIdentifier
279
- : pw.step === 'password' ? pw.submitPassword
280
- : pw.submitTwoFactor
281
- }
282
- loading={pw.isSubmitting}
283
- disabled={pw.isSubmitting}
284
- style={styles.primaryButton}
285
- >
286
- {pw.step === 'identifier' ? 'Continue' : pw.step === 'password' ? 'Sign in' : 'Verify'}
287
- </Button>
288
-
289
- {pw.error && (
290
- <Text className="text-destructive" style={styles.formError}>{pw.error}</Text>
291
- )}
292
-
293
- {pw.step === 'twoFactor' && (
294
- <TouchableOpacity onPress={() => pw.setUseBackupCode(!pw.useBackupCode)} accessibilityRole="button" style={styles.linkButton}>
295
- <Text style={[styles.linkText, { color: theme.colors.primary }]}>
296
- {pw.useBackupCode ? 'Use authenticator code' : 'Use a backup code'}
297
- </Text>
298
- </TouchableOpacity>
299
- )}
300
-
301
- {pw.step !== 'identifier' && (
302
- <TouchableOpacity onPress={pw.back} accessibilityRole="button" style={styles.linkButton}>
303
- <Text style={[styles.linkText, { color: theme.colors.textSecondary }]}>Back</Text>
304
- </TouchableOpacity>
305
- )}
306
- </View>
307
-
308
- {/* "or" divider */}
309
- <View style={styles.dividerRow}>
310
- <View style={[styles.dividerLine, { backgroundColor: theme.colors.border }]} />
311
- <Text style={[styles.dividerText, { color: theme.colors.textSecondary }]}>or</Text>
312
- <View style={[styles.dividerLine, { backgroundColor: theme.colors.border }]} />
313
- </View>
314
-
315
- {/* SECONDARY — cross-app device flow. Its loading/error state gates
316
- ONLY this section; the password form above is always usable. */}
317
- {isLoading ? (
318
- <View style={styles.deviceLoading}>
319
- <Loading size="small" style={styles.statusSpinner} />
320
- <Text style={[styles.statusText, { color: theme.colors.textSecondary }]}>Preparing sign in…</Text>
321
- </View>
322
- ) : error ? (
323
- <View style={styles.errorContainer}>
324
- <Text className="text-destructive" style={styles.errorText}>{error}</Text>
325
- <Button variant="secondary" onPress={retry} style={styles.secondaryButton}>Try Again</Button>
326
- </View>
327
- ) : (
328
- <>
329
- {qrPayload && (
330
- <Button
331
- variant="secondary"
332
- onPress={openSameDeviceApproval}
333
- icon={<OxyLogo variant="icon" size={20} fillColor={theme.colors.text} style={styles.buttonIcon} />}
334
- style={styles.secondaryButton}
335
- >
336
- Sign in with the Oxy app
337
- </Button>
338
- )}
339
-
340
- {isWaiting && (
341
- <View style={styles.statusContainer}>
342
- <Loading size="small" style={styles.statusSpinner} />
343
- <Text style={[styles.statusText, { color: theme.colors.textSecondary }]}>Waiting for authorization…</Text>
344
- </View>
345
- )}
346
-
347
- <View style={styles.qrSection}>
348
- <AnotherDeviceQR qrData={qrData} qrPayload={qrPayload} />
349
- </View>
350
- </>
351
- )}
352
- </Animated.View>
353
- )}
354
-
355
- {/* Footer — create an account */}
356
- <View style={styles.footer}>
357
- <Text style={styles.footerText} className="text-muted-foreground">
358
- Don't have an Oxy account?{' '}
359
- </Text>
360
- <TouchableOpacity onPress={handleCreateAccount} accessibilityRole="link">
361
- <Text style={styles.footerLink} className="text-primary">Create one</Text>
362
- </TouchableOpacity>
363
- </View>
364
- </Animated.View>
365
- </Animated.View>
366
- </Modal>
367
- );
368
- };
369
-
370
- const styles = StyleSheet.create({
371
- backdrop: {
372
- flex: 1,
373
- justifyContent: 'center',
374
- alignItems: 'center',
375
- },
376
- card: {
377
- width: '100%',
378
- maxWidth: 420,
379
- alignItems: 'center',
380
- paddingHorizontal: 24,
381
- borderRadius: 28,
382
- },
383
- closeButton: {
384
- position: 'absolute',
385
- top: 16,
386
- right: 16,
387
- width: 36,
388
- height: 36,
389
- borderRadius: 18,
390
- justifyContent: 'center',
391
- alignItems: 'center',
392
- zIndex: 10,
393
- },
394
- header: {
395
- alignItems: 'center',
396
- marginBottom: 24,
397
- },
398
- title: {
399
- fontSize: 26,
400
- fontWeight: '800',
401
- letterSpacing: -0.5,
402
- marginTop: 16,
403
- textAlign: 'center',
404
- },
405
- subtitle: {
406
- fontSize: 15,
407
- lineHeight: 21,
408
- marginTop: 8,
409
- textAlign: 'center',
410
- },
411
- phase: {
412
- width: '100%',
413
- },
414
- backRow: {
415
- flexDirection: 'row',
416
- alignItems: 'center',
417
- gap: 4,
418
- alignSelf: 'flex-start',
419
- paddingVertical: 6,
420
- marginBottom: 8,
421
- },
422
- backText: {
423
- fontSize: 14,
424
- fontWeight: '600',
425
- },
426
- primaryButton: {
427
- width: '100%',
428
- borderRadius: 12,
429
- },
430
- secondaryButton: {
431
- width: '100%',
432
- borderRadius: 12,
433
- marginTop: 12,
434
- },
435
- buttonIcon: {
436
- marginRight: 10,
437
- },
438
- form: {
439
- width: '100%',
440
- },
441
- input: {
442
- width: '100%',
443
- borderWidth: 1,
444
- borderRadius: 12,
445
- paddingHorizontal: 16,
446
- paddingVertical: 13,
447
- fontSize: 15,
448
- marginBottom: 12,
449
- },
450
- contextText: {
451
- fontSize: 14,
452
- textAlign: 'center',
453
- marginBottom: 12,
454
- },
455
- formError: {
456
- fontSize: 14,
457
- textAlign: 'center',
458
- marginTop: 12,
459
- },
460
- linkButton: {
461
- alignSelf: 'center',
462
- paddingVertical: 8,
463
- marginTop: 8,
464
- },
465
- linkText: {
466
- fontSize: 14,
467
- fontWeight: '600',
468
- },
469
- dividerRow: {
470
- flexDirection: 'row',
471
- alignItems: 'center',
472
- width: '100%',
473
- marginVertical: 20,
474
- },
475
- dividerLine: {
476
- flex: 1,
477
- height: 1,
478
- },
479
- dividerText: {
480
- marginHorizontal: 12,
481
- fontSize: 13,
482
- },
483
- deviceLoading: {
484
- flexDirection: 'row',
485
- alignItems: 'center',
486
- justifyContent: 'center',
487
- paddingVertical: 12,
488
- },
489
- statusContainer: {
490
- flexDirection: 'row',
491
- alignItems: 'center',
492
- marginTop: 20,
493
- },
494
- statusSpinner: {
495
- flex: undefined,
496
- },
497
- statusText: {
498
- marginLeft: 8,
499
- fontSize: 14,
500
- },
501
- qrSection: {
502
- width: '100%',
503
- marginTop: 24,
504
- },
505
- errorContainer: {
506
- alignItems: 'center',
507
- paddingVertical: 20,
508
- width: '100%',
509
- },
510
- errorText: {
511
- fontSize: 14,
512
- textAlign: 'center',
513
- marginBottom: 16,
514
- },
515
- footer: {
516
- flexDirection: 'row',
517
- flexWrap: 'wrap',
518
- justifyContent: 'center',
519
- marginTop: 28,
520
- },
521
- footerText: {
522
- fontSize: 14,
523
- },
524
- footerLink: {
525
- fontSize: 14,
526
- fontWeight: '600',
527
- },
528
- });
529
-
530
- export default SignInModal;