@mediacubeco/expo-template-fsd 2.3.1 → 2.4.1

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 (333) hide show
  1. package/.claude/commands/git-commit.md +164 -0
  2. package/.claude/rules/architecture.md +38 -0
  3. package/.claude/rules/{prettier-eslint-typescript.mdc → prettier-eslint-typescript.md} +5 -10
  4. package/.claude/settings.json +2 -2
  5. package/.claude/skills/api/SKILL.md +362 -0
  6. package/.claude/skills/api/references/client/overview.md +106 -0
  7. package/.claude/skills/api/references/hooks/index.ts +3 -0
  8. package/.claude/skills/api/references/hooks/use-api-health.ts +25 -0
  9. package/.claude/skills/api/references/hooks/use-api-post.ts +46 -0
  10. package/.claude/skills/api/references/hooks/use-api-posts.ts +24 -0
  11. package/.claude/skills/api/references/mock/post.mock.ts +29 -0
  12. package/.claude/skills/{generate-api-model/references → api/references/model}/entities/common.ts +5 -2
  13. package/.claude/skills/api/references/model/resources/common.ts +9 -0
  14. package/.claude/skills/api/references/queries/health.ts +14 -0
  15. package/.claude/skills/api/references/queries/index.ts +2 -0
  16. package/.claude/skills/api/references/queries/post.ts +23 -0
  17. package/.claude/skills/api/references/repository/health/health.ts +11 -0
  18. package/.claude/skills/api/references/repository/health/health.types.ts +25 -0
  19. package/.claude/skills/api/references/repository/health/index.ts +2 -0
  20. package/.claude/skills/api/references/repository/post/index.ts +9 -0
  21. package/.claude/skills/api/references/repository/post/post.ts +34 -0
  22. package/.claude/skills/api/references/repository/post/post.types.ts +61 -0
  23. package/.claude/skills/code-style/SKILL.md +1025 -1
  24. package/.claude/skills/code-style/references/components/payout-speed-option/index.ts +2 -0
  25. package/.claude/skills/code-style/references/components/payout-speed-option/payout-speed-option.styles.ts +76 -0
  26. package/.claude/skills/code-style/references/components/payout-speed-option/payout-speed-option.tsx +58 -0
  27. package/.claude/skills/code-style/references/components/payout-speed-option/payout-speed-option.types.ts +22 -0
  28. package/.claude/skills/code-style/references/components/post/index.ts +2 -0
  29. package/.claude/skills/code-style/references/components/post/post.styles.ts +19 -0
  30. package/.claude/skills/code-style/references/components/post/post.tsx +21 -0
  31. package/.claude/skills/code-style/references/components/post/post.types.ts +9 -0
  32. package/.claude/skills/code-style/references/components/wrap/index.ts +2 -0
  33. package/.claude/skills/code-style/references/components/wrap/wrap.styles.ts +15 -0
  34. package/.claude/skills/code-style/references/components/wrap/wrap.tsx +31 -0
  35. package/.claude/skills/code-style/references/components/wrap/wrap.types.ts +10 -0
  36. package/.claude/skills/code-style/references/hooks/use-posts.ts +37 -0
  37. package/.claude/skills/code-style/references/pages/post/index.ts +4 -0
  38. package/.claude/skills/code-style/references/pages/post/post-details/index.ts +1 -0
  39. package/.claude/skills/code-style/references/pages/post/post-details/post-details.tsx +13 -0
  40. package/.claude/skills/code-style/references/pages/post/post-guide/index.ts +1 -0
  41. package/.claude/skills/code-style/references/pages/post/post-guide/post-guide.tsx +17 -0
  42. package/.claude/skills/code-style/references/pages/post/post-list/index.ts +1 -0
  43. package/.claude/skills/code-style/references/pages/post/post-list/post-list.styles.ts +17 -0
  44. package/.claude/skills/code-style/references/pages/post/post-list/post-list.tsx +25 -0
  45. package/.claude/skills/code-style/references/pages/post/post-share/index.ts +1 -0
  46. package/.claude/skills/code-style/references/pages/post/post-share/post-share.tsx +13 -0
  47. package/.claude/skills/code-style/references/routes/(stack)/_layout.tsx +18 -0
  48. package/.claude/skills/code-style/references/routes/(stack)/details.tsx +8 -0
  49. package/.claude/skills/code-style/references/routes/(stack)/guide.tsx +8 -0
  50. package/.claude/skills/code-style/references/routes/(stack)/index.tsx +8 -0
  51. package/.claude/skills/code-style/references/routes/(stack)/share.tsx +8 -0
  52. package/.claude/skills/code-style/references/routes/(tabs)/(post-details)/index.tsx +8 -0
  53. package/.claude/skills/code-style/references/routes/(tabs)/(post-list)/index.tsx +8 -0
  54. package/.claude/skills/code-style/references/routes/(tabs)/_layout.tsx +50 -0
  55. package/.claude/skills/code-style/references/routes/_app.tsx +20 -0
  56. package/.claude/skills/code-style/references/routes/guide.tsx +8 -0
  57. package/.claude/skills/code-style/references/routes/share.tsx +8 -0
  58. package/.claude/skills/code-style/references/store/use-post-draft-store.ts +62 -0
  59. package/.claude/skills/design-style/SKILL.md +320 -0
  60. package/.env +3 -1
  61. package/.env.example +3 -1
  62. package/CLAUDE.md +5 -11
  63. package/app.json +6 -3
  64. package/axios.d.ts +5 -0
  65. package/env.d.ts +3 -1
  66. package/package.json +33 -40
  67. package/patches/react-native-screens+4.25.2.patch +118 -0
  68. package/react-query.d.ts +13 -0
  69. package/src/app/(root)/(home)/_layout.tsx +2 -2
  70. package/src/app/(root)/(home)/index.tsx +2 -2
  71. package/src/app/(root)/(settings)/_layout.tsx +2 -2
  72. package/src/app/(root)/(settings)/index.tsx +2 -2
  73. package/src/app/(root)/_layout.tsx +35 -32
  74. package/src/pages/home/home-main.tsx +3 -7
  75. package/src/pages/settings/settings-main.tsx +3 -7
  76. package/src/shared/assets/fonts/index.ts +3 -3
  77. package/src/shared/assets/fonts/sf-pro-text-bold.ttf +0 -0
  78. package/src/shared/assets/fonts/sf-pro-text-regular.ttf +0 -0
  79. package/src/shared/assets/fonts/sf-pro-text-semibold.ttf +0 -0
  80. package/src/shared/assets/icons/back.tsx +21 -0
  81. package/src/shared/assets/icons/close.tsx +21 -0
  82. package/src/shared/assets/icons/common.ts +8 -0
  83. package/src/shared/assets/icons/default.tsx +44 -0
  84. package/src/shared/assets/icons/index.ts +14 -1
  85. package/src/shared/assets/icons/refresh.tsx +23 -0
  86. package/src/shared/assets/icons/share.tsx +38 -0
  87. package/src/shared/assets/icons/type.ts +7 -0
  88. package/src/shared/assets/translations/index.ts +4 -4
  89. package/src/shared/constants/config.ts +13 -0
  90. package/src/shared/constants/environment.ts +16 -4
  91. package/src/shared/constants/index.ts +1 -0
  92. package/src/shared/hooks/index.ts +1 -4
  93. package/src/shared/hooks/use-compose.ts +23 -0
  94. package/src/shared/lib/api/api.client.ts +157 -0
  95. package/src/shared/lib/api/api.provider.tsx +14 -36
  96. package/src/shared/lib/api/api.ts +1 -5
  97. package/src/shared/lib/api/api.types.ts +6 -3
  98. package/src/shared/lib/api/hooks/index.ts +1 -0
  99. package/src/shared/lib/api/index.ts +2 -3
  100. package/src/shared/lib/api/models/api-instance/api-instance.client.ts +50 -0
  101. package/src/shared/lib/api/models/api-instance/api-instance.ts +30 -82
  102. package/src/shared/lib/api/models/api-instance/api-instance.types.ts +16 -18
  103. package/src/shared/lib/api/models/api-instance/api-instance.utils.ts +13 -20
  104. package/src/shared/lib/api/models/api-instance/index.ts +3 -0
  105. package/src/shared/lib/api/queries/index.ts +1 -0
  106. package/src/shared/lib/api/repositories/index.ts +1 -1
  107. package/src/shared/lib/localization/constants/index.ts +16 -5
  108. package/src/shared/lib/localization/index.ts +5 -1
  109. package/src/shared/lib/navigation/hooks/index.ts +8 -3
  110. package/src/shared/{hooks/use-breakpoints.ts → lib/navigation/hooks/use-navigation-breakpoints.ts} +2 -5
  111. package/src/shared/lib/navigation/hooks/use-navigation-dimensions.ts +12 -0
  112. package/src/shared/lib/navigation/hooks/use-navigation-options.tsx +175 -0
  113. package/src/shared/lib/navigation/hooks/{use-navigation.ts → use-navigation-route.ts} +2 -2
  114. package/src/shared/lib/navigation/hooks/use-navigation-safe-area.ts +61 -0
  115. package/src/shared/lib/navigation/hooks/use-navigation-tabs-native.ts +10 -0
  116. package/src/shared/lib/navigation/hooks/use-navigation-tabs.tsx +10 -0
  117. package/src/shared/lib/navigation/hooks/use-navigation-transition.ts +27 -0
  118. package/src/shared/lib/navigation/index.ts +11 -4
  119. package/src/shared/lib/navigation/navigation-tabs-native.context.tsx +5 -0
  120. package/src/shared/lib/navigation/navigation-tabs-native.provider.tsx +17 -0
  121. package/src/shared/lib/navigation/navigation-tabs.context.tsx +10 -0
  122. package/src/shared/lib/navigation/navigation-tabs.provider.tsx +22 -0
  123. package/src/shared/lib/navigation/navigation.provider.tsx +6 -1
  124. package/src/shared/lib/storage/index.ts +1 -1
  125. package/src/shared/lib/storage/storage.provider.tsx +4 -0
  126. package/src/shared/lib/storage/storage.ts +29 -25
  127. package/src/shared/lib/theme/constants/animations.ts +26 -0
  128. package/src/shared/lib/theme/constants/colors.ts +336 -43
  129. package/src/shared/lib/theme/constants/delays.ts +1 -1
  130. package/src/shared/lib/theme/constants/durations.ts +1 -1
  131. package/src/shared/lib/theme/constants/fonts.ts +2 -1
  132. package/src/shared/lib/theme/constants/index.ts +42 -20
  133. package/src/shared/lib/theme/constants/shadows.ts +7 -25
  134. package/src/shared/lib/theme/constants/sizes.ts +11 -2
  135. package/src/shared/lib/theme/constants/transparencies.ts +1 -1
  136. package/src/shared/lib/theme/hooks/use-theme-setup.ts +3 -1
  137. package/src/shared/lib/theme/index.ts +10 -1
  138. package/src/shared/lib/theme/theme.provider.tsx +45 -19
  139. package/src/shared/lib/theme/theme.scope.tsx +43 -0
  140. package/src/shared/lib/theme/theme.types.ts +15 -3
  141. package/src/shared/lib/theme/utils/color.ts +81 -0
  142. package/src/shared/lib/theme/utils/index.ts +2 -0
  143. package/src/shared/lib/theme/utils/snapshot.ts +17 -0
  144. package/src/shared/lib/theme/utils/storage.ts +5 -2
  145. package/src/shared/services/browser/browser.ts +66 -0
  146. package/src/shared/services/browser/index.ts +1 -0
  147. package/src/shared/services/cookies/cookies.ts +73 -0
  148. package/src/shared/services/cookies/index.ts +1 -0
  149. package/src/shared/services/index.ts +5 -0
  150. package/src/shared/services/linking/index.ts +1 -0
  151. package/src/shared/services/linking/linking.ts +22 -0
  152. package/src/shared/services/share/index.ts +1 -0
  153. package/src/shared/services/share/share.ts +28 -0
  154. package/src/shared/services/universal-links/index.ts +104 -0
  155. package/src/shared/services/universal-links/universal-links.ts +25 -0
  156. package/src/shared/services/universal-links/universal-links.types.ts +5 -0
  157. package/src/shared/ui/atoms/blur/blur.tsx +9 -4
  158. package/src/shared/ui/atoms/blur/blur.types.ts +1 -1
  159. package/src/shared/ui/atoms/blur-progress/blur-progress.styles.ts +16 -0
  160. package/src/shared/ui/atoms/blur-progress/blur-progress.tsx +30 -0
  161. package/src/shared/ui/atoms/blur-progress/blur-progress.types.tsx +5 -0
  162. package/src/shared/ui/atoms/blur-progress/index.ts +1 -0
  163. package/src/shared/ui/atoms/glass/glass.tsx +13 -5
  164. package/src/shared/ui/atoms/glass/glass.types.ts +1 -1
  165. package/src/shared/ui/atoms/icon/icon.styles.ts +82 -0
  166. package/src/shared/ui/atoms/icon/icon.tsx +21 -0
  167. package/src/shared/ui/atoms/icon/icon.types.ts +23 -0
  168. package/src/shared/ui/atoms/icon/index.ts +2 -0
  169. package/src/shared/ui/atoms/index.ts +7 -0
  170. package/src/shared/ui/atoms/skeleton/index.ts +2 -0
  171. package/src/shared/ui/atoms/skeleton/skeleton.styles.ts +69 -0
  172. package/src/shared/ui/atoms/skeleton/skeleton.tsx +26 -0
  173. package/src/shared/ui/atoms/skeleton/skeleton.types.ts +9 -0
  174. package/src/shared/ui/atoms/spinner/index.ts +2 -0
  175. package/src/shared/ui/atoms/spinner/spinner.styles.ts +102 -0
  176. package/src/shared/ui/atoms/spinner/spinner.tsx +48 -0
  177. package/src/shared/ui/atoms/spinner/spinner.types.ts +25 -0
  178. package/src/shared/ui/atoms/text/index.ts +2 -0
  179. package/src/shared/ui/atoms/text/text.styles.ts +186 -0
  180. package/src/shared/ui/atoms/text/text.tsx +37 -0
  181. package/src/shared/ui/atoms/text/text.types.ts +35 -0
  182. package/src/shared/ui/atoms/touch/components/haptics/haptics.styles.ts +21 -0
  183. package/src/shared/ui/atoms/touch/components/haptics/haptics.tsx +28 -0
  184. package/src/shared/ui/atoms/touch/components/haptics/haptics.types.ts +17 -0
  185. package/src/shared/ui/atoms/touch/components/haptics/index.ts +2 -0
  186. package/src/shared/ui/atoms/touch/components/index.ts +3 -0
  187. package/src/shared/ui/atoms/touch/components/ripple/index.ts +2 -0
  188. package/src/shared/ui/atoms/touch/components/ripple/ripple.styles.ts +78 -0
  189. package/src/shared/ui/atoms/touch/components/ripple/ripple.tsx +29 -0
  190. package/src/shared/ui/atoms/touch/components/ripple/ripple.types.ts +17 -0
  191. package/src/shared/ui/atoms/touch/components/spring/index.ts +2 -0
  192. package/src/shared/ui/atoms/touch/components/spring/spring.styles.ts +31 -0
  193. package/src/shared/ui/atoms/touch/components/spring/spring.tsx +28 -0
  194. package/src/shared/ui/atoms/touch/components/spring/spring.types.ts +17 -0
  195. package/src/shared/ui/atoms/touch/index.ts +2 -0
  196. package/src/shared/ui/atoms/touch/touch.styles.ts +14 -0
  197. package/src/shared/ui/atoms/touch/touch.tsx +137 -0
  198. package/src/shared/ui/atoms/touch/touch.types.ts +27 -0
  199. package/src/shared/ui/atoms/visibility/index.ts +2 -0
  200. package/src/shared/ui/atoms/visibility/visibility.styles.ts +85 -0
  201. package/src/shared/ui/atoms/visibility/visibility.tsx +61 -0
  202. package/src/shared/ui/atoms/visibility/visibility.types.ts +34 -0
  203. package/src/shared/ui/molecules/keyboard-area/keyboard-area.styles.ts +11 -9
  204. package/src/shared/ui/molecules/keyboard-area/keyboard-area.tsx +3 -6
  205. package/src/shared/ui/molecules/refresh-control/refresh-control.tsx +3 -5
  206. package/src/shared/ui/molecules/refresh-control/refresh-control.types.ts +1 -1
  207. package/src/shared/ui/molecules/slider/components/indicator/components/dot/dot.styles.ts +41 -0
  208. package/src/shared/ui/molecules/slider/components/indicator/components/dot/dot.tsx +12 -0
  209. package/src/shared/ui/molecules/slider/components/indicator/components/dot/dot.types.ts +13 -0
  210. package/src/shared/ui/molecules/slider/components/indicator/components/dot/index.ts +2 -0
  211. package/src/shared/ui/molecules/slider/components/indicator/index.ts +2 -0
  212. package/src/shared/ui/molecules/slider/components/indicator/indicator.styles.ts +20 -0
  213. package/src/shared/ui/molecules/slider/components/indicator/indicator.tsx +22 -0
  214. package/src/shared/ui/molecules/slider/components/indicator/indicator.types.ts +10 -0
  215. package/src/shared/ui/molecules/slider/index.ts +3 -0
  216. package/src/shared/ui/molecules/slider/slider.styles.ts +68 -0
  217. package/src/shared/ui/molecules/slider/slider.tsx +64 -0
  218. package/src/shared/ui/molecules/slider/slider.types.ts +28 -0
  219. package/src/shared/ui/organisms/bar/bar.styles.ts +100 -0
  220. package/src/shared/ui/organisms/bar/bar.tsx +89 -0
  221. package/src/shared/ui/organisms/bar/bar.types.ts +49 -0
  222. package/src/shared/ui/organisms/bar/index.ts +2 -0
  223. package/src/shared/ui/organisms/bar-tab/bar-tab.tsx +9 -0
  224. package/src/shared/ui/organisms/bar-tab/bar-tab.types.ts +5 -0
  225. package/src/shared/ui/organisms/bar-tab/components/index.ts +1 -0
  226. package/src/shared/ui/organisms/bar-tab/components/tab/index.ts +2 -0
  227. package/src/shared/ui/organisms/bar-tab/components/tab/tab.styles.ts +21 -0
  228. package/src/shared/ui/organisms/bar-tab/components/tab/tab.tsx +18 -0
  229. package/src/shared/ui/organisms/bar-tab/components/tab/tab.types.ts +5 -0
  230. package/src/shared/ui/organisms/bar-tab/index.ts +2 -0
  231. package/src/shared/ui/organisms/bar-tab-navigation/bar-tab-navigation.styles.ts +22 -0
  232. package/src/shared/ui/organisms/bar-tab-navigation/bar-tab-navigation.tsx +66 -0
  233. package/src/shared/ui/organisms/bar-tab-navigation/bar-tab-navigation.types.ts +5 -0
  234. package/src/shared/ui/organisms/bar-tab-navigation/components/index.ts +1 -0
  235. package/src/shared/ui/organisms/bar-tab-navigation/components/tab-navigation/index.ts +2 -0
  236. package/src/shared/ui/organisms/bar-tab-navigation/components/tab-navigation/tab-navigation.styles.ts +56 -0
  237. package/src/shared/ui/organisms/bar-tab-navigation/components/tab-navigation/tab-navigation.tsx +30 -0
  238. package/src/shared/ui/organisms/bar-tab-navigation/components/tab-navigation/tab-navigation.types.ts +7 -0
  239. package/src/shared/ui/organisms/bar-tab-navigation/index.ts +2 -0
  240. package/src/shared/ui/organisms/index.ts +4 -1
  241. package/src/shared/ui/organisms/slider/components/indicator/components/dot/dot.styles.ts +41 -0
  242. package/src/shared/ui/organisms/slider/components/indicator/components/dot/dot.tsx +12 -0
  243. package/src/shared/ui/organisms/slider/components/indicator/components/dot/dot.types.ts +13 -0
  244. package/src/shared/ui/organisms/slider/components/indicator/components/dot/index.ts +2 -0
  245. package/src/shared/ui/organisms/slider/components/indicator/index.ts +2 -0
  246. package/src/shared/ui/organisms/slider/components/indicator/indicator.styles.ts +20 -0
  247. package/src/shared/ui/organisms/slider/components/indicator/indicator.tsx +22 -0
  248. package/src/shared/ui/organisms/slider/components/indicator/indicator.types.ts +10 -0
  249. package/src/shared/ui/organisms/slider/index.ts +3 -0
  250. package/src/shared/ui/organisms/slider/slider.styles.ts +68 -0
  251. package/src/shared/ui/organisms/slider/slider.tsx +64 -0
  252. package/src/shared/ui/organisms/slider/slider.types.ts +28 -0
  253. package/src/shared/ui/templates/index.ts +3 -0
  254. package/src/shared/ui/templates/modal-container/index.ts +13 -0
  255. package/src/shared/ui/templates/modal-container/modal-container-list.tsx +45 -0
  256. package/src/shared/ui/templates/modal-container/modal-container-scroll.tsx +66 -0
  257. package/src/shared/ui/templates/modal-container/modal-container-section-list.tsx +46 -0
  258. package/src/shared/ui/templates/modal-container/modal-container.hooks.tsx +172 -0
  259. package/src/shared/ui/templates/modal-container/modal-container.styles.ts +121 -0
  260. package/src/shared/ui/templates/modal-container/modal-container.types.ts +69 -0
  261. package/src/shared/ui/templates/screen-container/index.ts +1 -1
  262. package/src/shared/ui/templates/screen-container/screen-container-list.tsx +28 -10
  263. package/src/shared/ui/templates/screen-container/screen-container-scroll.tsx +28 -10
  264. package/src/shared/ui/templates/screen-container/screen-container-section-list.tsx +29 -11
  265. package/src/shared/ui/templates/screen-container/screen-container.hooks.tsx +79 -8
  266. package/src/shared/ui/templates/screen-container/screen-container.styles.ts +105 -15
  267. package/src/shared/ui/templates/screen-container/screen-container.types.tsx +34 -7
  268. package/src/shared/ui/templates/screen-header/components/index.ts +6 -0
  269. package/src/shared/ui/templates/screen-header/components/screen-header-description/index.ts +2 -0
  270. package/src/shared/ui/templates/screen-header/components/screen-header-description/screen-header-description.tsx +15 -0
  271. package/src/shared/ui/templates/screen-header/components/screen-header-description/screen-header-description.types.ts +11 -0
  272. package/src/shared/ui/templates/screen-header/components/screen-header-icon/index.ts +2 -0
  273. package/src/shared/ui/templates/screen-header/components/screen-header-icon/screen-header-icon.styles.ts +44 -0
  274. package/src/shared/ui/templates/screen-header/components/screen-header-icon/screen-header-icon.tsx +65 -0
  275. package/src/shared/ui/templates/screen-header/components/screen-header-icon/screen-header-icon.types.ts +14 -0
  276. package/src/shared/ui/templates/screen-header/components/screen-header-icon-back/index.ts +2 -0
  277. package/src/shared/ui/templates/screen-header/components/screen-header-icon-back/screen-header-icon-back.tsx +17 -0
  278. package/src/shared/ui/templates/screen-header/components/screen-header-icon-back/screen-header-icon-back.types.ts +6 -0
  279. package/src/shared/ui/templates/screen-header/components/screen-header-icon-close/index.ts +2 -0
  280. package/src/shared/ui/templates/screen-header/components/screen-header-icon-close/screen-header-icon-close.tsx +27 -0
  281. package/src/shared/ui/templates/screen-header/components/screen-header-icon-close/screen-header-icon-close.types.ts +10 -0
  282. package/src/shared/ui/templates/screen-header/components/screen-header-info/index.ts +2 -0
  283. package/src/shared/ui/templates/screen-header/components/screen-header-info/screen-header-info.tsx +15 -0
  284. package/src/shared/ui/templates/screen-header/components/screen-header-info/screen-header-info.types.ts +10 -0
  285. package/src/shared/ui/templates/screen-header/components/screen-header-title/index.ts +2 -0
  286. package/src/shared/ui/templates/screen-header/components/screen-header-title/screen-header-title.tsx +19 -0
  287. package/src/shared/ui/templates/screen-header/components/screen-header-title/screen-header-title.types.ts +13 -0
  288. package/src/shared/ui/templates/screen-header/index.ts +3 -0
  289. package/src/shared/ui/templates/screen-header/screen-header.styles.ts +49 -0
  290. package/src/shared/ui/templates/screen-header/screen-header.tsx +26 -0
  291. package/src/shared/ui/templates/screen-header/screen-header.types.ts +15 -0
  292. package/src/shared/ui/templates/web-container/index.ts +2 -0
  293. package/src/shared/ui/templates/web-container/web-container.styles.ts +34 -0
  294. package/src/shared/ui/templates/web-container/web-container.tsx +172 -0
  295. package/src/shared/ui/templates/web-container/web-container.types.ts +21 -0
  296. package/.claude/rules/app-routing.mdc +0 -47
  297. package/.claude/rules/exports-at-end.mdc +0 -55
  298. package/.claude/rules/kebab-case-naming.mdc +0 -29
  299. package/.claude/rules/mediacubeco-packages.mdc +0 -56
  300. package/.claude/skills/generate-api-model/SKILL.md +0 -230
  301. package/.claude/skills/generate-api-model/references/resources/common.ts +0 -8
  302. package/.claude/skills/generate-api-model-mock/SKILL.md +0 -56
  303. package/.claude/skills/git-commit/SKILL.md +0 -139
  304. package/.gitignore +0 -34
  305. package/src/shared/assets/icons/like.tsx +0 -17
  306. package/src/shared/hooks/use-animated.ts +0 -200
  307. package/src/shared/hooks/use-mixins.ts +0 -36
  308. package/src/shared/hooks/use-safe-area.ts +0 -75
  309. package/src/shared/lib/api/repositories/auth/auth.ts +0 -23
  310. package/src/shared/lib/api/repositories/auth/auth.types.ts +0 -22
  311. package/src/shared/lib/api/repositories/auth/index.ts +0 -1
  312. package/src/shared/lib/navigation/hooks/use-navigation-native-tabs.ts +0 -10
  313. package/src/shared/lib/navigation/hooks/use-navigation-options.ts +0 -123
  314. package/src/shared/lib/navigation/navigation-native-tabs.context.tsx +0 -5
  315. package/src/shared/lib/navigation/navigation-native-tabs.provider.tsx +0 -12
  316. package/src/shared/lib/theme/constants/borders.ts +0 -8
  317. package/src/shared/lib/theme/constants/weights.ts +0 -13
  318. /package/.claude/skills/{generate-api-model/references → api/references/model}/entities/index.ts +0 -0
  319. /package/.claude/skills/{generate-api-model/references → api/references/model}/entities/post/index.ts +0 -0
  320. /package/.claude/skills/{generate-api-model/references → api/references/model}/entities/post/post-comment.ts +0 -0
  321. /package/.claude/skills/{generate-api-model/references → api/references/model}/entities/post/post.ts +0 -0
  322. /package/.claude/skills/{generate-api-model/references → api/references/model}/entities/user/index.ts +0 -0
  323. /package/.claude/skills/{generate-api-model/references → api/references/model}/entities/user/user-settings.ts +0 -0
  324. /package/.claude/skills/{generate-api-model/references → api/references/model}/entities/user/user-verification.ts +0 -0
  325. /package/.claude/skills/{generate-api-model/references → api/references/model}/entities/user/user.ts +0 -0
  326. /package/.claude/skills/{generate-api-model/references → api/references/model}/resources/index.ts +0 -0
  327. /package/.claude/skills/{generate-api-model/references → api/references/model}/resources/post/index.ts +0 -0
  328. /package/.claude/skills/{generate-api-model/references → api/references/model}/resources/post/post-comment.ts +0 -0
  329. /package/.claude/skills/{generate-api-model/references → api/references/model}/resources/post/post.ts +0 -0
  330. /package/.claude/skills/{generate-api-model/references → api/references/model}/resources/user/index.ts +0 -0
  331. /package/.claude/skills/{generate-api-model/references → api/references/model}/resources/user/user-settings.ts +0 -0
  332. /package/.claude/skills/{generate-api-model/references → api/references/model}/resources/user/user-verification.ts +0 -0
  333. /package/.claude/skills/{generate-api-model/references → api/references/model}/resources/user/user.ts +0 -0
@@ -0,0 +1,106 @@
1
+ # API infrastructure (shared, not per-domain)
2
+
3
+ These pieces exist **once** in the API lib. A new domain plugs into them — it
4
+ does not regenerate them. Read this so the per-domain code you generate fits the
5
+ machine around it, and so you know which shared files to touch.
6
+
7
+ ## The transport: `ApiInstance`
8
+
9
+ Every repository extends `ApiInstance`, which owns `fetch`. Two things matter for
10
+ generated repositories:
11
+
12
+ - **Transport options.** Every request accepts `options?: { signal?, timeout? }`.
13
+ The domain `Config` types carry this through `ApiConfig<Config>`
14
+ (`Config & { options?: ApiInstanceOptions }`). Repository methods split it out,
15
+ mapping the camelCase fields into snake_case `params`/`body` by hand:
16
+ `async getX({ isActive, options })` → `this.get('/', { params: { is_active: isActive }, options })`.
17
+ This is why the `options`/`params` separation in the repository is mandatory —
18
+ forget it and an `AbortSignal` leaks into the query string.
19
+ - **Empty/error handling is centralized.** A 204 or empty body returns
20
+ `undefined`; non-2xx throws an `Error` whose `cause` is the `Response` (so the
21
+ status survives). The repository does not try/catch — errors propagate to React
22
+ Query. Repositories return the raw success payload unchanged; shaping into
23
+ `{ list }`/`{ item }` and the camelCase conversion both happen in the hook's `select`.
24
+
25
+ ## Errors are handled in one place: `QueryCache.onError`
26
+
27
+ The `QueryClient` is built with a `QueryCache` whose `onError` is the single
28
+ funnel for every failed query (a future toast/Sentry hook lives here). It reads
29
+ `query.meta.silent` to skip noise. Consequence for generated code: **hooks and
30
+ repositories never log or swallow errors** — they let them throw. Per-query
31
+ suppression is `meta: { silent: true }`, nothing more.
32
+
33
+ `retry` skips 4xx (client errors don't heal on repeat) and retries the rest up to
34
+ twice, reading the status from the error's `cause`.
35
+
36
+ ```ts
37
+ const queryClient = new QueryClient({
38
+ queryCache: new QueryCache({
39
+ onError: (error, query) => {
40
+ if (query.meta?.silent) {
41
+ return
42
+ }
43
+
44
+ ErrorHandler.capture(error, { signal: 'query', message: JSON.stringify(query.queryKey) })
45
+ },
46
+ }),
47
+ defaultOptions: {
48
+ queries: {
49
+ retry: (failureCount, error) => {
50
+ const status = getErrorStatus(error)
51
+
52
+ if (status !== undefined && status >= 400 && status < 500) {
53
+ return false
54
+ }
55
+
56
+ return failureCount < MAX_RETRY_COUNT
57
+ },
58
+ },
59
+ },
60
+ })
61
+ ```
62
+
63
+ ## Typed `meta`
64
+
65
+ `meta` is typed globally (module augmentation of `Register` in a root
66
+ `react-query.d.ts`), so `meta: { persist: true }` and `meta: { silent: true }`
67
+ are checked, not free-form:
68
+
69
+ ```ts
70
+ type ApiQueryMeta = {
71
+ persist?: boolean
72
+ silent?: boolean
73
+ }
74
+
75
+ declare module '@tanstack/react-query' {
76
+ interface Register {
77
+ queryMeta: ApiQueryMeta
78
+ mutationMeta: ApiQueryMeta
79
+ }
80
+ }
81
+ ```
82
+
83
+ - `persist: true` — the query is whitelisted for AsyncStorage/MMKV persistence
84
+ (survives restarts). Only set it on non-sensitive, slow-changing data.
85
+ - `silent: true` — `onError` ignores this query.
86
+
87
+ ## Persistence and freshness
88
+
89
+ - Persistence is opt-in per query via `meta: { persist: true }`. Never persist
90
+ user-private data — the store is not encrypted.
91
+ - `staleTime` is opt-in. Slow-changing reference data (countries, languages,
92
+ labels) uses `staleTime: STALE_TIME` so it is not refetched on every mount.
93
+ Always-fresh data (status, feature flags, anything user-specific) omits it.
94
+
95
+ ## Online + focus
96
+
97
+ `focusManager` (app foreground/background) and `onlineManager` (network via
98
+ `expo-network`) are wired once at module scope so `refetchOnReconnect` and
99
+ pause-while-offline work in React Native. Nothing per-domain here.
100
+
101
+ ## What a NEW domain must touch in shared files
102
+
103
+ 1. `api.ts` — register the repository singleton: `static postRepository = new PostRepository('/posts')` (URN is the plural route).
104
+ 2. `constants/index.ts` — add the base query key: `POSTS: 'posts'` in `QUERY_KEYS`.
105
+ 3. Barrels — `resources/index.ts`, `entities/index.ts`, `repositories/index.ts`, `queries/index.ts`, `hooks/index.ts` each get one re-export line (alphabetical).
106
+ 4. Prefetch (optional) — if the domain is reference data shown on first screens, add `queryClient.prefetchQuery(postQueries.list())` to the startup prefetch.
@@ -0,0 +1,3 @@
1
+ export * from './use-api-health'
2
+ export * from './use-api-post'
3
+ export * from './use-api-posts'
@@ -0,0 +1,25 @@
1
+ import { useQuery } from '@tanstack/react-query'
2
+ import { healthQueries } from '../queries'
3
+ import { type GetHealthResponse } from '../repositories'
4
+
5
+ // map-case: every field is optional, so the default answer is the empty wire object
6
+ const PLACEHOLDER_DATA: GetHealthResponse = {}
7
+
8
+ const selectHealth = (data: GetHealthResponse) => {
9
+ return {
10
+ item: {
11
+ maintenance: data.maintenance,
12
+ startAt: data.start_at,
13
+ },
14
+ }
15
+ }
16
+
17
+ const useApiHealth = () => {
18
+ return useQuery({
19
+ ...healthQueries.detail(),
20
+ placeholderData: PLACEHOLDER_DATA,
21
+ select: selectHealth,
22
+ })
23
+ }
24
+
25
+ export { useApiHealth }
@@ -0,0 +1,46 @@
1
+ import { useMutation, useQuery } from '@tanstack/react-query'
2
+ import { Api } from '../api'
3
+ import { queryClient } from '../api.client'
4
+ import { PostEntity } from '../entities'
5
+ import { postQueries } from '../queries'
6
+ import {
7
+ type CreatePostConfig,
8
+ type CreatePostResponse,
9
+ type GetPostResponse,
10
+ } from '../repositories'
11
+
12
+ const PLACEHOLDER_DATA: GetPostResponse = {
13
+ data: { is_skeleton: true },
14
+ }
15
+
16
+ const selectPost = (data: GetPostResponse) => {
17
+ return {
18
+ item: new PostEntity(data.data),
19
+ }
20
+ }
21
+
22
+ const selectPostCreate = (data: CreatePostResponse) => {
23
+ return {
24
+ item: new PostEntity(data.data),
25
+ }
26
+ }
27
+
28
+ const useApiPost = (id: PostEntity['id']) => {
29
+ return useQuery({
30
+ ...postQueries.detail(id),
31
+ placeholderData: PLACEHOLDER_DATA,
32
+ select: selectPost,
33
+ })
34
+ }
35
+
36
+ const useApiPostCreate = () => {
37
+ return useMutation({
38
+ mutationFn: async (config: CreatePostConfig) =>
39
+ selectPostCreate(await Api.postRepository.createPost(config)),
40
+ onSettled: () => {
41
+ queryClient.invalidateQueries({ queryKey: postQueries.key })
42
+ },
43
+ })
44
+ }
45
+
46
+ export { useApiPost, useApiPostCreate }
@@ -0,0 +1,24 @@
1
+ import { useQuery } from '@tanstack/react-query'
2
+ import { PostEntity } from '../entities'
3
+ import { postQueries } from '../queries'
4
+ import { type GetPostListResponse } from '../repositories'
5
+
6
+ const INITIAL_DATA: GetPostListResponse = {
7
+ data: [{ is_skeleton: true }, { is_skeleton: true }, { is_skeleton: true }],
8
+ }
9
+
10
+ const selectPostList = (data: GetPostListResponse) => {
11
+ return {
12
+ list: data.data?.map((post) => new PostEntity(post)) ?? [],
13
+ }
14
+ }
15
+
16
+ const useApiPosts = () => {
17
+ return useQuery({
18
+ ...postQueries.list(),
19
+ initialData: INITIAL_DATA,
20
+ select: selectPostList,
21
+ })
22
+ }
23
+
24
+ export { useApiPosts }
@@ -0,0 +1,29 @@
1
+ import { PostEntity } from '../entities'
2
+ import { type PostResource } from '../resources'
3
+
4
+ const POST_RESOURCE_LIST: PostResource[] = [
5
+ {
6
+ id: '1',
7
+ title: 'Getting started with the API layer',
8
+ description: 'A short walkthrough of resources, entities and queries.',
9
+ number_of_likes: 12,
10
+ number_of_comments: 3,
11
+ },
12
+ {
13
+ id: '2',
14
+ title: 'Caching reference data',
15
+ description: 'When to set staleTime and persist on a query.',
16
+ number_of_likes: 47,
17
+ number_of_comments: 8,
18
+ },
19
+ ]
20
+
21
+ const getPostMockResourceList = () => {
22
+ return JSON.parse(JSON.stringify(POST_RESOURCE_LIST)) as PostResource[]
23
+ }
24
+
25
+ const getPostMockEntityList = () => {
26
+ return getPostMockResourceList().map((post) => new PostEntity(post))
27
+ }
28
+
29
+ export { getPostMockResourceList, getPostMockEntityList }
@@ -20,8 +20,11 @@ class BaseEntity<Resource extends BaseResource> {
20
20
  this.updatedAt = resource?.updated_at ?? new Date()
21
21
  }
22
22
 
23
- get isPending() {
24
- return this.resource?.is_pending ?? this.context?.is_pending ?? false
23
+ /**
24
+ * Флаг определяющий, что данные еще не подгружены
25
+ */
26
+ get isSkeleton() {
27
+ return this.resource?.is_skeleton ?? this.context?.is_skeleton ?? false
25
28
  }
26
29
  }
27
30
 
@@ -0,0 +1,9 @@
1
+ type BaseResource = {
2
+ id?: string
3
+ created_at?: Date
4
+ updated_at?: Date
5
+ /** Флаг определяющий, что данные еще не подгружены **/
6
+ is_skeleton?: boolean
7
+ }
8
+
9
+ export type { BaseResource }
@@ -0,0 +1,14 @@
1
+ import { queryOptions } from '@tanstack/react-query'
2
+ import { Api } from '../api'
3
+ import { QUERY_KEYS } from '../constants'
4
+
5
+ const healthQueries = {
6
+ key: [QUERY_KEYS.HEALTH] as const,
7
+ detail: () =>
8
+ queryOptions({
9
+ queryKey: healthQueries.key,
10
+ queryFn: (options) => Api.healthRepository.getHealth({ options }),
11
+ }),
12
+ }
13
+
14
+ export { healthQueries }
@@ -0,0 +1,2 @@
1
+ export * from './health'
2
+ export * from './post'
@@ -0,0 +1,23 @@
1
+ import { queryOptions } from '@tanstack/react-query'
2
+ import { Api } from '../api'
3
+ import { QUERY_KEYS, STALE_TIME } from '../constants'
4
+ import { type PostEntity } from '../entities'
5
+ import { type GetPostListConfig } from '../repositories'
6
+
7
+ const postQueries = {
8
+ key: [QUERY_KEYS.POSTS] as const,
9
+ list: (config: GetPostListConfig = {}) =>
10
+ queryOptions({
11
+ queryKey: [...postQueries.key, config] as const,
12
+ queryFn: (options) => Api.postRepository.getPostList({ ...config, options }),
13
+ staleTime: STALE_TIME,
14
+ meta: { persist: true },
15
+ }),
16
+ detail: (id: PostEntity['id']) =>
17
+ queryOptions({
18
+ queryKey: [...postQueries.key, id] as const,
19
+ queryFn: (options) => Api.postRepository.getPost({ id, options }),
20
+ }),
21
+ }
22
+
23
+ export { postQueries }
@@ -0,0 +1,11 @@
1
+ import { ApiInstance } from '../../models'
2
+ import { type GetHealthApiConfig, type GetHealthApiResponse } from './health.types'
3
+
4
+ class HealthRepository extends ApiInstance {
5
+ // no auth
6
+ async getHealth({ options }: GetHealthApiConfig) {
7
+ return await this.get<GetHealthApiResponse>('/', { options })
8
+ }
9
+ }
10
+
11
+ export default HealthRepository
@@ -0,0 +1,25 @@
1
+ import { type ApiConfig, type ApiResponse } from '../../api.types'
2
+
3
+ type GetHealthConfig = {}
4
+
5
+ type GetHealthResponse = {
6
+ maintenance?: boolean
7
+ start_at?: Date
8
+ }
9
+
10
+ // config
11
+
12
+ type GetHealthApiConfig = ApiConfig<GetHealthConfig>
13
+
14
+ // response
15
+
16
+ type GetHealthApiResponse = ApiResponse<GetHealthResponse>
17
+
18
+ export type {
19
+ GetHealthConfig,
20
+ GetHealthResponse,
21
+ // config
22
+ GetHealthApiConfig,
23
+ // response
24
+ GetHealthApiResponse,
25
+ }
@@ -0,0 +1,2 @@
1
+ export { default as HealthRepository } from './health'
2
+ export { type GetHealthConfig, type GetHealthResponse } from './health.types'
@@ -0,0 +1,9 @@
1
+ export { default as PostRepository } from './post'
2
+ export {
3
+ type CreatePostConfig,
4
+ type CreatePostResponse,
5
+ type GetPostConfig,
6
+ type GetPostListConfig,
7
+ type GetPostListResponse,
8
+ type GetPostResponse,
9
+ } from './post.types'
@@ -0,0 +1,34 @@
1
+ import { ApiInstance } from '../../models'
2
+ import {
3
+ type CreatePostApiConfig,
4
+ type CreatePostApiResponse,
5
+ type GetPostApiConfig,
6
+ type GetPostApiResponse,
7
+ type GetPostListApiConfig,
8
+ type GetPostListApiResponse,
9
+ } from './post.types'
10
+
11
+ class PostRepository extends ApiInstance {
12
+ // no auth
13
+ async getPostList({ isPublished, options }: GetPostListApiConfig) {
14
+ return await this.get<GetPostListApiResponse>('/', {
15
+ params: { is_published: isPublished },
16
+ options,
17
+ })
18
+ }
19
+
20
+ // auth
21
+ async getPost({ id, options }: GetPostApiConfig) {
22
+ return await this.get<GetPostApiResponse>(`/${id}`, { options })
23
+ }
24
+
25
+ // auth
26
+ async createPost({ title, description, options }: CreatePostApiConfig) {
27
+ return await this.post<CreatePostApiResponse>('/', {
28
+ body: { title, description },
29
+ options,
30
+ })
31
+ }
32
+ }
33
+
34
+ export default PostRepository
@@ -0,0 +1,61 @@
1
+ import { type ApiConfig, type ApiResponse } from '../../api.types'
2
+ import { type PostEntity } from '../../entities'
3
+ import { type PostResource } from '../../resources'
4
+
5
+ type GetPostListConfig = {
6
+ isPublished?: boolean
7
+ }
8
+
9
+ type GetPostConfig = {
10
+ id: PostEntity['id']
11
+ }
12
+
13
+ type CreatePostConfig = {
14
+ title: string
15
+ description?: string
16
+ }
17
+
18
+ type GetPostListResponse = {
19
+ data?: PostResource[]
20
+ }
21
+
22
+ type GetPostResponse = {
23
+ data?: PostResource
24
+ }
25
+
26
+ type CreatePostResponse = {
27
+ data?: PostResource
28
+ }
29
+
30
+ // config
31
+
32
+ type GetPostListApiConfig = ApiConfig<GetPostListConfig>
33
+
34
+ type GetPostApiConfig = ApiConfig<GetPostConfig>
35
+
36
+ type CreatePostApiConfig = ApiConfig<CreatePostConfig>
37
+
38
+ // response
39
+
40
+ type GetPostListApiResponse = ApiResponse<GetPostListResponse>
41
+
42
+ type GetPostApiResponse = ApiResponse<GetPostResponse>
43
+
44
+ type CreatePostApiResponse = ApiResponse<CreatePostResponse>
45
+
46
+ export type {
47
+ GetPostListConfig,
48
+ GetPostConfig,
49
+ CreatePostConfig,
50
+ GetPostListResponse,
51
+ GetPostResponse,
52
+ CreatePostResponse,
53
+ // config
54
+ GetPostListApiConfig,
55
+ GetPostApiConfig,
56
+ CreatePostApiConfig,
57
+ // response
58
+ GetPostListApiResponse,
59
+ GetPostApiResponse,
60
+ CreatePostApiResponse,
61
+ }