diff --git a/petJournal/app/src/main/java/com/soujunior/petjournal/ui/components/Button3.kt b/petJournal/app/src/main/java/com/soujunior/petjournal/ui/components/Button3.kt index f16788c2..d2b37434 100644 --- a/petJournal/app/src/main/java/com/soujunior/petjournal/ui/components/Button3.kt +++ b/petJournal/app/src/main/java/com/soujunior/petjournal/ui/components/Button3.kt @@ -21,6 +21,8 @@ import androidx.compose.ui.draw.shadow import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.dp import ir.kaaveh.sdpcompose.sdp import ir.kaaveh.sdpcompose.ssp @@ -31,6 +33,8 @@ fun Button3( enableButton: Boolean, modifier: Modifier = Modifier, text: String = "Button", + textSize: TextUnit = 12.ssp, + contentPaddingValues : Dp = 12.sdp, buttonColor: ButtonColors = ButtonDefaults.buttonColors(MaterialTheme.colorScheme.background), textColor: Color = MaterialTheme.colorScheme.primary, isLoading: Boolean = false @@ -54,20 +58,20 @@ fun Button3( ) , border = BorderStroke( - width = 2.sdp, + width = 1.sdp, color = Color(0xFF959EA6) ), shape = RoundedCornerShape(size = 50.dp), colors = buttonColor, - contentPadding = PaddingValues(12.sdp) + contentPadding = PaddingValues(contentPaddingValues) ) { if (!isLoading) { Text( text = text, - fontWeight = FontWeight.W900, - fontSize = 12.ssp, - style = MaterialTheme.typography.titleLarge, + fontWeight = FontWeight.W500, + fontSize = textSize, + style = MaterialTheme.typography.headlineLarge, color = textColor ) } else { diff --git a/petJournal/app/src/main/java/com/soujunior/petjournal/ui/components/PetItem.kt b/petJournal/app/src/main/java/com/soujunior/petjournal/ui/components/PetItem.kt index 62e0d0dc..82ef1432 100644 --- a/petJournal/app/src/main/java/com/soujunior/petjournal/ui/components/PetItem.kt +++ b/petJournal/app/src/main/java/com/soujunior/petjournal/ui/components/PetItem.kt @@ -1,6 +1,7 @@ package com.soujunior.petjournal.ui.components import android.widget.ImageView +import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer @@ -13,7 +14,11 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import com.soujunior.petjournal.R import ir.kaaveh.sdpcompose.sdp import ir.kaaveh.sdpcompose.ssp @@ -34,12 +39,21 @@ fun PetItem( shape = RoundedCornerShape(16.sdp), onClick = onClick ) { - GlideImage( - modifier = Modifier.fillMaxSize(), - context = LocalContext.current, - url = imageRes, - scaleType = ImageView.ScaleType.CENTER_CROP - ) + if(!imageRes.isEmpty()) { + GlideImage( + modifier = Modifier.fillMaxSize(), + context = LocalContext.current, + url = imageRes, + scaleType = ImageView.ScaleType.CENTER_CROP + ) + }else{ + //placeholder de imagem vazia + Image( + painter = painterResource(id = R.drawable.image_pet_empty_selected), + contentDescription = "image description", + contentScale = ContentScale.Crop + ) + } } Text( @@ -50,4 +64,10 @@ fun PetItem( ) Spacer(Modifier.padding(bottom = 24.sdp)) } +} + +@Preview +@Composable +private fun previewPetItem(){ + PetItem(modifier = Modifier, imageRes = "", name = "", onClick = {}) } \ No newline at end of file diff --git a/petJournal/app/src/main/java/com/soujunior/petjournal/ui/components/TaskCard.kt b/petJournal/app/src/main/java/com/soujunior/petjournal/ui/components/TaskCard.kt new file mode 100644 index 00000000..ce4084fd --- /dev/null +++ b/petJournal/app/src/main/java/com/soujunior/petjournal/ui/components/TaskCard.kt @@ -0,0 +1,229 @@ +package com.soujunior.petjournal.ui.components + +import androidx.compose.animation.animateContentSize +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.background +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.aspectRatio +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.offset +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.shape.RoundedCornerShape +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +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.graphics.RectangleShape +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.soujunior.petjournal.R +import com.soujunior.petjournal.ui.components.data.TaskData +import com.soujunior.petjournal.ui.components.data.TaskDummyData +import ir.kaaveh.sdpcompose.sdp +import ir.kaaveh.sdpcompose.ssp + +@Composable +fun TaskCard( + taskData: TaskData +) { + var expanded by remember { mutableStateOf(false) } + + Box( + modifier = Modifier.clip(RectangleShape) + ) { + Surface( + shape = RoundedCornerShape(8.sdp), + tonalElevation = 2.dp, + modifier = Modifier + .padding(2.sdp) + .animateContentSize() // Animates the size change + ) { + // Background icon when expanded - outside the Surface + if (expanded) { + Icon( + painter = painterResource(id = taskData.tipo.iconeVector!!), + contentDescription = "Ícone ${taskData.tipo.nome}", + tint = taskData.tipo.cor.copy(alpha = .5f), + modifier = Modifier + .align(Alignment.BottomStart) + .padding(start = 2.sdp, bottom = 42.sdp) + .size(150.sdp) + .offset(x = (-80).dp, y = (70).dp) + ) + } + Column { + // Main content: Title/Date on Start, Description on End + Row( + modifier = Modifier + .fillMaxWidth() + .padding(4.sdp), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.Top + ) { + // Left side: Title and Date + Column( + modifier = Modifier + .padding(horizontal = 8.sdp) + .weight(0.4f), + horizontalAlignment = Alignment.Start + ) { + Text( + text = taskData.titulo, + modifier = Modifier.padding(bottom = 2.sdp), + style = MaterialTheme.typography.titleMedium, + fontSize = 15.ssp + + ) + Text( + text = taskData.dataHora, + style = MaterialTheme.typography.titleMedium, + color = Color.Gray, + fontSize = 10.ssp + ) + + /** + * Vai receber n ids de pets e vai criar a grid com as imagens dos respectivos pets + * */ + if (expanded) { + LazyVerticalGrid( + modifier = Modifier.fillMaxWidth(), + columns = GridCells.Fixed(3), + horizontalArrangement = Arrangement.Start + ) { + items(taskData.pets.size) { index -> + Box(modifier = Modifier.aspectRatio(1f)) { + PetItem(modifier = Modifier, imageRes = "", name = "", onClick = {}) + } + } + } + } + } + + // Right side: Description + Column( + modifier = Modifier + .padding(horizontal = 8.sdp) + .weight(0.6f), + horizontalAlignment = Alignment.Start + ) { + val displayText = if (!expanded && taskData.descricaoResumida.length > 50) { + taskData.descricaoResumida.take(50) + "..." + } else { + taskData.descricaoResumida + } + + Text( + text = displayText, + style = MaterialTheme.typography.titleSmall, + modifier = Modifier + .fillMaxWidth(1f) + .padding(start = 8.sdp) + ) + + if (expanded) { + Text( + text = taskData.descricaoCompleta, + style = MaterialTheme.typography.titleSmall, + modifier = Modifier + .fillMaxWidth(1f) + .padding(start = 8.sdp, top = 8.sdp) + ) + } + } + } + + // Expanded content + if (expanded) { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 8.sdp, top = 16.sdp), + ) { + Button( + onClick = {}, + modifier = Modifier + .width(100.sdp) + .height(25.sdp) + .align(Alignment.CenterHorizontally), + border = BorderStroke( + 1.sdp, Color(0xFF959EA6) + ), + shape = RoundedCornerShape(50.sdp), + colors = ButtonDefaults.buttonColors(MaterialTheme.colorScheme.background) + + ) { + // TODO: AJUSTAR A COR DO BOTÃO PARA A COR DA TAREFA + Text( + text = "Editar Tarefa", + fontSize = 10.ssp, + color = taskData.tipo.cor, + style = MaterialTheme.typography.headlineLarge + ) + } + } + } + + // Bottom section: "Ver Mais" / "Ver Menos" + Box( + modifier = Modifier + .fillMaxWidth() + .background(taskData.tipo.cor) + .clickable { expanded = !expanded } // Toggles the expanded state + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 6.sdp), + horizontalArrangement = Arrangement.Center + ) { + Text( + text = if (expanded) "Ver Menos" else "Ver Mais", + fontSize = 10.ssp, + color = MaterialTheme.colorScheme.background, + style = MaterialTheme.typography.displaySmall + ) + } + } + } + } + + + } +} + +@Preview +@Composable +private fun TaskCardPreview() { + Column(Modifier.padding(8.sdp)) { + TaskCard( + taskData = TaskDummyData.sampleTasks[0] + ) +// TaskCard( +// taskData = TaskDummyData.sampleTasks[1] +// ) +// TaskCard( +// taskData = TaskDummyData.sampleTasks[2] +// ) + } +} diff --git a/petJournal/app/src/main/java/com/soujunior/petjournal/ui/components/data/TaskTypes.kt b/petJournal/app/src/main/java/com/soujunior/petjournal/ui/components/data/TaskTypes.kt new file mode 100644 index 00000000..9e8cfe48 --- /dev/null +++ b/petJournal/app/src/main/java/com/soujunior/petjournal/ui/components/data/TaskTypes.kt @@ -0,0 +1,153 @@ +package com.soujunior.petjournal.ui.components.data + +import androidx.annotation.DrawableRes +import androidx.compose.ui.graphics.Color +import com.soujunior.petjournal.R + +data class TaskType( + val id: String, + val nome: String, + val cor: Color, + @DrawableRes val icone: Int? = null, // Recebe um vetor drawable + @DrawableRes val iconeVector: Int? = null // Recebe um drawable vector +) + +object TaskTypes { + val VACINA = TaskType( + id = "vacina", + nome = "Vacina", + cor = Color(0xFFFA680E), + icone = R.drawable.icone_vacinas, + iconeVector = R.drawable.icone_vacinas_vector + ) + + val CONSULTAS = TaskType( + id = "consultas", + nome = "Consultas", + cor = Color(0xFF20955E), + icone = R.drawable.icone_consulta, + iconeVector = R.drawable.icone_consultas_vector + + ) + + val RACAO = TaskType( + id = "racao", + nome = "Ração", + cor = Color(0xFF881803), + icone = R.drawable.icone_racao, + iconeVector = R.drawable.icone_racao_vector + ) + + val MEDICAMENTOS = TaskType( + id = "medicamentos", + nome = "Medicamentos", + cor = Color(0xFF2F99E5), + icone = R.drawable.icone_medicamento, + iconeVector = R.drawable.icone_medicamentos_vector + + ) + + val BANHOS = TaskType( + id = "banhos", + nome = "Banhos", + cor = Color(0xFFD03A94), + icone = R.drawable.icone_banho, + iconeVector = R.drawable.icone_banhos_vector + + ) + + val PASSEIO = TaskType( + id = "passeio", + nome = "Passeio", + cor = Color(0xFFB78AF7), + icone = R.drawable.icone_passeio, + iconeVector = R.drawable.icone_passeios_vector + + ) + + // Lista com todos os tipos para facilitar iteração + val ALL_TYPES = listOf( + VACINA, + CONSULTAS, + RACAO, + MEDICAMENTOS, + BANHOS, + PASSEIO + ) + + // Função para buscar tipo por ID + fun getTypeById(id: String): TaskType? { + return ALL_TYPES.find { it.id == id } + } + + // Função para buscar tipo por nome + fun getTypeByName(nome: String): TaskType? { + return ALL_TYPES.find { it.nome.equals(nome, ignoreCase = true) } + } +} + +data class PetData( + val id: String, + val imageRes: String = "" // String vazia por enquanto +) + +data class TaskData( + val id: String, + val titulo: String, + val descricaoResumida: String, + val descricaoCompleta: String, + val dataHora: String, + val tipo: TaskType, + val pets: List = emptyList() +) + +// Dados dummy para exemplo/preview +object TaskDummyData { + private val samplePets = listOf( + PetData(id = "pet_001"), + PetData(id = "pet_002"), + PetData(id = "pet_003"), + PetData(id = "pet_004"), + PetData(id = "pet_005"), + PetData(id = "pet_006") + ) + + val sampleTasks = listOf( + TaskData( + id = "1", + titulo = "Carprofeno", + descricaoResumida = "Anti-inflamatorio não esteroide para alivio da dor e inflamação", + descricaoCompleta = "Medicamento anti-inflamatório não esteroide para alívio da dor e inflamação. Deve ser administrado com cuidado e seguindo as instruções veterinárias. Dosagem recomendada conforme peso do animal.", + dataHora = "12/08/2025 - 10:30", + tipo = TaskTypes.MEDICAMENTOS, + pets = listOf(samplePets[0], samplePets[1], samplePets[2]) + ), + TaskData( + id = "2", + titulo = "Vacina Antirrábica", + descricaoResumida = "Vacina obrigatória contra raiva para proteção do pet", + descricaoCompleta = "Vacina antirrábica anual obrigatória. Essencial para proteção contra a raiva e exigida por lei. Deve ser aplicada por veterinário e gera certificado de vacinação.", + dataHora = "15/08/2025 - 14:00", + tipo = TaskTypes.VACINA, + pets = listOf(samplePets[0]) + ), + TaskData( + id = "3", + titulo = "Consulta de Rotina", + descricaoResumida = "Check-up geral para avaliação da saúde do pet", + descricaoCompleta = "Consulta veterinária de rotina para avaliação geral da saúde, verificação de peso, exame físico completo e orientações sobre cuidados preventivos.", + dataHora = "20/08/2025 - 09:15", + tipo = TaskTypes.CONSULTAS, + pets = listOf(samplePets[1], samplePets[3]) + ), + TaskData( + id = "4", + titulo = "Ração Premium", + descricaoResumida = "Trocar para ração premium conforme orientação veterinária", + descricaoCompleta = "Mudança gradual para ração premium de alta qualidade. Fazer transição lenta misturando com a ração atual por 7 dias. Quantidade: 200g por dia dividida em 2 refeições.", + dataHora = "18/08/2025 - 18:00", + tipo = TaskTypes.RACAO, + pets = listOf(samplePets[0], samplePets[2], samplePets[4], samplePets[5]) + ) + ) +} diff --git a/petJournal/app/src/main/java/com/soujunior/petjournal/ui/screens_app/screens_pets/petListScreen/PetListScreen.kt.kt b/petJournal/app/src/main/java/com/soujunior/petjournal/ui/screens_app/screens_pets/petListScreen/PetListScreen.kt similarity index 100% rename from petJournal/app/src/main/java/com/soujunior/petjournal/ui/screens_app/screens_pets/petListScreen/PetListScreen.kt.kt rename to petJournal/app/src/main/java/com/soujunior/petjournal/ui/screens_app/screens_pets/petListScreen/PetListScreen.kt diff --git a/petJournal/app/src/main/java/com/soujunior/petjournal/ui/screens_app/screens_pets/taskListScreen/TaskListScreen.kt b/petJournal/app/src/main/java/com/soujunior/petjournal/ui/screens_app/screens_pets/taskListScreen/TaskListScreen.kt new file mode 100644 index 00000000..f402e532 --- /dev/null +++ b/petJournal/app/src/main/java/com/soujunior/petjournal/ui/screens_app/screens_pets/taskListScreen/TaskListScreen.kt @@ -0,0 +1,10 @@ +package com.soujunior.petjournal.ui.screens_app.screens_pets.taskListScreen + +import androidx.compose.runtime.Composable +import androidx.navigation.NavController +import com.soujunior.petjournal.ui.screens_app.screens_pets.taskListScreen.components.Screen + +@Composable +fun TaskListScreen(navController: NavController) { + Screen(navController) +} \ No newline at end of file diff --git a/petJournal/app/src/main/java/com/soujunior/petjournal/ui/screens_app/screens_pets/taskListScreen/TaskListViewModel.kt b/petJournal/app/src/main/java/com/soujunior/petjournal/ui/screens_app/screens_pets/taskListScreen/TaskListViewModel.kt new file mode 100644 index 00000000..2cc1ec08 --- /dev/null +++ b/petJournal/app/src/main/java/com/soujunior/petjournal/ui/screens_app/screens_pets/taskListScreen/TaskListViewModel.kt @@ -0,0 +1,2 @@ +package com.soujunior.petjournal.ui.screens_app.screens_pets.taskListScreen + diff --git a/petJournal/app/src/main/java/com/soujunior/petjournal/ui/screens_app/screens_pets/taskListScreen/TaskListViewModelImpl.kt b/petJournal/app/src/main/java/com/soujunior/petjournal/ui/screens_app/screens_pets/taskListScreen/TaskListViewModelImpl.kt new file mode 100644 index 00000000..b3cbcbd5 --- /dev/null +++ b/petJournal/app/src/main/java/com/soujunior/petjournal/ui/screens_app/screens_pets/taskListScreen/TaskListViewModelImpl.kt @@ -0,0 +1,4 @@ +package com.soujunior.petjournal.ui.screens_app.screens_pets.taskListScreen + +class TaskListViewModelImpl { +} \ No newline at end of file diff --git a/petJournal/app/src/main/java/com/soujunior/petjournal/ui/screens_app/screens_pets/taskListScreen/components/Screen.kt b/petJournal/app/src/main/java/com/soujunior/petjournal/ui/screens_app/screens_pets/taskListScreen/components/Screen.kt new file mode 100644 index 00000000..34cce820 --- /dev/null +++ b/petJournal/app/src/main/java/com/soujunior/petjournal/ui/screens_app/screens_pets/taskListScreen/components/Screen.kt @@ -0,0 +1,9 @@ +package com.soujunior.petjournal.ui.screens_app.screens_pets.taskListScreen.components + +import androidx.compose.runtime.Composable +import androidx.navigation.NavController + +@Composable +fun Screen(navController: NavController){ + +} \ No newline at end of file diff --git a/petJournal/app/src/main/res/drawable/icone_banho.png b/petJournal/app/src/main/res/drawable/icone_banho.png new file mode 100644 index 00000000..85b6e0b8 Binary files /dev/null and b/petJournal/app/src/main/res/drawable/icone_banho.png differ diff --git a/petJournal/app/src/main/res/drawable/icone_banhos_vector.xml b/petJournal/app/src/main/res/drawable/icone_banhos_vector.xml new file mode 100644 index 00000000..16052616 --- /dev/null +++ b/petJournal/app/src/main/res/drawable/icone_banhos_vector.xml @@ -0,0 +1,9 @@ + + + diff --git a/petJournal/app/src/main/res/drawable/icone_consulta.png b/petJournal/app/src/main/res/drawable/icone_consulta.png new file mode 100644 index 00000000..a8cb8b9c Binary files /dev/null and b/petJournal/app/src/main/res/drawable/icone_consulta.png differ diff --git a/petJournal/app/src/main/res/drawable/icone_consultas_vector.xml b/petJournal/app/src/main/res/drawable/icone_consultas_vector.xml new file mode 100644 index 00000000..d26b9e7a --- /dev/null +++ b/petJournal/app/src/main/res/drawable/icone_consultas_vector.xml @@ -0,0 +1,13 @@ + + + diff --git a/petJournal/app/src/main/res/drawable/icone_medicamento.png b/petJournal/app/src/main/res/drawable/icone_medicamento.png new file mode 100644 index 00000000..325fa4f7 Binary files /dev/null and b/petJournal/app/src/main/res/drawable/icone_medicamento.png differ diff --git a/petJournal/app/src/main/res/drawable/icone_medicamentos_vector.xml b/petJournal/app/src/main/res/drawable/icone_medicamentos_vector.xml new file mode 100644 index 00000000..9f136be3 --- /dev/null +++ b/petJournal/app/src/main/res/drawable/icone_medicamentos_vector.xml @@ -0,0 +1,24 @@ + + + + + diff --git a/petJournal/app/src/main/res/drawable/icone_passeio.png b/petJournal/app/src/main/res/drawable/icone_passeio.png new file mode 100644 index 00000000..32e3ae1c Binary files /dev/null and b/petJournal/app/src/main/res/drawable/icone_passeio.png differ diff --git a/petJournal/app/src/main/res/drawable/icone_passeios_vector.xml b/petJournal/app/src/main/res/drawable/icone_passeios_vector.xml new file mode 100644 index 00000000..c8c5cd02 --- /dev/null +++ b/petJournal/app/src/main/res/drawable/icone_passeios_vector.xml @@ -0,0 +1,11 @@ + + + diff --git a/petJournal/app/src/main/res/drawable/icone_racao.png b/petJournal/app/src/main/res/drawable/icone_racao.png new file mode 100644 index 00000000..a58289f1 Binary files /dev/null and b/petJournal/app/src/main/res/drawable/icone_racao.png differ diff --git a/petJournal/app/src/main/res/drawable/icone_racao_vector.xml b/petJournal/app/src/main/res/drawable/icone_racao_vector.xml new file mode 100644 index 00000000..3b46755b --- /dev/null +++ b/petJournal/app/src/main/res/drawable/icone_racao_vector.xml @@ -0,0 +1,9 @@ + + + diff --git a/petJournal/app/src/main/res/drawable/icone_vacinas.png b/petJournal/app/src/main/res/drawable/icone_vacinas.png new file mode 100644 index 00000000..df84cfdf Binary files /dev/null and b/petJournal/app/src/main/res/drawable/icone_vacinas.png differ diff --git a/petJournal/app/src/main/res/drawable/icone_vacinas_vector.xml b/petJournal/app/src/main/res/drawable/icone_vacinas_vector.xml new file mode 100644 index 00000000..f1e11706 --- /dev/null +++ b/petJournal/app/src/main/res/drawable/icone_vacinas_vector.xml @@ -0,0 +1,13 @@ + + +