tambah data yg hilang
This commit is contained in:
parent
c44202b92e
commit
22ed13bf4c
|
|
@ -4,6 +4,7 @@ import 'package:http/http.dart' as http;
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import '../main.dart'; // Mengarah ke MainNavigation di main.dart
|
import '../main.dart'; // Mengarah ke MainNavigation di main.dart
|
||||||
import 'register_screen.dart';
|
import 'register_screen.dart';
|
||||||
|
import '../utils/api_config.dart';
|
||||||
|
|
||||||
class LoginScreen extends StatefulWidget {
|
class LoginScreen extends StatefulWidget {
|
||||||
const LoginScreen({super.key});
|
const LoginScreen({super.key});
|
||||||
|
|
@ -35,7 +36,7 @@ class _LoginScreenState extends State<LoginScreen> {
|
||||||
try {
|
try {
|
||||||
final response = await http
|
final response = await http
|
||||||
.post(
|
.post(
|
||||||
Uri.parse('https://gobony-wedgy-cathi.ngrok-free.dev/api/mobile/login'),
|
Uri.parse('${ApiConfig.apiRoot}/mobile/login'),
|
||||||
headers: {
|
headers: {
|
||||||
'Accept': 'application/json',
|
'Accept': 'application/json',
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
|
@ -45,7 +46,7 @@ class _LoginScreenState extends State<LoginScreen> {
|
||||||
'password': password,
|
'password': password,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.timeout(const Duration(seconds: 15));
|
.timeout(const Duration(seconds: 30));
|
||||||
|
|
||||||
if (response.statusCode != 200) {
|
if (response.statusCode != 200) {
|
||||||
throw Exception('Login gagal');
|
throw Exception('Login gagal');
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
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 'dart:convert';
|
import 'dart:convert';
|
||||||
// import 'login_screen.dart'; // Nanti ini dipakai untuk kembali ke halaman login
|
import '../utils/api_config.dart';
|
||||||
|
|
||||||
class RegisterScreen extends StatefulWidget {
|
class RegisterScreen extends StatefulWidget {
|
||||||
const RegisterScreen({super.key});
|
const RegisterScreen({super.key});
|
||||||
|
|
@ -45,7 +45,7 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
||||||
try {
|
try {
|
||||||
final response = await http
|
final response = await http
|
||||||
.post(
|
.post(
|
||||||
Uri.parse('https://gobony-wedgy-cathi.ngrok-free.dev/api/mobile/register'),
|
Uri.parse('${ApiConfig.apiRoot}/mobile/register'),
|
||||||
headers: {
|
headers: {
|
||||||
'Accept': 'application/json',
|
'Accept': 'application/json',
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
|
@ -56,7 +56,7 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
||||||
'password_confirmation': confirmPassword,
|
'password_confirmation': confirmPassword,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.timeout(const Duration(seconds: 15));
|
.timeout(const Duration(seconds: 30));
|
||||||
|
|
||||||
if (response.statusCode != 201) {
|
if (response.statusCode != 201) {
|
||||||
final jsonResponse = jsonDecode(response.body);
|
final jsonResponse = jsonDecode(response.body);
|
||||||
|
|
|
||||||
|
|
@ -213,7 +213,7 @@ class ClassificationService {
|
||||||
Uri.parse('$_historyUrl?page=$page&per_page=1000$userParam'),
|
Uri.parse('$_historyUrl?page=$page&per_page=1000$userParam'),
|
||||||
headers: {'Accept': 'application/json'},
|
headers: {'Accept': 'application/json'},
|
||||||
)
|
)
|
||||||
.timeout(const Duration(seconds: 15));
|
.timeout(const Duration(seconds: 30));
|
||||||
|
|
||||||
if (response.statusCode != 200) {
|
if (response.statusCode != 200) {
|
||||||
throw Exception('Gagal mengambil riwayat');
|
throw Exception('Gagal mengambil riwayat');
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
|
import '../utils/api_config.dart';
|
||||||
|
|
||||||
class ProductItem {
|
class ProductItem {
|
||||||
final int id;
|
final int id;
|
||||||
|
|
@ -44,7 +45,7 @@ class ProductItem {
|
||||||
|
|
||||||
class ProductService {
|
class ProductService {
|
||||||
// Samakan dengan API root di classification_service.dart
|
// Samakan dengan API root di classification_service.dart
|
||||||
static const String _apiRoot = 'https://gobony-wedgy-cathi.ngrok-free.dev/api';
|
static const String _apiRoot = ApiConfig.apiRoot;
|
||||||
static const String _productsUrl = '$_apiRoot/products';
|
static const String _productsUrl = '$_apiRoot/products';
|
||||||
|
|
||||||
final http.Client _httpClient;
|
final http.Client _httpClient;
|
||||||
|
|
@ -55,7 +56,7 @@ class ProductService {
|
||||||
try {
|
try {
|
||||||
final response = await _httpClient
|
final response = await _httpClient
|
||||||
.get(Uri.parse(_productsUrl), headers: {'Accept': 'application/json'})
|
.get(Uri.parse(_productsUrl), headers: {'Accept': 'application/json'})
|
||||||
.timeout(const Duration(seconds: 15));
|
.timeout(const Duration(seconds: 30));
|
||||||
|
|
||||||
if (response.statusCode != 200) {
|
if (response.statusCode != 200) {
|
||||||
throw Exception('Gagal mengambil produk');
|
throw Exception('Gagal mengambil produk');
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
class ApiConfig {
|
||||||
|
// Ganti URL ini jika ngrok Anda di-restart atau jika menggunakan IP server lokal
|
||||||
|
// Contoh Ngrok: 'https://YOUR_SUBDOMAIN.ngrok-free.dev/api'
|
||||||
|
// Contoh IP Lokal (WiFi): 'http://192.168.1.16:8000/api'
|
||||||
|
static const String apiRoot = 'https://gobony-wedgy-cathi.ngrok-free.dev/api';
|
||||||
|
}
|
||||||
|
|
@ -159,17 +159,72 @@ public function classifyAndSave(Request $request)
|
||||||
|
|
||||||
$diseaseInfo = $this->getDiseaseInfo($result['predicted_class']);
|
$diseaseInfo = $this->getDiseaseInfo($result['predicted_class']);
|
||||||
|
|
||||||
// Skip database save for now - just return prediction result
|
// Extract location components
|
||||||
|
$locationAddress = $request->input('location_address');
|
||||||
|
$locationLat = $request->input('location_lat');
|
||||||
|
$locationLng = $request->input('location_lng');
|
||||||
|
$kabupaten = $request->input('kabupaten');
|
||||||
|
$kecamatan = $request->input('kecamatan');
|
||||||
|
$kelurahan = $request->input('kelurahan');
|
||||||
|
|
||||||
|
// Fallback parsing if address is provided but components are missing
|
||||||
|
if ($locationAddress && (!$kabupaten || !$kecamatan || !$kelurahan)) {
|
||||||
|
$parsedLoc = $this->extractLocationComponents($locationAddress, $locationLat, $locationLng);
|
||||||
|
$kabupaten = $kabupaten ?: $parsedLoc['kabupaten'];
|
||||||
|
$kecamatan = $kecamatan ?: $parsedLoc['kecamatan'];
|
||||||
|
$kelurahan = $kelurahan ?: $parsedLoc['kelurahan'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simpan ke database Model Classification (untuk riwayat di mobile)
|
||||||
|
$classification = Classification::create([
|
||||||
|
'user_id' => $request->input('user_id'),
|
||||||
|
'image_path' => $storagePath,
|
||||||
|
'filename' => $file->getClientOriginalName(),
|
||||||
|
'predicted_class' => $result['predicted_class'],
|
||||||
|
'confidence' => (float) $result['confidence'],
|
||||||
|
'all_predictions' => $result['all_predictions'],
|
||||||
|
'disease_name' => $diseaseInfo['name'] ?? null,
|
||||||
|
'severity' => $diseaseInfo['severity'] ?? null,
|
||||||
|
'notes' => $request->input('notes'),
|
||||||
|
'location_address' => $locationAddress,
|
||||||
|
'location_lat' => $locationLat,
|
||||||
|
'location_lng' => $locationLng,
|
||||||
|
'kabupaten' => $kabupaten,
|
||||||
|
'kecamatan' => $kecamatan,
|
||||||
|
'kelurahan' => $kelurahan,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Simpan ke database Model ClassificationHistory (untuk riwayat di web admin)
|
||||||
|
if ($request->filled('user_id')) {
|
||||||
|
ClassificationHistory::create([
|
||||||
|
'user_id' => $request->input('user_id'),
|
||||||
|
'jenis_penyakit' => $diseaseInfo['name'] ?? $result['predicted_class'],
|
||||||
|
'location_address' => $locationAddress,
|
||||||
|
'location_lat' => $locationLat,
|
||||||
|
'location_lng' => $locationLng,
|
||||||
|
'kabupaten' => $kabupaten,
|
||||||
|
'kecamatan' => $kecamatan,
|
||||||
|
'kelurahan' => $kelurahan,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'success' => true,
|
'success' => true,
|
||||||
'message' => 'Gambar berhasil diklasifikasi dan disimpan',
|
'message' => 'Gambar berhasil diklasifikasi dan disimpan',
|
||||||
'data' => [
|
'data' => [
|
||||||
|
'id' => $classification->id,
|
||||||
'image_path' => Storage::url($storagePath),
|
'image_path' => Storage::url($storagePath),
|
||||||
'predicted_class' => $result['predicted_class'],
|
'predicted_class' => $result['predicted_class'],
|
||||||
'confidence' => round($result['confidence'] * 100, 2) . '%',
|
'confidence' => round($result['confidence'] * 100, 2) . '%',
|
||||||
'confidence_value' => $result['confidence'],
|
'confidence_value' => $result['confidence'],
|
||||||
'all_predictions' => $result['all_predictions'],
|
'all_predictions' => $result['all_predictions'],
|
||||||
'disease_info' => $diseaseInfo,
|
'disease_info' => $diseaseInfo,
|
||||||
|
'location_address' => $classification->location_address,
|
||||||
|
'location_lat' => $classification->location_lat,
|
||||||
|
'location_lng' => $classification->location_lng,
|
||||||
|
'kabupaten' => $classification->kabupaten,
|
||||||
|
'kecamatan' => $classification->kecamatan,
|
||||||
|
'kelurahan' => $classification->kelurahan,
|
||||||
'timestamp' => now(),
|
'timestamp' => now(),
|
||||||
]
|
]
|
||||||
], 200);
|
], 200);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue