Upload source code aplikasi KopiKaoCare
|
|
@ -0,0 +1,15 @@
|
|||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/caches
|
||||
/.idea/libraries
|
||||
/.idea/modules.xml
|
||||
/.idea/workspace.xml
|
||||
/.idea/navEditor.xml
|
||||
/.idea/assetWizardSettings.xml
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
.externalNativeBuild
|
||||
.cxx
|
||||
local.properties
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
|
|
@ -0,0 +1 @@
|
|||
Projek TA
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AndroidProjectSystem">
|
||||
<option name="providerId" value="com.android.tools.idea.GradleProjectSystem" />
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<bytecodeTargetLevel target="21" />
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="deploymentTargetSelector">
|
||||
<selectionStates>
|
||||
<SelectionState runConfigName="app">
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
</SelectionState>
|
||||
</selectionStates>
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DeviceTable">
|
||||
<option name="columnSorters">
|
||||
<list>
|
||||
<ColumnSorterState>
|
||||
<option name="column" value="Name" />
|
||||
<option name="order" value="ASCENDING" />
|
||||
</ColumnSorterState>
|
||||
<ColumnSorterState>
|
||||
<option name="column" value="Type" />
|
||||
<option name="order" value="ASCENDING" />
|
||||
</ColumnSorterState>
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="testRunner" value="CHOOSE_PER_TEST" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
<option value="$PROJECT_DIR$/app" />
|
||||
</set>
|
||||
</option>
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
<option name="id" value="Android" />
|
||||
</component>
|
||||
<component name="VisualizationToolProject">
|
||||
<option name="state">
|
||||
<ProjectState>
|
||||
<option name="scale" value="0.19237365722656252" />
|
||||
</ProjectState>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RunConfigurationProducerService">
|
||||
<option name="ignoredProducers">
|
||||
<set>
|
||||
<option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.PatternConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
|
||||
<option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
|
||||
<option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
|
||||
</set>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1 @@
|
|||
/build
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
plugins {
|
||||
alias(libs.plugins.android.application)
|
||||
}
|
||||
|
||||
android {
|
||||
|
||||
namespace = "com.example.projekta"
|
||||
compileSdk = 36
|
||||
|
||||
defaultConfig {
|
||||
|
||||
applicationId = "com.example.projekta"
|
||||
minSdk = 24
|
||||
targetSdk = 33
|
||||
|
||||
versionCode = 1
|
||||
versionName = "1.0"
|
||||
|
||||
testInstrumentationRunner =
|
||||
"androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
packaging {
|
||||
resources {
|
||||
excludes += setOf(
|
||||
"META-INF/INDEX.LIST",
|
||||
"META-INF/DEPENDENCIES",
|
||||
"META-INF/io.netty.versions.properties",
|
||||
"META-INF/LICENSE*",
|
||||
"META-INF/NOTICE*"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
|
||||
release {
|
||||
|
||||
isMinifyEnabled = false
|
||||
|
||||
proguardFiles(
|
||||
getDefaultProguardFile(
|
||||
"proguard-android-optimize.txt"
|
||||
),
|
||||
"proguard-rules.pro"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
|
||||
sourceCompatibility =
|
||||
JavaVersion.VERSION_11
|
||||
|
||||
targetCompatibility =
|
||||
JavaVersion.VERSION_11
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
|
||||
viewBinding = true
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
// ANDROID
|
||||
implementation(libs.androidx.core.ktx)
|
||||
implementation(libs.androidx.appcompat)
|
||||
implementation(libs.material)
|
||||
implementation(libs.androidx.activity)
|
||||
implementation(libs.androidx.constraintlayout)
|
||||
|
||||
// RECYCLERVIEW
|
||||
implementation(
|
||||
"androidx.recyclerview:recyclerview:1.3.2"
|
||||
)
|
||||
|
||||
// CIRCLE IMAGE
|
||||
implementation(
|
||||
"de.hdodenhof:circleimageview:3.1.0"
|
||||
)
|
||||
|
||||
// IMAGE LOADER
|
||||
implementation(
|
||||
"io.coil-kt:coil:2.6.0"
|
||||
)
|
||||
|
||||
// VOLLEY
|
||||
implementation(
|
||||
"com.android.volley:volley:1.2.1"
|
||||
)
|
||||
|
||||
// SPLASH SCREEN
|
||||
implementation(
|
||||
"androidx.core:core-splashscreen:1.0.1"
|
||||
)
|
||||
|
||||
// MQTT
|
||||
implementation("com.hivemq:hivemq-mqtt-client:1.3.3")
|
||||
|
||||
// TEST
|
||||
testImplementation(libs.junit)
|
||||
|
||||
androidTestImplementation(
|
||||
libs.androidx.junit
|
||||
)
|
||||
|
||||
androidTestImplementation(
|
||||
libs.androidx.espresso.core
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.example.projekta
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ExampleInstrumentedTest {
|
||||
@Test
|
||||
fun useAppContext() {
|
||||
// Context of the app under test.
|
||||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
assertEquals("com.example.projekta", appContext.packageName)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<!-- INTERNET -->
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK"/>
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
|
||||
<!-- CAMERA -->
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
|
||||
<!-- STORAGE Android 13+ -->
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
||||
|
||||
<!-- STORAGE Android 12 ke bawah -->
|
||||
<uses-permission
|
||||
android:name="android.permission.READ_EXTERNAL_STORAGE"
|
||||
android:maxSdkVersion="32" />
|
||||
|
||||
<!-- CAMERA OPTIONAL -->
|
||||
<uses-feature
|
||||
android:name="android.hardware.camera"
|
||||
android:required="false" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.ProjekTA"
|
||||
android:usesCleartextTraffic="true"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
>
|
||||
|
||||
|
||||
|
||||
<!-- SPLASH -->
|
||||
<activity
|
||||
android:name=".SplashActivity"
|
||||
android:exported="true"
|
||||
android:theme="@style/Theme.ProjekTA.Splash">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<!-- LOGIN -->
|
||||
<activity android:name=".SignInActivity" android:exported="false" />
|
||||
<activity android:name=".LoginActivity" android:exported="false" />
|
||||
<activity android:name=".RegisterActivity" android:exported="false" />
|
||||
|
||||
<!-- MENU -->
|
||||
<activity android:name=".MenuActivity" android:exported="false" />
|
||||
|
||||
<!-- PROFILE -->
|
||||
<activity android:name=".ProfileActivity" android:exported="false" />
|
||||
|
||||
<!-- MENU DETAIL -->
|
||||
<activity android:name=".PemupukanActivity" android:exported="false" />
|
||||
<activity android:name=".MetodePemupukanActivity" android:exported="false" />
|
||||
<activity android:name=".PanelSuryaActivity" android:exported="false" />
|
||||
<activity android:name=".PanduanActivity" android:exported="false" />
|
||||
<activity android:name=".TentangActivity" android:exported="false" />
|
||||
|
||||
<!-- HISTORI -->
|
||||
<activity android:name=".HistoriActivity" android:exported="false" />
|
||||
|
||||
<!-- MAIN -->
|
||||
<activity android:name=".MainActivity" android:exported="false" />
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
package com.example.projekta
|
||||
|
||||
import android.os.Bundle
|
||||
import android.widget.ImageView
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.android.volley.Request
|
||||
import com.android.volley.toolbox.JsonArrayRequest
|
||||
import com.android.volley.toolbox.Volley
|
||||
import org.json.JSONObject
|
||||
|
||||
class HistoriActivity : AppCompatActivity() {
|
||||
|
||||
private lateinit var recyclerHistori: RecyclerView
|
||||
|
||||
private lateinit var historiList:
|
||||
ArrayList<HistoriModel>
|
||||
|
||||
private lateinit var historiAdapter:
|
||||
HistoriAdapter
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
setContentView(R.layout.activity_histori)
|
||||
|
||||
// ================= BACK =================
|
||||
val btnBack =
|
||||
findViewById<ImageView>(R.id.btnBack)
|
||||
|
||||
btnBack.setOnClickListener {
|
||||
finish()
|
||||
}
|
||||
|
||||
// ================= RECYCLERVIEW =================
|
||||
recyclerHistori =
|
||||
findViewById(R.id.recyclerHistori)
|
||||
|
||||
recyclerHistori.layoutManager =
|
||||
LinearLayoutManager(this)
|
||||
|
||||
historiList = ArrayList()
|
||||
|
||||
historiAdapter =
|
||||
HistoriAdapter(
|
||||
this,
|
||||
historiList
|
||||
)
|
||||
|
||||
recyclerHistori.adapter =
|
||||
historiAdapter
|
||||
|
||||
// ================= LOAD HISTORI =================
|
||||
loadHistori()
|
||||
}
|
||||
|
||||
private fun loadHistori() {
|
||||
|
||||
val url =
|
||||
"http://192.168.43.191/projekta/get_histori.php"
|
||||
|
||||
val request = JsonArrayRequest(
|
||||
|
||||
Request.Method.GET,
|
||||
url,
|
||||
null,
|
||||
|
||||
{ response ->
|
||||
|
||||
historiList.clear()
|
||||
|
||||
for (i in 0 until response.length()) {
|
||||
|
||||
val data: JSONObject =
|
||||
response.getJSONObject(i)
|
||||
|
||||
val histori = HistoriModel(
|
||||
|
||||
createdAt =
|
||||
data.getString("created_at"),
|
||||
|
||||
jamPemupukan =
|
||||
data.getString("jam_pemupukan"),
|
||||
|
||||
mode =
|
||||
data.getString("mode"),
|
||||
|
||||
durasiPompa =
|
||||
data.getString("durasi_pompa"),
|
||||
|
||||
intervalHari =
|
||||
data.getString("interval_hari"),
|
||||
|
||||
statusTanah =
|
||||
data.getString("status_tanah")
|
||||
)
|
||||
|
||||
historiList.add(histori)
|
||||
}
|
||||
|
||||
historiAdapter.notifyDataSetChanged()
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
Toast.makeText(
|
||||
this,
|
||||
"Gagal mengambil histori",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
)
|
||||
|
||||
Volley.newRequestQueue(this)
|
||||
.add(request)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
package com.example.projekta
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.cardview.widget.CardView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
|
||||
class HistoriAdapter(
|
||||
|
||||
private val context: Context,
|
||||
private val historiList: ArrayList<HistoriModel>
|
||||
|
||||
) : RecyclerView.Adapter<HistoriAdapter.ViewHolder>() {
|
||||
|
||||
class ViewHolder(itemView: View)
|
||||
: RecyclerView.ViewHolder(itemView) {
|
||||
|
||||
val tvTanggal: TextView =
|
||||
itemView.findViewById(R.id.tvTanggal)
|
||||
|
||||
val tvJam: TextView =
|
||||
itemView.findViewById(R.id.tvJam)
|
||||
|
||||
val tvMode: TextView =
|
||||
itemView.findViewById(R.id.tvMode)
|
||||
|
||||
val tvDurasi: TextView =
|
||||
itemView.findViewById(R.id.tvDurasi)
|
||||
|
||||
val tvInterval: TextView =
|
||||
itemView.findViewById(R.id.tvInterval)
|
||||
|
||||
val tvStatusTanah: TextView =
|
||||
itemView.findViewById(R.id.tvStatusTanah)
|
||||
|
||||
val cardHistori: CardView =
|
||||
itemView.findViewById(R.id.cardHistori)
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(
|
||||
parent: ViewGroup,
|
||||
viewType: Int
|
||||
): ViewHolder {
|
||||
|
||||
val view = LayoutInflater.from(context)
|
||||
.inflate(
|
||||
R.layout.item_histori,
|
||||
parent,
|
||||
false
|
||||
)
|
||||
|
||||
return ViewHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(
|
||||
holder: ViewHolder,
|
||||
position: Int
|
||||
) {
|
||||
|
||||
val histori =
|
||||
historiList[position]
|
||||
|
||||
// TANGGAL
|
||||
holder.tvTanggal.text =
|
||||
histori.createdAt
|
||||
|
||||
// JAM
|
||||
holder.tvJam.text =
|
||||
histori.jamPemupukan
|
||||
|
||||
// MODE
|
||||
holder.tvMode.text =
|
||||
"• Mode: ${histori.mode}"
|
||||
|
||||
// DURASI
|
||||
holder.tvDurasi.text =
|
||||
"• Durasi: ${histori.durasiPompa}"
|
||||
|
||||
// INTERVAL
|
||||
holder.tvInterval.text =
|
||||
"• Interval: ${histori.intervalHari}"
|
||||
|
||||
// STATUS TANAH
|
||||
holder.tvStatusTanah.text =
|
||||
"🔥 Status Tanah: ${histori.statusTanah}"
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
|
||||
return historiList.size
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package com.example.projekta
|
||||
|
||||
data class HistoriModel(
|
||||
|
||||
val createdAt: String = "",
|
||||
|
||||
val jamPemupukan: String = "",
|
||||
|
||||
val mode: String = "",
|
||||
|
||||
val durasiPompa: String = "",
|
||||
|
||||
val intervalHari: String = "",
|
||||
|
||||
val statusTanah: String = ""
|
||||
|
||||
)
|
||||
|
|
@ -0,0 +1,216 @@
|
|||
package com.example.projekta
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.text.InputType
|
||||
import android.util.Patterns
|
||||
import android.view.MotionEvent
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.android.volley.Request
|
||||
import com.android.volley.toolbox.StringRequest
|
||||
import com.android.volley.toolbox.Volley
|
||||
import com.example.projekta.databinding.ActivityLoginBinding
|
||||
import org.json.JSONObject
|
||||
|
||||
class LoginActivity : AppCompatActivity() {
|
||||
|
||||
private lateinit var binding: ActivityLoginBinding
|
||||
private var isPasswordVisible = false
|
||||
|
||||
private val url = "http://192.168.43.191/projekta/login.php"
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
binding = ActivityLoginBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
// =========================
|
||||
// CEK SESSION LOGIN
|
||||
// =========================
|
||||
val sharedPref = getSharedPreferences("LOGIN", MODE_PRIVATE)
|
||||
|
||||
if (sharedPref.getBoolean("isLogin", false)) {
|
||||
startActivity(Intent(this, MenuActivity::class.java))
|
||||
finish()
|
||||
}
|
||||
|
||||
binding.btnBack.setOnClickListener {
|
||||
finish()
|
||||
}
|
||||
|
||||
setupPasswordToggle()
|
||||
|
||||
binding.btnLogin.setOnClickListener {
|
||||
|
||||
val email = binding.etEmail.text.toString().trim()
|
||||
val password = binding.etPassword.text.toString()
|
||||
|
||||
// VALIDASI EMAIL
|
||||
if (email.isEmpty() || !Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
|
||||
binding.etEmail.error = "Email tidak valid"
|
||||
return@setOnClickListener
|
||||
}
|
||||
|
||||
// VALIDASI PASSWORD
|
||||
if (password.length < 6) {
|
||||
binding.etPassword.error = "Password minimal 6 karakter"
|
||||
return@setOnClickListener
|
||||
}
|
||||
|
||||
loginUser(email, password)
|
||||
}
|
||||
|
||||
binding.txtRegister.setOnClickListener {
|
||||
startActivity(Intent(this, RegisterActivity::class.java))
|
||||
}
|
||||
}
|
||||
|
||||
// =========================
|
||||
// LOGIN USER
|
||||
// =========================
|
||||
private fun loginUser(email: String, password: String) {
|
||||
|
||||
val request = object : StringRequest(
|
||||
Request.Method.POST,
|
||||
url,
|
||||
|
||||
{ response ->
|
||||
|
||||
try {
|
||||
|
||||
val json = JSONObject(response)
|
||||
|
||||
if (json.getString("status") == "success") {
|
||||
|
||||
val idUser = json.getString("id")
|
||||
val nama = json.getString("nama")
|
||||
val emailUser = json.getString("email")
|
||||
|
||||
// SIMPAN SESSION LOGIN
|
||||
val sharedPref = getSharedPreferences("LOGIN", MODE_PRIVATE)
|
||||
|
||||
sharedPref.edit()
|
||||
.putBoolean("isLogin", true)
|
||||
.putString("id_user", idUser)
|
||||
.putString("nama", nama)
|
||||
.putString("email", emailUser)
|
||||
.apply()
|
||||
|
||||
Toast.makeText(
|
||||
this,
|
||||
"Login berhasil",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
|
||||
startActivity(Intent(this, MenuActivity::class.java))
|
||||
finish()
|
||||
|
||||
} else {
|
||||
|
||||
Toast.makeText(
|
||||
this,
|
||||
"Email / Password salah",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
|
||||
}
|
||||
|
||||
} catch (e: Exception) {
|
||||
|
||||
Toast.makeText(
|
||||
this,
|
||||
"Response server tidak valid",
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
Toast.makeText(
|
||||
this,
|
||||
"Gagal koneksi server",
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
|
||||
}
|
||||
|
||||
) {
|
||||
|
||||
override fun getParams(): MutableMap<String, String> {
|
||||
|
||||
val params = HashMap<String, String>()
|
||||
|
||||
params["email"] = email
|
||||
params["password"] = password
|
||||
|
||||
return params
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Volley.newRequestQueue(this).add(request)
|
||||
|
||||
}
|
||||
|
||||
// =========================
|
||||
// PASSWORD TOGGLE
|
||||
// =========================
|
||||
private fun setupPasswordToggle() {
|
||||
|
||||
binding.etPassword.setOnTouchListener { _, event ->
|
||||
|
||||
val drawableEnd = 2
|
||||
|
||||
if (event.action == MotionEvent.ACTION_UP) {
|
||||
|
||||
val drawable = binding.etPassword.compoundDrawables[drawableEnd]
|
||||
|
||||
if (drawable != null &&
|
||||
event.rawX >= (binding.etPassword.right - drawable.bounds.width())
|
||||
) {
|
||||
|
||||
isPasswordVisible = !isPasswordVisible
|
||||
|
||||
if (isPasswordVisible) {
|
||||
|
||||
binding.etPassword.inputType =
|
||||
InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
|
||||
|
||||
binding.etPassword.setCompoundDrawablesWithIntrinsicBounds(
|
||||
R.drawable.ic_lock,
|
||||
0,
|
||||
R.drawable.ic_eye_off,
|
||||
0
|
||||
)
|
||||
|
||||
} else {
|
||||
|
||||
binding.etPassword.inputType =
|
||||
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
|
||||
|
||||
binding.etPassword.setCompoundDrawablesWithIntrinsicBounds(
|
||||
R.drawable.ic_lock,
|
||||
0,
|
||||
R.drawable.ic_eye,
|
||||
0
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
binding.etPassword.setSelection(binding.etPassword.text.length)
|
||||
|
||||
return@setOnTouchListener true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package com.example.projekta
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.example.projekta.databinding.ActivityMainBinding
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
|
||||
private lateinit var binding: ActivityMainBinding
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
binding = ActivityMainBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
// tes klik layar
|
||||
binding.root.setOnClickListener {
|
||||
println("App jalan 🔥")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
package com.example.projekta
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.BitmapFactory
|
||||
import android.os.Bundle
|
||||
import android.util.Base64
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.GravityCompat
|
||||
import com.example.projekta.databinding.ActivityMenuBinding
|
||||
|
||||
class MenuActivity : AppCompatActivity() {
|
||||
|
||||
private lateinit var binding: ActivityMenuBinding
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
binding = ActivityMenuBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
loadUserSidebar()
|
||||
|
||||
// Buka Drawer
|
||||
binding.btnMenu.setOnClickListener {
|
||||
binding.drawerLayout.openDrawer(GravityCompat.START)
|
||||
}
|
||||
|
||||
// Menu Profile
|
||||
binding.menuProfile.setOnClickListener {
|
||||
startActivity(Intent(this, ProfileActivity::class.java))
|
||||
binding.drawerLayout.closeDrawer(GravityCompat.START)
|
||||
}
|
||||
|
||||
// Menu Logout
|
||||
binding.menuLogout.setOnClickListener {
|
||||
|
||||
getSharedPreferences("LOGIN", MODE_PRIVATE).edit().clear().apply()
|
||||
getSharedPreferences("USER_DATA", MODE_PRIVATE).edit().clear().apply()
|
||||
|
||||
val intent = Intent(this, LoginActivity::class.java)
|
||||
intent.flags =
|
||||
Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||
|
||||
startActivity(intent)
|
||||
finish()
|
||||
}
|
||||
|
||||
// Menu Pemupukan
|
||||
binding.menuPemupukan.setOnClickListener {
|
||||
startActivity(Intent(this, PemupukanActivity::class.java))
|
||||
}
|
||||
|
||||
// Menu Panel Surya
|
||||
binding.menuPanelSurya.setOnClickListener {
|
||||
startActivity(Intent(this, PanelSuryaActivity::class.java))
|
||||
}
|
||||
|
||||
// Menu Panduan
|
||||
binding.menuPanduan.setOnClickListener {
|
||||
startActivity(Intent(this, PanduanActivity::class.java))
|
||||
}
|
||||
|
||||
// Menu Tentang
|
||||
binding.menuTentang.setOnClickListener {
|
||||
startActivity(Intent(this, TentangActivity::class.java))
|
||||
}
|
||||
|
||||
// Menu Histori
|
||||
binding.menuHistori.setOnClickListener {
|
||||
startActivity(Intent(this, HistoriActivity::class.java))
|
||||
}
|
||||
|
||||
// Tombol Back
|
||||
onBackPressedDispatcher.addCallback(
|
||||
this,
|
||||
object : OnBackPressedCallback(true) {
|
||||
override fun handleOnBackPressed() {
|
||||
|
||||
if (binding.drawerLayout.isDrawerOpen(GravityCompat.START)) {
|
||||
binding.drawerLayout.closeDrawer(GravityCompat.START)
|
||||
} else {
|
||||
finishAffinity()
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// Refresh data sidebar setiap Activity kembali dibuka
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
loadUserSidebar()
|
||||
}
|
||||
|
||||
// Memuat nama dan foto profil pada sidebar
|
||||
private fun loadUserSidebar() {
|
||||
|
||||
val sharedPref = getSharedPreferences("USER_DATA", Context.MODE_PRIVATE)
|
||||
|
||||
val nama = sharedPref.getString("nama", "Nama Pengguna")
|
||||
val foto = sharedPref.getString("foto", "")
|
||||
|
||||
binding.txtSidebarName.text = nama
|
||||
|
||||
if (!foto.isNullOrEmpty()) {
|
||||
|
||||
try {
|
||||
|
||||
val cleanBase64 = foto
|
||||
.replace("\n", "")
|
||||
.replace("\r", "")
|
||||
.replace(" ", "")
|
||||
|
||||
val imageBytes = Base64.decode(cleanBase64, Base64.DEFAULT)
|
||||
|
||||
val bitmap = BitmapFactory.decodeByteArray(
|
||||
imageBytes,
|
||||
0,
|
||||
imageBytes.size
|
||||
)
|
||||
|
||||
binding.imgSidebarProfile.setImageBitmap(bitmap)
|
||||
|
||||
} catch (e: Exception) {
|
||||
|
||||
binding.imgSidebarProfile.setImageResource(R.drawable.profileman)
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
binding.imgSidebarProfile.setImageResource(R.drawable.profileman)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,389 @@
|
|||
package com.example.projekta
|
||||
|
||||
import android.app.TimePickerDialog
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.widget.Button
|
||||
import android.widget.EditText
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.cardview.widget.CardView
|
||||
import com.android.volley.Request
|
||||
import com.android.volley.toolbox.JsonObjectRequest
|
||||
import com.android.volley.toolbox.StringRequest
|
||||
import com.android.volley.toolbox.Volley
|
||||
import java.util.Calendar
|
||||
import java.util.Locale
|
||||
|
||||
class MetodePemupukanActivity : AppCompatActivity() {
|
||||
|
||||
private lateinit var btnBack: ImageView
|
||||
|
||||
private lateinit var cardAuto: CardView
|
||||
private lateinit var cardManual: CardView
|
||||
|
||||
private lateinit var etInterval: EditText
|
||||
private lateinit var etDurasi: EditText
|
||||
|
||||
private lateinit var tvJam: TextView
|
||||
|
||||
private lateinit var btnPilihJam: Button
|
||||
private lateinit var btnSimpan: Button
|
||||
|
||||
private lateinit var btnPompaManual: Button
|
||||
private lateinit var tvStatusManual: TextView
|
||||
|
||||
private var mode = "otomatis"
|
||||
private var isPompaOn = false
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_metode_pemupukan)
|
||||
|
||||
initView()
|
||||
setupListener()
|
||||
loadPengaturan()
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
|
||||
btnBack = findViewById(R.id.btnBack)
|
||||
|
||||
cardAuto = findViewById(R.id.cardAuto)
|
||||
cardManual = findViewById(R.id.cardManual)
|
||||
|
||||
etInterval = findViewById(R.id.etInterval)
|
||||
etDurasi = findViewById(R.id.etDurasi)
|
||||
|
||||
tvJam = findViewById(R.id.tvJam)
|
||||
|
||||
btnPilihJam = findViewById(R.id.btnPilihJam)
|
||||
btnSimpan = findViewById(R.id.btnSimpan)
|
||||
|
||||
btnPompaManual = findViewById(R.id.btnPompaManual)
|
||||
tvStatusManual = findViewById(R.id.tvStatusManual)
|
||||
}
|
||||
|
||||
private fun setupListener() {
|
||||
|
||||
btnBack.setOnClickListener {
|
||||
finish()
|
||||
}
|
||||
|
||||
cardAuto.setOnClickListener {
|
||||
setModeOtomatis()
|
||||
}
|
||||
|
||||
cardManual.setOnClickListener {
|
||||
setModeManual()
|
||||
}
|
||||
|
||||
btnPilihJam.setOnClickListener {
|
||||
|
||||
val calendar = Calendar.getInstance()
|
||||
|
||||
TimePickerDialog(
|
||||
this,
|
||||
{ _, hour, minute ->
|
||||
|
||||
tvJam.text = String.format(
|
||||
Locale.getDefault(),
|
||||
"%02d:%02d:00",
|
||||
hour,
|
||||
minute
|
||||
)
|
||||
},
|
||||
calendar.get(Calendar.HOUR_OF_DAY),
|
||||
calendar.get(Calendar.MINUTE),
|
||||
true
|
||||
).show()
|
||||
}
|
||||
|
||||
btnPompaManual.setOnClickListener {
|
||||
togglePompaManual()
|
||||
}
|
||||
|
||||
btnSimpan.setOnClickListener {
|
||||
simpanPengaturan()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setModeOtomatis() {
|
||||
|
||||
mode = "otomatis"
|
||||
|
||||
etInterval.isEnabled = true
|
||||
etDurasi.isEnabled = true
|
||||
btnPilihJam.isEnabled = true
|
||||
|
||||
cardAuto.cardElevation = 12f
|
||||
cardManual.cardElevation = 4f
|
||||
}
|
||||
|
||||
private fun setModeManual() {
|
||||
|
||||
mode = "manual"
|
||||
|
||||
etInterval.isEnabled = false
|
||||
etDurasi.isEnabled = false
|
||||
btnPilihJam.isEnabled = false
|
||||
|
||||
cardAuto.cardElevation = 4f
|
||||
cardManual.cardElevation = 12f
|
||||
}
|
||||
|
||||
private fun togglePompaManual() {
|
||||
|
||||
if (mode != "manual") {
|
||||
|
||||
Toast.makeText(
|
||||
this,
|
||||
"Pilih MODE MANUAL terlebih dahulu",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
isPompaOn = !isPompaOn
|
||||
|
||||
if (isPompaOn) {
|
||||
|
||||
tvStatusManual.text = "STATUS: ON"
|
||||
tvStatusManual.setTextColor(
|
||||
Color.parseColor("#2E7D32")
|
||||
)
|
||||
|
||||
btnPompaManual.text = "MATIKAN POMPA"
|
||||
btnPompaManual.setBackgroundColor(
|
||||
Color.parseColor("#D32F2F")
|
||||
)
|
||||
|
||||
simpanHistori("manual", "ON")
|
||||
|
||||
} else {
|
||||
|
||||
tvStatusManual.text = "STATUS: OFF"
|
||||
tvStatusManual.setTextColor(
|
||||
Color.parseColor("#D32F2F")
|
||||
)
|
||||
|
||||
btnPompaManual.text = "NYALAKAN POMPA"
|
||||
btnPompaManual.setBackgroundColor(
|
||||
Color.parseColor("#2E7D32")
|
||||
)
|
||||
|
||||
simpanHistori("manual", "OFF")
|
||||
}
|
||||
}
|
||||
|
||||
private fun simpanPengaturan() {
|
||||
|
||||
if (mode == "otomatis") {
|
||||
|
||||
if (etInterval.text.toString().trim().isEmpty()) {
|
||||
etInterval.error = "Isi interval hari"
|
||||
return
|
||||
}
|
||||
|
||||
if (etDurasi.text.toString().trim().isEmpty()) {
|
||||
etDurasi.error = "Isi durasi detik"
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
val url =
|
||||
"http://192.168.43.191/projekta/save_pengaturan.php"
|
||||
|
||||
val request = object : StringRequest(
|
||||
Method.POST,
|
||||
url,
|
||||
|
||||
{ response ->
|
||||
|
||||
Toast.makeText(
|
||||
this,
|
||||
response,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
Toast.makeText(
|
||||
this,
|
||||
"Gagal koneksi server",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
) {
|
||||
|
||||
override fun getParams(): MutableMap<String, String> {
|
||||
|
||||
val params = HashMap<String, String>()
|
||||
|
||||
params["mode"] = mode
|
||||
|
||||
if (mode == "otomatis") {
|
||||
|
||||
params["interval_hari"] =
|
||||
etInterval.text.toString().trim()
|
||||
|
||||
params["durasi"] =
|
||||
etDurasi.text.toString().trim()
|
||||
|
||||
params["jam"] =
|
||||
tvJam.text.toString()
|
||||
|
||||
} else {
|
||||
|
||||
params["status_manual"] =
|
||||
if (isPompaOn) "ON" else "OFF"
|
||||
}
|
||||
|
||||
return params
|
||||
}
|
||||
}
|
||||
|
||||
Volley.newRequestQueue(this)
|
||||
.add(request)
|
||||
}
|
||||
|
||||
private fun simpanHistori(
|
||||
modePemupukan: String,
|
||||
statusPompa: String
|
||||
) {
|
||||
|
||||
val url =
|
||||
"http://192.168.43.191/projekta/insert_histori.php"
|
||||
|
||||
val request = object : StringRequest(
|
||||
Request.Method.POST,
|
||||
url,
|
||||
{},
|
||||
{}
|
||||
) {
|
||||
|
||||
override fun getParams(): MutableMap<String, String> {
|
||||
|
||||
val params = HashMap<String, String>()
|
||||
|
||||
params["mode"] = modePemupukan
|
||||
|
||||
params["status"] = statusPompa
|
||||
|
||||
return params
|
||||
}
|
||||
}
|
||||
|
||||
Volley.newRequestQueue(this)
|
||||
.add(request)
|
||||
|
||||
}
|
||||
|
||||
private fun loadPengaturan() {
|
||||
|
||||
val url =
|
||||
"http://192.168.43.191/projekta/get_pengaturan.php"
|
||||
|
||||
val request = JsonObjectRequest(
|
||||
Request.Method.GET,
|
||||
url,
|
||||
null,
|
||||
|
||||
{ response ->
|
||||
|
||||
try {
|
||||
|
||||
if (response.getBoolean("success")) {
|
||||
|
||||
mode =
|
||||
response.getString("mode")
|
||||
|
||||
val interval =
|
||||
response.getInt("interval_hari")
|
||||
|
||||
val durasi =
|
||||
response.getInt("durasi")
|
||||
|
||||
val jam =
|
||||
response.getString("jam")
|
||||
|
||||
val statusManual =
|
||||
response.getString("status_manual")
|
||||
|
||||
tvJam.text = jam
|
||||
|
||||
etInterval.setText(
|
||||
interval.toString()
|
||||
)
|
||||
|
||||
etDurasi.setText(
|
||||
durasi.toString()
|
||||
)
|
||||
|
||||
if (mode == "manual") {
|
||||
|
||||
setModeManual()
|
||||
|
||||
if (statusManual == "ON") {
|
||||
|
||||
isPompaOn = true
|
||||
|
||||
tvStatusManual.text =
|
||||
"STATUS: ON"
|
||||
|
||||
tvStatusManual.setTextColor(
|
||||
Color.parseColor("#2E7D32")
|
||||
)
|
||||
|
||||
btnPompaManual.text =
|
||||
"MATIKAN POMPA"
|
||||
|
||||
btnPompaManual.setBackgroundColor(
|
||||
Color.parseColor("#D32F2F")
|
||||
)
|
||||
|
||||
} else {
|
||||
|
||||
isPompaOn = false
|
||||
|
||||
tvStatusManual.text =
|
||||
"STATUS: OFF"
|
||||
|
||||
tvStatusManual.setTextColor(
|
||||
Color.parseColor("#D32F2F")
|
||||
)
|
||||
|
||||
btnPompaManual.text =
|
||||
"NYALAKAN POMPA"
|
||||
|
||||
btnPompaManual.setBackgroundColor(
|
||||
Color.parseColor("#2E7D32")
|
||||
)
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
setModeOtomatis()
|
||||
}
|
||||
}
|
||||
|
||||
} catch (e: Exception) {
|
||||
|
||||
setModeOtomatis()
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
setModeOtomatis()
|
||||
}
|
||||
)
|
||||
|
||||
Volley.newRequestQueue(this)
|
||||
.add(request)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package com.example.projekta
|
||||
|
||||
import android.os.Bundle
|
||||
import android.widget.ImageView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
|
||||
class PanduanActivity : AppCompatActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_panduan)
|
||||
|
||||
val btnBack = findViewById<ImageView>(R.id.btnBack)
|
||||
btnBack.setOnClickListener {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
package com.example.projekta
|
||||
|
||||
import android.os.Bundle
|
||||
import android.widget.Button
|
||||
import android.widget.ImageView
|
||||
import android.widget.ProgressBar
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.android.volley.Request
|
||||
import com.android.volley.toolbox.JsonObjectRequest
|
||||
import com.android.volley.toolbox.Volley
|
||||
|
||||
class PanelSuryaActivity : AppCompatActivity() {
|
||||
|
||||
private lateinit var tvStatusPanel: TextView
|
||||
private lateinit var tvDaya: TextView
|
||||
private lateinit var tvStatusDaya: TextView
|
||||
private lateinit var tvSumberEnergi: TextView
|
||||
private lateinit var tvStatusSistem: TextView
|
||||
private lateinit var tvStatusPompa: TextView
|
||||
private lateinit var tvUpdate: TextView
|
||||
private lateinit var progressDaya: ProgressBar
|
||||
private lateinit var btnRefresh: Button
|
||||
|
||||
private val url =
|
||||
"http://192.168.43.191/projekta/get_panel_surya.php"
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_panel_surya)
|
||||
|
||||
findViewById<ImageView>(R.id.btnBack).setOnClickListener {
|
||||
finish()
|
||||
}
|
||||
|
||||
tvStatusPanel = findViewById(R.id.tvStatusPanel)
|
||||
tvDaya = findViewById(R.id.tvDaya)
|
||||
tvStatusDaya = findViewById(R.id.tvStatusDaya)
|
||||
tvSumberEnergi = findViewById(R.id.tvSumberEnergi)
|
||||
tvStatusSistem = findViewById(R.id.tvStatusSistem)
|
||||
tvStatusPompa = findViewById(R.id.tvStatusPompa)
|
||||
tvUpdate = findViewById(R.id.tvUpdate)
|
||||
progressDaya = findViewById(R.id.progressDaya)
|
||||
btnRefresh = findViewById(R.id.btnRefresh)
|
||||
|
||||
ambilDataPanelSurya()
|
||||
|
||||
btnRefresh.setOnClickListener {
|
||||
ambilDataPanelSurya()
|
||||
}
|
||||
}
|
||||
|
||||
private fun ambilDataPanelSurya() {
|
||||
|
||||
val request = JsonObjectRequest(
|
||||
Request.Method.GET,
|
||||
url,
|
||||
null,
|
||||
|
||||
{ response ->
|
||||
|
||||
val statusPanel =
|
||||
response.optString("status_panel", "-")
|
||||
|
||||
val daya =
|
||||
response.optInt("daya", 0)
|
||||
|
||||
val statusDaya =
|
||||
response.optString("status_daya", "-")
|
||||
|
||||
val sumberEnergi =
|
||||
response.optString("sumber_energi", "-")
|
||||
|
||||
val statusSistem =
|
||||
response.optString("status_sistem", "-")
|
||||
|
||||
val statusPompa =
|
||||
response.optString("status_pompa", "-")
|
||||
|
||||
val waktuUpdate =
|
||||
response.optString("waktu_update", "-")
|
||||
|
||||
tvStatusPanel.text = "🟢 $statusPanel"
|
||||
|
||||
tvDaya.text = "$daya%"
|
||||
|
||||
progressDaya.progress = daya
|
||||
|
||||
when {
|
||||
daya >= 80 -> {
|
||||
tvStatusDaya.text = "🟢 $statusDaya"
|
||||
}
|
||||
|
||||
daya >= 40 -> {
|
||||
tvStatusDaya.text = "🟡 $statusDaya"
|
||||
}
|
||||
|
||||
else -> {
|
||||
tvStatusDaya.text = "🔴 $statusDaya"
|
||||
}
|
||||
}
|
||||
|
||||
tvSumberEnergi.text =
|
||||
"🔆 Sumber Energi : $sumberEnergi"
|
||||
|
||||
tvStatusSistem.text =
|
||||
"⚙️ Status Sistem : $statusSistem"
|
||||
|
||||
tvStatusPompa.text =
|
||||
"🚰 Status Pompa : $statusPompa"
|
||||
|
||||
tvUpdate.text =
|
||||
"🕒 Update Terakhir : $waktuUpdate"
|
||||
|
||||
},
|
||||
|
||||
{ error ->
|
||||
|
||||
tvStatusPanel.text = "❌ Gagal mengambil data"
|
||||
|
||||
tvDaya.text = "0%"
|
||||
|
||||
progressDaya.progress = 0
|
||||
|
||||
tvStatusDaya.text = "-"
|
||||
|
||||
tvSumberEnergi.text =
|
||||
"🔆 Sumber Energi : -"
|
||||
|
||||
tvStatusSistem.text =
|
||||
"⚙️ Status Sistem : -"
|
||||
|
||||
tvStatusPompa.text =
|
||||
"🚰 Status Pompa : -"
|
||||
|
||||
tvUpdate.text =
|
||||
"🕒 Update Terakhir : -"
|
||||
|
||||
error.printStackTrace()
|
||||
}
|
||||
)
|
||||
|
||||
Volley.newRequestQueue(this).add(request)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,344 @@
|
|||
package com.example.projekta
|
||||
|
||||
import android.content.Intent
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.widget.Button
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.hivemq.client.mqtt.MqttClient
|
||||
import com.hivemq.client.mqtt.mqtt3.Mqtt3AsyncClient
|
||||
import org.json.JSONObject
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class PemupukanActivity : AppCompatActivity() {
|
||||
|
||||
private lateinit var tvSuhuUdara: TextView
|
||||
private lateinit var tvKelembapanUdara: TextView
|
||||
private lateinit var tvSuhuTanah: TextView
|
||||
private lateinit var tvKelembapanTanah: TextView
|
||||
private lateinit var tvStatusTanah: TextView
|
||||
private lateinit var tvStatusSistem: TextView
|
||||
private lateinit var tvStatusPompa: TextView
|
||||
|
||||
private lateinit var mqttClient: Mqtt3AsyncClient
|
||||
|
||||
private val mqttUser = "DeaBaasithian"
|
||||
private val mqttPassword = "Lekmamok123#"
|
||||
|
||||
private val topicSensor =
|
||||
"pemupukan/sensor"
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
setContentView(
|
||||
R.layout.activity_pemupukan
|
||||
)
|
||||
|
||||
val btnBack =
|
||||
findViewById<ImageView>(
|
||||
R.id.btnBack
|
||||
)
|
||||
|
||||
val btnMetode =
|
||||
findViewById<Button>(
|
||||
R.id.btnMetode
|
||||
)
|
||||
|
||||
tvSuhuUdara =
|
||||
findViewById(
|
||||
R.id.tvSuhuUdara
|
||||
)
|
||||
|
||||
tvKelembapanUdara =
|
||||
findViewById(
|
||||
R.id.tvKelembapanUdara
|
||||
)
|
||||
|
||||
tvSuhuTanah =
|
||||
findViewById(
|
||||
R.id.tvSuhuTanah
|
||||
)
|
||||
|
||||
tvKelembapanTanah =
|
||||
findViewById(
|
||||
R.id.tvKelembapanTanah
|
||||
)
|
||||
|
||||
tvStatusTanah =
|
||||
findViewById(
|
||||
R.id.tvStatusTanah
|
||||
)
|
||||
|
||||
tvStatusSistem =
|
||||
findViewById(
|
||||
R.id.tvStatusSistem
|
||||
)
|
||||
|
||||
tvStatusPompa =
|
||||
findViewById(
|
||||
R.id.tvStatusPompa
|
||||
)
|
||||
|
||||
btnBack.setOnClickListener {
|
||||
finish()
|
||||
}
|
||||
|
||||
btnMetode.setOnClickListener {
|
||||
startActivity(
|
||||
Intent(
|
||||
this,
|
||||
MetodePemupukanActivity::class.java
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
tampilDataKosong()
|
||||
|
||||
connectMQTT()
|
||||
}
|
||||
|
||||
private fun tampilDataKosong() {
|
||||
|
||||
tvSuhuTanah.text =
|
||||
"🌡️ Suhu Tanah: --"
|
||||
|
||||
tvKelembapanTanah.text =
|
||||
"🌱 Kelembapan Tanah: --"
|
||||
|
||||
tvSuhuUdara.text =
|
||||
"☀️ Suhu Udara: --"
|
||||
|
||||
tvKelembapanUdara.text =
|
||||
"💦 Kelembapan Udara: --"
|
||||
|
||||
tvStatusTanah.text =
|
||||
"🟢 Status Tanah: --"
|
||||
|
||||
tvStatusSistem.text =
|
||||
"⚙️ Menyambungkan..."
|
||||
|
||||
tvStatusPompa.text =
|
||||
"🚰 Status Pompa: --"
|
||||
}
|
||||
|
||||
private fun connectMQTT() {
|
||||
|
||||
mqttClient =
|
||||
MqttClient.builder()
|
||||
|
||||
.useMqttVersion3()
|
||||
|
||||
.identifier(
|
||||
"android_" +
|
||||
System.currentTimeMillis()
|
||||
)
|
||||
|
||||
.serverHost(
|
||||
"09c34b6317bd4610829ec8a206e9da43.s1.eu.hivemq.cloud"
|
||||
)
|
||||
|
||||
.serverPort(
|
||||
8883
|
||||
)
|
||||
|
||||
.sslWithDefaultConfig()
|
||||
|
||||
.buildAsync()
|
||||
|
||||
mqttClient.connectWith()
|
||||
|
||||
.simpleAuth()
|
||||
|
||||
.username(
|
||||
mqttUser
|
||||
)
|
||||
|
||||
.password(
|
||||
mqttPassword.toByteArray()
|
||||
)
|
||||
|
||||
.applySimpleAuth()
|
||||
|
||||
.send()
|
||||
|
||||
.whenComplete { _, error ->
|
||||
|
||||
runOnUiThread {
|
||||
|
||||
if (error == null) {
|
||||
|
||||
tvStatusSistem.text =
|
||||
"⚙️ MQTT Connected"
|
||||
|
||||
Log.d(
|
||||
"MQTT",
|
||||
"CONNECT OK"
|
||||
)
|
||||
|
||||
subscribeSensor()
|
||||
|
||||
} else {
|
||||
|
||||
tvStatusSistem.text =
|
||||
"⚙️ Connect Failed"
|
||||
|
||||
Log.e(
|
||||
"MQTT",
|
||||
error.stackTraceToString()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun subscribeSensor() {
|
||||
|
||||
mqttClient.subscribeWith()
|
||||
|
||||
.topicFilter(
|
||||
topicSensor
|
||||
)
|
||||
|
||||
.callback { publish ->
|
||||
|
||||
try {
|
||||
|
||||
val payload =
|
||||
String(
|
||||
publish.payloadAsBytes
|
||||
)
|
||||
|
||||
Log.d(
|
||||
"MQTT_DATA",
|
||||
payload
|
||||
)
|
||||
|
||||
val json =
|
||||
JSONObject(
|
||||
payload
|
||||
)
|
||||
|
||||
runOnUiThread {
|
||||
|
||||
tvSuhuTanah.text =
|
||||
"🌡️ Suhu Tanah: ${
|
||||
json.optDouble(
|
||||
"suhu_tanah",
|
||||
0.0
|
||||
).roundToInt()
|
||||
}°C"
|
||||
|
||||
tvKelembapanTanah.text =
|
||||
"🌱 Kelembapan Tanah: ${
|
||||
json.optInt(
|
||||
"kelembapan_tanah",
|
||||
0
|
||||
)
|
||||
}%"
|
||||
|
||||
tvSuhuUdara.text =
|
||||
"☀️ Suhu Udara: ${
|
||||
json.optDouble(
|
||||
"suhu_udara",
|
||||
0.0
|
||||
).roundToInt()
|
||||
}°C"
|
||||
|
||||
tvKelembapanUdara.text =
|
||||
"💦 Kelembapan Udara: ${
|
||||
json.optDouble(
|
||||
"kelembapan_udara",
|
||||
0.0
|
||||
).roundToInt()
|
||||
}%"
|
||||
|
||||
tvStatusTanah.text =
|
||||
"🟢 Status Tanah: ${
|
||||
json.optString(
|
||||
"status_tanah",
|
||||
"-"
|
||||
)
|
||||
}"
|
||||
|
||||
val statusPompa =
|
||||
json.optString(
|
||||
"status_pompa",
|
||||
"OFF"
|
||||
)
|
||||
|
||||
tvStatusPompa.text =
|
||||
"🚰 Status Pompa: $statusPompa"
|
||||
|
||||
if (
|
||||
statusPompa.equals(
|
||||
"ON",
|
||||
true
|
||||
)
|
||||
) {
|
||||
tvStatusPompa.setTextColor(
|
||||
Color.GREEN
|
||||
)
|
||||
} else {
|
||||
tvStatusPompa.setTextColor(
|
||||
Color.RED
|
||||
)
|
||||
}
|
||||
|
||||
tvStatusSistem.text =
|
||||
"⚙️ Data Realtime"
|
||||
}
|
||||
|
||||
} catch (e: Exception) {
|
||||
|
||||
Log.e(
|
||||
"JSON",
|
||||
e.stackTraceToString()
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.send()
|
||||
|
||||
.whenComplete { _, error ->
|
||||
|
||||
runOnUiThread {
|
||||
|
||||
if (error == null) {
|
||||
|
||||
Log.d(
|
||||
"MQTT",
|
||||
"SUBSCRIBE OK"
|
||||
)
|
||||
|
||||
} else {
|
||||
|
||||
tvStatusSistem.text =
|
||||
"⚙️ Subscribe Failed"
|
||||
|
||||
Log.e(
|
||||
"MQTT",
|
||||
error.stackTraceToString()
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
|
||||
super.onDestroy()
|
||||
|
||||
if (::mqttClient.isInitialized) {
|
||||
|
||||
mqttClient.disconnect()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,338 @@
|
|||
package com.example.projekta
|
||||
|
||||
import android.Manifest
|
||||
import android.app.AlertDialog
|
||||
import android.app.DatePickerDialog
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.os.Bundle
|
||||
import android.util.Base64
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.PermissionChecker
|
||||
import com.android.volley.toolbox.StringRequest
|
||||
import com.android.volley.toolbox.Volley
|
||||
import com.example.projekta.databinding.ActivityProfileBinding
|
||||
import org.json.JSONObject
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.util.Calendar
|
||||
|
||||
class ProfileActivity : AppCompatActivity() {
|
||||
|
||||
private lateinit var binding: ActivityProfileBinding
|
||||
private var bitmapImage: Bitmap? = null
|
||||
|
||||
// ===============================
|
||||
// PILIH FOTO GALERI
|
||||
// ===============================
|
||||
private val pickImage =
|
||||
registerForActivityResult(ActivityResultContracts.GetContent()) { uri ->
|
||||
|
||||
if (uri != null) {
|
||||
|
||||
val inputStream = contentResolver.openInputStream(uri)
|
||||
bitmapImage = BitmapFactory.decodeStream(inputStream)
|
||||
|
||||
binding.imgProfile.setImageBitmap(bitmapImage)
|
||||
}
|
||||
}
|
||||
|
||||
// ===============================
|
||||
// CAMERA
|
||||
// ===============================
|
||||
private val takePhoto =
|
||||
registerForActivityResult(ActivityResultContracts.TakePicturePreview()) { bitmap ->
|
||||
|
||||
if (bitmap != null) {
|
||||
bitmapImage = bitmap
|
||||
binding.imgProfile.setImageBitmap(bitmap)
|
||||
}
|
||||
}
|
||||
|
||||
// ===============================
|
||||
// PERMISSION CAMERA
|
||||
// ===============================
|
||||
private val requestCameraPermission =
|
||||
registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted ->
|
||||
|
||||
if (granted) {
|
||||
takePhoto.launch(null)
|
||||
} else {
|
||||
Toast.makeText(this, "Izin kamera ditolak", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
binding = ActivityProfileBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
binding.btnBack.setOnClickListener {
|
||||
finish()
|
||||
}
|
||||
|
||||
loadProfile()
|
||||
|
||||
binding.imgProfile.setOnClickListener {
|
||||
showImagePickerDialog()
|
||||
}
|
||||
|
||||
binding.etTanggal.setOnClickListener {
|
||||
showDatePicker()
|
||||
}
|
||||
|
||||
binding.btnUpdate.setOnClickListener {
|
||||
updateProfile()
|
||||
}
|
||||
}
|
||||
|
||||
// ===============================
|
||||
// LOAD PROFILE
|
||||
// ===============================
|
||||
private fun loadProfile() {
|
||||
|
||||
val url = "http://192.168.43.191/projekta/profile.php"
|
||||
|
||||
val request = object : StringRequest(
|
||||
Method.POST,
|
||||
url,
|
||||
{ response ->
|
||||
|
||||
try {
|
||||
|
||||
val json = JSONObject(response)
|
||||
|
||||
val nama = json.optString("nama")
|
||||
val email = json.optString("email")
|
||||
val phone = json.optString("phone")
|
||||
val tanggal = json.optString("tanggal")
|
||||
val foto = json.optString("foto").trim()
|
||||
|
||||
binding.etNama.setText(nama)
|
||||
binding.etEmail.setText(email)
|
||||
binding.etPhone.setText(phone)
|
||||
binding.etTanggal.setText(tanggal)
|
||||
|
||||
binding.txtName.text = nama
|
||||
binding.txtEmail.text = email
|
||||
|
||||
// FOTO
|
||||
if (foto.isNotEmpty()) {
|
||||
|
||||
val decoded = Base64.decode(foto, Base64.DEFAULT)
|
||||
|
||||
val bitmap = BitmapFactory.decodeByteArray(
|
||||
decoded,
|
||||
0,
|
||||
decoded.size
|
||||
)
|
||||
|
||||
if (bitmap != null) {
|
||||
binding.imgProfile.setImageBitmap(bitmap)
|
||||
}
|
||||
}
|
||||
|
||||
} catch (e: Exception) {
|
||||
Toast.makeText(this, "Format data error", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
},
|
||||
{
|
||||
Toast.makeText(this, "Gagal koneksi server", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
) {
|
||||
|
||||
override fun getParams(): MutableMap<String, String> {
|
||||
|
||||
val params = HashMap<String, String>()
|
||||
|
||||
val email = getSharedPreferences(
|
||||
"LOGIN",
|
||||
Context.MODE_PRIVATE
|
||||
).getString("email", "")
|
||||
|
||||
params["email"] = email ?: ""
|
||||
|
||||
return params
|
||||
}
|
||||
}
|
||||
|
||||
Volley.newRequestQueue(this).add(request)
|
||||
}
|
||||
|
||||
// ===============================
|
||||
// UPDATE PROFILE
|
||||
// ===============================
|
||||
private fun updateProfile() {
|
||||
|
||||
val url = "http://192.168.43.191/projekta/update_profile.php"
|
||||
|
||||
val request = object : StringRequest(
|
||||
Method.POST,
|
||||
url,
|
||||
{ response ->
|
||||
|
||||
if (response.contains("success")) {
|
||||
|
||||
val namaBaru = binding.etNama.text.toString().trim()
|
||||
|
||||
val pref = getSharedPreferences(
|
||||
"USER_DATA",
|
||||
Context.MODE_PRIVATE
|
||||
)
|
||||
|
||||
val editor = pref.edit()
|
||||
|
||||
editor.putString("nama", namaBaru)
|
||||
|
||||
// simpan foto utk sidebar
|
||||
if (bitmapImage != null) {
|
||||
|
||||
val baos = ByteArrayOutputStream()
|
||||
|
||||
bitmapImage!!.compress(
|
||||
Bitmap.CompressFormat.JPEG,
|
||||
80,
|
||||
baos
|
||||
)
|
||||
|
||||
val base64Foto = Base64.encodeToString(
|
||||
baos.toByteArray(),
|
||||
Base64.NO_WRAP
|
||||
)
|
||||
|
||||
editor.putString("foto", base64Foto)
|
||||
}
|
||||
|
||||
editor.apply()
|
||||
|
||||
binding.txtName.text = namaBaru
|
||||
|
||||
Toast.makeText(
|
||||
this,
|
||||
"Profil berhasil diperbarui",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
|
||||
} else {
|
||||
|
||||
Toast.makeText(
|
||||
this,
|
||||
"Gagal update",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
|
||||
},
|
||||
{
|
||||
Toast.makeText(this, "Error server", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
) {
|
||||
|
||||
override fun getParams(): MutableMap<String, String> {
|
||||
|
||||
val params = HashMap<String, String>()
|
||||
|
||||
val email = getSharedPreferences(
|
||||
"LOGIN",
|
||||
Context.MODE_PRIVATE
|
||||
).getString("email", "")
|
||||
|
||||
params["email"] = email ?: ""
|
||||
params["nama"] = binding.etNama.text.toString().trim()
|
||||
params["phone"] = binding.etPhone.text.toString().trim()
|
||||
params["tanggal"] = binding.etTanggal.text.toString().trim()
|
||||
|
||||
if (bitmapImage != null) {
|
||||
|
||||
val baos = ByteArrayOutputStream()
|
||||
|
||||
bitmapImage!!.compress(
|
||||
Bitmap.CompressFormat.JPEG,
|
||||
80,
|
||||
baos
|
||||
)
|
||||
|
||||
params["foto"] = Base64.encodeToString(
|
||||
baos.toByteArray(),
|
||||
Base64.NO_WRAP
|
||||
)
|
||||
|
||||
} else {
|
||||
params["foto"] = ""
|
||||
}
|
||||
|
||||
return params
|
||||
}
|
||||
}
|
||||
|
||||
Volley.newRequestQueue(this).add(request)
|
||||
}
|
||||
|
||||
// ===============================
|
||||
// DATE PICKER
|
||||
// ===============================
|
||||
private fun showDatePicker() {
|
||||
|
||||
val c = Calendar.getInstance()
|
||||
|
||||
DatePickerDialog(
|
||||
this,
|
||||
{ _, y, m, d ->
|
||||
|
||||
binding.etTanggal.setText(
|
||||
"$d/${m + 1}/$y"
|
||||
)
|
||||
|
||||
},
|
||||
c.get(Calendar.YEAR),
|
||||
c.get(Calendar.MONTH),
|
||||
c.get(Calendar.DAY_OF_MONTH)
|
||||
).show()
|
||||
}
|
||||
|
||||
// ===============================
|
||||
// PILIH FOTO
|
||||
// ===============================
|
||||
private fun showImagePickerDialog() {
|
||||
|
||||
val pilihan = arrayOf("Galeri", "Kamera")
|
||||
|
||||
AlertDialog.Builder(this)
|
||||
.setTitle("Pilih Foto")
|
||||
.setItems(pilihan) { _, which ->
|
||||
|
||||
when (which) {
|
||||
0 -> pickImage.launch("image/*")
|
||||
1 -> openCamera()
|
||||
}
|
||||
|
||||
}
|
||||
.show()
|
||||
}
|
||||
|
||||
// ===============================
|
||||
// OPEN CAMERA
|
||||
// ===============================
|
||||
private fun openCamera() {
|
||||
|
||||
if (
|
||||
ContextCompat.checkSelfPermission(
|
||||
this,
|
||||
Manifest.permission.CAMERA
|
||||
) == PermissionChecker.PERMISSION_GRANTED
|
||||
) {
|
||||
takePhoto.launch(null)
|
||||
} else {
|
||||
requestCameraPermission.launch(
|
||||
Manifest.permission.CAMERA
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,200 @@
|
|||
package com.example.projekta
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.text.InputType
|
||||
import android.util.Patterns
|
||||
import android.view.MotionEvent
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.android.volley.Request
|
||||
import com.android.volley.toolbox.StringRequest
|
||||
import com.android.volley.toolbox.Volley
|
||||
import com.example.projekta.databinding.ActivityRegisterBinding
|
||||
|
||||
class RegisterActivity : AppCompatActivity() {
|
||||
|
||||
private lateinit var binding: ActivityRegisterBinding
|
||||
|
||||
private var isPasswordVisible = false
|
||||
private var isConfirmPasswordVisible = false
|
||||
|
||||
private val url = "http://192.168.43.191/projekta/register.php"
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
binding = ActivityRegisterBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
binding.btnBack.setOnClickListener {
|
||||
finish()
|
||||
}
|
||||
|
||||
setupPasswordToggle()
|
||||
|
||||
binding.btnRegister.setOnClickListener {
|
||||
|
||||
val name = binding.etName.text.toString().trim()
|
||||
val email = binding.etEmail.text.toString().trim()
|
||||
val password = binding.etPassword.text.toString()
|
||||
val confirmPassword = binding.etConfirmPassword.text.toString()
|
||||
|
||||
// VALIDASI
|
||||
if (name.isEmpty()) {
|
||||
binding.etName.error = "Nama wajib diisi"
|
||||
return@setOnClickListener
|
||||
}
|
||||
|
||||
if (email.isEmpty() || !Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
|
||||
binding.etEmail.error = "Email tidak valid"
|
||||
return@setOnClickListener
|
||||
}
|
||||
|
||||
if (password.length < 6) {
|
||||
binding.etPassword.error = "Password minimal 6 karakter"
|
||||
return@setOnClickListener
|
||||
}
|
||||
|
||||
if (password != confirmPassword) {
|
||||
binding.etConfirmPassword.error = "Password tidak sama"
|
||||
return@setOnClickListener
|
||||
}
|
||||
|
||||
registerUser(name, email, password)
|
||||
}
|
||||
|
||||
binding.txtLogin.setOnClickListener {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
private fun registerUser(nama: String, email: String, password: String) {
|
||||
|
||||
val request = object : StringRequest(
|
||||
Request.Method.POST,
|
||||
url,
|
||||
{ response ->
|
||||
|
||||
if (response.trim() == "success") {
|
||||
|
||||
Toast.makeText(this, "Register berhasil", Toast.LENGTH_SHORT).show()
|
||||
|
||||
startActivity(Intent(this, LoginActivity::class.java))
|
||||
finish()
|
||||
|
||||
} else {
|
||||
Toast.makeText(this, "Gagal: $response", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
|
||||
},
|
||||
{
|
||||
Toast.makeText(this, "Error koneksi server", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
|
||||
) {
|
||||
|
||||
override fun getParams(): MutableMap<String, String> {
|
||||
val params = HashMap<String, String>()
|
||||
|
||||
// 🔥 INI YANG BENAR (HARUS SAMA DENGAN PHP)
|
||||
params["nama"] = nama
|
||||
params["email"] = email
|
||||
params["password"] = password
|
||||
|
||||
return params
|
||||
}
|
||||
}
|
||||
|
||||
Volley.newRequestQueue(this).add(request)
|
||||
}
|
||||
|
||||
private fun setupPasswordToggle() {
|
||||
|
||||
binding.etPassword.setOnTouchListener { _, event ->
|
||||
|
||||
val drawableEnd = 2
|
||||
|
||||
if (event.action == MotionEvent.ACTION_UP) {
|
||||
|
||||
val drawable = binding.etPassword.compoundDrawables[drawableEnd]
|
||||
|
||||
if (drawable != null &&
|
||||
event.rawX >= (binding.etPassword.right - drawable.bounds.width())
|
||||
) {
|
||||
|
||||
isPasswordVisible = !isPasswordVisible
|
||||
|
||||
if (isPasswordVisible) {
|
||||
binding.etPassword.inputType =
|
||||
InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
|
||||
|
||||
binding.etPassword.setCompoundDrawablesWithIntrinsicBounds(
|
||||
R.drawable.ic_lock,
|
||||
0,
|
||||
R.drawable.ic_eye_off,
|
||||
0
|
||||
)
|
||||
} else {
|
||||
binding.etPassword.inputType =
|
||||
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
|
||||
|
||||
binding.etPassword.setCompoundDrawablesWithIntrinsicBounds(
|
||||
R.drawable.ic_lock,
|
||||
0,
|
||||
R.drawable.ic_eye,
|
||||
0
|
||||
)
|
||||
}
|
||||
|
||||
binding.etPassword.setSelection(binding.etPassword.text.length)
|
||||
return@setOnTouchListener true
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
binding.etConfirmPassword.setOnTouchListener { _, event ->
|
||||
|
||||
val drawableEnd = 2
|
||||
|
||||
if (event.action == MotionEvent.ACTION_UP) {
|
||||
|
||||
val drawable = binding.etConfirmPassword.compoundDrawables[drawableEnd]
|
||||
|
||||
if (drawable != null &&
|
||||
event.rawX >= (binding.etConfirmPassword.right - drawable.bounds.width())
|
||||
) {
|
||||
|
||||
isConfirmPasswordVisible = !isConfirmPasswordVisible
|
||||
|
||||
if (isConfirmPasswordVisible) {
|
||||
binding.etConfirmPassword.inputType =
|
||||
InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
|
||||
|
||||
binding.etConfirmPassword.setCompoundDrawablesWithIntrinsicBounds(
|
||||
R.drawable.ic_lock,
|
||||
0,
|
||||
R.drawable.ic_eye_off,
|
||||
0
|
||||
)
|
||||
} else {
|
||||
binding.etConfirmPassword.inputType =
|
||||
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
|
||||
|
||||
binding.etConfirmPassword.setCompoundDrawablesWithIntrinsicBounds(
|
||||
R.drawable.ic_lock,
|
||||
0,
|
||||
R.drawable.ic_eye,
|
||||
0
|
||||
)
|
||||
}
|
||||
|
||||
binding.etConfirmPassword.setSelection(binding.etConfirmPassword.text.length)
|
||||
return@setOnTouchListener true
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package com.example.projekta
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.example.projekta.databinding.ActivitySignInBinding
|
||||
|
||||
class SignInActivity : AppCompatActivity() {
|
||||
|
||||
private lateinit var binding: ActivitySignInBinding
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
binding = ActivitySignInBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
// 🔥 Tombol Sign In → Login
|
||||
binding.btnSignIn.setOnClickListener {
|
||||
startActivity(Intent(this, LoginActivity::class.java))
|
||||
}
|
||||
|
||||
// 🔥 Tombol Create Account → Register
|
||||
binding.btnRegister.setOnClickListener {
|
||||
startActivity(Intent(this, RegisterActivity::class.java))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package com.example.projekta
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
|
||||
class SplashActivity : AppCompatActivity() {
|
||||
|
||||
private val PREF_NAME = "LOGIN"
|
||||
private val KEY_LOGIN = "isLogin"
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_splash)
|
||||
|
||||
Handler(Looper.getMainLooper()).postDelayed({
|
||||
|
||||
val sharedPref = getSharedPreferences(PREF_NAME, MODE_PRIVATE)
|
||||
val isLogin = sharedPref.getBoolean(KEY_LOGIN, false)
|
||||
|
||||
if (isLogin) {
|
||||
startActivity(Intent(this, MenuActivity::class.java))
|
||||
} else {
|
||||
startActivity(Intent(this, SignInActivity::class.java))
|
||||
}
|
||||
|
||||
finish()
|
||||
|
||||
}, 2000)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package com.example.projekta
|
||||
|
||||
import android.os.Bundle
|
||||
import android.widget.ImageView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
|
||||
class TentangActivity : AppCompatActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_tentang)
|
||||
|
||||
val btnBack = findViewById<ImageView>(R.id.btnBack)
|
||||
btnBack.setOnClickListener {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="#2E7D32"/>
|
||||
<corners android:radius="30dp"/>
|
||||
</shape>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<!-- Warna hijau tua -->
|
||||
<solid android:color="#2E7D32"/>
|
||||
|
||||
<!-- Biar jadi gelembung -->
|
||||
<corners android:radius="30dp"/>
|
||||
|
||||
</shape>
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<!-- Warna hitam transparan -->
|
||||
<solid android:color="#33000000"/>
|
||||
|
||||
<!-- Sudut melengkung -->
|
||||
<corners android:radius="12dp"/>
|
||||
|
||||
<!-- Border tipis putih -->
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#FFFFFF"/>
|
||||
|
||||
</shape>
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<solid android:color="#F2F2F2"/>
|
||||
|
||||
<corners android:radius="18dp"/>
|
||||
|
||||
</shape>
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
|
||||
<solid android:color="#2E8E0E"/>
|
||||
|
||||
</shape>
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="#2E7D32"/>
|
||||
<corners android:radius="50dp"/>
|
||||
</shape>
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
|
||||
<solid android:color="#FFFFFF"/>
|
||||
|
||||
<stroke
|
||||
android:width="2dp"
|
||||
android:color="#4CAF50"/>
|
||||
|
||||
</shape>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="#FFFFFF"/>
|
||||
<corners android:radius="100dp"/>
|
||||
</shape>
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="#A5D6A7"/>
|
||||
<corners android:radius="16dp"/>
|
||||
</shape>
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="#E8F5E9"/>
|
||||
<corners android:radius="20dp"/>
|
||||
</shape>
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="#D9E4E6"/>
|
||||
<corners android:radius="20dp"/>
|
||||
</shape>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="#FFFFFF"/>
|
||||
<corners
|
||||
android:topLeftRadius="40dp"
|
||||
android:topRightRadius="40dp"/>
|
||||
</shape>
|
||||
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
|
@ -0,0 +1,11 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="#2E7D32">
|
||||
|
||||
<path
|
||||
android:fillColor="#2E7D32"
|
||||
android:pathData="M20,4H4C2.9,4 2,4.9 2,6V18C2,19.1 2.9,20 4,20H20C21.1,20 22,19.1 22,18V6C22,4.9 21.1,4 20,4ZM20,8L12,13L4,8V6L12,11L20,6V8Z"/>
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="#2E7D32">
|
||||
|
||||
<path
|
||||
android:fillColor="#2E7D32"
|
||||
android:pathData="M12,6C7,6 2.7,9.1 1,12C2.7,14.9 7,18 12,18C17,18 21.3,14.9 23,12C21.3,9.1 17,6 12,6ZM12,16C9.8,16 8,14.2 8,12C8,9.8 9.8,8 12,8C14.2,8 16,9.8 16,12C16,14.2 14.2,16 12,16Z"/>
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="#2E7D32">
|
||||
|
||||
<path
|
||||
android:fillColor="#2E7D32"
|
||||
android:pathData="M2,4.27L3.28,3L21,20.72L19.73,22L16.65,18.92C15.17,19.61 13.63,20 12,20C7,20 2.73,16.89 1,12C1.73,9.93 3.06,8.06 4.83,6.61L2,4.27ZM12,8C14.21,8 16,9.79 16,12C16,12.58 15.87,13.13 15.64,13.62L10.38,8.36C10.87,8.13 11.42,8 12,8ZM6.53,8.11L8.08,9.66C8.03,9.87 8,10.08 8,10.3C8,12.51 9.79,14.3 12,14.3C12.22,14.3 12.43,14.27 12.64,14.22L14.19,15.77C13.53,16.13 12.79,16.3 12,16.3C9.24,16.3 7,14.06 7,11.3C7,10.51 7.17,9.77 7.53,9.11L6.53,8.11Z"/>
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,170 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path
|
||||
android:fillColor="#3DDC84"
|
||||
android:pathData="M0,0h108v108h-108z" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M9,0L9,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,0L19,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,0L29,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,0L39,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,0L49,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,0L59,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,0L69,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,0L79,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M89,0L89,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M99,0L99,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,9L108,9"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,19L108,19"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,29L108,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,39L108,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,49L108,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,59L108,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,69L108,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,79L108,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,89L108,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,99L108,99"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,29L89,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,39L89,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,49L89,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,59L89,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,69L89,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,79L89,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,19L29,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,19L39,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,19L49,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,19L59,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,19L69,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,19L79,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:endX="85.84757"
|
||||
android:endY="92.4963"
|
||||
android:startX="42.9492"
|
||||
android:startY="49.59793"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:color="#44000000"
|
||||
android:offset="0.0" />
|
||||
<item
|
||||
android:color="#00000000"
|
||||
android:offset="1.0" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
||||
android:strokeWidth="1"
|
||||
android:strokeColor="#00000000" />
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="#2E7D32">
|
||||
|
||||
<path
|
||||
android:fillColor="#2E7D32"
|
||||
android:pathData="M12,2C9.79,2 8,3.79 8,6V8H6C4.9,8 4,8.9 4,10V20C4,21.1 4.9,22 6,22H18C19.1,22 20,21.1 20,20V10C20,8.9 19.1,8 18,8H16V6C16,3.79 14.21,2 12,2ZM12,4C13.1,4 14,4.9 14,6V8H10V6C10,4.9 10.9,4 12,4ZM12,17C10.9,17 10,16.1 10,15C10,13.9 10.9,13 12,13C13.1,13 14,13.9 14,15C14,16.1 13.1,17 12,17Z"/>
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="#2E7D32">
|
||||
|
||||
<path
|
||||
android:fillColor="#2E7D32"
|
||||
android:pathData="M12,12C14.21,12 16,10.21 16,8C16,5.79 14.21,4 12,4C9.79,4 8,5.79 8,8C8,10.21 9.79,12 12,12ZM12,14C9.33,14 4,15.34 4,18V20H20V18C20,15.34 14.67,14 12,14Z"/>
|
||||
</vector>
|
||||
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 107 KiB |
|
After Width: | Height: | Size: 8.3 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 2.5 MiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 77 KiB |
|
|
@ -0,0 +1,63 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:background="#F5F5F5">
|
||||
|
||||
<!-- HEADER -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="70dp"
|
||||
android:background="#43A047"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp">
|
||||
|
||||
<!-- BUTTON BACK -->
|
||||
<ImageView
|
||||
android:id="@+id/btnBack"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:src="@android:drawable/ic_media_previous"
|
||||
app:tint="#FFFFFF" />
|
||||
|
||||
<!-- TITLE -->
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Histori Pemupukan"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textStyle="bold"
|
||||
android:textSize="18sp"
|
||||
android:gravity="center" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- JUDUL -->
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Histori Pemupukan"
|
||||
android:textColor="#2E7D32"
|
||||
android:textStyle="bold"
|
||||
android:textSize="24sp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginBottom="12dp" />
|
||||
|
||||
<!-- RECYCLER VIEW -->
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerHistori"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingStart="12dp"
|
||||
android:paddingEnd="12dp"
|
||||
android:paddingBottom="20dp"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#F5F5F5">
|
||||
|
||||
<!-- TOP IMAGE -->
|
||||
<ImageView
|
||||
android:id="@+id/imgTop"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="250dp"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/temakopi"
|
||||
android:contentDescription="background"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<!-- BACK BUTTON -->
|
||||
<ImageView
|
||||
android:id="@+id/btnBack"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:src="@android:drawable/ic_media_previous"
|
||||
android:background="@drawable/bg_circle_white"
|
||||
android:padding="8dp"
|
||||
app:tint="#2E7D32"
|
||||
android:elevation="4dp"
|
||||
android:contentDescription="back"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:layout_margin="16dp"/>
|
||||
|
||||
<!-- CONTAINER -->
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:orientation="vertical"
|
||||
android:padding="24dp"
|
||||
android:background="@drawable/bg_top_curve"
|
||||
app:layout_constraintTop_toBottomOf="@id/imgTop"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
|
||||
<!-- TITLE -->
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Selamat Datang"
|
||||
android:textSize="26sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="#2E7D32"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Masuk ke akun anda"
|
||||
android:textSize="14sp"
|
||||
android:textColor="#888888"
|
||||
android:layout_marginBottom="24dp"/>
|
||||
|
||||
<!-- EMAIL -->
|
||||
<EditText
|
||||
android:id="@+id/etEmail"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="55dp"
|
||||
android:hint="Email"
|
||||
android:inputType="textEmailAddress"
|
||||
android:drawableStart="@drawable/ic_email"
|
||||
android:drawablePadding="10dp"
|
||||
android:padding="14dp"
|
||||
android:textColor="#2E7D32"
|
||||
android:textColorHint="#7A9E7E"
|
||||
android:background="@drawable/bg_input_round"
|
||||
android:layout_marginBottom="12dp"/>
|
||||
|
||||
<!-- PASSWORD -->
|
||||
<EditText
|
||||
android:id="@+id/etPassword"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="55dp"
|
||||
android:hint="Password"
|
||||
android:inputType="textPassword"
|
||||
android:drawableStart="@drawable/ic_lock"
|
||||
android:drawableEnd="@drawable/ic_eye"
|
||||
android:drawablePadding="10dp"
|
||||
android:padding="14dp"
|
||||
android:textColor="#2E7D32"
|
||||
android:textColorHint="#7A9E7E"
|
||||
android:background="@drawable/bg_input_round"/>
|
||||
|
||||
<!-- REMEMBER -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="10dp">
|
||||
|
||||
<CheckBox
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Remember Me"
|
||||
android:textSize="12sp"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Lupa password?"
|
||||
android:textSize="12sp"
|
||||
android:textColor="#2E7D32"
|
||||
android:layout_marginStart="16dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- LOGIN BUTTON -->
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btnLogin"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="55dp"
|
||||
android:text="Login"
|
||||
android:textColor="#FFFFFF"
|
||||
android:layout_marginTop="24dp"
|
||||
app:backgroundTint="#2E7D32"
|
||||
app:cornerRadius="30dp"/>
|
||||
|
||||
<!-- REGISTER -->
|
||||
<TextView
|
||||
android:id="@+id/txtRegister"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Belum punya akun? Register"
|
||||
android:textSize="13sp"
|
||||
android:layout_marginTop="16dp"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
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_height="match_parent"
|
||||
tools:context=".MainActivity">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Hello World!"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
@ -0,0 +1,280 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.drawerlayout.widget.DrawerLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/drawerLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<!-- ================= MAIN CONTENT ================= -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:background="#F5F5F5">
|
||||
|
||||
<!-- HEADER -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="100dp"
|
||||
android:background="#4CAF50"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/btnMenu"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:src="@android:drawable/ic_menu_sort_by_size"
|
||||
app:tint="#FFFFFF"
|
||||
android:contentDescription="Menu"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Beranda"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="#FFFFFF"
|
||||
android:layout_marginStart="16dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- TITLE -->
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Apa yang ingin anda lihat?"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
android:padding="16dp"/>
|
||||
|
||||
<!-- MENU LIST -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="10dp">
|
||||
|
||||
<!-- PEMUPUKAN -->
|
||||
<LinearLayout
|
||||
android:id="@+id/menuPemupukan"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="80dp"
|
||||
android:background="@drawable/bg_menu_item"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:padding="16dp"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:src="@drawable/pupuk"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Pemupukan"
|
||||
android:textSize="16sp"
|
||||
android:layout_marginStart="16dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- PANDUAN -->
|
||||
<LinearLayout
|
||||
android:id="@+id/menuPanduan"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="80dp"
|
||||
android:background="@drawable/bg_menu_item"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:padding="16dp"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:src="@drawable/sensor"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Panduan Pengoperasian"
|
||||
android:textSize="16sp"
|
||||
android:layout_marginStart="16dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- PANEL SURYA -->
|
||||
<LinearLayout
|
||||
android:id="@+id/menuPanelSurya"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="80dp"
|
||||
android:background="@drawable/bg_menu_item"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:padding="16dp"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:src="@drawable/solarpanel"
|
||||
android:contentDescription="Panel Surya"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Panel Surya"
|
||||
android:textSize="16sp"
|
||||
android:layout_marginStart="16dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- TENTANG -->
|
||||
<LinearLayout
|
||||
android:id="@+id/menuTentang"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="80dp"
|
||||
android:background="@drawable/bg_menu_item"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:padding="16dp"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:src="@drawable/panduan"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Tentang Aplikasi"
|
||||
android:textSize="16sp"
|
||||
android:layout_marginStart="16dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- HISTORI -->
|
||||
<LinearLayout
|
||||
android:id="@+id/menuHistori"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="80dp"
|
||||
android:background="@drawable/bg_menu_item"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:padding="16dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:src="@drawable/histori"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Histori Sensor"
|
||||
android:textSize="16sp"
|
||||
android:layout_marginStart="16dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- ================= SIDEBAR ================= -->
|
||||
<LinearLayout
|
||||
android:id="@+id/sidebar"
|
||||
android:layout_width="280dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="start"
|
||||
android:orientation="vertical"
|
||||
android:background="#FFFFFF">
|
||||
|
||||
<!-- HEADER SIDEBAR -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="120dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:padding="16dp"
|
||||
android:background="#7ED957">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imgSidebarProfile"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="60dp"
|
||||
android:src="@drawable/profileman"
|
||||
android:scaleType="centerCrop"
|
||||
android:background="@drawable/bg_circle_white"
|
||||
android:padding="2dp"
|
||||
android:contentDescription="Foto Profil"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtSidebarName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Nama Pengguna"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginStart="12dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- PROFILE -->
|
||||
<LinearLayout
|
||||
android:id="@+id/menuProfile"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="60dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:padding="16dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:src="@drawable/iconprofil"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Profile"
|
||||
android:layout_marginStart="16dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- LOGOUT -->
|
||||
<LinearLayout
|
||||
android:id="@+id/menuLogout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="60dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:padding="16dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:src="@drawable/logout"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Logout"
|
||||
android:layout_marginStart="16dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.drawerlayout.widget.DrawerLayout>
|
||||
|
|
@ -0,0 +1,201 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#F4F6F8">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/header"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="70dp"
|
||||
android:background="#2E8B57"
|
||||
android:gravity="center_vertical"
|
||||
android:padding="16dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/btnBack"
|
||||
android:layout_width="26dp"
|
||||
android:layout_height="26dp"
|
||||
android:contentDescription="Back"
|
||||
android:src="@android:drawable/ic_media_previous"
|
||||
app:tint="#FFFFFF" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:text="Pengaturan Pemupukan"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/cardAuto"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
app:cardCornerRadius="18dp"
|
||||
app:cardElevation="10dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/header"
|
||||
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="18dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="MODE OTOMATIS"
|
||||
android:textColor="#2E8B57"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:src="@android:drawable/ic_lock_idle_alarm" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvJam"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:text="07:00:00"
|
||||
android:textSize="16sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnPilihJam"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:backgroundTint="#2E8B57"
|
||||
android:text="Ubah Jam"
|
||||
android:textColor="#FFFFFF" />
|
||||
|
||||
<!-- Interval -->
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="18dp"
|
||||
android:text="Interval Pemupukan (Hari)"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etInterval"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginTop="6dp"
|
||||
android:hint="Contoh: 14"
|
||||
android:inputType="number" />
|
||||
|
||||
<!-- Durasi -->
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="18dp"
|
||||
android:text="Durasi Penyiraman (Detik)"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etDurasi"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginTop="6dp"
|
||||
android:hint="Contoh: 20"
|
||||
android:inputType="number" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/cardManual"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
app:cardCornerRadius="18dp"
|
||||
app:cardElevation="6dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/cardAuto"
|
||||
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="18dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="MODE MANUAL"
|
||||
android:textColor="#D32F2F"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvStatusManual"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:text="STATUS : OFF"
|
||||
android:textColor="#D32F2F"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnPompaManual"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="55dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:backgroundTint="#00C853"
|
||||
android:text="NYALAKAN POMPA"
|
||||
android:textColor="#FFFFFF" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnSimpan"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="55dp"
|
||||
android:layout_margin="16dp"
|
||||
android:backgroundTint="#2E8B57"
|
||||
android:text="SIMPAN PENGATURAN"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintTop_toBottomOf="@id/cardManual"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
|
@ -0,0 +1,207 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fillViewport="true"
|
||||
android:background="#55C216">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="20dp">
|
||||
|
||||
<!-- HEADER -->
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="80dp"
|
||||
android:paddingStart="12dp"
|
||||
android:paddingEnd="12dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/btnBack"
|
||||
android:layout_width="38dp"
|
||||
android:layout_height="38dp"
|
||||
android:layout_centerVertical="true"
|
||||
android:padding="8dp"
|
||||
android:src="@android:drawable/ic_media_previous"
|
||||
app:tint="#FFFFFF" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:text="Panduan"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textStyle="bold"
|
||||
android:textSize="28sp" />
|
||||
</RelativeLayout>
|
||||
|
||||
<!-- CARD 1 -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="10dp"
|
||||
android:background="#EDEDED"
|
||||
android:orientation="horizontal"
|
||||
android:padding="18dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="42dp"
|
||||
android:layout_height="42dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:src="@android:drawable/ic_lock_power_off"
|
||||
app:tint="#0A8F3D"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginStart="14dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Hidupkan Alat"
|
||||
android:textStyle="bold"
|
||||
android:textSize="20sp"
|
||||
android:textColor="#222222"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="6dp"
|
||||
android:text="Sambungkan perangkat ke listrik/USB atau tekan tombol power. Pastikan lampu indikator menyala sebagai tanda alat aktif."
|
||||
android:textSize="16sp"
|
||||
android:textColor="#222222"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- CARD 2 -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:background="#EDEDED"
|
||||
android:orientation="horizontal"
|
||||
android:padding="18dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="42dp"
|
||||
android:layout_height="42dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:src="@android:drawable/ic_menu_compass"
|
||||
app:tint="#0A8F3D"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginStart="14dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Sensor Membaca Data"
|
||||
android:textStyle="bold"
|
||||
android:textSize="20sp"
|
||||
android:textColor="#222222"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="6dp"
|
||||
android:text="Secara otomatis sensor akan mengukur kelembapan tanah, suhu udara, kelembapan udara."
|
||||
android:textSize="16sp"
|
||||
android:textColor="#222222"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- CARD 3 -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="10dp"
|
||||
android:background="#EDEDED"
|
||||
android:orientation="horizontal"
|
||||
android:padding="18dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="42dp"
|
||||
android:layout_height="42dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:src="@android:drawable/ic_menu_upload"
|
||||
app:tint="#0A8F3D"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginStart="14dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Data Terkirim Via Iot"
|
||||
android:textStyle="bold"
|
||||
android:textSize="20sp"
|
||||
android:textColor="#222222"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="6dp"
|
||||
android:text="Hasil pengukuran dikirim melalui Wi-Fi/internet ke server aplikasi."
|
||||
android:textSize="16sp"
|
||||
android:textColor="#222222"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- CARD 4 -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="10dp"
|
||||
android:background="#EDEDED"
|
||||
android:orientation="horizontal"
|
||||
android:padding="18dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="42dp"
|
||||
android:layout_height="42dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:src="@android:drawable/ic_menu_view"
|
||||
app:tint="#0A8F3D"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginStart="14dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Lihat Di Aplikasi"
|
||||
android:textStyle="bold"
|
||||
android:textSize="20sp"
|
||||
android:textColor="#222222"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="6dp"
|
||||
android:text="Buka aplikasi di smartphone. Data terbaru tampil di Dashboard dan histori dapat dilihat di menu sensor."
|
||||
android:textSize="16sp"
|
||||
android:textColor="#222222"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
|
@ -0,0 +1,216 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#F5F5F5">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<!-- HEADER -->
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/header"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="70dp"
|
||||
android:background="#2E8B57"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingHorizontal="16dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/btnBack"
|
||||
android:layout_width="28dp"
|
||||
android:layout_height="28dp"
|
||||
android:src="@android:drawable/ic_media_previous"
|
||||
android:contentDescription="Back"
|
||||
app:tint="@android:color/white"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:text="Monitoring Panel Surya"
|
||||
android:textColor="@android:color/white"
|
||||
android:textStyle="bold"
|
||||
android:textSize="18sp"
|
||||
android:paddingEnd="28dp"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- HEADER IMAGE -->
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imgHeader"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="180dp"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/panel"
|
||||
app:layout_constraintTop_toBottomOf="@id/header"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<!-- JUDUL -->
|
||||
|
||||
<TextView
|
||||
android:id="@+id/titleImage"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="☀️ Panel Surya"
|
||||
android:textColor="@android:color/white"
|
||||
android:textStyle="bold"
|
||||
android:textSize="24sp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginTop="28dp"
|
||||
app:layout_constraintStart_toStartOf="@id/imgHeader"
|
||||
app:layout_constraintTop_toTopOf="@id/imgHeader"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Monitoring Daya Sistem"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="15sp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginTop="6dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/titleImage"
|
||||
app:layout_constraintStart_toStartOf="@id/imgHeader"/>
|
||||
|
||||
<!-- CARD -->
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/cardPanel"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="20dp"
|
||||
android:layout_marginTop="-30dp"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:cardElevation="6dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/imgHeader"
|
||||
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="18dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Status Panel"
|
||||
android:textStyle="bold"
|
||||
android:textSize="16sp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvStatusPanel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="🟢 Aktif"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="#2E8B57"/>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="#DDDDDD"
|
||||
android:layout_marginVertical="12dp"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Cek Daya"
|
||||
android:textStyle="bold"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvDaya"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="95%"
|
||||
android:textSize="30sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="#2E8B57"/>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressDaya"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="12dp"
|
||||
android:max="100"
|
||||
android:progress="95"
|
||||
android:layout_marginTop="8dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvStatusDaya"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="🟢 Sangat Baik"
|
||||
android:textStyle="bold"
|
||||
android:textColor="#2E8B57"
|
||||
android:layout_marginTop="10dp"/>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="#DDDDDD"
|
||||
android:layout_marginVertical="12dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvSumberEnergi"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="🔆 Sumber Energi : Panel Surya 5 Wp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvStatusSistem"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="⚙️ Status Sistem : Aktif"
|
||||
android:layout_marginTop="10dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvStatusPompa"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="🚰 Status Pompa : OFF"
|
||||
android:layout_marginTop="10dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvUpdate"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="🕒 Update Terakhir : -"
|
||||
android:layout_marginTop="10dp"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnRefresh"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="55dp"
|
||||
android:layout_marginHorizontal="20dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginBottom="30dp"
|
||||
android:text="REFRESH DATA"
|
||||
android:textColor="@android:color/white"
|
||||
android:textStyle="bold"
|
||||
android:backgroundTint="#2E8B57"
|
||||
app:layout_constraintTop_toBottomOf="@id/cardPanel"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
|
@ -0,0 +1,200 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#F5F5F5">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<!-- HEADER -->
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/header"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="70dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:background="#2E8B57"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/btnBack"
|
||||
android:layout_width="28dp"
|
||||
android:layout_height="28dp"
|
||||
android:contentDescription="Back"
|
||||
android:padding="2dp"
|
||||
android:src="@android:drawable/ic_media_previous"
|
||||
app:tint="#FFFFFF" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:paddingEnd="28dp"
|
||||
android:text="Smart Fertilizer System"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- IMAGE -->
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imgHeader"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="180dp"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/kebunkopi"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/header" />
|
||||
|
||||
<!-- TITLE -->
|
||||
|
||||
<TextView
|
||||
android:id="@+id/titleImage"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginTop="30dp"
|
||||
android:text="Smart Fertilizer System"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintStart_toStartOf="@id/imgHeader"
|
||||
app:layout_constraintTop_toTopOf="@id/imgHeader" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/subTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="Tanaman: Kopi / Kakao"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintStart_toStartOf="@id/imgHeader"
|
||||
app:layout_constraintTop_toBottomOf="@id/titleImage" />
|
||||
|
||||
<!-- CARD STATUS -->
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/cardStatus"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginTop="-30dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:cardElevation="6dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/imgHeader">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvSuhuTanah"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="🌡️ Suhu Tanah: --"
|
||||
android:textColor="#333333"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvKelembapanTanah"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="🌱 Kelembapan Tanah: --"
|
||||
android:textColor="#333333"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvSuhuUdara"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="☀️ Suhu Udara: --"
|
||||
android:textColor="#333333"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvKelembapanUdara"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="💦 Kelembapan Udara: --"
|
||||
android:textColor="#333333"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvStatusTanah"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:text="🟢 Status Tanah: --"
|
||||
android:textColor="#2E8B57"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvStatusSistem"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="⚙️ Status Sistem: --"
|
||||
android:textColor="#2E8B57"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvStatusPompa"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="🚰 Status Pompa: --"
|
||||
android:textColor="#2E8B57"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<!-- BUTTON PENGATURAN -->
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnMetode"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="55dp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:layout_marginBottom="30dp"
|
||||
android:backgroundTint="#2E8B57"
|
||||
android:text="PENGATURAN PEMUPUKAN"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/cardStatus" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#F5F5F5">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="20dp">
|
||||
|
||||
<!-- BACK -->
|
||||
<ImageView
|
||||
android:id="@+id/btnBack"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:src="@android:drawable/ic_media_previous"
|
||||
android:padding="8dp"
|
||||
android:background="@drawable/bg_circle_green"
|
||||
app:tint="#FFFFFF" />
|
||||
|
||||
<!-- PROFILE IMAGE -->
|
||||
<de.hdodenhof.circleimageview.CircleImageView
|
||||
android:id="@+id/imgProfile"
|
||||
android:layout_width="110dp"
|
||||
android:layout_height="110dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="20dp"
|
||||
android:src="@drawable/profileman"
|
||||
app:civ_border_width="3dp"
|
||||
app:civ_border_color="#4CAF50" />
|
||||
|
||||
<!-- NAME -->
|
||||
<TextView
|
||||
android:id="@+id/txtName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Nama"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="10dp"/>
|
||||
|
||||
<!-- EMAIL DISPLAY -->
|
||||
<TextView
|
||||
android:id="@+id/txtEmail"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="email@gmail.com"
|
||||
android:layout_gravity="center"
|
||||
android:textColor="#888888"
|
||||
android:layout_marginBottom="20dp"/>
|
||||
|
||||
<!-- INPUT NAMA -->
|
||||
<EditText
|
||||
android:id="@+id/etNama"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:hint="Nama"
|
||||
android:padding="12dp"
|
||||
android:background="@android:drawable/edit_text"
|
||||
android:layout_marginBottom="10dp"/>
|
||||
|
||||
<!-- EMAIL (READ ONLY) -->
|
||||
<EditText
|
||||
android:id="@+id/etEmail"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:hint="Email"
|
||||
android:padding="12dp"
|
||||
android:background="@android:drawable/edit_text"
|
||||
android:enabled="false"
|
||||
android:layout_marginBottom="10dp"/>
|
||||
|
||||
<!-- PHONE -->
|
||||
<EditText
|
||||
android:id="@+id/etPhone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:hint="Phone"
|
||||
android:padding="12dp"
|
||||
android:background="@android:drawable/edit_text"
|
||||
android:inputType="phone"
|
||||
android:layout_marginBottom="10dp"/>
|
||||
|
||||
<!-- TANGGAL -->
|
||||
<EditText
|
||||
android:id="@+id/etTanggal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:hint="Tanggal Lahir"
|
||||
android:padding="12dp"
|
||||
android:background="@android:drawable/edit_text"
|
||||
android:focusable="false"
|
||||
android:clickable="true"
|
||||
android:layout_marginBottom="20dp"/>
|
||||
|
||||
<!-- BUTTON -->
|
||||
<Button
|
||||
android:id="@+id/btnUpdate"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="55dp"
|
||||
android:text="Perbarui Profil"
|
||||
android:textColor="#FFFFFF"
|
||||
android:background="@drawable/bg_button_login"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
|
@ -0,0 +1,148 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#F5F5F5">
|
||||
|
||||
<!-- TOP IMAGE -->
|
||||
<ImageView
|
||||
android:id="@+id/imgTop"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="250dp"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/temakopi"
|
||||
android:contentDescription="background"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<!-- BACK BUTTON -->
|
||||
<ImageView
|
||||
android:id="@+id/btnBack"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:src="@android:drawable/ic_media_previous"
|
||||
android:background="@drawable/bg_circle_white"
|
||||
android:padding="8dp"
|
||||
app:tint="#2E7D32"
|
||||
android:elevation="4dp"
|
||||
android:contentDescription="back"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:layout_margin="16dp"/>
|
||||
|
||||
<!-- CONTAINER -->
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:orientation="vertical"
|
||||
android:padding="24dp"
|
||||
android:background="@drawable/bg_top_curve"
|
||||
app:layout_constraintTop_toBottomOf="@id/imgTop"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
|
||||
<!-- TITLE -->
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Create Account"
|
||||
android:textSize="26sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="#2E7D32"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Daftar akun baru"
|
||||
android:textSize="14sp"
|
||||
android:textColor="#888888"
|
||||
android:layout_marginBottom="24dp"/>
|
||||
|
||||
<!-- FULL NAME -->
|
||||
<EditText
|
||||
android:id="@+id/etName"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="55dp"
|
||||
android:hint="Full Name"
|
||||
android:inputType="textPersonName"
|
||||
android:drawableStart="@drawable/ic_user"
|
||||
android:drawablePadding="10dp"
|
||||
android:padding="14dp"
|
||||
android:textColor="#2E7D32"
|
||||
android:textColorHint="#7A9E7E"
|
||||
android:background="@drawable/bg_input_round"
|
||||
android:layout_marginBottom="12dp"/>
|
||||
|
||||
<!-- EMAIL -->
|
||||
<EditText
|
||||
android:id="@+id/etEmail"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="55dp"
|
||||
android:hint="Email"
|
||||
android:inputType="textEmailAddress"
|
||||
android:drawableStart="@drawable/ic_email"
|
||||
android:drawablePadding="10dp"
|
||||
android:padding="14dp"
|
||||
android:textColor="#2E7D32"
|
||||
android:textColorHint="#7A9E7E"
|
||||
android:background="@drawable/bg_input_round"
|
||||
android:layout_marginBottom="12dp"/>
|
||||
|
||||
<!-- PASSWORD -->
|
||||
<EditText
|
||||
android:id="@+id/etPassword"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="55dp"
|
||||
android:hint="Password"
|
||||
android:inputType="textPassword"
|
||||
android:drawableStart="@drawable/ic_lock"
|
||||
android:drawableEnd="@drawable/ic_eye"
|
||||
android:drawablePadding="10dp"
|
||||
android:padding="14dp"
|
||||
android:textColor="#2E7D32"
|
||||
android:textColorHint="#7A9E7E"
|
||||
android:background="@drawable/bg_input_round"
|
||||
android:layout_marginBottom="12dp"/>
|
||||
|
||||
<!-- CONFIRM PASSWORD -->
|
||||
<EditText
|
||||
android:id="@+id/etConfirmPassword"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="55dp"
|
||||
android:hint="Confirm Password"
|
||||
android:inputType="textPassword"
|
||||
android:drawableStart="@drawable/ic_lock"
|
||||
android:drawableEnd="@drawable/ic_eye"
|
||||
android:drawablePadding="10dp"
|
||||
android:padding="14dp"
|
||||
android:textColor="#2E7D32"
|
||||
android:textColorHint="#7A9E7E"
|
||||
android:background="@drawable/bg_input_round"/>
|
||||
|
||||
<!-- BUTTON REGISTER -->
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btnRegister"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="55dp"
|
||||
android:text="Register"
|
||||
android:textColor="#FFFFFF"
|
||||
android:layout_marginTop="24dp"
|
||||
app:backgroundTint="#2E7D32"
|
||||
app:cornerRadius="30dp"/>
|
||||
|
||||
<!-- LOGIN LINK -->
|
||||
<TextView
|
||||
android:id="@+id/txtLogin"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Sudah punya akun? Login"
|
||||
android:textSize="13sp"
|
||||
android:layout_marginTop="16dp"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<!-- Background -->
|
||||
<ImageView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:src="@drawable/temakopi"
|
||||
android:scaleType="centerCrop"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<!-- Overlay -->
|
||||
<View
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:background="#55000000"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<!-- Title kiri atas -->
|
||||
<TextView
|
||||
android:id="@+id/txtTitle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="KopiKaoCare\nSmart Care for\nCoffee & Cocoa"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="28sp"
|
||||
android:textStyle="bold"
|
||||
android:lineSpacingExtra="6dp"
|
||||
android:layout_marginTop="60dp"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginEnd="24dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"/>
|
||||
|
||||
<!-- Container tombol -->
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center"
|
||||
android:layout_marginStart="40dp"
|
||||
android:layout_marginEnd="40dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
|
||||
<!-- Sign In -->
|
||||
<Button
|
||||
android:id="@+id/btnSignIn"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="55dp"
|
||||
android:text="Sign In"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="16sp"
|
||||
android:background="@drawable/bg_button_transparent"/>
|
||||
|
||||
<!-- Create Account -->
|
||||
<Button
|
||||
android:id="@+id/btnRegister"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="55dp"
|
||||
android:text="Create Account"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="16sp"
|
||||
android:background="@drawable/bg_button_transparent"
|
||||
android:layout_marginTop="16dp"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#F3E5AB">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imgKopi"
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="150dp"
|
||||
android:src="@drawable/kopikao"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtApp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="KopiKaoCare"
|
||||
android:textSize="22sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="#000000"
|
||||
app:layout_constraintTop_toBottomOf="@id/imgKopi"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:layout_marginTop="16dp"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#44BE16">
|
||||
|
||||
<!-- Tombol Back Bulat -->
|
||||
<ImageView
|
||||
android:id="@+id/btnBack"
|
||||
android:layout_width="38dp"
|
||||
android:layout_height="38dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:background="@drawable/bg_circle_back"
|
||||
android:padding="8dp"
|
||||
android:src="@android:drawable/ic_media_previous"
|
||||
app:tint="#FFFFFF"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"/>
|
||||
|
||||
<!-- Judul -->
|
||||
<TextView
|
||||
android:id="@+id/txtTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Tentang Aplikasi"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="22sp"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginTop="44dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<!-- Card Putih -->
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginStart="18dp"
|
||||
android:layout_marginEnd="18dp"
|
||||
android:layout_marginTop="28dp"
|
||||
android:layout_marginBottom="18dp"
|
||||
android:fillViewport="true"
|
||||
app:layout_constraintTop_toBottomOf="@id/txtTitle"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bg_card_tentang"
|
||||
android:orientation="vertical"
|
||||
android:padding="14dp">
|
||||
|
||||
<!-- Logo -->
|
||||
<ImageView
|
||||
android:layout_width="140dp"
|
||||
android:layout_height="90dp"
|
||||
android:layout_gravity="center"
|
||||
android:adjustViewBounds="true"
|
||||
android:src="@drawable/logokopi"/>
|
||||
|
||||
<!-- Isi Text -->
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text='KopiKaoCare adalah aplikasi berbasis IoT yang dirancang untuk mengontrol dan memantau sistem pemupukan otomatis pada tanaman kopi dan kakao. Aplikasi ini membaca kelembapan tanah secara real-time untuk menentukan waktu pemupukan yang tepat, sehingga pupuk diberikan sesuai kebutuhan tanaman. Dengan sistem otomatis berbasis tenaga surya, pemupukan menjadi lebih efisien, tepat dosis, dan ramah lingkungan. Dengan KopiKaoCare, petani dapat: • Memastikan kondisi tanah dan udara tetap ideal bagi pertumbuhan tanaman kopi dan kakao. • Mencegah risiko kekeringan atau kelembapan berlebih yang dapat menurunkan kualitas dan produktivitas tanaman. • Mengontrol sistem pemupukan otomatis secara manual maupun otomatis sesuai kebutuhan tanaman. • Mendukung pertanian yang lebih efisien, cerdas, dan berkelanjutan melalui pemanfaatan teknologi IoT dan energi terbarukan (panel surya). KopiKaoCare hadir sebagai solusi inovatif untuk meningkatkan efisiensi pemupukan, mengurangi kesalahan manual, serta mendukung sistem pertanian presisi demi ketahanan pangan yang lebih baik.'
|
||||
android:textColor="#222222"
|
||||
android:textSize="16sp"
|
||||
android:lineSpacingExtra="4dp"
|
||||
android:fontFamily="serif"
|
||||
android:layout_marginTop="10dp"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
|
||||
android:id="@+id/cardHistori"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
|
||||
app:cardCornerRadius="14dp"
|
||||
app:cardElevation="3dp"
|
||||
app:cardBackgroundColor="#FFFFFF">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="18dp">
|
||||
|
||||
<!-- TANGGAL -->
|
||||
<TextView
|
||||
android:id="@+id/tvTanggal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="20 Feb 2026"
|
||||
android:textStyle="bold"
|
||||
android:textSize="18sp"
|
||||
android:textColor="#2E7D32" />
|
||||
|
||||
<!-- JAM -->
|
||||
<TextView
|
||||
android:id="@+id/tvJam"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="07:00 WIB"
|
||||
android:textSize="15sp"
|
||||
android:textColor="#555555"
|
||||
android:layout_marginTop="8dp" />
|
||||
|
||||
<!-- MODE -->
|
||||
<TextView
|
||||
android:id="@+id/tvMode"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="• Mode: Otomatis"
|
||||
android:textStyle="bold"
|
||||
android:textColor="#444444"
|
||||
android:textSize="16sp"
|
||||
android:layout_marginTop="12dp" />
|
||||
|
||||
<!-- DURASI -->
|
||||
<TextView
|
||||
android:id="@+id/tvDurasi"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="• Durasi: 20 Detik"
|
||||
android:textColor="#555555"
|
||||
android:textSize="16sp"
|
||||
android:layout_marginTop="8dp" />
|
||||
|
||||
<!-- INTERVAL -->
|
||||
<TextView
|
||||
android:id="@+id/tvInterval"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="• Interval: 14 Hari"
|
||||
android:textColor="#555555"
|
||||
android:textSize="16sp"
|
||||
android:layout_marginTop="8dp" />
|
||||
|
||||
<!-- STATUS TANAH -->
|
||||
<TextView
|
||||
android:id="@+id/tvStatusTanah"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="🔥 Status Tanah: Kering"
|
||||
android:textStyle="bold"
|
||||
android:textColor="#C49000"
|
||||
android:textSize="15sp"
|
||||
android:layout_marginTop="10dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 982 B |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
|
|
@ -0,0 +1,7 @@
|
|||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Base.Theme.ProjekTA" parent="Theme.Material3.DayNight.NoActionBar">
|
||||
<!-- Customize your dark theme here. -->
|
||||
<!-- <item name="colorPrimary">@color/my_dark_primary</item> -->
|
||||
</style>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="black">#FF000000</color>
|
||||
<color name="white">#FFFFFFFF</color>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<resources>
|
||||
|
||||
<!-- APP -->
|
||||
<string name="app_name">Coffee App</string>
|
||||
|
||||
<!-- LOGIN / REGISTER -->
|
||||
<string name="sign_in_button">Sign In</string>
|
||||
<string name="register_button">Buat Akun</string>
|
||||
|
||||
<!-- ================= PEMUPUKAN ================= -->
|
||||
|
||||
<string name="back_button">Kembali</string>
|
||||
|
||||
<string name="title_pengaturan">Pengaturan Pemupukan</string>
|
||||
|
||||
<string name="mode_otomatis">MODE OTOMATIS</string>
|
||||
<string name="mode_manual">MODE MANUAL</string>
|
||||
|
||||
<string name="jam_default">⏰ Jam: 07:00 WIB</string>
|
||||
<string name="ubah_jam">Ubah Jam</string>
|
||||
|
||||
<string name="interval_default">📅 Setiap 14 Hari</string>
|
||||
<string name="durasi_label">⏱️ Durasi Penyiraman</string>
|
||||
|
||||
<string name="status_off">STATUS: OFF</string>
|
||||
<string name="aktifkan_pompa">AKTIFKAN POMPA</string>
|
||||
|
||||
<string name="simpan_pengaturan">SIMPAN PENGATURAN</string>
|
||||
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<!-- Base -->
|
||||
<style name="Base.Theme.ProjekTA" parent="Theme.Material3.DayNight.NoActionBar">
|
||||
|
||||
<!-- 🔥 WARNA UTAMA JADI HIJAU -->
|
||||
<item name="colorPrimary">#2E7D32</item>
|
||||
<item name="colorOnPrimary">#FFFFFF</item>
|
||||
|
||||
<item name="colorSecondary">#2E7D32</item>
|
||||
<item name="colorOnSecondary">#FFFFFF</item>
|
||||
|
||||
<!-- Optional biar konsisten -->
|
||||
<item name="colorPrimaryContainer">#A5D6A7</item>
|
||||
<item name="colorOnPrimaryContainer">#1B5E20</item>
|
||||
|
||||
</style>
|
||||
|
||||
<!-- Main -->
|
||||
<style name="Theme.ProjekTA" parent="Base.Theme.ProjekTA" />
|
||||
|
||||
<!-- SPLASH -->
|
||||
<style name="Theme.ProjekTA.Splash" parent="Theme.Material3.DayNight.NoActionBar">
|
||||
|
||||
<item name="android:windowSplashScreenBackground">#FFFFFF</item>
|
||||
<item name="android:windowSplashScreenAnimatedIcon">@drawable/kopikao</item>
|
||||
<item name="postSplashScreenTheme">@style/Theme.ProjekTA</item>
|
||||
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Sample backup rules file; uncomment and customize as necessary.
|
||||
See https://developer.android.com/guide/topics/data/autobackup
|
||||
for details.
|
||||
Note: This file is ignored for devices older than API 31
|
||||
See https://developer.android.com/about/versions/12/backup-restore
|
||||
-->
|
||||
<full-backup-content>
|
||||
<!--
|
||||
<include domain="sharedpref" path="."/>
|
||||
<exclude domain="sharedpref" path="device.xml"/>
|
||||
-->
|
||||
</full-backup-content>
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Sample data extraction rules file; uncomment and customize as necessary.
|
||||
See https://developer.android.com/about/versions/12/backup-restore#xml-changes
|
||||
for details.
|
||||
-->
|
||||
<data-extraction-rules>
|
||||
<cloud-backup>
|
||||
<!-- TODO: Use <include> and <exclude> to control what is backed up.
|
||||
<include .../>
|
||||
<exclude .../>
|
||||
-->
|
||||
</cloud-backup>
|
||||
<!--
|
||||
<device-transfer>
|
||||
<include .../>
|
||||
<exclude .../>
|
||||
</device-transfer>
|
||||
-->
|
||||
</data-extraction-rules>
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<network-security-config>
|
||||
|
||||
<base-config
|
||||
cleartextTrafficPermitted="true">
|
||||
|
||||
<trust-anchors>
|
||||
|
||||
<certificates
|
||||
src="system"/>
|
||||
|
||||
</trust-anchors>
|
||||
|
||||
</base-config>
|
||||
|
||||
</network-security-config>
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package com.example.projekta
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
class ExampleUnitTest {
|
||||
@Test
|
||||
fun addition_isCorrect() {
|
||||
assertEquals(4, 2 + 2)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
plugins {
|
||||
alias(libs.plugins.android.application) apply false
|
||||
}
|
||||