Skip to content

Commit 32a9fab

Browse files
authored
Merge pull request #44 from Resolum/release/v1.0.0
Release/v1.0.0
2 parents e99e874 + 1a8c13b commit 32a9fab

82 files changed

Lines changed: 3583 additions & 808 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/firebase-app-distribution.yml

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ jobs:
1717
steps:
1818
- name: Checkout repository
1919
uses: actions/checkout@v4
20+
with:
21+
fetch-depth: 0
2022

2123
- name: Set up JDK
2224
uses: actions/setup-java@v4
@@ -50,11 +52,74 @@ jobs:
5052
run: |
5153
echo "GOOGLE_APPLICATION_CREDENTIALS=$PWD/firebase-service-account.json" >> $GITHUB_ENV
5254
55+
- name: Decode and create keystore
56+
env:
57+
KEYSTORE_BASE: ${{ secrets.KEYSTORE_BASE }}
58+
run: |
59+
if [ -z "$KEYSTORE_BASE" ]; then
60+
echo "Missing KEYSTORE_BASE repository secret."
61+
exit 1
62+
fi
63+
printf '%s' "$KEYSTORE_BASE" | base64 --decode > "$RUNNER_TEMP/intiva-release.jks"
64+
echo "KEYSTORE_FILE_PATH=$RUNNER_TEMP/intiva-release.jks" >> $GITHUB_ENV
65+
echo "KEYSTORE_PATH=$RUNNER_TEMP/intiva-release.jks" >> $GITHUB_ENV
66+
67+
- name: Validate release keystore
68+
env:
69+
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
70+
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
71+
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
72+
run: |
73+
for secret_name in KEYSTORE_PASSWORD KEY_ALIAS KEY_PASSWORD; do
74+
if [ -z "${!secret_name}" ]; then
75+
echo "Missing $secret_name repository secret."
76+
exit 1
77+
fi
78+
done
79+
80+
keytool -list \
81+
-keystore "$KEYSTORE_PATH" \
82+
-storepass "$KEYSTORE_PASSWORD" \
83+
-alias "$KEY_ALIAS" > /dev/null
84+
85+
- name: Set app version
86+
run: |
87+
RAW_VERSION=""
88+
89+
if [[ "${GITHUB_EVENT_NAME}" == "release" ]]; then
90+
RAW_VERSION="${{ github.event.release.tag_name }}"
91+
elif [[ "${GITHUB_REF_NAME}" == release/* ]]; then
92+
RAW_VERSION="${GITHUB_REF_NAME#release/}"
93+
elif [[ "${GITHUB_REF_NAME}" == "main" ]]; then
94+
RAW_VERSION="$(git describe --tags --abbrev=0 2>/dev/null || true)"
95+
else
96+
RAW_VERSION="1.0.0"
97+
fi
98+
99+
if [[ -z "$RAW_VERSION" ]]; then
100+
RAW_VERSION="1.0.0"
101+
fi
102+
103+
VERSION_NAME="${RAW_VERSION#v}"
104+
VERSION_CODE="${GITHUB_RUN_NUMBER}"
105+
106+
echo "VERSION_NAME=$VERSION_NAME" >> $GITHUB_ENV
107+
echo "VERSION_CODE=$VERSION_CODE" >> $GITHUB_ENV
108+
echo "Version: $VERSION_NAME ($VERSION_CODE)"
109+
53110
- name: Grant execute permission to gradlew
54111
run: chmod +x ./gradlew
55112

56113
- name: Build release APK
114+
env:
115+
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
116+
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
117+
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
57118
run: ./gradlew assembleRelease
58119

59120
- name: Upload release to Firebase App Distribution
121+
env:
122+
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
123+
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
124+
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
60125
run: ./gradlew appDistributionUploadRelease

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
/.idea/workspace.xml
88
/.idea/navEditor.xml
99
/.idea/assetWizardSettings.xml
10+
/.idea
1011
.DS_Store
1112
/build
1213
/captures

.idea/deploymentTargetSelector.xml

Lines changed: 0 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/misc.xml

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

CONTRIBUTING.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Commit Guidelines
2+
3+
When contributing to this repository, please follow these guidelines to ensure a smooth and efficient collaboration process.
4+
5+
## Conventional Commits
6+
7+
Use the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification for commit messages. This helps maintain a clear and consistent commit history.
8+
9+
- Commit message must be in **English**.
10+
- Use present tense and an imperative mode.
11+
- Include a scope to specify the area of the codebase that is affected by the commit (optional but recommended).
12+
- You can use the following types of commits:
13+
- `feat`: A new feature.
14+
- `fix`: A bug fix.
15+
- `docs`: Documentation changes.
16+
- `refactor`: Code refactoring without changing functionality.
17+
- `test`: Adding or updating tests.
18+
- `chore`: Changes to the build process or auxiliary tools and libraries.
19+
20+
## Example Commit Message
21+
22+
```
23+
feat(home): add home screen.
24+
```
25+
26+
```
27+
docs: update read me file with installation instructions.
28+
```

LICENSE.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 Resolum
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Intiva Mobile Application
2+
3+
This repository contains the mobile application for the Intiva Platform, which is a platform for managing expenses, savings and incomes.
4+
The mobile application is built using Kotlin and Jetpack Compose and provides a user-friendly interface for users to interact with the features.
5+
It also uses Room for local data storage and Retrofit for network communication with the backend API.
6+
7+
## Summary
8+
9+
This application is a mobile application for the Intiva Platform. It includes the following features:
10+
11+
- Transaction management: Register and monitor all transactions, including expenses and incomes.
12+
- Categorization: Classify transactions into different categories for better organization and analysis.
13+
- Budget management: Set and track budgets for different categories of expenses and for different periods of time.
14+
- Savings management: Set and track savings goals, and monitor progress towards those goals.
15+
- Reminders and notifications: Set up reminders for upcoming bills, budget limits, and savings goals, and receive notifications to stay on track.
16+
- Family group management: Create and manage family groups to share expenses, budgets, and savings goals among family members.
17+
- Reporting and analytics: Generate reports and visualizations to analyze spending patterns, savings progress, and overall financial health.
18+
- User management: Manage user accounts, including registration, authentication, and authorization.
19+
20+
## Technologies Used
21+
22+
For the development of this API, the following technologies were used:
23+
24+
### Main Stack
25+
26+
- Kotlin: The programming language used for the development of the mobile application.
27+
- Jetpack Compose: A modern toolkit for building native Android UI, used to create the user interface of the mobile application.
28+
- Room: A persistence library for Android, used for local data storage in the mobile application.
29+
- Retrofit: A type-safe HTTP client for Android, used for network communication with the backend API.
30+
- Coroutines: A concurrency framework for Kotlin, used for asynchronous programming in the mobile application.
31+
- Dagger Hilt: A dependency injection framework for Android, used for managing dependencies in the mobile application.
32+
- Navigation Component: A framework for handling navigation in Android applications, used for managing navigation between different screens in the mobile application.
33+
- ViewModel: A component of the Android Architecture Components, used for managing UI-related data in a lifecycle-conscious way in the mobile application.
34+
35+
### Approaches and Patterns
36+
37+
- MVVC (Model-View-ViewModel): The application follows the MVVC architectural pattern, which separates the user interface (View) from the business logic (ViewModel) and the data (Model).
38+
- Clean Architecture: The application is structured following the principles of Clean Architecture, which promotes separation of concerns and makes the codebase more maintainable and testable.
39+
- Feature-based module organization: The codebase is organized into modules based on features, which helps to keep the codebase organized and makes it easier to navigate and maintain.
40+
41+
## Documentation
42+
43+
The project includes basic documentation and is available in the `docs` folder. It includes:
44+
45+
- C4 Model Software Architecture Diagrams: includes context, container and component level diagrams to provide an overview of the system architecture and its components.
46+
- Class Diagrams: includes class diagrams to illustrate the structure of the codebase and the relationships between classes.

app/build.gradle.kts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,21 @@ android {
3131
applicationId = "com.resolum.intiva"
3232
minSdk = 26
3333
targetSdk = 36
34-
versionCode = 1
35-
versionName = "1.0"
34+
versionCode = (System.getenv("VERSION_CODE") ?: "1").toInt()
35+
versionName = System.getenv("VERSION_NAME") ?: "1.0.0"
3636

3737
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
3838
}
3939

40+
signingConfigs {
41+
create("release") {
42+
storeFile = file(System.getenv("KEYSTORE_PATH") ?: "keystore.jks")
43+
storePassword = System.getenv("KEYSTORE_PASSWORD")
44+
keyAlias = System.getenv("KEY_ALIAS")
45+
keyPassword = System.getenv("KEY_PASSWORD")
46+
}
47+
}
48+
4049
buildTypes {
4150
debug {
4251
buildConfigField("String", "BASE_URL", "\"http://10.0.2.2:8080/api/v1/\"")
@@ -52,13 +61,15 @@ android {
5261

5362
matchingFallbacks += listOf("debug")
5463
}
64+
5565
release {
66+
signingConfig = signingConfigs.getByName("release")
5667
isMinifyEnabled = false
5768
proguardFiles(
5869
getDefaultProguardFile("proguard-android-optimize.txt"),
5970
"proguard-rules.pro"
6071
)
61-
buildConfigField("String", "BASE_URL", "\"https://stocksip-back-end.azurewebsites.net/api/v1/\"")
72+
buildConfigField("String", "BASE_URL", "\"https://intiva-api.azurewebsites.net/api/v1/\"")
6273

6374
firebaseAppDistribution {
6475
// Specifices the release notes file.
@@ -120,6 +131,7 @@ dependencies {
120131
testImplementation(libs.junit)
121132
testImplementation(libs.mockk)
122133
testImplementation(libs.kotlinx.coroutines.test)
134+
testImplementation(libs.mockwebserver.v4120)
123135
androidTestImplementation(platform(libs.androidx.compose.bom))
124136
androidTestImplementation(libs.androidx.compose.ui.test.junit4)
125137
androidTestImplementation(libs.androidx.espresso.core)

app/src/main/java/com/resolum/intiva/core/navigation/components/IntivaBottomNavBar.kt

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
// IntivaBottomNavBar.kt
22
package com.resolum.intiva.core.navigation.components
33

4+
import androidx.compose.foundation.BorderStroke
45
import androidx.compose.material.icons.Icons
56
import androidx.compose.material.icons.filled.Group
67
import androidx.compose.material.icons.filled.Home
78
import androidx.compose.material.icons.filled.Person
89
import androidx.compose.material.icons.filled.Receipt
910
import androidx.compose.material.icons.filled.TrackChanges
11+
import androidx.compose.material3.Surface
1012
import androidx.compose.material3.Icon
1113
import androidx.compose.material3.NavigationBar
1214
import androidx.compose.material3.NavigationBarItem
@@ -17,6 +19,7 @@ import androidx.compose.runtime.remember
1719
import androidx.compose.ui.Modifier
1820
import androidx.compose.ui.graphics.Color
1921
import androidx.compose.ui.text.style.TextOverflow
22+
import androidx.compose.ui.unit.dp
2023
import androidx.compose.ui.unit.sp
2124
import com.resolum.intiva.core.navigation.model.NavItem
2225
import com.resolum.intiva.core.navigation.routes.NavRoutes
@@ -43,7 +46,7 @@ fun IntivaBottomNavBar(
4346
NavItem(NavRoutes.HOME, "INICIO", Icons.Default.Home, "Home"),
4447
NavItem(
4548
NavRoutes.TRANSACTIONS,
46-
"TRANSACCIONES.",
49+
"TRANSACCIONES",
4750
Icons.Default.Receipt,
4851
"Transactions"
4952
),
@@ -62,32 +65,37 @@ fun IntivaBottomNavBar(
6265
indicatorColor = Color.White
6366
)
6467

65-
/** Render the bottom navigation bar with the defined items and colors. */
66-
NavigationBar(
67-
modifier = modifier,
68-
containerColor = Color.White,
69-
contentColor = IntivaColors.TextSecondary
68+
Surface(
69+
modifier = modifier,
70+
color = Color.White,
71+
border = BorderStroke(1.dp, Color(0xFFE8E8EF))
7072
) {
71-
navItems.forEach { item ->
72-
NavigationBarItem(
73-
icon = {
74-
Icon(
75-
imageVector = item.icon,
76-
contentDescription = item.contentDescription
77-
)
78-
},
79-
label = {
80-
Text(
81-
text = item.label,
82-
fontSize = 9.sp,
83-
maxLines = 1,
84-
overflow = TextOverflow.Clip
85-
)
86-
},
87-
selected = currentRoute == item.route,
88-
onClick = { onNavigate(item.route) },
89-
colors = itemColors
90-
)
73+
/** Render the bottom navigation bar with the defined items and colors. */
74+
NavigationBar(
75+
containerColor = Color.White,
76+
contentColor = IntivaColors.TextSecondary
77+
) {
78+
navItems.forEach { item ->
79+
NavigationBarItem(
80+
icon = {
81+
Icon(
82+
imageVector = item.icon,
83+
contentDescription = item.contentDescription
84+
)
85+
},
86+
label = {
87+
Text(
88+
text = item.label,
89+
fontSize = 8.sp,
90+
maxLines = 1,
91+
overflow = TextOverflow.Clip
92+
)
93+
},
94+
selected = currentRoute == item.route,
95+
onClick = { onNavigate(item.route) },
96+
colors = itemColors
97+
)
98+
}
9199
}
92100
}
93-
}
101+
}

0 commit comments

Comments
 (0)