First Commit:

Version 1.0 [Non Optimized Version]
This commit is contained in:
Diassdp
2025-01-19 11:52:27 +07:00
commit f299dfb3a0
92 changed files with 4558 additions and 0 deletions

View File

@ -0,0 +1,109 @@
package com.healthjournal.ui.custom
import android.content.Context
import android.graphics.Canvas
import android.graphics.drawable.Drawable
import android.text.Editable
import android.text.InputFilter
import android.text.InputType
import android.text.TextWatcher
import android.util.AttributeSet
import android.util.Patterns
import androidx.core.content.ContextCompat
import com.healthjournal.R
import com.google.android.material.textfield.TextInputEditText
class CustomEditText : TextInputEditText {
private var errorBackground: Drawable? = null
private var defaultBackground: Drawable? = null
private var isError: Boolean = false
constructor(context: Context) : super(context) {
init()
}
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
init()
}
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
) {
init()
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
background = if (isError) {
errorBackground
} else {
defaultBackground
}
}
private fun init() {
errorBackground = ContextCompat.getDrawable(context, R.drawable.bg_edt_error)
defaultBackground = ContextCompat.getDrawable(context, R.drawable.bg_edt_default)
if (inputType == InputType.TYPE_CLASS_NUMBER) {
filters = arrayOf(InputFilter { source, _, _, _, _, _ ->
source.filter { it.isDigit() }
})
}
addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
val input = p0.toString()
if (input.isEmpty()) {
error = context.getString(R.string.empty_field)
isError = true
} else {
error = null
isError = false
validateInput(input)
}
}
override fun afterTextChanged(p0: Editable?) {}
})
}
private fun validateInput(input: String) {
when (inputType) {
EMAIL -> {
if (!Patterns.EMAIL_ADDRESS.matcher(input).matches()) {
error = context.getString(R.string.email_validation)
isError = true
} else {
isError = false
}
}
PASSWORD -> {
if (input.length < 6) {
error = context.getString(R.string.password_length)
isError = true
} else {
isError = false
}
}
InputType.TYPE_CLASS_NUMBER -> {
if (!input.matches("\\d+".toRegex())) {
error = context.getString(R.string.empty_field)
isError = true
} else {
isError = false
}
}
}
}
companion object {
const val EMAIL = 0x00000021
const val PASSWORD = 0x00000081
}
}

View File

@ -0,0 +1,227 @@
package com.healthjournal.ui.dashboard
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.firebase.Firebase
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.database.FirebaseDatabase
import com.google.firebase.database.database
import com.healthjournal.R
import com.healthjournal.data.ResultData
import com.healthjournal.databinding.ActivityMainBinding
import com.healthjournal.ui.journal.input.JournalInputActivity
import com.healthjournal.ui.login.LoginActivity
import com.healthjournal.ui.profile.ProfileActivity
import com.healthjournal.ui.recommendation.RecommendationActivity
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var user: FirebaseAuth
private lateinit var mainAdapter: MainAdapter
private val healthDataList: MutableList<ResultData> = mutableListOf()
private val database = Firebase.database
private var dailyReport = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
user = FirebaseAuth.getInstance()
userCheck()
setupListener()
populateHistory()
navigationBottomBar()
}
private fun navigationBottomBar(){
binding.bottomNavigation.setOnItemSelectedListener {
when(it.itemId){
R.id.nav_add -> addJournal()
R.id.nav_home -> home()
R.id.nav_profile -> profile()
}
true
}
}
private fun getWeekCount() {
val today = Calendar.getInstance()
val userID = user.currentUser!!.uid
var count = 0
val dateFormat = SimpleDateFormat("dd/MM/yyyy", Locale.getDefault())
today.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY)
val startDate = dateFormat.format(today.time)
val endDate = today.clone() as Calendar
endDate.add(Calendar.DAY_OF_WEEK, 6)
val endDateString = dateFormat.format(endDate.time)
database.getReference("users").child(userID).child("journal")
.get()
.addOnCompleteListener { task ->
if (task.isSuccessful) {
count = task.result.children.count { snapshot ->
val date = snapshot.child("date").value.toString()
date >= startDate && date <= endDateString
}
Log.d("debug", "Entries found: $count for week: $startDate - $endDateString")
binding.tvDailyCounter.text = "$count/7"
} else {
Log.e("error", task.exception?.message.toString())
Toast.makeText(this, task.exception?.message, Toast.LENGTH_SHORT).show()
}
}
}
private fun addJournal(){
if (dailyReport != false){
Toast.makeText(this, "Daily Report Already Created", Toast.LENGTH_SHORT).show()
} else {
startActivity(Intent(this, JournalInputActivity::class.java))
}
}
private fun home(){
}
private fun profile(){
intent = Intent(this, ProfileActivity::class.java)
startActivity(intent)
}
private fun setupListener(){
binding.btnRecomendation.setOnClickListener {
startActivity(Intent(this, RecommendationActivity::class.java))
finish()
}
binding.btnInputData.setOnClickListener {
startActivity(Intent(this, JournalInputActivity::class.java))
finish()
}
}
private fun dailycheck() {
val today = SimpleDateFormat("dd/MM/yyyy", Locale.getDefault()).format(android.icu.util.Calendar.getInstance().time).toString()
val userID = user.currentUser!!.uid
database.getReference("users").child(userID).child("journal").get().addOnCompleteListener { task ->
if (task.isSuccessful) {
task.result.children.forEach {
if (it.child("date").value.toString() == today) {
dailyReport = true
switchLayout()
populateTodayReport()
}
}
} else {
Log.d("error", task.exception!!.message.toString())
Toast.makeText(this, task.exception!!.message, Toast.LENGTH_SHORT).show()
}
}
}
private fun switchLayout(){
if (binding.clDailyReport1.visibility == View.VISIBLE){
binding.clDailyReport1.visibility = View.INVISIBLE
binding.clDailyReport2.visibility = View.VISIBLE
binding.btnRecomendation.visibility = View.VISIBLE
binding.ivCuboidIndicator1Green.visibility = View.VISIBLE
binding.ivCuboidIndicator2Green.visibility = View.VISIBLE
binding.ivCuboidIndicator1Orange.visibility = View.INVISIBLE
binding.ivCuboidIndicator2Orange.visibility = View.INVISIBLE
} else {
binding.clDailyReport1.visibility = View.VISIBLE
binding.clDailyReport2.visibility = View.INVISIBLE
binding.btnRecomendation.visibility = View.GONE
binding.ivCuboidIndicator1Green.visibility = View.INVISIBLE
binding.ivCuboidIndicator2Green.visibility = View.INVISIBLE
binding.ivCuboidIndicator1Orange.visibility = View.VISIBLE
binding.ivCuboidIndicator2Orange.visibility = View.VISIBLE
}
}
private fun userCheck() {
val user = FirebaseAuth.getInstance().currentUser
if (user == null) {
Toast.makeText(this, "Please Login to an account", Toast.LENGTH_SHORT).show()
val intent = Intent(this, LoginActivity::class.java)
startActivity(intent)
finish()
} else {
Toast.makeText(this, "Welcome back!", Toast.LENGTH_SHORT).show()
dailycheck()
getWeekCount()
}
}
private fun populateHistory() {
val userID = user.currentUser!!.uid
mainAdapter = MainAdapter(healthDataList)
binding.rvHealthHistory.apply {
adapter = mainAdapter
layoutManager = LinearLayoutManager(this@MainActivity)
}
database.getReference("users").child(userID).child("journal").get()
.addOnCompleteListener { task ->
if (task.isSuccessful) {
healthDataList.clear()
task.result.children.forEach { snapshot ->
val journalID = snapshot.child("date").value.toString()
val bloodSugar = snapshot.child("bloodSugar").value.toString().toFloatOrNull() ?: 0f
val diastolicBP = snapshot.child("bloodPressureDIA").value.toString().toIntOrNull() ?: 0
val systolicBP = snapshot.child("bloodPressureSYS").value.toString().toIntOrNull() ?: 0
val BMI = snapshot.child("bmi").value.toString().toFloatOrNull() ?: 0f
val date = snapshot.child("date").value.toString()
val resultData = ResultData(journalID, bloodSugar, diastolicBP, systolicBP, BMI, date)
healthDataList.add(resultData)
}
mainAdapter.notifyDataSetChanged()
} else {
Log.d("error", task.exception?.message.toString())
Toast.makeText(this, task.exception?.message, Toast.LENGTH_SHORT).show()
}
}
}
private fun populateTodayReport(){
val today = SimpleDateFormat("dd/MM/yyyy", Locale.getDefault()).format(android.icu.util.Calendar.getInstance().time).toString()
val userID = user.currentUser!!.uid
database.getReference("users").child(userID).child("journal").get().addOnCompleteListener { task ->
if (task.isSuccessful) {
task.result.children.forEach {
if (it.child("date").value.toString() == today) {
binding.tvBloodsugarLevel.text = it.child("bloodSugar").value.toString()+" mg/dL"
binding.tvBloodsugarDesc.text = it.child("recommendation").child("bloodSugarAnalysis").value.toString()
binding.tvBloodpressureLevel.text = it.child("bloodPressureDIA").value.toString()+"/"+it.child("bloodPressureSYS").value.toString()+" mm Hg"
binding.tvBloodpressureDesc.text = it.child("recommendation").child("bloodPressureAnalysis").value.toString()
binding.tvBmiLevel.text = it.child("BMI").value.toString() +" BMI"
binding.tvBmiDesc.text = it.child("recommendation").child("BMIAnalysis").value.toString()
}
}
} else {
Log.d("error", task.exception!!.message.toString())
Toast.makeText(this, task.exception!!.message, Toast.LENGTH_SHORT).show()
}
}
}
}

View File

@ -0,0 +1,73 @@
package com.healthjournal.ui.dashboard
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.healthjournal.R
import com.healthjournal.data.ResultData
import com.healthjournal.ui.journal.detail.DetailJournalActivity
import java.text.SimpleDateFormat
import java.util.Locale
class MainAdapter(private val healthDataList: MutableList<ResultData>) : RecyclerView.Adapter<MainAdapter.HealthViewHolder>() {
class HealthViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val tvDay: TextView = view.findViewById(R.id.tv_day)
val tvDate: TextView = view.findViewById(R.id.tv_date)
val tvBloodSugar: TextView = view.findViewById(R.id.tv_BS_Level)
val tvBloodPressure: TextView = view.findViewById(R.id.tv_BP_Level)
}
// Function to update the list and notify the adapter
fun setData(newData: List<ResultData>) {
healthDataList.clear()
healthDataList.addAll(newData)
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HealthViewHolder {
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 {
val dateFormat = SimpleDateFormat("dd/MM/yyyy", Locale.getDefault())
val parsedDate = dateFormat.parse(date)
if (parsedDate != null) {
SimpleDateFormat("EEEE", Locale.getDefault()).format(parsedDate)
} else {
"Invalid Date"
}
} catch (e: Exception) {
"Invalid Date"
}
}
private fun countGoals (){
}
override fun onBindViewHolder(holder: HealthViewHolder, position: Int) {
val healthData = healthDataList[position]
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.itemView.setOnClickListener {
val context = holder.itemView.context
val intent = Intent(context, DetailJournalActivity::class.java).apply {
putExtra("HEALTH_DATA", healthData)
}
context.startActivity(intent)
}
}
override fun getItemCount(): Int = healthDataList.size
}

View File

@ -0,0 +1,92 @@
package com.healthjournal.ui.journal.detail
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.google.firebase.Firebase
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.database.database
import com.healthjournal.R
import com.healthjournal.data.ResultData
import com.healthjournal.databinding.ActivityDetailJournalBinding
class DetailJournalActivity : AppCompatActivity() {
private lateinit var binding: ActivityDetailJournalBinding
private lateinit var user: FirebaseAuth
private val database = Firebase.database
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityDetailJournalBinding.inflate(layoutInflater)
setContentView(binding.root)
val healthData = intent.getSerializableExtra("HEALTH_DATA") as? ResultData
}
private fun populateDetailJournal() {
val userID = user.currentUser?.uid
val journalDate = intent.getStringExtra("JOURNAL_DATE")
if (userID != null && journalDate != null) {
database.getReference("users").child(userID).child("journal").child(journalDate).get()
.addOnCompleteListener(DetailJournalActivity()) {
if (it.isSuccessful) {
val data = it.result
if (data != null) {
/*
binding.tvBloodsugarLevel2.text = data.bloodSugarLevel
binding.tvBloodsugarDesc.text = data.bloodSugarDesc
binding.tvBloodpressureLevel2.text = data.bloodPressureLevel
binding.tvBloodpressureDesc.text = data.bloodPressureDesc
binding.tvBMILevel2.text = data.bmiLevel
binding.tvBMIDesc.text = data.bmiDesc
binding.tvGoals2.text = countGoalsCompleted(data.goalsCompleted)
binding.tvJournalNote.text = data.journalNote
*/
}
} else {
Toast.makeText(this, it.exception!!.message, Toast.LENGTH_SHORT).show()
Log.d("error", it.exception!!.message.toString())
}
}
}
}
private fun countGoalsCompleted(goalsCompleted: List<Boolean>): String {
var count = 0
for (completed in goalsCompleted) {
if (completed) {
count++
}
}
return count.toString()
}
private fun deleteHistory() {
val userID = user.currentUser?.uid
val journalDate = intent.getStringExtra("JOURNAL_DATE")
if (userID != null && journalDate != null) {
database.getReference("users").child(userID).child("journal").child(journalDate)
.removeValue()
.addOnCompleteListener(DetailJournalActivity()) {
if (it.isSuccessful) {
Toast.makeText(this, "History deleted successfully", Toast.LENGTH_SHORT)
.show()
finish()
} else {
Toast.makeText(this, it.exception!!.message, Toast.LENGTH_SHORT).show()
}
}
}
}
private fun setupListener() {
binding.btnDeleteHistory.setOnClickListener() {
deleteHistory()
}
}
}

View File

@ -0,0 +1,127 @@
package com.healthjournal.ui.journal.input
import android.content.Intent
import android.icu.util.Calendar
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.database.FirebaseDatabase
import com.healthjournal.algorithm.AlgoritmaKesehatan
import com.healthjournal.databinding.ActivityJournalInputBinding
import com.healthjournal.ui.dashboard.MainActivity
import com.healthjournal.data.HealthData
import java.text.SimpleDateFormat
import java.util.Locale
class JournalInputActivity : AppCompatActivity() {
private lateinit var binding: ActivityJournalInputBinding
private lateinit var user: FirebaseAuth
private lateinit var database: FirebaseDatabase
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityJournalInputBinding.inflate(layoutInflater)
setContentView(binding.root)
user = FirebaseAuth.getInstance()
database = FirebaseDatabase.getInstance()
val userId = user.currentUser?.uid
if (userId != null) {
database.getReference("users").child(userId).get()
.addOnCompleteListener { task ->
if (task.isSuccessful && task.result.exists()) {
binding.edtInputWeight.setText(task.result.child("weight").value.toString())
binding.edtHeight.setText(task.result.child("height").value.toString())
binding.edtAge.setText(task.result.child("date").value.toString())
binding.edtGender.setText(task.result.child("gender").value.toString())
} else {
Toast.makeText(this, "Error: ${task.exception?.message}", Toast.LENGTH_SHORT).show()
Log.d("error", task.exception?.message.toString())
}
}
} else {
Toast.makeText(this, "User not logged in", Toast.LENGTH_SHORT).show()
finish()
}
setupListener()
}
private fun setupListener() {
binding.btnInputData.setOnClickListener {
submitData()
}
}
private fun calculateBMI(weight: Int, height: Int): Float {
val heightInMeters = height / 100f
val BMI = weight / (heightInMeters * heightInMeters)
return BMI
}
fun calculateAge(birthDate: String): Int {
val sdf = SimpleDateFormat("dd/MM/yyyy", Locale.getDefault())
val date = sdf.parse(birthDate)
val birthCalendar = Calendar.getInstance()
birthCalendar.time = date
val today = Calendar.getInstance()
var age = today.get(Calendar.YEAR) - birthCalendar.get(Calendar.YEAR)
if (today.get(Calendar.DAY_OF_YEAR) < birthCalendar.get(Calendar.DAY_OF_YEAR)) {
age--
}
return age
}
private fun submitData() {
val userId = user.currentUser?.uid
if (userId == null) {
Toast.makeText(this, "User not logged in", Toast.LENGTH_SHORT).show()
return
}
val journalDate = SimpleDateFormat("dd/MM/yyyy", Locale.getDefault()).format(Calendar.getInstance().time).toString()
val bloodPressureSYS = binding.edtInputBloodPressureSYS.text.toString()
val bloodPressureDIA = binding.edtInputBloodPressureDIA.text.toString()
val bloodSugar = binding.edtInputBloodSugar.text.toString()
val weight = binding.edtInputWeight.text.toString().toInt()
val height = binding.edtHeight.text.toString().toInt()
val note = binding.edtInputNote.text.toString()
val age = calculateAge(binding.edtAge.text.toString())
val gender = binding.edtGender.text.toString()
Log.d("journalDate", journalDate)
if (weight != null && bloodPressureSYS.isNotEmpty() && bloodPressureDIA.isNotEmpty() && bloodSugar.isNotEmpty()) {
database.getReference("users").child(userId).child("height").get().addOnSuccessListener { snapshot ->
val BMI = calculateBMI(weight, height)
val healthData = HealthData(bloodSugar.toFloat(), bloodPressureSYS.toInt(), bloodPressureDIA.toInt(), BMI,age,gender)
val recommendation = AlgoritmaKesehatan().recommendationOfTheDay(healthData)
val data = hashMapOf(
"date" to journalDate,
"bloodPressureSYS" to bloodPressureSYS,
"bloodPressureDIA" to bloodPressureDIA,
"bloodSugar" to bloodSugar,
"BMI" to BMI,
"note" to note,
"recommendation" to recommendation
)
database.getReference("users").child(userId).child("journal").push().setValue(data).addOnCompleteListener {
if (it.isSuccessful) {
Toast.makeText(this, "Data Input Success", Toast.LENGTH_SHORT).show()
startActivity(Intent(this, MainActivity::class.java))
finish()
} else {
Toast.makeText(this, it.exception?.message, Toast.LENGTH_SHORT).show()
Log.d("error", it.exception?.message.toString())
}
}
}
} else {
Toast.makeText(this, "Please fill all fields correctly", Toast.LENGTH_SHORT).show()
}
}
}

View File

@ -0,0 +1,57 @@
package com.healthjournal.ui.login
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.firebase.auth.FirebaseAuth
import com.healthjournal.databinding.ActivityLoginBinding
import com.healthjournal.ui.dashboard.MainActivity
import com.healthjournal.ui.register.RegisterActivity
class LoginActivity : AppCompatActivity() {
private lateinit var binding: ActivityLoginBinding
private lateinit var user: FirebaseAuth
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityLoginBinding.inflate(layoutInflater)
setContentView(binding.root)
user = FirebaseAuth.getInstance()
setuplistener()
}
private fun setuplistener() {
binding.btnLogin.setOnClickListener{
loginUser()
}
binding.btnRegister.setOnClickListener{
startActivity(Intent(this@LoginActivity, RegisterActivity::class.java))
finish()
}
}
private fun loginUser() {
val email = binding.edtEmail.text.toString()
val password = binding.edtPassword.text.toString()
if (email.isEmpty() || password.isEmpty()) {
if (email.isEmpty()) binding.edtEmail.error = "Email cannot be empty"
if (password.isEmpty()) binding.edtPassword.error = "Password cannot be empty"
Toast.makeText(this, "Email & Password cannot be empty", Toast.LENGTH_SHORT).show()
} else {
user.signInWithEmailAndPassword(email, password).addOnCompleteListener(LoginActivity()){ task ->
if (task.isSuccessful) {
Toast.makeText(this, "Login Success", Toast.LENGTH_SHORT).show()
startActivity(Intent(this@LoginActivity, MainActivity::class.java))
finish()
}
else{
Toast.makeText(this, task.exception!!.message, Toast.LENGTH_SHORT).show()
Log.d("error", task.exception!!.message.toString())
}
}
}
}
}

View File

@ -0,0 +1,81 @@
package com.healthjournal.ui.profile
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.google.firebase.Firebase
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.database.database
import com.healthjournal.R
import com.healthjournal.databinding.ActivityProfileBinding
import com.healthjournal.ui.login.LoginActivity
class ProfileActivity : AppCompatActivity() {
private lateinit var binding: ActivityProfileBinding
private lateinit var user: FirebaseAuth
private val database = Firebase.database
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityProfileBinding.inflate(layoutInflater)
setContentView(binding.root)
setupListener()
populateData()
}
private fun setupListener() {
binding.btnLogout.setOnClickListener {
logout()
}
binding.btnUpdateData.setOnClickListener {
updateData()
}
}
private fun logout(){
user.signOut()
startActivity(Intent(this, LoginActivity::class.java))
finish()
}
private fun updateData(){
val userID = user.currentUser?.uid
val name = binding.edtName.text.toString()
val email = binding.edtEmail.text.toString()
val date = binding.edtDates.text.toString()
val weight = binding.edtInputWeight.text.toString()
val height = binding.edtInputHeight.text.toString()
val userRef = database.getReference("users").child(userID!!)
userRef.child("name").setValue(name)
userRef.child("email").setValue(email)
userRef.child("date").setValue(date)
userRef.child("weight").setValue(weight)
userRef.child("height").setValue(height)
Toast.makeText(this, "Data Updated", Toast.LENGTH_SHORT).show()
populateData()
}
private fun populateData(){
val userID = user.currentUser?.uid
val userRef = database.getReference("users").child(userID!!)
userRef.get().addOnCompleteListener(ProfileActivity()){
if (it.isSuccessful){
binding.edtName.setText(it.result.child("name").value.toString())
binding.edtDates.setText(it.result.child("date").value.toString())
binding.edtInputHeight.setText(it.result.child("height").value.toString())
binding.edtInputWeight.setText(it.result.child("weight").value.toString())
} else {
Toast.makeText(this, it.exception.toString(), Toast.LENGTH_SHORT).show()
Log.d("ProfileActivity", it.exception.toString())
}
}
}
}

View File

@ -0,0 +1,40 @@
package com.healthjournal.ui.recommendation
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.CheckBox
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.healthjournal.R
class RecommendationAdapter(
private val recommendationList: List<Pair<String, Boolean>>,
private val onCheckedChange: (position: Int, isChecked: Boolean) -> Unit
) : RecyclerView.Adapter<RecommendationAdapter.RecommendationViewHolder>() {
inner class RecommendationViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val tvGoalName: TextView = view.findViewById(R.id.tv_goal_name)
val checkBox: CheckBox = view.findViewById(R.id.toggle)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecommendationViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_goals_recommendation, parent, false)
return RecommendationViewHolder(view)
}
override fun onBindViewHolder(holder: RecommendationViewHolder, position: Int) {
val (task, isCompleted) = recommendationList[position]
holder.tvGoalName.text = task
holder.checkBox.isChecked = isCompleted
holder.checkBox.setOnCheckedChangeListener { _, isChecked ->
onCheckedChange(position, isChecked)
}
holder.itemView.setOnClickListener {
holder.checkBox.isChecked = !holder.checkBox.isChecked
}
}
override fun getItemCount(): Int = recommendationList.size
}

View File

@ -0,0 +1,99 @@
package com.healthjournal.ui.recommendation
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.database.FirebaseDatabase
import com.healthjournal.databinding.ActivityRecommendationBinding
import java.text.SimpleDateFormat
import java.util.Locale
class RecommendationActivity : AppCompatActivity() {
private lateinit var binding: ActivityRecommendationBinding
private lateinit var user: FirebaseAuth
private lateinit var database: FirebaseDatabase
private lateinit var adapter: RecommendationAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityRecommendationBinding.inflate(layoutInflater)
setContentView(binding.root)
user = FirebaseAuth.getInstance()
database = FirebaseDatabase.getInstance()
populateData()
}
private fun populateData() {
val userID = user.currentUser?.uid ?: return
val today = SimpleDateFormat("dd/MM/yyyy", Locale.getDefault())
.format(android.icu.util.Calendar.getInstance().time)
database.getReference("users").child(userID).child("journal")
.get()
.addOnCompleteListener { task ->
if (task.isSuccessful) {
task.result.children.forEach {
if (it.child("date").value.toString() == today) {
binding.tvBloodsugarLevel2.text = "${it.child("bloodSugar").value} mg/dL"
binding.tvBloodsugarDesc.text = it.child("recommendation").child("bloodSugarAnalysis").value.toString()
binding.tvBloodpressureLevel2.text = "${it.child("bloodPressureDIA").value}/${it.child("bloodPressureSYS").value} mm Hg"
binding.tvBloodpressureDesc.text = it.child("recommendation").child("bloodPressureAnalysis").value.toString()
binding.tvBMILevel2.text = "${it.child("BMI").value} BMI"
binding.tvBMIDesc.text = it.child("recommendation").child("BMIAnalysis").value.toString()
val tasks = it.child("recommendation").child("tasks").value
val referencePath = it.key ?: return@forEach
populateRecomendation(tasks, userID, referencePath)
}
}
} else {
Log.e("error", task.exception?.message.toString())
Toast.makeText(this, task.exception?.message, Toast.LENGTH_SHORT).show()
}
}
}
private fun populateRecomendation(tasks: Any?, userID: String, journalKey: String) {
val taskList = mutableListOf<Pair<String, Boolean>>()
// Handle List format for tasks
if (tasks is List<*>) {
tasks.forEach { taskData ->
if (taskData is Map<*, *> && taskData["task"] != null && taskData["completed"] != null) {
val taskDescription = taskData["task"].toString()
val isCompleted = taskData["completed"] as? Boolean ?: false
taskList.add(Pair(taskDescription, isCompleted))
}
}
// Set up RecyclerView and Adapter
adapter = RecommendationAdapter(taskList) { position, isChecked ->
taskList[position] = taskList[position].copy(second = isChecked)
// Update Firebase
database.getReference("users")
.child(userID)
.child("journal")
.child(journalKey)
.child("recommendation")
.child("tasks")
.child(position.toString())
.child("completed")
.setValue(isChecked)
}
binding.rvTasks.apply {
layoutManager = LinearLayoutManager(this@RecommendationActivity)
adapter = this@RecommendationActivity.adapter
}
} else {
Log.e("error", "Invalid tasks data format")
Log.e("error", tasks.toString())
}
}
}

View File

@ -0,0 +1,60 @@
package com.healthjournal.ui.register
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.firebase.auth.FirebaseAuth
import com.healthjournal.databinding.ActivityRegisterBinding
import com.healthjournal.ui.users.UsersInputActivity
class RegisterActivity : AppCompatActivity() {
private lateinit var binding: ActivityRegisterBinding
private lateinit var user: FirebaseAuth
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityRegisterBinding.inflate(layoutInflater)
setContentView(binding.root)
user = FirebaseAuth.getInstance()
setuplistener()
}
private fun setuplistener(){
binding.btnRegister.setOnClickListener{
registerUser()
}
binding.btnLogin.setOnClickListener{
}
}
private fun registerUser(){
val email = binding.edtEmail.text.toString()
val password = binding.edtPassword.text.toString()
val confirmPassword = binding.edtPasswordConfirm.text.toString()
if (email.isEmpty() || password.isEmpty() || confirmPassword.isEmpty()){
if (email.isEmpty()) binding.edtEmail.error = "Email cannot be empty"
if (password.isEmpty()) binding.edtPassword.error = "Password cannot be empty"
if (confirmPassword.isEmpty()) binding.edtPasswordConfirm.error = "Confirm Password cannot be empty"
} else {
if (password == confirmPassword){
user.createUserWithEmailAndPassword(email, password).addOnCompleteListener(RegisterActivity()){ task ->
if(task.isSuccessful){
Toast.makeText(this, "Register Success", Toast.LENGTH_SHORT).show()
startActivity(Intent(this@RegisterActivity,UsersInputActivity::class.java))
finish()
} else{
Toast.makeText(this, task.exception!!.message, Toast.LENGTH_SHORT).show()
Log.d("error", task.exception!!.message.toString())
}
}
} else {
binding.edtPasswordConfirm.error = "Password does not match"
}
}
}
}

View File

@ -0,0 +1,21 @@
package com.healthjournal.ui.splashscreen
import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.healthjournal.R
class SplashscreenActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_splashscreen)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
}
}

View File

@ -0,0 +1,101 @@
package com.healthjournal.ui.users
import android.app.DatePickerDialog
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.widget.ArrayAdapter
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.firebase.Firebase
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.database.database
import com.healthjournal.databinding.ActivityUsersInputBinding
import com.healthjournal.ui.dashboard.MainActivity
import java.util.Calendar
class UsersInputActivity : AppCompatActivity() {
private lateinit var binding: ActivityUsersInputBinding
private lateinit var user: FirebaseAuth
private val database = Firebase.database
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityUsersInputBinding.inflate(layoutInflater)
setContentView(binding.root)
user = FirebaseAuth.getInstance()
val gender = arrayOf("Male", "Female", "Other")
// Adapter for conditions
val conditionAdapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, gender)
binding.dropdownGender.setAdapter(conditionAdapter)
userCheck()
setuplistener()
}
private fun userCheck(){
if(user.currentUser != null){
user.currentUser?.let {
binding.tvEmail.text = it.email
}
}
}
private fun setuplistener(){
binding.btnInput.setOnClickListener{
inputUserData()
}
binding.edtDateOfBirth.setOnClickListener{
datepicker()
}
}
private fun datepicker(){
val calendar = Calendar.getInstance()
val year = calendar.get(Calendar.YEAR)
val month = calendar.get(Calendar.MONTH)
val day = calendar.get(Calendar.DAY_OF_MONTH)
val datePickerDialog = DatePickerDialog(
this,
{ _, selectedYear, selectedMonth, selectedDay ->
val selectedDate = "$selectedDay/${selectedMonth + 1}/$selectedYear"
binding.edtDateOfBirth.setText(selectedDate)
},
year, month, day
)
datePickerDialog.show()
}
private fun inputUserData() {
val userID = user.currentUser?.uid
val name = binding.edtName.text.toString()
val gender = binding.dropdownGender.text.toString()
val date = binding.edtDateOfBirth.text.toString()
val weight = binding.edtInputWeight.text.toString()
val height = binding.edtInputHeigh.text.toString()
if(userID != null){
if (name.isNotEmpty() && gender.isNotEmpty() && date.isNotEmpty() && weight.isNotEmpty() && height.isNotEmpty()){
val data = hashMapOf(
"name" to name,
"gender" to gender,
"date" to date,
"height" to height,
"weight" to weight)
database.getReference("users").child(userID).setValue(data).addOnCompleteListener(UsersInputActivity()){
if(it.isSuccessful){
Toast.makeText(this, "Data Input Success", Toast.LENGTH_SHORT).show()
startActivity(Intent(this@UsersInputActivity, MainActivity::class.java))
finish()
} else{
Toast.makeText(this, it.exception!!.message, Toast.LENGTH_SHORT).show()
Log.d("error", it.exception!!.message.toString())
}
}
}
}
}
}