Skip to content

Commit 382d2c2

Browse files
authored
Merge pull request #3 from markus-bcit/deployment
Deployment
2 parents 683febe + acb09de commit 382d2c2

18 files changed

Lines changed: 1271 additions & 5 deletions

.claude/settings.local.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"permissions": {
3+
"allow": [
4+
"Bash([ -f \"eas.json\" ])",
5+
"Bash(mkdir:*)"
6+
],
7+
"deny": [],
8+
"ask": []
9+
}
10+
}

.env.example

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# API Configuration
2+
API_BASE_URL=http://localhost:7071/api
3+
4+
# Feature Flags
5+
USE_MOCK_DATA=false
6+
7+
# Mock User ID for local testing
8+
MOCK_USER_ID=123e4567-e89b-12d3-a456-426614174001

.github/workflows/build.yml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: Build iOS & Android
2+
3+
on:
4+
push:
5+
branches: [main, integration]
6+
pull_request:
7+
branches: [main, integration]
8+
workflow_dispatch: # Manual trigger
9+
10+
jobs:
11+
build:
12+
name: EAS Build
13+
runs-on: ubuntu-latest
14+
strategy:
15+
matrix:
16+
platform: [ios, android]
17+
steps:
18+
- name: Checkout code
19+
uses: actions/checkout@v4
20+
21+
- name: Setup Node.js
22+
uses: actions/setup-node@v4
23+
with:
24+
node-version: 18
25+
cache: 'npm'
26+
27+
- name: Setup Expo and EAS
28+
uses: expo/expo-github-action@v8
29+
with:
30+
expo-version: latest
31+
eas-version: latest
32+
token: ${{ secrets.EXPO_TOKEN }}
33+
34+
- name: Install dependencies
35+
run: npm ci
36+
37+
- name: Build ${{ matrix.platform }}
38+
run: |
39+
eas build --platform ${{ matrix.platform }} --profile preview --non-interactive
40+
41+
- name: Comment build status
42+
if: github.event_name == 'pull_request'
43+
uses: actions/github-script@v7
44+
with:
45+
script: |
46+
github.rest.issues.createComment({
47+
issue_number: context.issue.number,
48+
owner: context.repo.owner,
49+
repo: context.repo.repo,
50+
body: '✅ ${{ matrix.platform }} build complete! Download from https://expo.dev/accounts/markus-bcit/projects/bolic-app/builds'
51+
})

CLAUDE.md

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,30 @@ Development mock data in `data/mock-data.ts`:
113113

114114
All mock data structured according to API schema for seamless future integration.
115115

116-
### API Reference
116+
### API Integration
117117
Backend API spec: `openapi.yaml`
118-
- Endpoints: `/training-days`, `/exercises`, `/training-session`
118+
- **Base URL**: `http://localhost:7071/api` (local development)
119+
- **Endpoints**: `/training-days`, `/exercises`, `/training-session`
119120
- Science-based metrics: RIR (Reps In Reserve), RPE (Rate of Perceived Exertion)
120121
- Target position tracking (lengthened, shortened)
121122
- Muscle-specific subcategories for precise tracking
123+
124+
API Services (`services/api/`):
125+
- `config.ts` - API configuration and environment variables
126+
- `client.ts` - Base HTTP client with error handling
127+
- `training-days.ts` - Training day CRUD operations
128+
- `exercises.ts` - Exercise management functions
129+
- `training-sessions.ts` - Training session operations
130+
- `data-source.ts` - Unified interface with mock/API toggle
131+
132+
React Hooks:
133+
- `hooks/useTrainingDay.ts` - Hook for fetching training days with loading/error states
134+
135+
Environment Configuration (`.env`):
136+
```env
137+
API_BASE_URL=http://localhost:7071/api
138+
USE_MOCK_DATA=false # Set to true to use mock data, false for real API
139+
MOCK_USER_ID=123e4567-e89b-12d3-a456-426614174001
140+
```
141+
142+
See `services/api/README.md` for detailed usage examples.

SIDELOADING.md

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# Sideloading Guide
2+
3+
This guide explains how to install the iOS app on your iPhone without paying for the Apple Developer Program ($100/year).
4+
5+
## Quick Overview
6+
7+
1. **GitHub Actions** builds the IPA automatically
8+
2. **Download** the IPA from EAS
9+
3. **Sideload** using AltStore or Sideloadly
10+
4. **Re-sign** every 7 days (free Apple ID limitation)
11+
12+
## Step 1: Set Up GitHub Actions
13+
14+
### Required Secret
15+
Add your Expo token to GitHub repository secrets:
16+
17+
1. Get your Expo token:
18+
```bash
19+
npx expo login
20+
npx eas whoami
21+
npx eas token:create
22+
```
23+
24+
2. Add to GitHub:
25+
- Go to your repo → Settings → Secrets and variables → Actions
26+
- Click "New repository secret"
27+
- Name: `EXPO_TOKEN`
28+
- Value: [paste your token]
29+
30+
### Trigger a Build
31+
32+
Builds automatically run on push to `main` or `integration` branches.
33+
34+
Or manually trigger:
35+
- Go to Actions tab → "Build iOS & Android" → "Run workflow"
36+
37+
## Step 2: Download the IPA
38+
39+
After the build completes (15-20 minutes):
40+
41+
1. Go to https://expo.dev
42+
2. Navigate to your project → Builds
43+
3. Find the latest iOS build
44+
4. Click "Download" to get the `.ipa` file
45+
46+
## Step 3: Sideload to Your iPhone
47+
48+
### Option A: AltStore (Recommended)
49+
**Free, wireless, auto-refresh**
50+
51+
1. Download AltServer from https://altstore.io
52+
2. Install AltStore on your iPhone via AltServer (follow their guide)
53+
3. Open AltStore on iPhone → My Apps → + → Select the IPA
54+
4. AltStore will auto-refresh every 7 days when on same WiFi
55+
56+
### Option B: Sideloadly
57+
**Free, wired connection**
58+
59+
1. Download from https://sideloadly.io
60+
2. Connect iPhone via USB
61+
3. Drag IPA into Sideloadly
62+
4. Enter Apple ID and click Start
63+
5. Manually re-sideload every 7 days
64+
65+
### Option C: TrollStore (If Available)
66+
**Permanent install, no 7-day limit**
67+
68+
Only works on specific iOS versions (check trollstore.app for compatibility):
69+
- Install TrollStore
70+
- Open IPA with TrollStore
71+
- No re-signing needed!
72+
73+
## Step 4: Trust the Certificate
74+
75+
First time installing:
76+
1. Go to Settings → General → VPN & Device Management
77+
2. Tap your Apple ID
78+
3. Tap "Trust"
79+
80+
## Troubleshooting
81+
82+
### Build Fails
83+
- Check GitHub Actions logs
84+
- Ensure `EXPO_TOKEN` secret is set correctly
85+
- Verify `eas.json` configuration
86+
87+
### "Untrusted Developer"
88+
- Go to Settings → General → VPN & Device Management
89+
- Trust your Apple ID certificate
90+
91+
### App Crashes on Launch
92+
- Make sure you downloaded the **iOS** build, not Android
93+
- Try rebuilding with `eas build --platform ios --profile preview --clear-cache`
94+
95+
### Re-signing Expired (7 days)
96+
- Download the IPA again from EAS (same build works)
97+
- Or trigger a new build in GitHub Actions
98+
- Sideload again with AltStore/Sideloadly
99+
100+
## Build Profiles Explained
101+
102+
From `eas.json`:
103+
104+
- **preview** (for sideloading): Creates internal distribution IPA/APK
105+
- iOS: Archive build suitable for sideloading
106+
- Android: APK file for direct install
107+
108+
- **development**: Development client with hot reload
109+
110+
- **production**: For App Store/Play Store submission
111+
112+
## Cost Comparison
113+
114+
| Method | Cost | Re-sign Frequency |
115+
|--------|------|-------------------|
116+
| Free Apple ID + Sideloading | $0 | Every 7 days |
117+
| Apple Developer Program | $100/year | Never |
118+
| TrollStore (if compatible) | $0 | Never |
119+
120+
## Resources
121+
122+
- [AltStore Setup Guide](https://altstore.io)
123+
- [Sideloadly Guide](https://sideloadly.io)
124+
- [EAS Build Documentation](https://docs.expo.dev/build/introduction/)
125+
- [TrollStore Compatibility](https://ios.cfw.guide/installing-trollstore/)

app/(tabs)/programs.tsx

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { Colors } from '@/constants/theme';
66
import { mockTrainingDay, mockFullPrograms } from '@/data/mock-data';
77
import type { TrainingExercise, Program, Mesocycle } from '@/types/training';
88
import { useThemeCustomization } from '@/contexts/ThemeContext';
9+
import { router } from 'expo-router';
910

1011
const muscleCategoryIcons: Record<string, keyof typeof Ionicons.glyphMap> = {
1112
Chest: 'fitness',
@@ -226,7 +227,16 @@ export default function ProgramsPage() {
226227

227228
{/* Current Training Day */}
228229
<View style={styles.trainingDaySection}>
229-
<Text style={[styles.sectionTitle, { color: theme.text }]}>Current Training Day</Text>
230+
<View style={styles.sectionHeader}>
231+
<Text style={[styles.sectionTitle, { color: theme.text }]}>Current Training Day</Text>
232+
<TouchableOpacity
233+
style={[styles.newExerciseButton, { backgroundColor: customColors.primaryButton }]}
234+
onPress={() => router.push('/exercise-form')}
235+
>
236+
<Ionicons name="add" size={20} color="white" />
237+
<Text style={styles.newExerciseButtonText}>New Exercise</Text>
238+
</TouchableOpacity>
239+
</View>
230240
<View style={[styles.trainingDayCard, { backgroundColor: theme.card, borderColor: theme.cardBorder }]}>
231241
{/* Training Day Header */}
232242
<View style={styles.trainingDayHeader}>
@@ -410,10 +420,28 @@ const styles = StyleSheet.create({
410420
marginTop: 8,
411421
marginBottom: 16,
412422
},
423+
sectionHeader: {
424+
flexDirection: 'row',
425+
alignItems: 'center',
426+
justifyContent: 'space-between',
427+
marginBottom: 12,
428+
},
413429
sectionTitle: {
414430
fontSize: 20,
415431
fontWeight: '600',
416-
marginBottom: 12,
432+
},
433+
newExerciseButton: {
434+
flexDirection: 'row',
435+
alignItems: 'center',
436+
gap: 6,
437+
paddingHorizontal: 16,
438+
paddingVertical: 10,
439+
borderRadius: 12,
440+
},
441+
newExerciseButtonText: {
442+
color: 'white',
443+
fontSize: 15,
444+
fontWeight: '600',
417445
},
418446
trainingDayCard: {
419447
borderRadius: 16,

app/_layout.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ export default function RootLayout() {
3030
headerShown: false,
3131
}}
3232
/>
33+
<Stack.Screen
34+
name="exercise-form"
35+
options={{
36+
presentation: 'modal',
37+
headerShown: false,
38+
}}
39+
/>
3340
</Stack>
3441
<StatusBar style="auto" />
3542
</ThemeProvider>

0 commit comments

Comments
 (0)