Version 3.1(After Revision):

Added Lihat Laporan Button in dashboard to move into the new Chart
Added Indonesia Full Translation Full
This commit is contained in:
Diassdp
2025-05-16 20:17:45 +07:00
parent 7474a84575
commit 1aa29f0e23
22 changed files with 682 additions and 230 deletions

View File

@ -50,6 +50,7 @@ dependencies {
implementation("androidx.navigation:navigation-fragment-ktx:2.7.7") implementation("androidx.navigation:navigation-fragment-ktx:2.7.7")
implementation("androidx.navigation:navigation-ui-ktx:2.7.7") implementation("androidx.navigation:navigation-ui-ktx:2.7.7")
implementation ("com.github.PhilJay:MPAndroidChart:v3.1.0")
// Firebase libraries // Firebase libraries
implementation(libs.firebase.database) implementation(libs.firebase.database)

View File

@ -0,0 +1,62 @@
import android.content.Context
import android.content.Intent
import android.graphics.Rect
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import com.github.mikephil.charting.components.MarkerView
import com.github.mikephil.charting.data.Entry
import com.github.mikephil.charting.highlight.Highlight
import com.github.mikephil.charting.utils.MPPointF
import com.healthjournal.R
import com.healthjournal.data.ResultData
import com.healthjournal.ui.journal.detail.DetailJournalActivity
class MyMarkerView(
private val context: Context,
private val dataList: List<ResultData>
) : MarkerView(context, R.layout.marker_view) {
private val tvContent: TextView = findViewById(R.id.tvContent)
private var lastHighlightedIndex: Int? = null
override fun refreshContent(e: Entry?, highlight: Highlight?) {
e?.let {
val index = e.x.toInt()
lastHighlightedIndex = index
if (index in dataList.indices) {
val item = dataList[index]
val content = """
Hari: ${getIndonesianDayName(item.date)}
Tanggal: ${item.date}
Gula Darah: ${item.bloodSugar}
BMI: ${item.BMI.toString().substring(0, 4)}
Tekanan Darah: ${item.systolicBP}/${item.diastolicBP} mmHg
""".trimIndent()
tvContent.text = content
} else {
tvContent.text = ""
}
}
super.refreshContent(e, highlight)
}
override fun getOffset(): MPPointF {
return MPPointF(-(width / 2).toFloat(), -height.toFloat())
}
private fun getIndonesianDayName(dateString: String): String {
return try {
val sdf = java.text.SimpleDateFormat("dd/MM/yyyy", java.util.Locale("id", "ID"))
val date = sdf.parse(dateString)
if (date != null) {
val dayFormat = java.text.SimpleDateFormat("EEEE", java.util.Locale("id", "ID"))
dayFormat.format(date)
} else {
"-"
}
} catch (e: Exception) {
"-"
}
}
}

View File

@ -23,6 +23,7 @@ import com.healthjournal.data.ResultData
import com.healthjournal.databinding.ActivityMainBinding import com.healthjournal.databinding.ActivityMainBinding
import com.healthjournal.receiver.ReminderReceiver import com.healthjournal.receiver.ReminderReceiver
import com.healthjournal.ui.journal.input.JournalInputActivity import com.healthjournal.ui.journal.input.JournalInputActivity
import com.healthjournal.ui.laporan
import com.healthjournal.ui.login.LoginActivity import com.healthjournal.ui.login.LoginActivity
import com.healthjournal.ui.profile.ProfileActivity import com.healthjournal.ui.profile.ProfileActivity
import com.healthjournal.ui.recommendation.RecommendationActivity import com.healthjournal.ui.recommendation.RecommendationActivity
@ -56,12 +57,12 @@ class MainActivity : AppCompatActivity() {
private fun scheduleHealthReminders(context: Context) { private fun scheduleHealthReminders(context: Context) {
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
val daysOfWeek = listOf(Calendar.MONDAY, Calendar.WEDNESDAY, Calendar.FRIDAY) val daysOfWeek = listOf(Calendar.MONDAY, Calendar.WEDNESDAY, Calendar.FRIDAY)
for (day in daysOfWeek.shuffled().take(3)) { for (day in daysOfWeek.shuffled().take(3)) {
val calendar = Calendar.getInstance().apply { val calendar = Calendar.getInstance().apply {
set(Calendar.DAY_OF_WEEK, day) set(Calendar.DAY_OF_WEEK, day)
set(Calendar.HOUR_OF_DAY, 9) // Set reminder at 9 AM set(Calendar.HOUR_OF_DAY, 9)
set(Calendar.MINUTE, 0) set(Calendar.MINUTE, 0)
set(Calendar.SECOND, 0) set(Calendar.SECOND, 0)
} }
@ -74,13 +75,12 @@ class MainActivity : AppCompatActivity() {
alarmManager.setRepeating( alarmManager.setRepeating(
AlarmManager.RTC_WAKEUP, AlarmManager.RTC_WAKEUP,
calendar.timeInMillis, calendar.timeInMillis,
AlarmManager.INTERVAL_DAY * 7, // Repeat every week AlarmManager.INTERVAL_DAY * 7,
pendingIntent pendingIntent
) )
} }
} }
private fun navigationBottomBar() { private fun navigationBottomBar() {
val bottomNav = findViewById<BottomNavigationView>(R.id.nav_view) val bottomNav = findViewById<BottomNavigationView>(R.id.nav_view)
@ -102,14 +102,13 @@ class MainActivity : AppCompatActivity() {
binding.ivAdd.setOnClickListener { binding.ivAdd.setOnClickListener {
if (dailyReport) { if (dailyReport) {
Toast.makeText(this, "Daily Report Already Created", Toast.LENGTH_SHORT).show() Toast.makeText(this, "Laporan harian sudah dibuat", Toast.LENGTH_SHORT).show()
} else { } else {
startActivity(Intent(this, JournalInputActivity::class.java)) startActivity(Intent(this, JournalInputActivity::class.java))
} }
} }
} }
private fun getWeekCount() { private fun getWeekCount() {
val today = Calendar.getInstance() val today = Calendar.getInstance()
val userID = user.currentUser!!.uid val userID = user.currentUser!!.uid
@ -117,11 +116,9 @@ class MainActivity : AppCompatActivity() {
val dateFormat = SimpleDateFormat("dd/MM/yyyy", Locale.getDefault()) val dateFormat = SimpleDateFormat("dd/MM/yyyy", Locale.getDefault())
// Set start of the week (Sunday)
today.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY) today.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY)
val startDate = today.time val startDate = today.time
// Set end of the week (Saturday)
val endDate = today.clone() as Calendar val endDate = today.clone() as Calendar
endDate.add(Calendar.DAY_OF_WEEK, 6) endDate.add(Calendar.DAY_OF_WEEK, 6)
val endDateDate = endDate.time val endDateDate = endDate.time
@ -138,7 +135,7 @@ class MainActivity : AppCompatActivity() {
} }
entryDate?.let { it in startDate..endDateDate } ?: false entryDate?.let { it in startDate..endDateDate } ?: false
} }
Log.d("debug", "Entries found: $count for week: ${dateFormat.format(startDate)} - ${dateFormat.format(endDateDate)}") Log.d("debug", "Jumlah entri: $count minggu ini: ${dateFormat.format(startDate)} - ${dateFormat.format(endDateDate)}")
binding.tvDailyCounter.text = "$count/7" binding.tvDailyCounter.text = "$count/7"
} else { } else {
Log.e("error", task.exception?.message.toString()) Log.e("error", task.exception?.message.toString())
@ -147,39 +144,43 @@ class MainActivity : AppCompatActivity() {
} }
} }
private fun setupListener() {
private fun setupListener(){
binding.btnRecomendation.setOnClickListener { binding.btnRecomendation.setOnClickListener {
startActivity(Intent(this, RecommendationActivity::class.java)) startActivity(Intent(this, RecommendationActivity::class.java))
} }
binding.btnInputData.setOnClickListener { binding.btnInputData.setOnClickListener {
startActivity(Intent(this, JournalInputActivity::class.java)) startActivity(Intent(this, JournalInputActivity::class.java))
} }
binding.btnReport.setOnClickListener {
val intent = Intent(this, laporan::class.java)
intent.putExtra("healthDataList", ArrayList(healthDataList))
startActivity(intent)
}
} }
private fun dailycheck() { private fun dailycheck() {
getWeekCount() getWeekCount()
val today = SimpleDateFormat("dd/MM/yyyy", Locale.getDefault()).format(android.icu.util.Calendar.getInstance().time).toString() val today = SimpleDateFormat("dd/MM/yyyy", Locale.getDefault()).format(Calendar.getInstance().time)
val userID = user.currentUser!!.uid val userID = user.currentUser!!.uid
database.getReference("users").child(userID).child("journal").get().addOnCompleteListener { task -> database.getReference("users").child(userID).child("journal").get().addOnCompleteListener { task ->
if (task.isSuccessful) { if (task.isSuccessful) {
task.result.children.forEach { task.result.children.forEach {
if (it.child("date").value.toString() == today) { if (it.child("date").value.toString() == today) {
dailyReport = true dailyReport = true
switchLayout() switchLayout()
val referencePath = it.key ?: return@forEach val referencePath = it.key ?: return@forEach
populateTodayReport(referencePath) populateTodayReport(referencePath)
}
} }
} else {
Log.d("error", task.exception!!.message.toString())
Toast.makeText(this, task.exception!!.message, Toast.LENGTH_SHORT).show()
} }
} else {
Log.d("error", task.exception!!.message.toString())
Toast.makeText(this, task.exception!!.message, Toast.LENGTH_SHORT).show()
}
} }
} }
private fun switchLayout(){ private fun switchLayout() {
if (binding.clDailyReport1.visibility == View.VISIBLE){ if (binding.clDailyReport1.visibility == View.VISIBLE) {
binding.clDailyReport1.visibility = View.INVISIBLE binding.clDailyReport1.visibility = View.INVISIBLE
binding.clDailyReport2.visibility = View.VISIBLE binding.clDailyReport2.visibility = View.VISIBLE
binding.btnRecomendation.visibility = View.VISIBLE binding.btnRecomendation.visibility = View.VISIBLE
@ -206,17 +207,17 @@ class MainActivity : AppCompatActivity() {
userRef.get().addOnCompleteListener { task -> userRef.get().addOnCompleteListener { task ->
if (task.isSuccessful) { if (task.isSuccessful) {
if (task.result.exists() && task.result.childrenCount > 0) { if (task.result.exists() && task.result.childrenCount > 0) {
Toast.makeText(this, "Selamat Kembali!", Toast.LENGTH_SHORT).show() Toast.makeText(this, "Selamat datang kembali!", Toast.LENGTH_SHORT).show()
dailycheck() dailycheck()
getWeekCount() getWeekCount()
populateHistory() populateHistory()
} else { } else {
Toast.makeText(this, "Tidak ada user data kesehatan. Tolong isi data kesehatan profile.", Toast.LENGTH_LONG).show() Toast.makeText(this, "Data kesehatan belum tersedia. Silakan isi profil terlebih dahulu.", Toast.LENGTH_LONG).show()
startActivity(Intent(this@MainActivity, UsersInputActivity::class.java)) startActivity(Intent(this@MainActivity, UsersInputActivity::class.java))
finish() finish()
} }
} else { } else {
Toast.makeText(this, "Failed to retrieve user data.", Toast.LENGTH_SHORT).show() Toast.makeText(this, "Gagal mengambil data pengguna.", Toast.LENGTH_SHORT).show()
} }
} }
} else { } else {
@ -244,7 +245,7 @@ class MainActivity : AppCompatActivity() {
val bloodSugar = data.child("bloodSugar").value.toString().toFloatOrNull() ?: 0f val bloodSugar = data.child("bloodSugar").value.toString().toFloatOrNull() ?: 0f
val diastolicBP = data.child("bloodPressureDIA").value.toString().toIntOrNull() ?: 0 val diastolicBP = data.child("bloodPressureDIA").value.toString().toIntOrNull() ?: 0
val systolicBP = data.child("bloodPressureSYS").value.toString().toIntOrNull() ?: 0 val systolicBP = data.child("bloodPressureSYS").value.toString().toIntOrNull() ?: 0
val BMI = data.child("bmi").value.toString().toFloatOrNull() ?: 0f val BMI = data.child("BMI").value.toString().toFloatOrNull() ?: 0f
val date = data.child("date").value.toString() val date = data.child("date").value.toString()
val task = data.child("recommendation").child("tasks").value as? List<Map<String, Any>> ?: emptyList() val task = data.child("recommendation").child("tasks").value as? List<Map<String, Any>> ?: emptyList()
@ -265,10 +266,9 @@ class MainActivity : AppCompatActivity() {
}) })
} }
private fun populateTodayReport(referencePath: String) { private fun populateTodayReport(referencePath: String) {
if (!::user.isInitialized || user.currentUser == null) { if (!::user.isInitialized || user.currentUser == null) {
Log.e("MainActivity", "User not logged in, cannot fetch today's report") Log.e("MainActivity", "Pengguna belum login, tidak bisa ambil laporan hari ini.")
return return
} }
@ -284,7 +284,7 @@ class MainActivity : AppCompatActivity() {
binding.tvBmiLevel.text = String.format(Locale.getDefault(), "%.2f BMI", bmiValue) binding.tvBmiLevel.text = String.format(Locale.getDefault(), "%.2f BMI", bmiValue)
binding.tvBmiDesc.text = it.result.child("recommendation").child("BMIAnalysis").value.toString() binding.tvBmiDesc.text = it.result.child("recommendation").child("BMIAnalysis").value.toString()
} else { } else {
Log.e("MainActivity", "Error fetching today's report: ${it.exception?.message}") Log.e("MainActivity", "Gagal mengambil laporan hari ini: ${it.exception?.message}")
Toast.makeText(this, it.exception?.message, Toast.LENGTH_SHORT).show() Toast.makeText(this, it.exception?.message, Toast.LENGTH_SHORT).show()
} }
} }

View File

@ -1,7 +1,6 @@
package com.healthjournal.ui.dashboard package com.healthjournal.ui.dashboard
import android.content.Intent import android.content.Intent
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@ -11,80 +10,73 @@ import com.healthjournal.R
import com.healthjournal.data.ResultData import com.healthjournal.data.ResultData
import com.healthjournal.ui.journal.detail.DetailJournalActivity import com.healthjournal.ui.journal.detail.DetailJournalActivity
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Locale import java.util.*
class MainAdapter(private val healthDataList: MutableList<ResultData>) : RecyclerView.Adapter<MainAdapter.HealthViewHolder>() { class MainAdapter(private val daftarDataKesehatan: MutableList<ResultData>) : RecyclerView.Adapter<MainAdapter.HolderDataKesehatan>() {
class HealthViewHolder(view: View) : RecyclerView.ViewHolder(view) { class HolderDataKesehatan(view: View) : RecyclerView.ViewHolder(view) {
val tvDay: TextView = view.findViewById(R.id.tv_day) val tvHari: TextView = view.findViewById(R.id.tv_day)
val tvDate: TextView = view.findViewById(R.id.tv_date) val tvTanggal: TextView = view.findViewById(R.id.tv_date)
val tvBloodSugar: TextView = view.findViewById(R.id.tv_BS_Level) val tvGulaDarah: TextView = view.findViewById(R.id.tv_BS_Level)
val tvBloodPressure: TextView = view.findViewById(R.id.tv_BP_Level) val tvTekananDarah: TextView = view.findViewById(R.id.tv_BP_Level)
val tvGoals: TextView = view.findViewById(R.id.tv_goals_count) val tvTugas: TextView = view.findViewById(R.id.tv_goals_count)
} }
// Function to update the list and notify the adapter fun perbaruiData(dataBaru: List<ResultData>) {
fun setData(newData: List<ResultData>) { daftarDataKesehatan.clear()
healthDataList.clear() daftarDataKesehatan.addAll(dataBaru)
healthDataList.addAll(newData)
notifyDataSetChanged() notifyDataSetChanged()
} }
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HealthViewHolder { private fun dapatkanHariDariTanggal(tanggal: String): String {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_health_history, parent, false)
return HealthViewHolder(view)
}
private fun dayOfWeek(date: String): String {
return try { return try {
val dateFormat = SimpleDateFormat("dd/MM/yyyy", Locale.getDefault()) val formatTanggal = SimpleDateFormat("dd/MM/yyyy", Locale("id", "ID"))
val parsedDate = dateFormat.parse(date) val tanggalTerurai = formatTanggal.parse(tanggal)
if (parsedDate != null) { if (tanggalTerurai != null) {
SimpleDateFormat("EEEE", Locale.getDefault()).format(parsedDate) SimpleDateFormat("EEEE", Locale("id", "ID")).format(tanggalTerurai)
.replaceFirstChar { it.uppercaseChar() }
} else { } else {
"Invalid Date" "Tanggal Tidak Valid"
} }
} catch (e: Exception) { } catch (e: Exception) {
"Invalid Date" "Tanggal Tidak Valid"
} }
} }
private fun countGoals(taskList: List<Map<String, Any>>): String { private fun hitungTugasRekomendasi(daftarTugas: List<Map<String, Any>>): String {
Log.d("debug", taskList.toString()) val total = daftarTugas.size
var completedGoals = 0 val selesai = daftarTugas.count { (it["completed"] as? Boolean) == true }
val totalGoals = taskList.size
for (task in taskList) {
val isCompleted = task["completed"] as? Boolean ?: false
if (isCompleted) {
completedGoals++
}
}
return when { return when {
totalGoals == 0 -> "No goals available" total == 0 -> "Tidak ada tugas"
completedGoals == 0 -> "No goals completed" selesai == 0 -> "Belum ada tugas selesai"
else -> "$completedGoals/$totalGoals goals completed" else -> "$selesai dari $total tugas selesai"
} }
} }
override fun onBindViewHolder(holder: HealthViewHolder, position: Int) { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HolderDataKesehatan {
val healthData = healthDataList[position] val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_health_history, parent, false)
return HolderDataKesehatan(view)
}
override fun onBindViewHolder(holder: HolderDataKesehatan, posisi: Int) {
val data = daftarDataKesehatan[posisi]
holder.tvHari.text = dapatkanHariDariTanggal(data.date)
holder.tvTanggal.text = data.date
holder.tvGulaDarah.text = "${data.bloodSugar} mg/dL"
holder.tvTekananDarah.text = "${data.systolicBP}/${data.diastolicBP} mmHg"
holder.tvTugas.text = hitungTugasRekomendasi(data.task)
holder.tvDay.text = dayOfWeek(healthData.date)
holder.tvDate.text = healthData.date
holder.tvBloodSugar.text = "${healthData.bloodSugar} mg/dL"
holder.tvBloodPressure.text = "${healthData.diastolicBP}/${healthData.systolicBP} mm Hg"
holder.tvGoals.text = countGoals(healthData.task)
holder.itemView.setOnClickListener { holder.itemView.setOnClickListener {
val context = holder.itemView.context val context = holder.itemView.context
val intent = Intent(context, DetailJournalActivity::class.java).apply { val intent = Intent(context, DetailJournalActivity::class.java).apply {
putExtra("JOURNAL_KEY", healthData.journalID) putExtra("JOURNAL_KEY", data.journalID)
} }
context.startActivity(intent) context.startActivity(intent)
} }
} }
override fun getItemCount(): Int = healthDataList.size override fun getItemCount(): Int = daftarDataKesehatan.size
} }

View File

@ -1,96 +1,199 @@
package com.healthjournal.ui package com.healthjournal.ui
import MyMarkerView
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import androidx.activity.enableEdgeToEdge import android.view.MotionEvent
import android.widget.ArrayAdapter
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat import androidx.core.content.ContextCompat
import androidx.core.view.WindowInsetsCompat import com.github.mikephil.charting.charts.LineChart
import com.github.mikephil.charting.components.XAxis
import com.github.mikephil.charting.data.*
import com.github.mikephil.charting.formatter.IndexAxisValueFormatter
import com.github.mikephil.charting.highlight.Highlight
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet
import com.github.mikephil.charting.listener.ChartTouchListener
import com.github.mikephil.charting.listener.OnChartGestureListener
import com.github.mikephil.charting.listener.OnChartValueSelectedListener
import com.google.android.material.textfield.MaterialAutoCompleteTextView
import com.healthjournal.R import com.healthjournal.R
import com.healthjournal.data.ResultData
import com.healthjournal.ui.journal.detail.DetailJournalActivity
import java.text.SimpleDateFormat
import java.util.*
class laporan : AppCompatActivity() { class laporan : AppCompatActivity() {
private lateinit var lineChart: LineChart private lateinit var chartBMI: LineChart
private lateinit var chartSugar: LineChart
private lateinit var chartPressure: LineChart
private val jsonString = """ private lateinit var resultList: List<ResultData>
{ private val sdf = SimpleDateFormat("dd/MM/yyyy", Locale.getDefault())
"journal": {
"-OI9BcS6G4-Ftau4WJe0": { private lateinit var sharedMarkerView: MyMarkerView
"BMI": 22.7731876373291,
"bloodPressureDIA": "76",
"bloodPressureSYS": "113",
"bloodSugar": "80",
"date": "03/02/2025"
},
"-OIJnaHgm2dP_Mbzu2Ta": {
"BMI": 22.7731876373291,
"bloodPressureDIA": "72",
"bloodPressureSYS": "109",
"bloodSugar": "89",
"date": "05/02/2025"
}
}
}
"""
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main) setContentView(R.layout.activity_laporan)
lineChart = findViewById(R.id.lineChart) supportActionBar?.title = "Laporan Kesehatan"
renderChart()
chartBMI = findViewById(R.id.chartBMI)
chartSugar = findViewById(R.id.chartSugar)
chartPressure = findViewById(R.id.chartPressure)
@Suppress("UNCHECKED_CAST")
resultList = intent.getSerializableExtra("healthDataList") as? List<ResultData> ?: emptyList()
renderCharts(resultList)
} }
private fun renderChart() { private fun renderCharts(data: List<ResultData>) {
val labels = ArrayList<String>() val labels = ArrayList<String>()
val bmiEntries = ArrayList<Entry>() val bmiEntries = ArrayList<Entry>()
val sugarEntries = ArrayList<Entry>() val sugarEntries = ArrayList<Entry>()
val pressureEntries = ArrayList<Entry>() // We'll use SYS for simplicity val systolicEntries = ArrayList<Entry>()
val diastolicEntries = ArrayList<Entry>()
val sdf = SimpleDateFormat("dd/MM/yyyy", Locale.getDefault()) val sorted = data.sortedBy { sdf.parse(it.date) }
val chartData = JSONObject(jsonString).getJSONObject("journal")
val keys = chartData.keys().asSequence().sortedBy {
sdf.parse(chartData.getJSONObject(it).getString("date"))
}.toList()
keys.forEachIndexed { index, key -> sorted.forEachIndexed { index, item ->
val entry = chartData.getJSONObject(key) labels.add("[${getIndonesianDayName(item.date)}] \n${item.date}")
val date = entry.getString("date") bmiEntries.add(Entry(index.toFloat(), item.BMI))
val bmi = entry.getDouble("BMI").toFloat() sugarEntries.add(Entry(index.toFloat(), item.bloodSugar))
val sugar = entry.getString("bloodSugar").toFloat() systolicEntries.add(Entry(index.toFloat(), item.systolicBP.toFloat()))
val pressure = entry.getString("bloodPressureSYS").toFloat() diastolicEntries.add(Entry(index.toFloat(), item.diastolicBP.toFloat()))
labels.add(date)
bmiEntries.add(Entry(index.toFloat(), bmi))
sugarEntries.add(Entry(index.toFloat(), sugar))
pressureEntries.add(Entry(index.toFloat(), pressure))
} }
val bmiDataSet = LineDataSet(bmiEntries, "BMI").apply { sharedMarkerView = MyMarkerView(this, sorted)
color = resources.getColor(android.R.color.holo_green_dark)
drawChart(chartBMI, listOf(LineDataSet(bmiEntries, "BMI").apply {
val color = ContextCompat.getColor(this@laporan, R.color.chart_bmi)
setColor(color)
setCircleColor(color) setCircleColor(color)
} lineWidth = 2f
valueTextSize = 10f
}), labels)
val sugarDataSet = LineDataSet(sugarEntries, "Blood Sugar").apply { drawChart(chartSugar, listOf(LineDataSet(sugarEntries, "Gula Darah").apply {
color = resources.getColor(android.R.color.holo_red_dark) val color = ContextCompat.getColor(this@laporan, R.color.chart_sugar)
setColor(color)
setCircleColor(color) setCircleColor(color)
} lineWidth = 2f
valueTextSize = 10f
}), labels)
val pressureDataSet = LineDataSet(pressureEntries, "Blood Pressure (SYS)").apply { drawChart(chartPressure, listOf(
color = resources.getColor(android.R.color.holo_blue_dark) LineDataSet(systolicEntries, "Sistolik").apply {
setCircleColor(color) val color = ContextCompat.getColor(this@laporan, R.color.chart_systolic)
} setColor(color)
setCircleColor(color)
lineWidth = 2f
valueTextSize = 10f
},
LineDataSet(diastolicEntries, "Diastolik").apply {
val color = ContextCompat.getColor(this@laporan, R.color.chart_diastolic)
setColor(color)
setCircleColor(color)
lineWidth = 2f
valueTextSize = 10f
}
), labels)
val lineData = LineData(bmiDataSet, sugarDataSet, pressureDataSet) setupHighlightListeners()
lineChart.data = lineData setupDoubleTapNavigation(chartBMI, sorted)
setupDoubleTapNavigation(chartSugar, sorted)
val xAxis = lineChart.xAxis setupDoubleTapNavigation(chartPressure, sorted)
xAxis.valueFormatter = IndexAxisValueFormatter(labels)
xAxis.position = XAxis.XAxisPosition.BOTTOM
xAxis.granularity = 1f
xAxis.labelRotationAngle = -45f
lineChart.axisRight.isEnabled = false
lineChart.description.text = "Health Metrics Over Time"
lineChart.invalidate()
} }
}
private fun drawChart(chart: LineChart, dataSets: List<ILineDataSet>, labels: List<String>) {
chart.data = LineData(dataSets)
chart.xAxis.apply {
valueFormatter = IndexAxisValueFormatter(labels)
position = XAxis.XAxisPosition.BOTTOM
granularity = 1f
labelRotationAngle = -45f
}
chart.axisRight.isEnabled = false
chart.description.isEnabled = false
chart.legend.isEnabled = true
chart.setTouchEnabled(true)
chart.isDragEnabled = true
chart.setScaleEnabled(true)
chart.setPinchZoom(true)
chart.setDoubleTapToZoomEnabled(false)
chart.setVisibleXRangeMaximum(7f)
chart.moveViewToX(chart.data.entryCount.toFloat())
chart.marker = sharedMarkerView
chart.invalidate()
}
private fun setupHighlightListeners() {
val charts = listOf(chartBMI, chartSugar, chartPressure)
for (chart in charts) {
chart.setOnChartValueSelectedListener(object : OnChartValueSelectedListener {
override fun onValueSelected(e: Entry?, h: Highlight?) {
charts.filter { it != chart }.forEach {
it.highlightValue(null, true)
}
}
override fun onNothingSelected() {}
})
}
}
private fun setupDoubleTapNavigation(chart: LineChart, data: List<ResultData>) {
var lastTapTime = 0L
var lastEntry: Entry? = null
chart.setOnChartGestureListener(object : OnChartGestureListener {
override fun onChartSingleTapped(me: MotionEvent?) {
me ?: return
val highlight = chart.getHighlightByTouchPoint(me.x, me.y)
val entry = highlight?.let { chart.data.getEntryForHighlight(it) }
val currentTime = System.currentTimeMillis()
if (entry != null && lastEntry == entry && currentTime - lastTapTime < 400) {
val index = entry.x.toInt()
if (index in data.indices) {
val item = data[index]
val intent = Intent(this@laporan, DetailJournalActivity::class.java).apply {
putExtra("JOURNAL_KEY", item.journalID)
}
startActivity(intent)
}
}
lastEntry = entry
lastTapTime = currentTime
}
override fun onChartGestureStart(me: MotionEvent?, lastPerformedGesture: ChartTouchListener.ChartGesture?) {}
override fun onChartGestureEnd(me: MotionEvent?, lastPerformedGesture: ChartTouchListener.ChartGesture?) {}
override fun onChartLongPressed(me: MotionEvent?) {}
override fun onChartDoubleTapped(me: MotionEvent?) {}
override fun onChartFling(me1: MotionEvent?, me2: MotionEvent?, velocityX: Float, velocityY: Float) {}
override fun onChartScale(me: MotionEvent?, scaleX: Float, scaleY: Float) {}
override fun onChartTranslate(me: MotionEvent?, dX: Float, dY: Float) {}
})
}
private fun getIndonesianDayName(dateString: String): String {
return try {
val date = sdf.parse(dateString) ?: return ""
val locale = Locale("id", "ID")
val dayFormat = SimpleDateFormat("EEEE", locale)
dayFormat.format(date)
} catch (e: Exception) {
""
}
}
}

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
<solid android:color="?attr/colorPrimary" />
</shape>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#CC000000" />
<corners android:radius="8dp" />
<padding
android:left="8dp"
android:top="8dp"
android:right="8dp"
android:bottom="8dp" />
<stroke
android:width="1dp"
android:color="#88000000" />
</shape>

View File

@ -5,14 +5,14 @@
android:id="@+id/main" android:id="@+id/main"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@color/Secondary_Light" android:background="@color/background"
tools:context=".ui.journal.detail.DetailJournalActivity"> tools:context=".ui.journal.detail.DetailJournalActivity">
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraintLayout" android:id="@+id/constraintLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="250dp" android:layout_height="250dp"
android:background="@color/Accent_Dark_Gray" android:background="@drawable/bg_dashboard"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"> app:layout_constraintTop_toTopOf="parent">
@ -22,7 +22,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
android:text="JOURNAL DETAIL" android:text="DETAIL JURNAL"
android:textAlignment="center" android:textAlignment="center"
android:textColor="@color/Primary_Dark" android:textColor="@color/Primary_Dark"
android:textSize="20sp" android:textSize="20sp"
@ -35,11 +35,11 @@
android:id="@+id/tv_bloodsugar_level1" android:id="@+id/tv_bloodsugar_level1"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Blood Sugar Level :" android:layout_marginTop="8dp"
android:text="Tingkat Gula Darah :"
android:textColor="@color/Primary_Dark" android:textColor="@color/Primary_Dark"
android:textSize="16sp" android:textSize="16sp"
android:textStyle="bold" android:textStyle="bold"
android:layout_marginTop="10dp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.375" app:layout_constraintHorizontal_bias="0.375"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
@ -60,29 +60,29 @@
app:layout_constraintTop_toBottomOf="@id/tv_title" app:layout_constraintTop_toBottomOf="@id/tv_title"
tools:text="100 mg/dL" /> tools:text="100 mg/dL" />
<TextView <TextView
android:id="@+id/tv_bloodsugar_desc" android:id="@+id/tv_bloodsugar_desc"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textSize="10sp" android:textSize="10sp"
android:textColor="@color/black"
app:layout_constraintEnd_toEndOf="@+id/tv_bloodsugar_level2" app:layout_constraintEnd_toEndOf="@+id/tv_bloodsugar_level2"
app:layout_constraintStart_toStartOf="@+id/tv_bloodsugar_level1" app:layout_constraintStart_toStartOf="@+id/tv_bloodsugar_level1"
app:layout_constraintTop_toBottomOf="@id/tv_bloodsugar_level1" app:layout_constraintTop_toBottomOf="@id/tv_bloodsugar_level1"
tools:text="Your blood sugar level is within the normal range. Maintain a balanced diet and regular exercise." /> tools:text="olahraga teratur." />
<TextView <TextView
android:id="@+id/tv_bloodpressure_level1" android:id="@+id/tv_bloodpressure_level1"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Blood Pressure Level :" android:layout_marginTop="8dp"
android:text="Tingkat Tekanan Darah :"
android:textColor="@color/Primary_Dark" android:textColor="@color/Primary_Dark"
android:textSize="16sp" android:textSize="16sp"
android:textStyle="bold" android:textStyle="bold"
android:layout_marginTop="10dp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.408" app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="@+id/tv_bloodsugar_level1"
app:layout_constraintTop_toBottomOf="@id/tv_bloodsugar_desc" /> app:layout_constraintTop_toBottomOf="@id/tv_bloodsugar_desc" />
<TextView <TextView
@ -100,29 +100,29 @@
app:layout_constraintTop_toBottomOf="@id/tv_bloodsugar_desc" app:layout_constraintTop_toBottomOf="@id/tv_bloodsugar_desc"
tools:text="119/70 mm Hg" /> tools:text="119/70 mm Hg" />
<TextView <TextView
android:id="@+id/tv_bloodpressure_desc" android:id="@+id/tv_bloodpressure_desc"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textSize="10sp" android:textSize="10sp"
android:textColor="@color/black"
app:layout_constraintEnd_toEndOf="@+id/tv_bloodpressure_level2" app:layout_constraintEnd_toEndOf="@+id/tv_bloodpressure_level2"
app:layout_constraintStart_toStartOf="@+id/tv_bloodpressure_level1" app:layout_constraintStart_toStartOf="@+id/tv_bloodpressure_level1"
app:layout_constraintTop_toBottomOf="@id/tv_bloodpressure_level1" app:layout_constraintTop_toBottomOf="@id/tv_bloodpressure_level1"
tools:text="Your blood sugar level is within the normal range. Maintain a balanced diet and regular exercise." /> tools:text="Tingkat tekanan darah Anda berada dalam kisaran normal. Pertahankan pola makan seimbang dan olahraga teratur." />
<TextView <TextView
android:id="@+id/tv_BMI_level1" android:id="@+id/tv_BMI_level1"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="BMI(Body Mass Index) :" android:layout_marginTop="8dp"
android:text="BMI (Indeks Massa Tubuh) :"
android:textColor="@color/Primary_Dark" android:textColor="@color/Primary_Dark"
android:textSize="16sp" android:textSize="16sp"
android:textStyle="bold" android:textStyle="bold"
android:layout_marginTop="10dp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.426" app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="@+id/tv_bloodpressure_level1"
app:layout_constraintTop_toBottomOf="@id/tv_bloodpressure_desc" /> app:layout_constraintTop_toBottomOf="@id/tv_bloodpressure_desc" />
<TextView <TextView
@ -141,23 +141,23 @@
app:layout_constraintTop_toBottomOf="@id/tv_bloodpressure_desc" app:layout_constraintTop_toBottomOf="@id/tv_bloodpressure_desc"
tools:text="22.03 BMI" /> tools:text="22.03 BMI" />
<TextView <TextView
android:id="@+id/tv_BMI_desc" android:id="@+id/tv_BMI_desc"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textSize="10sp" android:textSize="10sp"
android:textColor="@color/black"
app:layout_constraintEnd_toEndOf="@+id/tv_BMI_level2" app:layout_constraintEnd_toEndOf="@+id/tv_BMI_level2"
app:layout_constraintStart_toStartOf="@+id/tv_BMI_level1" app:layout_constraintStart_toStartOf="@+id/tv_BMI_level1"
app:layout_constraintTop_toBottomOf="@id/tv_BMI_level1" app:layout_constraintTop_toBottomOf="@id/tv_BMI_level1"
tools:text="This is still considered an acceptable range, and is associated with good health." /> tools:text="Ini masih dianggap kisaran yang dapat diterima, dan berhubungan dengan kesehatan yang baik." />
<TextView <TextView
android:id="@+id/tv_goals1" android:id="@+id/tv_goals1"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:text="Goals Completed :" android:text="Tugas yang Dicapai :"
android:textColor="@color/Primary_Dark" android:textColor="@color/Primary_Dark"
android:textSize="16sp" android:textSize="16sp"
android:textStyle="bold" android:textStyle="bold"
@ -187,7 +187,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:text="JOURNAL NOTES" android:text="CATATAN JURNAL"
android:textAlignment="center" android:textAlignment="center"
android:textColor="@color/Primary_Dark" android:textColor="@color/Primary_Dark"
android:textSize="20sp" android:textSize="20sp"
@ -205,6 +205,7 @@
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:padding="10dp" android:padding="10dp"
android:textSize="11sp" android:textSize="11sp"
android:textColor="@color/black"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_title_note" app:layout_constraintTop_toBottomOf="@+id/tv_title_note"
@ -217,7 +218,7 @@
android:layout_marginTop="20dp" android:layout_marginTop="20dp"
android:layout_marginBottom="20dp" android:layout_marginBottom="20dp"
android:background="@drawable/bg_button" android:background="@drawable/bg_button"
android:text="Delete History" android:text="Hapus Riwayat"
android:textAllCaps="true" android:textAllCaps="true"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="14sp" android:textSize="14sp"
@ -227,4 +228,3 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_journal_note" /> app:layout_constraintTop_toBottomOf="@+id/tv_journal_note" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -23,7 +23,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="Tolong Masukan Laporan Hari Ini" android:text="Silakan Masukkan Laporan Hari Ini"
android:textStyle="bold" android:textStyle="bold"
android:textColor="@color/Primary_Dark" android:textColor="@color/Primary_Dark"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
@ -48,7 +48,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:fontFamily="@font/poppins_regular" android:fontFamily="@font/poppins_regular"
android:text="Blood Pressure\n(SYS) (mm/HG)" android:text="Tekanan Darah\n(Sistolik) \n(mm/Hg)"
android:textAlignment="center" android:textAlignment="center"
android:textColor="@color/Primary_Dark" android:textColor="@color/Primary_Dark"
android:textSize="8sp" android:textSize="8sp"
@ -71,7 +71,6 @@
app:layout_constraintEnd_toEndOf="@+id/tv_input_blood_pressure_SYS" app:layout_constraintEnd_toEndOf="@+id/tv_input_blood_pressure_SYS"
app:layout_constraintStart_toStartOf="@+id/tv_input_blood_pressure_SYS" app:layout_constraintStart_toStartOf="@+id/tv_input_blood_pressure_SYS"
app:layout_constraintTop_toBottomOf="@id/tv_input_blood_pressure_SYS" /> app:layout_constraintTop_toBottomOf="@id/tv_input_blood_pressure_SYS" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
@ -91,7 +90,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:fontFamily="@font/poppins_regular" android:fontFamily="@font/poppins_regular"
android:text="Blood Pressure\n(DIA) (mm/HG)" android:text="Tekanan Darah\n(Diastolik)\n(mm/Hg)"
android:textAlignment="center" android:textAlignment="center"
android:textColor="@color/Primary_Dark" android:textColor="@color/Primary_Dark"
android:textSize="8sp" android:textSize="8sp"
@ -114,7 +113,6 @@
app:layout_constraintEnd_toEndOf="@+id/tv_input_blood_pressure_DIA" app:layout_constraintEnd_toEndOf="@+id/tv_input_blood_pressure_DIA"
app:layout_constraintStart_toStartOf="@+id/tv_input_blood_pressure_DIA" app:layout_constraintStart_toStartOf="@+id/tv_input_blood_pressure_DIA"
app:layout_constraintTop_toBottomOf="@+id/tv_input_blood_pressure_DIA" /> app:layout_constraintTop_toBottomOf="@+id/tv_input_blood_pressure_DIA" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
@ -129,12 +127,13 @@
app:layout_constraintStart_toStartOf="@+id/cl_input_note" app:layout_constraintStart_toStartOf="@+id/cl_input_note"
app:layout_constraintTop_toBottomOf="@+id/cl_input_blood_pressure_SYS" app:layout_constraintTop_toBottomOf="@+id/cl_input_blood_pressure_SYS"
app:layout_constraintVertical_bias="0.05"> app:layout_constraintVertical_bias="0.05">
<TextView <TextView
android:id="@+id/tv_input_blood_sugar" android:id="@+id/tv_input_blood_sugar"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:fontFamily="@font/poppins_regular" android:fontFamily="@font/poppins_regular"
android:text="Blood Sugar \nLevel (mg/dL)" android:text="Kadar Gula\nDarah (mg/dL)"
android:textAlignment="center" android:textAlignment="center"
android:textColor="@color/Primary_Dark" android:textColor="@color/Primary_Dark"
android:textSize="8sp" android:textSize="8sp"
@ -177,7 +176,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:fontFamily="@font/poppins_regular" android:fontFamily="@font/poppins_regular"
android:text="Weight\n(kg)" android:text="Berat Badan\n(kg)"
android:textAlignment="center" android:textAlignment="center"
android:textColor="@color/Primary_Dark" android:textColor="@color/Primary_Dark"
android:textSize="8sp" android:textSize="8sp"
@ -203,34 +202,22 @@
<EditText <EditText
android:id="@+id/edt_gender" android:id="@+id/edt_gender"
android:layout_width="match_parent"
android:layout_height="20dp"
android:background="@color/white"
android:visibility="gone" android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent" />
app:layout_constraintStart_toStartOf="parent" />
<EditText <EditText
android:id="@+id/edt_age" android:id="@+id/edt_age"
android:layout_width="match_parent"
android:layout_height="20dp"
android:background="@color/white"
android:visibility="gone" android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent" />
app:layout_constraintStart_toStartOf="parent" />
<EditText <EditText
android:id="@+id/edt_height" android:id="@+id/edt_height"
android:layout_width="match_parent"
android:layout_height="20dp"
android:background="@color/white"
android:visibility="gone" android:visibility="gone"
android:maxLength="3"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent" />
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
@ -250,7 +237,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:fontFamily="@font/poppins_regular" android:fontFamily="@font/poppins_regular"
android:text="NOTES" android:text="Catatan"
android:textAlignment="center" android:textAlignment="center"
android:textColor="@color/Primary_Dark" android:textColor="@color/Primary_Dark"
android:textSize="8sp" android:textSize="8sp"
@ -284,7 +271,7 @@
android:layout_height="39dp" android:layout_height="39dp"
android:layout_marginBottom="36dp" android:layout_marginBottom="36dp"
android:background="@drawable/bg_button" android:background="@drawable/bg_button"
android:text="Input Data" android:text="Kirim Data"
android:textAllCaps="false" android:textAllCaps="false"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="14sp" android:textSize="14sp"
@ -293,4 +280,4 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" /> app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,16 +1,233 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".ui.laporan"> android:background="@color/background"
android:fillViewport="true">
<androidx.constraintlayout.widget.ConstraintLayout
<com.github.mikephil.charting.charts.LineChart
android:id="@+id/lineChart"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="400dp" /> android:layout_height="wrap_content"
android:padding="16dp">
</androidx.constraintlayout.widget.ConstraintLayout> <TextView
android:id="@+id/tvHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Laporan Kesehatan"
android:textSize="24sp"
android:textStyle="bold"
android:textColor="@android:color/black"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginBottom="8dp" />
<androidx.cardview.widget.CardView
android:id="@+id/cardBMI"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:cardElevation="4dp"
app:cardCornerRadius="16dp"
app:layout_constraintTop_toBottomOf="@id/tvHeader"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="12dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="BMI"
android:textColor="@color/black"
android:textStyle="bold"
android:textSize="16sp" />
<com.github.mikephil.charting.charts.LineChart
android:id="@+id/chartBMI"
android:layout_width="match_parent"
android:layout_height="200dp" />
<!-- Hint/Legend -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="8dp"
android:gravity="center_vertical">
<View
android:layout_width="16dp"
android:layout_height="16dp"
android:backgroundTint="@color/chart_bmi"
android:background="@drawable/color_circle" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" BMI"
android:textSize="14sp"
android:layout_marginStart="4dp"/>
</LinearLayout>
<TextView
android:id="@+id/scrollIndicatorBMI"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="← Lama (Older) | Baru (Newer) →"
android:textAlignment="center"
android:textColor="@android:color/darker_gray"
android:textSize="14sp"
android:paddingTop="8dp"
android:paddingBottom="4dp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
<!-- Sugar Chart Card -->
<androidx.cardview.widget.CardView
android:id="@+id/cardSugar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
app:cardElevation="4dp"
app:cardCornerRadius="16dp"
app:layout_constraintTop_toBottomOf="@id/cardBMI"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="12dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Gula Darah"
android:textColor="@color/black"
android:textStyle="bold"
android:textSize="16sp" />
<com.github.mikephil.charting.charts.LineChart
android:id="@+id/chartSugar"
android:layout_width="match_parent"
android:layout_height="200dp" />
<!-- Hint/Legend -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="8dp"
android:gravity="center_vertical">
<View
android:layout_width="16dp"
android:layout_height="16dp"
android:backgroundTint="@color/chart_sugar"
android:background="@drawable/color_circle" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" Gula Darah"
android:textSize="14sp"
android:layout_marginStart="4dp"/>
</LinearLayout>
<TextView
android:id="@+id/scrollIndicatorSugar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="← Lama (Older) | Baru (Newer) →"
android:textAlignment="center"
android:textColor="@android:color/darker_gray"
android:textSize="14sp"
android:paddingTop="8dp"
android:paddingBottom="4dp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
<!-- Blood Pressure Chart Card -->
<androidx.cardview.widget.CardView
android:id="@+id/cardPressure"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
app:cardElevation="4dp"
app:cardCornerRadius="16dp"
app:layout_constraintTop_toBottomOf="@id/cardSugar"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="12dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Tekanan Darah"
android:textStyle="bold"
android:textColor="@color/black"
android:textSize="16sp" />
<com.github.mikephil.charting.charts.LineChart
android:id="@+id/chartPressure"
android:layout_width="match_parent"
android:layout_height="200dp" />
<!-- Hint/Legend -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="8dp"
android:gravity="center_vertical">
<View
android:layout_width="16dp"
android:layout_height="16dp"
android:backgroundTint="@color/chart_systolic"
android:background="@drawable/color_circle" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" Sistolik"
android:textSize="14sp"
android:layout_marginEnd="12dp" />
<View
android:layout_width="16dp"
android:layout_height="16dp"
android:backgroundTint="@color/chart_diastolic"
android:background="@drawable/color_circle" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" Diastolik"
android:textSize="14sp"
android:layout_marginStart="4dp" />
</LinearLayout>
<TextView
android:id="@+id/scrollIndicatorPressure"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="← Lama (Older) | Baru (Newer) →"
android:textAlignment="center"
android:textColor="@android:color/darker_gray"
android:textSize="14sp"
android:paddingTop="8dp"
android:paddingBottom="4dp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>

View File

@ -5,6 +5,7 @@
android:id="@+id/main" android:id="@+id/main"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@color/background"
tools:context=".ui.dashboard.MainActivity"> tools:context=".ui.dashboard.MainActivity">
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
@ -262,6 +263,7 @@ z
android:layout_width="200dp" android:layout_width="200dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Your blood sugar level is within the normal range. Maintain a balanced diet and regular exercise." android:text="Your blood sugar level is within the normal range. Maintain a balanced diet and regular exercise."
android:textColor="@color/black"
android:textSize="12sp" android:textSize="12sp"
app:layout_constraintEnd_toEndOf="@+id/tv_bloodsugar_level" app:layout_constraintEnd_toEndOf="@+id/tv_bloodsugar_level"
app:layout_constraintHorizontal_bias="0.0" app:layout_constraintHorizontal_bias="0.0"
@ -298,6 +300,7 @@ z
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Your blood pressure is within the normal range. Continue a heart-healthy lifestyle." android:text="Your blood pressure is within the normal range. Continue a heart-healthy lifestyle."
android:textSize="12sp" android:textSize="12sp"
android:textColor="@color/black"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0" app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="@+id/tv_sub_title_BPL" app:layout_constraintStart_toStartOf="@+id/tv_sub_title_BPL"
@ -337,6 +340,7 @@ z
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="This is still considered an acceptable range, and is associated with good health." android:text="This is still considered an acceptable range, and is associated with good health."
android:textSize="12sp" android:textSize="12sp"
android:textColor="@color/black"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0" app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="@+id/tv_sub_title_BMI" app:layout_constraintStart_toStartOf="@+id/tv_sub_title_BMI"
@ -499,10 +503,14 @@ z
android:id="@+id/rv_health_history" android:id="@+id/rv_health_history"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@id/nav_view"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.516"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
tools:listitem="@layout/item_health_history" app:layout_constraintTop_toBottomOf="@+id/cl_Health_Report"
app:layout_constraintTop_toBottomOf="@+id/cl_Health_Report" /> app:layout_constraintVertical_bias="0.0"
tools:itemCount="1"
tools:listitem="@layout/item_health_history" />
<ImageView <ImageView
android:id="@+id/iv_add" android:id="@+id/iv_add"

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:background="@drawable/bg_profile" android:background="@drawable/bg_profile"
android:layout_margin="10dp" android:layout_margin="10dp"
android:padding="5dp" android:padding="5dp"
@ -13,7 +12,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="280dp" android:layout_marginEnd="280dp"
android:text="Friday" android:text="Jumat"
android:textColor="@color/black"
android:textStyle="bold" android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
@ -49,13 +49,14 @@
app:layout_constraintHorizontal_bias="0.0" app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_date" app:layout_constraintTop_toBottomOf="@+id/tv_date"
app:layout_constraintVertical_bias="0.647" /> app:layout_constraintVertical_bias="0.388" />
<TextView <TextView
android:id="@+id/tv_sub_BSL" android:id="@+id/tv_sub_BSL"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Blood Sugar Level : " android:textColor="@color/black"
android:text="Kadar Gula Darah : "
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.176" app:layout_constraintHorizontal_bias="0.176"
@ -81,13 +82,14 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="88dp" android:layout_marginEnd="88dp"
android:text="Blood Pressure Level :" android:text="Kadar Tekanan Darah :"
android:textColor="@color/black"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.604" app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@+id/iv_user" app:layout_constraintStart_toStartOf="@+id/tv_sub_BSL"
app:layout_constraintTop_toBottomOf="@+id/tv_sub_BSL" app:layout_constraintTop_toBottomOf="@+id/tv_sub_BSL"
app:layout_constraintVertical_bias="0.042" /> app:layout_constraintVertical_bias="0.0" />
<TextView <TextView
android:id="@+id/tv_BP_Level" android:id="@+id/tv_BP_Level"
@ -107,21 +109,23 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="28dp" android:layout_marginEnd="28dp"
android:text="Recommended goals completed" android:text="Target yang Disarankan Tercapai"
android:textColor="@color/black"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.666" app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@+id/iv_user" app:layout_constraintStart_toStartOf="@+id/tv_sub_BPL"
app:layout_constraintTop_toBottomOf="@+id/tv_sub_BPL" app:layout_constraintTop_toBottomOf="@+id/tv_sub_BPL"
app:layout_constraintVertical_bias="0.038" /> app:layout_constraintVertical_bias="0.071" />
<TextView <TextView
android:id="@+id/tv_goals_count" android:id="@+id/tv_goals_count"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="@color/black"
android:text="[lorem ipsum]" android:text="[lorem ipsum]"
app:layout_constraintEnd_toEndOf="@+id/tv_sub_goals" app:layout_constraintEnd_toEndOf="@+id/tv_sub_goals"
app:layout_constraintStart_toStartOf="@+id/tv_sub_goals" app:layout_constraintStart_toStartOf="@+id/tv_sub_goals"
app:layout_constraintTop_toBottomOf="@+id/tv_sub_goals" /> app:layout_constraintTop_toBottomOf="@+id/tv_sub_goals" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/marker_background"
android:padding="12dp"
android:orientation="vertical"
android:elevation="6dp"
android:descendantFocusability="blocksDescendants">
<TextView
android:id="@+id/tvContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="14sp"
android:textStyle="bold"
android:paddingBottom="6dp" />
</LinearLayout>

View File

@ -0,0 +1,3 @@
<resources>
<dimen name="fab_margin">48dp</dimen>
</resources>

View File

@ -0,0 +1,8 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="Theme.HealthJournal" parent="Base.Theme.HealthJournal">
<!-- Transparent system bars for edge-to-edge. -->
<item name="android:navigationBarColor">@android:color/transparent</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowLightStatusBar">?attr/isLightTheme</item>
</style>
</resources>

View File

@ -0,0 +1,3 @@
<resources>
<dimen name="fab_margin">200dp</dimen>
</resources>

View File

@ -0,0 +1,3 @@
<resources>
<dimen name="fab_margin">48dp</dimen>
</resources>

View File

@ -2,6 +2,7 @@
<resources> <resources>
<color name="black">#FF000000</color> <color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color> <color name="white">#FFFFFFFF</color>
<color name="background">#E8F4F8</color>
<color name="Primary_Dark">#004343</color> <color name="Primary_Dark">#004343</color>
<color name="Primary_Light">#006C6C</color> <color name="Primary_Light">#006C6C</color>
@ -9,8 +10,13 @@
<color name="Secondary_Dark">#7ABDBD</color> <color name="Secondary_Dark">#7ABDBD</color>
<color name="Secondary_Light">#E8F4F8</color> <color name="Secondary_Light">#E8F4F8</color>
<color name="Accent_Dark_Gray">#D9D9D9</color> <color name="Accent_Dark_Gray">#EFEDED</color>
<color name="Accent_Light_Orange">#FF5722</color> <color name="Accent_Light_Orange">#FF5722</color>
<color name="Accent_Light_Red">#FF0000</color> <color name="Accent_Light_Red">#FF0000</color>
<color name="chart_bmi">#388E3C</color>
<color name="chart_sugar">#D32F2F</color>
<color name="chart_systolic">#1976D2</color>
<color name="chart_diastolic">#F57C00</color>
</resources> </resources>

View File

@ -0,0 +1,3 @@
<resources>
<dimen name="fab_margin">16dp</dimen>
</resources>

View File

@ -60,5 +60,12 @@
// Activity Recommendation // Activity Recommendation
// Activity S
<string-array name="filter_options">
<item>Daily</item>
<item>Weekly</item>
<item>Monthly</item>
</string-array>
</resources> </resources>

View File

@ -2,15 +2,18 @@
<!-- Base application theme. --> <!-- Base application theme. -->
<style name="Base.Theme.HealthJournal" parent="Theme.MaterialComponents.DayNight.NoActionBar"> <style name="Base.Theme.HealthJournal" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<item name="colorPrimary">@color/Primary_Dark</item> <item name="colorPrimary">@color/Primary_Dark</item>
<item name="colorPrimaryVariant">@color/Primary_Dark</item> <item name="colorPrimaryVariant">@color/Primary_Light</item>
<item name="colorOnPrimary">@color/Primary_Light</item> <item name="colorOnPrimary">@color/white</item>
<item name="colorSecondary">@color/Accent_Light_Orange</item> <item name="colorSecondary">@color/Accent_Light_Orange</item>
<item name="colorOnSecondary">@color/Primary_Dark</item> <item name="colorOnSecondary">@color/white</item>
<item name="android:statusBarColor">@color/Primary_Dark</item>
<!-- <item name="colorPrimary">@color/my_light_primary</item> --> <item name="android:navigationBarColor">@color/Primary_Dark</item>
<item name="android:textColorPrimary">@color/black</item>
<item name="android:textColorSecondary">@color/Secondary_Dark</item>
</style> </style>
<style name="Theme.HealthJournal" parent="Base.Theme.HealthJournal" /> <style name="Theme.HealthJournal" parent="Base.Theme.HealthJournal" />
<style name="CategoryItemStyle"> <style name="CategoryItemStyle">
<item name="android:layout_width">wrap_content</item> <item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item> <item name="android:layout_height">wrap_content</item>
@ -36,4 +39,4 @@
<item name="android:fontFamily">@font/poppins_regular</item> <item name="android:fontFamily">@font/poppins_regular</item>
<item name="android:textStyle">bold</item> <item name="android:textStyle">bold</item>
</style> </style>
</resources> </resources>

View File

@ -16,6 +16,7 @@ dependencyResolutionManagement {
repositories { repositories {
google() google()
mavenCentral() mavenCentral()
maven(url = "https://jitpack.io")
} }
} }