Expanded student view
This commit is contained in:
parent
fbc450e0ee
commit
97fe7a8139
|
@ -0,0 +1,9 @@
|
||||||
|
package com.jaytux.grader
|
||||||
|
|
||||||
|
fun String.maxN(n: Int): String {
|
||||||
|
return if (this.length > n) {
|
||||||
|
this.substring(0, n - 3) + "..."
|
||||||
|
} else {
|
||||||
|
this
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,7 +15,6 @@ import androidx.compose.ui.unit.dp
|
||||||
import com.jaytux.grader.viewmodel.GroupAssignmentState
|
import com.jaytux.grader.viewmodel.GroupAssignmentState
|
||||||
import com.mohamedrejeb.richeditor.model.rememberRichTextState
|
import com.mohamedrejeb.richeditor.model.rememberRichTextState
|
||||||
import com.mohamedrejeb.richeditor.ui.material3.OutlinedRichTextEditor
|
import com.mohamedrejeb.richeditor.ui.material3.OutlinedRichTextEditor
|
||||||
import com.mohamedrejeb.richeditor.ui.material3.RichTextEditor
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
|
|
|
@ -11,11 +11,13 @@ import androidx.compose.material3.*
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.DpSize
|
import androidx.compose.ui.unit.DpSize
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.window.DialogWindow
|
import androidx.compose.ui.window.DialogWindow
|
||||||
import androidx.compose.ui.window.WindowPosition
|
import androidx.compose.ui.window.WindowPosition
|
||||||
import androidx.compose.ui.window.rememberDialogState
|
import androidx.compose.ui.window.rememberDialogState
|
||||||
|
import com.jaytux.grader.maxN
|
||||||
import com.jaytux.grader.viewmodel.GroupState
|
import com.jaytux.grader.viewmodel.GroupState
|
||||||
import com.jaytux.grader.viewmodel.StudentState
|
import com.jaytux.grader.viewmodel.StudentState
|
||||||
|
|
||||||
|
@ -26,37 +28,114 @@ fun StudentView(state: StudentState) {
|
||||||
val groupGrades by state.groupGrades.entities
|
val groupGrades by state.groupGrades.entities
|
||||||
val soloGrades by state.soloGrades.entities
|
val soloGrades by state.soloGrades.entities
|
||||||
|
|
||||||
// TODO: incorporate grades into UI
|
|
||||||
|
|
||||||
Column(Modifier.padding(10.dp)) {
|
Column(Modifier.padding(10.dp)) {
|
||||||
PaneHeader(state.student.name, "student", state.editionCourse)
|
PaneHeader(state.student.name, "student", state.editionCourse)
|
||||||
Row {
|
Row {
|
||||||
Column(Modifier.padding(10.dp).weight(0.45f)) {
|
Column(Modifier.weight(0.45f)) {
|
||||||
Spacer(Modifier.height(10.dp))
|
Column(Modifier.padding(10.dp).weight(0.35f)) {
|
||||||
InteractToEdit(state.student.name, { state.update { this.name = it } }, "Name")
|
Spacer(Modifier.height(10.dp))
|
||||||
InteractToEdit(state.student.contact, { state.update { this.contact = it } }, "Contact")
|
InteractToEdit(state.student.name, { state.update { this.name = it } }, "Name")
|
||||||
InteractToEdit(state.student.note, { state.update { this.note = it } }, "Note", singleLine = false)
|
InteractToEdit(state.student.contact, { state.update { this.contact = it } }, "Contact")
|
||||||
}
|
InteractToEdit(state.student.note, { state.update { this.note = it } }, "Note", singleLine = false)
|
||||||
Box(Modifier.weight(0.55f)) {}
|
}
|
||||||
}
|
Column(Modifier.weight(0.20f)) {
|
||||||
Row {
|
Text("Courses", style = MaterialTheme.typography.headlineSmall)
|
||||||
Column(Modifier.weight(0.5f)) {
|
ListOrEmpty(courses, { Text("Not a member of any course") }) { _, it ->
|
||||||
Text("Courses", style = MaterialTheme.typography.headlineSmall)
|
val (ed, course) = it
|
||||||
ListOrEmpty(courses, { Text("Not a member of any course") }) { _, it ->
|
Text("${course.name} (${ed.name})", style = MaterialTheme.typography.bodyMedium)
|
||||||
val (ed, course) = it
|
}
|
||||||
Text("${course.name} (${ed.name})", style = MaterialTheme.typography.bodyMedium)
|
}
|
||||||
|
Column(Modifier.weight(0.45f)) {
|
||||||
|
Text("Groups", style = MaterialTheme.typography.headlineSmall)
|
||||||
|
ListOrEmpty(groups, { Text("Not a member of any group") }) { _, it ->
|
||||||
|
Row {
|
||||||
|
val (group, c) = it
|
||||||
|
val (course, ed) = c
|
||||||
|
Text(group.name, style = MaterialTheme.typography.bodyMedium)
|
||||||
|
Spacer(Modifier.width(5.dp))
|
||||||
|
Text(
|
||||||
|
"(in course $course ($ed))",
|
||||||
|
Modifier.align(Alignment.Bottom),
|
||||||
|
style = MaterialTheme.typography.bodySmall
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Column(Modifier.weight(0.55f)) {
|
||||||
|
Text("Courses", style = MaterialTheme.typography.headlineSmall)
|
||||||
|
LazyColumn {
|
||||||
|
item {
|
||||||
|
Text("As group member", fontWeight = FontWeight.Bold)
|
||||||
|
}
|
||||||
|
items(groupGrades) {
|
||||||
|
groupGradeWidget(it)
|
||||||
|
}
|
||||||
|
|
||||||
Column(Modifier.weight(0.5f)) {
|
item {
|
||||||
Text("Groups", style = MaterialTheme.typography.headlineSmall)
|
Text("Solo assignments", fontWeight = FontWeight.Bold)
|
||||||
ListOrEmpty(groups, { Text("Not a member of any group") }) { _, it ->
|
}
|
||||||
|
items(soloGrades) {
|
||||||
|
soloGradeWidget(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun groupGradeWidget(gg: StudentState.LocalGroupGrade) {
|
||||||
|
val (group, assignment, gGrade, iGrade) = gg
|
||||||
|
var expanded by remember { mutableStateOf(false) }
|
||||||
|
Row(Modifier.padding(5.dp)) {
|
||||||
|
Spacer(Modifier.width(10.dp))
|
||||||
|
Surface(
|
||||||
|
Modifier.clickable { expanded = !expanded }.fillMaxWidth(),
|
||||||
|
tonalElevation = 5.dp,
|
||||||
|
shape = MaterialTheme.shapes.medium
|
||||||
|
) {
|
||||||
|
Column(Modifier.padding(5.dp)) {
|
||||||
|
Text("${assignment.maxN(25)} (${iGrade ?: gGrade ?: "no grade yet"})")
|
||||||
|
|
||||||
|
if (expanded) {
|
||||||
Row {
|
Row {
|
||||||
val (group, c) = it
|
Spacer(Modifier.width(10.dp))
|
||||||
val (course, ed) = c
|
Column {
|
||||||
Text(group.name, style = MaterialTheme.typography.bodyMedium)
|
ItalicAndNormal("Assignment: ", assignment)
|
||||||
Spacer(Modifier.width(5.dp))
|
ItalicAndNormal("Group name: ", group)
|
||||||
Text("(in course $course ($ed))", Modifier.align(Alignment.Bottom), style = MaterialTheme.typography.bodySmall)
|
ItalicAndNormal("Group grade: ", gGrade ?: "no grade yet")
|
||||||
|
ItalicAndNormal("Individual grade: ", iGrade ?: "no individual grade")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun soloGradeWidget(sg: StudentState.LocalSoloGrade) {
|
||||||
|
val (assignment, grade) = sg
|
||||||
|
var expanded by remember { mutableStateOf(false) }
|
||||||
|
Row(Modifier.padding(5.dp)) {
|
||||||
|
Spacer(Modifier.width(10.dp))
|
||||||
|
Surface(
|
||||||
|
Modifier.clickable { expanded = !expanded }.fillMaxWidth(),
|
||||||
|
tonalElevation = 5.dp,
|
||||||
|
shape = MaterialTheme.shapes.medium
|
||||||
|
) {
|
||||||
|
Column(Modifier.padding(5.dp)) {
|
||||||
|
Text("${assignment.maxN(25)} (${grade ?: "no grade yet"})")
|
||||||
|
|
||||||
|
if (expanded) {
|
||||||
|
Row {
|
||||||
|
Spacer(Modifier.width(10.dp))
|
||||||
|
Column {
|
||||||
|
ItalicAndNormal("Assignment: ", assignment)
|
||||||
|
ItalicAndNormal("Individual grade: ", grade ?: "no grade yet")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -343,3 +343,9 @@ fun DateTimePicker(
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ItalicAndNormal(italic: String, normal: String) = Row{
|
||||||
|
Text(italic, fontStyle = FontStyle.Italic)
|
||||||
|
Text(normal)
|
||||||
|
}
|
Loading…
Reference in New Issue