diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 66154f8..bd34dc7 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -44,6 +44,7 @@ dependencies { implementation(libs.androidx.appcompat) implementation(libs.material) implementation(libs.androidx.constraintlayout) + implementation(libs.androidx.coordinatorlayout) implementation(libs.androidx.lifecycle.livedata.ktx) implementation(libs.androidx.lifecycle.viewmodel.ktx) implementation(libs.androidx.navigation.fragment.ktx) diff --git a/app/src/main/java/sh/sar/gridflow/MainActivity.kt b/app/src/main/java/sh/sar/gridflow/MainActivity.kt index 52d44cc..64feec9 100644 --- a/app/src/main/java/sh/sar/gridflow/MainActivity.kt +++ b/app/src/main/java/sh/sar/gridflow/MainActivity.kt @@ -1,7 +1,10 @@ package sh.sar.gridflow +import android.content.Intent +import android.net.Uri import android.os.Bundle import android.view.Menu +import android.view.MenuItem import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatDelegate @@ -41,12 +44,50 @@ class MainActivity : AppCompatActivity() { // Update navigation header with user info updateNavHeader(navView) - // Only Home in the navigation + // Set up navigation with all main fragments appBarConfiguration = AppBarConfiguration( - setOf(R.id.nav_home), drawerLayout + setOf( + R.id.nav_dashboard, + R.id.nav_subscriptions, + R.id.nav_band_rates, + R.id.nav_bill_history, + R.id.nav_pay_any_bill + ), drawerLayout ) setupActionBarWithNavController(navController, appBarConfiguration) navView.setupWithNavController(navController) + + // Handle special menu items (Terms of Service and Privacy Policy) + navView.setNavigationItemSelectedListener { menuItem -> + when (menuItem.itemId) { + R.id.nav_terms_of_service -> { + openUrl("https://fenaka.mv/terms-and-conditions") + drawerLayout.closeDrawers() + true + } + R.id.nav_privacy_policy -> { + openUrl("https://fenaka.mv/privacy-policy") + drawerLayout.closeDrawers() + true + } + else -> { + // Let the default navigation handle other items + try { + navController.navigate(menuItem.itemId) + menuItem.isChecked = true + drawerLayout.closeDrawers() + true + } catch (e: Exception) { + false + } + } + } + } + } + + private fun openUrl(url: String) { + val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) + startActivity(intent) } private fun updateNavHeader(navView: NavigationView) { diff --git a/app/src/main/java/sh/sar/gridflow/ui/bandrates/BandRatesFragment.kt b/app/src/main/java/sh/sar/gridflow/ui/bandrates/BandRatesFragment.kt new file mode 100644 index 0000000..620acfc --- /dev/null +++ b/app/src/main/java/sh/sar/gridflow/ui/bandrates/BandRatesFragment.kt @@ -0,0 +1,39 @@ +package sh.sar.gridflow.ui.bandrates + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.lifecycle.ViewModelProvider +import sh.sar.gridflow.databinding.FragmentBandRatesBinding + +class BandRatesFragment : Fragment() { + + private var _binding: FragmentBandRatesBinding? = null + private val binding get() = _binding!! + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + val bandRatesViewModel = + ViewModelProvider(this).get(BandRatesViewModel::class.java) + + _binding = FragmentBandRatesBinding.inflate(inflater, container, false) + val root: View = binding.root + + val textView = binding.textBandRates + bandRatesViewModel.text.observe(viewLifecycleOwner) { + textView.text = it + } + + return root + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } +} diff --git a/app/src/main/java/sh/sar/gridflow/ui/bandrates/BandRatesViewModel.kt b/app/src/main/java/sh/sar/gridflow/ui/bandrates/BandRatesViewModel.kt new file mode 100644 index 0000000..1db14c8 --- /dev/null +++ b/app/src/main/java/sh/sar/gridflow/ui/bandrates/BandRatesViewModel.kt @@ -0,0 +1,13 @@ +package sh.sar.gridflow.ui.bandrates + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel + +class BandRatesViewModel : ViewModel() { + + private val _text = MutableLiveData().apply { + value = "Band Rates\n\nComing soon..." + } + val text: LiveData = _text +} diff --git a/app/src/main/java/sh/sar/gridflow/ui/billhistory/BillHistoryFragment.kt b/app/src/main/java/sh/sar/gridflow/ui/billhistory/BillHistoryFragment.kt new file mode 100644 index 0000000..91a10cb --- /dev/null +++ b/app/src/main/java/sh/sar/gridflow/ui/billhistory/BillHistoryFragment.kt @@ -0,0 +1,39 @@ +package sh.sar.gridflow.ui.billhistory + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.lifecycle.ViewModelProvider +import sh.sar.gridflow.databinding.FragmentBillHistoryBinding + +class BillHistoryFragment : Fragment() { + + private var _binding: FragmentBillHistoryBinding? = null + private val binding get() = _binding!! + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + val billHistoryViewModel = + ViewModelProvider(this).get(BillHistoryViewModel::class.java) + + _binding = FragmentBillHistoryBinding.inflate(inflater, container, false) + val root: View = binding.root + + val textView = binding.textBillHistory + billHistoryViewModel.text.observe(viewLifecycleOwner) { + textView.text = it + } + + return root + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } +} diff --git a/app/src/main/java/sh/sar/gridflow/ui/billhistory/BillHistoryViewModel.kt b/app/src/main/java/sh/sar/gridflow/ui/billhistory/BillHistoryViewModel.kt new file mode 100644 index 0000000..1e7f075 --- /dev/null +++ b/app/src/main/java/sh/sar/gridflow/ui/billhistory/BillHistoryViewModel.kt @@ -0,0 +1,13 @@ +package sh.sar.gridflow.ui.billhistory + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel + +class BillHistoryViewModel : ViewModel() { + + private val _text = MutableLiveData().apply { + value = "Bill History\n\nComing soon..." + } + val text: LiveData = _text +} diff --git a/app/src/main/java/sh/sar/gridflow/ui/payanybill/PayAnyBillFragment.kt b/app/src/main/java/sh/sar/gridflow/ui/payanybill/PayAnyBillFragment.kt new file mode 100644 index 0000000..ce3d4c7 --- /dev/null +++ b/app/src/main/java/sh/sar/gridflow/ui/payanybill/PayAnyBillFragment.kt @@ -0,0 +1,39 @@ +package sh.sar.gridflow.ui.payanybill + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.lifecycle.ViewModelProvider +import sh.sar.gridflow.databinding.FragmentPayAnyBillBinding + +class PayAnyBillFragment : Fragment() { + + private var _binding: FragmentPayAnyBillBinding? = null + private val binding get() = _binding!! + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + val payAnyBillViewModel = + ViewModelProvider(this).get(PayAnyBillViewModel::class.java) + + _binding = FragmentPayAnyBillBinding.inflate(inflater, container, false) + val root: View = binding.root + + val textView = binding.textPayAnyBill + payAnyBillViewModel.text.observe(viewLifecycleOwner) { + textView.text = it + } + + return root + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } +} diff --git a/app/src/main/java/sh/sar/gridflow/ui/payanybill/PayAnyBillViewModel.kt b/app/src/main/java/sh/sar/gridflow/ui/payanybill/PayAnyBillViewModel.kt new file mode 100644 index 0000000..58f601c --- /dev/null +++ b/app/src/main/java/sh/sar/gridflow/ui/payanybill/PayAnyBillViewModel.kt @@ -0,0 +1,13 @@ +package sh.sar.gridflow.ui.payanybill + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel + +class PayAnyBillViewModel : ViewModel() { + + private val _text = MutableLiveData().apply { + value = "Pay Any Bill\n\nComing soon..." + } + val text: LiveData = _text +} diff --git a/app/src/main/java/sh/sar/gridflow/ui/subscriptions/SubscriptionsFragment.kt b/app/src/main/java/sh/sar/gridflow/ui/subscriptions/SubscriptionsFragment.kt new file mode 100644 index 0000000..7bb868b --- /dev/null +++ b/app/src/main/java/sh/sar/gridflow/ui/subscriptions/SubscriptionsFragment.kt @@ -0,0 +1,45 @@ +package sh.sar.gridflow.ui.subscriptions + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.fragment.app.Fragment +import androidx.lifecycle.ViewModelProvider +import sh.sar.gridflow.databinding.FragmentSubscriptionsBinding + +class SubscriptionsFragment : Fragment() { + + private var _binding: FragmentSubscriptionsBinding? = null + private val binding get() = _binding!! + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + val subscriptionsViewModel = + ViewModelProvider(this).get(SubscriptionsViewModel::class.java) + + _binding = FragmentSubscriptionsBinding.inflate(inflater, container, false) + val root: View = binding.root + + val textView = binding.textSubscriptions + subscriptionsViewModel.text.observe(viewLifecycleOwner) { + textView.text = it + } + + // Handle FAB click + binding.fabAddSubscription.setOnClickListener { + Toast.makeText(context, "Add subscription coming soon", Toast.LENGTH_SHORT).show() + } + + return root + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } +} diff --git a/app/src/main/java/sh/sar/gridflow/ui/subscriptions/SubscriptionsViewModel.kt b/app/src/main/java/sh/sar/gridflow/ui/subscriptions/SubscriptionsViewModel.kt new file mode 100644 index 0000000..5e8458a --- /dev/null +++ b/app/src/main/java/sh/sar/gridflow/ui/subscriptions/SubscriptionsViewModel.kt @@ -0,0 +1,13 @@ +package sh.sar.gridflow.ui.subscriptions + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel + +class SubscriptionsViewModel : ViewModel() { + + private val _text = MutableLiveData().apply { + value = "Subscriptions\n\nComing soon..." + } + val text: LiveData = _text +} diff --git a/app/src/main/res/drawable/ic_add_24.xml b/app/src/main/res/drawable/ic_add_24.xml new file mode 100644 index 0000000..ac3e915 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_band_rates_24.xml b/app/src/main/res/drawable/ic_band_rates_24.xml new file mode 100644 index 0000000..c9758a7 --- /dev/null +++ b/app/src/main/res/drawable/ic_band_rates_24.xml @@ -0,0 +1,31 @@ + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_bill_history_24.xml b/app/src/main/res/drawable/ic_bill_history_24.xml new file mode 100644 index 0000000..48682a6 --- /dev/null +++ b/app/src/main/res/drawable/ic_bill_history_24.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/app/src/main/res/drawable/ic_dashboard_24.xml b/app/src/main/res/drawable/ic_dashboard_24.xml new file mode 100644 index 0000000..9eda440 --- /dev/null +++ b/app/src/main/res/drawable/ic_dashboard_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_pay_any_bill_24.xml b/app/src/main/res/drawable/ic_pay_any_bill_24.xml new file mode 100644 index 0000000..64c01fc --- /dev/null +++ b/app/src/main/res/drawable/ic_pay_any_bill_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_privacy_24.xml b/app/src/main/res/drawable/ic_privacy_24.xml new file mode 100644 index 0000000..cf90202 --- /dev/null +++ b/app/src/main/res/drawable/ic_privacy_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_subscriptions_24.xml b/app/src/main/res/drawable/ic_subscriptions_24.xml new file mode 100644 index 0000000..2b47e60 --- /dev/null +++ b/app/src/main/res/drawable/ic_subscriptions_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_terms_24.xml b/app/src/main/res/drawable/ic_terms_24.xml new file mode 100644 index 0000000..ae4772a --- /dev/null +++ b/app/src/main/res/drawable/ic_terms_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/fragment_band_rates.xml b/app/src/main/res/layout/fragment_band_rates.xml new file mode 100644 index 0000000..004b59d --- /dev/null +++ b/app/src/main/res/layout/fragment_band_rates.xml @@ -0,0 +1,29 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_bill_history.xml b/app/src/main/res/layout/fragment_bill_history.xml new file mode 100644 index 0000000..a4e4da7 --- /dev/null +++ b/app/src/main/res/layout/fragment_bill_history.xml @@ -0,0 +1,29 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_pay_any_bill.xml b/app/src/main/res/layout/fragment_pay_any_bill.xml new file mode 100644 index 0000000..ba0fed7 --- /dev/null +++ b/app/src/main/res/layout/fragment_pay_any_bill.xml @@ -0,0 +1,29 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_subscriptions.xml b/app/src/main/res/layout/fragment_subscriptions.xml new file mode 100644 index 0000000..f2fc3d4 --- /dev/null +++ b/app/src/main/res/layout/fragment_subscriptions.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/menu/activity_main_drawer.xml b/app/src/main/res/menu/activity_main_drawer.xml index 1fb2d32..9e77f69 100644 --- a/app/src/main/res/menu/activity_main_drawer.xml +++ b/app/src/main/res/menu/activity_main_drawer.xml @@ -5,8 +5,35 @@ + android:id="@+id/nav_dashboard" + android:icon="@drawable/ic_dashboard_24" + android:title="@string/menu_dashboard" /> + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/navigation/mobile_navigation.xml b/app/src/main/res/navigation/mobile_navigation.xml index f07bd3f..a5b4e86 100644 --- a/app/src/main/res/navigation/mobile_navigation.xml +++ b/app/src/main/res/navigation/mobile_navigation.xml @@ -3,12 +3,36 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/mobile_navigation" - app:startDestination="@+id/nav_home"> + app:startDestination="@+id/nav_dashboard"> + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 262bfaf..d150699 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -7,7 +7,11 @@ Navigation header Settings - Home - Gallery - Slideshow + Dashboard + Subscriptions + Band Rates + Bill History + Pay any bill + Terms of Service + Privacy Policy \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e3b8d95..106c4c1 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,6 +15,7 @@ navigationUiKtx = "2.6.0" okhttp = "4.12.0" gson = "2.10.1" security = "1.1.0-alpha06" +coordinatorlayout = "1.2.0" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } @@ -32,6 +33,7 @@ okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhtt okhttp-logging = { group = "com.squareup.okhttp3", name = "logging-interceptor", version.ref = "okhttp" } gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" } security-crypto = { group = "androidx.security", name = "security-crypto", version.ref = "security" } +androidx-coordinatorlayout = { group = "androidx.coordinatorlayout", name = "coordinatorlayout", version.ref = "coordinatorlayout" } [plugins] android-application = { id = "com.android.application", version.ref = "agp" }