diff --git a/DBTApp/.idea/codeStyles/Project.xml b/DBTApp/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..7f70f7e --- /dev/null +++ b/DBTApp/.idea/codeStyles/Project.xml @@ -0,0 +1,158 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/DBTApp/.idea/codeStyles/codeStyleConfig.xml b/DBTApp/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..79ee123 --- /dev/null +++ b/DBTApp/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/DBTApp/.idea/deploymentTargetSelector.xml b/DBTApp/.idea/deploymentTargetSelector.xml index 2a7a811..2b60ed8 100644 --- a/DBTApp/.idea/deploymentTargetSelector.xml +++ b/DBTApp/.idea/deploymentTargetSelector.xml @@ -4,22 +4,18 @@ - - - - - - - - \ No newline at end of file diff --git a/DBTApp/app/build.gradle.kts b/DBTApp/app/build.gradle.kts index a6ebec1..067653a 100644 --- a/DBTApp/app/build.gradle.kts +++ b/DBTApp/app/build.gradle.kts @@ -2,6 +2,7 @@ plugins { alias(libs.plugins.android.application) alias(libs.plugins.kotlin.android) alias(libs.plugins.compose.compiler) + id("com.google.devtools.ksp") } android { @@ -37,6 +38,9 @@ android { buildFeatures { compose = true } + ksp { + arg("room.schemaLocation", "$projectDir/schemas") + } } dependencies { @@ -70,6 +74,12 @@ dependencies { //Compose navigation implementation(libs.androidx.navigation.compose) + //room (for AppDatabase) + implementation(libs.room.runtime) + ksp(libs.androidx.room.compiler) + implementation(libs.androidx.room.ktx) + + implementation(libs.androidx.core.ktx) implementation(libs.androidx.appcompat) implementation(libs.material) diff --git a/DBTApp/app/schemas/de.cdaut.dbtapp.model.AppDatabase/1.json b/DBTApp/app/schemas/de.cdaut.dbtapp.model.AppDatabase/1.json new file mode 100644 index 0000000..41d6ad0 --- /dev/null +++ b/DBTApp/app/schemas/de.cdaut.dbtapp.model.AppDatabase/1.json @@ -0,0 +1,43 @@ +{ + "formatVersion": 1, + "database": { + "version": 1, + "identityHash": "9293dc46eca03d297eae6183174db499", + "entities": [ + { + "tableName": "Skill", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`identifier` BLOB NOT NULL, `title` TEXT NOT NULL, `description` TEXT NOT NULL, PRIMARY KEY(`identifier`))", + "fields": [ + { + "fieldPath": "identifier", + "columnName": "identifier", + "affinity": "BLOB", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "identifier" + ] + } + } + ], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '9293dc46eca03d297eae6183174db499')" + ] + } +} \ No newline at end of file diff --git a/DBTApp/app/src/main/java/de/cdaut/dbtapp/MainActivity.kt b/DBTApp/app/src/main/java/de/cdaut/dbtapp/MainActivity.kt index 8e03061..36c2b54 100644 --- a/DBTApp/app/src/main/java/de/cdaut/dbtapp/MainActivity.kt +++ b/DBTApp/app/src/main/java/de/cdaut/dbtapp/MainActivity.kt @@ -1,36 +1,30 @@ package de.cdaut.dbtapp -import android.graphics.drawable.shapes.Shape import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent -import androidx.compose.foundation.Image -import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Emergency -import androidx.compose.material3.Button -import androidx.compose.material3.ButtonColors -import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold -import androidx.compose.material3.Shapes import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController -import com.google.android.material.floatingactionbutton.FloatingActionButton import de.cdaut.dbtapp.components.BottomNavigationBar +import de.cdaut.dbtapp.components.FavouritesScreen +import de.cdaut.dbtapp.components.SkillsChainsScreen import de.cdaut.dbtapp.components.SkillsScreen +import de.cdaut.dbtapp.components.TrackingScreen import de.cdaut.dbtapp.navigation.Screens class MainActivity : ComponentActivity() { @@ -42,49 +36,52 @@ class MainActivity : ComponentActivity() { } } -@Preview(locale = "en-US") +@Preview(locale = "en-US", device = "id:pixel_6") @Composable private fun MainContent() { val navController = rememberNavController() - Box { - Scaffold( - modifier = Modifier.fillMaxSize(), - bottomBar = { BottomNavigationBar(navController) }, - floatingActionButton = { EmergencyButton() } - ) { paddingValues -> - NavHost( - navController = navController, - startDestination = Screens.Home.route, - modifier = Modifier.padding(paddingValues = paddingValues) - ) { - composable(Screens.Tracking.route) { - Text("Tracking") - } - composable(Screens.Skillslist.route) { - SkillsScreen() - } - composable(Screens.Home.route) { - Text("Home") - } - composable(Screens.Favourites.route) { - Text("Favourites") + MaterialTheme { + Box { + Scaffold( + modifier = Modifier.fillMaxSize(), + bottomBar = { BottomNavigationBar(navController) }, + floatingActionButton = { EmergencyButton() } + ) { paddingValues -> + NavHost( + navController = navController, + startDestination = Screens.Home.route, + modifier = Modifier.padding(paddingValues = paddingValues) + ) { + composable(Screens.Tracking.route) { + TrackingScreen() + } + composable(Screens.Skillslist.route) { + SkillsScreen() + } + composable(Screens.Home.route) { + Text("Home") + } + composable(Screens.Favourites.route) { + FavouritesScreen() - } - composable(Screens.Skillschains.route) { - Text("Skillschains") + } + composable(Screens.Skillschains.route) { + SkillsChainsScreen() + } } } } } } -@Preview @Composable private fun EmergencyButton() { FloatingActionButton( - onClick = {}, - containerColor = Color.Red + onClick = { + //TODO: Implement function for emergency Button + }, + containerColor = MaterialTheme.colorScheme.error ) { Icon( imageVector = Icons.Filled.Emergency, diff --git a/DBTApp/app/src/main/java/de/cdaut/dbtapp/components/BottomNavigationBar.kt b/DBTApp/app/src/main/java/de/cdaut/dbtapp/components/BottomNavigationBar.kt index 5513015..c1e92e2 100644 --- a/DBTApp/app/src/main/java/de/cdaut/dbtapp/components/BottomNavigationBar.kt +++ b/DBTApp/app/src/main/java/de/cdaut/dbtapp/components/BottomNavigationBar.kt @@ -19,17 +19,19 @@ import de.cdaut.dbtapp.navigation.BottomNavigationItem fun BottomNavigationBar(navController: NavController) { var context = LocalContext.current //remember the currently selected view + //default view is home + val homeView = BottomNavigationItem() + .bottomNavigationItems() + .find { item -> item.label == "Home" }!!.idx var navigationSelectedItem by remember { mutableIntStateOf( - //default view is home - BottomNavigationItem().bottomNavigationItems(ctx = context) - .find { item -> item.label == "Home" }!!.idx + homeView ) } NavigationBar { //Create an entry in the bottom bar for each view - BottomNavigationItem().bottomNavigationItems(ctx = context).sortedBy { item -> item.idx } + BottomNavigationItem().bottomNavigationItems().sortedBy { item -> item.idx } .forEachIndexed { index, item -> NavigationBarItem( selected = index == navigationSelectedItem, diff --git a/DBTApp/app/src/main/java/de/cdaut/dbtapp/components/Favourites.kt b/DBTApp/app/src/main/java/de/cdaut/dbtapp/components/Favourites.kt new file mode 100644 index 0000000..15bcf04 --- /dev/null +++ b/DBTApp/app/src/main/java/de/cdaut/dbtapp/components/Favourites.kt @@ -0,0 +1,136 @@ +package de.cdaut.dbtapp.components + +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.IntrinsicSize +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowDropDown +import androidx.compose.material.icons.filled.ArrowDropUp +import androidx.compose.material.icons.filled.PlayArrow +import androidx.compose.material3.Button +import androidx.compose.material3.Card +import androidx.compose.material3.Icon +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import de.cdaut.dbtapp.R +import de.cdaut.dbtapp.model.Skill +import de.cdaut.dbtapp.model.SkillCategory + +@Preview +@Composable +fun FavouritesScreen() { + Column( + Modifier.verticalScroll(rememberScrollState()), + horizontalAlignment = Alignment.CenterHorizontally + ) { + RoundedSearchBar(onSearch = {}, stringResource(R.string.label_skills_search_bar)) + SkillCategory.entries.forEach { skillCategory -> + FavouritesCategoryCard(skillCategory) + } + } +} + +@Composable +private fun FavouritesCategoryCard(category: SkillCategory) { + var enabled by remember { + mutableStateOf(false) + } + + Card( + Modifier + .fillMaxWidth() + .padding(10.dp) + ) { + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween, + modifier = Modifier + .fillMaxWidth() + .clickable(onClick = { enabled = !enabled }), + ) { + TitleText( + modifier = Modifier.padding(10.dp), + content = category.title + ) + Icon( + modifier = Modifier + .padding(5.dp), + imageVector = if (enabled) Icons.Filled.ArrowDropUp else Icons.Filled.ArrowDropDown, + contentDescription = stringResource(R.string.desc_btn_expand) + ) + } + if (enabled) { + category.skills.forEach { skill -> + SingleSkillCard(skill = skill) + } + } + } +} + +@Composable +private fun SingleSkillCard(skill: Skill) { + Row( + modifier = Modifier + .fillMaxWidth() + .height(IntrinsicSize.Min) + .background(Color.Transparent) + .padding(10.dp) + .background(Color.White, shape = RoundedCornerShape(5.dp)) + .padding(10.dp), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically + ) { + Column( + modifier = Modifier + .fillMaxHeight() + .fillMaxWidth(fraction = 0.8f), + verticalArrangement = Arrangement.SpaceBetween, + + ) { + TitleText(skill.title) + Spacer(modifier = Modifier.height(10.dp)) + DescriptionText(skill.description) + } + + Button( + modifier = Modifier + .clip(CircleShape) + .size(50.dp), + contentPadding = PaddingValues(0.dp), + shape = CircleShape, + onClick = { + //TODO: Start Skill + } + ) { + Icon( + imageVector = Icons.Filled.PlayArrow, + contentDescription = "TODO: PROVIDE" + ) + } + + } +} \ No newline at end of file diff --git a/DBTApp/app/src/main/java/de/cdaut/dbtapp/components/Searchbar.kt b/DBTApp/app/src/main/java/de/cdaut/dbtapp/components/Searchbar.kt new file mode 100644 index 0000000..12e53d5 --- /dev/null +++ b/DBTApp/app/src/main/java/de/cdaut/dbtapp/components/Searchbar.kt @@ -0,0 +1,58 @@ +package de.cdaut.dbtapp.components + +import androidx.compose.foundation.text.input.rememberTextFieldState +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Search +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.SearchBar +import androidx.compose.material3.SearchBarDefaults +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import de.cdaut.dbtapp.R + +@Preview +@Composable +private fun RoundedSearchBarPrev() { + RoundedSearchBar(onSearch = {}, stringResource(R.string.label_skills_search_bar)) +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun RoundedSearchBar(onSearch: (String) -> Unit = {}, placeholder: String) { + // Controls expansion state of the search bar + var expanded by rememberSaveable { mutableStateOf(false) } + var textFieldState = rememberTextFieldState() + + SearchBar( + inputField = { + SearchBarDefaults.InputField( + query = textFieldState.text.toString(), + onQueryChange = { textFieldState.edit { replace(0, length, it) } }, + onSearch = { + onSearch(textFieldState.text.toString()) + expanded = false + }, + expanded = expanded, + onExpandedChange = { expanded = it }, + leadingIcon = { + Icon( + Icons.Filled.Search, + contentDescription = stringResource(R.string.content_desc_search_bar) + ) + }, + placeholder = { Text(placeholder) } + ) + }, + expanded = expanded, + onExpandedChange = { expanded = it } + ) { + Text("Placeholder") + } +} \ No newline at end of file diff --git a/DBTApp/app/src/main/java/de/cdaut/dbtapp/components/SkillsList.kt b/DBTApp/app/src/main/java/de/cdaut/dbtapp/components/SkillsList.kt index 3f93d07..deb0593 100644 --- a/DBTApp/app/src/main/java/de/cdaut/dbtapp/components/SkillsList.kt +++ b/DBTApp/app/src/main/java/de/cdaut/dbtapp/components/SkillsList.kt @@ -1,12 +1,9 @@ package de.cdaut.dbtapp.components import androidx.compose.foundation.background -import androidx.compose.foundation.border import androidx.compose.foundation.clickable -import androidx.compose.foundation.gestures.ScrollableState -import androidx.compose.foundation.gestures.scrollable -import androidx.compose.foundation.interaction.Interaction import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.IntrinsicSize import androidx.compose.foundation.layout.Row @@ -15,19 +12,17 @@ import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowDropDown +import androidx.compose.material.icons.filled.ArrowDropUp import androidx.compose.material.icons.filled.Star -import androidx.compose.material.icons.outlined.Star import androidx.compose.material.icons.outlined.StarOutline -import androidx.compose.material3.Button import androidx.compose.material3.Card import androidx.compose.material3.Icon -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -40,7 +35,6 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.em import de.cdaut.dbtapp.R import de.cdaut.dbtapp.model.Skill import de.cdaut.dbtapp.model.SkillCategory @@ -49,8 +43,10 @@ import de.cdaut.dbtapp.model.SkillCategory @Composable fun SkillsScreen() { Column( - Modifier.verticalScroll(rememberScrollState()) + Modifier.verticalScroll(rememberScrollState()), + horizontalAlignment = Alignment.CenterHorizontally ) { + RoundedSearchBar(onSearch = {}, stringResource(R.string.label_skills_search_bar)) SkillCategory.entries.forEach { skillCategory -> SkillsCategoryCard(skillCategory.skills, skillCategory.title) Spacer(Modifier.height(5.dp)) @@ -58,7 +54,6 @@ fun SkillsScreen() { } } -@Preview @Composable private fun SkillsCategoryCardPrev() { SkillsCategoryCard(Skill.mockSkills(), "Skill") @@ -66,22 +61,41 @@ private fun SkillsCategoryCardPrev() { @Composable fun SkillsCategoryCard(skills: List, title: String) { + var enabled by remember { + mutableStateOf(false) + } + Card( Modifier .fillMaxWidth() .padding(10.dp) ) { - TitleText( - modifier = Modifier.padding(10.dp), - content = title - ) - skills.forEach { skill -> - SingleSkillCard(skill.title, skill.description) + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween, + modifier = Modifier + .fillMaxWidth() + .clickable(onClick = { enabled = !enabled }), + ) { + TitleText( + modifier = Modifier.padding(10.dp), + content = title + ) + Icon( + modifier = Modifier + .padding(5.dp), + imageVector = if (enabled) Icons.Filled.ArrowDropUp else Icons.Filled.ArrowDropDown, + contentDescription = stringResource(R.string.desc_btn_expand) + ) + } + if (enabled) { + skills.forEach { skill -> + SingleSkillCard(skill.title, skill.description) + } } } } -@Preview @Composable private fun SingleSkillsCardPreview() { SingleSkillCard( @@ -118,16 +132,29 @@ private fun SingleSkillCard(title: String, description: String) { DescriptionText(description) } - Icon( - modifier = Modifier - .padding(10.dp) - .clickable(onClick = { - selected = !selected - }), - imageVector = if (selected) Icons.Outlined.Star else Icons.Outlined.StarOutline, - contentDescription = stringResource(R.string.desc_btn_fav), - tint = if (selected) Color.Yellow else Color.Black - ) + Box( + modifier = Modifier.clip(CircleShape), + contentAlignment = Alignment.Center + ) { + if (selected) { + Icon( + modifier = Modifier.clip(CircleShape), + imageVector = Icons.Filled.Star, + contentDescription = "Filled Star", + tint = Color.Yellow + ) + } + Icon( + modifier = Modifier + .clip(CircleShape) + .padding(10.dp) + .clickable(onClick = { + selected = !selected + }), + imageVector = Icons.Outlined.StarOutline, + contentDescription = stringResource(R.string.desc_btn_fav) + ) + } } -} \ No newline at end of file +} diff --git a/DBTApp/app/src/main/java/de/cdaut/dbtapp/components/Skillschains.kt b/DBTApp/app/src/main/java/de/cdaut/dbtapp/components/Skillschains.kt new file mode 100644 index 0000000..a4762c2 --- /dev/null +++ b/DBTApp/app/src/main/java/de/cdaut/dbtapp/components/Skillschains.kt @@ -0,0 +1,167 @@ +package de.cdaut.dbtapp.components + +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Add +import androidx.compose.material.icons.filled.ArrowDropDown +import androidx.compose.material.icons.filled.ArrowDropUp +import androidx.compose.material.icons.filled.PlayArrow +import androidx.compose.material3.Button +import androidx.compose.material3.Card +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import de.cdaut.dbtapp.R +import de.cdaut.dbtapp.model.Skill +import de.cdaut.dbtapp.model.Skillschain +import de.cdaut.dbtapp.model.Skillschain.Companion.mockSkillschains + +@Preview +@Composable +fun SkillsChainsScreen() { + Column( + Modifier.verticalScroll(rememberScrollState()), + horizontalAlignment = Alignment.CenterHorizontally + ) { + RoundedSearchBar(onSearch = {}, stringResource(R.string.label_skillschains_search_bar)) + + Spacer(Modifier.height(10.dp)) + + AddSkillschainBtn() + + mockSkillschains().forEach { + SkillschainCard(skillschain = it) + } + } +} + +@Composable +private fun AddSkillschainBtn(modifier: Modifier = Modifier) { + Button( + onClick = { + //TODO: Add Skillschain + }, + modifier = Modifier.fillMaxWidth(0.9f) + ) { + Icon( + imageVector = Icons.Filled.Add, + contentDescription = "//TODO: Provide" + ) + Text(stringResource(R.string.btn_add_skillschain)) + } +} + +@Composable +fun SkillschainCard(modifier: Modifier = Modifier, skillschain: Skillschain) { + + var open by remember { + mutableStateOf(false) + } + + Card( + Modifier + .fillMaxWidth() + .padding(10.dp) + .background(MaterialTheme.colorScheme.primaryContainer, CircleShape) + ) { + Column { + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween, + ) { + TitleText( + modifier = Modifier.padding(10.dp), + content = skillschain.title + ) + Row( + modifier = Modifier + .padding(10.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Button( + modifier = Modifier + .clip(CircleShape) + .size(50.dp), + contentPadding = PaddingValues(0.dp), + shape = CircleShape, + onClick = { + //TODO: Start Skills Chain + } + ) { + Icon( + imageVector = Icons.Filled.PlayArrow, + contentDescription = "TODO: PROVIDE" + ) + } + + Icon( + modifier = Modifier + .padding(5.dp) + .clickable(onClick = { open = !open }), + imageVector = if (open) Icons.Filled.ArrowDropUp else Icons.Filled.ArrowDropDown, + contentDescription = stringResource(R.string.desc_btn_expand) + ) + } + } + if (open) { + skillschain.skills.forEach { + SkillCard(skill = it) + } + } + } + } +} + +@Composable +fun SkillCard(modifier: Modifier = Modifier, skill: Skill) { + Row( + modifier = Modifier + .fillMaxWidth() + .background(Color.Transparent) + .padding(10.dp) + .background(Color.White, shape = RoundedCornerShape(5.dp)) + .padding(10.dp), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically + ) { + Column( + modifier = Modifier + .fillMaxHeight() + .fillMaxWidth(), + verticalArrangement = Arrangement.SpaceBetween, + + ) { + TitleText(skill.title) + Spacer(modifier = Modifier.height(10.dp)) + DescriptionText(skill.description) + } + } +} \ No newline at end of file diff --git a/DBTApp/app/src/main/java/de/cdaut/dbtapp/components/Texts.kt b/DBTApp/app/src/main/java/de/cdaut/dbtapp/components/Texts.kt index 82d3988..e47c583 100644 --- a/DBTApp/app/src/main/java/de/cdaut/dbtapp/components/Texts.kt +++ b/DBTApp/app/src/main/java/de/cdaut/dbtapp/components/Texts.kt @@ -6,10 +6,8 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.sp @Preview diff --git a/DBTApp/app/src/main/java/de/cdaut/dbtapp/components/Tracking.kt b/DBTApp/app/src/main/java/de/cdaut/dbtapp/components/Tracking.kt new file mode 100644 index 0000000..2f7c12d --- /dev/null +++ b/DBTApp/app/src/main/java/de/cdaut/dbtapp/components/Tracking.kt @@ -0,0 +1,400 @@ +package de.cdaut.dbtapp.components + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.aspectRatio +import androidx.compose.foundation.layout.fillMaxWidth +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.lazy.grid.GridCells +import androidx.compose.foundation.lazy.grid.LazyVerticalGrid +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Add +import androidx.compose.material.icons.filled.CalendarMonth +import androidx.compose.material.icons.filled.ChevronLeft +import androidx.compose.material.icons.filled.ChevronRight +import androidx.compose.material.icons.filled.RemoveRedEye +import androidx.compose.material3.Button +import androidx.compose.material3.Card +import androidx.compose.material3.Checkbox +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.platform.LocalConfiguration +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.em +import de.cdaut.dbtapp.R +import de.cdaut.dbtapp.model.TherapyAssignment +import de.cdaut.dbtapp.model.TherapyAssignment.Companion.mockTherapyAssignments +import de.cdaut.dbtapp.model.Tracker +import de.cdaut.dbtapp.model.Tracker.Companion.mockTrackers +import de.cdaut.dbtapp.util.weekdayListByLocale +import java.time.LocalDate +import java.time.format.DateTimeFormatter +import java.time.format.FormatStyle +import java.time.temporal.WeekFields + +@Preview(device = "id:pixel_6") +@Composable +fun TrackingScreen() { + Column( + modifier = Modifier + .verticalScroll(rememberScrollState()) + .fillMaxWidth() + .background(MaterialTheme.colorScheme.background), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Column( + modifier = Modifier + .fillMaxWidth(0.9f), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Spacer(modifier = Modifier.height(20.dp)) + Card { + TopCalendar() + } + Spacer(modifier = Modifier.height(10.dp)) + Row( + modifier = Modifier + .fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceEvenly + ) { + Button( + onClick = { + //TODO: Add tracker + } + ) { + Icon( + Icons.Filled.Add, + contentDescription = "//TODO: Provide", + tint = MaterialTheme.colorScheme.onPrimary + ) + Text( + text = stringResource(R.string.add_trackter), + style = MaterialTheme.typography.labelLarge, + color = MaterialTheme.colorScheme.onPrimary + ) + } + + Button( + onClick = { + //TODO: View statistics + } + ) { + Text( + modifier = Modifier.padding(horizontal = 5.dp), + text = stringResource(R.string.view_stats), + style = MaterialTheme.typography.labelLarge, + color = MaterialTheme.colorScheme.onPrimary + ) + Icon( + Icons.Filled.RemoveRedEye, + contentDescription = "//TODO: Provide", + tint = MaterialTheme.colorScheme.onPrimary + ) + } + } + Button( + onClick = { + //TODO: Add diary card here + }, + modifier = Modifier.fillMaxWidth(), + ) { + Icon(Icons.Filled.Add, stringResource(R.string.btn_add_diarycard)) + Text(stringResource(R.string.btn_add_diarycard)) + } + Spacer(modifier = Modifier.height(10.dp)) + TitledListCard( + stringResource(R.string.card_therapy_hw_heading), + //cannot eta reduce because + //Function References of @Composable functions are not currently supported + rows = { assignments -> + TherapyAssignmentCardContent(assignments) + }, + addAction = { + //TODO: Add Therapy assignment + }, + items = mockTherapyAssignments() + ) + + Spacer(modifier = Modifier.height(10.dp)) + + TitledListCard( + stringResource(R.string.tracker_card_title), + //cannot eta reduce because + //Function References of @Composable functions are not currently supported + rows = { trackers -> OtherTrackersCardContent(trackers = List(4) { _ -> trackers[0] }) }, + addAction = { + //TODO: Add new tracker + }, + items = mockTrackers() + ) + } + } +} + +@Composable +private fun TopCalendar() { + + var currentDateMut: MutableState = remember { + mutableStateOf(LocalDate.now()) + } + + + Column( + horizontalAlignment = Alignment.CenterHorizontally + ) { + //Top Navigation and display items + Row( + modifier = Modifier + .fillMaxWidth() + .padding(10.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween + ) { + //Header stating the currently selected date + Text( + fontSize = 4.5.em, + text = currentDateMut.value.format( + DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG) + .withLocale(LocalConfiguration.current.locales[0]) + ) + ) + // arrows to switch month + Row( + verticalAlignment = Alignment.CenterVertically + ) { + Icon( + modifier = Modifier + .clip(CircleShape) + .clickable(onClick = { + currentDateMut.value = LocalDate.now() + }), + imageVector = Icons.Filled.CalendarMonth, + contentDescription = "//TODO: Provide" + ) + Spacer(modifier = Modifier.width(10.dp)) + Icon( + modifier = Modifier + .clip(CircleShape) + .clickable(onClick = { + currentDateMut.value = currentDateMut.value.minusMonths(1) + }) + .size(30.dp), + imageVector = Icons.Filled.ChevronLeft, + contentDescription = "TODO: Provide" + ) + + Icon( + modifier = Modifier + .clip(CircleShape) + .clickable(onClick = { + currentDateMut.value = currentDateMut.value.plusMonths(1) + }) + .size(30.dp), + imageVector = Icons.Filled.ChevronRight, + contentDescription = "TODO: Provide" + ) + } + } + + // labels for current day + Row( + modifier = Modifier + .fillMaxWidth() + .padding(10.dp), + horizontalArrangement = Arrangement.SpaceBetween, + ) { + weekdayListByLocale(LocalConfiguration.current.locales[0]).map { label -> + Text( + text = label, + modifier = Modifier.padding(10.dp), + textAlign = TextAlign.Center, + fontWeight = FontWeight.Bold + ) + } + } + + CalendarDaysGrid(currentDateMut) + } +} + +@Composable +private fun CalendarDaysGrid(selectedDateMut: MutableState) { + val locale = LocalConfiguration.current.locales[0] + val selectedDate = selectedDateMut.value + + val firstDayOfMonth = LocalDate.of(selectedDate.year, selectedDate.month, 1) + val totalDaysInMonth = firstDayOfMonth.lengthOfMonth() + val firstDayOfWeek = WeekFields.of(locale).firstDayOfWeek + + //calculate shift required in the beginning + val shift = (firstDayOfMonth.dayOfWeek.value - firstDayOfWeek.value + 7) % 7 + val totalCells = ((shift + totalDaysInMonth + 6) / 7) * 7 + + val days = List(totalCells) { index -> + val dayNumber = index - shift + 1 + if (dayNumber in 1..totalDaysInMonth) dayNumber else null + } + + // Calendar Grid + // FIXME: Something better than a lazy grid would be good because scrolling + LazyVerticalGrid( + columns = GridCells.Fixed(7), + userScrollEnabled = false, + modifier = Modifier + .fillMaxWidth() + .height(320.dp) + ) { + items(days.size) { index -> + days[index]?.let { day -> + + var dayBoxModifier = Modifier + .padding(4.dp) + .clip(CircleShape) + .aspectRatio(1f) + .clickable(onClick = { + selectedDateMut.value = LocalDate.of( + selectedDate.year, + selectedDate.month, + day + ) + }) + .clip(CircleShape) + + //add a mark to the currently selected day + if (day == selectedDate.dayOfMonth) { + dayBoxModifier = dayBoxModifier.border( + 2.dp, + MaterialTheme.colorScheme.onPrimaryContainer, + CircleShape + ) + } + + Box( + modifier = dayBoxModifier, + contentAlignment = Alignment.Center + ) { + Text(text = day.toString()) + } + } + } + } +} + +@Composable +private fun TitledListCard( + title: String, + rows: @Composable Function1, Unit>, + addAction: () -> Unit, + items: List +) { + Card( + modifier = Modifier.fillMaxWidth() + ) { + Column { + Row( + modifier = Modifier + .padding(10.dp) + .fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = title, + style = MaterialTheme.typography.titleMedium + ) + Icon( + modifier = Modifier + .size(30.dp) + .clip(CircleShape) + .clickable(onClick = addAction), + imageVector = Icons.Filled.Add, + contentDescription = "TODO: Provide" + ) + } + HorizontalDivider() + rows(items) + } + } +} + +@Composable +private fun TherapyAssignmentCardContent(assignments: List) { + for (assignment in assignments) { + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween, + ) { + Column { + Text( + modifier = Modifier.padding(horizontal = 10.dp, vertical = 0.dp), + text = assignment.title, + style = MaterialTheme.typography.bodyMedium + ) + Text( + modifier = Modifier.padding(horizontal = 10.dp, vertical = 0.dp), + text = assignment.description, + style = MaterialTheme.typography.bodySmall + ) + } + Checkbox( + onCheckedChange = { + assignment.done = !assignment.done + }, + checked = assignment.done + ) + } + } +} + +@Composable +private fun OtherTrackersCardContent(trackers: List) { + for (tracker in trackers) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(5.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween, + ) { + Column { + Text( + modifier = Modifier.padding(horizontal = 10.dp, vertical = 0.dp), + text = tracker.title, + style = MaterialTheme.typography.bodyMedium + ) + Text( + modifier = Modifier.padding(horizontal = 10.dp, vertical = 0.dp), + text = tracker.description, + style = MaterialTheme.typography.bodySmall + ) + } + } + } +} \ No newline at end of file diff --git a/DBTApp/app/src/main/java/de/cdaut/dbtapp/model/AppDatabase.kt b/DBTApp/app/src/main/java/de/cdaut/dbtapp/model/AppDatabase.kt new file mode 100644 index 0000000..241064d --- /dev/null +++ b/DBTApp/app/src/main/java/de/cdaut/dbtapp/model/AppDatabase.kt @@ -0,0 +1,9 @@ +package de.cdaut.dbtapp.model + +import androidx.room.Database +import androidx.room.RoomDatabase + +@Database(entities = [Skill::class], version = 1) +abstract class AppDatabase : RoomDatabase() { + abstract fun skillDao() : SkillDao +} \ No newline at end of file diff --git a/DBTApp/app/src/main/java/de/cdaut/dbtapp/model/Skill.kt b/DBTApp/app/src/main/java/de/cdaut/dbtapp/model/Skill.kt index 612c86a..23dad64 100644 --- a/DBTApp/app/src/main/java/de/cdaut/dbtapp/model/Skill.kt +++ b/DBTApp/app/src/main/java/de/cdaut/dbtapp/model/Skill.kt @@ -1,24 +1,53 @@ package de.cdaut.dbtapp.model -class Skill(val title: String, val description: String) { +import androidx.room.ColumnInfo +import androidx.room.Dao +import androidx.room.Delete +import androidx.room.Entity +import androidx.room.Insert +import androidx.room.PrimaryKey +import androidx.room.Query +import java.util.UUID + +@Entity +class Skill( + @PrimaryKey val identifier: UUID = UUID.randomUUID(), + @ColumnInfo(name = "title") val title: String, + @ColumnInfo(name = "description") val description: String +) { companion object { fun mockSkills(): List { return listOf( Skill( - title = "Test Hallo :3", - description = "lorem ipsum dolor sid amnet consequetur blabla yada yada" + title = "5-4-3-2-1", + description = "5 sehen, 5 hören, 5 fühlen, 4 sehen, 4 hören…" ), Skill( - title = "5-4-3-2-1", + title = "Skilltitel", description = "Hier kurz beschreiben wie die Übung funktioniert. Ggf. mehrere Zeilen aber nicht super lang" ), - Skill( - title = "UwU UwU awawawa", - description = "Just arf a little like the good fopsgirl you are :3" - ) +// Skill( +// title = "UwU UwU awawawa", +// description = "Just arf a little like the good fopsgirl you are :3" +// ) ) } } +} + +@Dao +interface SkillDao { + @Query("SELECT * FROM Skill") + fun getAll(): List + + @Query("SELECT * FROM Skill WHERE title LIKE :title LIMIT 1") + fun findByName(title: String): Skill + + @Insert + fun insertAll(vararg skills: Skill) + + @Delete + fun delete(skill: Skill) } \ No newline at end of file diff --git a/DBTApp/app/src/main/java/de/cdaut/dbtapp/model/SkillCategory.kt b/DBTApp/app/src/main/java/de/cdaut/dbtapp/model/SkillCategory.kt index c09483a..a81c9c9 100644 --- a/DBTApp/app/src/main/java/de/cdaut/dbtapp/model/SkillCategory.kt +++ b/DBTApp/app/src/main/java/de/cdaut/dbtapp/model/SkillCategory.kt @@ -1,6 +1,5 @@ package de.cdaut.dbtapp.model -import androidx.compose.foundation.layout.Arrangement enum class SkillCategory(val title: String, val skills: List = Skill.mockSkills()) { Mindfulness("Achtsamkeitsübungen"), diff --git a/DBTApp/app/src/main/java/de/cdaut/dbtapp/model/Skillschain.kt b/DBTApp/app/src/main/java/de/cdaut/dbtapp/model/Skillschain.kt new file mode 100644 index 0000000..2b9000f --- /dev/null +++ b/DBTApp/app/src/main/java/de/cdaut/dbtapp/model/Skillschain.kt @@ -0,0 +1,28 @@ +package de.cdaut.dbtapp.model + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.PrimaryKey +import java.util.UUID + +@Entity +class Skillschain( + @PrimaryKey val identifier: UUID = UUID.randomUUID(), + @ColumnInfo(name = "name") val title: String, + @ColumnInfo(name = "skills") val skills: List +) { + companion object { + fun mockSkillschains(): List { + return listOf( + Skillschain( + title = "Skillskette 1", + skills = Skill.mockSkills() + ), + Skillschain( + title = "Skillskette 2", + skills = Skill.mockSkills() + ) + ) + } + } +} \ No newline at end of file diff --git a/DBTApp/app/src/main/java/de/cdaut/dbtapp/model/TherapyAssignment.kt b/DBTApp/app/src/main/java/de/cdaut/dbtapp/model/TherapyAssignment.kt new file mode 100644 index 0000000..f336f48 --- /dev/null +++ b/DBTApp/app/src/main/java/de/cdaut/dbtapp/model/TherapyAssignment.kt @@ -0,0 +1,33 @@ +package de.cdaut.dbtapp.model + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.PrimaryKey +import java.util.UUID + +@Entity +class TherapyAssignment( + @PrimaryKey val identifier: UUID = UUID.randomUUID(), + @ColumnInfo(name = "title") val title: String, + @ColumnInfo(name = "description") val description: String, + @ColumnInfo(name = "done") var done: Boolean +) { + + companion object { + fun mockTherapyAssignments(): List { + return listOf( + TherapyAssignment( + title = "Selbstfürsorge", + description = "Mir selbst eine gute Sache tun", + done = true + ), + TherapyAssignment( + title = "Bedürfnis durchsetzen", + description = "Eine Sache durchsetzen, die mir schwer fällt", + done = false + ) + ) + } + } + +} \ No newline at end of file diff --git a/DBTApp/app/src/main/java/de/cdaut/dbtapp/model/Tracker.kt b/DBTApp/app/src/main/java/de/cdaut/dbtapp/model/Tracker.kt new file mode 100644 index 0000000..4cb59d1 --- /dev/null +++ b/DBTApp/app/src/main/java/de/cdaut/dbtapp/model/Tracker.kt @@ -0,0 +1,26 @@ +package de.cdaut.dbtapp.model + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.PrimaryKey +import java.util.UUID + +@Entity +class Tracker( + @PrimaryKey val identifier: UUID = UUID.randomUUID(), + @ColumnInfo(name = "title") val title: String, + @ColumnInfo(name = "description") val description: String +) { + + companion object { + fun mockTrackers(): List { + return listOf( + Tracker( + title = "Stimmung", + description = "Deine aktuelle Stimmung" + ) + ) + } + } + +} \ No newline at end of file diff --git a/DBTApp/app/src/main/java/de/cdaut/dbtapp/navigation/BottomNavigationItem.kt b/DBTApp/app/src/main/java/de/cdaut/dbtapp/navigation/BottomNavigationItem.kt index 2d3bf49..cc69155 100644 --- a/DBTApp/app/src/main/java/de/cdaut/dbtapp/navigation/BottomNavigationItem.kt +++ b/DBTApp/app/src/main/java/de/cdaut/dbtapp/navigation/BottomNavigationItem.kt @@ -1,15 +1,14 @@ package de.cdaut.dbtapp.navigation -import android.content.Context import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.MenuBook import androidx.compose.material.icons.filled.CalendarToday import androidx.compose.material.icons.filled.Checklist import androidx.compose.material.icons.filled.Home import androidx.compose.material.icons.outlined.Star +import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.platform.LocalContext -import androidx.core.content.ContextCompat.getString +import androidx.compose.ui.res.stringResource import de.cdaut.dbtapp.R data class BottomNavigationItem( @@ -18,34 +17,35 @@ data class BottomNavigationItem( val route: String = "", val idx: Int = 0 ) { - fun bottomNavigationItems(ctx: Context): List { + @Composable + fun bottomNavigationItems(): List { return listOf( BottomNavigationItem( - label = getString(ctx, R.string.label_tracking), + label = stringResource(R.string.label_tracking), icon = Icons.Filled.CalendarToday, route = Screens.Tracking.route, idx = 0 ), BottomNavigationItem( - label = getString(ctx, R.string.label_skillslist), + label = stringResource(R.string.label_skillslist), icon = Icons.AutoMirrored.Filled.MenuBook, route = Screens.Skillslist.route, idx = 1 ), BottomNavigationItem( - label = getString(ctx, R.string.label_home), + label = stringResource(R.string.label_home), icon = Icons.Filled.Home, route = Screens.Home.route, idx = 2 ), BottomNavigationItem( - label = getString(ctx, R.string.label_favourites), + label = stringResource(R.string.label_favourites), icon = Icons.Outlined.Star, route = Screens.Favourites.route, idx = 3 ), BottomNavigationItem( - label = getString(ctx, R.string.label_skillschains), + label = stringResource(R.string.label_skillschains), icon = Icons.Filled.Checklist, route = Screens.Skillschains.route, idx = 4 diff --git a/DBTApp/app/src/main/java/de/cdaut/dbtapp/util/DateHelpers.kt b/DBTApp/app/src/main/java/de/cdaut/dbtapp/util/DateHelpers.kt new file mode 100644 index 0000000..03d52b9 --- /dev/null +++ b/DBTApp/app/src/main/java/de/cdaut/dbtapp/util/DateHelpers.kt @@ -0,0 +1,15 @@ +package de.cdaut.dbtapp.util + +import java.time.DayOfWeek +import java.time.format.TextStyle +import java.time.temporal.WeekFields +import java.util.Locale + +fun weekdayListByLocale(locale: Locale): List { + val listOfDayNames = DayOfWeek.entries.map { it.getDisplayName(TextStyle.NARROW, locale).substring(0, 1) } + val firstDayOfWeek = WeekFields.of(locale).firstDayOfWeek.ordinal + val orderedListOfDayNames = + listOfDayNames.subList(firstDayOfWeek, 7) + listOfDayNames.subList(0, firstDayOfWeek) + + return orderedListOfDayNames +} diff --git a/DBTApp/app/src/main/res/values-de/strings.xml b/DBTApp/app/src/main/res/values-de/strings.xml index e45a695..2f78508 100644 --- a/DBTApp/app/src/main/res/values-de/strings.xml +++ b/DBTApp/app/src/main/res/values-de/strings.xml @@ -8,4 +8,14 @@ Skillsketten Notfallknopf Favorisieren Button + Ausklappen + Diary Card Hinzufügen + Therapiehausaufgaben + Tracker hinzufügen + Statistiken + Tracker + Skill Suchen + Suche Icon + Skillskette Suchen + Skillskette hinzufügen \ No newline at end of file diff --git a/DBTApp/app/src/main/res/values/strings.xml b/DBTApp/app/src/main/res/values/strings.xml index 51849cb..f9a13dd 100644 --- a/DBTApp/app/src/main/res/values/strings.xml +++ b/DBTApp/app/src/main/res/values/strings.xml @@ -7,4 +7,14 @@ Skills Chains Emergency Button Favourte Button + Expand + Add Diary Card + Therapy Assignments + Add Tracker + View Statistics + Trackers + Search Skill + Search Icon + Search Skills Chain + Add Skillschain \ No newline at end of file diff --git a/DBTApp/build.gradle.kts b/DBTApp/build.gradle.kts index b2c8728..8f68b77 100644 --- a/DBTApp/build.gradle.kts +++ b/DBTApp/build.gradle.kts @@ -3,4 +3,5 @@ plugins { alias(libs.plugins.android.application) apply false alias(libs.plugins.kotlin.android) apply false alias(libs.plugins.compose.compiler) apply false + id("com.google.devtools.ksp") version "2.0.21-1.0.27" apply false } \ No newline at end of file diff --git a/DBTApp/gradle/libs.versions.toml b/DBTApp/gradle/libs.versions.toml index b497618..86e7f11 100644 --- a/DBTApp/gradle/libs.versions.toml +++ b/DBTApp/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] activityCompose = "1.10.1" -agp = "8.9.2" +agp = "8.10.1" kotlin = "2.0.21" coreKtx = "1.16.0" junit = "4.13.2" @@ -8,7 +8,10 @@ junitVersion = "1.2.1" espressoCore = "3.6.1" appcompat = "1.7.0" material = "1.12.0" -navigationCompose = "2.7.0-rc01" +navigationCompose = "2.9.0" +roomCompiler = "2.7.1" +roomKtx = "2.7.1" +roomRuntime = "2.7.1" [libraries] androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "activityCompose" } @@ -18,6 +21,9 @@ androidx-material-icons-core = { module = "androidx.compose.material:material-ic androidx-material-icons-extended = { module = "androidx.compose.material:material-icons-extended" } androidx-material3 = { module = "androidx.compose.material3:material3" } androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "navigationCompose" } +androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "roomCompiler" } +androidx-room-ktx = { module = "androidx.room:room-ktx", version.ref = "roomKtx" } +androidx-room-runtime = { module = "androidx.room:room-runtime" } androidx-ui-test-manifest = { module = "androidx.compose.ui:ui-test-manifest" } androidx-ui-test-junit4 = { module = "androidx.compose.ui:ui-test-junit4" } androidx-ui-tooling = { module = "androidx.compose.ui:ui-tooling" } @@ -27,6 +33,7 @@ androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "j androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" } material = { group = "com.google.android.material", name = "material", version.ref = "material" } +room-runtime = { module = "androidx.room:room-runtime", version.ref = "roomRuntime" } [plugins] android-application = { id = "com.android.application", version.ref = "agp" } diff --git a/planning/screenshots/favourites_screen.png b/planning/screenshots/favourites_screen.png new file mode 100644 index 0000000..32d871f Binary files /dev/null and b/planning/screenshots/favourites_screen.png differ diff --git a/planning/screenshots/skillschains_screen.png b/planning/screenshots/skillschains_screen.png new file mode 100644 index 0000000..6f343c3 Binary files /dev/null and b/planning/screenshots/skillschains_screen.png differ diff --git a/planning/screenshots/skillslist.png b/planning/screenshots/skillslist.png new file mode 100644 index 0000000..5f2cf82 Binary files /dev/null and b/planning/screenshots/skillslist.png differ diff --git a/planning/screenshots/tracking_screen.png b/planning/screenshots/tracking_screen.png new file mode 100644 index 0000000..68eb4f1 Binary files /dev/null and b/planning/screenshots/tracking_screen.png differ