From 71afc1861494833651a32eea84efe0b9cd97515e Mon Sep 17 00:00:00 2001 From: PanMobile Date: Tue, 3 Feb 2026 20:46:44 +0300 Subject: [PATCH 01/24] =?UTF-8?q?ANDR-71:=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BD=D1=83=D0=B6=D0=BD=D1=8B?= =?UTF-8?q?=D1=85=20=D1=82=D0=B5=D0=BA=D1=81=D1=82=D0=BE=D0=B2=20=D0=B4?= =?UTF-8?q?=D0=BB=D1=8F=20entry-point'=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/ui/src/main/res/values/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/ui/src/main/res/values/strings.xml b/core/ui/src/main/res/values/strings.xml index 774e6c8b..1b7c1a34 100644 --- a/core/ui/src/main/res/values/strings.xml +++ b/core/ui/src/main/res/values/strings.xml @@ -24,4 +24,7 @@ УПС! Назад Не удалось загрузить данные + + Интервью тренажер + Улучшите свои знания перед собеседованием \ No newline at end of file From e692337f453c1f60e326d142f268410675943aed Mon Sep 17 00:00:00 2001 From: PanMobile Date: Tue, 3 Feb 2026 20:47:39 +0300 Subject: [PATCH 02/24] =?UTF-8?q?ANDR-71:=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=81=D1=83=D1=89=D0=BD=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D0=B8=20=D1=82=D1=80=D0=B5=D0=BD=D0=B0=D0=B6=D0=B5?= =?UTF-8?q?=D1=80=D0=B0=20=D0=B2=20=D0=B1=D0=B8=D0=B7=D0=BD=D0=B5=D1=81=20?= =?UTF-8?q?=D0=BB=D0=BE=D0=B3=D0=B8=D0=BA=D0=B5=20=D0=B3=D0=BB=D0=B0=D0=B2?= =?UTF-8?q?=D0=BD=D0=BE=D0=B3=D0=BE=20=D1=8D=D0=BA=D1=80=D0=B0=D0=BD=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/presentation/intents/QuestionMainScreenCommand.kt | 1 + .../impl/presentation/mapper/QuestionMainScreenMapper.kt | 7 +++++++ .../impl/presentation/model/QuestionMainItemType.kt | 1 + 3 files changed, 9 insertions(+) diff --git a/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/presentation/intents/QuestionMainScreenCommand.kt b/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/presentation/intents/QuestionMainScreenCommand.kt index 99d2037e..5b55dd91 100644 --- a/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/presentation/intents/QuestionMainScreenCommand.kt +++ b/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/presentation/intents/QuestionMainScreenCommand.kt @@ -3,4 +3,5 @@ package ru.yeahub.example_home.impl.presentation.intents sealed class QuestionMainScreenCommand { object NavigateToBaseQuestions : QuestionMainScreenCommand() object NavigateToCollections : QuestionMainScreenCommand() + object NavigateToInterviewTrainer : QuestionMainScreenCommand() } \ No newline at end of file diff --git a/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/presentation/mapper/QuestionMainScreenMapper.kt b/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/presentation/mapper/QuestionMainScreenMapper.kt index f8b1470f..e4db2d99 100644 --- a/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/presentation/mapper/QuestionMainScreenMapper.kt +++ b/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/presentation/mapper/QuestionMainScreenMapper.kt @@ -14,6 +14,13 @@ class QuestionMainScreenMapper { description = TextOrResource.Resource(R.string.base_questions_description), imageRes = R.drawable.icon_base_question ), + //imageRes тренажера потом изменить на нормальный + QuestionMainUiModel( + type = QuestionMainItemType.InterviewTrainer, + title = TextOrResource.Resource(R.string.interview_trainer_title), + description = TextOrResource.Resource(R.string.interview_trainer_description), + imageRes = R.drawable.question_square + ), QuestionMainUiModel( type = QuestionMainItemType.Collections, title = TextOrResource.Resource(R.string.collections_title), diff --git a/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/presentation/model/QuestionMainItemType.kt b/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/presentation/model/QuestionMainItemType.kt index dbb2aa25..4c6e20c9 100644 --- a/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/presentation/model/QuestionMainItemType.kt +++ b/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/presentation/model/QuestionMainItemType.kt @@ -3,4 +3,5 @@ package ru.yeahub.example_home.impl.presentation.model sealed class QuestionMainItemType { object BaseQuestions : QuestionMainItemType() object Collections : QuestionMainItemType() + object InterviewTrainer : QuestionMainItemType() } From a713b92611ca67c0f75ef9c3d7c6b22de6f5574f Mon Sep 17 00:00:00 2001 From: PanMobile Date: Tue, 3 Feb 2026 20:48:34 +0300 Subject: [PATCH 03/24] =?UTF-8?q?ANDR-71:=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B1?= =?UTF-8?q?=D0=BE=D1=82=D0=BA=D0=B8=20=D0=BA=D0=BE=D0=BC=D0=B0=D0=BD=D0=B4?= =?UTF-8?q?=D1=8B=20=D0=BF=D0=BE=20=D1=82=D1=80=D0=B5=D0=BD=D0=B0=D0=B6?= =?UTF-8?q?=D0=B5=D1=80=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/presentation/viewmodel/QuestionMainViewModel.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/presentation/viewmodel/QuestionMainViewModel.kt b/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/presentation/viewmodel/QuestionMainViewModel.kt index 2b261a43..ba3b7c6a 100644 --- a/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/presentation/viewmodel/QuestionMainViewModel.kt +++ b/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/presentation/viewmodel/QuestionMainViewModel.kt @@ -45,6 +45,10 @@ class QuestionMainViewModel( ) QuestionMainItemType.Collections -> _command.emit(QuestionMainScreenCommand.NavigateToCollections) + + QuestionMainItemType.InterviewTrainer -> { + _command.emit(QuestionMainScreenCommand.NavigateToInterviewTrainer) + } } } } From b42e8a9a493b9119c0dbc5674348542aaec49738 Mon Sep 17 00:00:00 2001 From: PanMobile Date: Tue, 3 Feb 2026 20:49:47 +0300 Subject: [PATCH 04/24] =?UTF-8?q?ANDR-71:=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B0=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8?= =?UTF-8?q?=D1=8F=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA=D0=B8?= =?UTF-8?q?=20=D0=BD=D0=B0=D0=B2=D0=B8=D0=B3=D0=B0=D1=86=D0=B8=D0=B8=20?= =?UTF-8?q?=D0=BA=20=D1=82=D1=80=D0=B5=D0=BD=D0=B0=D0=B6=D0=B5=D1=80=D1=83?= =?UTF-8?q?=20=D0=B8=20=D0=BF=D0=B5=D1=80=D0=B5=D0=B4=D0=B0=D0=B5=D1=82?= =?UTF-8?q?=D1=81=D1=8F=20=D0=B2=20=D0=BF=D0=B0=D1=80=D0=B0=D0=BC=D0=B5?= =?UTF-8?q?=D1=82=D1=80=20=D0=B3=D0=BB=D0=B0=D0=B2=D0=BD=D0=BE=D0=B3=D0=BE?= =?UTF-8?q?=20=D1=8D=D0=BA=D1=80=D0=B0=D0=BD=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/QuestionMainFeatureImpl.kt | 32 +++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/QuestionMainFeatureImpl.kt b/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/QuestionMainFeatureImpl.kt index 2bc10887..836b24a5 100644 --- a/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/QuestionMainFeatureImpl.kt +++ b/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/QuestionMainFeatureImpl.kt @@ -28,7 +28,7 @@ class QuestionMainFeatureImpl : FeatureApi { navGraphBuilder: NavGraphBuilder, navController: NavHostController, pathManager: NavigationPathManager, - modifier: Modifier + modifier: Modifier, ) { val currentPath = pathManager.getCurrentPath() Timber.d("HomeFeatureImpl registerGraph: currentPath: $currentPath") @@ -50,6 +50,9 @@ class QuestionMainFeatureImpl : FeatureApi { }, onNavigateToCollections = { handleCollectionsNavigation(pathManager, navController) + }, + onNavigateToInterviewTrainer = { + handleInterviewTrainerNavigation(pathManager, navController) } ) } @@ -60,7 +63,7 @@ class QuestionMainFeatureImpl : FeatureApi { */ private fun handleQuestionsNavigation( pathManager: NavigationPathManager, - navController: NavHostController + navController: NavHostController, ) { // Сбрасываем текущий путь на корневую фичу pathManager.setCurrentPath(FeatureRoute.QuestionsFeature.FEATURE_NAME) @@ -83,7 +86,7 @@ class QuestionMainFeatureImpl : FeatureApi { */ private fun handleCollectionsNavigation( pathManager: NavigationPathManager, - navController: NavHostController + navController: NavHostController, ) { // Сбрасываем текущий путь на корневую фичу pathManager.setCurrentPath(FeatureRoute.CollectionsFeature.FEATURE_NAME) @@ -100,4 +103,27 @@ class QuestionMainFeatureImpl : FeatureApi { restoreState = true } } + + /** + * Обработка навигации к интервью тренажеру. + */ + private fun handleInterviewTrainerNavigation( + pathManager: NavigationPathManager, + navController: NavHostController, + ) { + // Сбрасываем текущий путь на корневую фичу + pathManager.setCurrentPath(FeatureRoute.InterviewTrainerFeature.FEATURE_NAME) + + val interviewTrainerPath = pathManager.getCurrentPath() + + Timber.d("HomeFeatureImpl handleInterviewTrainerNavigation: Navigating to: $interviewTrainerPath") + + navController.navigate(interviewTrainerPath) { + popUpTo(navController.graph.startDestinationId) { + saveState = true + } + launchSingleTop = true + restoreState = true + } + } } From 564d0599d60845bb846e4640723942c68cd423b2 Mon Sep 17 00:00:00 2001 From: PanMobile Date: Tue, 3 Feb 2026 20:52:08 +0300 Subject: [PATCH 05/24] =?UTF-8?q?ANDR-71:=20=D0=A2=D0=B5=D1=81=D1=82=20?= =?UTF-8?q?=D0=9F=D1=80=D0=B5=D0=B2=D1=8C=D1=8E=20=D1=81=20=D0=BA=D0=BD?= =?UTF-8?q?=D0=BE=D0=BF=D0=BA=D0=BE=D0=B9=20=D1=82=D1=80=D0=B5=D0=BD=D0=B0?= =?UTF-8?q?=D0=B6=D0=B5=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/presentation/view/QuestionsMainScreen.kt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/presentation/view/QuestionsMainScreen.kt b/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/presentation/view/QuestionsMainScreen.kt index f433bac6..1be835b3 100644 --- a/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/presentation/view/QuestionsMainScreen.kt +++ b/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/presentation/view/QuestionsMainScreen.kt @@ -60,7 +60,7 @@ fun QuestionsMainScreen( fun QuestionsMainScreenContent( state: QuestionMainScreenState, onItemClick: (QuestionMainUiModel) -> Unit, - onBackClick: () -> Unit + onBackClick: () -> Unit, ) { val context = LocalContext.current val scrollState = rememberScrollState() @@ -193,6 +193,13 @@ val stateWithContent = QuestionMainScreenState.Content( description = TextOrResource.Resource(R.string.base_questions_description), imageRes = R.drawable.icon_base_question ), + //imageRes тренажера потом изменить на нормальный + QuestionMainUiModel( + type = QuestionMainItemType.InterviewTrainer, + title = TextOrResource.Resource(R.string.interview_trainer_title), + description = TextOrResource.Resource(R.string.interview_trainer_description), + imageRes = R.drawable.question_square + ), QuestionMainUiModel( type = QuestionMainItemType.Collections, title = TextOrResource.Resource(R.string.collections_title), From 16950a57ba3892a9b6cff615380758c661be2219 Mon Sep 17 00:00:00 2001 From: PanMobile Date: Tue, 3 Feb 2026 20:52:39 +0300 Subject: [PATCH 06/24] =?UTF-8?q?ANDR-71:=20=D0=98=D1=81=D0=BF=D0=BE=D0=BB?= =?UTF-8?q?=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=BB=D1=8F?= =?UTF-8?q?=D0=BC=D0=B1=D0=B4=D1=8B=20=D0=BD=D0=B0=D0=B2=D0=B8=D0=B3=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D0=B8=20=D0=B4=D0=BB=D1=8F=20=D0=BE=D1=82=D0=BF?= =?UTF-8?q?=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20=D0=BA=D0=BE=D0=BC=D0=BC=D0=B0?= =?UTF-8?q?=D0=BD=D0=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/presentation/view/QuestionsMainScreen.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/presentation/view/QuestionsMainScreen.kt b/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/presentation/view/QuestionsMainScreen.kt index 1be835b3..fb816572 100644 --- a/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/presentation/view/QuestionsMainScreen.kt +++ b/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/presentation/view/QuestionsMainScreen.kt @@ -37,7 +37,8 @@ import ru.yeahub.ui.R fun QuestionsMainScreen( onBackClick: () -> Unit, onNavigateToBaseQuestions: () -> Unit, - onNavigateToCollections: () -> Unit + onNavigateToCollections: () -> Unit, + onNavigateToInterviewTrainer: () -> Unit, ) { val viewModel: QuestionMainViewModel = koinViewModel() val state by viewModel.state.collectAsStateWithLifecycle() @@ -46,6 +47,7 @@ fun QuestionsMainScreen( when (command) { is QuestionMainScreenCommand.NavigateToBaseQuestions -> onNavigateToBaseQuestions() is QuestionMainScreenCommand.NavigateToCollections -> onNavigateToCollections() + is QuestionMainScreenCommand.NavigateToInterviewTrainer -> onNavigateToInterviewTrainer() } } From 13011a5ea9d4745bccf4b8ed2379bd4664ce5208 Mon Sep 17 00:00:00 2001 From: PanMobile Date: Tue, 3 Feb 2026 22:32:58 +0300 Subject: [PATCH 07/24] =?UTF-8?q?ANDR-71:=20=D0=98=D0=B7=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=20=D0=B2=D0=BD=D0=B5=D1=88=D0=BD=D1=8F=D1=8F?= =?UTF-8?q?=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D1=8F=20=D0=BD=D0=B0?= =?UTF-8?q?=D0=B2=D0=B8=D0=B3=D0=B0=D1=86=D0=B8=D0=B8-=D0=B2=D1=85=D0=BE?= =?UTF-8?q?=D0=B4=D0=B0=20=D0=B2=20=D1=84=D0=B8=D1=87=D1=83=20=D1=82=D1=80?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=D0=B6=D0=B5=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yeahub/interview_trainer/api/InterviewTrainerApi.kt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/feature/interview-trainer/api/src/main/java/ru/yeahub/interview_trainer/api/InterviewTrainerApi.kt b/feature/interview-trainer/api/src/main/java/ru/yeahub/interview_trainer/api/InterviewTrainerApi.kt index b98d29ed..0a7c0364 100644 --- a/feature/interview-trainer/api/src/main/java/ru/yeahub/interview_trainer/api/InterviewTrainerApi.kt +++ b/feature/interview-trainer/api/src/main/java/ru/yeahub/interview_trainer/api/InterviewTrainerApi.kt @@ -10,12 +10,16 @@ import androidx.compose.runtime.Composable */ interface InterviewTrainerApi { /** - * Экран тренажера собеседований. + * Главный/первый экран тренажера собеседований (CreateQuizScreen). + * Является entry-point'ом в фичу + * С него начинается вся внутренняя навигация * * @param onBackClick Действие при нажатии кнопки "Назад" + * @param onStartTrainingClick Действие при нажатии на старт тренировки в тренажере */ @Composable - fun InterviewTrainerScreen( + fun CreateQuizScreen( onBackClick: () -> Unit, + onStartTrainingClick: (specializationId: String, questionsCount: String) -> Unit, ) } \ No newline at end of file From 36b62216b5d985382b64b340341febd692880455 Mon Sep 17 00:00:00 2001 From: PanMobile Date: Tue, 3 Feb 2026 22:34:08 +0300 Subject: [PATCH 08/24] =?UTF-8?q?ANDR-71:=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B0=20=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D1=8F=20InterviewTrainerFeatureImpl.=20?= =?UTF-8?q?=D0=92=D0=BD=D1=83=D1=82=D1=80=D0=B8=20=D1=80=D0=B5=D0=B3=D0=B8?= =?UTF-8?q?=D1=81=D1=82=D1=80=D0=B0=D1=86=D0=B8=D1=8F=20=D0=B3=D1=80=D0=B0?= =?UTF-8?q?=D1=84=D0=B0,=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=BD=D0=B0=D0=B2=D0=B8=D0=B3=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D0=B8=20=D0=BD=D0=B0=D0=B7=D0=B0=D0=B4=20=D0=B8=20=D0=BE=D0=B1?= =?UTF-8?q?=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA=D0=B0=20=D0=BD=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=B3=D0=B0=D1=86=D0=B8=D0=B8=20=D0=BA=20=D1=8D=D0=BA?= =?UTF-8?q?=D1=80=D0=B0=D0=BD=D1=83=20=D1=82=D1=80=D0=B5=D0=BD=D0=B8=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/InterviewTrainerFeatureImpl.kt | 80 ++++++++++++++++++- 1 file changed, 78 insertions(+), 2 deletions(-) diff --git a/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/InterviewTrainerFeatureImpl.kt b/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/InterviewTrainerFeatureImpl.kt index 1c9a29f4..9a4be470 100644 --- a/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/InterviewTrainerFeatureImpl.kt +++ b/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/InterviewTrainerFeatureImpl.kt @@ -3,11 +3,14 @@ package ru.yeahub.interview_trainer.impl import androidx.compose.ui.Modifier import androidx.navigation.NavGraphBuilder import androidx.navigation.NavHostController +import androidx.navigation.compose.composable +import ru.yeahub.interview_trainer.api.InterviewTrainerApi import ru.yeahub.navigation_api.FeatureApi import ru.yeahub.navigation_api.FeatureRoute import ru.yeahub.navigation_api.NavigationPathManager +import timber.log.Timber -class InterviewTrainerFeatureImpl : FeatureApi { +class InterviewTrainerFeatureImpl(private val trainerApi: InterviewTrainerApi) : FeatureApi { override fun getFeatureName(): String = FeatureRoute.InterviewTrainerFeature.FEATURE_NAME override fun registerGraph( @@ -16,6 +19,79 @@ class InterviewTrainerFeatureImpl : FeatureApi { pathManager: NavigationPathManager, modifier: Modifier, ) { - TODO("Not yet implemented") + val currentPath = pathManager.getCurrentPath() + Timber.d("InterviewTrainerFeatureImpl registerGraph: currentPath: $currentPath") + + val createQuizRoute = if (currentPath.isEmpty()) { + getFeatureName() + } else { + pathManager.createChildPath(getFeatureName()) + } + Timber.d("InterviewTrainerFeatureImpl registerGraph: Registering route: $createQuizRoute") + + navGraphBuilder.composable(createQuizRoute) { + trainerApi.CreateQuizScreen( + onBackClick = { handleBackNavigation(pathManager, navController) }, + + onStartTrainingClick = { specializationId, questionsCount -> + handleQuizNavigation( + pathManager, + navController, + specializationId, + questionsCount + ) + } + ) + } + } + + /** + * Обработка навигации назад. + */ + private fun handleBackNavigation( + pathManager: NavigationPathManager, + navController: NavHostController, + ) { + val parentPath = pathManager.getCurrentPath() + Timber.d("InterviewTrainerFeatureImpl handleBackNavigation: Navigating to parent: $parentPath") + + pathManager.setCurrentPath(parentPath) + + if (parentPath.isEmpty()) { + navController.navigateUp() + } else { + navController.navigate(parentPath) { + popUpTo(parentPath) { + inclusive = true + } + } + } + } + + /** + * Обработка навигации к экрану тренировки (InterviewQuizScreen). + */ + private fun handleQuizNavigation( + pathManager: NavigationPathManager, + navController: NavHostController, + specializationId: String, + questionsCount: String, + ) { + pathManager.setCurrentPath(getFeatureName()) + + // Используем текущий путь как базу для экрана тренировки + val quizPath = pathManager.createParametrizedPath( + featureName = "quiz", + "specializationId", "questionCount" + ) + + val concretePath = pathManager.createConcretePath( + parametrizedPath = quizPath, + specializationId, questionsCount + ) + Timber.d("InterviewTrainerFeatureImpl handleQuizNavigation: Navigating to: $concretePath") + + pathManager.setCurrentPath(concretePath) + navController.navigate(concretePath) } } \ No newline at end of file From ac244ecbc654fdb2089a5e8b637163b2a3a46037 Mon Sep 17 00:00:00 2001 From: PanMobile Date: Tue, 3 Feb 2026 23:06:42 +0300 Subject: [PATCH 09/24] =?UTF-8?q?ANDR-71:=20=D0=BF=D1=80=D0=B0=D0=B2=D0=BA?= =?UTF-8?q?=D0=B8=20=D0=BF=D0=BE=20ktlint'=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/InterviewTrainerFeatureImpl.kt | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/InterviewTrainerFeatureImpl.kt b/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/InterviewTrainerFeatureImpl.kt index 9a4be470..88487fb4 100644 --- a/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/InterviewTrainerFeatureImpl.kt +++ b/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/InterviewTrainerFeatureImpl.kt @@ -31,8 +31,9 @@ class InterviewTrainerFeatureImpl(private val trainerApi: InterviewTrainerApi) : navGraphBuilder.composable(createQuizRoute) { trainerApi.CreateQuizScreen( - onBackClick = { handleBackNavigation(pathManager, navController) }, - + onBackClick = { + handleBackNavigation(pathManager, navController) + }, onStartTrainingClick = { specializationId, questionsCount -> handleQuizNavigation( pathManager, @@ -82,12 +83,14 @@ class InterviewTrainerFeatureImpl(private val trainerApi: InterviewTrainerApi) : // Используем текущий путь как базу для экрана тренировки val quizPath = pathManager.createParametrizedPath( featureName = "quiz", - "specializationId", "questionCount" + "specializationId", + "questionCount" ) val concretePath = pathManager.createConcretePath( parametrizedPath = quizPath, - specializationId, questionsCount + specializationId, + questionsCount ) Timber.d("InterviewTrainerFeatureImpl handleQuizNavigation: Navigating to: $concretePath") From 0d696d12556eb0648d4c914cea89466a64402be7 Mon Sep 17 00:00:00 2001 From: PanMobile Date: Thu, 5 Feb 2026 17:55:21 +0300 Subject: [PATCH 10/24] =?UTF-8?q?ANDR-71:=20ScreenMapper=20=D1=82=D0=B5?= =?UTF-8?q?=D0=BF=D0=B5=D1=80=D1=8C=20=D0=BA=D0=BB=D0=B0=D1=81=D1=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/createQuiz/presentation/CreateQuizScreenMapper.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/presentation/CreateQuizScreenMapper.kt b/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/presentation/CreateQuizScreenMapper.kt index 1abd7353..1a17edd5 100644 --- a/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/presentation/CreateQuizScreenMapper.kt +++ b/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/presentation/CreateQuizScreenMapper.kt @@ -2,7 +2,7 @@ package ru.yeahub.interview_trainer.impl.createQuiz.presentation import ru.yeahub.interview_trainer.impl.createQuiz.domain.DomainSpecialization -object CreateQuizScreenMapper { +class CreateQuizScreenMapper() { fun getScreenState( specializations: List, From 8d35990ebcab90005c37a052a8b19b49c7dcbdcc Mon Sep 17 00:00:00 2001 From: PanMobile Date: Thu, 5 Feb 2026 20:33:11 +0300 Subject: [PATCH 11/24] =?UTF-8?q?ANDR-71:=20=D0=9A=D0=BE=D0=BD=D1=81=D1=82?= =?UTF-8?q?=D0=B0=D0=BD=D1=82=D1=8B=20=D0=BD=D0=B0=D0=B7=D0=B2=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D0=B9=20=D1=8D=D0=BA=D1=80=D0=B0=D0=BD=D0=BE=D0=B2=20?= =?UTF-8?q?=D0=B8=D0=BD=D1=82=D0=B5=D1=80=D0=B2=D1=8C=D1=8E-=D1=82=D1=80?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=D0=B6=D0=B5=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/ru/yeahub/navigation_api/FeatureRoute.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/navigation-api/src/main/java/ru/yeahub/navigation_api/FeatureRoute.kt b/core/navigation-api/src/main/java/ru/yeahub/navigation_api/FeatureRoute.kt index bccd38fb..4d23aba2 100644 --- a/core/navigation-api/src/main/java/ru/yeahub/navigation_api/FeatureRoute.kt +++ b/core/navigation-api/src/main/java/ru/yeahub/navigation_api/FeatureRoute.kt @@ -65,5 +65,9 @@ object FeatureRoute { object InterviewTrainerFeature { const val FEATURE_NAME = "interview_trainer" + + const val CREATE_QUIZ_SCREEN_NAME = "create_quiz" + const val INTERVIEW_QUIZ_SCREEN_NAME = "interview_quiz" + const val INTERVIEW_QUIZ_RESULT_SCREEN_NAME = "interview_quiz_result" } } \ No newline at end of file From a62b5f7ed782b114a9adfda02558c6cc0d7206f7 Mon Sep 17 00:00:00 2001 From: PanMobile Date: Thu, 5 Feb 2026 21:07:39 +0300 Subject: [PATCH 12/24] =?UTF-8?q?ANDR-71:=20=D0=A0=D0=B5=D0=B2=D0=BE=D1=80?= =?UTF-8?q?=D0=BA=20=D0=BD=D0=B0=D0=B2=D0=B8=D0=B3=D0=B0=D1=86=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/InterviewTrainerFeatureImpl.kt | 83 ++++++++++--------- 1 file changed, 45 insertions(+), 38 deletions(-) diff --git a/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/InterviewTrainerFeatureImpl.kt b/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/InterviewTrainerFeatureImpl.kt index 88487fb4..71a09bea 100644 --- a/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/InterviewTrainerFeatureImpl.kt +++ b/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/InterviewTrainerFeatureImpl.kt @@ -3,14 +3,19 @@ package ru.yeahub.interview_trainer.impl import androidx.compose.ui.Modifier import androidx.navigation.NavGraphBuilder import androidx.navigation.NavHostController +import androidx.navigation.NavType import androidx.navigation.compose.composable -import ru.yeahub.interview_trainer.api.InterviewTrainerApi +import androidx.navigation.navArgument +import ru.yeahub.interview_trainer.impl.createQuiz.presentation.CreateQuizResult +import ru.yeahub.interview_trainer.impl.createQuiz.ui.CreateQuizScreen import ru.yeahub.navigation_api.FeatureApi import ru.yeahub.navigation_api.FeatureRoute import ru.yeahub.navigation_api.NavigationPathManager import timber.log.Timber -class InterviewTrainerFeatureImpl(private val trainerApi: InterviewTrainerApi) : FeatureApi { +private const val TITLE_TOP_APP_BAR = "title" + +class InterviewTrainerFeatureImpl() : FeatureApi { override fun getFeatureName(): String = FeatureRoute.InterviewTrainerFeature.FEATURE_NAME override fun registerGraph( @@ -19,29 +24,41 @@ class InterviewTrainerFeatureImpl(private val trainerApi: InterviewTrainerApi) : pathManager: NavigationPathManager, modifier: Modifier, ) { - val currentPath = pathManager.getCurrentPath() - Timber.d("InterviewTrainerFeatureImpl registerGraph: currentPath: $currentPath") + val basePathWithParams = pathManager.createParametrizedPath( + featureName = getFeatureName() + "/" + + FeatureRoute.InterviewTrainerFeature.CREATE_QUIZ_SCREEN_NAME, + TITLE_TOP_APP_BAR + ) + Timber.d("InterviewTrainerFeatureImpl registerGraph: currentPath: $basePathWithParams") - val createQuizRoute = if (currentPath.isEmpty()) { - getFeatureName() - } else { - pathManager.createChildPath(getFeatureName()) - } - Timber.d("InterviewTrainerFeatureImpl registerGraph: Registering route: $createQuizRoute") + navGraphBuilder.composable( + route = basePathWithParams, + arguments = listOf( + navArgument(TITLE_TOP_APP_BAR) { + type = NavType.StringType + } + ) + ) { backStackEntry -> + val titleTopAppBar = backStackEntry.arguments?.getString(TITLE_TOP_APP_BAR) ?: "" - navGraphBuilder.composable(createQuizRoute) { - trainerApi.CreateQuizScreen( - onBackClick = { - handleBackNavigation(pathManager, navController) + CreateQuizScreen( + onResult = { result -> + when (result) { + is CreateQuizResult.NavigateBack -> handleBackNavigation( + pathManager, + navController + ) + + is CreateQuizResult.NavigateToInterviewQuizScreen -> handleQuizNavigation( + pathManager = pathManager, + navController = navController, + titleTopAppBar = titleTopAppBar, + specializationId = result.specializationId.toString(), + questionsCount = result.questionCount.toString() + ) + } }, - onStartTrainingClick = { specializationId, questionsCount -> - handleQuizNavigation( - pathManager, - navController, - specializationId, - questionsCount - ) - } + titleTopAppBar = titleTopAppBar ) } } @@ -75,26 +92,16 @@ class InterviewTrainerFeatureImpl(private val trainerApi: InterviewTrainerApi) : private fun handleQuizNavigation( pathManager: NavigationPathManager, navController: NavHostController, + titleTopAppBar: String, specializationId: String, questionsCount: String, ) { - pathManager.setCurrentPath(getFeatureName()) + val interviewQuizRoute = getFeatureName() + "/" + + FeatureRoute.InterviewTrainerFeature.INTERVIEW_QUIZ_SCREEN_NAME + "/" + + titleTopAppBar + specializationId + questionsCount - // Используем текущий путь как базу для экрана тренировки - val quizPath = pathManager.createParametrizedPath( - featureName = "quiz", - "specializationId", - "questionCount" - ) - - val concretePath = pathManager.createConcretePath( - parametrizedPath = quizPath, - specializationId, - questionsCount - ) - Timber.d("InterviewTrainerFeatureImpl handleQuizNavigation: Navigating to: $concretePath") + Timber.d("InterviewTrainerFeatureImpl registerGraph: $interviewQuizRoute") - pathManager.setCurrentPath(concretePath) - navController.navigate(concretePath) + navController.navigate(interviewQuizRoute) } } \ No newline at end of file From 8cfd05308d6f6ca3cf3e265b0a7bb66713448e1f Mon Sep 17 00:00:00 2001 From: PanMobile Date: Thu, 5 Feb 2026 21:08:02 +0300 Subject: [PATCH 13/24] =?UTF-8?q?ANDR-71:=20=D0=A3=D0=BB=D1=83=D1=87=D1=88?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=8D=D0=BA=D1=80=D0=B0=D0=BD=D0=B0?= =?UTF-8?q?.=20=D0=9F=D0=BE=D0=B4=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=B2=D1=8C=D1=8E=D0=BC=D0=BE=D0=B4=D0=B5=D0=BB?= =?UTF-8?q?=D0=B8=20=D0=B8=20=D0=BA=D0=BE=D0=BC=D0=B0=D0=BD=D0=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/createQuiz/ui/CreateQuizScreen.kt | 34 ++++++++++++++++--- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/ui/CreateQuizScreen.kt b/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/ui/CreateQuizScreen.kt index 8ef23837..3a96cf08 100644 --- a/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/ui/CreateQuizScreen.kt +++ b/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/ui/CreateQuizScreen.kt @@ -36,9 +36,11 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.unit.dp import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.viewmodel.compose.viewModel import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow +import org.koin.androidx.compose.koinViewModel import ru.yeahub.core_ui.component.ErrorScreen import ru.yeahub.core_ui.component.PrimaryButton import ru.yeahub.core_ui.component.SkillButton @@ -65,17 +67,39 @@ private val FIGMA_HORIZONTAL_PADDING = 16.dp private val FIGMA_VERTICAL_BLOCKS_PADDING = 16.dp private val FIGMA_VERTICAL_FIRST_AND_LAST_ELEMENT_PADDING = 24.dp +@Composable +fun CreateQuizScreen( + onResult: (CreateQuizResult) -> Unit, + titleTopAppBar: String, +) { + val viewModel: CreateQuizViewModel = koinViewModel() + + val screenState by viewModel.screenState.collectAsStateWithLifecycle() + + HandleCommand( + commandFlow = viewModel.commands, + onResult = { result -> onResult(result) } + ) + + ScreenUI( + state = screenState, + onEvent = viewModel::onEvent, + titleTopAppBar = TextOrResource.Text(titleTopAppBar) + ) +} + + @Composable private fun ScreenUI( state: CreateQuizState, onEvent: (CreateQuizEvent) -> Unit, - headerText: TextOrResource, + titleTopAppBar: TextOrResource, ) { Scaffold( containerColor = colors.black10, topBar = { TopAppBarWithBottomBorder( - title = headerText, + title = titleTopAppBar, onBackClick = { onEvent(CreateQuizEvent.OnBackClick) } ) } @@ -409,7 +433,7 @@ fun CreateQuizScreenPreview( ScreenUI( state = state, onEvent = { }, - headerText = TextOrResource.Resource(R.string.create_quiz_top_bar_header_text), + titleTopAppBar = TextOrResource.Resource(R.string.create_quiz_top_bar_header_text), ) } @@ -433,7 +457,7 @@ fun DynamicPreviewUI() { } val mockViewModel = viewModelCreator { - CreateQuizViewModel(mockUseCase, CreateQuizScreenMapper) + CreateQuizViewModel(mockUseCase, CreateQuizScreenMapper()) } val mockState by mockViewModel.screenState.collectAsState() @@ -458,7 +482,7 @@ fun DynamicPreviewUI() { ScreenUI( state = mockState, onEvent = mockViewModel::onEvent, - headerText = TextOrResource.Resource(R.string.create_quiz_top_bar_header_text) + titleTopAppBar = TextOrResource.Resource(R.string.create_quiz_top_bar_header_text) ) } } From 50271e4a6adc760697517b7516613aa4320bcda4 Mon Sep 17 00:00:00 2001 From: PanMobile Date: Thu, 5 Feb 2026 21:26:20 +0300 Subject: [PATCH 14/24] =?UTF-8?q?ANDR-71:=20=D0=92=D1=82=D0=BE=D1=80=D0=B8?= =?UTF-8?q?=D1=87=D0=BD=D1=8B=D0=B5=20=D0=9C=D0=BE=D0=B4=D1=83=D0=BB=D0=B8?= =?UTF-8?q?=20DI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../createQuiz/di/CreateQuizRepositoryModule.kt | 14 ++++++++++++++ .../impl/createQuiz/di/CreateQuizUseCaseModule.kt | 8 ++++++++ .../createQuiz/di/CreateQuizViewModelModule.kt | 14 ++++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/di/CreateQuizRepositoryModule.kt create mode 100644 feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/di/CreateQuizUseCaseModule.kt create mode 100644 feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/di/CreateQuizViewModelModule.kt diff --git a/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/di/CreateQuizRepositoryModule.kt b/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/di/CreateQuizRepositoryModule.kt new file mode 100644 index 00000000..6ee18e69 --- /dev/null +++ b/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/di/CreateQuizRepositoryModule.kt @@ -0,0 +1,14 @@ +package ru.yeahub.interview_trainer.impl.createQuiz.di + +import org.koin.dsl.module +import ru.yeahub.interview_trainer.impl.createQuiz.data.CreateQuizRepositoryImpl +import ru.yeahub.interview_trainer.impl.createQuiz.domain.CreateQuizRepositoryApi + +val createQuizRepositoryModule = module { + single { + CreateQuizRepositoryImpl( + apiService = get(), + mapper = get() + ) + } +} \ No newline at end of file diff --git a/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/di/CreateQuizUseCaseModule.kt b/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/di/CreateQuizUseCaseModule.kt new file mode 100644 index 00000000..5593887e --- /dev/null +++ b/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/di/CreateQuizUseCaseModule.kt @@ -0,0 +1,8 @@ +package ru.yeahub.interview_trainer.impl.createQuiz.di + +import org.koin.dsl.module +import ru.yeahub.interview_trainer.impl.createQuiz.domain.GetSpecializationsListUseCaseImpl + +val createQuizUseCaseModule = module { + factory { GetSpecializationsListUseCaseImpl(repository = get()) } +} \ No newline at end of file diff --git a/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/di/CreateQuizViewModelModule.kt b/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/di/CreateQuizViewModelModule.kt new file mode 100644 index 00000000..2661abfa --- /dev/null +++ b/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/di/CreateQuizViewModelModule.kt @@ -0,0 +1,14 @@ +package ru.yeahub.interview_trainer.impl.createQuiz.di + +import org.koin.androidx.viewmodel.dsl.viewModel +import org.koin.dsl.module +import ru.yeahub.interview_trainer.impl.createQuiz.presentation.CreateQuizViewModel + +val createQuizViewModelModule = module { + viewModel { + CreateQuizViewModel( + getSpecializationsListUseCase = get(), + screenMapper = get() + ) + } +} \ No newline at end of file From d766db4394b0d3bead4ae5038674790dee73ca8e Mon Sep 17 00:00:00 2001 From: PanMobile Date: Thu, 5 Feb 2026 21:27:01 +0300 Subject: [PATCH 15/24] =?UTF-8?q?ANDR-71:=20=D0=92=D1=82=D0=BE=D1=80=D0=B8?= =?UTF-8?q?=D1=87=D0=BD=D1=8B=D0=B9=20=D0=BC=D0=B0=D0=BF=D0=BF=D0=B5=D1=80?= =?UTF-8?q?=20DI=20=D0=BC=D0=BE=D0=B4=D1=83=D0=BB=D1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/createQuiz/di/CreateQuizMapperModule.kt | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/di/CreateQuizMapperModule.kt diff --git a/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/di/CreateQuizMapperModule.kt b/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/di/CreateQuizMapperModule.kt new file mode 100644 index 00000000..63404062 --- /dev/null +++ b/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/di/CreateQuizMapperModule.kt @@ -0,0 +1,13 @@ +package ru.yeahub.interview_trainer.impl.createQuiz.di + +import org.koin.dsl.module +import ru.yeahub.interview_trainer.impl.createQuiz.data.CreateQuizDataToDomainMapper +import ru.yeahub.interview_trainer.impl.createQuiz.presentation.CreateQuizScreenMapper + +val createQuizScreenMapperModule = module { + single { CreateQuizScreenMapper() } +} + +val createQuizDataToDomainMapperModule = module { + factory { CreateQuizDataToDomainMapper() } +} \ No newline at end of file From 384dadf5078338abe78bb8424583dccc1f623a2a Mon Sep 17 00:00:00 2001 From: PanMobile Date: Thu, 5 Feb 2026 21:27:14 +0300 Subject: [PATCH 16/24] =?UTF-8?q?ANDR-71:=20=D0=9E=D1=81=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D0=BD=D0=BE=D0=B9=20DI=20=D0=BC=D0=BE=D0=B4=D1=83=D0=BB=D1=8C?= =?UTF-8?q?=20=D1=8D=D0=BA=D1=80=D0=B0=D0=BD=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/createQuiz/di/CreateQuizModule.kt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/di/CreateQuizModule.kt diff --git a/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/di/CreateQuizModule.kt b/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/di/CreateQuizModule.kt new file mode 100644 index 00000000..3de9b4d8 --- /dev/null +++ b/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/di/CreateQuizModule.kt @@ -0,0 +1,17 @@ +package ru.yeahub.interview_trainer.impl.createQuiz.di + +import org.koin.dsl.bind +import org.koin.dsl.module +import ru.yeahub.interview_trainer.impl.InterviewTrainerFeatureImpl +import ru.yeahub.navigation_api.FeatureApi + +val createQuizModule = module { + includes( + createQuizScreenMapperModule, + createQuizDataToDomainMapperModule, + createQuizRepositoryModule, + createQuizUseCaseModule, + createQuizViewModelModule + ) + single { InterviewTrainerFeatureImpl() } bind FeatureApi::class +} \ No newline at end of file From d9cc977a0ed296e856ecfe9b58958e742f863cee Mon Sep 17 00:00:00 2001 From: PanMobile Date: Thu, 5 Feb 2026 22:21:19 +0300 Subject: [PATCH 17/24] =?UTF-8?q?ANDR-71:=20=D0=9F=D0=BE=D0=B4=D0=BA=D0=BB?= =?UTF-8?q?=D1=8E=D1=87=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BC=D0=BE=D0=B4=D1=83?= =?UTF-8?q?=D0=BB=D1=8F=20=D1=82=D1=80=D0=B5=D0=BD=D0=B0=D0=B6=D0=B5=D1=80?= =?UTF-8?q?=D0=B0=20=D0=B2=D0=BE=20=D0=B2=D1=81=D0=B5=20=D0=BF=D1=80=D0=B8?= =?UTF-8?q?=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle.kts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index ca5114c6..98a588b1 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -115,6 +115,8 @@ dependencies { implementation(project(":feature:questions-or-collections:impl")) implementation(project(":feature:public-collections:impl")) implementation(project(":feature:selection-specializations:impl")) + implementation(project(":feature:interview-trainer:api")) + implementation(project(":feature:interview-trainer:impl")) } tasks.withType { From 063c8d0aad4ecec080e1d7a805cdb3ab5c998096 Mon Sep 17 00:00:00 2001 From: PanMobile Date: Thu, 5 Feb 2026 22:21:30 +0300 Subject: [PATCH 18/24] =?UTF-8?q?ANDR-71:=20=D0=9F=D0=BE=D0=B4=D0=BA=D0=BB?= =?UTF-8?q?=D1=8E=D1=87=D0=B5=D0=BD=D0=B8=D0=B5=20KOIN=20=D0=BC=D0=BE?= =?UTF-8?q?=D0=B4=D1=83=D0=BB=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/ru/yeahub/Application.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/ru/yeahub/Application.kt b/app/src/main/java/ru/yeahub/Application.kt index 792c54b3..f36bfecf 100644 --- a/app/src/main/java/ru/yeahub/Application.kt +++ b/app/src/main/java/ru/yeahub/Application.kt @@ -7,6 +7,7 @@ import ru.yeahub.detail_question.impl.di.detailQuestionFeatureModule import ru.yeahub.example_details.impl.detailsFeatureModule import ru.yeahub.example_home.impl.data.di.questionsMainFeatureModule import ru.yeahub.example_profile.impl.profileFeatureModule +import ru.yeahub.interview_trainer.impl.createQuiz.di.createQuizModule import ru.yeahub.navigation_impl.navigationPathModule import ru.yeahub.network_impl.networkModule import ru.yeahub.public_collections.impl.di.CollectionsFeatureModule @@ -53,7 +54,8 @@ class Application : Application() { CollectionsFeatureModule, detailQuestionFeatureModule, collectionsAndQuestionsFeatureModule, - specializationFeatureModule + specializationFeatureModule, + createQuizModule ) } // проверка, что модули загружены From ff7582ddc06c46a51c152cf2fe8e2a3cab39d77b Mon Sep 17 00:00:00 2001 From: PanMobile Date: Thu, 5 Feb 2026 23:10:35 +0300 Subject: [PATCH 19/24] =?UTF-8?q?ANDR-71:=20=D0=98=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=20DI=20=D0=BC=D0=BE=D0=B4=D1=83=D0=BB?= =?UTF-8?q?=D1=8C=20=D0=B4=D0=BB=D1=8F=20=D1=8E=D0=B7=D0=BA=D0=B5=D0=B9?= =?UTF-8?q?=D1=81=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/createQuiz/di/CreateQuizUseCaseModule.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/di/CreateQuizUseCaseModule.kt b/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/di/CreateQuizUseCaseModule.kt index 5593887e..c38e3a9e 100644 --- a/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/di/CreateQuizUseCaseModule.kt +++ b/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/di/CreateQuizUseCaseModule.kt @@ -2,7 +2,12 @@ package ru.yeahub.interview_trainer.impl.createQuiz.di import org.koin.dsl.module import ru.yeahub.interview_trainer.impl.createQuiz.domain.GetSpecializationsListUseCaseImpl +import ru.yeahub.interview_trainer.impl.createQuiz.domain.GetSpecializationsUseCase val createQuizUseCaseModule = module { - factory { GetSpecializationsListUseCaseImpl(repository = get()) } + factory { + GetSpecializationsListUseCaseImpl( + repository = get() + ) + } } \ No newline at end of file From 4758c41133ec57add6dacb250d555737d4a1cf76 Mon Sep 17 00:00:00 2001 From: PanMobile Date: Thu, 5 Feb 2026 23:42:07 +0300 Subject: [PATCH 20/24] =?UTF-8?q?ANDR-71:=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20=D1=8D=D0=BA=D1=80=D0=B0=D0=BD=D1=83=20=D1=81?= =?UTF-8?q?=D0=BA=D1=80=D0=BE=D0=BB=D0=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/createQuiz/ui/CreateQuizScreen.kt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/ui/CreateQuizScreen.kt b/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/ui/CreateQuizScreen.kt index 3a96cf08..7a4203bc 100644 --- a/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/ui/CreateQuizScreen.kt +++ b/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/createQuiz/ui/CreateQuizScreen.kt @@ -14,7 +14,9 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width +import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.Scaffold @@ -88,7 +90,6 @@ fun CreateQuizScreen( ) } - @Composable private fun ScreenUI( state: CreateQuizState, @@ -105,7 +106,9 @@ private fun ScreenUI( } ) { paddingValues -> Box( - modifier = Modifier.padding(paddingValues) + modifier = Modifier + .padding(paddingValues) + .verticalScroll(rememberScrollState()) ) { when (state) { CreateQuizState.Loading -> CreateQuizLoading() From 4eabdad87d84760ddf7141f2d24b41be6f72e9ed Mon Sep 17 00:00:00 2001 From: PanMobile Date: Thu, 5 Feb 2026 23:42:41 +0300 Subject: [PATCH 21/24] =?UTF-8?q?ANDR-71:=20=D0=9D=D0=B0=D0=B2=D0=B8=D0=B3?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D1=8F=20=D1=81=20=D0=B3=D0=BB=D0=B0=D0=B2?= =?UTF-8?q?=D0=BD=D0=BE=D0=B3=D0=BE=20=D1=8D=D0=BA=D1=80=D0=B0=D0=BD=D0=B0?= =?UTF-8?q?=20=D0=BD=D0=B0=20=D0=BF=D0=B5=D1=80=D0=B2=D1=8B=D0=B9=20=D1=8D?= =?UTF-8?q?=D0=BA=D1=80=D0=B0=D0=BD=20=D1=82=D1=80=D0=B5=D0=BD=D0=B0=D0=B6?= =?UTF-8?q?=D0=B5=D1=80=D0=B0=20(CreateQuizScreen)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example_home/impl/QuestionMainFeatureImpl.kt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/QuestionMainFeatureImpl.kt b/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/QuestionMainFeatureImpl.kt index 836b24a5..912b8b97 100644 --- a/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/QuestionMainFeatureImpl.kt +++ b/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/QuestionMainFeatureImpl.kt @@ -111,14 +111,18 @@ class QuestionMainFeatureImpl : FeatureApi { pathManager: NavigationPathManager, navController: NavHostController, ) { + val titleTopAppBar = "Interview Trainer" + // Сбрасываем текущий путь на корневую фичу pathManager.setCurrentPath(FeatureRoute.InterviewTrainerFeature.FEATURE_NAME) - val interviewTrainerPath = pathManager.getCurrentPath() + val createQuizPath = pathManager.getCurrentPath() + "/" + + FeatureRoute.InterviewTrainerFeature.CREATE_QUIZ_SCREEN_NAME + "/" + + titleTopAppBar - Timber.d("HomeFeatureImpl handleInterviewTrainerNavigation: Navigating to: $interviewTrainerPath") + Timber.d("HomeFeatureImpl handleInterviewTrainerNavigation: Navigating to: $createQuizPath") - navController.navigate(interviewTrainerPath) { + navController.navigate(createQuizPath) { popUpTo(navController.graph.startDestinationId) { saveState = true } From d7dd6f1df392fc4db23c978b8910953f070de704 Mon Sep 17 00:00:00 2001 From: PanMobile Date: Thu, 5 Feb 2026 23:43:01 +0300 Subject: [PATCH 22/24] =?UTF-8?q?ANDR-71:=20=D0=A1=D0=BE=D0=B7=D0=B4=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BF=D1=83=D1=82=D0=B5=D0=B9=20=D0=B4?= =?UTF-8?q?=D0=BB=D1=8F=20=D1=8D=D0=BA=D1=80=D0=B0=D0=BD=D0=B0=20=D1=82?= =?UTF-8?q?=D1=80=D0=B5=D0=BD=D0=B0=D0=B6=D0=B5=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/InterviewTrainerFeatureImpl.kt | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/InterviewTrainerFeatureImpl.kt b/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/InterviewTrainerFeatureImpl.kt index 71a09bea..c21f5325 100644 --- a/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/InterviewTrainerFeatureImpl.kt +++ b/feature/interview-trainer/impl/src/main/java/ru/yeahub/interview_trainer/impl/InterviewTrainerFeatureImpl.kt @@ -24,15 +24,19 @@ class InterviewTrainerFeatureImpl() : FeatureApi { pathManager: NavigationPathManager, modifier: Modifier, ) { - val basePathWithParams = pathManager.createParametrizedPath( - featureName = getFeatureName() + "/" + - FeatureRoute.InterviewTrainerFeature.CREATE_QUIZ_SCREEN_NAME, - TITLE_TOP_APP_BAR - ) - Timber.d("InterviewTrainerFeatureImpl registerGraph: currentPath: $basePathWithParams") + //Регистрируем базовый путь фичи (interview_trainer) + pathManager.registerFeaturePath(featureName = getFeatureName(), basePath = getFeatureName()) + + val featurePath = pathManager.getFeaturePath(getFeatureName()) ?: getFeatureName() + + //Создаем путь экрана создания тренировки (interview_trainer/create_quiz/{title} + val createQuizRoute = + "$featurePath/${FeatureRoute.InterviewTrainerFeature.CREATE_QUIZ_SCREEN_NAME}/{$TITLE_TOP_APP_BAR}" + + Timber.d("InterviewTrainerFeatureImpl registerGraph: currentPath: $createQuizRoute") navGraphBuilder.composable( - route = basePathWithParams, + route = createQuizRoute, arguments = listOf( navArgument(TITLE_TOP_APP_BAR) { type = NavType.StringType @@ -70,7 +74,7 @@ class InterviewTrainerFeatureImpl() : FeatureApi { pathManager: NavigationPathManager, navController: NavHostController, ) { - val parentPath = pathManager.getCurrentPath() + val parentPath = pathManager.getParentPath() Timber.d("InterviewTrainerFeatureImpl handleBackNavigation: Navigating to parent: $parentPath") pathManager.setCurrentPath(parentPath) @@ -98,7 +102,7 @@ class InterviewTrainerFeatureImpl() : FeatureApi { ) { val interviewQuizRoute = getFeatureName() + "/" + FeatureRoute.InterviewTrainerFeature.INTERVIEW_QUIZ_SCREEN_NAME + "/" + - titleTopAppBar + specializationId + questionsCount + "$titleTopAppBar/$specializationId/$questionsCount" Timber.d("InterviewTrainerFeatureImpl registerGraph: $interviewQuizRoute") From 84cc00424afe026dfce85c6fa2342ce3bc408009 Mon Sep 17 00:00:00 2001 From: PanMobile Date: Thu, 5 Feb 2026 23:50:29 +0300 Subject: [PATCH 23/24] =?UTF-8?q?ANDR-71:=20=D0=A3=D0=B1=D1=80=D0=B0=D0=BD?= =?UTF-8?q?=20=D1=85=D0=B0=D1=80=D0=B4=D0=BA=D0=BE=D0=B4=20=D0=BF=D1=83?= =?UTF-8?q?=D1=82=D1=8C=20=D1=8D=D0=BA=D1=80=D0=B0=D0=BD=D0=B0=20CreateQui?= =?UTF-8?q?z?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yeahub/example_home/impl/QuestionMainFeatureImpl.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/QuestionMainFeatureImpl.kt b/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/QuestionMainFeatureImpl.kt index 912b8b97..7c9dfe3f 100644 --- a/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/QuestionMainFeatureImpl.kt +++ b/feature/example-home/impl/src/main/java/ru/yeahub/example_home/impl/QuestionMainFeatureImpl.kt @@ -111,14 +111,14 @@ class QuestionMainFeatureImpl : FeatureApi { pathManager: NavigationPathManager, navController: NavHostController, ) { - val titleTopAppBar = "Interview Trainer" + val titleTopAppBar = "Test TitleTopAppBar" // Сбрасываем текущий путь на корневую фичу pathManager.setCurrentPath(FeatureRoute.InterviewTrainerFeature.FEATURE_NAME) - val createQuizPath = pathManager.getCurrentPath() + "/" + - FeatureRoute.InterviewTrainerFeature.CREATE_QUIZ_SCREEN_NAME + "/" + - titleTopAppBar + val createQuizPath = pathManager.createChildPath( + featureName = FeatureRoute.InterviewTrainerFeature.CREATE_QUIZ_SCREEN_NAME + ) + "/" + titleTopAppBar Timber.d("HomeFeatureImpl handleInterviewTrainerNavigation: Navigating to: $createQuizPath") From 91ed820473a232aad293ee465adf4d9c2e650558 Mon Sep 17 00:00:00 2001 From: PanMobile Date: Fri, 6 Feb 2026 00:08:32 +0300 Subject: [PATCH 24/24] =?UTF-8?q?ANDR-71:=20=D0=98=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=20=D0=BA=D0=BB=D0=B0=D1=81=D1=81=20?= =?UTF-8?q?=D1=82=D0=B5=D1=81=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/src/test/java/test/CreateQuizScreenMapperTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feature/interview-trainer/impl/src/test/java/test/CreateQuizScreenMapperTest.kt b/feature/interview-trainer/impl/src/test/java/test/CreateQuizScreenMapperTest.kt index a041a7d3..0e85697d 100644 --- a/feature/interview-trainer/impl/src/test/java/test/CreateQuizScreenMapperTest.kt +++ b/feature/interview-trainer/impl/src/test/java/test/CreateQuizScreenMapperTest.kt @@ -15,7 +15,7 @@ class CreateQuizScreenMapperTest { fun getScreenStateTest( testCase: CreateQuizScreenMapperTestCase, ) { - val result = CreateQuizScreenMapper.getScreenState( + val result = CreateQuizScreenMapper().getScreenState( specializations = testCase.specializations, selectedSpecializationId = testCase.selectedSpecializationId, questionsCount = testCase.questionsCount