Skip to content

Commit 7797b19

Browse files
committed
docs: update README to reflect current project structure
2 parents 7b98ebf + e9b7f49 commit 7797b19

17 files changed

Lines changed: 537 additions & 223 deletions

File tree

README.md

Lines changed: 342 additions & 201 deletions
Large diffs are not rendered by default.

apps/android/ChamaApp/app/build.gradle.kts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ dependencies {
8181
implementation("com.squareup.retrofit2:retrofit:2.9.0")
8282
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
8383

84+
85+
// OkHttp
86+
implementation("com.squareup.okhttp3:okhttp:4.12.0")
87+
implementation("com.squareup.okhttp3:logging-interceptor:4.12.0")
8488
// Coroutines
8589
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
8690

apps/android/ChamaApp/app/src/main/java/com/example/chama/MainActivity.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@ import androidx.compose.runtime.Composable
1212
import androidx.compose.ui.Modifier
1313
import androidx.compose.ui.tooling.preview.Preview
1414
import com.example.chama.ui.theme.ChamaAppTheme
15-
15+
import com.example.chama.network.TokenManager
1616
class MainActivity : ComponentActivity() {
1717
override fun onCreate(savedInstanceState: Bundle?) {
1818
super.onCreate(savedInstanceState)
19+
TokenManager.init(this)
1920
enableEdgeToEdge()
2021
setContent {
2122
ChamaAppTheme {
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.example.chama.models
2+
3+
4+
data class BaseResponse<T>(
5+
val success: Boolean,
6+
val message: String,
7+
val data: T? = null,
8+
val error: String? = null
9+
)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.example.chama.models
2+
3+
data class GroupModel(
4+
val id: Long? = null,
5+
val name: String,
6+
val description: String,
7+
val creatorId: Long,
8+
val targetAmount: Double
9+
)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.example.chama.models
2+
3+
data class LoanModel(
4+
val id: Long? = null,
5+
val borrowerId: Long,
6+
val groupId: Long,
7+
val amount: Double,
8+
val durationInMonths: Int,
9+
val purpose: String
10+
)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.example.chama.models
2+
3+
data class UserModel(
4+
val id: Long? = null,
5+
val email: String,
6+
val firstName: String,
7+
val lastName: String,
8+
val phoneNumber: String
9+
)
Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,32 @@
11
package com.example.chama.network
22

3+
import com.example.chama.models.BaseResponse
4+
import com.example.chama.models.GroupModel
5+
import com.example.chama.models.LoanModel
6+
import com.example.chama.models.UserModel
37
import retrofit2.Response
4-
import retrofit2.http.GET
8+
import retrofit2.http.*
59

610
interface ApiService {
711

8-
@GET("users")
9-
suspend fun getUsers(): Response<List<String>>
12+
// User endpoints
13+
@POST("users")
14+
suspend fun createUser(@Body user: UserModel): Response<BaseResponse<UserModel>>
1015

11-
}
16+
@GET("users/{id}")
17+
suspend fun getUser(@Path("id") id: Long): Response<BaseResponse<UserModel>>
18+
19+
// Group endpoints
20+
@POST("groups")
21+
suspend fun createGroup(@Body group: GroupModel): Response<BaseResponse<GroupModel>>
22+
23+
@GET("groups")
24+
suspend fun getGroups(): Response<BaseResponse<List<GroupModel>>>
25+
26+
// Loan endpoints
27+
@POST("loans")
28+
suspend fun requestLoan(@Body loan: LoanModel): Response<BaseResponse<LoanModel>>
29+
30+
@GET("loans/{id}")
31+
suspend fun getLoan(@Path("id") id: Long): Response<BaseResponse<LoanModel>>
32+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.example.chama.network
2+
3+
import okhttp3.Interceptor
4+
import okhttp3.Response
5+
6+
class AuthInterceptor : Interceptor {
7+
8+
override fun intercept(chain: Interceptor.Chain): Response {
9+
val originalRequest = chain.request()
10+
11+
// Get token from SharedPreferences or TokenManager
12+
val token = TokenManager.getToken()
13+
14+
val newRequest = if (token != null) {
15+
originalRequest.newBuilder()
16+
.header("Authorization", "Bearer $token")
17+
.header("Content-Type", "application/json")
18+
.build()
19+
} else {
20+
originalRequest.newBuilder()
21+
.header("Content-Type", "application/json")
22+
.build()
23+
}
24+
25+
return chain.proceed(newRequest)
26+
}
27+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.example.chama.network
2+
3+
import retrofit2.Response
4+
5+
object ErrorHandler {
6+
7+
fun <T> handleResponse(response: Response<T>): Result<T> {
8+
return when {
9+
response.isSuccessful -> {
10+
response.body()?.let {
11+
Result.success(it)
12+
} ?: Result.failure(Exception("Empty response body"))
13+
}
14+
response.code() == 401 -> {
15+
TokenManager.clearToken()
16+
Result.failure(Exception("Unauthorized. Please login again."))
17+
}
18+
response.code() == 404 -> {
19+
Result.failure(Exception("Resource not found."))
20+
}
21+
response.code() == 500 -> {
22+
Result.failure(Exception("Server error. Please try again later."))
23+
}
24+
else -> {
25+
Result.failure(Exception("Error: ${response.code()} ${response.message()}"))
26+
}
27+
}
28+
}
29+
}

0 commit comments

Comments
 (0)