Perubahan Full
|
@ -22,8 +22,14 @@ if (flutterVersionName == null) {
|
||||||
flutterVersionName = '1.0'
|
flutterVersionName = '1.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def keystoreProperties = new Properties()
|
||||||
|
def keystorePropertiesFile = rootProject.file('key.properties')
|
||||||
|
if (keystorePropertiesFile.exists()) {
|
||||||
|
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
||||||
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
namespace "com.example.beta_app1"
|
namespace "com.nutrify.app"
|
||||||
compileSdk flutter.compileSdkVersion
|
compileSdk flutter.compileSdkVersion
|
||||||
ndkVersion flutter.ndkVersion
|
ndkVersion flutter.ndkVersion
|
||||||
|
|
||||||
|
@ -42,7 +48,7 @@ android {
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||||
applicationId "com.example.beta_app1"
|
applicationId "com.nutrify.app"
|
||||||
// You can update the following values to match your application needs.
|
// You can update the following values to match your application needs.
|
||||||
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
|
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
|
||||||
minSdkVersion flutter.minSdkVersion
|
minSdkVersion flutter.minSdkVersion
|
||||||
|
@ -51,13 +57,17 @@ android {
|
||||||
versionName flutterVersionName
|
versionName flutterVersionName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
signingConfigs {
|
||||||
|
release {
|
||||||
|
keyAlias keystoreProperties['keyAlias']
|
||||||
|
keyPassword keystoreProperties['keyPassword']
|
||||||
|
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
|
||||||
|
storePassword keystoreProperties['storePassword']
|
||||||
|
}
|
||||||
|
}
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
// TODO: Add your own signing config for the release build.
|
signingConfig signingConfigs.release
|
||||||
// Signing with the debug keys for now, so `flutter run --release` works.
|
|
||||||
signingConfig signingConfigs.debug
|
|
||||||
minifyEnabled true
|
|
||||||
shrinkResources true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<application
|
<application
|
||||||
android:label="Nutrify"
|
android:label="Nutrify"
|
||||||
android:name="${applicationName}"
|
android:name="${applicationName}"
|
||||||
android:icon="@mipmap/ic_launcher">
|
android:icon="@mipmap/launcher_icon">
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package com.example.beta_app1
|
package com.nutrify.app
|
||||||
|
|
||||||
import io.flutter.embedding.android.FlutterActivity
|
import io.flutter.embedding.android.FlutterActivity
|
||||||
|
|
||||||
|
|
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 5.1 KiB |
BIN
flutter_01.png
Before Width: | Height: | Size: 2.9 MiB |
After Width: | Height: | Size: 15 KiB |
|
@ -427,7 +427,7 @@
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon;
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||||
CLANG_CXX_LIBRARY = "libc++";
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
@ -484,7 +484,7 @@
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon;
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||||
CLANG_CXX_LIBRARY = "libc++";
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 295 B After Width: | Height: | Size: 426 B |
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 978 B |
Before Width: | Height: | Size: 450 B After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 282 B After Width: | Height: | Size: 654 B |
Before Width: | Height: | Size: 462 B After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 704 B After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 978 B |
Before Width: | Height: | Size: 586 B After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 862 B After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 862 B After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 4.8 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 762 B After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 4.5 KiB |
|
@ -34,7 +34,7 @@ class _LoginPageState extends State<LoginPage> {
|
||||||
|
|
||||||
final prefs = await SharedPreferences.getInstance();
|
final prefs = await SharedPreferences.getInstance();
|
||||||
String mqttServerIp =
|
String mqttServerIp =
|
||||||
prefs.getString('mqtt_server_ip') ?? '192.168.183.153';
|
prefs.getString('mqtt_server_ip') ?? '192.168.182.153';
|
||||||
String url = 'http://$mqttServerIp/test_api/login.php';
|
String url = 'http://$mqttServerIp/test_api/login.php';
|
||||||
|
|
||||||
final response = await http.post(
|
final response = await http.post(
|
||||||
|
@ -128,7 +128,7 @@ class _LoginPageState extends State<LoginPage> {
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Image.asset(
|
Image.asset(
|
||||||
"images/nature.gif",
|
"images/nutrify.png",
|
||||||
height: 200,
|
height: 200,
|
||||||
width: 200,
|
width: 200,
|
||||||
),
|
),
|
||||||
|
@ -216,31 +216,41 @@ class _LoginPageState extends State<LoginPage> {
|
||||||
),
|
),
|
||||||
child: const Text(
|
child: const Text(
|
||||||
'Login',
|
'Login',
|
||||||
style: TextStyle(color: Colors.white),
|
style: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 25),
|
||||||
ElevatedButton(
|
Center(
|
||||||
onPressed: () {
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
const Text(
|
||||||
|
'Belum memiliki akun?',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.black,
|
||||||
|
fontSize: 14.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) => RegisterPage()),
|
builder: (context) => RegisterPage(),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
backgroundColor:
|
|
||||||
const Color.fromARGB(255, 255, 255, 255),
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(12.0),
|
|
||||||
),
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 16.0),
|
|
||||||
minimumSize: const Size(double.infinity, 50),
|
|
||||||
),
|
|
||||||
child: const Text(
|
child: const Text(
|
||||||
'Register',
|
' Register',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Color.fromARGB(166, 26, 21, 21)),
|
color: Colors.red,
|
||||||
|
fontSize: 14.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -259,7 +269,7 @@ class _LoginPageState extends State<LoginPage> {
|
||||||
const Text(
|
const Text(
|
||||||
"@2024",
|
"@2024",
|
||||||
style: TextStyle(color: Colors.black, fontSize: 10.0),
|
style: TextStyle(color: Colors.black, fontSize: 10.0),
|
||||||
)
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'dart:convert';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import 'login.dart';
|
import 'login.dart';
|
||||||
|
@ -53,21 +54,24 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validasi fullname (opsional)
|
|
||||||
|
|
||||||
final prefs = await SharedPreferences.getInstance();
|
final prefs = await SharedPreferences.getInstance();
|
||||||
String mqttServerIp = prefs.getString('mqtt_server_ip') ?? '192.168.0.1';
|
String mqttServerIp =
|
||||||
|
prefs.getString('mqtt_server_ip') ?? '192.168.182.153';
|
||||||
String url = 'http://$mqttServerIp/test_api/register.php';
|
String url = 'http://$mqttServerIp/test_api/register.php';
|
||||||
|
|
||||||
final response = await http.post(
|
final response = await http.post(
|
||||||
Uri.parse(url),
|
Uri.parse(url),
|
||||||
body: {
|
headers: {"Content-Type": "application/json"},
|
||||||
|
body: jsonEncode({
|
||||||
"username": username,
|
"username": username,
|
||||||
"password": password,
|
"password": password,
|
||||||
"fullname": fullname,
|
"fullname": fullname,
|
||||||
},
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (response.statusCode == 200) {
|
if (response.statusCode == 200) {
|
||||||
|
final responseData = jsonDecode(response.body);
|
||||||
|
if (responseData['status'] == 'success') {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
const SnackBar(
|
const SnackBar(
|
||||||
content: Text('Akun berhasil dibuat'),
|
content: Text('Akun berhasil dibuat'),
|
||||||
|
@ -81,7 +85,24 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
setState(() {
|
setState(() {
|
||||||
// Handle error
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Text(responseData['message']),
|
||||||
|
duration: Duration(seconds: 2),
|
||||||
|
backgroundColor: Colors.red,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setState(() {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(
|
||||||
|
content: Text('Failed to register user'),
|
||||||
|
duration: Duration(seconds: 2),
|
||||||
|
backgroundColor: Colors.red,
|
||||||
|
),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,23 +110,22 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
backgroundColor: Colors.white,
|
||||||
title: const Text('Halaman Registrasi'),
|
body: Center(
|
||||||
),
|
child: SingleChildScrollView(
|
||||||
body: SingleChildScrollView(
|
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(15.0),
|
padding: const EdgeInsets.all(15.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Padding(
|
Image.asset(
|
||||||
padding: const EdgeInsets.all(10.0),
|
"images/nutrify.png",
|
||||||
child:
|
height: 200,
|
||||||
Image.asset("images/nature.gif", height: 200, width: 200),
|
width: 200,
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 10,
|
height: 20,
|
||||||
),
|
),
|
||||||
Card(
|
Card(
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
|
@ -224,23 +244,78 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: registerUser,
|
onPressed: registerUser,
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: Color.fromARGB(255, 221, 41, 41),
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(12.0),
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
),
|
),
|
||||||
padding: const EdgeInsets.symmetric(vertical: 16.0),
|
padding:
|
||||||
|
const EdgeInsets.symmetric(vertical: 16.0),
|
||||||
minimumSize: const Size(double.infinity, 50),
|
minimumSize: const Size(double.infinity, 50),
|
||||||
),
|
),
|
||||||
child: const Text('Daftar'),
|
child: const Text(
|
||||||
|
'Daftar',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
const Text(
|
||||||
|
'Sudah memiliki akun?',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.black,
|
||||||
|
fontSize: 14.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => const LoginPage(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: const Text(
|
||||||
|
' Masuk',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.green,
|
||||||
|
fontSize: 14.0,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
const Text(
|
||||||
|
"Apps Made For",
|
||||||
|
style: TextStyle(color: Colors.black, fontSize: 10),
|
||||||
|
),
|
||||||
|
const Text(
|
||||||
|
"Nutrient Hydroponic Control",
|
||||||
|
style: TextStyle(color: Colors.black, fontSize: 10.0),
|
||||||
|
),
|
||||||
|
const Text(
|
||||||
|
"@2024",
|
||||||
|
style: TextStyle(color: Colors.black, fontSize: 10.0),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -258,8 +258,8 @@ class _ChartsSectionState extends State<ChartsSection> {
|
||||||
),
|
),
|
||||||
primaryYAxis: NumericAxis(
|
primaryYAxis: NumericAxis(
|
||||||
minimum: 0,
|
minimum: 0,
|
||||||
maximum: 20,
|
maximum: 1000,
|
||||||
interval: 5,
|
interval: 200,
|
||||||
majorGridLines: MajorGridLines(width: 0.5, color: Colors.grey[300]),
|
majorGridLines: MajorGridLines(width: 0.5, color: Colors.grey[300]),
|
||||||
axisLine: AxisLine(width: 0),
|
axisLine: AxisLine(width: 0),
|
||||||
labelStyle: TextStyle(color: Colors.grey[700], fontSize: 12),
|
labelStyle: TextStyle(color: Colors.grey[700], fontSize: 12),
|
||||||
|
|
|
@ -33,7 +33,7 @@ class _SplashScreenState extends State<SplashScreen> {
|
||||||
backgroundColor:
|
backgroundColor:
|
||||||
Colors.white, // Ubah sesuai warna latar belakang yang diinginkan
|
Colors.white, // Ubah sesuai warna latar belakang yang diinginkan
|
||||||
body: Center(
|
body: Center(
|
||||||
child: Image.asset('images/nature.gif',
|
child: Image.asset('images/nutrify.png',
|
||||||
width: 200,
|
width: 200,
|
||||||
height:
|
height:
|
||||||
200), // Pastikan untuk menambahkan logo Anda di folder assets
|
200), // Pastikan untuk menambahkan logo Anda di folder assets
|
||||||
|
|
|
@ -7,7 +7,7 @@ project(runner LANGUAGES CXX)
|
||||||
set(BINARY_NAME "beta_app1")
|
set(BINARY_NAME "beta_app1")
|
||||||
# The unique GTK application identifier for this application. See:
|
# The unique GTK application identifier for this application. See:
|
||||||
# https://wiki.gnome.org/HowDoI/ChooseApplicationID
|
# https://wiki.gnome.org/HowDoI/ChooseApplicationID
|
||||||
set(APPLICATION_ID "com.example.beta_app1")
|
set(APPLICATION_ID "com.nutrify.app")
|
||||||
|
|
||||||
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
|
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
|
||||||
# versions of CMake.
|
# versions of CMake.
|
||||||
|
|
56
pubspec.lock
|
@ -1,6 +1,14 @@
|
||||||
# Generated by pub
|
# Generated by pub
|
||||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||||
packages:
|
packages:
|
||||||
|
archive:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: archive
|
||||||
|
sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.6.1"
|
||||||
args:
|
args:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -65,6 +73,22 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.1"
|
version: "1.3.1"
|
||||||
|
checked_yaml:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: checked_yaml
|
||||||
|
sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.3"
|
||||||
|
cli_util:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: cli_util
|
||||||
|
sha256: c05b7406fdabc7a49a3929d4af76bcaccbbffcbcdcf185b082e1ae07da323d19
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.4.1"
|
||||||
clock:
|
clock:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -166,6 +190,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.3.2"
|
version: "3.3.2"
|
||||||
|
flutter_launcher_icons:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: flutter_launcher_icons
|
||||||
|
sha256: "526faf84284b86a4cb36d20a5e45147747b7563d921373d4ee0559c54fcdbcea"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.13.1"
|
||||||
flutter_lints:
|
flutter_lints:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
|
@ -232,6 +264,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.2"
|
version: "4.0.2"
|
||||||
|
image:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image
|
||||||
|
sha256: "2237616a36c0d69aef7549ab439b833fb7f9fb9fc861af2cc9ac3eedddd69ca8"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.2.0"
|
||||||
intl:
|
intl:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -240,6 +280,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.18.1"
|
version: "0.18.1"
|
||||||
|
json_annotation:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: json_annotation
|
||||||
|
sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.9.0"
|
||||||
leak_tracker:
|
leak_tracker:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -661,6 +709,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.5.0"
|
version: "6.5.0"
|
||||||
|
yaml:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: yaml
|
||||||
|
sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.2"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.3.4 <4.0.0"
|
dart: ">=3.3.4 <4.0.0"
|
||||||
flutter: ">=3.19.0"
|
flutter: ">=3.19.0"
|
||||||
|
|
11
pubspec.yaml
|
@ -42,6 +42,7 @@ dependencies:
|
||||||
liquid_progress_indicator_v2: ^0.5.0
|
liquid_progress_indicator_v2: ^0.5.0
|
||||||
cached_network_image: ^3.3.1
|
cached_network_image: ^3.3.1
|
||||||
flutter_local_notifications: ^17.2.1+2
|
flutter_local_notifications: ^17.2.1+2
|
||||||
|
flutter_launcher_icons: "^0.13.1"
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
@ -54,6 +55,12 @@ dev_dependencies:
|
||||||
# rules and activating additional ones.
|
# rules and activating additional ones.
|
||||||
flutter_lints: ^4.0.0
|
flutter_lints: ^4.0.0
|
||||||
|
|
||||||
|
flutter_launcher_icons:
|
||||||
|
android: "launcher_icon"
|
||||||
|
ios: true
|
||||||
|
image_path: "images/nutrify.png"
|
||||||
|
min_sdk_android: 21 # android min sdk min:16, default 21
|
||||||
|
|
||||||
# For information on the generic Dart part of this file, see the
|
# For information on the generic Dart part of this file, see the
|
||||||
# following page: https://dart.dev/tools/pub/pubspec
|
# following page: https://dart.dev/tools/pub/pubspec
|
||||||
|
|
||||||
|
@ -66,12 +73,10 @@ flutter:
|
||||||
|
|
||||||
# To add assets to your application, add an assets section, like this:
|
# To add assets to your application, add an assets section, like this:
|
||||||
assets:
|
assets:
|
||||||
- images/ahri_coven.gif
|
|
||||||
- images/ahri_ori.gif
|
|
||||||
- images/ahri_icon.jpg
|
- images/ahri_icon.jpg
|
||||||
- images/nature.gif
|
- images/nature.gif
|
||||||
- images/arga.jpg
|
- images/arga.jpg
|
||||||
- images/hidroponik.png
|
- images/nutrify.png
|
||||||
|
|
||||||
# An image asset can refer to one or more resolution-specific "variants", see
|
# An image asset can refer to one or more resolution-specific "variants", see
|
||||||
# https://flutter.dev/assets-and-images/#resolution-aware
|
# https://flutter.dev/assets-and-images/#resolution-aware
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
<?php
|
||||||
|
// Koneksi ke database
|
||||||
|
$conn = mysqli_connect("localhost", "root", "", "tugas_akhir");
|
||||||
|
|
||||||
|
// Periksa koneksi
|
||||||
|
if ($conn->connect_error) {
|
||||||
|
die("Connection failed: " . $conn->connect_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mendapatkan tanggal mulai dan akhir dari permintaan
|
||||||
|
$startDate = isset($_GET['start_date']) ? $_GET['start_date'] : null;
|
||||||
|
$endDate = isset($_GET['end_date']) ? $_GET['end_date'] : null;
|
||||||
|
|
||||||
|
// Menyiapkan klausa WHERE untuk filter tanggal
|
||||||
|
$whereClause = "";
|
||||||
|
if ($startDate && $endDate) {
|
||||||
|
$whereClause = " WHERE timestamp BETWEEN '$startDate' AND '$endDate'";
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = array();
|
||||||
|
$data1 = array();
|
||||||
|
$data2 = array();
|
||||||
|
$data3 = array();
|
||||||
|
|
||||||
|
// Mengambil data dari tabel tb_waterflow1 termasuk kolom timestamp dan id
|
||||||
|
$sql = "SELECT id_wf1 as x, timestamp, waterflow1_value as y1 FROM tb_waterflow1 $whereClause";
|
||||||
|
$result = $conn->query($sql);
|
||||||
|
|
||||||
|
if ($result) {
|
||||||
|
if ($result->num_rows > 0) {
|
||||||
|
while ($row = $result->fetch_assoc()) {
|
||||||
|
$data[] = $row;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
echo "Error: " . $conn->error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mengambil data dari tabel tb_waterflow2 termasuk kolom timestamp dan id
|
||||||
|
$sql1 = "SELECT id_wf2 as x, timestamp, waterflow2_value as y2 FROM tb_waterflow2 $whereClause";
|
||||||
|
$result1 = $conn->query($sql1);
|
||||||
|
|
||||||
|
if ($result1) {
|
||||||
|
if ($result1->num_rows > 0) {
|
||||||
|
while ($row = $result1->fetch_assoc()) {
|
||||||
|
$data1[] = $row;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
echo "Error: " . $conn->error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mengambil data dari tabel tb_ppm termasuk kolom timestamp dan id
|
||||||
|
$sql2 = "SELECT id_ppm as x, timestamp, ppm_value as y3 FROM tb_ppm $whereClause";
|
||||||
|
$result2 = $conn->query($sql2);
|
||||||
|
|
||||||
|
if ($result2) {
|
||||||
|
if ($result2->num_rows > 0) {
|
||||||
|
while ($row = $result2->fetch_assoc()) {
|
||||||
|
$data2[] = $row;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
echo "Error: " . $conn->error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mengambil data dari tabel tb_waterlevel termasuk kolom timestamp dan id
|
||||||
|
$sql3 = "SELECT id_wl as x, timestamp, ultrasonic_value as y FROM tb_waterlevel $whereClause";
|
||||||
|
$result3 = $conn->query($sql3);
|
||||||
|
|
||||||
|
if ($result3) {
|
||||||
|
if ($result3->num_rows > 0) {
|
||||||
|
while ($row = $result3->fetch_assoc()) {
|
||||||
|
$data3[] = $row;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
echo "Error: " . $conn->error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tutup koneksi
|
||||||
|
$conn->close();
|
||||||
|
|
||||||
|
// Mengatur header untuk respon JSON
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
// Mengirimkan data sebagai JSON
|
||||||
|
echo json_encode(array(
|
||||||
|
'tb_waterflow1' => $data,
|
||||||
|
'tb_waterflow2' => $data1,
|
||||||
|
'tb_ppm' => $data2,
|
||||||
|
'tb_waterlevel' => $data3
|
||||||
|
));
|
|
@ -0,0 +1,42 @@
|
||||||
|
<?php
|
||||||
|
// Koneksi ke database MySQL
|
||||||
|
$conn = mysqli_connect("localhost", "root", "", "tugas_akhir");
|
||||||
|
|
||||||
|
// Periksa koneksi
|
||||||
|
if (!$conn) {
|
||||||
|
die("Koneksi ke database gagal: " . mysqli_connect_error());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kueri untuk mengambil data tanaman
|
||||||
|
$sql = "SELECT id_plant, title, desk, kategori, img, date FROM tb_plant";
|
||||||
|
|
||||||
|
// Jalankan kueri SQL
|
||||||
|
$result = mysqli_query($conn, $sql);
|
||||||
|
|
||||||
|
// Inisialisasi array untuk menyimpan data tanaman
|
||||||
|
$plants = array();
|
||||||
|
|
||||||
|
// Base URL untuk gambar (sesuaikan dengan alamat server Anda)
|
||||||
|
$base_url = 'http://' . $_SERVER['SERVER_ADDR'] . '/Upload/uploads/';
|
||||||
|
|
||||||
|
// Periksa apakah kueri berhasil dijalankan
|
||||||
|
if (mysqli_num_rows($result) > 0) {
|
||||||
|
// Ambil setiap baris data tanaman dan tambahkan ke array
|
||||||
|
while ($row = mysqli_fetch_assoc($result)) {
|
||||||
|
// Tambahkan URL penuh untuk gambar
|
||||||
|
$row['img'] = $base_url . $row['img'];
|
||||||
|
$plants[] = $row;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Konversi array ke format JSON
|
||||||
|
$json_response = json_encode($plants);
|
||||||
|
|
||||||
|
// Set header untuk respon JSON
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
// Tampilkan respon JSON
|
||||||
|
echo $json_response;
|
||||||
|
|
||||||
|
// Tutup koneksi database
|
||||||
|
mysqli_close($conn);
|
|
@ -0,0 +1,27 @@
|
||||||
|
<!-- <?php
|
||||||
|
function dbconnection()
|
||||||
|
{
|
||||||
|
$con = mysqli_connect("localhost", "root", "", "tugas_akhir");
|
||||||
|
return $con;
|
||||||
|
}
|
||||||
|
?> -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- <?php
|
||||||
|
$servername = "localhost";
|
||||||
|
$username = "root";
|
||||||
|
$password = "";
|
||||||
|
$dbname = "tugas_akhir";
|
||||||
|
|
||||||
|
// Create connection
|
||||||
|
try {
|
||||||
|
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
|
||||||
|
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
echo "Connection failed: " . $e->getMessage();
|
||||||
|
}
|
||||||
|
?> -->
|
||||||
|
|
||||||
|
<?php
|
||||||
|
$con = mysqli_connect('localhost', 'root', '', 'tugas_akhir') or die('tidak terkoneksi');
|
||||||
|
?>
|
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
// Koneksi ke database MySQL
|
||||||
|
$conn = mysqli_connect("localhost", "root", "", "tugas_akhir");
|
||||||
|
|
||||||
|
// Periksa koneksi
|
||||||
|
if (!$conn) {
|
||||||
|
die("Koneksi ke database gagal: " . mysqli_connect_error());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Periksa apakah parameter username diberikan
|
||||||
|
if (isset($_GET['username'])) {
|
||||||
|
$username = $_GET['username'];
|
||||||
|
$sql = "SELECT username, fullname FROM tb_login WHERE username = '$username'";
|
||||||
|
} else {
|
||||||
|
// Tidak ada username, kembalikan semua data pengguna
|
||||||
|
$sql = "SELECT username, fullname FROM tb_login";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Jalankan kueri SQL
|
||||||
|
$result = mysqli_query($conn, $sql);
|
||||||
|
|
||||||
|
// Inisialisasi array untuk menyimpan data pengguna
|
||||||
|
$users = array();
|
||||||
|
|
||||||
|
// Periksa apakah kueri berhasil dijalankan
|
||||||
|
if (mysqli_num_rows($result) > 0) {
|
||||||
|
// Ambil setiap baris data pengguna dan tambahkan ke array
|
||||||
|
while ($row = mysqli_fetch_assoc($result)) {
|
||||||
|
$users[] = $row;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Konversi array ke format JSON
|
||||||
|
$json_response = json_encode($users);
|
||||||
|
|
||||||
|
// Set header untuk respon JSON
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
// Tampilkan respon JSON
|
||||||
|
echo $json_response;
|
||||||
|
|
||||||
|
// Tutup koneksi database
|
||||||
|
mysqli_close($conn);
|
|
@ -0,0 +1,44 @@
|
||||||
|
<?php
|
||||||
|
header("Access-Control-Allow-Origin: *");
|
||||||
|
header("Content-Type: application/json; charset=UTF-8");
|
||||||
|
|
||||||
|
$conn = new mysqli("localhost", "root", "", "tugas_akhir");
|
||||||
|
|
||||||
|
if ($conn->connect_error) {
|
||||||
|
die("Connection failed: " . $conn->connect_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
$username = $_POST['username'];
|
||||||
|
$password = $_POST['password'];
|
||||||
|
|
||||||
|
// Query untuk mengambil hash password berdasarkan username
|
||||||
|
$query = $conn->prepare("SELECT * FROM tb_login WHERE username=?");
|
||||||
|
$query->bind_param("s", $username);
|
||||||
|
$query->execute();
|
||||||
|
$result = $query->get_result();
|
||||||
|
|
||||||
|
if ($result->num_rows == 1) {
|
||||||
|
$data = $result->fetch_assoc();
|
||||||
|
$hashedPassword = $data['password'];
|
||||||
|
|
||||||
|
// Verifikasi password
|
||||||
|
if (password_verify($password, $hashedPassword)) {
|
||||||
|
$token = bin2hex(random_bytes(10)); // Generate a random token with 10 bytes
|
||||||
|
|
||||||
|
// Simpan token ke database
|
||||||
|
$updateQuery = $conn->prepare("UPDATE tb_login SET token=? WHERE username=?");
|
||||||
|
$updateQuery->bind_param("ss", $token, $username);
|
||||||
|
if ($updateQuery->execute()) {
|
||||||
|
$data['token'] = $token;
|
||||||
|
echo json_encode(array("success" => true, "data" => $data));
|
||||||
|
} else {
|
||||||
|
echo json_encode(array("success" => false, "message" => "Failed to update token"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
echo json_encode(array("success" => false, "message" => "Invalid username or password."));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
echo json_encode(array("success" => false, "message" => "Invalid username or password."));
|
||||||
|
}
|
||||||
|
|
||||||
|
$conn->close();
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
header("Access-Control-Allow-Origin: *");
|
||||||
|
header("Content-Type: application/json; charset=UTF-8");
|
||||||
|
|
||||||
|
$conn = new mysqli("localhost", "root", "", "tugas_akhir");
|
||||||
|
|
||||||
|
if ($conn->connect_error) {
|
||||||
|
die("Connection failed: " . $conn->connect_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
$token = $_POST['token'];
|
||||||
|
|
||||||
|
$query = "UPDATE tb_login SET token='' WHERE token='$token'";
|
||||||
|
|
||||||
|
if (mysqli_query($conn, $query)) {
|
||||||
|
echo json_encode(["success" => true]);
|
||||||
|
} else {
|
||||||
|
echo json_encode(["error" => "Failed to update token."]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$conn->close();
|
|
@ -0,0 +1,57 @@
|
||||||
|
<?php
|
||||||
|
header("Content-Type: application/json; charset=UTF-8");
|
||||||
|
|
||||||
|
$servername = "localhost";
|
||||||
|
$username = "root";
|
||||||
|
$password = "";
|
||||||
|
$dbname = "tugas_akhir";
|
||||||
|
|
||||||
|
// Create connection
|
||||||
|
$conn = new mysqli($servername, $username, $password, $dbname);
|
||||||
|
|
||||||
|
// Check connection
|
||||||
|
if ($conn->connect_error) {
|
||||||
|
echo json_encode(array("status" => "error", "message" => "Connection failed: " . $conn->connect_error));
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get POST data
|
||||||
|
$data = json_decode(file_get_contents("php://input"), true);
|
||||||
|
$username = $data['username'];
|
||||||
|
$password = $data['password'];
|
||||||
|
$fullname = $data['fullname'];
|
||||||
|
|
||||||
|
// Validate input data
|
||||||
|
if (empty($username) || empty($password) || empty($fullname)) {
|
||||||
|
echo json_encode(array("status" => "error", "message" => "All fields are required."));
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if username already exists
|
||||||
|
$sql = "SELECT * FROM tb_login WHERE username = ?";
|
||||||
|
$stmt = $conn->prepare($sql);
|
||||||
|
$stmt->bind_param("s", $username);
|
||||||
|
$stmt->execute();
|
||||||
|
$result = $stmt->get_result();
|
||||||
|
if ($result->num_rows > 0) {
|
||||||
|
echo json_encode(array("status" => "error", "message" => "Username already exists."));
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hash the password
|
||||||
|
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
|
||||||
|
|
||||||
|
// Insert new user
|
||||||
|
$sql = "INSERT INTO tb_login (username, password, fullname) VALUES (?, ?, ?)";
|
||||||
|
$stmt = $conn->prepare($sql);
|
||||||
|
$stmt->bind_param("sss", $username, $hashed_password, $fullname);
|
||||||
|
|
||||||
|
if ($stmt->execute()) {
|
||||||
|
echo json_encode(array("status" => "success", "message" => "Registration successful."));
|
||||||
|
} else {
|
||||||
|
echo json_encode(array("status" => "error", "message" => "Registration failed."));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close connections
|
||||||
|
$stmt->close();
|
||||||
|
$conn->close();
|
|
@ -0,0 +1,48 @@
|
||||||
|
<?php
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
// Database connection
|
||||||
|
$host = 'localhost';
|
||||||
|
$db = 'tugas_akhir';
|
||||||
|
$user = 'root';
|
||||||
|
$pass = '';
|
||||||
|
|
||||||
|
$conn = new mysqli($host, $user, $pass, $db);
|
||||||
|
|
||||||
|
if ($conn->connect_error) {
|
||||||
|
die("Connection failed: " . $conn->connect_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get JSON input
|
||||||
|
$input = file_get_contents('php://input');
|
||||||
|
$data = json_decode($input, true);
|
||||||
|
|
||||||
|
$topic = $data['topic'];
|
||||||
|
$value = $data['value'];
|
||||||
|
$speed = isset($data['speed']) ? $data['speed'] : null;
|
||||||
|
|
||||||
|
if ($topic == 'sensor/waterflow1') {
|
||||||
|
$stmt = $conn->prepare("INSERT INTO tb_waterflow1 (timestamp, waterflow1_value, waterflow1_speed) VALUES (NOW(), ?, ?)");
|
||||||
|
$stmt->bind_param("dd", $value, $speed);
|
||||||
|
} else if ($topic == 'sensor/waterflow2') {
|
||||||
|
$stmt = $conn->prepare("INSERT INTO tb_waterflow2 (timestamp, waterflow2_value, waterflow2_speed) VALUES (NOW(), ?, ?)");
|
||||||
|
$stmt->bind_param("dd", $value, $speed);
|
||||||
|
} else if ($topic == 'sensor/tds') {
|
||||||
|
$stmt = $conn->prepare("INSERT INTO tb_ppm (timestamp, ppm_value) VALUES (NOW(), ?)");
|
||||||
|
$stmt->bind_param("d", $value);
|
||||||
|
} else if ($topic == 'sensor/ultrasonic') {
|
||||||
|
$stmt = $conn->prepare("INSERT INTO tb_waterlevel (timestamp, ultrasonic_value) VALUES (NOW(), ?)");
|
||||||
|
$stmt->bind_param("d", $value);
|
||||||
|
} else {
|
||||||
|
echo json_encode(["status" => "error", "message" => "Unknown topic"]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($stmt->execute()) {
|
||||||
|
echo json_encode(["status" => "success"]);
|
||||||
|
} else {
|
||||||
|
echo json_encode(["status" => "error", "message" => $stmt->error]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt->close();
|
||||||
|
$conn->close();
|