From 411b4923877f10ebd3d0572df1a0eeddf5d2abb9 Mon Sep 17 00:00:00 2001
From: Sofiia-Khrystyna <sonia030605@gmail.com>
Date: Wed, 15 Jan 2025 15:32:12 +0100
Subject: [PATCH 01/10] Styling of the add appointment screen

---
 .../java/at/ac/fhstp/pawwatch/Navigation.kt   |  2 +-
 .../fhstp/pawwatch/ui/AddAppointmentScreen.kt | 59 +++++++++++++------
 ...tailScreen.kt => AllAppointmentsScreen.kt} |  0
 .../at/ac/fhstp/pawwatch/ui/theme/Color.kt    |  1 +
 .../at/ac/fhstp/pawwatch/ui/theme/Theme.kt    |  2 +-
 .../at/ac/fhstp/pawwatch/ui/theme/Type.kt     |  2 +-
 6 files changed, 46 insertions(+), 20 deletions(-)
 rename app/src/main/java/at/ac/fhstp/pawwatch/ui/{AppointmentDetailScreen.kt => AllAppointmentsScreen.kt} (100%)

diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/Navigation.kt b/app/src/main/java/at/ac/fhstp/pawwatch/Navigation.kt
index 584bf57..055f735 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/Navigation.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/Navigation.kt
@@ -52,7 +52,7 @@ fun BottomNavigationBar(navController: NavController) {
             selected = currentRoute == Screens.AddAppointment.route,
             onClick = { navController.navigate(Screens.AddAppointment.route) },
             icon = { Icon(Icons.Filled.Add, contentDescription = "Add Appointment") },
-            label = { Text("Add Appointment") }
+            label = { Text("Add") }
         )
         NavigationBarItem(
             selected = currentRoute == Screens.Overview.route,
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AddAppointmentScreen.kt b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AddAppointmentScreen.kt
index 729b76d..d0f6642 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AddAppointmentScreen.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AddAppointmentScreen.kt
@@ -23,7 +23,7 @@ fun AddAppointmentScreen(
     navController: NavController
 ) {
     // Collect the appointments as a state
-    val appointments by viewModel.appointments.collectAsState()
+    //val appointments by viewModel.appointments.collectAsState()
 
     // Store the selected appointment date
     var selectedAppointmentDate by remember { mutableStateOf<Long?>(null) }
@@ -37,9 +37,10 @@ fun AddAppointmentScreen(
 
     Column(
         modifier = Modifier
-            .fillMaxWidth()
+            .fillMaxSize()
             .padding(35.dp),
-        horizontalAlignment = Alignment.CenterHorizontally
+        horizontalAlignment = Alignment.CenterHorizontally,
+        verticalArrangement = Arrangement.Center
     ) {
         Spacer(modifier = Modifier.height(10.dp))
 
@@ -48,12 +49,13 @@ fun AddAppointmentScreen(
             style = MaterialTheme.typography.headlineMedium
         )
 
-        Spacer(modifier = Modifier.height(25.dp))
+        Spacer(modifier = Modifier.height(45.dp))
 
         Text(
             text = "Pet Name:",
             modifier = Modifier.align(Alignment.Start)
         )
+        Spacer(modifier = Modifier.height(5.dp))
 
         OutlinedTextField(
             value = petName.value,
@@ -62,14 +64,21 @@ fun AddAppointmentScreen(
             colors = TextFieldDefaults.outlinedTextFieldColors(
                 containerColor = MaterialTheme.colorScheme.secondary
             ),
-            textStyle = MaterialTheme.typography.bodyMedium
+            textStyle = MaterialTheme.typography.bodyMedium,
+            placeholder = {
+                Text(
+                    text = "Enter your pet name, e.g. Cupcake",
+                    style = MaterialTheme.typography.bodyMedium
+                )
+            }
         )
-        Spacer(modifier = Modifier.height(16.dp))
+        Spacer(modifier = Modifier.height(20.dp))
 
         Text(
             text = "Appointment Category:",
             modifier = Modifier.align(Alignment.Start)
         )
+        Spacer(modifier = Modifier.height(5.dp))
 
         OutlinedTextField(
             value = category.value,
@@ -78,14 +87,21 @@ fun AddAppointmentScreen(
             colors = TextFieldDefaults.outlinedTextFieldColors(
                 containerColor = MaterialTheme.colorScheme.secondary
             ),
-            textStyle = MaterialTheme.typography.bodyMedium
+            textStyle = MaterialTheme.typography.bodyMedium,
+            placeholder = {
+                Text(
+                    text = "Select a category, e.g. Grooming",
+                    style = MaterialTheme.typography.bodyMedium
+                )
+            }
         )
-        Spacer(modifier = Modifier.height(16.dp))
+        Spacer(modifier = Modifier.height(20.dp))
 
         Text(
-            text = "Description:",
+            text = "Description (Optional):",
             modifier = Modifier.align(Alignment.Start)
         )
+        Spacer(modifier = Modifier.height(5.dp))
 
         OutlinedTextField(
             value = description.value,
@@ -94,9 +110,15 @@ fun AddAppointmentScreen(
             colors = TextFieldDefaults.outlinedTextFieldColors(
                 containerColor = MaterialTheme.colorScheme.secondary
             ),
-            textStyle = MaterialTheme.typography.bodyMedium
+            textStyle = MaterialTheme.typography.bodyMedium,
+            placeholder = {
+                Text(
+                    text = "Enter a description, e.g. address, phone number",
+                    style = MaterialTheme.typography.bodyMedium
+                )
+            }
         )
-        Spacer(modifier = Modifier.height(16.dp))
+        Spacer(modifier = Modifier.height(20.dp))
 
 
         if (showDatePicker) {
@@ -111,10 +133,12 @@ fun AddAppointmentScreen(
 
         OutlinedButton(
             onClick = { showDatePicker = true },
+            modifier = Modifier.fillMaxWidth(),
             colors = ButtonDefaults.buttonColors(
-                containerColor = MaterialTheme.colorScheme.primary,
+                containerColor = MaterialTheme.colorScheme.tertiary,
                 contentColor = MaterialTheme.colorScheme.onPrimary
-            )
+            ),
+            elevation = ButtonDefaults.elevatedButtonElevation(defaultElevation = 4.dp)
         ) {
             Text(
                 text = "Select Appointment Date",
@@ -127,17 +151,17 @@ fun AddAppointmentScreen(
         selectedAppointmentDate?.let {
             val dateString = DateFormat.getDateInstance().format(Date(it))
             Text(
-                text = "Selected Appointment Date: $dateString",
+                text = "Selected Date: $dateString",
                 modifier = Modifier.padding(2.dp),
                 style = MaterialTheme.typography.labelMedium
             )
         }
 
-        Spacer(modifier = Modifier.height(22.dp))
+        Spacer(modifier = Modifier.height(40.dp))
 
         // Button to submit new appointment
         OutlinedButton(
-            modifier = Modifier.fillMaxWidth(),
+            modifier = Modifier.width(200.dp),
             colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.primary),
             onClick = {
                 if (petName.value.isNotBlank() && selectedAppointmentDate != null) {
@@ -155,7 +179,8 @@ fun AddAppointmentScreen(
                         category.value
                     )
                 }
-            }
+            },
+            elevation = ButtonDefaults.elevatedButtonElevation(defaultElevation = 3.dp)
         ) {
             Text(
                 text = "Add Appointment",
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentDetailScreen.kt b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AllAppointmentsScreen.kt
similarity index 100%
rename from app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentDetailScreen.kt
rename to app/src/main/java/at/ac/fhstp/pawwatch/ui/AllAppointmentsScreen.kt
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/ui/theme/Color.kt b/app/src/main/java/at/ac/fhstp/pawwatch/ui/theme/Color.kt
index 45ca9f5..13f9b18 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/ui/theme/Color.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/ui/theme/Color.kt
@@ -4,6 +4,7 @@ import androidx.compose.ui.graphics.Color
 
 val bg = Color(0xFFFDE9C3)
 val buttonBg = Color(0xFFFFBA66)
+val lightButtonBg = Color(0xFFFFCE93)
 val text = Color(0xFF000000)
 val fieldBg = Color(0xFFFFF4DE)
 val deleteButtonBg = Color(0xFFbf4342)
\ No newline at end of file
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/ui/theme/Theme.kt b/app/src/main/java/at/ac/fhstp/pawwatch/ui/theme/Theme.kt
index cc6be4e..c6c272e 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/ui/theme/Theme.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/ui/theme/Theme.kt
@@ -3,13 +3,13 @@ package at.ac.fhstp.pawwatch.ui.theme
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.lightColorScheme
 import androidx.compose.runtime.Composable
-import androidx.compose.ui.graphics.Color
 
 private val AppColorScheme = lightColorScheme(
     background = bg,
     primary = buttonBg,
     onPrimary = text,
     secondary = fieldBg,
+    tertiary = lightButtonBg,
     error = deleteButtonBg
 )
 
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/ui/theme/Type.kt b/app/src/main/java/at/ac/fhstp/pawwatch/ui/theme/Type.kt
index b6a201e..0b00793 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/ui/theme/Type.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/ui/theme/Type.kt
@@ -44,7 +44,7 @@ val Typography = Typography(
     labelMedium = TextStyle(
         fontFamily = FontFamily.Default,
         fontWeight = FontWeight.Bold,
-        fontSize = 15.sp,
+        fontSize = 17.sp,
         lineHeight = 24.sp,
         letterSpacing = 0.5.sp
     )
-- 
GitLab


From 1388e635f9a5b17acc4ec990ac8ada22c95c552f Mon Sep 17 00:00:00 2001
From: Sofiia-Khrystyna <sonia030605@gmail.com>
Date: Wed, 15 Jan 2025 15:39:55 +0100
Subject: [PATCH 02/10] test test

---
 .../main/java/at/ac/fhstp/pawwatch/ui/AddAppointmentScreen.kt    | 1 -
 1 file changed, 1 deletion(-)

diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AddAppointmentScreen.kt b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AddAppointmentScreen.kt
index d0f6642..e05a906 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AddAppointmentScreen.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AddAppointmentScreen.kt
@@ -219,7 +219,6 @@ fun CustomDatePickerDialog(
                             }
                             this.date = calendar.timeInMillis
 
-
                             setOnDateChangeListener { _, year, month, dayOfMonth ->
                                 calendar.set(year, month, dayOfMonth)
                                 onDateSelected(calendar.timeInMillis)
-- 
GitLab


From b74ef836b7ddc79367500139aabd30b73fb4785c Mon Sep 17 00:00:00 2001
From: Sofiia-Khrystyna <sonia030605@gmail.com>
Date: Wed, 15 Jan 2025 19:57:48 +0100
Subject: [PATCH 03/10] :zap:added time picker, but the time is shown in the
 wrong way with PM or AM

---
 .../java/at/ac/fhstp/pawwatch/MainActivity.kt |   4 +-
 .../pawwatch/data/AppointmentRepository.kt    |   2 +
 .../fhstp/pawwatch/data/db/AppointmentDao.kt  |   4 +-
 .../pawwatch/data/db/AppointmentDatabase.kt   |   3 +-
 .../pawwatch/data/db/AppointmentEntity.kt     |   1 +
 .../fhstp/pawwatch/ui/AddAppointmentScreen.kt | 180 +++++++++++++++---
 .../pawwatch/ui/AppointmentEditScreen.kt      |   3 +-
 .../fhstp/pawwatch/ui/AppointmentViewModel.kt |   8 +-
 8 files changed, 169 insertions(+), 36 deletions(-)

diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/MainActivity.kt b/app/src/main/java/at/ac/fhstp/pawwatch/MainActivity.kt
index 01ee352..7337ab0 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/MainActivity.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/MainActivity.kt
@@ -62,9 +62,9 @@ class MainActivity : ComponentActivity() {
                                         )
                                         navController.navigate(route)
                                     },
-                                    onAddAppointmentClick = { petName, description, date, category ->
+                                    onAddAppointmentClick = { petName, description, date, time, category ->
                                         // Add a new appointment via the ViewModel
-                                        viewModel.addAppointment(petName, description, date, category)
+                                        viewModel.addAppointment(petName, description, date, time, category)
                                         // Navigate back to the overview screen
                                         navController.popBackStack()
                                     },
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/data/AppointmentRepository.kt b/app/src/main/java/at/ac/fhstp/pawwatch/data/AppointmentRepository.kt
index f550e33..ebe0045 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/data/AppointmentRepository.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/data/AppointmentRepository.kt
@@ -22,6 +22,7 @@ class AppointmentRepository(private val taskDao: AppointmentDao) {
         petName: String,
         description: String,
         appointmentDate: Long,
+        appointmentTime: Long,
         category: String
     ) {
         taskDao.updateAppointment(
@@ -29,6 +30,7 @@ class AppointmentRepository(private val taskDao: AppointmentDao) {
             petName,
             description,
             appointmentDate,
+            appointmentTime,
             category
         )
     }
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/data/db/AppointmentDao.kt b/app/src/main/java/at/ac/fhstp/pawwatch/data/db/AppointmentDao.kt
index d9e0309..c1a24a9 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/data/db/AppointmentDao.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/data/db/AppointmentDao.kt
@@ -3,6 +3,7 @@ package at.ac.fhstp.pawwatch.data.db
 import androidx.room.Dao
 import androidx.room.Insert
 import androidx.room.Query
+import java.sql.Time
 
 @Dao
 interface AppointmentDao {
@@ -16,12 +17,13 @@ interface AppointmentDao {
     @Query("DELETE FROM appointment_table WHERE id = :appointmentId")
     suspend fun deleteAppointmentById(appointmentId: Long)
 
-    @Query("UPDATE appointment_table SET petName = :petName, description = :description, appointmentDate = :appointmentDate, category = :category WHERE id = :appointmentId")
+    @Query("UPDATE appointment_table SET petName = :petName, description = :description, appointmentDate = :appointmentDate, appointmentTime = :appointmentTime, category = :category WHERE id = :appointmentId")
     suspend fun updateAppointment(
         appointmentId: Long,
         petName: String,
         description: String,
         appointmentDate: Long,
+        appointmentTime: Long,
         category: String
     )
 
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/data/db/AppointmentDatabase.kt b/app/src/main/java/at/ac/fhstp/pawwatch/data/db/AppointmentDatabase.kt
index 169f89e..37a8456 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/data/db/AppointmentDatabase.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/data/db/AppointmentDatabase.kt
@@ -5,7 +5,7 @@ import androidx.room.Database
 import androidx.room.Room
 import androidx.room.RoomDatabase
 
-@Database(entities = [AppointmentEntity::class], version = 2)
+@Database(entities = [AppointmentEntity::class], version = 3)
 abstract class AppointmentDatabase : RoomDatabase() {
     abstract fun appointmentDao() : AppointmentDao
 
@@ -24,6 +24,5 @@ abstract class AppointmentDatabase : RoomDatabase() {
                 return tempInstance
             }
         }
-
     }
 }
\ No newline at end of file
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/data/db/AppointmentEntity.kt b/app/src/main/java/at/ac/fhstp/pawwatch/data/db/AppointmentEntity.kt
index 586a57a..f03f720 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/data/db/AppointmentEntity.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/data/db/AppointmentEntity.kt
@@ -10,5 +10,6 @@ data class AppointmentEntity(
     val petName: String,
     val description: String,
     val appointmentDate: Long,
+    val appointmentTime: Long,
     val category: String
 )
\ No newline at end of file
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AddAppointmentScreen.kt b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AddAppointmentScreen.kt
index e05a906..c3fed99 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AddAppointmentScreen.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AddAppointmentScreen.kt
@@ -1,6 +1,7 @@
 package at.ac.fhstp.pawwatch.ui
 
 import android.widget.CalendarView
+import android.widget.NumberPicker
 import androidx.compose.foundation.layout.*
 import androidx.compose.material3.*
 import androidx.compose.runtime.*
@@ -19,7 +20,7 @@ import java.util.*
 fun AddAppointmentScreen(
     viewModel: AppointmentViewModel,
     onAppointmentClick: (AppointmentEntity) -> Unit,
-    onAddAppointmentClick: (String, String, Long, String) -> Unit,
+    onAddAppointmentClick: (String, String, Long, Long, String) -> Unit,
     navController: NavController
 ) {
     // Collect the appointments as a state
@@ -27,6 +28,7 @@ fun AddAppointmentScreen(
 
     // Store the selected appointment date
     var selectedAppointmentDate by remember { mutableStateOf<Long?>(null) }
+    var selectedAppointmentTime by remember { mutableStateOf<Long?>(null) }
 
     // DatePicker Dialog state
     var showDatePicker by remember { mutableStateOf(false) }
@@ -124,6 +126,7 @@ fun AddAppointmentScreen(
         if (showDatePicker) {
             CustomDatePickerDialog(
                 selectedDate = selectedAppointmentDate, // Pass the previously selected date
+
                 onDismiss = { showDatePicker = false },
                 onDateSelected = { date ->
                     selectedAppointmentDate = date // Update the selected date
@@ -149,9 +152,9 @@ fun AddAppointmentScreen(
         // for displaying the selected appointment date below the button
         Spacer(modifier = Modifier.height(8.dp))
         selectedAppointmentDate?.let {
-            val dateString = DateFormat.getDateInstance().format(Date(it))
+            val dateTimeString = DateFormat.getDateTimeInstance().format(Date(it))
             Text(
-                text = "Selected Date: $dateString",
+                text = "Selected Date and Time: $dateTimeString",
                 modifier = Modifier.padding(2.dp),
                 style = MaterialTheme.typography.labelMedium
             )
@@ -176,6 +179,7 @@ fun AddAppointmentScreen(
                         petName.value,
                         description.value,
                         selectedAppointmentDate!!,
+                        selectedAppointmentTime!!,
                         category.value
                     )
                 }
@@ -189,6 +193,59 @@ fun AddAppointmentScreen(
         }
     }
 }
+//
+//@Composable
+//fun CustomDatePickerDialog(
+//    onDismiss: () -> Unit,
+//    selectedDate: Long?, // Pass the currently selected date
+//    onDateSelected: (Long) -> Unit
+//) {
+//    val calendar = Calendar.getInstance(Locale.getDefault()).apply {
+//        firstDayOfWeek = Calendar.MONDAY
+//    }
+//
+//    Dialog(onDismissRequest = onDismiss) {
+//        Surface(
+//            shape = MaterialTheme.shapes.medium,
+//            tonalElevation = 8.dp
+//        ) {
+//            Column(
+//                modifier = Modifier.padding(16.dp)
+//            ) {
+//                AndroidView(
+//                    factory = { context ->
+//                        CalendarView(context).apply {
+//                            this.firstDayOfWeek = Calendar.MONDAY
+//
+//                            // Set the calendar to the selected date or today's date
+//                            if (selectedDate != null) {
+//                                calendar.timeInMillis = selectedDate
+//                            }
+//                            this.date = calendar.timeInMillis
+//
+//                            setOnDateChangeListener { _, year, month, dayOfMonth ->
+//                                calendar.set(year, month, dayOfMonth)
+//                                onDateSelected(calendar.timeInMillis)
+//                                onDismiss() // Close the dialog after selecting a date
+//                            }
+//                        }
+//                    },
+//                    modifier = Modifier.wrapContentHeight()
+//                )
+//
+//                Spacer(modifier = Modifier.height(16.dp))
+//
+//                Button(
+//                    onClick = onDismiss,
+//                    modifier = Modifier.align(Alignment.End)
+//                ) {
+//                    Text("Cancel")
+//                }
+//            }
+//        }
+//    }
+//}
+
 
 @Composable
 fun CustomDatePickerDialog(
@@ -200,6 +257,11 @@ fun CustomDatePickerDialog(
         firstDayOfWeek = Calendar.MONDAY
     }
 
+    // Time selection state
+    var showTimePicker by remember { mutableStateOf(false) }
+    var selectedHour by remember { mutableIntStateOf(12) } // Default hour
+    var selectedMinute by remember { mutableIntStateOf(0) } // Default minute
+
     Dialog(onDismissRequest = onDismiss) {
         Surface(
             shape = MaterialTheme.shapes.medium,
@@ -208,34 +270,100 @@ fun CustomDatePickerDialog(
             Column(
                 modifier = Modifier.padding(16.dp)
             ) {
-                AndroidView(
-                    factory = { context ->
-                        CalendarView(context).apply {
-                            this.firstDayOfWeek = Calendar.MONDAY
-
-                            // Set the calendar to the selected date or today's date
-                            if (selectedDate != null) {
-                                calendar.timeInMillis = selectedDate
+                if (!showTimePicker) {
+                    // Calendar View
+                    AndroidView(
+                        factory = { context ->
+                            CalendarView(context).apply {
+                                this.firstDayOfWeek = Calendar.MONDAY
+
+                                // Set the calendar to the selected date or today's date
+                                if (selectedDate != null) {
+                                    calendar.timeInMillis = selectedDate
+                                }
+                                this.date = calendar.timeInMillis
+
+                                setOnDateChangeListener { _, year, month, dayOfMonth ->
+                                    calendar.set(year, month, dayOfMonth)
+                                    showTimePicker = true // Show time picker after date selection
+                                }
                             }
-                            this.date = calendar.timeInMillis
+                        },
+                        modifier = Modifier.wrapContentHeight()
+                    )
+
+                    Spacer(modifier = Modifier.height(16.dp))
+
+                    Button(
+                        onClick = onDismiss,
+                        modifier = Modifier.align(Alignment.End)
+                    ) {
+                        Text("Cancel")
+                    }
+                } else {
+                    // Time Picker
+                    Text("Select Time", style = MaterialTheme.typography.bodyLarge)
+                    Spacer(modifier = Modifier.height(16.dp))
+
+                    Row(
+                        verticalAlignment = Alignment.CenterVertically,
+                        horizontalArrangement = Arrangement.SpaceEvenly,
+                        modifier = Modifier.fillMaxWidth()
+                    ) {
+                        // Hour Picker
+                        AndroidView(
+                            factory = { context ->
+                                NumberPicker(context).apply {
+                                    minValue = 0
+                                    maxValue = 23
+                                    value = selectedHour
+                                    setOnValueChangedListener { _, _, newValue ->
+                                        selectedHour = newValue
+                                    }
+                                }
+                            },
+                            modifier = Modifier.wrapContentHeight()
+                        )
 
-                            setOnDateChangeListener { _, year, month, dayOfMonth ->
-                                calendar.set(year, month, dayOfMonth)
+                        // Minute Picker
+                        AndroidView(
+                            factory = { context ->
+                                NumberPicker(context).apply {
+                                    minValue = 0
+                                    maxValue = 59
+                                    value = selectedMinute
+                                    setOnValueChangedListener { _, _, newValue ->
+                                        selectedMinute = newValue
+                                    }
+                                }
+                            },
+                            modifier = Modifier.wrapContentHeight()
+                        )
+                    }
+
+                    Spacer(modifier = Modifier.height(16.dp))
+
+                    Row(
+                        modifier = Modifier.fillMaxWidth(),
+                        horizontalArrangement = Arrangement.SpaceBetween
+                    ) {
+                        Button(onClick = { showTimePicker = false }) {
+                            Text("Back")
+                        }
+                        Button(
+                            onClick = {
+                                calendar.set(Calendar.HOUR_OF_DAY, selectedHour)
+                                calendar.set(Calendar.MINUTE, selectedMinute)
+                                calendar.set(Calendar.SECOND, 0)
+
+                                // Pass the selected date and time
                                 onDateSelected(calendar.timeInMillis)
-                                onDismiss() // Close the dialog after selecting a date
+                                onDismiss()
                             }
+                        ) {
+                            Text("OK")
                         }
-                    },
-                    modifier = Modifier.wrapContentHeight()
-                )
-
-                Spacer(modifier = Modifier.height(16.dp))
-
-                Button(
-                    onClick = onDismiss,
-                    modifier = Modifier.align(Alignment.End)
-                ) {
-                    Text("Cancel")
+                    }
                 }
             }
         }
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentEditScreen.kt b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentEditScreen.kt
index bda19e3..3cafe06 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentEditScreen.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentEditScreen.kt
@@ -24,6 +24,7 @@ fun AppointmentEditScreen(
     var petName by remember { mutableStateOf(appointment?.petName ?: "") }
     var description by remember { mutableStateOf(appointment?.description ?: "") }
     var appointmentDate by remember { mutableLongStateOf(appointment?.appointmentDate ?: System.currentTimeMillis()) }
+    var appointmentTime by remember { mutableLongStateOf(appointment?.appointmentTime ?: System.currentTimeMillis()) }
     var category by remember { mutableStateOf(appointment?.category ?: "") }
 
     var showDatePicker by remember { mutableStateOf(false) }
@@ -142,7 +143,7 @@ fun AppointmentEditScreen(
         OutlinedButton(
             onClick = {
                 if (petName.isNotBlank() && description.isNotBlank()) {
-                    viewModel.editAppointment(appointmentId!!.toLong(), petName, description, appointmentDate, category)
+                    viewModel.editAppointment(appointmentId!!.toLong(), petName, description, appointmentDate, appointmentTime, category)
                     navController.navigateUp()
                 }
             },
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentViewModel.kt b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentViewModel.kt
index 74c1192..463d901 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentViewModel.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentViewModel.kt
@@ -33,8 +33,8 @@ class AppointmentViewModel(private val appointmentRepository: AppointmentReposit
     }
 
     // Add a new appointment
-    fun addAppointment(petName: String, description: String, appointmentDate: Long, category: String) {
-        val appointment = AppointmentEntity(petName = petName, description = description, appointmentDate = appointmentDate, category = category)
+    fun addAppointment(petName: String, description: String, appointmentDate: Long, appointmentTime: Long, category: String) {
+        val appointment = AppointmentEntity(petName = petName, description = description, appointmentDate = appointmentDate, appointmentTime = appointmentTime, category = category)
         viewModelScope.launch {
             appointmentRepository.insertAppointment(appointment)
             loadAppointments()  // Reload appointments from the repository to update the list
@@ -58,9 +58,9 @@ class AppointmentViewModel(private val appointmentRepository: AppointmentReposit
         }
     }
 
-    fun editAppointment(appointmentId: Long, petName: String, description: String, appointmentDate: Long, category: String) {
+    fun editAppointment(appointmentId: Long, petName: String, description: String, appointmentDate: Long, appointmentTime: Long, category: String) {
         viewModelScope.launch {
-            appointmentRepository.updateAppointment(appointmentId, petName, description, appointmentDate, category)
+            appointmentRepository.updateAppointment(appointmentId, petName, description, appointmentDate, appointmentTime, category)
             loadAppointments()  // Refresh the appointment list
         }
     }
-- 
GitLab


From 907082eb7db320840b556e990c4edc624d6e62f1 Mon Sep 17 00:00:00 2001
From: Sofiia-Khrystyna <sonia030605@gmail.com>
Date: Fri, 17 Jan 2025 10:40:55 +0100
Subject: [PATCH 04/10] :zap:added time picker, but the time is shown with
 offset of 1 hour

---
 app/build.gradle.kts                          |   1 +
 .../java/at/ac/fhstp/pawwatch/Navigation.kt   |  11 +-
 .../fhstp/pawwatch/ui/AddAppointmentScreen.kt | 117 ++++++------------
 ...tsScreen.kt => AppointmentDetailScreen.kt} |  11 +-
 .../pawwatch/ui/AppointmentEditScreen.kt      |  93 +++++++++++---
 .../at/ac/fhstp/pawwatch/ui/theme/Type.kt     |   8 ++
 gradle/libs.versions.toml                     |   4 +
 7 files changed, 145 insertions(+), 100 deletions(-)
 rename app/src/main/java/at/ac/fhstp/pawwatch/ui/{AllAppointmentsScreen.kt => AppointmentDetailScreen.kt} (89%)

diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index dba15af..438742f 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -73,4 +73,5 @@ dependencies {
     androidTestImplementation(libs.androidx.ui.test.junit4)
     debugImplementation(libs.androidx.ui.tooling)
     debugImplementation(libs.androidx.ui.test.manifest)
+    implementation(libs.jetbrains.kotlinx.datetime)
 }
\ No newline at end of file
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/Navigation.kt b/app/src/main/java/at/ac/fhstp/pawwatch/Navigation.kt
index 055f735..a4397d2 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/Navigation.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/Navigation.kt
@@ -28,6 +28,8 @@ import at.ac.fhstp.pawwatch.data.db.AppointmentEntity
 import at.ac.fhstp.pawwatch.ui.AppointmentViewModel
 import java.sql.Date
 import java.text.DateFormat
+import java.text.SimpleDateFormat
+import java.util.Locale
 
 
 sealed class Screens(val route: String) {
@@ -112,8 +114,15 @@ fun AppointmentCard(appointment: AppointmentEntity, onClick: () -> Unit) {
             )
             Spacer(modifier = Modifier.height(14.dp))
 
+            val date = Date(appointment.appointmentDate)
+            val time = Date(appointment.appointmentTime)
+
+            // Use SimpleDateFormat for 24-hour time format (HH:mm)
+            val timeFormat = SimpleDateFormat("HH:mm", Locale.getDefault())
+
+            // Combine Date and Time into one line
             Text(
-                "Date: ${DateFormat.getDateInstance().format(Date(appointment.appointmentDate))}",
+                "${DateFormat.getDateInstance().format(date)} at ${timeFormat.format(time)}",
                 style = MaterialTheme.typography.bodyMedium
             )
         }
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AddAppointmentScreen.kt b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AddAppointmentScreen.kt
index c3fed99..0577000 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AddAppointmentScreen.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AddAppointmentScreen.kt
@@ -1,6 +1,8 @@
 package at.ac.fhstp.pawwatch.ui
 
+import android.util.Log
 import android.widget.CalendarView
+import android.widget.DatePicker
 import android.widget.NumberPicker
 import androidx.compose.foundation.layout.*
 import androidx.compose.material3.*
@@ -12,7 +14,8 @@ import androidx.compose.ui.viewinterop.AndroidView
 import androidx.compose.ui.window.Dialog
 import androidx.navigation.NavController
 import at.ac.fhstp.pawwatch.data.db.AppointmentEntity
-import java.text.DateFormat
+import kotlinx.datetime.Instant
+import java.text.SimpleDateFormat
 import java.util.*
 
 @OptIn(ExperimentalMaterial3Api::class)
@@ -125,12 +128,20 @@ fun AddAppointmentScreen(
 
         if (showDatePicker) {
             CustomDatePickerDialog(
-                selectedDate = selectedAppointmentDate, // Pass the previously selected date
+                selectedDateTime = selectedAppointmentDate, // Pass the previously selected date
 
                 onDismiss = { showDatePicker = false },
-                onDateSelected = { date ->
-                    selectedAppointmentDate = date // Update the selected date
+                onDateTimeSelected = { dateTime ->
+                    Log.w("xaver", dateTime.toString())
+                    selectedAppointmentDate = dateTime
+                    selectedAppointmentTime = Calendar.getInstance().apply {
+                        timeInMillis = dateTime
+                    }.get(Calendar.HOUR_OF_DAY) * 3600000L + // Convert hours to ms
+                            Calendar.getInstance().apply {
+                                timeInMillis = dateTime
+                            }.get(Calendar.MINUTE) * 60000L // Convert minutes to ms
                 }
+
             )
         }
 
@@ -152,11 +163,11 @@ fun AddAppointmentScreen(
         // for displaying the selected appointment date below the button
         Spacer(modifier = Modifier.height(8.dp))
         selectedAppointmentDate?.let {
-            val dateTimeString = DateFormat.getDateTimeInstance().format(Date(it))
+            val dateTimeString = SimpleDateFormat("MMM dd, yyyy HH:mm", Locale.getDefault()).format(Date(it))
             Text(
                 text = "Selected Date and Time: $dateTimeString",
                 modifier = Modifier.padding(2.dp),
-                style = MaterialTheme.typography.labelMedium
+                style = MaterialTheme.typography.labelSmall
             )
         }
 
@@ -167,14 +178,10 @@ fun AddAppointmentScreen(
             modifier = Modifier.width(200.dp),
             colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.primary),
             onClick = {
-                if (petName.value.isNotBlank() && selectedAppointmentDate != null) {
-                    if (description.value.isBlank()) {
-                        description.value = "No Description"
-                    }
-                    if (category.value.isBlank()) {
-                        category.value = "General"
-                    }
-                    // Calls the onAddAppointmentClick with selected date
+                if (petName.value.isNotBlank() && selectedAppointmentDate != null && selectedAppointmentTime != null) {
+                    if (description.value.isBlank()) { description.value = "No Description" }
+                    if (category.value.isBlank()) { category.value = "General" }
+                    // Calls the onAddAppointmentClick with selected date and time
                     onAddAppointmentClick(
                         petName.value,
                         description.value,
@@ -183,6 +190,7 @@ fun AddAppointmentScreen(
                         category.value
                     )
                 }
+
             },
             elevation = ButtonDefaults.elevatedButtonElevation(defaultElevation = 3.dp)
         ) {
@@ -193,65 +201,12 @@ fun AddAppointmentScreen(
         }
     }
 }
-//
-//@Composable
-//fun CustomDatePickerDialog(
-//    onDismiss: () -> Unit,
-//    selectedDate: Long?, // Pass the currently selected date
-//    onDateSelected: (Long) -> Unit
-//) {
-//    val calendar = Calendar.getInstance(Locale.getDefault()).apply {
-//        firstDayOfWeek = Calendar.MONDAY
-//    }
-//
-//    Dialog(onDismissRequest = onDismiss) {
-//        Surface(
-//            shape = MaterialTheme.shapes.medium,
-//            tonalElevation = 8.dp
-//        ) {
-//            Column(
-//                modifier = Modifier.padding(16.dp)
-//            ) {
-//                AndroidView(
-//                    factory = { context ->
-//                        CalendarView(context).apply {
-//                            this.firstDayOfWeek = Calendar.MONDAY
-//
-//                            // Set the calendar to the selected date or today's date
-//                            if (selectedDate != null) {
-//                                calendar.timeInMillis = selectedDate
-//                            }
-//                            this.date = calendar.timeInMillis
-//
-//                            setOnDateChangeListener { _, year, month, dayOfMonth ->
-//                                calendar.set(year, month, dayOfMonth)
-//                                onDateSelected(calendar.timeInMillis)
-//                                onDismiss() // Close the dialog after selecting a date
-//                            }
-//                        }
-//                    },
-//                    modifier = Modifier.wrapContentHeight()
-//                )
-//
-//                Spacer(modifier = Modifier.height(16.dp))
-//
-//                Button(
-//                    onClick = onDismiss,
-//                    modifier = Modifier.align(Alignment.End)
-//                ) {
-//                    Text("Cancel")
-//                }
-//            }
-//        }
-//    }
-//}
-
 
 @Composable
 fun CustomDatePickerDialog(
     onDismiss: () -> Unit,
-    selectedDate: Long?, // Pass the currently selected date
-    onDateSelected: (Long) -> Unit
+    selectedDateTime: Long?, // Pass the currently selected date
+    onDateTimeSelected: (Long) -> Unit
 ) {
     val calendar = Calendar.getInstance(Locale.getDefault()).apply {
         firstDayOfWeek = Calendar.MONDAY
@@ -278,8 +233,8 @@ fun CustomDatePickerDialog(
                                 this.firstDayOfWeek = Calendar.MONDAY
 
                                 // Set the calendar to the selected date or today's date
-                                if (selectedDate != null) {
-                                    calendar.timeInMillis = selectedDate
+                                if (selectedDateTime != null) {
+                                    calendar.timeInMillis = selectedDateTime
                                 }
                                 this.date = calendar.timeInMillis
 
@@ -316,9 +271,11 @@ fun CustomDatePickerDialog(
                                 NumberPicker(context).apply {
                                     minValue = 0
                                     maxValue = 23
-                                    value = selectedHour
+                                    //value = selectedHour
+                                    value = calendar.get(Calendar.HOUR_OF_DAY)
                                     setOnValueChangedListener { _, _, newValue ->
-                                        selectedHour = newValue
+                                        //selectedHour = newValue
+                                        calendar.set(Calendar.HOUR_OF_DAY, newValue)
                                     }
                                 }
                             },
@@ -331,9 +288,11 @@ fun CustomDatePickerDialog(
                                 NumberPicker(context).apply {
                                     minValue = 0
                                     maxValue = 59
-                                    value = selectedMinute
+                                    //value = selectedMinute
+                                    value = calendar.get(Calendar.MINUTE)
                                     setOnValueChangedListener { _, _, newValue ->
-                                        selectedMinute = newValue
+                                        //selectedMinute = newValue
+                                        calendar.set(Calendar.MINUTE, newValue)
                                     }
                                 }
                             },
@@ -352,12 +311,12 @@ fun CustomDatePickerDialog(
                         }
                         Button(
                             onClick = {
-                                calendar.set(Calendar.HOUR_OF_DAY, selectedHour)
-                                calendar.set(Calendar.MINUTE, selectedMinute)
-                                calendar.set(Calendar.SECOND, 0)
+//                                calendar.set(Calendar.HOUR_OF_DAY, selectedHour)
+//                                calendar.set(Calendar.MINUTE, selectedMinute)
+                                //calendar.set(Calendar.SECOND, 0)
 
                                 // Pass the selected date and time
-                                onDateSelected(calendar.timeInMillis)
+                                onDateTimeSelected(calendar.timeInMillis)
                                 onDismiss()
                             }
                         ) {
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AllAppointmentsScreen.kt b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentDetailScreen.kt
similarity index 89%
rename from app/src/main/java/at/ac/fhstp/pawwatch/ui/AllAppointmentsScreen.kt
rename to app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentDetailScreen.kt
index f4f0c2f..41ebe17 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AllAppointmentsScreen.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentDetailScreen.kt
@@ -12,7 +12,9 @@ import androidx.navigation.NavController
 import at.ac.fhstp.pawwatch.Screens
 import at.ac.fhstp.pawwatch.ui.theme.text
 import java.text.DateFormat
+import java.text.SimpleDateFormat
 import java.util.Date
+import java.util.Locale
 
 @Composable
 fun AppointmentDetailScreen(
@@ -64,8 +66,15 @@ fun AppointmentDetailScreen(
             )
             Spacer(modifier = Modifier.height(10.dp))
 
+            // Format date and time (using SimpleDateFormat for time in 24-hour format)
+            val date = Date(it.appointmentDate)
+            val time = Date(it.appointmentTime)
+
+            val timeFormat = SimpleDateFormat("HH:mm", Locale.getDefault())
+
+            // Display Date and Time
             Text(
-                DateFormat.getDateInstance().format(Date(it.appointmentDate)),
+                "${DateFormat.getDateInstance().format(date)} at ${timeFormat.format(time)}",
                 style = MaterialTheme.typography.bodyMedium,
                 modifier = Modifier.padding(2.dp)
             )
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentEditScreen.kt b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentEditScreen.kt
index 3cafe06..67e1eb2 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentEditScreen.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentEditScreen.kt
@@ -12,6 +12,9 @@ import androidx.navigation.NavController
 import at.ac.fhstp.pawwatch.ui.theme.text
 import java.sql.Date
 import java.text.DateFormat
+import java.text.SimpleDateFormat
+import java.util.Calendar
+import java.util.Locale
 
 @OptIn(ExperimentalMaterial3Api::class)
 @Composable
@@ -23,11 +26,12 @@ fun AppointmentEditScreen(
     val appointment = appointmentId?.let { id -> viewModel.getAppointmentById(id.toLong()) }
     var petName by remember { mutableStateOf(appointment?.petName ?: "") }
     var description by remember { mutableStateOf(appointment?.description ?: "") }
-    var appointmentDate by remember { mutableLongStateOf(appointment?.appointmentDate ?: System.currentTimeMillis()) }
-    var appointmentTime by remember { mutableLongStateOf(appointment?.appointmentTime ?: System.currentTimeMillis()) }
+    var selectedAppointmentDate by remember { mutableLongStateOf(appointment?.appointmentDate ?: System.currentTimeMillis()) }
+    var selectedAppointmentTime by remember { mutableLongStateOf(appointment?.appointmentTime ?: System.currentTimeMillis()) }
     var category by remember { mutableStateOf(appointment?.category ?: "") }
 
     var showDatePicker by remember { mutableStateOf(false) }
+    var showTimePicker by remember { mutableStateOf(false) }
 
     Column(
         modifier = Modifier
@@ -110,48 +114,99 @@ fun AppointmentEditScreen(
 
         if (showDatePicker) {
             CustomDatePickerDialog(
-                selectedDate = appointmentDate,
+                selectedDateTime = selectedAppointmentDate, // Pass the previously selected date
+
                 onDismiss = { showDatePicker = false },
-                onDateSelected = { date ->
-                    appointmentDate = date // Update appointmentDate
-                    showDatePicker = false
+                onDateTimeSelected = { dateTime ->
+                    selectedAppointmentDate = dateTime
+                    selectedAppointmentTime = Calendar.getInstance().apply {
+                        timeInMillis = dateTime
+                    }.get(Calendar.HOUR_OF_DAY) * 3600000L + // Convert hours to ms
+                            Calendar.getInstance().apply {
+                                timeInMillis = dateTime
+                            }.get(Calendar.MINUTE) * 60000L // Convert minutes to ms
                 }
+
             )
         }
 
-        val formattedDate = DateFormat.getDateInstance().format(Date(appointmentDate))
-        Text(
-            "Selected Appointment Date: $formattedDate",
-            modifier = Modifier.padding(2.dp),
-            style = MaterialTheme.typography.labelMedium
-        )
+        // Display formatted date and time
+//        val formattedDate = DateFormat.getDateInstance().format(Date(selectedAppointmentDate))
+//        val timeFormat = SimpleDateFormat("HH:mm", Locale.getDefault())
+//        val formattedTime = timeFormat.format(Date(selectedAppointmentTime))
+//
+//        Text(
+//            "Selected Date and Time: $formattedDate at $formattedTime",
+//            modifier = Modifier.padding(2.dp),
+//            style = MaterialTheme.typography.labelMedium
+//        )
 
         Spacer(modifier = Modifier.height(8.dp))
 
         OutlinedButton(
             onClick = { showDatePicker = true },
-            colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.primary),
+            modifier = Modifier.fillMaxWidth(),
+            colors = ButtonDefaults.buttonColors(
+                containerColor = MaterialTheme.colorScheme.tertiary,
+                contentColor = MaterialTheme.colorScheme.onPrimary
+            ),
+            elevation = ButtonDefaults.elevatedButtonElevation(defaultElevation = 4.dp)
         ) {
             Text(
-                "Change Appointment Date",
+                text = "Change Date or Time",
                 style = MaterialTheme.typography.labelMedium
             )
         }
 
+        Spacer(modifier = Modifier.height(8.dp))
+        selectedAppointmentDate.let {
+            val dateTimeString = SimpleDateFormat("MMM dd, yyyy HH:mm", Locale.getDefault()).format(Date(it))
+            Text(
+                text = "Selected Date and Time: $dateTimeString",
+                modifier = Modifier.padding(2.dp),
+                style = MaterialTheme.typography.labelSmall
+            )
+        }
+
         Spacer(modifier = Modifier.height(16.dp))
 
+//        OutlinedButton(
+//            onClick = {
+//                if (petName.isNotBlank() && description.isNotBlank()) {
+//                    viewModel.editAppointment(appointmentId!!.toLong(), petName, description, selectedAppointmentDate, selectedAppointmentTime, category)
+//                    navController.navigateUp()
+//                }
+//            },
+//            modifier = Modifier.fillMaxWidth(),
+//            colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.primary),
+//        ) {
+//            Text(
+//                "Save Changes",
+//                style = MaterialTheme.typography.labelMedium
+//            )
+//        }
+
         OutlinedButton(
+            modifier = Modifier.width(200.dp),
+            colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.primary),
             onClick = {
-                if (petName.isNotBlank() && description.isNotBlank()) {
-                    viewModel.editAppointment(appointmentId!!.toLong(), petName, description, appointmentDate, appointmentTime, category)
+                if (petName.isNotBlank()) {
+                    viewModel.editAppointment(
+                        appointmentId!!.toLong(),
+                        petName,
+                        description,
+                        selectedAppointmentDate,
+                        selectedAppointmentTime,
+                        category
+                    )
                     navController.navigateUp()
                 }
+
             },
-            modifier = Modifier.fillMaxWidth(),
-            colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.primary),
+            elevation = ButtonDefaults.elevatedButtonElevation(defaultElevation = 3.dp)
         ) {
             Text(
-                "Save Changes",
+                text = "Save Changes",
                 style = MaterialTheme.typography.labelMedium
             )
         }
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/ui/theme/Type.kt b/app/src/main/java/at/ac/fhstp/pawwatch/ui/theme/Type.kt
index 0b00793..f6d5aae 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/ui/theme/Type.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/ui/theme/Type.kt
@@ -47,5 +47,13 @@ val Typography = Typography(
         fontSize = 17.sp,
         lineHeight = 24.sp,
         letterSpacing = 0.5.sp
+    ),
+
+    labelSmall = TextStyle(
+        fontFamily = FontFamily.Default,
+        fontWeight = FontWeight.Bold,
+        fontSize = 15.sp,
+        lineHeight = 24.sp,
+        letterSpacing = 0.5.sp
     )
 )
\ No newline at end of file
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 4684332..6140e43 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -5,6 +5,8 @@ coreKtx = "1.13.1"
 junit = "4.13.2"
 junitVersion = "1.2.1"
 espressoCore = "3.6.1"
+kotlinxDatetime = "0.6.1"
+kotlinxDatetimeVersion = "0.6.1"
 lifecycleRuntimeKtx = "2.8.6"
 activityCompose = "1.9.2"
 composeBom = "2024.04.01"
@@ -17,6 +19,7 @@ navigationCompose = "2.8.3"
 [libraries]
 androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
 androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "roomCompiler" }
+jetbrains-kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinxDatetimeVersion" }
 junit = { group = "junit", name = "junit", version.ref = "junit" }
 androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
 androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
@@ -33,6 +36,7 @@ androidx-material3 = { group = "androidx.compose.material3", name = "material3"
 androidx-room-common = { group = "androidx.room", name = "room-common", version.ref = "roomCommon" }
 androidx-room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "roomKtx" }
 androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" }
+kotlinx-datetime = { module = "kotlinx.datetime:kotlinx-datetime", version.ref = "kotlinxDatetime" }
 materialdatetimepicker = { module = "com.wdullaer:materialdatetimepicker", version.ref = "materialdatetimepicker" }
 
 [plugins]
-- 
GitLab


From 8be8ae7a2de8c550593ab5f6793dc9528b8bb2a1 Mon Sep 17 00:00:00 2001
From: Sofiia-Khrystyna <sonia030605@gmail.com>
Date: Fri, 17 Jan 2025 11:54:44 +0100
Subject: [PATCH 05/10] :tada:time picker,works everywhere now

---
 .../java/at/ac/fhstp/pawwatch/MainActivity.kt |  4 +-
 .../java/at/ac/fhstp/pawwatch/Navigation.kt   |  9 ++--
 .../pawwatch/data/AppointmentRepository.kt    |  2 -
 .../fhstp/pawwatch/data/db/AppointmentDao.kt  |  5 +--
 .../pawwatch/data/db/AppointmentDatabase.kt   |  2 +-
 .../pawwatch/data/db/AppointmentEntity.kt     |  3 +-
 .../fhstp/pawwatch/ui/AddAppointmentScreen.kt | 43 +++++--------------
 .../pawwatch/ui/AppointmentDetailScreen.kt    | 13 +++---
 .../pawwatch/ui/AppointmentEditScreen.kt      | 39 +++--------------
 .../fhstp/pawwatch/ui/AppointmentViewModel.kt |  8 ++--
 10 files changed, 36 insertions(+), 92 deletions(-)

diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/MainActivity.kt b/app/src/main/java/at/ac/fhstp/pawwatch/MainActivity.kt
index 7337ab0..f2c9db2 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/MainActivity.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/MainActivity.kt
@@ -62,9 +62,9 @@ class MainActivity : ComponentActivity() {
                                         )
                                         navController.navigate(route)
                                     },
-                                    onAddAppointmentClick = { petName, description, date, time, category ->
+                                    onAddAppointmentClick = { petName, description, dateTime, category ->
                                         // Add a new appointment via the ViewModel
-                                        viewModel.addAppointment(petName, description, date, time, category)
+                                        viewModel.addAppointment(petName, description, dateTime, category)
                                         // Navigate back to the overview screen
                                         navController.popBackStack()
                                     },
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/Navigation.kt b/app/src/main/java/at/ac/fhstp/pawwatch/Navigation.kt
index a4397d2..86c0ae3 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/Navigation.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/Navigation.kt
@@ -27,7 +27,6 @@ import androidx.navigation.compose.currentBackStackEntryAsState
 import at.ac.fhstp.pawwatch.data.db.AppointmentEntity
 import at.ac.fhstp.pawwatch.ui.AppointmentViewModel
 import java.sql.Date
-import java.text.DateFormat
 import java.text.SimpleDateFormat
 import java.util.Locale
 
@@ -114,15 +113,13 @@ fun AppointmentCard(appointment: AppointmentEntity, onClick: () -> Unit) {
             )
             Spacer(modifier = Modifier.height(14.dp))
 
-            val date = Date(appointment.appointmentDate)
-            val time = Date(appointment.appointmentTime)
+            val date = Date(appointment.appointmentDateTime)
 
             // Use SimpleDateFormat for 24-hour time format (HH:mm)
-            val timeFormat = SimpleDateFormat("HH:mm", Locale.getDefault())
+            val dateFormat = SimpleDateFormat("MMM dd, yyyy 'at' HH:mm", Locale.getDefault())
 
-            // Combine Date and Time into one line
             Text(
-                "${DateFormat.getDateInstance().format(date)} at ${timeFormat.format(time)}",
+                dateFormat.format(date),
                 style = MaterialTheme.typography.bodyMedium
             )
         }
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/data/AppointmentRepository.kt b/app/src/main/java/at/ac/fhstp/pawwatch/data/AppointmentRepository.kt
index ebe0045..f550e33 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/data/AppointmentRepository.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/data/AppointmentRepository.kt
@@ -22,7 +22,6 @@ class AppointmentRepository(private val taskDao: AppointmentDao) {
         petName: String,
         description: String,
         appointmentDate: Long,
-        appointmentTime: Long,
         category: String
     ) {
         taskDao.updateAppointment(
@@ -30,7 +29,6 @@ class AppointmentRepository(private val taskDao: AppointmentDao) {
             petName,
             description,
             appointmentDate,
-            appointmentTime,
             category
         )
     }
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/data/db/AppointmentDao.kt b/app/src/main/java/at/ac/fhstp/pawwatch/data/db/AppointmentDao.kt
index c1a24a9..ec987da 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/data/db/AppointmentDao.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/data/db/AppointmentDao.kt
@@ -17,13 +17,12 @@ interface AppointmentDao {
     @Query("DELETE FROM appointment_table WHERE id = :appointmentId")
     suspend fun deleteAppointmentById(appointmentId: Long)
 
-    @Query("UPDATE appointment_table SET petName = :petName, description = :description, appointmentDate = :appointmentDate, appointmentTime = :appointmentTime, category = :category WHERE id = :appointmentId")
+    @Query("UPDATE appointment_table SET petName = :petName, description = :description, appointmentDateTime = :appointmentDateTime, category = :category WHERE id = :appointmentId")
     suspend fun updateAppointment(
         appointmentId: Long,
         petName: String,
         description: String,
-        appointmentDate: Long,
-        appointmentTime: Long,
+        appointmentDateTime: Long,
         category: String
     )
 
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/data/db/AppointmentDatabase.kt b/app/src/main/java/at/ac/fhstp/pawwatch/data/db/AppointmentDatabase.kt
index 37a8456..5c6406a 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/data/db/AppointmentDatabase.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/data/db/AppointmentDatabase.kt
@@ -5,7 +5,7 @@ import androidx.room.Database
 import androidx.room.Room
 import androidx.room.RoomDatabase
 
-@Database(entities = [AppointmentEntity::class], version = 3)
+@Database(entities = [AppointmentEntity::class], version = 4)
 abstract class AppointmentDatabase : RoomDatabase() {
     abstract fun appointmentDao() : AppointmentDao
 
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/data/db/AppointmentEntity.kt b/app/src/main/java/at/ac/fhstp/pawwatch/data/db/AppointmentEntity.kt
index f03f720..6cdc0c1 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/data/db/AppointmentEntity.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/data/db/AppointmentEntity.kt
@@ -9,7 +9,6 @@ data class AppointmentEntity(
     val id: Int = 0,
     val petName: String,
     val description: String,
-    val appointmentDate: Long,
-    val appointmentTime: Long,
+    val appointmentDateTime: Long,
     val category: String
 )
\ No newline at end of file
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AddAppointmentScreen.kt b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AddAppointmentScreen.kt
index 0577000..82eae84 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AddAppointmentScreen.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AddAppointmentScreen.kt
@@ -1,8 +1,6 @@
 package at.ac.fhstp.pawwatch.ui
 
-import android.util.Log
 import android.widget.CalendarView
-import android.widget.DatePicker
 import android.widget.NumberPicker
 import androidx.compose.foundation.layout.*
 import androidx.compose.material3.*
@@ -14,7 +12,6 @@ import androidx.compose.ui.viewinterop.AndroidView
 import androidx.compose.ui.window.Dialog
 import androidx.navigation.NavController
 import at.ac.fhstp.pawwatch.data.db.AppointmentEntity
-import kotlinx.datetime.Instant
 import java.text.SimpleDateFormat
 import java.util.*
 
@@ -23,15 +20,12 @@ import java.util.*
 fun AddAppointmentScreen(
     viewModel: AppointmentViewModel,
     onAppointmentClick: (AppointmentEntity) -> Unit,
-    onAddAppointmentClick: (String, String, Long, Long, String) -> Unit,
+    onAddAppointmentClick: (String, String, Long, String) -> Unit,
     navController: NavController
 ) {
-    // Collect the appointments as a state
-    //val appointments by viewModel.appointments.collectAsState()
 
     // Store the selected appointment date
-    var selectedAppointmentDate by remember { mutableStateOf<Long?>(null) }
-    var selectedAppointmentTime by remember { mutableStateOf<Long?>(null) }
+    var selectedAppointmentDateTime by remember { mutableStateOf<Long?>(null) }
 
     // DatePicker Dialog state
     var showDatePicker by remember { mutableStateOf(false) }
@@ -127,19 +121,11 @@ fun AddAppointmentScreen(
 
 
         if (showDatePicker) {
-            CustomDatePickerDialog(
-                selectedDateTime = selectedAppointmentDate, // Pass the previously selected date
-
+            CustomDateTimePickerDialog(
+                selectedDateTime = selectedAppointmentDateTime, // Pass the previously selected date
                 onDismiss = { showDatePicker = false },
                 onDateTimeSelected = { dateTime ->
-                    Log.w("xaver", dateTime.toString())
-                    selectedAppointmentDate = dateTime
-                    selectedAppointmentTime = Calendar.getInstance().apply {
-                        timeInMillis = dateTime
-                    }.get(Calendar.HOUR_OF_DAY) * 3600000L + // Convert hours to ms
-                            Calendar.getInstance().apply {
-                                timeInMillis = dateTime
-                            }.get(Calendar.MINUTE) * 60000L // Convert minutes to ms
+                    selectedAppointmentDateTime = dateTime
                 }
 
             )
@@ -155,15 +141,15 @@ fun AddAppointmentScreen(
             elevation = ButtonDefaults.elevatedButtonElevation(defaultElevation = 4.dp)
         ) {
             Text(
-                text = "Select Appointment Date",
+                text = "Select Appointment Date and Time",
                 style = MaterialTheme.typography.labelMedium
             )
         }
 
         // for displaying the selected appointment date below the button
         Spacer(modifier = Modifier.height(8.dp))
-        selectedAppointmentDate?.let {
-            val dateTimeString = SimpleDateFormat("MMM dd, yyyy HH:mm", Locale.getDefault()).format(Date(it))
+        selectedAppointmentDateTime?.let {
+            val dateTimeString = SimpleDateFormat("MMM dd, yyyy 'at' HH:mm", Locale.getDefault()).format(Date(it))
             Text(
                 text = "Selected Date and Time: $dateTimeString",
                 modifier = Modifier.padding(2.dp),
@@ -178,15 +164,14 @@ fun AddAppointmentScreen(
             modifier = Modifier.width(200.dp),
             colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.primary),
             onClick = {
-                if (petName.value.isNotBlank() && selectedAppointmentDate != null && selectedAppointmentTime != null) {
+                if (petName.value.isNotBlank() && selectedAppointmentDateTime != null) {
                     if (description.value.isBlank()) { description.value = "No Description" }
                     if (category.value.isBlank()) { category.value = "General" }
                     // Calls the onAddAppointmentClick with selected date and time
                     onAddAppointmentClick(
                         petName.value,
                         description.value,
-                        selectedAppointmentDate!!,
-                        selectedAppointmentTime!!,
+                        selectedAppointmentDateTime!!,
                         category.value
                     )
                 }
@@ -203,7 +188,7 @@ fun AddAppointmentScreen(
 }
 
 @Composable
-fun CustomDatePickerDialog(
+fun CustomDateTimePickerDialog(
     onDismiss: () -> Unit,
     selectedDateTime: Long?, // Pass the currently selected date
     onDateTimeSelected: (Long) -> Unit
@@ -214,8 +199,6 @@ fun CustomDatePickerDialog(
 
     // Time selection state
     var showTimePicker by remember { mutableStateOf(false) }
-    var selectedHour by remember { mutableIntStateOf(12) } // Default hour
-    var selectedMinute by remember { mutableIntStateOf(0) } // Default minute
 
     Dialog(onDismissRequest = onDismiss) {
         Surface(
@@ -311,10 +294,6 @@ fun CustomDatePickerDialog(
                         }
                         Button(
                             onClick = {
-//                                calendar.set(Calendar.HOUR_OF_DAY, selectedHour)
-//                                calendar.set(Calendar.MINUTE, selectedMinute)
-                                //calendar.set(Calendar.SECOND, 0)
-
                                 // Pass the selected date and time
                                 onDateTimeSelected(calendar.timeInMillis)
                                 onDismiss()
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentDetailScreen.kt b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentDetailScreen.kt
index 41ebe17..b190a32 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentDetailScreen.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentDetailScreen.kt
@@ -66,17 +66,14 @@ fun AppointmentDetailScreen(
             )
             Spacer(modifier = Modifier.height(10.dp))
 
-            // Format date and time (using SimpleDateFormat for time in 24-hour format)
-            val date = Date(it.appointmentDate)
-            val time = Date(it.appointmentTime)
+            val date = Date(appointment.appointmentDateTime)
 
-            val timeFormat = SimpleDateFormat("HH:mm", Locale.getDefault())
+            // Use SimpleDateFormat for 24-hour time format (HH:mm)
+            val dateFormat = SimpleDateFormat("MMM dd, yyyy 'at' HH:mm", Locale.getDefault())
 
-            // Display Date and Time
             Text(
-                "${DateFormat.getDateInstance().format(date)} at ${timeFormat.format(time)}",
-                style = MaterialTheme.typography.bodyMedium,
-                modifier = Modifier.padding(2.dp)
+                dateFormat.format(date),
+                style = MaterialTheme.typography.bodyMedium
             )
 
             Spacer(modifier = Modifier.height(20.dp))
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentEditScreen.kt b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentEditScreen.kt
index 67e1eb2..0f89e76 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentEditScreen.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentEditScreen.kt
@@ -26,8 +26,7 @@ fun AppointmentEditScreen(
     val appointment = appointmentId?.let { id -> viewModel.getAppointmentById(id.toLong()) }
     var petName by remember { mutableStateOf(appointment?.petName ?: "") }
     var description by remember { mutableStateOf(appointment?.description ?: "") }
-    var selectedAppointmentDate by remember { mutableLongStateOf(appointment?.appointmentDate ?: System.currentTimeMillis()) }
-    var selectedAppointmentTime by remember { mutableLongStateOf(appointment?.appointmentTime ?: System.currentTimeMillis()) }
+    var selectedAppointmentDateTime by remember { mutableLongStateOf(appointment?.appointmentDateTime ?: System.currentTimeMillis()) }
     var category by remember { mutableStateOf(appointment?.category ?: "") }
 
     var showDatePicker by remember { mutableStateOf(false) }
@@ -113,20 +112,13 @@ fun AppointmentEditScreen(
         Spacer(modifier = Modifier.height(16.dp))
 
         if (showDatePicker) {
-            CustomDatePickerDialog(
-                selectedDateTime = selectedAppointmentDate, // Pass the previously selected date
+            CustomDateTimePickerDialog(
+                selectedDateTime = selectedAppointmentDateTime, // Pass the previously selected date
 
                 onDismiss = { showDatePicker = false },
                 onDateTimeSelected = { dateTime ->
-                    selectedAppointmentDate = dateTime
-                    selectedAppointmentTime = Calendar.getInstance().apply {
-                        timeInMillis = dateTime
-                    }.get(Calendar.HOUR_OF_DAY) * 3600000L + // Convert hours to ms
-                            Calendar.getInstance().apply {
-                                timeInMillis = dateTime
-                            }.get(Calendar.MINUTE) * 60000L // Convert minutes to ms
+                    selectedAppointmentDateTime = dateTime
                 }
-
             )
         }
 
@@ -159,8 +151,8 @@ fun AppointmentEditScreen(
         }
 
         Spacer(modifier = Modifier.height(8.dp))
-        selectedAppointmentDate.let {
-            val dateTimeString = SimpleDateFormat("MMM dd, yyyy HH:mm", Locale.getDefault()).format(Date(it))
+        selectedAppointmentDateTime.let {
+            val dateTimeString = SimpleDateFormat("MMM dd, yyyy 'at' HH:mm", Locale.getDefault()).format(Date(it))
             Text(
                 text = "Selected Date and Time: $dateTimeString",
                 modifier = Modifier.padding(2.dp),
@@ -170,22 +162,6 @@ fun AppointmentEditScreen(
 
         Spacer(modifier = Modifier.height(16.dp))
 
-//        OutlinedButton(
-//            onClick = {
-//                if (petName.isNotBlank() && description.isNotBlank()) {
-//                    viewModel.editAppointment(appointmentId!!.toLong(), petName, description, selectedAppointmentDate, selectedAppointmentTime, category)
-//                    navController.navigateUp()
-//                }
-//            },
-//            modifier = Modifier.fillMaxWidth(),
-//            colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.primary),
-//        ) {
-//            Text(
-//                "Save Changes",
-//                style = MaterialTheme.typography.labelMedium
-//            )
-//        }
-
         OutlinedButton(
             modifier = Modifier.width(200.dp),
             colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.primary),
@@ -195,8 +171,7 @@ fun AppointmentEditScreen(
                         appointmentId!!.toLong(),
                         petName,
                         description,
-                        selectedAppointmentDate,
-                        selectedAppointmentTime,
+                        selectedAppointmentDateTime,
                         category
                     )
                     navController.navigateUp()
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentViewModel.kt b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentViewModel.kt
index 463d901..6839d11 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentViewModel.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentViewModel.kt
@@ -33,8 +33,8 @@ class AppointmentViewModel(private val appointmentRepository: AppointmentReposit
     }
 
     // Add a new appointment
-    fun addAppointment(petName: String, description: String, appointmentDate: Long, appointmentTime: Long, category: String) {
-        val appointment = AppointmentEntity(petName = petName, description = description, appointmentDate = appointmentDate, appointmentTime = appointmentTime, category = category)
+    fun addAppointment(petName: String, description: String, appointmentDateTime: Long, category: String) {
+        val appointment = AppointmentEntity(petName = petName, description = description, appointmentDateTime = appointmentDateTime, category = category)
         viewModelScope.launch {
             appointmentRepository.insertAppointment(appointment)
             loadAppointments()  // Reload appointments from the repository to update the list
@@ -58,9 +58,9 @@ class AppointmentViewModel(private val appointmentRepository: AppointmentReposit
         }
     }
 
-    fun editAppointment(appointmentId: Long, petName: String, description: String, appointmentDate: Long, appointmentTime: Long, category: String) {
+    fun editAppointment(appointmentId: Long, petName: String, description: String, appointmentDateTime: Long, category: String) {
         viewModelScope.launch {
-            appointmentRepository.updateAppointment(appointmentId, petName, description, appointmentDate, appointmentTime, category)
+            appointmentRepository.updateAppointment(appointmentId, petName, description, appointmentDateTime, category)
             loadAppointments()  // Refresh the appointment list
         }
     }
-- 
GitLab


From 0d485112b3d10d744a6a93cad2783bb788eb6d6f Mon Sep 17 00:00:00 2001
From: Sofiia-Khrystyna <sonia030605@gmail.com>
Date: Fri, 17 Jan 2025 13:54:30 +0100
Subject: [PATCH 06/10] :card_file_box:overview related code is moved to
 separate file from Navigation

---
 .idea/vcs.xml                                 |  6 ++
 .../java/at/ac/fhstp/pawwatch/MainActivity.kt |  1 +
 .../java/at/ac/fhstp/pawwatch/Navigation.kt   | 86 +------------------
 .../at/ac/fhstp/pawwatch/ui/OverviewScreen.kt | 81 +++++++++++++++++
 4 files changed, 89 insertions(+), 85 deletions(-)
 create mode 100644 .idea/vcs.xml
 create mode 100644 app/src/main/java/at/ac/fhstp/pawwatch/ui/OverviewScreen.kt

diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$" vcs="Git" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/MainActivity.kt b/app/src/main/java/at/ac/fhstp/pawwatch/MainActivity.kt
index f2c9db2..639ed6e 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/MainActivity.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/MainActivity.kt
@@ -20,6 +20,7 @@ import at.ac.fhstp.pawwatch.ui.AppointmentDetailScreen
 import at.ac.fhstp.pawwatch.ui.AppointmentEditScreen
 import at.ac.fhstp.pawwatch.ui.AppointmentViewModelFactory
 import at.ac.fhstp.pawwatch.ui.AddAppointmentScreen
+import at.ac.fhstp.pawwatch.ui.OverviewScreen
 import at.ac.fhstp.pawwatch.ui.theme.PawWatchTheme
 
 class MainActivity : ComponentActivity() {
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/Navigation.kt b/app/src/main/java/at/ac/fhstp/pawwatch/Navigation.kt
index 86c0ae3..d03c9e0 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/Navigation.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/Navigation.kt
@@ -1,34 +1,12 @@
 package at.ac.fhstp.pawwatch
 
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.lazy.LazyColumn
-import androidx.compose.foundation.lazy.items
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.automirrored.filled.List
 import androidx.compose.material.icons.filled.Add
-import androidx.compose.material3.CardDefaults
-import androidx.compose.material3.Icon
-import androidx.compose.material3.MaterialTheme
-import androidx.compose.material3.NavigationBar
-import androidx.compose.material3.NavigationBarItem
-import androidx.compose.material3.OutlinedCard
-import androidx.compose.material3.Text
+import androidx.compose.material3.*
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.collectAsState
-import androidx.compose.runtime.getValue
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.unit.dp
 import androidx.navigation.NavController
 import androidx.navigation.compose.currentBackStackEntryAsState
-import at.ac.fhstp.pawwatch.data.db.AppointmentEntity
-import at.ac.fhstp.pawwatch.ui.AppointmentViewModel
-import java.sql.Date
-import java.text.SimpleDateFormat
-import java.util.Locale
 
 
 sealed class Screens(val route: String) {
@@ -62,66 +40,4 @@ fun BottomNavigationBar(navController: NavController) {
             label = { Text("Appointments") }
         )
     }
-}
-
-@Composable
-fun OverviewScreen(viewModel: AppointmentViewModel, navController: NavController) {
-    val appointments by viewModel.appointments.collectAsState()
-
-    LazyColumn(
-        modifier = Modifier.fillMaxWidth().padding(16.dp)
-    ) {
-        items(appointments) { appointment ->
-            AppointmentCard(appointment = appointment) {
-                navController.navigate(Screens.AppointmentDetails(appointmentId = appointment.id.toString()).createRoute(
-                    appointment.id.toString()
-                ))
-            }
-            Spacer(modifier = Modifier.height(14.dp))
-        }
-    }
-}
-
-@Composable
-fun AppointmentCard(appointment: AppointmentEntity, onClick: () -> Unit) {
-    OutlinedCard(
-        modifier = Modifier
-            .fillMaxWidth()
-            .padding(start = 16.dp, top = 8.dp, end = 16.dp, bottom = 0.dp),
-        onClick = onClick,
-        colors = CardDefaults.outlinedCardColors(
-            containerColor = MaterialTheme.colorScheme.secondary,
-            contentColor = MaterialTheme.colorScheme.onPrimary
-        )
-    ) {
-        Column(modifier = Modifier.padding(16.dp)) {
-            Text(
-                appointment.petName,
-                style = MaterialTheme.typography.bodyLarge
-            )
-            Spacer(modifier = Modifier.height(3.dp))
-
-            Text(
-                appointment.category,
-                style = MaterialTheme.typography.bodyMedium
-            )
-            Spacer(modifier = Modifier.height(10.dp))
-
-            Text(
-                appointment.description,
-                style = MaterialTheme.typography.bodyMedium
-            )
-            Spacer(modifier = Modifier.height(14.dp))
-
-            val date = Date(appointment.appointmentDateTime)
-
-            // Use SimpleDateFormat for 24-hour time format (HH:mm)
-            val dateFormat = SimpleDateFormat("MMM dd, yyyy 'at' HH:mm", Locale.getDefault())
-
-            Text(
-                dateFormat.format(date),
-                style = MaterialTheme.typography.bodyMedium
-            )
-        }
-    }
 }
\ No newline at end of file
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/ui/OverviewScreen.kt b/app/src/main/java/at/ac/fhstp/pawwatch/ui/OverviewScreen.kt
new file mode 100644
index 0000000..2c38030
--- /dev/null
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/ui/OverviewScreen.kt
@@ -0,0 +1,81 @@
+package at.ac.fhstp.pawwatch.ui
+
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.items
+import androidx.compose.material3.CardDefaults
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.OutlinedCard
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.getValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import androidx.navigation.NavController
+import at.ac.fhstp.pawwatch.Screens
+import at.ac.fhstp.pawwatch.data.db.AppointmentEntity
+import java.sql.Date
+import java.text.SimpleDateFormat
+import java.util.Locale
+
+@Composable
+fun OverviewScreen(viewModel: AppointmentViewModel, navController: NavController) {
+    val appointments by viewModel.appointments.collectAsState()
+
+    LazyColumn(
+        modifier = Modifier.fillMaxWidth().padding(16.dp)
+    ) {
+        items(appointments) { appointment ->
+            AppointmentCard(appointment = appointment) {
+                navController.navigate(
+                    Screens.AppointmentDetails(appointmentId = appointment.id.toString()).createRoute(
+                    appointment.id.toString()
+                ))
+            }
+            Spacer(modifier = Modifier.height(14.dp))
+        }
+    }
+}
+
+@Composable
+fun AppointmentCard(appointment: AppointmentEntity, onClick: () -> Unit) {
+    OutlinedCard(
+        modifier = Modifier
+            .fillMaxWidth()
+            .padding(start = 16.dp, top = 8.dp, end = 16.dp, bottom = 0.dp),
+        onClick = onClick,
+        colors = CardDefaults.outlinedCardColors(
+            containerColor = MaterialTheme.colorScheme.secondary,
+            contentColor = MaterialTheme.colorScheme.onPrimary
+        )
+    ) {
+        Column(modifier = Modifier.padding(16.dp)) {
+            Text(
+                appointment.petName,
+                style = MaterialTheme.typography.bodyLarge
+            )
+            Spacer(modifier = Modifier.height(3.dp))
+
+            Text(
+                appointment.category,
+                style = MaterialTheme.typography.bodyMedium
+            )
+            Spacer(modifier = Modifier.height(10.dp))
+
+            Text(
+                appointment.description,
+                style = MaterialTheme.typography.bodyMedium
+            )
+            Spacer(modifier = Modifier.height(14.dp))
+
+            val date = Date(appointment.appointmentDateTime)
+            val dateFormat = SimpleDateFormat("MMM dd, yyyy 'at' HH:mm", Locale.getDefault())
+
+            Text(
+                dateFormat.format(date),
+                style = MaterialTheme.typography.bodyMedium
+            )
+        }
+    }
+}
\ No newline at end of file
-- 
GitLab


From b1f1de2a892b0949f775cf2cd1faae938d9b9708 Mon Sep 17 00:00:00 2001
From: Sofiia-Khrystyna <sonia030605@gmail.com>
Date: Fri, 17 Jan 2025 22:10:51 +0100
Subject: [PATCH 07/10] :art: added shadowing for buttons + pop-up on the Add
 page as an error handler

---
 .../fhstp/pawwatch/ui/AddAppointmentScreen.kt | 23 ++++++--
 .../pawwatch/ui/AppointmentDetailScreen.kt    | 22 +++++---
 .../pawwatch/ui/AppointmentEditScreen.kt      | 20 ++-----
 .../at/ac/fhstp/pawwatch/ui/OverviewScreen.kt | 53 ++++++++++++++-----
 .../at/ac/fhstp/pawwatch/ui/theme/Color.kt    |  3 +-
 .../at/ac/fhstp/pawwatch/ui/theme/Theme.kt    |  1 +
 6 files changed, 84 insertions(+), 38 deletions(-)

diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AddAppointmentScreen.kt b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AddAppointmentScreen.kt
index 82eae84..9feac2c 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AddAppointmentScreen.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AddAppointmentScreen.kt
@@ -7,6 +7,7 @@ import androidx.compose.material3.*
 import androidx.compose.runtime.*
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.vector.ImageVector
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.viewinterop.AndroidView
 import androidx.compose.ui.window.Dialog
@@ -26,6 +27,7 @@ fun AddAppointmentScreen(
 
     // Store the selected appointment date
     var selectedAppointmentDateTime by remember { mutableStateOf<Long?>(null) }
+    var errorAddAppointment by remember { mutableStateOf(false) }
 
     // DatePicker Dialog state
     var showDatePicker by remember { mutableStateOf(false) }
@@ -131,6 +133,21 @@ fun AddAppointmentScreen(
             )
         }
 
+        if (errorAddAppointment) {
+            AlertDialog(
+                onDismissRequest = { errorAddAppointment = false },
+                title = { Text("Could not add an appointment") },
+                text = { Text("Please fill in all required fields and select a date and time") },
+                confirmButton = {
+                    Button(
+                        onClick = { errorAddAppointment = false }
+                    ) {
+                        Text("OK")
+                    }
+                }
+            )
+        }
+
         OutlinedButton(
             onClick = { showDatePicker = true },
             modifier = Modifier.fillMaxWidth(),
@@ -164,9 +181,9 @@ fun AddAppointmentScreen(
             modifier = Modifier.width(200.dp),
             colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.primary),
             onClick = {
-                if (petName.value.isNotBlank() && selectedAppointmentDateTime != null) {
+                if (petName.value.isNotBlank() && category.value.isNotBlank() && selectedAppointmentDateTime != null) {
                     if (description.value.isBlank()) { description.value = "No Description" }
-                    if (category.value.isBlank()) { category.value = "General" }
+                    //if (category.value.isBlank()) { category.value = "General" }
                     // Calls the onAddAppointmentClick with selected date and time
                     onAddAppointmentClick(
                         petName.value,
@@ -175,7 +192,7 @@ fun AddAppointmentScreen(
                         category.value
                     )
                 }
-
+                else errorAddAppointment = true
             },
             elevation = ButtonDefaults.elevatedButtonElevation(defaultElevation = 3.dp)
         ) {
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentDetailScreen.kt b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentDetailScreen.kt
index b190a32..330311a 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentDetailScreen.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentDetailScreen.kt
@@ -36,7 +36,8 @@ fun AppointmentDetailScreen(
                 navController.navigateUp()
             },
             modifier = Modifier.align(Alignment.Start),
-            colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.background)
+            colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.background),
+            elevation = ButtonDefaults.elevatedButtonElevation(defaultElevation = 3.dp)
         ) {
             Icon(
                 imageVector = Icons.AutoMirrored.Filled.ArrowBack,
@@ -46,7 +47,8 @@ fun AppointmentDetailScreen(
             Spacer(modifier = Modifier.width(6.dp))
             Text(
                 text = "Back",
-                color = text // same colour variable as for the icon
+                color = text, // same colour variable as for the icon
+                style = MaterialTheme.typography.labelMedium
             )
         }
 
@@ -94,9 +96,13 @@ fun AppointmentDetailScreen(
                         // Navigate using the sealed class route
                         navController.navigate(Screens.EditAppointment(it.id.toString()).createRoute(it.id.toString()))
                     },
-                    modifier = Modifier.width(150.dp)
+                    modifier = Modifier.width(150.dp),
+                    elevation = ButtonDefaults.elevatedButtonElevation(defaultElevation = 3.dp)
                 ) {
-                    Text("Edit")
+                    Text(
+                        text = "Edit",
+                        style = MaterialTheme.typography.labelMedium
+                    )
                 }
 
                 Spacer(modifier = Modifier.width(40.dp))
@@ -108,9 +114,13 @@ fun AppointmentDetailScreen(
                         viewModel.deleteAppointment(it.id.toLong()) // Call delete logic
                         navController.navigateUp()
                     },
-                    modifier = Modifier.width(150.dp)
+                    modifier = Modifier.width(150.dp),
+                    elevation = ButtonDefaults.elevatedButtonElevation(defaultElevation = 3.dp)
                 ) {
-                    Text("Delete")
+                    Text(
+                        text = "Delete",
+                        style = MaterialTheme.typography.labelMedium
+                    )
                 }
             }
         }
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentEditScreen.kt b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentEditScreen.kt
index 0f89e76..8e1067c 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentEditScreen.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentEditScreen.kt
@@ -30,7 +30,6 @@ fun AppointmentEditScreen(
     var category by remember { mutableStateOf(appointment?.category ?: "") }
 
     var showDatePicker by remember { mutableStateOf(false) }
-    var showTimePicker by remember { mutableStateOf(false) }
 
     Column(
         modifier = Modifier
@@ -44,7 +43,8 @@ fun AppointmentEditScreen(
                 navController.navigateUp()
             },
             modifier = Modifier.align(Alignment.Start),
-            colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.background)
+            colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.background),
+            elevation = ButtonDefaults.elevatedButtonElevation(defaultElevation = 3.dp)
         ) {
             Icon(
                 imageVector = Icons.AutoMirrored.Filled.ArrowBack,
@@ -54,7 +54,8 @@ fun AppointmentEditScreen(
             Spacer(modifier = Modifier.width(6.dp))
             Text(
                 text = "Back",
-                color = text // same colour variable as for the icon
+                color = text, // same colour variable as for the icon
+                style = MaterialTheme.typography.labelMedium
             )
         }
 
@@ -122,17 +123,6 @@ fun AppointmentEditScreen(
             )
         }
 
-        // Display formatted date and time
-//        val formattedDate = DateFormat.getDateInstance().format(Date(selectedAppointmentDate))
-//        val timeFormat = SimpleDateFormat("HH:mm", Locale.getDefault())
-//        val formattedTime = timeFormat.format(Date(selectedAppointmentTime))
-//
-//        Text(
-//            "Selected Date and Time: $formattedDate at $formattedTime",
-//            modifier = Modifier.padding(2.dp),
-//            style = MaterialTheme.typography.labelMedium
-//        )
-
         Spacer(modifier = Modifier.height(8.dp))
 
         OutlinedButton(
@@ -142,7 +132,7 @@ fun AppointmentEditScreen(
                 containerColor = MaterialTheme.colorScheme.tertiary,
                 contentColor = MaterialTheme.colorScheme.onPrimary
             ),
-            elevation = ButtonDefaults.elevatedButtonElevation(defaultElevation = 4.dp)
+            elevation = ButtonDefaults.elevatedButtonElevation(defaultElevation = 3.dp)
         ) {
             Text(
                 text = "Change Date or Time",
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/ui/OverviewScreen.kt b/app/src/main/java/at/ac/fhstp/pawwatch/ui/OverviewScreen.kt
index 2c38030..ca20d21 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/ui/OverviewScreen.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/ui/OverviewScreen.kt
@@ -3,6 +3,7 @@ package at.ac.fhstp.pawwatch.ui
 import androidx.compose.foundation.layout.*
 import androidx.compose.foundation.lazy.LazyColumn
 import androidx.compose.foundation.lazy.items
+import androidx.compose.material3.ButtonDefaults
 import androidx.compose.material3.CardDefaults
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.OutlinedCard
@@ -10,6 +11,7 @@ import androidx.compose.material3.Text
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.collectAsState
 import androidx.compose.runtime.getValue
+import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.unit.dp
 import androidx.navigation.NavController
@@ -20,35 +22,60 @@ import java.text.SimpleDateFormat
 import java.util.Locale
 
 @Composable
-fun OverviewScreen(viewModel: AppointmentViewModel, navController: NavController) {
+fun OverviewScreen(
+    viewModel: AppointmentViewModel,
+    navController: NavController
+) {
     val appointments by viewModel.appointments.collectAsState()
 
-    LazyColumn(
-        modifier = Modifier.fillMaxWidth().padding(16.dp)
+    Column(
+        modifier = Modifier
+            .fillMaxSize()
+            .padding(35.dp),
+        horizontalAlignment = Alignment.CenterHorizontally,
+        verticalArrangement = Arrangement.Center
     ) {
-        items(appointments) { appointment ->
-            AppointmentCard(appointment = appointment) {
-                navController.navigate(
-                    Screens.AppointmentDetails(appointmentId = appointment.id.toString()).createRoute(
-                    appointment.id.toString()
-                ))
+        Spacer(modifier = Modifier.height(10.dp))
+
+        Text(
+            text = "Your Appointments",
+            style = MaterialTheme.typography.headlineMedium
+        )
+
+        Spacer(modifier = Modifier.height(20.dp))
+
+        LazyColumn(
+            modifier = Modifier.fillMaxWidth()
+        ) {
+            items(appointments) { appointment ->
+                AppointmentCard(appointment = appointment) {
+                    navController.navigate(
+                        Screens.AppointmentDetails(appointmentId = appointment.id.toString()).createRoute(
+                            appointment.id.toString()
+                        ))
+                }
+                Spacer(modifier = Modifier.height(14.dp))
             }
-            Spacer(modifier = Modifier.height(14.dp))
         }
     }
+
 }
 
 @Composable
-fun AppointmentCard(appointment: AppointmentEntity, onClick: () -> Unit) {
+fun AppointmentCard(
+    appointment: AppointmentEntity,
+    onClick: () -> Unit
+) {
     OutlinedCard(
         modifier = Modifier
             .fillMaxWidth()
-            .padding(start = 16.dp, top = 8.dp, end = 16.dp, bottom = 0.dp),
+            .padding(top = 8.dp),
         onClick = onClick,
         colors = CardDefaults.outlinedCardColors(
             containerColor = MaterialTheme.colorScheme.secondary,
             contentColor = MaterialTheme.colorScheme.onPrimary
-        )
+        ),
+        elevation = CardDefaults.elevatedCardElevation(defaultElevation = 3.dp)
     ) {
         Column(modifier = Modifier.padding(16.dp)) {
             Text(
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/ui/theme/Color.kt b/app/src/main/java/at/ac/fhstp/pawwatch/ui/theme/Color.kt
index 13f9b18..22987b9 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/ui/theme/Color.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/ui/theme/Color.kt
@@ -5,6 +5,7 @@ import androidx.compose.ui.graphics.Color
 val bg = Color(0xFFFDE9C3)
 val buttonBg = Color(0xFFFFBA66)
 val lightButtonBg = Color(0xFFFFCE93)
+val appointmentBg = Color(0xFFF8F8F8)
 val text = Color(0xFF000000)
 val fieldBg = Color(0xFFFFF4DE)
-val deleteButtonBg = Color(0xFFbf4342)
\ No newline at end of file
+val deleteButtonBg = Color(0xFFE04F47)
\ No newline at end of file
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/ui/theme/Theme.kt b/app/src/main/java/at/ac/fhstp/pawwatch/ui/theme/Theme.kt
index c6c272e..8792eb1 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/ui/theme/Theme.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/ui/theme/Theme.kt
@@ -10,6 +10,7 @@ private val AppColorScheme = lightColorScheme(
     onPrimary = text,
     secondary = fieldBg,
     tertiary = lightButtonBg,
+    tertiaryContainer = appointmentBg,
     error = deleteButtonBg
 )
 
-- 
GitLab


From 913ac414c6c774369a471ace50b3c61c1d59a848 Mon Sep 17 00:00:00 2001
From: Sofiia-Khrystyna <sonia030605@gmail.com>
Date: Sat, 18 Jan 2025 00:20:37 +0100
Subject: [PATCH 08/10] :memo: the description is now shorten on the overview
 page + the height of the description field is set with scroll

---
 .../java/at/ac/fhstp/pawwatch/MainActivity.kt |  12 +-
 .../{AddAppointmentScreen.kt => AddScreen.kt} |  17 +-
 .../pawwatch/ui/AppointmentEditScreen.kt      | 179 ---------------
 ...intmentDetailScreen.kt => DetailScreen.kt} |  19 +-
 .../at/ac/fhstp/pawwatch/ui/EditScreen.kt     | 206 ++++++++++++++++++
 .../at/ac/fhstp/pawwatch/ui/OverviewScreen.kt |  11 +-
 6 files changed, 245 insertions(+), 199 deletions(-)
 rename app/src/main/java/at/ac/fhstp/pawwatch/ui/{AddAppointmentScreen.kt => AddScreen.kt} (95%)
 delete mode 100644 app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentEditScreen.kt
 rename app/src/main/java/at/ac/fhstp/pawwatch/ui/{AppointmentDetailScreen.kt => DetailScreen.kt} (89%)
 create mode 100644 app/src/main/java/at/ac/fhstp/pawwatch/ui/EditScreen.kt

diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/MainActivity.kt b/app/src/main/java/at/ac/fhstp/pawwatch/MainActivity.kt
index 639ed6e..2ae6fa2 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/MainActivity.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/MainActivity.kt
@@ -16,10 +16,10 @@ import androidx.navigation.compose.composable
 import androidx.navigation.compose.rememberNavController
 import at.ac.fhstp.pawwatch.data.AppointmentRepository
 import at.ac.fhstp.pawwatch.data.db.AppointmentDatabase
-import at.ac.fhstp.pawwatch.ui.AppointmentDetailScreen
-import at.ac.fhstp.pawwatch.ui.AppointmentEditScreen
+import at.ac.fhstp.pawwatch.ui.DetailScreen
+import at.ac.fhstp.pawwatch.ui.EditScreen
 import at.ac.fhstp.pawwatch.ui.AppointmentViewModelFactory
-import at.ac.fhstp.pawwatch.ui.AddAppointmentScreen
+import at.ac.fhstp.pawwatch.ui.AddScreen
 import at.ac.fhstp.pawwatch.ui.OverviewScreen
 import at.ac.fhstp.pawwatch.ui.theme.PawWatchTheme
 
@@ -54,7 +54,7 @@ class MainActivity : ComponentActivity() {
                                 OverviewScreen(viewModel, navController)
                             }
                             composable(Screens.AddAppointment.route) {
-                                AddAppointmentScreen(
+                                AddScreen(
                                     viewModel = viewModel,
                                     onAppointmentClick = { appointment ->
                                         // Navigate to the appointment details screen
@@ -74,7 +74,7 @@ class MainActivity : ComponentActivity() {
                             }
                             composable(Screens.AppointmentDetails("appointmentId").route) { backStackEntry ->
                                 val appointmentId = backStackEntry.arguments?.getString("appointmentId")
-                                AppointmentDetailScreen(
+                                DetailScreen(
                                     appointmentId = appointmentId,
                                     viewModel = viewModel,
                                     navController = navController
@@ -83,7 +83,7 @@ class MainActivity : ComponentActivity() {
 
                             composable(Screens.EditAppointment("{appointmentId}").route) { backStackEntry ->
                                 val appointmentId = backStackEntry.arguments?.getString("appointmentId")
-                                AppointmentEditScreen(
+                                EditScreen(
                                     appointmentId = appointmentId,
                                     viewModel = viewModel,
                                     navController = navController
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AddAppointmentScreen.kt b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AddScreen.kt
similarity index 95%
rename from app/src/main/java/at/ac/fhstp/pawwatch/ui/AddAppointmentScreen.kt
rename to app/src/main/java/at/ac/fhstp/pawwatch/ui/AddScreen.kt
index 9feac2c..e461123 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AddAppointmentScreen.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AddScreen.kt
@@ -3,11 +3,12 @@ package at.ac.fhstp.pawwatch.ui
 import android.widget.CalendarView
 import android.widget.NumberPicker
 import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.verticalScroll
 import androidx.compose.material3.*
 import androidx.compose.runtime.*
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.vector.ImageVector
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.viewinterop.AndroidView
 import androidx.compose.ui.window.Dialog
@@ -18,7 +19,7 @@ import java.util.*
 
 @OptIn(ExperimentalMaterial3Api::class)
 @Composable
-fun AddAppointmentScreen(
+fun AddScreen(
     viewModel: AppointmentViewModel,
     onAppointmentClick: (AppointmentEntity) -> Unit,
     onAddAppointmentClick: (String, String, Long, String) -> Unit,
@@ -107,7 +108,16 @@ fun AddAppointmentScreen(
         OutlinedTextField(
             value = description.value,
             onValueChange = { description.value = it },
-            modifier = Modifier.fillMaxWidth(),
+            modifier = Modifier
+                .fillMaxWidth()
+                .heightIn(max = 100.dp) // Restrict the height
+                .let { modifier ->
+                    if (description.value.length > 200) {
+                        modifier.verticalScroll(rememberScrollState()) // Enable scroll if content exceeds 200 characters
+                    } else {
+                        modifier
+                    }
+                },
             colors = TextFieldDefaults.outlinedTextFieldColors(
                 containerColor = MaterialTheme.colorScheme.secondary
             ),
@@ -119,6 +129,7 @@ fun AddAppointmentScreen(
                 )
             }
         )
+
         Spacer(modifier = Modifier.height(20.dp))
 
 
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentEditScreen.kt b/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentEditScreen.kt
deleted file mode 100644
index 8e1067c..0000000
--- a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentEditScreen.kt
+++ /dev/null
@@ -1,179 +0,0 @@
-package at.ac.fhstp.pawwatch.ui
-
-import androidx.compose.foundation.layout.*
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.automirrored.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 androidx.navigation.NavController
-import at.ac.fhstp.pawwatch.ui.theme.text
-import java.sql.Date
-import java.text.DateFormat
-import java.text.SimpleDateFormat
-import java.util.Calendar
-import java.util.Locale
-
-@OptIn(ExperimentalMaterial3Api::class)
-@Composable
-fun AppointmentEditScreen(
-    appointmentId: String?,
-    viewModel: AppointmentViewModel,
-    navController: NavController
-) {
-    val appointment = appointmentId?.let { id -> viewModel.getAppointmentById(id.toLong()) }
-    var petName by remember { mutableStateOf(appointment?.petName ?: "") }
-    var description by remember { mutableStateOf(appointment?.description ?: "") }
-    var selectedAppointmentDateTime by remember { mutableLongStateOf(appointment?.appointmentDateTime ?: System.currentTimeMillis()) }
-    var category by remember { mutableStateOf(appointment?.category ?: "") }
-
-    var showDatePicker by remember { mutableStateOf(false) }
-
-    Column(
-        modifier = Modifier
-            .fillMaxWidth()
-            .padding(35.dp),
-        horizontalAlignment = Alignment.CenterHorizontally
-    ) {
-        // Back Button
-        OutlinedButton(
-            onClick = {
-                navController.navigateUp()
-            },
-            modifier = Modifier.align(Alignment.Start),
-            colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.background),
-            elevation = ButtonDefaults.elevatedButtonElevation(defaultElevation = 3.dp)
-        ) {
-            Icon(
-                imageVector = Icons.AutoMirrored.Filled.ArrowBack,
-                contentDescription = "Back",
-                tint = text // "text" is the variable which contains black colour in Color.kt
-            )
-            Spacer(modifier = Modifier.width(6.dp))
-            Text(
-                text = "Back",
-                color = text, // same colour variable as for the icon
-                style = MaterialTheme.typography.labelMedium
-            )
-        }
-
-        Spacer(modifier = Modifier.height(40.dp))
-
-        Text(
-            text = "Pet Name:",
-            modifier = Modifier.align(Alignment.Start)
-        )
-
-        OutlinedTextField(
-            value = petName,
-            onValueChange = { petName = it },
-            modifier = Modifier.fillMaxWidth(),
-            colors = TextFieldDefaults.outlinedTextFieldColors(
-                containerColor = MaterialTheme.colorScheme.secondary
-            ),
-            textStyle = MaterialTheme.typography.bodyMedium
-        )
-
-        Spacer(modifier = Modifier.height(16.dp))
-
-        Text(
-            text = "Appointment Category:",
-            modifier = Modifier.align(Alignment.Start)
-        )
-
-        OutlinedTextField(
-            value = category,
-            onValueChange = { category = it },
-            modifier = Modifier.fillMaxWidth(),
-            colors = TextFieldDefaults.outlinedTextFieldColors(
-                containerColor = MaterialTheme.colorScheme.secondary
-            ),
-            textStyle = MaterialTheme.typography.bodyMedium
-        )
-
-        Spacer(modifier = Modifier.height(16.dp))
-
-        Text(
-            text = "Description:",
-            modifier = Modifier.align(Alignment.Start)
-        )
-
-        OutlinedTextField(
-            value = description,
-            onValueChange = { description = it },
-            modifier = Modifier.fillMaxWidth(),
-            colors = TextFieldDefaults.outlinedTextFieldColors(
-                containerColor = MaterialTheme.colorScheme.secondary
-            ),
-            textStyle = MaterialTheme.typography.bodyMedium
-        )
-
-        Spacer(modifier = Modifier.height(16.dp))
-
-        if (showDatePicker) {
-            CustomDateTimePickerDialog(
-                selectedDateTime = selectedAppointmentDateTime, // Pass the previously selected date
-
-                onDismiss = { showDatePicker = false },
-                onDateTimeSelected = { dateTime ->
-                    selectedAppointmentDateTime = dateTime
-                }
-            )
-        }
-
-        Spacer(modifier = Modifier.height(8.dp))
-
-        OutlinedButton(
-            onClick = { showDatePicker = true },
-            modifier = Modifier.fillMaxWidth(),
-            colors = ButtonDefaults.buttonColors(
-                containerColor = MaterialTheme.colorScheme.tertiary,
-                contentColor = MaterialTheme.colorScheme.onPrimary
-            ),
-            elevation = ButtonDefaults.elevatedButtonElevation(defaultElevation = 3.dp)
-        ) {
-            Text(
-                text = "Change Date or Time",
-                style = MaterialTheme.typography.labelMedium
-            )
-        }
-
-        Spacer(modifier = Modifier.height(8.dp))
-        selectedAppointmentDateTime.let {
-            val dateTimeString = SimpleDateFormat("MMM dd, yyyy 'at' HH:mm", Locale.getDefault()).format(Date(it))
-            Text(
-                text = "Selected Date and Time: $dateTimeString",
-                modifier = Modifier.padding(2.dp),
-                style = MaterialTheme.typography.labelSmall
-            )
-        }
-
-        Spacer(modifier = Modifier.height(16.dp))
-
-        OutlinedButton(
-            modifier = Modifier.width(200.dp),
-            colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.primary),
-            onClick = {
-                if (petName.isNotBlank()) {
-                    viewModel.editAppointment(
-                        appointmentId!!.toLong(),
-                        petName,
-                        description,
-                        selectedAppointmentDateTime,
-                        category
-                    )
-                    navController.navigateUp()
-                }
-
-            },
-            elevation = ButtonDefaults.elevatedButtonElevation(defaultElevation = 3.dp)
-        ) {
-            Text(
-                text = "Save Changes",
-                style = MaterialTheme.typography.labelMedium
-            )
-        }
-    }
-}
\ No newline at end of file
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentDetailScreen.kt b/app/src/main/java/at/ac/fhstp/pawwatch/ui/DetailScreen.kt
similarity index 89%
rename from app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentDetailScreen.kt
rename to app/src/main/java/at/ac/fhstp/pawwatch/ui/DetailScreen.kt
index 330311a..38940db 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/ui/AppointmentDetailScreen.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/ui/DetailScreen.kt
@@ -11,13 +11,12 @@ import androidx.compose.ui.unit.dp
 import androidx.navigation.NavController
 import at.ac.fhstp.pawwatch.Screens
 import at.ac.fhstp.pawwatch.ui.theme.text
-import java.text.DateFormat
 import java.text.SimpleDateFormat
 import java.util.Date
 import java.util.Locale
 
 @Composable
-fun AppointmentDetailScreen(
+fun DetailScreen(
     appointmentId: String?,
     viewModel: AppointmentViewModel,
     navController: NavController
@@ -26,9 +25,10 @@ fun AppointmentDetailScreen(
 
     Column(
         modifier = Modifier
-            .fillMaxWidth()
+            .fillMaxSize()
             .padding(35.dp),
-        horizontalAlignment = Alignment.CenterHorizontally
+        horizontalAlignment = Alignment.CenterHorizontally,
+        verticalArrangement = Arrangement.Center
     ) {
         // Back Button
         OutlinedButton(
@@ -58,15 +58,16 @@ fun AppointmentDetailScreen(
             Text(
                 it.petName,
                 style = MaterialTheme.typography.headlineMedium,
-                modifier = Modifier.padding(2.dp)
+                //modifier = Modifier.padding(2.dp)
             )
+            Spacer(modifier = Modifier.height(9.dp))
 
             Text(
                 it.category,
                 style = MaterialTheme.typography.bodyLarge,
-                modifier = Modifier.padding(2.dp)
+                //modifier = Modifier.padding(2.dp)
             )
-            Spacer(modifier = Modifier.height(10.dp))
+            Spacer(modifier = Modifier.height(20.dp))
 
             val date = Date(appointment.appointmentDateTime)
 
@@ -75,7 +76,7 @@ fun AppointmentDetailScreen(
 
             Text(
                 dateFormat.format(date),
-                style = MaterialTheme.typography.bodyMedium
+                style = MaterialTheme.typography.labelSmall
             )
 
             Spacer(modifier = Modifier.height(20.dp))
@@ -86,7 +87,7 @@ fun AppointmentDetailScreen(
                 modifier = Modifier.padding(2.dp)
             )
 
-            Spacer(modifier = Modifier.height(30.dp))
+            Spacer(modifier = Modifier.height(50.dp))
 
             Row {
                 // Edit Button
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/ui/EditScreen.kt b/app/src/main/java/at/ac/fhstp/pawwatch/ui/EditScreen.kt
new file mode 100644
index 0000000..0e91f39
--- /dev/null
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/ui/EditScreen.kt
@@ -0,0 +1,206 @@
+package at.ac.fhstp.pawwatch.ui
+
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.automirrored.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 androidx.navigation.NavController
+import at.ac.fhstp.pawwatch.ui.theme.text
+import java.sql.Date
+import java.text.SimpleDateFormat
+import java.util.Locale
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+fun EditScreen(
+    appointmentId: String?,
+    viewModel: AppointmentViewModel,
+    navController: NavController
+) {
+    val appointment = appointmentId?.let { id -> viewModel.getAppointmentById(id.toLong()) }
+    var petName by remember { mutableStateOf(appointment?.petName ?: "") }
+    var description by remember { mutableStateOf(appointment?.description ?: "") }
+    var selectedAppointmentDateTime by remember { mutableLongStateOf(appointment?.appointmentDateTime ?: System.currentTimeMillis()) }
+    var category by remember { mutableStateOf(appointment?.category ?: "") }
+
+    var showDatePicker by remember { mutableStateOf(false) }
+
+    Box(
+        modifier = Modifier
+            .fillMaxSize()
+            .padding(35.dp) // Padding for spacing within the screen
+    ) {
+        // Back Button at Top-Start
+        OutlinedButton(
+            onClick = {
+                navController.navigateUp()
+            },
+            modifier = Modifier
+                .align(Alignment.TopStart), // Aligns the button at the top-left corner
+                //.padding(8.dp), // Add padding around the button
+            colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.background),
+            elevation = ButtonDefaults.elevatedButtonElevation(defaultElevation = 3.dp),
+        ) {
+            Icon(
+                imageVector = Icons.AutoMirrored.Filled.ArrowBack,
+                contentDescription = "Back",
+                tint = text
+            )
+            Spacer(modifier = Modifier.width(6.dp))
+            Text(
+                text = "Back",
+                color = text,
+                style = MaterialTheme.typography.labelMedium
+            )
+        }
+
+        // Rest of the content
+        Column(
+            modifier = Modifier
+                .fillMaxSize()
+                .padding(top = 45.dp), // Leave space for the back button
+            horizontalAlignment = Alignment.CenterHorizontally,
+            verticalArrangement = Arrangement.Center
+        ) {
+            Text(
+                text = "Edit Appointment",
+                style = MaterialTheme.typography.headlineMedium
+            )
+
+            Spacer(modifier = Modifier.height(25.dp))
+
+            Text(
+                text = "Pet Name:",
+                modifier = Modifier.align(Alignment.Start)
+            )
+            Spacer(modifier = Modifier.height(5.dp))
+
+            OutlinedTextField(
+                value = petName,
+                onValueChange = { petName = it },
+                modifier = Modifier.fillMaxWidth(),
+                colors = TextFieldDefaults.outlinedTextFieldColors(
+                    containerColor = MaterialTheme.colorScheme.secondary
+                ),
+                textStyle = MaterialTheme.typography.bodyMedium
+            )
+
+            Spacer(modifier = Modifier.height(20.dp))
+
+            Text(
+                text = "Appointment Category:",
+                modifier = Modifier.align(Alignment.Start)
+            )
+            Spacer(modifier = Modifier.height(5.dp))
+
+            OutlinedTextField(
+                value = category,
+                onValueChange = { category = it },
+                modifier = Modifier.fillMaxWidth(),
+                colors = TextFieldDefaults.outlinedTextFieldColors(
+                    containerColor = MaterialTheme.colorScheme.secondary
+                ),
+                textStyle = MaterialTheme.typography.bodyMedium
+            )
+
+            Spacer(modifier = Modifier.height(20.dp))
+
+            Text(
+                text = "Description (Optional):",
+                modifier = Modifier.align(Alignment.Start)
+            )
+            Spacer(modifier = Modifier.height(5.dp))
+
+            OutlinedTextField(
+                value = description,
+                onValueChange = { description = it },
+                modifier = Modifier
+                    .fillMaxWidth()
+                    .heightIn(max = 100.dp) // Restrict the height
+                    .let { modifier ->
+                        if (description.length > 200) {
+                            modifier.verticalScroll(rememberScrollState()) // Enable scroll if content exceeds 200 characters
+                        } else {
+                            modifier
+                        }
+                    },
+                colors = TextFieldDefaults.outlinedTextFieldColors(
+                    containerColor = MaterialTheme.colorScheme.secondary
+                ),
+                textStyle = MaterialTheme.typography.bodyMedium
+            )
+
+
+            Spacer(modifier = Modifier.height(20.dp))
+
+            if (showDatePicker) {
+                CustomDateTimePickerDialog(
+                    selectedDateTime = selectedAppointmentDateTime,
+                    onDismiss = { showDatePicker = false },
+                    onDateTimeSelected = { dateTime ->
+                        selectedAppointmentDateTime = dateTime
+                    }
+                )
+            }
+
+            Spacer(modifier = Modifier.height(8.dp))
+
+            OutlinedButton(
+                onClick = { showDatePicker = true },
+                modifier = Modifier.fillMaxWidth(),
+                colors = ButtonDefaults.buttonColors(
+                    containerColor = MaterialTheme.colorScheme.tertiary,
+                    contentColor = MaterialTheme.colorScheme.onPrimary
+                ),
+                elevation = ButtonDefaults.elevatedButtonElevation(defaultElevation = 3.dp)
+            ) {
+                Text(
+                    text = "Change Date or Time",
+                    style = MaterialTheme.typography.labelMedium
+                )
+            }
+
+            Spacer(modifier = Modifier.height(8.dp))
+            selectedAppointmentDateTime.let {
+                val dateTimeString =
+                    SimpleDateFormat("MMM dd, yyyy 'at' HH:mm", Locale.getDefault()).format(Date(it))
+                Text(
+                    text = "Selected Date and Time: $dateTimeString",
+                    modifier = Modifier.padding(2.dp),
+                    style = MaterialTheme.typography.labelSmall
+                )
+            }
+
+            Spacer(modifier = Modifier.height(35.dp))
+
+            OutlinedButton(
+                modifier = Modifier.width(200.dp),
+                colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.primary),
+                onClick = {
+                    if (petName.isNotBlank()) {
+                        viewModel.editAppointment(
+                            appointmentId!!.toLong(),
+                            petName,
+                            description,
+                            selectedAppointmentDateTime,
+                            category
+                        )
+                        navController.navigateUp()
+                    }
+                },
+                elevation = ButtonDefaults.elevatedButtonElevation(defaultElevation = 3.dp)
+            ) {
+                Text(
+                    text = "Save Changes",
+                    style = MaterialTheme.typography.labelMedium
+                )
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/ui/OverviewScreen.kt b/app/src/main/java/at/ac/fhstp/pawwatch/ui/OverviewScreen.kt
index ca20d21..012224e 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/ui/OverviewScreen.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/ui/OverviewScreen.kt
@@ -42,7 +42,7 @@ fun OverviewScreen(
             style = MaterialTheme.typography.headlineMedium
         )
 
-        Spacer(modifier = Modifier.height(20.dp))
+        Spacer(modifier = Modifier.height(30.dp))
 
         LazyColumn(
             modifier = Modifier.fillMaxWidth()
@@ -90,12 +90,19 @@ fun AppointmentCard(
             )
             Spacer(modifier = Modifier.height(10.dp))
 
+            val shortenDescription = if (appointment.description.length > 70) {
+                "${appointment.description.take(70)}..."
+            } else {
+                appointment.description
+            }
+
             Text(
-                appointment.description,
+                shortenDescription,
                 style = MaterialTheme.typography.bodyMedium
             )
             Spacer(modifier = Modifier.height(14.dp))
 
+
             val date = Date(appointment.appointmentDateTime)
             val dateFormat = SimpleDateFormat("MMM dd, yyyy 'at' HH:mm", Locale.getDefault())
 
-- 
GitLab


From 18bb5ebee858fb35cfd2c867968e102ce2b95a76 Mon Sep 17 00:00:00 2001
From: Sofiia-Khrystyna <sonia030605@gmail.com>
Date: Sat, 18 Jan 2025 01:42:52 +0100
Subject: [PATCH 09/10] :art: added filter buttons + colouring of the missed
 appointments and the ones that are tmrw are done

---
 .../at/ac/fhstp/pawwatch/ui/OverviewScreen.kt | 112 +++++++++++++++++-
 .../at/ac/fhstp/pawwatch/ui/theme/Color.kt    |   3 +-
 .../at/ac/fhstp/pawwatch/ui/theme/Theme.kt    |   1 +
 3 files changed, 109 insertions(+), 7 deletions(-)

diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/ui/OverviewScreen.kt b/app/src/main/java/at/ac/fhstp/pawwatch/ui/OverviewScreen.kt
index 012224e..2c96abf 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/ui/OverviewScreen.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/ui/OverviewScreen.kt
@@ -6,11 +6,15 @@ import androidx.compose.foundation.lazy.items
 import androidx.compose.material3.ButtonDefaults
 import androidx.compose.material3.CardDefaults
 import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.OutlinedButton
 import androidx.compose.material3.OutlinedCard
 import androidx.compose.material3.Text
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.collectAsState
 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.unit.dp
@@ -19,6 +23,7 @@ import at.ac.fhstp.pawwatch.Screens
 import at.ac.fhstp.pawwatch.data.db.AppointmentEntity
 import java.sql.Date
 import java.text.SimpleDateFormat
+import java.util.Calendar
 import java.util.Locale
 
 @Composable
@@ -27,13 +32,26 @@ fun OverviewScreen(
     navController: NavController
 ) {
     val appointments by viewModel.appointments.collectAsState()
+    // State to store the filter type
+    var filterType by remember { mutableStateOf(FilterType.ALL) }
+
+    // Filter appointments based on the selected filter type
+    val filteredAppointments = when (filterType) {
+        FilterType.PAST -> appointments.filter { it.appointmentDateTime < System.currentTimeMillis() }
+        FilterType.UPCOMING -> appointments.filter { it.appointmentDateTime >= System.currentTimeMillis() }
+        else -> appointments // ALL
+    }
+
+    // Sort appointments by date
+    val sortedAppointments = filteredAppointments.sortedBy { it.appointmentDateTime }
+
 
     Column(
         modifier = Modifier
             .fillMaxSize()
             .padding(35.dp),
         horizontalAlignment = Alignment.CenterHorizontally,
-        verticalArrangement = Arrangement.Center
+        //verticalArrangement = Arrangement.Center
     ) {
         Spacer(modifier = Modifier.height(10.dp))
 
@@ -44,10 +62,25 @@ fun OverviewScreen(
 
         Spacer(modifier = Modifier.height(30.dp))
 
+        // Filter buttons
+        Row(
+            modifier = Modifier
+                .fillMaxWidth(),
+            horizontalArrangement = Arrangement.SpaceEvenly,
+            verticalAlignment = Alignment.CenterVertically,
+        ) {
+            FilterButton("All", FilterType.ALL, filterType) { filterType = it }
+            FilterButton("Past", FilterType.PAST, filterType) { filterType = it }
+            FilterButton("Upcoming", FilterType.UPCOMING, filterType) { filterType = it }
+        }
+
+        Spacer(modifier = Modifier.height(20.dp))
+
+        // Display sorted and filtered appointments
         LazyColumn(
             modifier = Modifier.fillMaxWidth()
         ) {
-            items(appointments) { appointment ->
+            items(sortedAppointments) { appointment ->
                 AppointmentCard(appointment = appointment) {
                     navController.navigate(
                         Screens.AppointmentDetails(appointmentId = appointment.id.toString()).createRoute(
@@ -66,6 +99,22 @@ fun AppointmentCard(
     appointment: AppointmentEntity,
     onClick: () -> Unit
 ) {
+    val date = Date(appointment.appointmentDateTime)
+    val dateFormat = SimpleDateFormat("MMM dd, yyyy 'at' HH:mm", Locale.getDefault())
+
+    // Get today's date and the appointment date
+    val calendar = Calendar.getInstance()
+    val today = calendar.apply { set(Calendar.HOUR_OF_DAY, 0); set(Calendar.MINUTE, 0); set(Calendar.SECOND, 0) }
+    val tomorrow = calendar.apply { add(Calendar.DATE, 1) }
+    val appointmentCalendar = Calendar.getInstance().apply { time = date }
+
+    // Check if the appointment is tomorrow
+    val isTomorrow = appointmentCalendar.get(Calendar.YEAR) == tomorrow.get(Calendar.YEAR) &&
+            appointmentCalendar.get(Calendar.DAY_OF_YEAR) == tomorrow.get(Calendar.DAY_OF_YEAR)
+
+    // Check if the appointment is missed
+    val isMissed = appointment.appointmentDateTime < System.currentTimeMillis()
+
     OutlinedCard(
         modifier = Modifier
             .fillMaxWidth()
@@ -102,14 +151,65 @@ fun AppointmentCard(
             )
             Spacer(modifier = Modifier.height(14.dp))
 
-
-            val date = Date(appointment.appointmentDateTime)
-            val dateFormat = SimpleDateFormat("MMM dd, yyyy 'at' HH:mm", Locale.getDefault())
+            // Appointment date with conditional coloring
+            val dateColor = when {
+                isMissed -> MaterialTheme.colorScheme.error // Red for missed appointments
+                isTomorrow -> MaterialTheme.colorScheme.onSecondary // Orange for tomorrow
+                else -> MaterialTheme.colorScheme.onPrimary // Default color
+            }
 
             Text(
                 dateFormat.format(date),
-                style = MaterialTheme.typography.bodyMedium
+                style = MaterialTheme.typography.labelSmall,
+                color = dateColor
             )
+
+            // Missed label
+            if (isMissed) {
+                Text(
+                    text = "Missed",
+                    style = MaterialTheme.typography.labelSmall,
+                    modifier = Modifier.padding(top = 4.dp),
+                    color = MaterialTheme.colorScheme.error
+                )
+            }
+
+            if (isTomorrow) {
+                Text(
+                    text = "Tomorrow",
+                    style = MaterialTheme.typography.labelSmall,
+                    modifier = Modifier.padding(top = 4.dp),
+                    color = MaterialTheme.colorScheme.onSecondary
+                )
+            }
         }
     }
+}
+
+@Composable
+fun FilterButton(
+    text: String,
+    filterType: FilterType,
+    currentFilterType: FilterType,
+    onClick: (FilterType) -> Unit
+) {
+    OutlinedButton(
+        onClick = { onClick(filterType) },
+        colors = ButtonDefaults.buttonColors(
+            containerColor = if (filterType == currentFilterType) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.secondary
+        ),
+        modifier = Modifier
+            .padding(horizontal = 5.dp) // Add some horizontal padding to make buttons smaller
+            .height(40.dp), // Set a fixed height to control the button size
+        elevation = ButtonDefaults.elevatedButtonElevation(defaultElevation = 4.dp)
+    ) {
+        Text(
+            text = text,
+            style = MaterialTheme.typography.bodyMedium
+        )
+    }
+}
+
+enum class FilterType {
+    ALL, PAST, UPCOMING
 }
\ No newline at end of file
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/ui/theme/Color.kt b/app/src/main/java/at/ac/fhstp/pawwatch/ui/theme/Color.kt
index 22987b9..954cfcc 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/ui/theme/Color.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/ui/theme/Color.kt
@@ -8,4 +8,5 @@ val lightButtonBg = Color(0xFFFFCE93)
 val appointmentBg = Color(0xFFF8F8F8)
 val text = Color(0xFF000000)
 val fieldBg = Color(0xFFFFF4DE)
-val deleteButtonBg = Color(0xFFE04F47)
\ No newline at end of file
+val deleteButtonBg = Color(0xFFE04F47)
+val dateLabel = Color(0xFFFF9800)
\ No newline at end of file
diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/ui/theme/Theme.kt b/app/src/main/java/at/ac/fhstp/pawwatch/ui/theme/Theme.kt
index 8792eb1..17bcd78 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/ui/theme/Theme.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/ui/theme/Theme.kt
@@ -9,6 +9,7 @@ private val AppColorScheme = lightColorScheme(
     primary = buttonBg,
     onPrimary = text,
     secondary = fieldBg,
+    onSecondary = dateLabel,
     tertiary = lightButtonBg,
     tertiaryContainer = appointmentBg,
     error = deleteButtonBg
-- 
GitLab


From 012d069507e5de2b142862406783a3e1a92e91fb Mon Sep 17 00:00:00 2001
From: Sofiia-Khrystyna <sonia030605@gmail.com>
Date: Sat, 18 Jan 2025 01:49:41 +0100
Subject: [PATCH 10/10] :art: back button on details screen is now aligned at
 the top properly

---
 .../at/ac/fhstp/pawwatch/ui/DetailScreen.kt   | 148 ++++++++++--------
 1 file changed, 80 insertions(+), 68 deletions(-)

diff --git a/app/src/main/java/at/ac/fhstp/pawwatch/ui/DetailScreen.kt b/app/src/main/java/at/ac/fhstp/pawwatch/ui/DetailScreen.kt
index 38940db..dcb6987 100644
--- a/app/src/main/java/at/ac/fhstp/pawwatch/ui/DetailScreen.kt
+++ b/app/src/main/java/at/ac/fhstp/pawwatch/ui/DetailScreen.kt
@@ -23,105 +23,117 @@ fun DetailScreen(
 ) {
     val appointment = appointmentId?.let { id -> viewModel.getAppointmentById(id.toLong()) }
 
-    Column(
+    Box(
         modifier = Modifier
             .fillMaxSize()
-            .padding(35.dp),
-        horizontalAlignment = Alignment.CenterHorizontally,
-        verticalArrangement = Arrangement.Center
+            .padding(35.dp) // Padding for spacing within the screen
     ) {
-        // Back Button
+        // Back Button at Top-Start
         OutlinedButton(
             onClick = {
                 navController.navigateUp()
             },
-            modifier = Modifier.align(Alignment.Start),
+            modifier = Modifier
+                .align(Alignment.TopStart), // Aligns the button at the top-left corner
+            //.padding(8.dp), // Add padding around the button
             colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.background),
-            elevation = ButtonDefaults.elevatedButtonElevation(defaultElevation = 3.dp)
+            elevation = ButtonDefaults.elevatedButtonElevation(defaultElevation = 3.dp),
         ) {
             Icon(
                 imageVector = Icons.AutoMirrored.Filled.ArrowBack,
                 contentDescription = "Back",
-                tint = text // "text" is the variable which contains black colour in Color.kt
+                tint = text
             )
             Spacer(modifier = Modifier.width(6.dp))
             Text(
                 text = "Back",
-                color = text, // same colour variable as for the icon
+                color = text,
                 style = MaterialTheme.typography.labelMedium
             )
         }
 
-        Spacer(modifier = Modifier.height(60.dp))
+        //Spacer(modifier = Modifier.height(60.dp))
 
-        appointment?.let {
-            Text(
-                it.petName,
-                style = MaterialTheme.typography.headlineMedium,
-                //modifier = Modifier.padding(2.dp)
-            )
-            Spacer(modifier = Modifier.height(9.dp))
+        // Rest of the content
+        Column(
+            modifier = Modifier
+                .fillMaxSize()
+                .padding(top = 45.dp), // Leave space for the back button
+            horizontalAlignment = Alignment.CenterHorizontally,
+            verticalArrangement = Arrangement.Center
+        ) {
+            appointment?.let {
+                Text(
+                    it.petName,
+                    style = MaterialTheme.typography.headlineMedium,
+                    //modifier = Modifier.padding(2.dp)
+                )
+                Spacer(modifier = Modifier.height(9.dp))
 
-            Text(
-                it.category,
-                style = MaterialTheme.typography.bodyLarge,
-                //modifier = Modifier.padding(2.dp)
-            )
-            Spacer(modifier = Modifier.height(20.dp))
+                Text(
+                    it.category,
+                    style = MaterialTheme.typography.bodyLarge,
+                    //modifier = Modifier.padding(2.dp)
+                )
+                Spacer(modifier = Modifier.height(20.dp))
 
-            val date = Date(appointment.appointmentDateTime)
+                val date = Date(appointment.appointmentDateTime)
 
-            // Use SimpleDateFormat for 24-hour time format (HH:mm)
-            val dateFormat = SimpleDateFormat("MMM dd, yyyy 'at' HH:mm", Locale.getDefault())
+                // Use SimpleDateFormat for 24-hour time format (HH:mm)
+                val dateFormat = SimpleDateFormat("MMM dd, yyyy 'at' HH:mm", Locale.getDefault())
 
-            Text(
-                dateFormat.format(date),
-                style = MaterialTheme.typography.labelSmall
-            )
+                Text(
+                    dateFormat.format(date),
+                    style = MaterialTheme.typography.labelSmall
+                )
 
-            Spacer(modifier = Modifier.height(20.dp))
+                Spacer(modifier = Modifier.height(20.dp))
 
-            Text(
-                it.description,
-                style = MaterialTheme.typography.bodyMedium,
-                modifier = Modifier.padding(2.dp)
-            )
+                Text(
+                    it.description,
+                    style = MaterialTheme.typography.bodyMedium,
+                    modifier = Modifier.padding(2.dp)
+                )
 
-            Spacer(modifier = Modifier.height(50.dp))
+                Spacer(modifier = Modifier.height(50.dp))
 
-            Row {
-                // Edit Button
-                OutlinedButton(
-                    colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.primary),
-                    onClick = {
-                        // Navigate using the sealed class route
-                        navController.navigate(Screens.EditAppointment(it.id.toString()).createRoute(it.id.toString()))
-                    },
-                    modifier = Modifier.width(150.dp),
-                    elevation = ButtonDefaults.elevatedButtonElevation(defaultElevation = 3.dp)
-                ) {
-                    Text(
-                        text = "Edit",
-                        style = MaterialTheme.typography.labelMedium
-                    )
-                }
+                Row {
+                    // Edit Button
+                    OutlinedButton(
+                        colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.primary),
+                        onClick = {
+                            // Navigate using the sealed class route
+                            navController.navigate(
+                                Screens.EditAppointment(it.id.toString())
+                                    .createRoute(it.id.toString())
+                            )
+                        },
+                        modifier = Modifier.width(150.dp),
+                        elevation = ButtonDefaults.elevatedButtonElevation(defaultElevation = 3.dp)
+                    ) {
+                        Text(
+                            text = "Edit",
+                            style = MaterialTheme.typography.labelMedium
+                        )
+                    }
 
-                Spacer(modifier = Modifier.width(40.dp))
+                    Spacer(modifier = Modifier.width(40.dp))
 
-                // Delete Button
-                OutlinedButton(
-                    colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.error),
-                    onClick = {
-                        viewModel.deleteAppointment(it.id.toLong()) // Call delete logic
-                        navController.navigateUp()
-                    },
-                    modifier = Modifier.width(150.dp),
-                    elevation = ButtonDefaults.elevatedButtonElevation(defaultElevation = 3.dp)
-                ) {
-                    Text(
-                        text = "Delete",
-                        style = MaterialTheme.typography.labelMedium
-                    )
+                    // Delete Button
+                    OutlinedButton(
+                        colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.error),
+                        onClick = {
+                            viewModel.deleteAppointment(it.id.toLong()) // Call delete logic
+                            navController.navigateUp()
+                        },
+                        modifier = Modifier.width(150.dp),
+                        elevation = ButtonDefaults.elevatedButtonElevation(defaultElevation = 3.dp)
+                    ) {
+                        Text(
+                            text = "Delete",
+                            style = MaterialTheme.typography.labelMedium
+                        )
+                    }
                 }
             }
         }
-- 
GitLab