@mediacubeco/expo-template-fsd 1.2.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/rules/app-routing.mdc +5 -5
- package/.claude/rules/mediacubeco-packages.mdc +56 -0
- package/.claude/settings.json +11 -0
- package/.claude/settings.local.json +11 -0
- package/.claude/skills/code-style/SKILL.md +1 -0
- package/.claude/skills/generate-api-model/SKILL.md +193 -61
- package/.claude/skills/generate-api-model/references/entities/common.ts +28 -0
- package/.claude/skills/generate-api-model/references/entities/index.ts +4 -0
- package/.claude/skills/generate-api-model/references/entities/post/index.ts +2 -0
- package/.claude/skills/generate-api-model/references/entities/post/post-comment.ts +16 -0
- package/.claude/skills/generate-api-model/references/entities/post/post.ts +27 -0
- package/.claude/skills/generate-api-model/references/entities/user/index.ts +3 -0
- package/.claude/skills/generate-api-model/references/entities/user/user-settings.ts +16 -0
- package/.claude/skills/generate-api-model/references/entities/user/user-verification.ts +22 -0
- package/.claude/skills/generate-api-model/references/entities/user/user.ts +26 -0
- package/.claude/skills/generate-api-model/references/resources/common.ts +8 -0
- package/.claude/skills/generate-api-model/references/resources/index.ts +4 -0
- package/.claude/skills/generate-api-model/references/resources/post/index.ts +2 -0
- package/.claude/skills/generate-api-model/references/resources/post/post-comment.ts +8 -0
- package/.claude/skills/generate-api-model/references/resources/post/post.ts +14 -0
- package/.claude/skills/generate-api-model/references/resources/user/index.ts +3 -0
- package/.claude/skills/generate-api-model/references/resources/user/user-settings.ts +8 -0
- package/.claude/skills/generate-api-model/references/resources/user/user-verification.ts +16 -0
- package/.claude/skills/generate-api-model/references/resources/user/user.ts +13 -0
- package/.claude/skills/git-commit/SKILL.md +139 -0
- package/.env +0 -1
- package/.env.example +0 -1
- package/CLAUDE.md +80 -0
- package/env.d.ts +0 -1
- package/expo-env.d.ts +3 -0
- package/i18next.d.ts +1 -1
- package/package.json +44 -43
- package/skills-lock.json +29 -0
- package/src/app/_app.tsx +2 -0
- package/src/shared/assets/icons/like.tsx +1 -1
- package/src/shared/constants/environment.ts +1 -7
- package/src/shared/hooks/use-animated.ts +1 -1
- package/src/shared/hooks/use-safe-area.ts +2 -2
- package/src/shared/lib/api/api.provider.tsx +2 -2
- package/src/shared/lib/api/api.types.ts +1 -1
- package/src/shared/lib/api/entities/common.ts +5 -5
- package/src/shared/lib/api/hooks/common.ts +1 -1
- package/src/shared/lib/api/models/api-instance/api-instance.ts +9 -9
- package/src/shared/lib/api/models/api-instance/api-instance.types.ts +1 -1
- package/src/shared/lib/api/models/api-instance/api-instance.utils.ts +4 -4
- package/src/shared/lib/api/repositories/auth/auth.ts +6 -1
- package/src/shared/lib/api/repositories/auth/auth.types.ts +1 -1
- package/src/shared/lib/api/resources/common.ts +3 -3
- package/src/shared/lib/localization/constants/index.ts +1 -1
- package/src/shared/lib/localization/hooks/use-localization.ts +1 -1
- package/src/shared/lib/localization/localization.provider.tsx +1 -1
- package/src/shared/lib/localization/localization.types.ts +1 -1
- package/src/shared/lib/localization/utils/storage.ts +1 -1
- package/src/shared/lib/navigation/hooks/use-navigation-options.ts +7 -6
- package/src/shared/lib/navigation/navigation.provider.tsx +2 -2
- package/src/shared/lib/navigation/navigation.types.ts +1 -1
- package/src/shared/lib/theme/theme.context.ts +1 -1
- package/src/shared/lib/theme/theme.provider.tsx +21 -6
- package/src/shared/lib/theme/theme.types.ts +2 -2
- package/src/shared/lib/theme/utils/storage.ts +1 -1
- package/src/shared/ui/molecules/keyboard-area/keyboard-area.tsx +1 -1
- package/src/shared/ui/molecules/refresh-control/refresh-control.tsx +1 -1
- package/src/shared/ui/molecules/refresh-control/refresh-control.types.ts +1 -1
- package/src/shared/ui/templates/screen-container/screen-container-list.tsx +1 -1
- package/src/shared/ui/templates/screen-container/screen-container-scroll.tsx +1 -1
- package/src/shared/ui/templates/screen-container/screen-container-section-list.tsx +1 -1
- package/src/shared/ui/templates/screen-container/screen-container.hooks.tsx +3 -3
- package/src/shared/ui/templates/screen-container/screen-container.styles.ts +1 -1
- package/src/shared/ui/templates/screen-container/screen-container.types.tsx +13 -13
- package/svg.d.ts +1 -1
- package/.claude/mcp.json +0 -0
- package/.claude/rules/abstract-skills-agents.mdc +0 -25
- package/src/shared/utils/generators.ts +0 -11
- package/src/shared/utils/index.ts +0 -1
- /package/src/{screens → pages}/.gitkeep +0 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type BaseResource } from '../common'
|
|
2
|
+
|
|
3
|
+
enum UserVerificationStatus {
|
|
4
|
+
Pending = 1,
|
|
5
|
+
Verified = 2,
|
|
6
|
+
Rejected = 3,
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
type UserVerificationResource = BaseResource & {
|
|
10
|
+
is_email_verified?: boolean
|
|
11
|
+
is_phone_verified?: boolean
|
|
12
|
+
status?: UserVerificationStatus
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export { UserVerificationStatus }
|
|
16
|
+
export type { UserVerificationResource }
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type BaseResource } from '../common'
|
|
2
|
+
import { type UserSettingsResource } from './user-settings'
|
|
3
|
+
import { type UserVerificationResource } from './user-verification'
|
|
4
|
+
|
|
5
|
+
type UserResource = BaseResource & {
|
|
6
|
+
first_name?: string
|
|
7
|
+
last_name?: string
|
|
8
|
+
avatar?: string
|
|
9
|
+
verification?: UserVerificationResource
|
|
10
|
+
settings?: UserSettingsResource
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type { UserResource }
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: git-commit
|
|
3
|
+
description: Creates git commits with proper messages and decomposes staged/unstaged changes into logical atomic commits. Use this skill whenever the user says "commit", "закоммить", "сделай коммит", "commit changes", "push", or asks to commit anything. Also use when the user asks to split or decompose changes into multiple commits. Always invoke this skill before running any git commit command — it provides the decomposition logic and message format rules for this project.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Git Commit Skill
|
|
7
|
+
|
|
8
|
+
This skill governs how to commit changes in this repository. The key goals are:
|
|
9
|
+
|
|
10
|
+
- Every commit is **atomic** — one logical change per commit, easy to revert or cherry-pick
|
|
11
|
+
- Every commit message **starts with the branch identifier** so commits are traceable to their task
|
|
12
|
+
- The message body is **specific and complete** — a future reader can understand what changed without looking at the diff
|
|
13
|
+
|
|
14
|
+
## Step 1: Understand the branch
|
|
15
|
+
|
|
16
|
+
Extract the branch identifier by stripping the `feature/` prefix:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
git branch --show-current
|
|
20
|
+
# feature/CU-869cbv9z3 → prefix = "CU-869cbv9z3"
|
|
21
|
+
# fix/CU-123abc → prefix = "CU-123abc"
|
|
22
|
+
# main → prefix = "" (no prefix, use plain message)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
If the branch has no prefix to strip (e.g., `main`, `develop`), commit without a prefix.
|
|
26
|
+
|
|
27
|
+
## Step 2: Analyze all changes
|
|
28
|
+
|
|
29
|
+
Run these together to get the full picture:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
git status
|
|
33
|
+
git diff HEAD
|
|
34
|
+
git diff --cached
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Read the actual diff carefully — don't just look at filenames. You need to understand _what_ each change does, not just _where_ it is, to group things correctly.
|
|
38
|
+
|
|
39
|
+
## Step 3: Decompose into logical commits
|
|
40
|
+
|
|
41
|
+
This is the most important step. Think like a reviewer who will bisect this history in six months.
|
|
42
|
+
|
|
43
|
+
**Each commit should answer one question: "What single thing does this do?"**
|
|
44
|
+
|
|
45
|
+
Good decomposition principles:
|
|
46
|
+
|
|
47
|
+
- **By concern, not by file** — a component and its corresponding style/hook that only exist to support it belong together
|
|
48
|
+
- **Config/tooling separate from features** — `eslint`, `tsconfig`, `package.json`, `.env` changes are their own commit unless they were added specifically to enable a single feature that's in the same batch
|
|
49
|
+
- **Shared infrastructure separate from consumers** — a new shared component goes in one commit, the screen that uses it goes in another
|
|
50
|
+
- **Refactoring separate from new behavior** — if you cleaned up a file while adding a feature, those are two commits
|
|
51
|
+
- **In FSD terms**: changes that span multiple layers (`shared` + `entities` + `features` + `pages`) usually mean multiple commits — one per layer boundary crossed
|
|
52
|
+
|
|
53
|
+
Common anti-patterns to avoid:
|
|
54
|
+
|
|
55
|
+
- One giant commit with "various fixes" — always decompose
|
|
56
|
+
- Splitting one logical unit across commits (e.g., a component in one commit, its required types in another)
|
|
57
|
+
- Committing unrelated files together just because they were modified in the same session
|
|
58
|
+
|
|
59
|
+
After analyzing, produce a decomposition plan like this (show it mentally, then execute without asking for confirmation unless the decomposition is genuinely ambiguous):
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
Commit 1: CU-869cbv9z3: add UserEntity and UserResource types
|
|
63
|
+
→ src/shared/lib/api/entities/user.ts
|
|
64
|
+
→ src/shared/lib/api/resources/user.ts
|
|
65
|
+
|
|
66
|
+
Commit 2: CU-869cbv9z3: add UserRepository with profile endpoint
|
|
67
|
+
→ src/shared/lib/api/models/user-repository.ts
|
|
68
|
+
→ src/shared/lib/api/api.ts (registration only)
|
|
69
|
+
|
|
70
|
+
Commit 3: CU-869cbv9z3: add profile screen with user data fetching
|
|
71
|
+
→ src/pages/profile/
|
|
72
|
+
→ src/features/profile/
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Step 4: Stage and commit each group
|
|
76
|
+
|
|
77
|
+
For each commit in the plan, stage exactly the relevant files and commit:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
# Stage specific files (never use git add . or git add -A)
|
|
81
|
+
git add .
|
|
82
|
+
|
|
83
|
+
# Commit with the correct message format
|
|
84
|
+
git commit -m "{prefix}: add UserEntity and UserResource types"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Repeat for each commit in the plan.
|
|
88
|
+
|
|
89
|
+
If a single file contains changes that belong to different logical commits (mixed concerns in one file), use `git add -p` to stage only the relevant hunks:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
git add -p src/shared/lib/api/api.ts
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Commit message format
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
BRANCH-ID: short imperative description
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Rules:
|
|
102
|
+
|
|
103
|
+
- Start with the branch ID (everything after `feature/`, `fix/`, `chore/` etc.)
|
|
104
|
+
- Follow with `: ` then the message
|
|
105
|
+
- Use imperative mood: "add", "fix", "remove", "update", "extract" — not "added", "adding", "fixes"
|
|
106
|
+
- Be specific: "add UserEntity with profile fields" beats "add user types"
|
|
107
|
+
- Keep it under 72 characters total
|
|
108
|
+
- No period at the end
|
|
109
|
+
|
|
110
|
+
**Examples:**
|
|
111
|
+
|
|
112
|
+
| Situation | Message |
|
|
113
|
+
| -------------------- | ----------------------------------------------------- |
|
|
114
|
+
| New API types | `{prefix} - add OrderResource and OrderEntity` |
|
|
115
|
+
| New screen | `{prefix} - add checkout screen with order summary` |
|
|
116
|
+
| Bug fix | `{prefix} - fix token refresh on 401 response` |
|
|
117
|
+
| Config change | `{prefix} - add react-query persistence config` |
|
|
118
|
+
| Refactor | `{prefix} - extract AuthHeader into shared component` |
|
|
119
|
+
| Multiple small fixes | `{prefix} - fix navigation types and screen params` |
|
|
120
|
+
|
|
121
|
+
## Step 5: Verify
|
|
122
|
+
|
|
123
|
+
After all commits are done:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
git log --oneline -10
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Each commit should read cleanly as a standalone unit of work. If two adjacent commits feel like they should be one, or one commit feels like it should be two — that's worth noting but not worth amending if already done.
|
|
130
|
+
|
|
131
|
+
## Edge cases
|
|
132
|
+
|
|
133
|
+
**Nothing staged, nothing to commit** — say so and stop. Don't create empty commits.
|
|
134
|
+
|
|
135
|
+
**Only whitespace / formatting changes** — still a valid commit: `{prefix} - format auth module`.
|
|
136
|
+
|
|
137
|
+
**Single logical change across many files** — fine, that's one commit. Stage all the files together.
|
|
138
|
+
|
|
139
|
+
**Uncertain decomposition** — if you genuinely cannot tell whether two changes are the same logical unit, keep them together. Atomic is better than artificially split.
|
package/.env
CHANGED
package/.env.example
CHANGED
package/CLAUDE.md
CHANGED
|
@@ -1 +1,81 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
1
5
|
@AGENTS.md
|
|
6
|
+
@README.md
|
|
7
|
+
|
|
8
|
+
## Environment
|
|
9
|
+
|
|
10
|
+
Create `.env.local` with:
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
EXPO_PUBLIC_API_URL=https://...
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Required at startup — `src/shared/constants/environment.ts` throws if is missing or `API_URL` doesn't start with `https://`.
|
|
17
|
+
|
|
18
|
+
## Architecture
|
|
19
|
+
|
|
20
|
+
FSD (Feature-Sliced Design) layers, top to bottom:
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
src/app/ — Expo Router entry, provider composition
|
|
24
|
+
src/pages/ — Full screen components
|
|
25
|
+
src/widgets/ — Composite UI blocks
|
|
26
|
+
src/features/ — User interaction slices
|
|
27
|
+
src/entities/ — Business domain models (consumer-side)
|
|
28
|
+
src/shared/ — Reusable code with no business logic
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Import alias: `~shared/` → `src/shared/`
|
|
32
|
+
|
|
33
|
+
### Provider stack (`src/app/_layout.tsx`)
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
ApiProvider → ThemeProvider → LocalizationProvider → NavigationProvider
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
- **ApiProvider** — TanStack Query with AsyncStorage persistence. Queries with `meta.persist = true` survive app restarts.
|
|
40
|
+
- **ThemeProvider** — light/dark/system mode stored in SecureStore. Theme tokens accessed via `useTheme()` / `useThemeMode()`.
|
|
41
|
+
- **LocalizationProvider** — i18next with `en`/`ru` translations in `src/shared/assets/translations/`.
|
|
42
|
+
- **NavigationProvider** — wraps GestureHandler, SafeArea, KeyboardController, and `@react-navigation/native`'s ThemeProvider.
|
|
43
|
+
|
|
44
|
+
### API layer (`src/shared/lib/api/`)
|
|
45
|
+
|
|
46
|
+
Two-type pattern for every API domain:
|
|
47
|
+
|
|
48
|
+
- **Resource** (`resources/`) — raw server shape, all fields optional, snake_case, extends `BaseResource`
|
|
49
|
+
- **Entity** (`entities/`) — class that consumes a Resource, exposes camelCase properties with safe defaults, extends `BaseEntity<Resource>`
|
|
50
|
+
|
|
51
|
+
`BaseEntity` provides `id`, `createdAt`, `updatedAt`, `isPending`. Entities accept an optional `context` (parent resource) for nested field fallbacks.
|
|
52
|
+
|
|
53
|
+
Repositories extend `ApiInstance` (`models/api-instance/`) which is an abstract class with typed `get/post/put/patch/delete` methods. All repositories are registered on the `Api` singleton (`api.ts`).
|
|
54
|
+
|
|
55
|
+
### Theme system (`src/shared/lib/theme/`)
|
|
56
|
+
|
|
57
|
+
Token constants live in `constants/` (colors, fonts, sizes, shadows, borders, durations, delays, transparencies, weights). Access inside components via:
|
|
58
|
+
|
|
59
|
+
- `useTheme()` — returns `{ theme, themeMode, themeModeSystem, setThemeMode }`
|
|
60
|
+
- `useThemeMode()` — returns `{ COLORS, FONTS, SIZES, … }` for the current mode
|
|
61
|
+
|
|
62
|
+
### Navigation (`src/shared/lib/navigation/`)
|
|
63
|
+
|
|
64
|
+
Expo Router with file-based routing. Helper hooks:
|
|
65
|
+
|
|
66
|
+
- `useNavigation()` — thin wrapper around `useRouter()`
|
|
67
|
+
- `useNavigationParams()` — typed local params
|
|
68
|
+
- `useNavigationStackOptions()` — returns `createStackOptions()` and `createScreenOptions()` factory functions
|
|
69
|
+
- `useNavigationTabBarOptions()` — returns `createTabBarOptions()` and `createTabOptions()` for native tabs
|
|
70
|
+
|
|
71
|
+
### Shared UI (`src/shared/ui/`)
|
|
72
|
+
|
|
73
|
+
Atomic design: `atoms/` → `molecules/` → `organisms/` → `templates/`.
|
|
74
|
+
|
|
75
|
+
`ScreenContainer` (in `templates/`) is the standard scrollable/list screen wrapper — handles safe area, pull-to-refresh (`RefreshControl`), keyboard avoidance (`KeyboardArea`), and header/footer overflow.
|
|
76
|
+
|
|
77
|
+
Utility hooks in `src/shared/hooks/`: `useTheme`, `useBreakpoints` (responsive breakpoints), `useMixins` (window-relative sizing), `useSafeArea`, `useAnimated`.
|
|
78
|
+
|
|
79
|
+
### Secrets
|
|
80
|
+
|
|
81
|
+
`.secret/` is git-ignored. Keystore and provisioning files go there — see `.secret/README.md` for the expected file list.
|
package/env.d.ts
CHANGED
package/expo-env.d.ts
ADDED
package/i18next.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"private": false,
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"name": "@mediacubeco/expo-template-fsd",
|
|
5
5
|
"description": "Application by Mediacube developers",
|
|
6
6
|
"license": "MIT",
|
|
@@ -10,57 +10,58 @@
|
|
|
10
10
|
"@tanstack/query-async-storage-persister": "^5.99.0",
|
|
11
11
|
"@tanstack/react-query": "^5.99.0",
|
|
12
12
|
"@tanstack/react-query-persist-client": "^5.99.0",
|
|
13
|
-
"expo": "~
|
|
14
|
-
"expo-blur": "~
|
|
15
|
-
"expo-constants": "~
|
|
16
|
-
"expo-device": "~
|
|
17
|
-
"expo-font": "~
|
|
18
|
-
"expo-glass-effect": "~
|
|
19
|
-
"expo-haptics": "~
|
|
20
|
-
"expo-image": "~
|
|
21
|
-
"expo-linking": "~
|
|
22
|
-
"expo-localization": "~
|
|
23
|
-
"expo-
|
|
24
|
-
"expo-
|
|
25
|
-
"expo-
|
|
26
|
-
"expo-
|
|
27
|
-
"expo-
|
|
28
|
-
"expo-
|
|
29
|
-
"expo-
|
|
13
|
+
"expo": "~56.0.8",
|
|
14
|
+
"expo-blur": "~56.0.3",
|
|
15
|
+
"expo-constants": "~56.0.16",
|
|
16
|
+
"expo-device": "~56.0.4",
|
|
17
|
+
"expo-font": "~56.0.5",
|
|
18
|
+
"expo-glass-effect": "~56.0.4",
|
|
19
|
+
"expo-haptics": "~56.0.3",
|
|
20
|
+
"expo-image": "~56.0.9",
|
|
21
|
+
"expo-linking": "~56.0.13",
|
|
22
|
+
"expo-localization": "~56.0.6",
|
|
23
|
+
"expo-navigation-bar": "~56.0.3",
|
|
24
|
+
"expo-router": "~56.2.8",
|
|
25
|
+
"expo-secure-store": "~56.0.4",
|
|
26
|
+
"expo-splash-screen": "~56.0.10",
|
|
27
|
+
"expo-status-bar": "~56.0.4",
|
|
28
|
+
"expo-symbols": "~56.0.5",
|
|
29
|
+
"expo-system-ui": "~56.0.5",
|
|
30
|
+
"expo-web-browser": "~56.0.5",
|
|
30
31
|
"i18next": "^26.0.5",
|
|
31
32
|
"react": "^19.2.0",
|
|
32
33
|
"react-dom": "^19.2.0",
|
|
33
34
|
"react-i18next": "^17.0.3",
|
|
34
|
-
"react-native": "^0.
|
|
35
|
-
"react-native-gesture-handler": "~2.
|
|
36
|
-
"react-native-keyboard-controller": "1.
|
|
37
|
-
"react-native-reanimated": "4.
|
|
38
|
-
"react-native-safe-area-context": "~5.
|
|
39
|
-
"react-native-screens": "~4.
|
|
40
|
-
"react-native-svg": "15.15.
|
|
35
|
+
"react-native": "^0.85.3",
|
|
36
|
+
"react-native-gesture-handler": "~2.31.2",
|
|
37
|
+
"react-native-keyboard-controller": "1.21.6",
|
|
38
|
+
"react-native-reanimated": "4.3.1",
|
|
39
|
+
"react-native-safe-area-context": "~5.7.0",
|
|
40
|
+
"react-native-screens": "~4.25.2",
|
|
41
|
+
"react-native-svg": "15.15.4",
|
|
41
42
|
"react-native-web": "^0.21.0",
|
|
42
|
-
"react-native-worklets": "0.
|
|
43
|
-
"@mediacubeco/base": "
|
|
44
|
-
"@mediacubeco/base
|
|
45
|
-
"@mediacubeco/base-react-native": "
|
|
43
|
+
"react-native-worklets": "0.8.3",
|
|
44
|
+
"@mediacubeco/base-react": "2.0.0",
|
|
45
|
+
"@mediacubeco/base": "2.0.0",
|
|
46
|
+
"@mediacubeco/base-react-native": "2.0.0"
|
|
46
47
|
},
|
|
47
48
|
"devDependencies": {
|
|
48
49
|
"@types/react": "^19.2.0",
|
|
49
|
-
"@types/react-dom": "^19.2.
|
|
50
|
+
"@types/react-dom": "^19.2.3",
|
|
50
51
|
"eslint": "^9.39.1",
|
|
51
52
|
"husky": "^9.1.7",
|
|
52
53
|
"prettier": "^3.8.1",
|
|
53
|
-
"typescript": "^
|
|
54
|
-
"@mediacubeco/eslint-config-fsd": "
|
|
55
|
-
"@mediacubeco/eslint-config": "
|
|
56
|
-
"@mediacubeco/eslint-config-react": "
|
|
57
|
-
"@mediacubeco/prettier-config
|
|
58
|
-
"@mediacubeco/typescript-config": "
|
|
59
|
-
"@mediacubeco/
|
|
60
|
-
"@mediacubeco/
|
|
61
|
-
"@mediacubeco/
|
|
62
|
-
"@mediacubeco/typescript-config
|
|
63
|
-
"@mediacubeco/
|
|
54
|
+
"typescript": "^6.0.3",
|
|
55
|
+
"@mediacubeco/eslint-config-fsd": "2.0.0",
|
|
56
|
+
"@mediacubeco/eslint-config": "2.0.0",
|
|
57
|
+
"@mediacubeco/eslint-config-react": "2.0.0",
|
|
58
|
+
"@mediacubeco/prettier-config": "2.0.0",
|
|
59
|
+
"@mediacubeco/typescript-config-fsd": "2.0.0",
|
|
60
|
+
"@mediacubeco/typescript-config-react": "2.0.0",
|
|
61
|
+
"@mediacubeco/typescript-config-react-native": "2.0.0",
|
|
62
|
+
"@mediacubeco/eslint-config-react-native": "2.0.0",
|
|
63
|
+
"@mediacubeco/typescript-config": "2.0.0",
|
|
64
|
+
"@mediacubeco/prettier-config-fsd": "2.0.0"
|
|
64
65
|
},
|
|
65
66
|
"scripts": {
|
|
66
67
|
"prebuild": "expo prebuild",
|
|
@@ -70,8 +71,8 @@
|
|
|
70
71
|
"ios": "expo start --ios",
|
|
71
72
|
"ios:device": "expo run:ios -d",
|
|
72
73
|
"web": "expo start --web",
|
|
73
|
-
"format": "prettier --write
|
|
74
|
-
"lint": "eslint
|
|
74
|
+
"format": "prettier --write ./src",
|
|
75
|
+
"lint": "eslint ./src",
|
|
75
76
|
"type": "tsc"
|
|
76
77
|
}
|
|
77
78
|
}
|
package/skills-lock.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"skills": {
|
|
4
|
+
"impeccable": {
|
|
5
|
+
"source": "pbakaus/impeccable",
|
|
6
|
+
"sourceType": "github",
|
|
7
|
+
"skillPath": ".agents/skills/impeccable/SKILL.md",
|
|
8
|
+
"computedHash": "2f248d7db158d32acb8d52e688444de1edbaccf7344ac5288634cbe427bc8a8a"
|
|
9
|
+
},
|
|
10
|
+
"react-native-best-practices": {
|
|
11
|
+
"source": "callstackincubator/agent-skills",
|
|
12
|
+
"sourceType": "github",
|
|
13
|
+
"skillPath": "skills/react-native-best-practices/SKILL.md",
|
|
14
|
+
"computedHash": "15bd57b18d9ad0dcd003bd2c7ec6ed17d813cc671dd4d423e1d904d2a7b9d2bb"
|
|
15
|
+
},
|
|
16
|
+
"vercel-react-best-practices": {
|
|
17
|
+
"source": "vercel-labs/agent-skills",
|
|
18
|
+
"sourceType": "github",
|
|
19
|
+
"skillPath": "skills/react-best-practices/SKILL.md",
|
|
20
|
+
"computedHash": "ca7b0c0c6e5f2750043f7f0cd72d16ac4e2abc48f9b5500d047a4b77a2506212"
|
|
21
|
+
},
|
|
22
|
+
"vercel-react-native-skills": {
|
|
23
|
+
"source": "vercel-labs/agent-skills",
|
|
24
|
+
"sourceType": "github",
|
|
25
|
+
"skillPath": "skills/react-native-skills/SKILL.md",
|
|
26
|
+
"computedHash": "41d24eafa7c3d82e270439808f7cfbc4d51aeb2d14f2809a2267c16275784d06"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
package/src/app/_app.tsx
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { NavigationBar } from 'expo-navigation-bar'
|
|
1
2
|
import { Stack } from 'expo-router'
|
|
2
3
|
import { StatusBar } from 'expo-status-bar'
|
|
3
4
|
import { useNavigationStackOptions } from '~shared/lib'
|
|
@@ -8,6 +9,7 @@ const App = () => {
|
|
|
8
9
|
return (
|
|
9
10
|
<>
|
|
10
11
|
<StatusBar style={'auto'} />
|
|
12
|
+
<NavigationBar style={'auto'} />
|
|
11
13
|
<Stack screenOptions={createStackOptions()}>
|
|
12
14
|
<Stack.Screen name={'(root)'} />
|
|
13
15
|
</Stack>
|
|
@@ -4,10 +4,4 @@ if (!API_URL || !API_URL.startsWith('https://')) {
|
|
|
4
4
|
throw new Error(`API_URL is invalid: ${API_URL}`)
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
if (!API_TOKEN) {
|
|
10
|
-
throw new Error(`API_TOKEN is invalid: ${API_TOKEN}`)
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export { API_URL, API_TOKEN }
|
|
7
|
+
export { API_URL }
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Platform } from 'react-native'
|
|
2
2
|
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
|
3
|
-
import { useBottomTabBarHeight } from '
|
|
4
|
-
import { useHeaderHeight } from '
|
|
3
|
+
import { useBottomTabBarHeight } from 'expo-router/js-tabs'
|
|
4
|
+
import { useHeaderHeight } from 'expo-router/react-navigation'
|
|
5
5
|
|
|
6
6
|
const ANDROID_TAB_BAR_DEFAULT_HEIGHT = 56
|
|
7
7
|
const IOS_TAB_BAR_DEFAULT_HEIGHT = 50
|
|
@@ -3,10 +3,10 @@ import { createAsyncStoragePersister } from '@tanstack/query-async-storage-persi
|
|
|
3
3
|
import { focusManager, QueryClient } from '@tanstack/react-query'
|
|
4
4
|
import {
|
|
5
5
|
PersistQueryClientProvider,
|
|
6
|
-
PersistQueryClientProviderProps,
|
|
6
|
+
type PersistQueryClientProviderProps,
|
|
7
7
|
} from '@tanstack/react-query-persist-client'
|
|
8
8
|
import { apiAsyncStorage } from './utils'
|
|
9
|
-
import { ApiProviderProps } from './api.types'
|
|
9
|
+
import { type ApiProviderProps } from './api.types'
|
|
10
10
|
|
|
11
11
|
const client = new QueryClient({
|
|
12
12
|
defaultOptions: {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { generateIdFactory } from '
|
|
2
|
-
import { BaseResource } from '../resources'
|
|
1
|
+
import { generateIdFactory } from '@mediacontent/base/utils'
|
|
2
|
+
import { type BaseResource } from '../resources'
|
|
3
3
|
|
|
4
4
|
const generateId = generateIdFactory()
|
|
5
5
|
|
|
@@ -16,12 +16,12 @@ class BaseEntity<Resource extends BaseResource> {
|
|
|
16
16
|
this.context = context
|
|
17
17
|
|
|
18
18
|
this.id = resource?.id ?? generateId()
|
|
19
|
-
this.createdAt = resource?.
|
|
20
|
-
this.updatedAt = resource?.
|
|
19
|
+
this.createdAt = resource?.created_at ?? new Date()
|
|
20
|
+
this.updatedAt = resource?.updated_at ?? new Date()
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
get isPending() {
|
|
24
|
-
return this.resource?.
|
|
24
|
+
return this.resource?.is_pending ?? this.context?.is_pending ?? false
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { ErrorHandler, Log } from '@mediacubeco/base/helpers'
|
|
2
|
-
import {
|
|
2
|
+
import { API_URL } from '../../../../constants'
|
|
3
3
|
import { formatRoute, formatURI } from './api-instance.utils'
|
|
4
4
|
import { ApiInstanceMethod } from './api-instance.constants'
|
|
5
5
|
import {
|
|
6
|
-
ApiInstanceConfig,
|
|
7
|
-
ApiInstanceDefaultBody,
|
|
8
|
-
ApiInstanceDefaultHeaders,
|
|
9
|
-
ApiInstanceDefaultParams,
|
|
10
|
-
ApiInstanceRoute,
|
|
11
|
-
ApiInstanceURL,
|
|
12
|
-
ApiInstanceURN,
|
|
6
|
+
type ApiInstanceConfig,
|
|
7
|
+
type ApiInstanceDefaultBody,
|
|
8
|
+
type ApiInstanceDefaultHeaders,
|
|
9
|
+
type ApiInstanceDefaultParams,
|
|
10
|
+
type ApiInstanceRoute,
|
|
11
|
+
type ApiInstanceURL,
|
|
12
|
+
type ApiInstanceURN,
|
|
13
13
|
} from './api-instance.types'
|
|
14
14
|
|
|
15
15
|
abstract class ApiInstance {
|
|
@@ -25,7 +25,7 @@ abstract class ApiInstance {
|
|
|
25
25
|
this.headers = {
|
|
26
26
|
'Accept': 'application/json',
|
|
27
27
|
'Content-Type': 'application/json',
|
|
28
|
-
'Authorization': `Bearer ${API_TOKEN}`,
|
|
28
|
+
// 'Authorization': `Bearer ${API_TOKEN}`,
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
|
-
ApiInstanceDefaultParams,
|
|
3
|
-
ApiInstanceRoute,
|
|
4
|
-
ApiInstanceURL,
|
|
5
|
-
ApiInstanceURN,
|
|
2
|
+
type ApiInstanceDefaultParams,
|
|
3
|
+
type ApiInstanceRoute,
|
|
4
|
+
type ApiInstanceURL,
|
|
5
|
+
type ApiInstanceURN,
|
|
6
6
|
} from './api-instance.types'
|
|
7
7
|
|
|
8
8
|
const formatURI = (url: ApiInstanceURL, urn: ApiInstanceURN, route: ApiInstanceRoute) => {
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { ApiInstance } from '../../models'
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
type SignInConfig,
|
|
4
|
+
type SignInResponse,
|
|
5
|
+
type SignUpConfig,
|
|
6
|
+
type SignUpResponse,
|
|
7
|
+
} from './auth.types'
|
|
3
8
|
|
|
4
9
|
class AuthRepository extends ApiInstance {
|
|
5
10
|
async signIn(_: SignInConfig) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useCallback } from 'react'
|
|
2
2
|
import { useTranslation } from 'react-i18next'
|
|
3
|
-
import { LocalizationCode } from '../constants'
|
|
3
|
+
import { type LocalizationCode } from '../constants'
|
|
4
4
|
import { localizationStorage } from '../utils'
|
|
5
5
|
|
|
6
6
|
const useLocalization = () => {
|