@oxyhq/services 5.4.2 → 5.4.4

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 (418) hide show
  1. package/README.md +14 -0
  2. package/lib/commonjs/assets/OxyLogo.svg +1 -0
  3. package/lib/commonjs/assets/assets/OxyLogo.svg +1 -0
  4. package/lib/commonjs/assets/assets/fonts/Phudu/Phudu-Black.ttf +0 -0
  5. package/lib/commonjs/assets/assets/fonts/Phudu/Phudu-Bold.ttf +0 -0
  6. package/lib/commonjs/assets/assets/fonts/Phudu/Phudu-ExtraBold.ttf +0 -0
  7. package/lib/commonjs/assets/assets/fonts/Phudu/Phudu-Light.ttf +0 -0
  8. package/lib/commonjs/assets/assets/fonts/Phudu/Phudu-Medium.ttf +0 -0
  9. package/lib/commonjs/assets/assets/fonts/Phudu/Phudu-Regular.ttf +0 -0
  10. package/lib/commonjs/assets/assets/fonts/Phudu/Phudu-SemiBold.ttf +0 -0
  11. package/lib/commonjs/assets/assets/icons/OxyServices.tsx +67 -0
  12. package/lib/commonjs/assets/assets/icons/logo_OxyServices.svg +1 -0
  13. package/lib/commonjs/assets/assets/illustrations/HighFive.tsx +41 -0
  14. package/lib/commonjs/assets/fonts/Phudu/Phudu-Black.ttf +0 -0
  15. package/lib/commonjs/assets/fonts/Phudu/Phudu-Bold.ttf +0 -0
  16. package/lib/commonjs/assets/fonts/Phudu/Phudu-ExtraBold.ttf +0 -0
  17. package/lib/commonjs/assets/fonts/Phudu/Phudu-Light.ttf +0 -0
  18. package/lib/commonjs/assets/fonts/Phudu/Phudu-Medium.ttf +0 -0
  19. package/lib/commonjs/assets/fonts/Phudu/Phudu-Regular.ttf +0 -0
  20. package/lib/commonjs/assets/fonts/Phudu/Phudu-SemiBold.ttf +0 -0
  21. package/lib/commonjs/assets/icons/OxyServices.js +53 -0
  22. package/lib/commonjs/assets/icons/OxyServices.js.map +1 -0
  23. package/lib/commonjs/assets/icons/logo_OxyServices.svg +1 -0
  24. package/lib/commonjs/assets/illustrations/HighFive.js +61 -0
  25. package/lib/commonjs/assets/illustrations/HighFive.js.map +1 -0
  26. package/lib/commonjs/constants/version.js +28 -0
  27. package/lib/commonjs/constants/version.js.map +1 -0
  28. package/lib/commonjs/core/index.js +1660 -0
  29. package/lib/commonjs/core/index.js.map +1 -0
  30. package/lib/commonjs/index.js +160 -0
  31. package/lib/commonjs/index.js.map +1 -0
  32. package/lib/commonjs/lib/sonner.js +21 -0
  33. package/lib/commonjs/lib/sonner.js.map +1 -0
  34. package/lib/commonjs/models/interfaces.js +2 -0
  35. package/lib/commonjs/models/interfaces.js.map +1 -0
  36. package/lib/commonjs/models/secureSession.js +2 -0
  37. package/lib/commonjs/models/secureSession.js.map +1 -0
  38. package/lib/commonjs/node/createAuth.js +95 -0
  39. package/lib/commonjs/node/createAuth.js.map +1 -0
  40. package/lib/commonjs/node/index.js +63 -0
  41. package/lib/commonjs/node/index.js.map +1 -0
  42. package/lib/commonjs/package.json +1 -0
  43. package/lib/commonjs/ui/components/Avatar.js +98 -0
  44. package/lib/commonjs/ui/components/Avatar.js.map +1 -0
  45. package/lib/commonjs/ui/components/FollowButton.js +246 -0
  46. package/lib/commonjs/ui/components/FollowButton.js.map +1 -0
  47. package/lib/commonjs/ui/components/FontLoader.js +181 -0
  48. package/lib/commonjs/ui/components/FontLoader.js.map +1 -0
  49. package/lib/commonjs/ui/components/GroupedItem.js +109 -0
  50. package/lib/commonjs/ui/components/GroupedItem.js.map +1 -0
  51. package/lib/commonjs/ui/components/GroupedSection.js +33 -0
  52. package/lib/commonjs/ui/components/GroupedSection.js.map +1 -0
  53. package/lib/commonjs/ui/components/OxyLogo.js +56 -0
  54. package/lib/commonjs/ui/components/OxyLogo.js.map +1 -0
  55. package/lib/commonjs/ui/components/OxyProvider.js +522 -0
  56. package/lib/commonjs/ui/components/OxyProvider.js.map +1 -0
  57. package/lib/commonjs/ui/components/OxySignInButton.js +178 -0
  58. package/lib/commonjs/ui/components/OxySignInButton.js.map +1 -0
  59. package/lib/commonjs/ui/components/ProfileCard.js +124 -0
  60. package/lib/commonjs/ui/components/ProfileCard.js.map +1 -0
  61. package/lib/commonjs/ui/components/QuickActions.js +87 -0
  62. package/lib/commonjs/ui/components/QuickActions.js.map +1 -0
  63. package/lib/commonjs/ui/components/Section.js +36 -0
  64. package/lib/commonjs/ui/components/Section.js.map +1 -0
  65. package/lib/commonjs/ui/components/SectionTitle.js +35 -0
  66. package/lib/commonjs/ui/components/SectionTitle.js.map +1 -0
  67. package/lib/commonjs/ui/components/bottomSheet/index.js +37 -0
  68. package/lib/commonjs/ui/components/bottomSheet/index.js.map +1 -0
  69. package/lib/commonjs/ui/components/icon/OxyIcon.js +27 -0
  70. package/lib/commonjs/ui/components/icon/OxyIcon.js.map +1 -0
  71. package/lib/commonjs/ui/components/icon/index.js +14 -0
  72. package/lib/commonjs/ui/components/icon/index.js.map +1 -0
  73. package/lib/commonjs/ui/components/index.js +97 -0
  74. package/lib/commonjs/ui/components/index.js.map +1 -0
  75. package/lib/commonjs/ui/components/internal/GroupedPillButtons.js +213 -0
  76. package/lib/commonjs/ui/components/internal/GroupedPillButtons.js.map +1 -0
  77. package/lib/commonjs/ui/components/internal/TextField.js +576 -0
  78. package/lib/commonjs/ui/components/internal/TextField.js.map +1 -0
  79. package/lib/commonjs/ui/context/OxyContext.js +584 -0
  80. package/lib/commonjs/ui/context/OxyContext.js.map +1 -0
  81. package/lib/commonjs/ui/index.js +136 -0
  82. package/lib/commonjs/ui/index.js.map +1 -0
  83. package/lib/commonjs/ui/navigation/OxyRouter.js +269 -0
  84. package/lib/commonjs/ui/navigation/OxyRouter.js.map +1 -0
  85. package/lib/commonjs/ui/navigation/types.js +6 -0
  86. package/lib/commonjs/ui/navigation/types.js.map +1 -0
  87. package/lib/commonjs/ui/screens/AccountCenterScreen.js +313 -0
  88. package/lib/commonjs/ui/screens/AccountCenterScreen.js.map +1 -0
  89. package/lib/commonjs/ui/screens/AccountManagementDemo.js +299 -0
  90. package/lib/commonjs/ui/screens/AccountManagementDemo.js.map +1 -0
  91. package/lib/commonjs/ui/screens/AccountOverviewScreen.js +855 -0
  92. package/lib/commonjs/ui/screens/AccountOverviewScreen.js.map +1 -0
  93. package/lib/commonjs/ui/screens/AccountSettingsScreen.js +843 -0
  94. package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -0
  95. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +788 -0
  96. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +1 -0
  97. package/lib/commonjs/ui/screens/AppInfoScreen.js +664 -0
  98. package/lib/commonjs/ui/screens/AppInfoScreen.js.map +1 -0
  99. package/lib/commonjs/ui/screens/BillingManagementScreen.js +636 -0
  100. package/lib/commonjs/ui/screens/BillingManagementScreen.js.map +1 -0
  101. package/lib/commonjs/ui/screens/FeedbackScreen.js +1169 -0
  102. package/lib/commonjs/ui/screens/FeedbackScreen.js.map +1 -0
  103. package/lib/commonjs/ui/screens/FileManagementScreen.js +2515 -0
  104. package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -0
  105. package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js +1620 -0
  106. package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js.map +1 -0
  107. package/lib/commonjs/ui/screens/ProfileScreen.js +450 -0
  108. package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -0
  109. package/lib/commonjs/ui/screens/SessionManagementScreen.js +449 -0
  110. package/lib/commonjs/ui/screens/SessionManagementScreen.js.map +1 -0
  111. package/lib/commonjs/ui/screens/SignInScreen.js +882 -0
  112. package/lib/commonjs/ui/screens/SignInScreen.js.map +1 -0
  113. package/lib/commonjs/ui/screens/SignUpScreen.js +1036 -0
  114. package/lib/commonjs/ui/screens/SignUpScreen.js.map +1 -0
  115. package/lib/commonjs/ui/screens/karma/KarmaAboutScreen.js +88 -0
  116. package/lib/commonjs/ui/screens/karma/KarmaAboutScreen.js.map +1 -0
  117. package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js +364 -0
  118. package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js.map +1 -0
  119. package/lib/commonjs/ui/screens/karma/KarmaFAQScreen.js +227 -0
  120. package/lib/commonjs/ui/screens/karma/KarmaFAQScreen.js.map +1 -0
  121. package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js +148 -0
  122. package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -0
  123. package/lib/commonjs/ui/screens/karma/KarmaRewardsScreen.js +127 -0
  124. package/lib/commonjs/ui/screens/karma/KarmaRewardsScreen.js.map +1 -0
  125. package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js +105 -0
  126. package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js.map +1 -0
  127. package/lib/commonjs/ui/store/index.js +52 -0
  128. package/lib/commonjs/ui/store/index.js.map +1 -0
  129. package/lib/commonjs/ui/styles/FONTS.md +126 -0
  130. package/lib/commonjs/ui/styles/fonts.js +84 -0
  131. package/lib/commonjs/ui/styles/fonts.js.map +1 -0
  132. package/lib/commonjs/ui/styles/index.js +28 -0
  133. package/lib/commonjs/ui/styles/index.js.map +1 -0
  134. package/lib/commonjs/ui/styles/theme.js +121 -0
  135. package/lib/commonjs/ui/styles/theme.js.map +1 -0
  136. package/lib/commonjs/utils/deviceManager.js +173 -0
  137. package/lib/commonjs/utils/deviceManager.js.map +1 -0
  138. package/lib/commonjs/utils/index.js +13 -0
  139. package/lib/commonjs/utils/index.js.map +1 -0
  140. package/lib/commonjs/utils/polyfills.js +42 -0
  141. package/lib/commonjs/utils/polyfills.js.map +1 -0
  142. package/lib/module/assets/OxyLogo.svg +1 -0
  143. package/lib/module/assets/assets/OxyLogo.svg +1 -0
  144. package/lib/module/assets/assets/fonts/Phudu/Phudu-Black.ttf +0 -0
  145. package/lib/module/assets/assets/fonts/Phudu/Phudu-Bold.ttf +0 -0
  146. package/lib/module/assets/assets/fonts/Phudu/Phudu-ExtraBold.ttf +0 -0
  147. package/lib/module/assets/assets/fonts/Phudu/Phudu-Light.ttf +0 -0
  148. package/lib/module/assets/assets/fonts/Phudu/Phudu-Medium.ttf +0 -0
  149. package/lib/module/assets/assets/fonts/Phudu/Phudu-Regular.ttf +0 -0
  150. package/lib/module/assets/assets/fonts/Phudu/Phudu-SemiBold.ttf +0 -0
  151. package/lib/module/assets/assets/icons/OxyServices.tsx +67 -0
  152. package/lib/module/assets/assets/icons/logo_OxyServices.svg +1 -0
  153. package/lib/module/assets/assets/illustrations/HighFive.tsx +41 -0
  154. package/lib/module/assets/fonts/Phudu/Phudu-Black.ttf +0 -0
  155. package/lib/module/assets/fonts/Phudu/Phudu-Bold.ttf +0 -0
  156. package/lib/module/assets/fonts/Phudu/Phudu-ExtraBold.ttf +0 -0
  157. package/lib/module/assets/fonts/Phudu/Phudu-Light.ttf +0 -0
  158. package/lib/module/assets/fonts/Phudu/Phudu-Medium.ttf +0 -0
  159. package/lib/module/assets/fonts/Phudu/Phudu-Regular.ttf +0 -0
  160. package/lib/module/assets/fonts/Phudu/Phudu-SemiBold.ttf +0 -0
  161. package/lib/module/assets/icons/OxyServices.js +46 -0
  162. package/lib/module/assets/icons/OxyServices.js.map +1 -0
  163. package/lib/module/assets/icons/logo_OxyServices.svg +1 -0
  164. package/lib/module/assets/illustrations/HighFive.js +55 -0
  165. package/lib/module/assets/illustrations/HighFive.js.map +1 -0
  166. package/lib/module/constants/version.js +21 -0
  167. package/lib/module/constants/version.js.map +1 -0
  168. package/lib/module/core/index.js +1634 -0
  169. package/lib/module/core/index.js.map +1 -0
  170. package/lib/module/index.js +48 -0
  171. package/lib/module/index.js.map +1 -0
  172. package/lib/module/lib/sonner.js +16 -0
  173. package/lib/module/lib/sonner.js.map +1 -0
  174. package/lib/module/models/interfaces.js +2 -0
  175. package/lib/module/models/interfaces.js.map +1 -0
  176. package/lib/module/models/secureSession.js +2 -0
  177. package/lib/module/models/secureSession.js.map +1 -0
  178. package/lib/module/node/createAuth.js +90 -0
  179. package/lib/module/node/createAuth.js.map +1 -0
  180. package/lib/module/node/index.js +27 -0
  181. package/lib/module/node/index.js.map +1 -0
  182. package/lib/module/package.json +1 -0
  183. package/lib/module/ui/components/Avatar.js +93 -0
  184. package/lib/module/ui/components/Avatar.js.map +1 -0
  185. package/lib/module/ui/components/FollowButton.js +241 -0
  186. package/lib/module/ui/components/FollowButton.js.map +1 -0
  187. package/lib/module/ui/components/FontLoader.js +176 -0
  188. package/lib/module/ui/components/FontLoader.js.map +1 -0
  189. package/lib/module/ui/components/GroupedItem.js +104 -0
  190. package/lib/module/ui/components/GroupedItem.js.map +1 -0
  191. package/lib/module/ui/components/GroupedSection.js +28 -0
  192. package/lib/module/ui/components/GroupedSection.js.map +1 -0
  193. package/lib/module/ui/components/OxyLogo.js +49 -0
  194. package/lib/module/ui/components/OxyLogo.js.map +1 -0
  195. package/lib/module/ui/components/OxyProvider.js +516 -0
  196. package/lib/module/ui/components/OxyProvider.js.map +1 -0
  197. package/lib/module/ui/components/OxySignInButton.js +172 -0
  198. package/lib/module/ui/components/OxySignInButton.js.map +1 -0
  199. package/lib/module/ui/components/ProfileCard.js +119 -0
  200. package/lib/module/ui/components/ProfileCard.js.map +1 -0
  201. package/lib/module/ui/components/QuickActions.js +82 -0
  202. package/lib/module/ui/components/QuickActions.js.map +1 -0
  203. package/lib/module/ui/components/Section.js +31 -0
  204. package/lib/module/ui/components/Section.js.map +1 -0
  205. package/lib/module/ui/components/SectionTitle.js +30 -0
  206. package/lib/module/ui/components/SectionTitle.js.map +1 -0
  207. package/lib/module/ui/components/bottomSheet/index.js +5 -0
  208. package/lib/module/ui/components/bottomSheet/index.js.map +1 -0
  209. package/lib/module/ui/components/icon/OxyIcon.js +22 -0
  210. package/lib/module/ui/components/icon/OxyIcon.js.map +1 -0
  211. package/lib/module/ui/components/icon/index.js +4 -0
  212. package/lib/module/ui/components/icon/index.js.map +1 -0
  213. package/lib/module/ui/components/index.js +18 -0
  214. package/lib/module/ui/components/index.js.map +1 -0
  215. package/lib/module/ui/components/internal/GroupedPillButtons.js +208 -0
  216. package/lib/module/ui/components/internal/GroupedPillButtons.js.map +1 -0
  217. package/lib/module/ui/components/internal/TextField.js +571 -0
  218. package/lib/module/ui/components/internal/TextField.js.map +1 -0
  219. package/lib/module/ui/context/OxyContext.js +579 -0
  220. package/lib/module/ui/context/OxyContext.js.map +1 -0
  221. package/lib/module/ui/index.js +26 -0
  222. package/lib/module/ui/index.js.map +1 -0
  223. package/lib/module/ui/navigation/OxyRouter.js +262 -0
  224. package/lib/module/ui/navigation/OxyRouter.js.map +1 -0
  225. package/lib/module/ui/navigation/types.js +4 -0
  226. package/lib/module/ui/navigation/types.js.map +1 -0
  227. package/lib/module/ui/screens/AccountCenterScreen.js +308 -0
  228. package/lib/module/ui/screens/AccountCenterScreen.js.map +1 -0
  229. package/lib/module/ui/screens/AccountManagementDemo.js +296 -0
  230. package/lib/module/ui/screens/AccountManagementDemo.js.map +1 -0
  231. package/lib/module/ui/screens/AccountOverviewScreen.js +849 -0
  232. package/lib/module/ui/screens/AccountOverviewScreen.js.map +1 -0
  233. package/lib/module/ui/screens/AccountSettingsScreen.js +837 -0
  234. package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -0
  235. package/lib/module/ui/screens/AccountSwitcherScreen.js +782 -0
  236. package/lib/module/ui/screens/AccountSwitcherScreen.js.map +1 -0
  237. package/lib/module/ui/screens/AppInfoScreen.js +658 -0
  238. package/lib/module/ui/screens/AppInfoScreen.js.map +1 -0
  239. package/lib/module/ui/screens/BillingManagementScreen.js +631 -0
  240. package/lib/module/ui/screens/BillingManagementScreen.js.map +1 -0
  241. package/lib/module/ui/screens/FeedbackScreen.js +1164 -0
  242. package/lib/module/ui/screens/FeedbackScreen.js.map +1 -0
  243. package/lib/module/ui/screens/FileManagementScreen.js +2510 -0
  244. package/lib/module/ui/screens/FileManagementScreen.js.map +1 -0
  245. package/lib/module/ui/screens/PremiumSubscriptionScreen.js +1615 -0
  246. package/lib/module/ui/screens/PremiumSubscriptionScreen.js.map +1 -0
  247. package/lib/module/ui/screens/ProfileScreen.js +444 -0
  248. package/lib/module/ui/screens/ProfileScreen.js.map +1 -0
  249. package/lib/module/ui/screens/SessionManagementScreen.js +444 -0
  250. package/lib/module/ui/screens/SessionManagementScreen.js.map +1 -0
  251. package/lib/module/ui/screens/SignInScreen.js +876 -0
  252. package/lib/module/ui/screens/SignInScreen.js.map +1 -0
  253. package/lib/module/ui/screens/SignUpScreen.js +1030 -0
  254. package/lib/module/ui/screens/SignUpScreen.js.map +1 -0
  255. package/lib/module/ui/screens/karma/KarmaAboutScreen.js +83 -0
  256. package/lib/module/ui/screens/karma/KarmaAboutScreen.js.map +1 -0
  257. package/lib/module/ui/screens/karma/KarmaCenterScreen.js +358 -0
  258. package/lib/module/ui/screens/karma/KarmaCenterScreen.js.map +1 -0
  259. package/lib/module/ui/screens/karma/KarmaFAQScreen.js +222 -0
  260. package/lib/module/ui/screens/karma/KarmaFAQScreen.js.map +1 -0
  261. package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js +142 -0
  262. package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -0
  263. package/lib/module/ui/screens/karma/KarmaRewardsScreen.js +122 -0
  264. package/lib/module/ui/screens/karma/KarmaRewardsScreen.js.map +1 -0
  265. package/lib/module/ui/screens/karma/KarmaRulesScreen.js +100 -0
  266. package/lib/module/ui/screens/karma/KarmaRulesScreen.js.map +1 -0
  267. package/lib/module/ui/store/index.js +44 -0
  268. package/lib/module/ui/store/index.js.map +1 -0
  269. package/lib/module/ui/styles/FONTS.md +126 -0
  270. package/lib/module/ui/styles/fonts.js +81 -0
  271. package/lib/module/ui/styles/fonts.js.map +1 -0
  272. package/lib/module/ui/styles/index.js +5 -0
  273. package/lib/module/ui/styles/index.js.map +1 -0
  274. package/lib/module/ui/styles/theme.js +114 -0
  275. package/lib/module/ui/styles/theme.js.map +1 -0
  276. package/lib/module/utils/deviceManager.js +167 -0
  277. package/lib/module/utils/deviceManager.js.map +1 -0
  278. package/lib/module/utils/index.js +4 -0
  279. package/lib/module/utils/index.js.map +1 -0
  280. package/lib/module/utils/polyfills.js +36 -0
  281. package/lib/module/utils/polyfills.js.map +1 -0
  282. package/lib/typescript/assets/icons/OxyServices.d.ts +29 -0
  283. package/lib/typescript/assets/icons/OxyServices.d.ts.map +1 -0
  284. package/lib/typescript/assets/illustrations/HighFive.d.ts +9 -0
  285. package/lib/typescript/assets/illustrations/HighFive.d.ts.map +1 -0
  286. package/lib/typescript/constants/version.d.ts +14 -0
  287. package/lib/typescript/constants/version.d.ts.map +1 -0
  288. package/lib/typescript/core/index.d.ts +603 -0
  289. package/lib/typescript/core/index.d.ts.map +1 -0
  290. package/lib/typescript/index.d.ts +20 -0
  291. package/lib/typescript/index.d.ts.map +1 -0
  292. package/lib/typescript/lib/sonner.d.ts +6 -0
  293. package/lib/typescript/lib/sonner.d.ts.map +1 -0
  294. package/lib/typescript/models/interfaces.d.ts +179 -0
  295. package/lib/typescript/models/interfaces.d.ts.map +1 -0
  296. package/lib/typescript/models/secureSession.d.ts +27 -0
  297. package/lib/typescript/models/secureSession.d.ts.map +1 -0
  298. package/lib/typescript/node/createAuth.d.ts +7 -0
  299. package/lib/typescript/node/createAuth.d.ts.map +1 -0
  300. package/lib/typescript/node/index.d.ts +13 -0
  301. package/lib/typescript/node/index.d.ts.map +1 -0
  302. package/lib/typescript/types/expo-vector-icons.d.ts +3 -0
  303. package/lib/typescript/types/express.d.ts +5 -0
  304. package/lib/typescript/types/react-redux.d.ts +5 -0
  305. package/lib/typescript/ui/components/Avatar.d.ts +62 -0
  306. package/lib/typescript/ui/components/Avatar.d.ts.map +1 -0
  307. package/lib/typescript/ui/components/FollowButton.d.ts +92 -0
  308. package/lib/typescript/ui/components/FollowButton.d.ts.map +1 -0
  309. package/lib/typescript/ui/components/FontLoader.d.ts +15 -0
  310. package/lib/typescript/ui/components/FontLoader.d.ts.map +1 -0
  311. package/lib/typescript/ui/components/GroupedItem.d.ts +17 -0
  312. package/lib/typescript/ui/components/GroupedItem.d.ts.map +1 -0
  313. package/lib/typescript/ui/components/GroupedSection.d.ts +19 -0
  314. package/lib/typescript/ui/components/GroupedSection.d.ts.map +1 -0
  315. package/lib/typescript/ui/components/OxyLogo.d.ts +29 -0
  316. package/lib/typescript/ui/components/OxyLogo.d.ts.map +1 -0
  317. package/lib/typescript/ui/components/OxyProvider.d.ts +12 -0
  318. package/lib/typescript/ui/components/OxyProvider.d.ts.map +1 -0
  319. package/lib/typescript/ui/components/OxySignInButton.d.ts +70 -0
  320. package/lib/typescript/ui/components/OxySignInButton.d.ts.map +1 -0
  321. package/lib/typescript/ui/components/ProfileCard.d.ts +20 -0
  322. package/lib/typescript/ui/components/ProfileCard.d.ts.map +1 -0
  323. package/lib/typescript/ui/components/QuickActions.d.ts +15 -0
  324. package/lib/typescript/ui/components/QuickActions.d.ts.map +1 -0
  325. package/lib/typescript/ui/components/Section.d.ts +11 -0
  326. package/lib/typescript/ui/components/Section.d.ts.map +1 -0
  327. package/lib/typescript/ui/components/SectionTitle.d.ts +9 -0
  328. package/lib/typescript/ui/components/SectionTitle.d.ts.map +1 -0
  329. package/lib/typescript/ui/components/bottomSheet/index.d.ts +4 -0
  330. package/lib/typescript/ui/components/bottomSheet/index.d.ts.map +1 -0
  331. package/lib/typescript/ui/components/icon/OxyIcon.d.ts +10 -0
  332. package/lib/typescript/ui/components/icon/OxyIcon.d.ts.map +1 -0
  333. package/lib/typescript/ui/components/icon/index.d.ts +3 -0
  334. package/lib/typescript/ui/components/icon/index.d.ts.map +1 -0
  335. package/lib/typescript/ui/components/index.d.ts +13 -0
  336. package/lib/typescript/ui/components/index.d.ts.map +1 -0
  337. package/lib/typescript/ui/components/internal/GroupedPillButtons.d.ts +18 -0
  338. package/lib/typescript/ui/components/internal/GroupedPillButtons.d.ts.map +1 -0
  339. package/lib/typescript/ui/components/internal/TextField.d.ts +25 -0
  340. package/lib/typescript/ui/components/internal/TextField.d.ts.map +1 -0
  341. package/lib/typescript/ui/context/OxyContext.d.ts +42 -0
  342. package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -0
  343. package/lib/typescript/ui/index.d.ts +17 -0
  344. package/lib/typescript/ui/index.d.ts.map +1 -0
  345. package/lib/typescript/ui/navigation/OxyRouter.d.ts +5 -0
  346. package/lib/typescript/ui/navigation/OxyRouter.d.ts.map +1 -0
  347. package/lib/typescript/ui/navigation/types.d.ts +116 -0
  348. package/lib/typescript/ui/navigation/types.d.ts.map +1 -0
  349. package/lib/typescript/ui/screens/AccountCenterScreen.d.ts +5 -0
  350. package/lib/typescript/ui/screens/AccountCenterScreen.d.ts.map +1 -0
  351. package/lib/typescript/ui/screens/AccountManagementDemo.d.ts +8 -0
  352. package/lib/typescript/ui/screens/AccountManagementDemo.d.ts.map +1 -0
  353. package/lib/typescript/ui/screens/AccountOverviewScreen.d.ts +5 -0
  354. package/lib/typescript/ui/screens/AccountOverviewScreen.d.ts.map +1 -0
  355. package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts +5 -0
  356. package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts.map +1 -0
  357. package/lib/typescript/ui/screens/AccountSwitcherScreen.d.ts +5 -0
  358. package/lib/typescript/ui/screens/AccountSwitcherScreen.d.ts.map +1 -0
  359. package/lib/typescript/ui/screens/AppInfoScreen.d.ts +5 -0
  360. package/lib/typescript/ui/screens/AppInfoScreen.d.ts.map +1 -0
  361. package/lib/typescript/ui/screens/BillingManagementScreen.d.ts +5 -0
  362. package/lib/typescript/ui/screens/BillingManagementScreen.d.ts.map +1 -0
  363. package/lib/typescript/ui/screens/FeedbackScreen.d.ts +5 -0
  364. package/lib/typescript/ui/screens/FeedbackScreen.d.ts.map +1 -0
  365. package/lib/typescript/ui/screens/FileManagementScreen.d.ts +8 -0
  366. package/lib/typescript/ui/screens/FileManagementScreen.d.ts.map +1 -0
  367. package/lib/typescript/ui/screens/PremiumSubscriptionScreen.d.ts +5 -0
  368. package/lib/typescript/ui/screens/PremiumSubscriptionScreen.d.ts.map +1 -0
  369. package/lib/typescript/ui/screens/ProfileScreen.d.ts +9 -0
  370. package/lib/typescript/ui/screens/ProfileScreen.d.ts.map +1 -0
  371. package/lib/typescript/ui/screens/SessionManagementScreen.d.ts +5 -0
  372. package/lib/typescript/ui/screens/SessionManagementScreen.d.ts.map +1 -0
  373. package/lib/typescript/ui/screens/SignInScreen.d.ts +5 -0
  374. package/lib/typescript/ui/screens/SignInScreen.d.ts.map +1 -0
  375. package/lib/typescript/ui/screens/SignUpScreen.d.ts +5 -0
  376. package/lib/typescript/ui/screens/SignUpScreen.d.ts.map +1 -0
  377. package/lib/typescript/ui/screens/karma/KarmaAboutScreen.d.ts +5 -0
  378. package/lib/typescript/ui/screens/karma/KarmaAboutScreen.d.ts.map +1 -0
  379. package/lib/typescript/ui/screens/karma/KarmaCenterScreen.d.ts +5 -0
  380. package/lib/typescript/ui/screens/karma/KarmaCenterScreen.d.ts.map +1 -0
  381. package/lib/typescript/ui/screens/karma/KarmaFAQScreen.d.ts +5 -0
  382. package/lib/typescript/ui/screens/karma/KarmaFAQScreen.d.ts.map +1 -0
  383. package/lib/typescript/ui/screens/karma/KarmaLeaderboardScreen.d.ts +5 -0
  384. package/lib/typescript/ui/screens/karma/KarmaLeaderboardScreen.d.ts.map +1 -0
  385. package/lib/typescript/ui/screens/karma/KarmaRewardsScreen.d.ts +5 -0
  386. package/lib/typescript/ui/screens/karma/KarmaRewardsScreen.d.ts.map +1 -0
  387. package/lib/typescript/ui/screens/karma/KarmaRulesScreen.d.ts +5 -0
  388. package/lib/typescript/ui/screens/karma/KarmaRulesScreen.d.ts.map +1 -0
  389. package/lib/typescript/ui/store/index.d.ts +19 -0
  390. package/lib/typescript/ui/store/index.d.ts.map +1 -0
  391. package/lib/typescript/ui/styles/fonts.d.ts +21 -0
  392. package/lib/typescript/ui/styles/fonts.d.ts.map +1 -0
  393. package/lib/typescript/ui/styles/index.d.ts +3 -0
  394. package/lib/typescript/ui/styles/index.d.ts.map +1 -0
  395. package/lib/typescript/ui/styles/theme.d.ts +68 -0
  396. package/lib/typescript/ui/styles/theme.d.ts.map +1 -0
  397. package/lib/typescript/utils/deviceManager.d.ts +66 -0
  398. package/lib/typescript/utils/deviceManager.d.ts.map +1 -0
  399. package/lib/typescript/utils/index.d.ts +3 -0
  400. package/lib/typescript/utils/index.d.ts.map +1 -0
  401. package/lib/typescript/utils/polyfills.d.ts +6 -0
  402. package/lib/typescript/utils/polyfills.d.ts.map +1 -0
  403. package/package.json +7 -6
  404. package/src/assets/illustrations/HighFive.tsx +41 -0
  405. package/src/node/createAuth.ts +116 -0
  406. package/src/node/index.ts +4 -0
  407. package/src/types/expo-vector-icons.d.ts +3 -0
  408. package/src/types/express.d.ts +5 -0
  409. package/src/types/react-redux.d.ts +5 -0
  410. package/src/ui/components/OxyProvider.tsx +136 -135
  411. package/src/ui/components/internal/GroupedPillButtons.tsx +253 -0
  412. package/src/ui/components/internal/TextField.tsx +694 -0
  413. package/src/ui/index.ts +6 -2
  414. package/src/ui/navigation/OxyRouter.tsx +8 -3
  415. package/src/ui/screens/FeedbackScreen.tsx +1042 -0
  416. package/src/ui/screens/SignInScreen.tsx +179 -222
  417. package/src/ui/screens/SignUpScreen.tsx +772 -608
  418. package/src/ui/store/index.ts +51 -0
@@ -0,0 +1,1042 @@
1
+ import React, { useState, useRef, useEffect, useCallback, useMemo } from 'react';
2
+ import {
3
+ View,
4
+ Text,
5
+ TextInput,
6
+ TouchableOpacity,
7
+ StyleSheet,
8
+ ActivityIndicator,
9
+ Platform,
10
+ KeyboardAvoidingView,
11
+ ScrollView,
12
+ Animated,
13
+ StatusBar,
14
+ Alert,
15
+ Dimensions,
16
+ } from 'react-native';
17
+ import { BaseScreenProps } from '../navigation/types';
18
+ import { useOxy } from '../context/OxyContext';
19
+ import { useThemeColors } from '../styles';
20
+ import { Ionicons } from '@expo/vector-icons';
21
+ import { toast } from '../../lib/sonner';
22
+ import { packageInfo } from '../../constants/version';
23
+
24
+ // Types for better type safety
25
+ interface FeedbackData {
26
+ type: 'bug' | 'feature' | 'general' | 'support';
27
+ title: string;
28
+ description: string;
29
+ priority: 'low' | 'medium' | 'high' | 'critical';
30
+ category: string;
31
+ contactEmail: string;
32
+ systemInfo: boolean;
33
+ }
34
+
35
+ interface FeedbackState {
36
+ status: 'idle' | 'submitting' | 'success' | 'error';
37
+ message: string;
38
+ }
39
+
40
+ // Constants
41
+ const FEEDBACK_TYPES = [
42
+ { id: 'bug', label: 'Bug Report', icon: 'bug', color: '#FF3B30', description: 'Report a problem or issue' },
43
+ { id: 'feature', label: 'Feature Request', icon: 'bulb', color: '#007AFF', description: 'Suggest a new feature' },
44
+ { id: 'general', label: 'General Feedback', icon: 'chatbubble', color: '#34C759', description: 'Share your thoughts' },
45
+ { id: 'support', label: 'Support Request', icon: 'help-circle', color: '#FF9500', description: 'Get help with something' },
46
+ ];
47
+
48
+ const PRIORITY_LEVELS = [
49
+ { id: 'low', label: 'Low', icon: 'arrow-down', color: '#34C759' },
50
+ { id: 'medium', label: 'Medium', icon: 'remove', color: '#FF9500' },
51
+ { id: 'high', label: 'High', icon: 'arrow-up', color: '#FF3B30' },
52
+ { id: 'critical', label: 'Critical', icon: 'warning', color: '#FF0000' },
53
+ ];
54
+
55
+ const CATEGORIES = {
56
+ bug: ['UI/UX', 'Performance', 'Authentication', 'File Management', 'Billing', 'Other'],
57
+ feature: ['User Interface', 'File Management', 'Security', 'Performance', 'Integration', 'Other'],
58
+ general: ['User Experience', 'Design', 'Performance', 'Documentation', 'Other'],
59
+ support: ['Account Issues', 'Billing', 'Technical Problems', 'Feature Questions', 'Other'],
60
+ };
61
+
62
+ // Styles factory function
63
+ const createStyles = (colors: any, theme: string) => StyleSheet.create({
64
+ container: {
65
+ flex: 1,
66
+ },
67
+ scrollContent: {
68
+ flexGrow: 1,
69
+ paddingHorizontal: 24,
70
+ paddingTop: 40,
71
+ paddingBottom: 20,
72
+ },
73
+ stepContainer: {
74
+ flex: 1,
75
+ justifyContent: 'flex-start',
76
+ alignItems: 'flex-start',
77
+ },
78
+ modernHeader: {
79
+ alignItems: 'flex-start',
80
+ width: '100%',
81
+ marginBottom: 24,
82
+ },
83
+ modernTitle: {
84
+ fontFamily: Platform.OS === 'web' ? 'Phudu' : 'Phudu-Bold',
85
+ fontWeight: Platform.OS === 'web' ? 'bold' : undefined,
86
+ fontSize: 42,
87
+ lineHeight: 48,
88
+ marginBottom: 12,
89
+ textAlign: 'left',
90
+ letterSpacing: -1,
91
+ },
92
+ modernSubtitle: {
93
+ fontSize: 18,
94
+ lineHeight: 24,
95
+ textAlign: 'left',
96
+ opacity: 0.8,
97
+ marginBottom: 24,
98
+ },
99
+ stepTitle: {
100
+ fontFamily: Platform.OS === 'web' ? 'Phudu' : 'Phudu-Bold',
101
+ fontWeight: Platform.OS === 'web' ? 'bold' : undefined,
102
+ fontSize: 42,
103
+ lineHeight: 48,
104
+ marginBottom: 12,
105
+ textAlign: 'left',
106
+ letterSpacing: -1,
107
+ },
108
+ inputContainer: {
109
+ width: '100%',
110
+ marginBottom: 24,
111
+ },
112
+ premiumInputWrapper: {
113
+ flexDirection: 'row',
114
+ alignItems: 'center',
115
+ height: 56,
116
+ borderRadius: 16,
117
+ paddingHorizontal: 20,
118
+ borderWidth: 2,
119
+ backgroundColor: colors.inputBackground,
120
+ },
121
+ textAreaWrapper: {
122
+ flexDirection: 'column',
123
+ alignItems: 'flex-start',
124
+ minHeight: 120,
125
+ borderRadius: 16,
126
+ paddingHorizontal: 20,
127
+ paddingVertical: 16,
128
+ borderWidth: 2,
129
+ backgroundColor: colors.inputBackground,
130
+ },
131
+ inputIcon: {
132
+ marginRight: 12,
133
+ },
134
+ inputContent: {
135
+ flex: 1,
136
+ },
137
+ modernLabel: {
138
+ fontSize: 12,
139
+ fontWeight: '500',
140
+ marginBottom: 2,
141
+ },
142
+ modernInput: {
143
+ flex: 1,
144
+ fontSize: 16,
145
+ height: '100%',
146
+ },
147
+ textArea: {
148
+ flex: 1,
149
+ fontSize: 16,
150
+ textAlignVertical: 'top',
151
+ minHeight: 80,
152
+ },
153
+ typeGrid: {
154
+ flexDirection: 'row',
155
+ flexWrap: 'wrap',
156
+ gap: 12,
157
+ marginBottom: 24,
158
+ },
159
+ typeCard: {
160
+ width: (Dimensions.get('window').width - 72) / 2,
161
+ padding: 20,
162
+ borderRadius: 16,
163
+ borderWidth: 2,
164
+ alignItems: 'center',
165
+ justifyContent: 'center',
166
+ minHeight: 120,
167
+ },
168
+ typeIcon: {
169
+ marginBottom: 12,
170
+ },
171
+ typeLabel: {
172
+ fontSize: 16,
173
+ fontWeight: '600',
174
+ textAlign: 'center',
175
+ marginBottom: 4,
176
+ },
177
+ typeDescription: {
178
+ fontSize: 12,
179
+ textAlign: 'center',
180
+ opacity: 0.8,
181
+ },
182
+ priorityContainer: {
183
+ flexDirection: 'row',
184
+ justifyContent: 'space-between',
185
+ marginBottom: 24,
186
+ },
187
+ priorityButton: {
188
+ flex: 1,
189
+ padding: 16,
190
+ borderRadius: 12,
191
+ borderWidth: 2,
192
+ alignItems: 'center',
193
+ marginHorizontal: 4,
194
+ },
195
+ priorityLabel: {
196
+ fontSize: 12,
197
+ fontWeight: '600',
198
+ marginTop: 4,
199
+ },
200
+ categoryContainer: {
201
+ marginBottom: 24,
202
+ },
203
+ categoryButton: {
204
+ flexDirection: 'row',
205
+ alignItems: 'center',
206
+ paddingVertical: 12,
207
+ paddingHorizontal: 16,
208
+ borderRadius: 12,
209
+ borderWidth: 1,
210
+ marginBottom: 8,
211
+ },
212
+ categoryText: {
213
+ fontSize: 16,
214
+ marginLeft: 12,
215
+ },
216
+ checkboxContainer: {
217
+ flexDirection: 'row',
218
+ alignItems: 'center',
219
+ marginBottom: 24,
220
+ },
221
+ checkbox: {
222
+ width: 24,
223
+ height: 24,
224
+ borderRadius: 6,
225
+ borderWidth: 2,
226
+ marginRight: 12,
227
+ alignItems: 'center',
228
+ justifyContent: 'center',
229
+ },
230
+ checkboxText: {
231
+ fontSize: 16,
232
+ flex: 1,
233
+ },
234
+ button: {
235
+ flexDirection: 'row',
236
+ alignItems: 'center',
237
+ justifyContent: 'center',
238
+ paddingVertical: 18,
239
+ paddingHorizontal: 32,
240
+ borderRadius: 16,
241
+ marginVertical: 8,
242
+ shadowOffset: {
243
+ width: 0,
244
+ height: 4,
245
+ },
246
+ shadowOpacity: 0.3,
247
+ shadowRadius: 8,
248
+ elevation: 6,
249
+ gap: 8,
250
+ width: '100%',
251
+ },
252
+ buttonText: {
253
+ color: '#FFFFFF',
254
+ fontSize: 16,
255
+ fontWeight: '600',
256
+ letterSpacing: 0.5,
257
+ },
258
+ navigationButtons: {
259
+ flexDirection: 'row',
260
+ justifyContent: 'center',
261
+ marginTop: 16,
262
+ marginBottom: 8,
263
+ width: '100%',
264
+ gap: 8,
265
+ },
266
+ navButton: {
267
+ flexDirection: 'row',
268
+ alignItems: 'center',
269
+ paddingVertical: 6,
270
+ paddingHorizontal: 12,
271
+ gap: 6,
272
+ minWidth: 70,
273
+ borderWidth: 1,
274
+ shadowOffset: {
275
+ width: 0,
276
+ height: 2,
277
+ },
278
+ shadowOpacity: 0.1,
279
+ shadowRadius: 4,
280
+ elevation: 2,
281
+ },
282
+ backButton: {
283
+ backgroundColor: 'transparent',
284
+ borderTopLeftRadius: 35,
285
+ borderBottomLeftRadius: 35,
286
+ borderTopRightRadius: 12,
287
+ borderBottomRightRadius: 12,
288
+ },
289
+ nextButton: {
290
+ backgroundColor: 'transparent',
291
+ borderTopRightRadius: 35,
292
+ borderBottomRightRadius: 35,
293
+ borderTopLeftRadius: 12,
294
+ borderBottomLeftRadius: 12,
295
+ },
296
+ navButtonText: {
297
+ fontSize: 13,
298
+ fontWeight: '500',
299
+ },
300
+ progressContainer: {
301
+ flexDirection: 'row',
302
+ justifyContent: 'center',
303
+ marginBottom: 20,
304
+ marginTop: 8,
305
+ },
306
+ progressDot: {
307
+ height: 10,
308
+ width: 10,
309
+ borderRadius: 5,
310
+ marginHorizontal: 6,
311
+ borderWidth: 2,
312
+ borderColor: '#fff',
313
+ shadowColor: colors.primary,
314
+ shadowOpacity: 0.08,
315
+ shadowOffset: { width: 0, height: 1 },
316
+ shadowRadius: 2,
317
+ elevation: 1,
318
+ },
319
+ summaryContainer: {
320
+ padding: 0,
321
+ marginBottom: 24,
322
+ width: '100%',
323
+ },
324
+ summaryRow: {
325
+ flexDirection: 'row',
326
+ marginBottom: 10,
327
+ },
328
+ summaryLabel: {
329
+ fontSize: 15,
330
+ width: 90,
331
+ },
332
+ summaryValue: {
333
+ fontSize: 15,
334
+ fontWeight: '600',
335
+ flex: 1,
336
+ },
337
+ successContainer: {
338
+ alignItems: 'center',
339
+ justifyContent: 'center',
340
+ padding: 40,
341
+ },
342
+ successIcon: {
343
+ marginBottom: 24,
344
+ },
345
+ successTitle: {
346
+ fontSize: 24,
347
+ fontWeight: 'bold',
348
+ marginBottom: 12,
349
+ textAlign: 'center',
350
+ },
351
+ successMessage: {
352
+ fontSize: 16,
353
+ textAlign: 'center',
354
+ opacity: 0.8,
355
+ marginBottom: 24,
356
+ },
357
+ });
358
+
359
+ // Custom hooks for better separation of concerns
360
+ const useFeedbackForm = () => {
361
+ const [feedbackData, setFeedbackData] = useState<FeedbackData>({
362
+ type: 'general',
363
+ title: '',
364
+ description: '',
365
+ priority: 'medium',
366
+ category: '',
367
+ contactEmail: '',
368
+ systemInfo: true,
369
+ });
370
+
371
+ const [feedbackState, setFeedbackState] = useState<FeedbackState>({
372
+ status: 'idle',
373
+ message: ''
374
+ });
375
+
376
+ const updateField = useCallback((field: keyof FeedbackData, value: any) => {
377
+ setFeedbackData(prev => ({ ...prev, [field]: value }));
378
+ }, []);
379
+
380
+ const resetForm = useCallback(() => {
381
+ setFeedbackData({
382
+ type: 'general',
383
+ title: '',
384
+ description: '',
385
+ priority: 'medium',
386
+ category: '',
387
+ contactEmail: '',
388
+ systemInfo: true,
389
+ });
390
+ setFeedbackState({ status: 'idle', message: '' });
391
+ }, []);
392
+
393
+ return {
394
+ feedbackData,
395
+ feedbackState,
396
+ setFeedbackState,
397
+ updateField,
398
+ resetForm
399
+ };
400
+ };
401
+
402
+ // Reusable components
403
+ const FormInput: React.FC<{
404
+ icon: string;
405
+ label: string;
406
+ value: string;
407
+ onChangeText: (text: string) => void;
408
+ placeholder?: string;
409
+ multiline?: boolean;
410
+ numberOfLines?: number;
411
+ testID?: string;
412
+ colors: any;
413
+ styles: any;
414
+ borderColor?: string;
415
+ }> = React.memo(({
416
+ icon,
417
+ label,
418
+ value,
419
+ onChangeText,
420
+ placeholder,
421
+ multiline = false,
422
+ numberOfLines = 1,
423
+ testID,
424
+ colors,
425
+ styles,
426
+ borderColor,
427
+ }) => (
428
+ <View style={styles.inputContainer}>
429
+ <View style={[
430
+ multiline ? styles.textAreaWrapper : styles.premiumInputWrapper,
431
+ {
432
+ borderColor: borderColor || colors.border,
433
+ backgroundColor: colors.inputBackground,
434
+ shadowColor: colors.primary,
435
+ shadowOffset: { width: 0, height: 4 },
436
+ shadowOpacity: 0.1,
437
+ shadowRadius: 12,
438
+ elevation: 3,
439
+ }
440
+ ]}>
441
+ {!multiline && (
442
+ <Ionicons
443
+ name={icon as any}
444
+ size={22}
445
+ color={colors.secondaryText}
446
+ style={styles.inputIcon}
447
+ />
448
+ )}
449
+ <View style={styles.inputContent}>
450
+ <Text style={[styles.modernLabel, { color: colors.secondaryText }]}>
451
+ {label}
452
+ </Text>
453
+ <TextInput
454
+ style={[
455
+ multiline ? styles.textArea : styles.modernInput,
456
+ { color: colors.text }
457
+ ]}
458
+ value={value}
459
+ onChangeText={onChangeText}
460
+ placeholder={placeholder}
461
+ placeholderTextColor={colors.secondaryText + '60'}
462
+ multiline={multiline}
463
+ numberOfLines={multiline ? numberOfLines : undefined}
464
+ testID={testID}
465
+ />
466
+ </View>
467
+ </View>
468
+ </View>
469
+ ));
470
+
471
+ const ProgressIndicator: React.FC<{ currentStep: number; totalSteps: number; colors: any; styles: any }> = React.memo(({ currentStep, totalSteps, colors, styles }) => (
472
+ <View style={styles.progressContainer}>
473
+ {Array.from({ length: totalSteps }, (_, index) => (
474
+ <View
475
+ key={index}
476
+ style={[
477
+ styles.progressDot,
478
+ currentStep === index ?
479
+ { backgroundColor: colors.primary, width: 24 } :
480
+ { backgroundColor: colors.border }
481
+ ]}
482
+ />
483
+ ))}
484
+ </View>
485
+ ));
486
+
487
+ // Main component
488
+ const FeedbackScreen: React.FC<BaseScreenProps> = ({
489
+ navigate,
490
+ goBack,
491
+ onClose,
492
+ theme,
493
+ }) => {
494
+ const { user, oxyServices } = useOxy();
495
+ const colors = useThemeColors(theme);
496
+
497
+ // Form state
498
+ const { feedbackData, feedbackState, setFeedbackState, updateField, resetForm } = useFeedbackForm();
499
+
500
+ // UI state
501
+ const [currentStep, setCurrentStep] = useState(0);
502
+ const [errorMessage, setErrorMessage] = useState('');
503
+
504
+ // Animation refs
505
+ const fadeAnim = useRef(new Animated.Value(1)).current;
506
+ const slideAnim = useRef(new Animated.Value(0)).current;
507
+
508
+ // Memoized styles
509
+ const styles = useMemo(() => createStyles(colors, theme), [colors, theme]);
510
+
511
+ // Animation functions
512
+ const animateTransition = useCallback((nextStep: number) => {
513
+ Animated.timing(fadeAnim, {
514
+ toValue: 0,
515
+ duration: 250,
516
+ useNativeDriver: true,
517
+ }).start(() => {
518
+ setCurrentStep(nextStep);
519
+ slideAnim.setValue(-100);
520
+
521
+ Animated.parallel([
522
+ Animated.timing(fadeAnim, {
523
+ toValue: 1,
524
+ duration: 250,
525
+ useNativeDriver: true,
526
+ }),
527
+ Animated.timing(slideAnim, {
528
+ toValue: 0,
529
+ duration: 300,
530
+ useNativeDriver: true,
531
+ })
532
+ ]).start();
533
+ });
534
+ }, [fadeAnim, slideAnim]);
535
+
536
+ const nextStep = useCallback(() => {
537
+ if (currentStep < 3) {
538
+ animateTransition(currentStep + 1);
539
+ }
540
+ }, [currentStep, animateTransition]);
541
+
542
+ const prevStep = useCallback(() => {
543
+ if (currentStep > 0) {
544
+ animateTransition(currentStep - 1);
545
+ }
546
+ }, [currentStep, animateTransition]);
547
+
548
+ // Form validation helpers
549
+ const isTypeStepValid = useCallback(() => {
550
+ return feedbackData.type && feedbackData.category;
551
+ }, [feedbackData.type, feedbackData.category]);
552
+
553
+ const isDetailsStepValid = useCallback(() => {
554
+ return feedbackData.title.trim() && feedbackData.description.trim();
555
+ }, [feedbackData.title, feedbackData.description]);
556
+
557
+ const isContactStepValid = useCallback(() => {
558
+ return feedbackData.contactEmail.trim() || user?.email;
559
+ }, [feedbackData.contactEmail, user?.email]);
560
+
561
+ // Submit feedback handler
562
+ const handleSubmitFeedback = useCallback(async () => {
563
+ if (!isTypeStepValid() || !isDetailsStepValid() || !isContactStepValid()) {
564
+ toast.error('Please fill in all required fields');
565
+ return;
566
+ }
567
+
568
+ try {
569
+ setFeedbackState({ status: 'submitting', message: '' });
570
+ setErrorMessage('');
571
+
572
+ // Prepare feedback data
573
+ const feedbackPayload = {
574
+ type: feedbackData.type,
575
+ title: feedbackData.title,
576
+ description: feedbackData.description,
577
+ priority: feedbackData.priority,
578
+ category: feedbackData.category,
579
+ contactEmail: feedbackData.contactEmail || user?.email,
580
+ systemInfo: feedbackData.systemInfo ? {
581
+ platform: Platform.OS,
582
+ version: Platform.Version?.toString() || 'Unknown',
583
+ appVersion: packageInfo.version,
584
+ userId: user?.id,
585
+ username: user?.username,
586
+ timestamp: new Date().toISOString(),
587
+ } : undefined,
588
+ };
589
+
590
+ // For now, we'll simulate the API call
591
+ // In a real implementation, you would call oxyServices.submitFeedback(feedbackPayload)
592
+ await new Promise(resolve => setTimeout(resolve, 2000)); // Simulate API call
593
+
594
+ setFeedbackState({ status: 'success', message: 'Feedback submitted successfully!' });
595
+ toast.success('Thank you for your feedback!');
596
+
597
+ // Reset form after success
598
+ setTimeout(() => {
599
+ resetForm();
600
+ setCurrentStep(0);
601
+ }, 3000);
602
+
603
+ } catch (error: any) {
604
+ setFeedbackState({ status: 'error', message: error.message || 'Failed to submit feedback' });
605
+ toast.error(error.message || 'Failed to submit feedback');
606
+ }
607
+ }, [feedbackData, user, isTypeStepValid, isDetailsStepValid, isContactStepValid, resetForm]);
608
+
609
+ // Step components
610
+ const renderTypeStep = useCallback(() => (
611
+ <Animated.View style={[
612
+ styles.stepContainer,
613
+ { opacity: fadeAnim, transform: [{ translateX: slideAnim }] }
614
+ ]}>
615
+ <View style={styles.modernHeader}>
616
+ <Text style={[styles.stepTitle, { color: colors.text }]}>
617
+ What type of feedback?
618
+ </Text>
619
+ <Text style={[styles.modernSubtitle, { color: colors.secondaryText }]}>
620
+ Choose the category that best describes your feedback
621
+ </Text>
622
+ </View>
623
+
624
+ <View style={styles.typeGrid}>
625
+ {FEEDBACK_TYPES.map((type) => (
626
+ <TouchableOpacity
627
+ key={type.id}
628
+ style={[
629
+ styles.typeCard,
630
+ {
631
+ borderColor: feedbackData.type === type.id ? type.color : colors.border,
632
+ backgroundColor: feedbackData.type === type.id ? type.color + '10' : colors.inputBackground,
633
+ }
634
+ ]}
635
+ onPress={() => {
636
+ updateField('type', type.id);
637
+ updateField('category', '');
638
+ }}
639
+ >
640
+ <View style={[styles.typeIcon, { backgroundColor: type.color + '20', padding: 12, borderRadius: 12 }]}>
641
+ <Ionicons name={type.icon as any} size={24} color={type.color} />
642
+ </View>
643
+ <Text style={[styles.typeLabel, { color: colors.text }]}>
644
+ {type.label}
645
+ </Text>
646
+ <Text style={[styles.typeDescription, { color: colors.secondaryText }]}>
647
+ {type.description}
648
+ </Text>
649
+ </TouchableOpacity>
650
+ ))}
651
+ </View>
652
+
653
+ {feedbackData.type && (
654
+ <View style={styles.categoryContainer}>
655
+ <Text style={[styles.modernLabel, { color: colors.secondaryText, marginBottom: 12 }]}>
656
+ Category
657
+ </Text>
658
+ {CATEGORIES[feedbackData.type as keyof typeof CATEGORIES]?.map((category) => (
659
+ <TouchableOpacity
660
+ key={category}
661
+ style={[
662
+ styles.categoryButton,
663
+ {
664
+ borderColor: feedbackData.category === category ? colors.primary : colors.border,
665
+ backgroundColor: feedbackData.category === category ? colors.primary + '10' : colors.inputBackground,
666
+ }
667
+ ]}
668
+ onPress={() => updateField('category', category)}
669
+ >
670
+ <Ionicons
671
+ name={feedbackData.category === category ? 'checkmark-circle' : 'ellipse-outline'}
672
+ size={20}
673
+ color={feedbackData.category === category ? colors.primary : colors.secondaryText}
674
+ />
675
+ <Text style={[styles.categoryText, { color: colors.text }]}>
676
+ {category}
677
+ </Text>
678
+ </TouchableOpacity>
679
+ ))}
680
+ </View>
681
+ )}
682
+
683
+ <View style={styles.navigationButtons}>
684
+ <TouchableOpacity
685
+ style={[styles.navButton, {
686
+ backgroundColor: 'transparent',
687
+ borderColor: colors.border,
688
+ shadowColor: colors.border,
689
+ borderTopLeftRadius: 35,
690
+ borderBottomLeftRadius: 35,
691
+ borderTopRightRadius: 35,
692
+ borderBottomRightRadius: 35,
693
+ }]}
694
+ onPress={goBack}
695
+ >
696
+ <Ionicons name="arrow-back" size={16} color={colors.text} />
697
+ <Text style={[styles.navButtonText, { color: colors.text }]}>Back</Text>
698
+ </TouchableOpacity>
699
+
700
+ <TouchableOpacity
701
+ style={[styles.navButton, {
702
+ backgroundColor: colors.primary,
703
+ borderColor: colors.primary,
704
+ shadowColor: colors.primary,
705
+ borderTopLeftRadius: 35,
706
+ borderBottomLeftRadius: 35,
707
+ borderTopRightRadius: 35,
708
+ borderBottomRightRadius: 35,
709
+ }]}
710
+ onPress={nextStep}
711
+ disabled={!isTypeStepValid()}
712
+ >
713
+ <Text style={[styles.navButtonText, { color: '#FFFFFF' }]}>Next</Text>
714
+ <Ionicons name="arrow-forward" size={16} color="#FFFFFF" />
715
+ </TouchableOpacity>
716
+ </View>
717
+ </Animated.View>
718
+ ), [fadeAnim, slideAnim, colors, feedbackData, updateField, goBack, nextStep, isTypeStepValid, styles]);
719
+
720
+ const renderDetailsStep = useCallback(() => (
721
+ <Animated.View style={[
722
+ styles.stepContainer,
723
+ { opacity: fadeAnim, transform: [{ translateX: slideAnim }] }
724
+ ]}>
725
+ <View style={styles.modernHeader}>
726
+ <Text style={[styles.stepTitle, { color: colors.text }]}>
727
+ Tell us more
728
+ </Text>
729
+ <Text style={[styles.modernSubtitle, { color: colors.secondaryText }]}>
730
+ Provide details about your feedback
731
+ </Text>
732
+ </View>
733
+
734
+ <FormInput
735
+ icon="create-outline"
736
+ label="Title"
737
+ value={feedbackData.title}
738
+ onChangeText={(text) => {
739
+ updateField('title', text);
740
+ setErrorMessage('');
741
+ }}
742
+ placeholder="Brief summary of your feedback"
743
+ testID="feedback-title-input"
744
+ colors={colors}
745
+ styles={styles}
746
+ />
747
+
748
+ <FormInput
749
+ icon="document-text-outline"
750
+ label="Description"
751
+ value={feedbackData.description}
752
+ onChangeText={(text) => {
753
+ updateField('description', text);
754
+ setErrorMessage('');
755
+ }}
756
+ placeholder="Please provide detailed information..."
757
+ multiline={true}
758
+ numberOfLines={6}
759
+ testID="feedback-description-input"
760
+ colors={colors}
761
+ styles={styles}
762
+ />
763
+
764
+ <View style={styles.priorityContainer}>
765
+ <Text style={[styles.modernLabel, { color: colors.secondaryText, marginBottom: 12 }]}>
766
+ Priority Level
767
+ </Text>
768
+ {PRIORITY_LEVELS.map((priority) => (
769
+ <TouchableOpacity
770
+ key={priority.id}
771
+ style={[
772
+ styles.priorityButton,
773
+ {
774
+ borderColor: feedbackData.priority === priority.id ? priority.color : colors.border,
775
+ backgroundColor: feedbackData.priority === priority.id ? priority.color + '10' : colors.inputBackground,
776
+ }
777
+ ]}
778
+ onPress={() => updateField('priority', priority.id)}
779
+ >
780
+ <Ionicons name={priority.icon as any} size={20} color={priority.color} />
781
+ <Text style={[styles.priorityLabel, { color: colors.text }]}>
782
+ {priority.label}
783
+ </Text>
784
+ </TouchableOpacity>
785
+ ))}
786
+ </View>
787
+
788
+ <View style={styles.navigationButtons}>
789
+ <TouchableOpacity
790
+ style={[styles.navButton, styles.backButton, {
791
+ borderColor: colors.border,
792
+ shadowColor: colors.border,
793
+ }]}
794
+ onPress={prevStep}
795
+ >
796
+ <Ionicons name="arrow-back" size={16} color={colors.text} />
797
+ <Text style={[styles.navButtonText, { color: colors.text }]}>Back</Text>
798
+ </TouchableOpacity>
799
+
800
+ <TouchableOpacity
801
+ style={[styles.navButton, styles.nextButton, {
802
+ backgroundColor: colors.primary,
803
+ borderColor: colors.primary,
804
+ shadowColor: colors.primary,
805
+ }]}
806
+ onPress={nextStep}
807
+ disabled={!isDetailsStepValid()}
808
+ >
809
+ <Text style={[styles.navButtonText, { color: '#FFFFFF' }]}>Next</Text>
810
+ <Ionicons name="arrow-forward" size={16} color="#FFFFFF" />
811
+ </TouchableOpacity>
812
+ </View>
813
+ </Animated.View>
814
+ ), [fadeAnim, slideAnim, colors, feedbackData, updateField, setErrorMessage, prevStep, nextStep, isDetailsStepValid, styles]);
815
+
816
+ const renderContactStep = useCallback(() => (
817
+ <Animated.View style={[
818
+ styles.stepContainer,
819
+ { opacity: fadeAnim, transform: [{ translateX: slideAnim }] }
820
+ ]}>
821
+ <View style={styles.modernHeader}>
822
+ <Text style={[styles.stepTitle, { color: colors.text }]}>
823
+ Contact Information
824
+ </Text>
825
+ <Text style={[styles.modernSubtitle, { color: colors.secondaryText }]}>
826
+ Help us get back to you
827
+ </Text>
828
+ </View>
829
+
830
+ <FormInput
831
+ icon="mail-outline"
832
+ label="Email Address"
833
+ value={feedbackData.contactEmail}
834
+ onChangeText={(text) => {
835
+ updateField('contactEmail', text);
836
+ setErrorMessage('');
837
+ }}
838
+ placeholder={user?.email || "Enter your email address"}
839
+ testID="feedback-email-input"
840
+ colors={colors}
841
+ styles={styles}
842
+ />
843
+
844
+ <View style={styles.checkboxContainer}>
845
+ <TouchableOpacity
846
+ style={[
847
+ styles.checkbox,
848
+ {
849
+ borderColor: feedbackData.systemInfo ? colors.primary : colors.border,
850
+ backgroundColor: feedbackData.systemInfo ? colors.primary : 'transparent',
851
+ }
852
+ ]}
853
+ onPress={() => updateField('systemInfo', !feedbackData.systemInfo)}
854
+ >
855
+ {feedbackData.systemInfo && (
856
+ <Ionicons name="checkmark" size={16} color="#FFFFFF" />
857
+ )}
858
+ </TouchableOpacity>
859
+ <Text style={[styles.checkboxText, { color: colors.text }]}>
860
+ Include system information to help us better understand your issue
861
+ </Text>
862
+ </View>
863
+
864
+ <View style={styles.navigationButtons}>
865
+ <TouchableOpacity
866
+ style={[styles.navButton, styles.backButton, {
867
+ borderColor: colors.border,
868
+ shadowColor: colors.border,
869
+ }]}
870
+ onPress={prevStep}
871
+ >
872
+ <Ionicons name="arrow-back" size={16} color={colors.text} />
873
+ <Text style={[styles.navButtonText, { color: colors.text }]}>Back</Text>
874
+ </TouchableOpacity>
875
+
876
+ <TouchableOpacity
877
+ style={[styles.navButton, styles.nextButton, {
878
+ backgroundColor: colors.primary,
879
+ borderColor: colors.primary,
880
+ shadowColor: colors.primary,
881
+ }]}
882
+ onPress={nextStep}
883
+ disabled={!isContactStepValid()}
884
+ >
885
+ <Text style={[styles.navButtonText, { color: '#FFFFFF' }]}>Next</Text>
886
+ <Ionicons name="arrow-forward" size={16} color="#FFFFFF" />
887
+ </TouchableOpacity>
888
+ </View>
889
+ </Animated.View>
890
+ ), [fadeAnim, slideAnim, colors, feedbackData, user, updateField, setErrorMessage, prevStep, nextStep, isContactStepValid, styles]);
891
+
892
+ const renderSummaryStep = useCallback(() => (
893
+ <Animated.View style={[
894
+ styles.stepContainer,
895
+ { opacity: fadeAnim, transform: [{ translateX: slideAnim }] }
896
+ ]}>
897
+ <View style={styles.modernHeader}>
898
+ <Text style={[styles.stepTitle, { color: colors.text }]}>
899
+ Review & Submit
900
+ </Text>
901
+ <Text style={[styles.modernSubtitle, { color: colors.secondaryText }]}>
902
+ Please review your feedback before submitting
903
+ </Text>
904
+ </View>
905
+
906
+ <View style={styles.summaryContainer}>
907
+ <View style={styles.summaryRow}>
908
+ <Text style={[styles.summaryLabel, { color: colors.secondaryText }]}>Type:</Text>
909
+ <Text style={[styles.summaryValue, { color: colors.text }]}>
910
+ {FEEDBACK_TYPES.find(t => t.id === feedbackData.type)?.label}
911
+ </Text>
912
+ </View>
913
+
914
+ <View style={styles.summaryRow}>
915
+ <Text style={[styles.summaryLabel, { color: colors.secondaryText }]}>Category:</Text>
916
+ <Text style={[styles.summaryValue, { color: colors.text }]}>{feedbackData.category}</Text>
917
+ </View>
918
+
919
+ <View style={styles.summaryRow}>
920
+ <Text style={[styles.summaryLabel, { color: colors.secondaryText }]}>Priority:</Text>
921
+ <Text style={[styles.summaryValue, { color: colors.text }]}>
922
+ {PRIORITY_LEVELS.find(p => p.id === feedbackData.priority)?.label}
923
+ </Text>
924
+ </View>
925
+
926
+ <View style={styles.summaryRow}>
927
+ <Text style={[styles.summaryLabel, { color: colors.secondaryText }]}>Title:</Text>
928
+ <Text style={[styles.summaryValue, { color: colors.text }]}>{feedbackData.title}</Text>
929
+ </View>
930
+
931
+ <View style={styles.summaryRow}>
932
+ <Text style={[styles.summaryLabel, { color: colors.secondaryText }]}>Contact:</Text>
933
+ <Text style={[styles.summaryValue, { color: colors.text }]}>
934
+ {feedbackData.contactEmail || user?.email}
935
+ </Text>
936
+ </View>
937
+ </View>
938
+
939
+ <TouchableOpacity
940
+ style={[styles.button, { backgroundColor: colors.primary }]}
941
+ onPress={handleSubmitFeedback}
942
+ disabled={feedbackState.status === 'submitting'}
943
+ testID="submit-feedback-button"
944
+ >
945
+ {feedbackState.status === 'submitting' ? (
946
+ <ActivityIndicator color="#FFFFFF" size="small" />
947
+ ) : (
948
+ <>
949
+ <Text style={styles.buttonText}>Submit Feedback</Text>
950
+ <Ionicons name="send" size={20} color="#FFFFFF" />
951
+ </>
952
+ )}
953
+ </TouchableOpacity>
954
+
955
+ <View style={styles.navigationButtons}>
956
+ <TouchableOpacity
957
+ style={[styles.navButton, {
958
+ backgroundColor: 'transparent',
959
+ borderColor: colors.border,
960
+ shadowColor: colors.border,
961
+ borderTopLeftRadius: 35,
962
+ borderBottomLeftRadius: 35,
963
+ borderTopRightRadius: 35,
964
+ borderBottomRightRadius: 35,
965
+ }]}
966
+ onPress={prevStep}
967
+ >
968
+ <Ionicons name="arrow-back" size={16} color={colors.text} />
969
+ <Text style={[styles.navButtonText, { color: colors.text }]}>Back</Text>
970
+ </TouchableOpacity>
971
+ </View>
972
+ </Animated.View>
973
+ ), [fadeAnim, slideAnim, colors, feedbackData, user, feedbackState.status, handleSubmitFeedback, prevStep, styles]);
974
+
975
+ const renderSuccessStep = useCallback(() => (
976
+ <Animated.View style={[
977
+ styles.stepContainer,
978
+ { opacity: fadeAnim, transform: [{ translateX: slideAnim }] }
979
+ ]}>
980
+ <View style={styles.successContainer}>
981
+ <View style={[styles.successIcon, { backgroundColor: colors.success + '20', padding: 24, borderRadius: 50 }]}>
982
+ <Ionicons name="checkmark-circle" size={48} color={colors.success} />
983
+ </View>
984
+ <Text style={[styles.successTitle, { color: colors.text }]}>
985
+ Thank You!
986
+ </Text>
987
+ <Text style={[styles.successMessage, { color: colors.secondaryText }]}>
988
+ Your feedback has been submitted successfully. We'll review it and get back to you soon.
989
+ </Text>
990
+ <TouchableOpacity
991
+ style={[styles.button, { backgroundColor: colors.primary }]}
992
+ onPress={() => {
993
+ resetForm();
994
+ setCurrentStep(0);
995
+ }}
996
+ >
997
+ <Text style={styles.buttonText}>Submit Another</Text>
998
+ </TouchableOpacity>
999
+ </View>
1000
+ </Animated.View>
1001
+ ), [fadeAnim, slideAnim, colors, resetForm, styles]);
1002
+
1003
+ // Render current step
1004
+ const renderCurrentStep = useCallback(() => {
1005
+ if (feedbackState.status === 'success') {
1006
+ return renderSuccessStep();
1007
+ }
1008
+
1009
+ switch (currentStep) {
1010
+ case 0: return renderTypeStep();
1011
+ case 1: return renderDetailsStep();
1012
+ case 2: return renderContactStep();
1013
+ case 3: return renderSummaryStep();
1014
+ default: return renderTypeStep();
1015
+ }
1016
+ }, [currentStep, feedbackState.status, renderTypeStep, renderDetailsStep, renderContactStep, renderSummaryStep, renderSuccessStep]);
1017
+
1018
+ return (
1019
+ <KeyboardAvoidingView
1020
+ style={[styles.container, { backgroundColor: colors.background }]}
1021
+ behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
1022
+ >
1023
+ <StatusBar
1024
+ barStyle={theme === 'dark' ? 'light-content' : 'dark-content'}
1025
+ backgroundColor={colors.background}
1026
+ />
1027
+
1028
+ <ScrollView
1029
+ contentContainerStyle={styles.scrollContent}
1030
+ showsVerticalScrollIndicator={false}
1031
+ keyboardShouldPersistTaps="handled"
1032
+ >
1033
+ {feedbackState.status !== 'success' && (
1034
+ <ProgressIndicator currentStep={currentStep} totalSteps={4} colors={colors} styles={styles} />
1035
+ )}
1036
+ {renderCurrentStep()}
1037
+ </ScrollView>
1038
+ </KeyboardAvoidingView>
1039
+ );
1040
+ };
1041
+
1042
+ export default FeedbackScreen;