summaryrefslogtreecommitdiff
path: root/app/src/main/java/sh/lajo/buddy/EducationScreen.kt
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/sh/lajo/buddy/EducationScreen.kt')
-rw-r--r--app/src/main/java/sh/lajo/buddy/EducationScreen.kt216
1 files changed, 216 insertions, 0 deletions
diff --git a/app/src/main/java/sh/lajo/buddy/EducationScreen.kt b/app/src/main/java/sh/lajo/buddy/EducationScreen.kt
new file mode 100644
index 0000000..e37770a
--- /dev/null
+++ b/app/src/main/java/sh/lajo/buddy/EducationScreen.kt
@@ -0,0 +1,216 @@
+package sh.lajo.buddy
+
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.items
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.ArrowBack
+import androidx.compose.material3.*
+import androidx.compose.runtime.*
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import coil.compose.AsyncImage
+
+@Composable
+fun EducationScreen(repository: EducationRepository = remember { EducationRepository() }) {
+ var lectures by remember { mutableStateOf<List<EducationLecture>>(emptyList()) }
+ var selectedLecture by remember { mutableStateOf<EducationLecture?>(null) }
+ var showingQuiz by remember { mutableStateOf(false) }
+ var isLoading by remember { mutableStateOf(true) }
+
+ LaunchedEffect(Unit) {
+ lectures = repository.fetchLectures()
+ isLoading = false
+ }
+
+ if (isLoading) {
+ Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
+ CircularProgressIndicator()
+ }
+ } else if (showingQuiz && selectedLecture != null) {
+ QuizScreen(quiz = selectedLecture!!.quiz, onBack = { showingQuiz = false })
+ } else if (selectedLecture != null) {
+ LectureDetailScreen(
+ lecture = selectedLecture!!,
+ onBack = { selectedLecture = null },
+ onStartQuiz = { showingQuiz = true }
+ )
+ } else {
+ LectureListScreen(lectures = lectures, onLectureClick = { selectedLecture = it })
+ }
+}
+
+@Composable
+fun LectureListScreen(lectures: List<EducationLecture>, onLectureClick: (EducationLecture) -> Unit) {
+ LazyColumn(
+ modifier = Modifier.fillMaxSize(),
+ contentPadding = PaddingValues(16.dp),
+ verticalArrangement = Arrangement.spacedBy(8.dp)
+ ) {
+ item {
+ Text(
+ text = "Edukacija",
+ style = MaterialTheme.typography.headlineMedium,
+ modifier = Modifier.padding(bottom = 16.dp)
+ )
+ }
+ items(lectures) { lecture ->
+ ElevatedCard(
+ onClick = { onLectureClick(lecture) },
+ modifier = Modifier.fillMaxWidth()
+ ) {
+ Text(
+ text = lecture.title,
+ modifier = Modifier.padding(16.dp),
+ style = MaterialTheme.typography.titleLarge
+ )
+ }
+ }
+ }
+}
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+fun LectureDetailScreen(
+ lecture: EducationLecture,
+ onBack: () -> Unit,
+ onStartQuiz: () -> Unit
+) {
+ Scaffold(
+ topBar = {
+ TopAppBar(
+ title = { Text(lecture.title) },
+ navigationIcon = {
+ IconButton(onClick = onBack) {
+ Icon(Icons.Default.ArrowBack, contentDescription = "Back")
+ }
+ }
+ )
+ }
+ ) { paddingValues ->
+ LazyColumn(
+ modifier = Modifier
+ .fillMaxSize()
+ .padding(paddingValues),
+ contentPadding = PaddingValues(16.dp),
+ verticalArrangement = Arrangement.spacedBy(16.dp)
+ ) {
+ lecture.lectureItems.forEach { item ->
+ item {
+ Text(text = item.title, style = MaterialTheme.typography.headlineSmall)
+ }
+ items(item.lectureElements) { element ->
+ when (element.type) {
+ "text" -> element.text?.let { Text(text = it, style = MaterialTheme.typography.bodyLarge) }
+ "image" -> element.imageUrl?.let {
+ AsyncImage(
+ model = it,
+ contentDescription = null,
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(vertical = 8.dp)
+ )
+ }
+ }
+ }
+ item {
+ HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp))
+ }
+ }
+ item {
+ Button(
+ onClick = onStartQuiz,
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(top = 16.dp)
+ ) {
+ Text("Započni kviz")
+ }
+ }
+ }
+ }
+}
+
+@Composable
+fun QuizScreen(quiz: Quiz, onBack: () -> Unit) {
+ var currentQuestionIndex by remember { mutableIntStateOf(0) }
+ var selectedAnswerIndex by remember { mutableStateOf<Int?>(null) }
+ var score by remember { mutableIntStateOf(0) }
+ var showResult by remember { mutableStateOf(false) }
+
+ val currentQuestion = quiz.questions.getOrNull(currentQuestionIndex)
+
+ if (showResult || currentQuestion == null) {
+ Column(
+ modifier = Modifier
+ .fillMaxSize()
+ .padding(16.dp),
+ horizontalAlignment = Alignment.CenterHorizontally,
+ verticalArrangement = Arrangement.Center
+ ) {
+ Text(text = "Kviz završen!", style = MaterialTheme.typography.headlineMedium)
+ Spacer(modifier = Modifier.height(8.dp))
+ Text(text = "Tvoj rezultat: $score / ${quiz.questions.size}", style = MaterialTheme.typography.titleLarge)
+ Spacer(modifier = Modifier.height(24.dp))
+ Button(onClick = onBack) {
+ Text("Povratak na predavanje")
+ }
+ }
+ } else {
+ Column(
+ modifier = Modifier
+ .fillMaxSize()
+ .padding(16.dp)
+ ) {
+ Text(
+ text = "Pitanje ${currentQuestionIndex + 1} od ${quiz.questions.size}",
+ style = MaterialTheme.typography.labelMedium
+ )
+ Spacer(modifier = Modifier.height(8.dp))
+ Text(text = currentQuestion.question, style = MaterialTheme.typography.headlineSmall)
+ Spacer(modifier = Modifier.height(24.dp))
+ currentQuestion.answers.forEachIndexed { index, answer ->
+ val isSelected = selectedAnswerIndex == index
+ OutlinedCard(
+ onClick = { selectedAnswerIndex = index },
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(vertical = 4.dp),
+ colors = CardDefaults.outlinedCardColors(
+ containerColor = if (isSelected) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.surface
+ ),
+ border = CardDefaults.outlinedCardBorder().run {
+ if (isSelected) copy(width = 2.dp) else this
+ }
+ ) {
+ Text(
+ text = answer,
+ modifier = Modifier.padding(16.dp),
+ style = MaterialTheme.typography.bodyLarge
+ )
+ }
+ }
+ Spacer(modifier = Modifier.weight(1f))
+ Button(
+ onClick = {
+ // correctAnswer in JSON is "1" which refers to index 1 (second answer)
+ val correctIndex = currentQuestion.correctAnswer.toIntOrNull() ?: 0
+ if (selectedAnswerIndex == correctIndex) {
+ score++
+ }
+ if (currentQuestionIndex < quiz.questions.size - 1) {
+ currentQuestionIndex++
+ selectedAnswerIndex = null
+ } else {
+ showResult = true
+ }
+ },
+ enabled = selectedAnswerIndex != null,
+ modifier = Modifier.fillMaxWidth()
+ ) {
+ Text(if (currentQuestionIndex < quiz.questions.size - 1) "Sljedeće pitanje" else "Završi kviz")
+ }
+ }
+ }
+}