diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/AndroidProjectSystem.xml b/.idea/AndroidProjectSystem.xml new file mode 100644 index 0000000..4a53bee --- /dev/null +++ b/.idea/AndroidProjectSystem.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..b86273d --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml new file mode 100644 index 0000000..b268ef3 --- /dev/null +++ b/.idea/deploymentTargetSelector.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..97f0a8e --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..7061a0d --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,61 @@ + + + + \ No newline at end of file diff --git a/.idea/migrations.xml b/.idea/migrations.xml new file mode 100644 index 0000000..f8051a6 --- /dev/null +++ b/.idea/migrations.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..74dd639 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..16660f1 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/approagency/drug/MainActivity.kt b/app/src/main/java/com/approagency/drug/MainActivity.kt index 13703a3..698bbd7 100644 --- a/app/src/main/java/com/approagency/drug/MainActivity.kt +++ b/app/src/main/java/com/approagency/drug/MainActivity.kt @@ -11,6 +11,7 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview +import com.approagency.drug.presentation.screens.HomeScreen import com.approagency.drug.ui.theme.DrugTheme class MainActivity : ComponentActivity() { @@ -20,28 +21,9 @@ class MainActivity : ComponentActivity() { setContent { DrugTheme { Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding -> - Greeting( - name = "Android", - modifier = Modifier.padding(innerPadding) - ) + HomeScreen(modifier = Modifier.padding(innerPadding)) } } } } } - -@Composable -fun Greeting(name: String, modifier: Modifier = Modifier) { - Text( - text = "Hello $name!", - modifier = modifier - ) -} - -@Preview(showBackground = true) -@Composable -fun GreetingPreview() { - DrugTheme { - Greeting("Android") - } -} \ No newline at end of file diff --git a/app/src/main/java/com/approagency/drug/di/AppModule.kt b/app/src/main/java/com/approagency/drug/di/AppModule.kt index 3ff2fe0..3c19394 100644 --- a/app/src/main/java/com/approagency/drug/di/AppModule.kt +++ b/app/src/main/java/com/approagency/drug/di/AppModule.kt @@ -1,9 +1,13 @@ package com.approagency.drug.di + +import android.app.Application import com.approagency.drug.data.repository.DrugRepositoryImpl import com.approagency.drug.domain.repository.DrugRepository import com.approagency.drug.domain.usecase.GetDrugSearchUseCase +import com.approagency.drug.presentation.viewModel.HomeViewModel import com.approagency.drug.utils.Config +import org.koin.core.module.dsl.viewModel import org.koin.dsl.module import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory @@ -29,5 +33,7 @@ val appModule= module { GetDrugSearchUseCase(get()) } - // + //view model + viewModel { (app: Application) -> + HomeViewModel(app, get())} } \ No newline at end of file diff --git a/app/src/main/java/com/approagency/drug/presentation/screens/HomeScreen.kt b/app/src/main/java/com/approagency/drug/presentation/screens/HomeScreen.kt index 5ec8967..4595bd0 100644 --- a/app/src/main/java/com/approagency/drug/presentation/screens/HomeScreen.kt +++ b/app/src/main/java/com/approagency/drug/presentation/screens/HomeScreen.kt @@ -2,10 +2,14 @@ package com.approagency.drug.presentation.screens import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import com.approagency.drug.presentation.viewModel.HomeViewModel +import org.koin.androidx.compose.koinViewModel @Composable fun HomeScreen( modifier: Modifier, - view -) \ No newline at end of file + viewModel: HomeViewModel = koinViewModel() +){ + +} \ No newline at end of file diff --git a/app/src/main/java/com/approagency/drug/presentation/viewModel/HomeViewModel.kt b/app/src/main/java/com/approagency/drug/presentation/viewModel/HomeViewModel.kt new file mode 100644 index 0000000..c89a6e3 --- /dev/null +++ b/app/src/main/java/com/approagency/drug/presentation/viewModel/HomeViewModel.kt @@ -0,0 +1,66 @@ +package com.approagency.drug.presentation.viewModel + +import android.net.http.HttpException +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.approagency.drug.data.dto.DrugListResponse +import com.approagency.drug.domain.model.DrugSearchParams +import com.approagency.drug.domain.usecase.GetDrugSearchUseCase +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asSharedFlow +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch + +class HomeViewModel ( + private val getDrugSearchUseCase: GetDrugSearchUseCase +): ViewModel() { + private val _uiState = MutableStateFlow(DrugSearchState()) + val uiState : StateFlow = _uiState + + + // Add SharedFlow for one-time events + private val _event = MutableSharedFlow() + val event = _event.asSharedFlow() + + fun searchDrugs(drugSearchParams: DrugSearchParams) { + _uiState.update { it.copy(isLoading = true) } + viewModelScope.launch { + try { + val result = getDrugSearchUseCase.invoke(drugSearchParams) + _uiState.update { it.copy( + isLoading = false, + drugsData = result + ) } + } catch (e: HttpException) { + handleError(e.message) + }catch (e: Exception) { + handleError(e.localizedMessage ?: "Unknown error") + } + } + } + + private suspend fun handleError(message: String?) { + _uiState.update { it.copy(isLoading = false) } + _event.emit(HomeEvent.ShowError(message ?: "Error occurred")) + } + + // Clear error when consumed + fun clearError() { + _uiState.update { it.copy(error = null) } + } +} + + +sealed class HomeEvent { + data class ShowError(val message: String) : HomeEvent() + data class NavigateToDetails(val drugId: String) : HomeEvent() +} + +data class DrugSearchState( + val isLoading: Boolean = false, + val drugsData: Result? = null, + val error:String? = null +) +