another commit

This commit is contained in:
kicap1992
2022-06-08 06:03:46 +08:00
commit 330bfdeadb
60 changed files with 9627 additions and 0 deletions

56
.gitignore vendored Normal file
View File

@ -0,0 +1,56 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
/build/
ios/
android/
linux/
macos/
windows/
web/
# Web related
lib/generated_plugin_registrant.dart
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
# ignore globals.dart and AndroidManifest.xml
lib/globals.dart
android/**/*AndroidManifest.xml

10
.metadata Normal file
View File

@ -0,0 +1,10 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: fdd0af78bbda27e1084ec859b27765d927cbe27e
channel: beta
project_type: app

2
README.md Normal file
View File

@ -0,0 +1,2 @@
# kurir mobile app

29
analysis_options.yaml Normal file
View File

@ -0,0 +1,29 @@
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at
# https://dart-lang.github.io/linter/lints/index.html.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options

BIN
assets/loading.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
assets/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

354
lib/api/beforeLoginAPI.dart Normal file
View File

@ -0,0 +1,354 @@
// ignore_for_file: file_names, non_constant_identifier_names
import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get_storage/get_storage.dart';
import 'package:http/http.dart' as http;
import '../globals.dart' as globals;
class BeforeLoginApi extends ChangeNotifier {
// class BeforeLoginApi {
static var client = http.Client();
static var storage = GetStorage();
static clientClose(http.Client client) {
client.close();
}
// sign up kurir
static Future<Map<String, dynamic>> sign_up_kurir(Map data, String fotoKTP,
String fotoHoldingKTP, String fotoKendaraan, String fotoProfil) async {
Map<String, dynamic> result;
client = http.Client();
// result = "sini berlakunya signup";
bool _cek_jaringan = await cek_jaringan(client);
if (_cek_jaringan) {
try {
await EasyLoading.show(
status: 'Melakukan\nPendaftaran...',
maskType: EasyLoadingMaskType.black,
);
var postUri = Uri.parse('${globals.http_to_server}api/login/daftar1');
var request = http.MultipartRequest("POST", postUri);
request.fields['data'] = jsonEncode(data);
request.files
.add(await http.MultipartFile.fromPath('ktp_photo', fotoKTP));
request.files.add(await http.MultipartFile.fromPath(
'ktp_holding_photo', fotoHoldingKTP));
request.files.add(await http.MultipartFile.fromPath(
'kenderaan_photo', fotoKendaraan));
request.files
.add(await http.MultipartFile.fromPath('photo', fotoProfil));
var streamResponse =
await request.send().timeout(const Duration(seconds: 30));
// var streamResponse = await request.send();
var response = await http.Response.fromStream(streamResponse);
var datanya = jsonDecode(response.body);
log(response.statusCode.toString() + " ini status code");
log(datanya.toString());
if (response.statusCode == 200) {
result = {
'status': response.statusCode,
'message': datanya['message'],
};
} else {
result = {
'status': response.statusCode,
'message': datanya['message']
};
}
} on SocketException catch (e) {
// abort the client
await EasyLoading.dismiss();
// closeClient();
log(e.toString() + " ini error socket");
result = {
'status': 500,
'message': "Tidak dapat terhubung ke server,koneksi timeout"
};
} on TimeoutException catch (e) {
// client.close();
log(e.toString() + " ini timeout");
result = {
'status': 500,
'message': "Tidak dapat terhubung ke server,koneksi timeout"
};
} catch (e) {
log(e.toString() + " ini di catch");
result = {
'status': 500,
'message': "Tidak dapat terhubung ke server,koneksi timeout"
};
}
} else {
result = {
'status': 500,
'message': "Tidak dapat terhubung ke server,koneksi timeout"
};
}
return result;
}
// sign up pengirim
static Future<Map<String, dynamic>> sign_up_pengirim(
Map data, String fotoProfil) async {
// open client
client = http.Client();
Map<String, dynamic> result;
// result = {'status': 500, 'message': "sini berlakunya signup pengirim"};
bool _cek_jaringan = await cek_jaringan(client);
log("cek jaringan : " + _cek_jaringan.toString());
if (!_cek_jaringan) {
result = {
'status': 500,
'message':
"Tidak dapat terhubung ke server, Sila periksa koneksi internet anda"
};
} else {
if (_cek_jaringan) {
try {
await EasyLoading.show(
status: 'Melakukan\nPendaftaran...',
maskType: EasyLoadingMaskType.black,
);
var postUri = Uri.parse('${globals.http_to_server}api/login/daftar1');
var request = http.MultipartRequest("POST", postUri);
request.fields['data'] = jsonEncode(data);
request.files
.add(await http.MultipartFile.fromPath('photo', fotoProfil));
var streamResponse =
await request.send().timeout(const Duration(seconds: 30));
// var streamResponse = await request.send();
var response = await http.Response.fromStream(streamResponse);
var datanya = jsonDecode(response.body);
log(response.statusCode.toString() + " ini status code");
log(datanya.toString());
if (response.statusCode == 200) {
result = {
'status': response.statusCode,
'message': datanya['message'],
};
} else {
result = {
'status': response.statusCode,
'message': datanya['message']
};
}
} on SocketException catch (e) {
// abort the client
await EasyLoading.dismiss();
// closeClient();
log(e.toString() + " ini error socket");
result = {
'status': 500,
'message': "Tidak dapat terhubung ke server,koneksi timeout"
};
} on TimeoutException catch (e) {
// client.close();
log(e.toString() + " ini timeout");
result = {
'status': 500,
'message': "Tidak dapat terhubung ke server,koneksi timeout"
};
} catch (e) {
log(e.toString() + " ini di catch");
result = {
'status': 500,
'message': "Tidak dapat terhubung ke server,koneksi timeout"
};
}
} else {
result = {
'status': 500,
'message': "Tidak dapat terhubung ke server,koneksi timeout"
};
}
}
return result;
}
// log in user
static Future<Map<String, dynamic>> log_in_user(
String username, String password, String role) async {
client = http.Client();
late Map<String, dynamic> result;
bool _cek_jaringan = await cek_jaringan(client);
log("cek jaringan : " + _cek_jaringan.toString());
if (!_cek_jaringan) {
result = {
'status': 500,
'message':
"Tidak dapat terhubung ke server, Sila periksa koneksi internet anda"
};
} else {
// wait for 3 sec
try {
await EasyLoading.show(
status: 'Sedang\nLogin\n...',
maskType: EasyLoadingMaskType.black,
);
var _url = Uri.parse(
'${globals.http_to_server}api/login?username=$username&password=$password&role=$role');
var _response = await http.get(
_url,
// body: {'username': username, 'password': password, 'role': role},
headers: {
"Accept": "application/json",
// "authorization":
// "Basic ${base64Encode(utf8.encode("Kicap_karan:bb10c6d9f01ec0cb16726b59e36c2f73"))}",
"crossDomain": "true"
},
);
var _data = jsonDecode(_response.body);
log(_response.statusCode.toString() + " ini status code");
log(_data['data']['_idnya'].toString() + " ini id");
if (_response.statusCode == 200) {
storage.write('username', username);
storage.write('password', password);
storage.write('role', role);
storage.write('id', _data['data']['_idnya']);
result = {
'status': _response.statusCode,
'message': _data['message'],
'focus': _data['data'],
};
} else {
storage.remove('username');
storage.remove('password');
storage.remove('role');
result = {
'status': _response.statusCode,
'message': _data['message'],
'focus': _data['data'],
};
}
} catch (e) {
storage.erase();
log(e.toString() + " ini di catch");
result = {
'status': 500,
'message': "Tidak dapat terhubung ke server,koneksi timeout"
};
}
}
return result;
}
// logout user
static Future<void> logout() async {
storage.remove('username');
storage.remove('password');
storage.remove('role');
storage.remove('id');
}
// checking connection to server
static Future<bool> cek_jaringan(http.Client client) async {
late bool result;
// client get for globals.http_to_server
try {
var response =
await client.get(Uri.parse("${globals.http_to_server}api"), headers: {
"Accept": "application/json",
// "authorization":
// "Basic ${base64Encode(utf8.encode("Kicap_karan:bb10c6d9f01ec0cb16726b59e36c2f73"))}",
"crossDomain": "true"
}).timeout(const Duration(seconds: 10));
// final data = jsonDecode(response.body);
if (response.statusCode == 200) {
result = true;
} else {
result = false;
}
} on SocketException {
await EasyLoading.dismiss();
result = false;
await clientClose(client);
log(" ini error socket");
} on TimeoutException {
await EasyLoading.dismiss();
result = false;
// close client
await clientClose(client);
log(" ini timeout");
} on Exception {
result = false;
log(" ini timeout");
} catch (e) {
result = false;
log(" ini timeout");
}
return result;
}
// // checking connection to server
// Future<bool> cek_jaringan1(http.Client client) async {
// late bool result;
// // client get for globals.http_to_server
// try {
// var response =
// await client.get(Uri.parse("${globals.http_to_server}api"), headers: {
// "Accept": "application/json",
// // "authorization":
// // "Basic ${base64Encode(utf8.encode("Kicap_karan:bb10c6d9f01ec0cb16726b59e36c2f73"))}",
// "crossDomain": "true"
// }).timeout(const Duration(seconds: 5));
// // final data = jsonDecode(response.body);
// if (response.statusCode == 200) {
// result = true;
// } else {
// result = false;
// }
// } on SocketException {
// await EasyLoading.dismiss();
// result = false;
// await clientClose(client);
// log(" ini error socket");
// } on TimeoutException {
// await EasyLoading.dismiss();
// result = false;
// // close client
// await clientClose(client);
// log(" ini timeout");
// } on Exception {
// result = false;
// log(" ini timeout");
// } catch (e) {
// result = false;
// log(" ini timeout");
// }
// return result;
// }
}

186
lib/api/kurirApi.dart Normal file
View File

@ -0,0 +1,186 @@
// ignore_for_file: non_constant_identifier_names, file_names
import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import 'dart:io';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get_storage/get_storage.dart';
import 'package:http/http.dart' as http;
import '../globals.dart' as globals;
class KurirApi {
static var client = http.Client();
static clientClose(http.Client client) {
client.close();
}
// cek pengaturan kurir
static Future<Map<String, dynamic>> cekPengaturanKurir() async {
client = http.Client();
late Map<String, dynamic> result;
bool _cek_jaringan = await cek_jaringan(client);
log("cek jaringan : " + _cek_jaringan.toString());
var storage = GetStorage();
var username = storage.read("username");
var password = storage.read("password");
var id = storage.read("id");
if (!_cek_jaringan) {
result = {
'status': 500,
'message':
"Tidak dapat terhubung ke server, Sila periksa koneksi internet anda"
};
} else {
// wait for 3 sec
// await Future.delayed(Duration(seconds: 3));
// result = {'status': 200, 'message': "sini dia"};
try {
log("${globals.http_to_server}api/kurir/pengaturan?username=$username&password=$password&id=$id");
var response = await client.get(
Uri.parse(
"${globals.http_to_server}api/kurir/pengaturan?username=$username&password=$password&id=$id"),
headers: {
"Accept": "application/json",
// "authorization":
// "Basic ${base64Encode(utf8.encode("Kicap_karan:bb10c6d9f01ec0cb16726b59e36c2f73"))}",
"crossDomain": "true"
}).timeout(const Duration(seconds: 10));
final data = jsonDecode(response.body);
log(data.toString());
log("ini status : " + response.statusCode.toString());
if (response.statusCode == 200) {
result = {
'status': 200,
'message': data['message'],
'data': data['data']
};
} else {
result = {
'status': 500,
'message': "Gagal mengatur biaya pengiriman",
'data': data
};
}
} catch (e) {
result = {
'status': 500,
'message':
"Tidak dapat terhubung ke server, Sila periksa koneksi internet anda"
};
}
}
return result;
}
// tambah/edit pengaturan kurir
static Future<Map<String, dynamic>> pengaturanKurir(
String minimalBiaya, String maksimalBiaya, String biayaPerKilo) async {
client = http.Client();
late Map<String, dynamic> result;
bool _cek_jaringan = await cek_jaringan(client);
log("cek jaringan : " + _cek_jaringan.toString());
var storage = GetStorage();
var username = storage.read("username");
var password = storage.read("password");
var id = storage.read("id");
if (!_cek_jaringan) {
result = {
'status': 500,
'message':
"Tidak dapat terhubung ke server, Sila periksa koneksi internet anda"
};
} else {
// wait for 3 sec
// await Future.delayed(Duration(seconds: 3));
// result = {'status': 200, 'message': "sini dia"};
try {
var response = await client.post(
Uri.parse(
"${globals.http_to_server}api/kurir/pengaturan?username=$username&password=$password&id=$id"),
headers: {
"Accept": "application/json",
// "authorization":
// "Basic ${base64Encode(utf8.encode("Kicap_karan:bb10c6d9f01ec0cb16726b59e36c2f73"))}",
"crossDomain": "true"
},
body: {
"minimal_biaya_pengiriman": minimalBiaya,
"maksimal_biaya_pengiriman": maksimalBiaya,
"biaya_per_kilo": biayaPerKilo
}).timeout(const Duration(seconds: 10));
final data = jsonDecode(response.body);
log(data.toString());
log("ini status : " + response.statusCode.toString());
if (response.statusCode == 200) {
result = {'status': 200, 'message': data['message'], 'data': data};
} else {
result = {
'status': 500,
'message': "Gagal mengatur biaya pengiriman",
'data': data
};
}
} catch (e) {
result = {
'status': 500,
'message':
"Tidak dapat terhubung ke server, Sila periksa koneksi internet anda"
};
}
}
return result;
}
// checking connection to server
static Future<bool> cek_jaringan(http.Client client) async {
late bool result;
// client get for globals.http_to_server
try {
var response =
await client.get(Uri.parse("${globals.http_to_server}api"), headers: {
"Accept": "application/json",
// "authorization":
// "Basic ${base64Encode(utf8.encode("Kicap_karan:bb10c6d9f01ec0cb16726b59e36c2f73"))}",
"crossDomain": "true"
}).timeout(const Duration(seconds: 10));
// final data = jsonDecode(response.body);
if (response.statusCode == 200) {
result = true;
} else {
result = false;
}
} on SocketException {
await EasyLoading.dismiss();
result = false;
await clientClose(client);
log(" ini error socket");
} on TimeoutException {
await EasyLoading.dismiss();
result = false;
// close client
await clientClose(client);
log(" ini timeout");
} on Exception {
result = false;
log(" ini timeout");
} catch (e) {
result = false;
log(" ini timeout");
}
return result;
}
}

393
lib/api/pengirimApi.dart Normal file
View File

@ -0,0 +1,393 @@
// ignore_for_file: non_constant_identifier_names, file_names
import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import 'dart:io';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get_storage/get_storage.dart';
import 'package:http/http.dart' as http;
import '../globals.dart' as globals;
class PengirimApi {
static var client = http.Client();
static var storage = GetStorage();
static var username = storage.read("username");
static var password = storage.read("password");
static var id = storage.read("id");
static clientClose(http.Client client) {
client.close();
}
// get all kurir
static Future<Map<String, dynamic>> getAllKurir() async {
client = http.Client();
late Map<String, dynamic> result;
bool _cek_jaringan = await cek_jaringan(client);
// log("cek jaringan : " + _cek_jaringan.toString());
if (!_cek_jaringan) {
result = {
'status': 500,
'message':
"Tidak dapat terhubung ke server, Sila periksa koneksi internet anda"
};
} else {
// wait for 3 sec
// await Future.delayed(Duration(seconds: 3));
// result = {'status': 200, 'message': "sini dia"};
try {
var response = await client.get(
Uri.parse(
"${globals.http_to_server}api/pengirim/kurir?username=$username&password=$password&id=$id"),
headers: {
"Accept": "application/json",
// "authorization":
// "Basic ${base64Encode(utf8.encode("Kicap_karan:bb10c6d9f01ec0cb16726b59e36c2f73"))}",
"crossDomain": "true"
}).timeout(const Duration(seconds: 10));
final data = jsonDecode(response.body);
// log(data.toString());
// log("ini status : " + response.statusCode.toString());
if (response.statusCode == 200) {
result = {
'status': 200,
'message': data['message'],
'data': data['data']
};
} else {
result = {
'status': 500,
'message': "Gagal mengatur biaya pengiriman",
'data': data
};
}
} catch (e) {
result = {
'status': 500,
'message':
"Tidak dapat terhubung ke server, Sila periksa koneksi internet anda"
};
}
}
return result;
}
// get kurir by nama
static Future<Map<String, dynamic>> getKurirByNama(String nama) async {
client = http.Client();
late Map<String, dynamic> result;
bool _cek_jaringan = await cek_jaringan(client);
// log("cek jaringan : " + _cek_jaringan.toString());
if (!_cek_jaringan) {
result = {
'status': 500,
'message':
"Tidak dapat terhubung ke server, Sila periksa koneksi internet anda"
};
} else {
// wait for 3 sec
// await Future.delayed(Duration(seconds: 3));
// result = {'status': 200, 'message': "sini dia"};
try {
var response = await client.get(
Uri.parse(
"${globals.http_to_server}api/pengirim/kurir/nama?nama=$nama&username=$username&password=$password&id=$id"),
headers: {
"Accept": "application/json",
// "authorization":
// "Basic ${base64Encode(utf8.encode("Kicap_karan:bb10c6d9f01ec0cb16726b59e36c2f73"))}",
"crossDomain": "true"
}).timeout(const Duration(seconds: 10));
final data = jsonDecode(response.body);
// log(data.toString());
// log("ini status : " + response.statusCode.toString());
if (response.statusCode == 200) {
result = {
'status': 200,
'message': data['message'],
'data': data['data']
};
} else {
result = {
'status': 500,
'message': "Gagal mengatur biaya pengiriman",
'data': data
};
}
} catch (e) {
result = {
'status': 500,
'message':
"Tidak dapat terhubung ke server, Sila periksa koneksi internet anda"
};
}
}
return result;
}
// get kurir by nama
static Future<Map<String, dynamic>> getKurirByFilter(
String? nama, int? biayaMaksimal, int? biayaPerKm) async {
client = http.Client();
late Map<String, dynamic> result;
bool _cek_jaringan = await cek_jaringan(client);
// log("cek jaringan : " + _cek_jaringan.toString());
if (!_cek_jaringan) {
result = {
'status': 500,
'message':
"Tidak dapat terhubung ke server, Sila periksa koneksi internet anda"
};
} else {
// wait for 3 sec
// await Future.delayed(Duration(seconds: 3));
// result = {'status': 200, 'message': "sini dia"};
try {
String _nama = nama ?? "";
String _biayaMaksimal = biayaMaksimal?.toString() ?? "";
String _biayaPerKm = biayaPerKm?.toString() ?? "";
var response = await client.get(
Uri.parse(
"${globals.http_to_server}api/pengirim/kurir/filter?nama=$_nama&biaya_maksimal=$_biayaMaksimal&biaya_per_km=$_biayaPerKm&username=$username&password=$password&id=$id"),
headers: {
"Accept": "application/json",
// "authorization":
// "Basic ${base64Encode(utf8.encode("Kicap_karan:bb10c6d9f01ec0cb16726b59e36c2f73"))}",
"crossDomain": "true"
}).timeout(const Duration(seconds: 10));
final data = jsonDecode(response.body);
// log(data.toString());
// log("ini status : " + response.statusCode.toString());
if (response.statusCode == 200) {
result = {
'status': 200,
'message': data['message'],
'data': data['data']
};
} else {
result = {
'status': 500,
'message': "Gagal mengatur biaya pengiriman",
'data': data
};
}
} catch (e) {
result = {
'status': 500,
'message':
"Tidak dapat terhubung ke server, Sila periksa koneksi internet anda"
};
}
}
return result;
}
// post create pengiriman barang
static Future<Map<String, dynamic>> createPengirimanBarang(
Map<String, dynamic> _datanya) async {
client = http.Client();
late Map<String, dynamic> result;
bool _cek_jaringan = await cek_jaringan(client);
// log("cek jaringan : " + _cek_jaringan.toString());
if (!_cek_jaringan) {
result = {
'status': 500,
'message':
"Tidak dapat terhubung ke server, Sila periksa koneksi internet anda"
};
} else {
try {
String foto_path = _datanya['foto_path'];
// log(foto_path.toString() + " ini datanya di pengiriman barang");
// remove foto_path from _datanya
_datanya.remove('foto_path');
log(_datanya.toString());
var postUri = Uri.parse(
'${globals.http_to_server}api/pengirim/pengiriman_barang?username=$username&password=$password&id=$id');
var request = http.MultipartRequest("POST", postUri);
request.fields['data'] = jsonEncode(_datanya);
request.files.add(
await http.MultipartFile.fromPath('foto_pengiriman', foto_path));
var streamResponse =
await request.send().timeout(const Duration(seconds: 30));
// var streamResponse = await request.send();
var response = await http.Response.fromStream(streamResponse);
var datanya = jsonDecode(response.body);
log(datanya.toString() + " ini datanya di pengiriman barang");
result = {
'status': 200,
'message': datanya['message'],
};
} catch (e) {
log(e.toString() + " ini error");
result = {'status': 500, 'message': e.toString()};
}
}
return result;
}
// get log Kiriman
static Future<Map<String, dynamic>> getLogKiriman() async {
client = http.Client();
late Map<String, dynamic> result;
bool _cek_jaringan = await cek_jaringan(client);
// log("cek jaringan : " + _cek_jaringan.toString());
if (!_cek_jaringan) {
result = {
'status': 500,
'message':
"Tidak dapat terhubung ke server, Sila periksa koneksi internet anda"
};
} else {
// wait for 3 sec
// await Future.delayed(Duration(seconds: 3));
// result = {'status': 200, 'message': "sini dia"};
try {
var response = await client.get(
Uri.parse(
"${globals.http_to_server}api/pengirim/log_kiriman?username=$username&password=$password&id=$id"),
headers: {
"Accept": "application/json",
// "authorization":
// "Basic ${base64Encode(utf8.encode("Kicap_karan:bb10c6d9f01ec0cb16726b59e36c2f73"))}",
"crossDomain": "true"
}).timeout(const Duration(seconds: 10));
final data = jsonDecode(response.body);
// log(data.toString());
if (response.statusCode == 200) {
result = {
'status': 200,
'message': "Berhasil mendapatkan log kiriman",
'data': data['data']
};
} else {
result = {
'status': 500,
'message': "Gagal mengambil data log kiriman",
'data': data
};
}
} catch (e) {
log(e.toString() + " ini error");
result = {
'status': 500,
'message':
"Tidak dapat terhubung ke server, Sila periksa koneksi internet anda"
};
}
}
return result;
}
static Future<double> jarak_route(
double lat1, double lng1, double lat2, double lng2) async {
client = http.Client();
double jarak = 0;
bool _cek_jaringan = await cek_jaringan(client);
// log("cek jaringan : " + _cek_jaringan.toString());
if (!_cek_jaringan) {
jarak = 0;
} else {
try {
var response = await client.get(
Uri.parse(
"https://maps.googleapis.com/maps/api/directions/json?origin=$lat1,$lng1&destination=$lat2,$lng2&key=${globals.api_key}"),
headers: {
"Accept": "application/json",
// "authorization":
// "Basic ${base64Encode(utf8.encode("Kicap_karan:bb10c6d9f01ec0cb16726b59e36c2f73"))}",
"crossDomain": "true"
}).timeout(const Duration(seconds: 10));
// log()
final data = jsonDecode(response.body);
if (data["routes"].length > 0) {
jarak = data["routes"][0]["legs"][0]["distance"]["value"] / 1000;
} else {
jarak = 0;
}
} catch (e) {
jarak = 0;
}
}
return jarak;
}
// checking connection to server
static Future<bool> cek_jaringan(http.Client client) async {
late bool result;
// client get for globals.http_to_server
try {
var response =
await client.get(Uri.parse("${globals.http_to_server}api"), headers: {
"Accept": "application/json",
// "authorization":
// "Basic ${base64Encode(utf8.encode("Kicap_karan:bb10c6d9f01ec0cb16726b59e36c2f73"))}",
"crossDomain": "true"
}).timeout(const Duration(seconds: 10));
// final data = jsonDecode(response.body);
if (response.statusCode == 200) {
result = true;
} else {
result = false;
}
} on SocketException {
await EasyLoading.dismiss();
result = false;
await clientClose(client);
log(" ini error socket");
} on TimeoutException {
await EasyLoading.dismiss();
result = false;
// close client
await clientClose(client);
log(" ini timeout");
} on Exception {
result = false;
log(" ini timeout");
} catch (e) {
result = false;
log(" ini timeout");
}
return result;
}
}

218
lib/api/petaApi.dart Normal file
View File

@ -0,0 +1,218 @@
// ignore_for_file: non_constant_identifier_names, file_names
import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import 'dart:io';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get_storage/get_storage.dart';
import 'package:http/http.dart' as http;
import '../globals.dart' as globals;
class PetaApi {
static var client = http.Client();
static var storage = GetStorage();
static var username = storage.read("username");
static var password = storage.read("password");
static var id = storage.read("id");
static clientClose(http.Client client) {
client.close();
}
// cek kecamatan_map
static Future<Map<String, dynamic>> cekKecamatan() async {
client = http.Client();
late Map<String, dynamic> result;
bool _cek_jaringan = await cek_jaringan(client);
log("cek jaringan : " + _cek_jaringan.toString());
if (!_cek_jaringan) {
result = {
'status': 500,
'message':
"Tidak dapat terhubung ke server, Sila periksa koneksi internet anda"
};
} else {
// wait for 3 sec
// await Future.delayed(Duration(seconds: 3));
// result = {'status': 200, 'message': "sini dia"};
try {
var response = await client.get(
Uri.parse("${globals.http_to_server}api/peta/kecamatan"),
headers: {
"Accept": "application/json",
// "authorization":
// "Basic ${base64Encode(utf8.encode("Kicap_karan:bb10c6d9f01ec0cb16726b59e36c2f73"))}",
"crossDomain": "true"
}).timeout(const Duration(seconds: 10));
final data = jsonDecode(response.body);
// log(data.toString());
// log("ini status : " + response.statusCode.toString());
if (response.statusCode == 200) {
result = {'status': 200, 'message': "sini dia", 'data': data['data']};
} else {
result = {
'status': 500,
'message':
"Tidak dapat terhubung ke server, Sila periksa koneksi internet anda"
};
}
} catch (e) {
result = {
'status': 500,
'message':
"Tidak dapat terhubung ke server, Sila periksa koneksi internet anda"
};
}
}
return result;
}
// cek kelurahan_desa_map
static Future<Map<String, dynamic>> cekKelurahanDesa() async {
client = http.Client();
late Map<String, dynamic> result;
bool _cek_jaringan = await cek_jaringan(client);
log("cek jaringan : " + _cek_jaringan.toString());
if (!_cek_jaringan) {
result = {
'status': 500,
'message':
"Tidak dapat terhubung ke server, Sila periksa koneksi internet anda"
};
} else {
try {
var response = await client.get(
Uri.parse("${globals.http_to_server}api/peta/kelurahan_desa"),
headers: {
"Accept": "application/json",
// "authorization":
// "Basic ${base64Encode(utf8.encode("Kicap_karan:bb10c6d9f01ec0cb16726b59e36c2f73"))}",
"crossDomain": "true"
}).timeout(const Duration(seconds: 10));
final data = jsonDecode(response.body);
// log(data.toString());
// log("ini status : " + response.statusCode.toString());
if (response.statusCode == 200) {
result = {'status': 200, 'message': "sini dia", 'data': data['data']};
} else {
result = {
'status': 500,
'message':
"Tidak dapat terhubung ke server, Sila periksa koneksi internet anda"
};
}
} catch (e) {
result = {
'status': 500,
'message':
"Tidak dapat terhubung ke server, Sila periksa koneksi internet anda"
};
}
}
return result;
}
// cek_kelurahan_desa_detail_map
static Future<Map<String, dynamic>> cekKelurahanDesaDetail(
String nama) async {
client = http.Client();
late Map<String, dynamic> result;
bool _cek_jaringan = await cek_jaringan(client);
log("cek jaringan : " + _cek_jaringan.toString());
if (!_cek_jaringan) {
result = {
'status': 500,
'message':
"Tidak dapat terhubung ke server, Sila periksa koneksi internet anda"
};
} else {
try {
var response = await client.get(
Uri.parse(
"${globals.http_to_server}api/peta/kelurahan_desa?kelurahan_desa=$nama"),
headers: {
"Accept": "application/json",
// "authorization":
// "Basic ${base64Encode(utf8.encode("Kicap_karan:bb10c6d9f01ec0cb16726b59e36c2f73"))}",
"crossDomain": "true"
}).timeout(const Duration(seconds: 10));
final data = jsonDecode(response.body);
// log(data.toString());
// log("ini status : " + response.statusCode.toString());
if (response.statusCode == 200) {
result = {'status': 200, 'message': "sini dia", 'data': data['data']};
} else {
result = {
'status': 500,
'message':
"Tidak dapat terhubung ke server, Sila periksa koneksi internet anda"
};
}
} catch (e) {
result = {
'status': 500,
'message':
"Tidak dapat terhubung ke server, Sila periksa koneksi internet anda"
};
}
}
return result;
}
// checking connection to server
static Future<bool> cek_jaringan(http.Client client) async {
late bool result;
// client get for globals.http_to_server
try {
var response =
await client.get(Uri.parse("${globals.http_to_server}api"), headers: {
"Accept": "application/json",
// "authorization":
// "Basic ${base64Encode(utf8.encode("Kicap_karan:bb10c6d9f01ec0cb16726b59e36c2f73"))}",
"crossDomain": "true"
}).timeout(const Duration(seconds: 10));
// final data = jsonDecode(response.body);
if (response.statusCode == 200) {
result = true;
} else {
result = false;
}
} on SocketException {
await EasyLoading.dismiss();
result = false;
await clientClose(client);
log(" ini error socket");
} on TimeoutException {
await EasyLoading.dismiss();
result = false;
// close client
await clientClose(client);
log(" ini timeout");
} on Exception {
result = false;
log(" ini timeout");
} catch (e) {
result = false;
log(" ini timeout");
}
return result;
}
}

View File

@ -0,0 +1,12 @@
// ignore_for_file: file_names
import 'package:get/get.dart';
import '../controller/after_login/beforeEnterController.dart';
class BeforeEnterBinding extends Bindings {
@override
void dependencies() {
Get.put(BeforeEnterController());
}
}

View File

@ -0,0 +1,15 @@
// ignore_for_file: file_names
import 'package:get/get.dart';
import 'package:kurir/controller/after_login/kurir/pengaturanController.dart';
import '../controller/after_login/kurir/indexController.dart';
class KurirIndexBinding extends Bindings {
@override
void dependencies() {
Get.lazyPut<KurirIndexController>(() => KurirIndexController());
Get.lazyPut<PengaturanKurirController>(() => PengaturanKurirController());
}
}

View File

@ -0,0 +1,13 @@
// ignore_for_file: file_names
import 'package:get/get.dart';
import 'package:kurir/controller/after_login/kurir/profileController.dart';
class KurirProfileBinding extends Bindings {
// KurirProfileBinding() : super(autoInit: false);
@override
void dependencies() {
Get.lazyPut<KurirProfileController>(() => KurirProfileController());
}
}

View File

@ -0,0 +1,13 @@
// ignore_for_file: file_names
import 'package:get/get.dart';
import '../controller/before_login/loginController.dart';
class LoginBinding extends Bindings {
@override
void dependencies() {
Get.put(LoginController());
// Get.lazyPut(() => LoginController(), fenix: true);
}
}

View File

@ -0,0 +1,12 @@
// ignore_for_file: file_names
import 'package:get/get.dart';
import '../controller/before_login/pendaftaranKurirController.dart';
class PendaftaranKurirBinding extends Bindings {
@override
void dependencies() {
Get.put(PendaftaranKurirController());
}
}

View File

@ -0,0 +1,12 @@
// ignore_for_file: file_names
import 'package:get/get.dart';
import '../controller/before_login/pendaftaranPengirimController.dart';
class PendaftaranPengirimBinding extends Bindings {
@override
void dependencies() {
Get.put(PendaftaranPengirimController());
}
}

View File

@ -0,0 +1,18 @@
// ignore_for_file: file_names
import 'package:get/get.dart';
import 'package:kurir/controller/after_login/pengirim/kirimBarangController.dart';
import 'package:kurir/controller/after_login/pengirim/logKirimanController.dart';
import '../controller/after_login/pengirim/indexController.dart';
class PengirimIndexBinding extends Bindings {
@override
void dependencies() {
Get.lazyPut<PengirimIndexController>(() => PengirimIndexController());
Get.lazyPut<KirimBarangController>(() => KirimBarangController());
Get.lazyPut<LogKirimanController>(() => LogKirimanController());
}
}

View File

@ -0,0 +1,12 @@
// ignore_for_file: file_names
import 'package:get/get.dart';
import '../controller/splashController.dart';
class SplashBinding extends Bindings {
@override
void dependencies() {
Get.put(SplashController());
}
}

View File

@ -0,0 +1,97 @@
// ignore_for_file: file_names, non_constant_identifier_names
import 'dart:developer';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import '../../api/beforeLoginAPI.dart';
class BeforeEnterController extends GetxController {
final storage = GetStorage();
@override
void onInit() async {
await EasyLoading.show(
status: 'Loading...',
maskType: EasyLoadingMaskType.black,
);
// wait 3 sec
// await Future.delayed(const Duration(seconds: 3));
// await EasyLoading.dismiss();
log("sini on init before enter");
cek_login();
// log(storage.read('role') + "ini role nya");
super.onInit();
}
void cek_login() async {
final _username =
(storage.read('username') != null) ? storage.read('username') : "";
final _password =
(storage.read('password') != null) ? storage.read('password') : "";
final _role = (storage.read('role') != null) ? storage.read('role') : "";
final _id = (storage.read('id') != null) ? storage.read('id') : "";
late bool _wrongPassword;
Map<String, dynamic> _data = await BeforeLoginApi.log_in_user(
_username, _password, _role.toLowerCase());
switch (_data['status']) {
case 200:
_wrongPassword = true;
break;
case 400:
_wrongPassword = false;
break;
default:
_wrongPassword = false;
break;
}
log(_username.toString() + " ini usernamenya");
log(_password.toString() + " ini passwordnya");
log(_role.toString() + " ini role nya");
log(_id.toString() + " ini id nya");
// await Future.delayed(const Duration(seconds: 3));
await EasyLoading.dismiss();
if (!_wrongPassword) {
storage.remove('username');
storage.remove('password');
storage.remove('role');
Get.offAllNamed(
'/index',
arguments: {
"tap": 0,
"history": [0],
},
);
return;
}
if (_role.toLowerCase() == "kurir") {
Get.offAllNamed(
'/kurirIndex',
);
return;
}
if (_role.toLowerCase() == "pengirim") {
Get.offAllNamed(
'pengirimIndex',
arguments: {
"tap": 1,
// "history": _historyIndex.value,
},
);
return;
}
}
}

View File

@ -0,0 +1,115 @@
// ignore_for_file: file_names
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:kurir/controller/after_login/kurir/pengaturanController.dart';
import 'package:socket_io_client/socket_io_client.dart';
class KurirIndexController extends GetxController {
late Socket socket;
final Rx<int> _indexTap = 0.obs; // bottom navigation index tap
PageController pageController =
PageController(initialPage: 0, keepPage: true);
pageChanged(int index) async {
_indexTap.value = index;
switch (index) {
case 0:
final ctrl = Get.put<PengaturanKurirController>(
PengaturanKurirController(),
);
ctrl.onInit();
// Get.put(PengaturanKurirController());
break;
default:
}
}
@override
void onInit() {
log('KurirIndexController onInit');
// final ctrl = Get.put(PengaturanKurirController());
// ctrl.onInit();
connectToServer();
super.onInit();
}
BottomNavigationBar bottomNavigationBar(context) {
return BottomNavigationBar(
type: BottomNavigationBarType.fixed,
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Pengaturan',
),
BottomNavigationBarItem(
icon: Icon(Icons.login),
label: 'Pengiriman',
),
BottomNavigationBarItem(
icon: Icon(Icons.app_registration),
label: 'Log History',
),
BottomNavigationBarItem(
icon: Icon(Icons.account_circle),
label: 'Profile',
),
],
currentIndex: _indexTap.value,
selectedItemColor: const Color.fromARGB(255, 148, 183, 229),
onTap: (index) => _onItemTapped(index, context),
);
}
_onItemTapped(int index, BuildContext context) {
log("sini on item tapped");
_indexTap.value = index;
if (index == 3) {
Get.offAllNamed('/profileKurir');
}
FocusScope.of(context).unfocus();
// Get.delete<PengaturanKurirController>();
pageController.animateToPage(index,
duration: const Duration(milliseconds: 300), curve: Curves.ease);
}
void connectToServer() async {
log("sini connect to socket io");
try {
// Configure socket transports must be sepecified
socket = io('http://192.168.43.125:3001/', <String, dynamic>{
'transports': ['websocket'],
'autoConnect': true,
});
// Connect to websocket
socket.connect();
socket.onConnect((_) {
log("sini connected");
// socket.emit('join', 'kurir');
});
// Connect to websocket
// socket.connect();
socket.on('connect', (_) => log('connect asdasdsad: ${socket.id}'));
socket.on('coba1', (_) => log(_.toString() + " ini coba2"));
log(socket.connected.toString());
} catch (e) {
log(e.toString());
log('tidak connect');
}
}
// onWillpop() async {
// log("ini onWillpop");
// return false;
// }
}

View File

@ -0,0 +1,114 @@
// ignore_for_file: file_names, non_constant_identifier_names
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import 'package:kurir/api/kurirApi.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:intl/intl.dart';
import 'package:kurir/models/kurirModel.dart';
class PengaturanKurirController extends GetxController {
final storage = GetStorage();
var formKey = GlobalKey<FormState>(); // for form validation
Rx<String> status = ''.obs;
final minimalBiayaPengirimanController = TextEditingController();
final maksimalBiayaPengirimanController = TextEditingController();
final biayaPerKiloController = TextEditingController();
final FocusNode minimalBiayaPengirimanFocusNode = FocusNode();
final FocusNode maksimalBiayaPengirimanFocusNode = FocusNode();
final FocusNode biayaPerKiloFocusNode = FocusNode();
@override
void onInit() {
log("sini pengaturan controller");
minimalBiayaPengirimanController.clear();
maksimalBiayaPengirimanController.clear();
biayaPerKiloController.clear();
log('ini idnya ' + storage.read('id'));
super.onInit();
}
@override
void onReady() {
cek_datanya();
super.onReady();
}
cek_datanya() async {
await EasyLoading.show(
status: 'Loading Data...',
maskType: EasyLoadingMaskType.black,
);
final result = await KurirApi.cekPengaturanKurir();
log(result.toString());
if (result['status'] == 200 && result['data'] != null) {
final PengaturanBiayaKurirModel pengaturanBiayaKurir =
PengaturanBiayaKurirModel.fromJson(result['data']);
minimalBiayaPengirimanController.text =
thousandsSeperator(pengaturanBiayaKurir.minimalBiayaPengiriman!);
maksimalBiayaPengirimanController.text =
thousandsSeperator(pengaturanBiayaKurir.maksimalBiayaPengiriman!);
biayaPerKiloController.text =
thousandsSeperator(pengaturanBiayaKurir.biayaPerKilo!);
status.value = 'Ubah';
} else {
status.value = 'Simpan';
}
await EasyLoading.dismiss();
}
simpan() async {
// remove "," from text
//get alert dialog
final minimalBiayaPengiriman =
minimalBiayaPengirimanController.text.replaceAll(RegExp(r','), '');
final maksimalBiayaPengiriman =
maksimalBiayaPengirimanController.text.replaceAll(RegExp(r','), '');
final biayaPerKilo =
biayaPerKiloController.text.replaceAll(RegExp(r','), '');
// log(minimalBiayaPengiriman + " ini minimal biaya pengiriman");
// log(maksimalBiayaPengiriman + " ini maksimal biaya pengiriman");
// log(biayaPerKilo + " ini biaya per kilo");
await EasyLoading.show(
status: 'Pengaturan Biaya...',
maskType: EasyLoadingMaskType.black,
);
final result = await KurirApi.pengaturanKurir(
minimalBiayaPengiriman, maksimalBiayaPengiriman, biayaPerKilo);
log(result.toString());
onInit();
await EasyLoading.dismiss();
}
coba() {
log("sini coba terjadi");
}
thousandsSeperator(int number) {
final formatter = NumberFormat('#,###');
final numbernya = formatter.format(number);
// log(numbernya + " ini numbernya");
return numbernya;
}
removeComma(String number) {
final numbernya = number.replaceAll(RegExp(r','), '');
return int.parse(numbernya);
}
}

View File

@ -0,0 +1,32 @@
// ignore_for_file: file_names
import 'package:get/get.dart';
import 'dart:developer';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:kurir/api/beforeLoginAPI.dart';
class KurirProfileController extends GetxController {
@override
void onInit() {
log("sini profile kurir controller oninit");
super.onInit();
}
logout() async {
await EasyLoading.show(
status: 'Pengaturan Biaya...',
maskType: EasyLoadingMaskType.black,
);
await BeforeLoginApi.logout();
await EasyLoading.dismiss();
Get.offAllNamed(
'/index',
arguments: {
"tap": 0,
"history": [0],
},
);
}
}

View File

@ -0,0 +1,82 @@
// ignore_for_file: file_names
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:kurir/controller/after_login/pengirim/kirimBarangController.dart';
import 'package:kurir/controller/after_login/pengirim/logKirimanController.dart';
class PengirimIndexController extends GetxController {
dynamic argumicData = Get.arguments;
final Rx<int> _indexTap = 0.obs; // bottom navigation index tap
late PageController pageController;
pageChanged(int index) async {
// Get.delete<KirimBarangController>();
if (index == 0) {
var _init = Get.put(KirimBarangController());
_init.onInit();
// Get.lazyPut<KirimBarangController>(() => KirimBarangController());
}
if (index == 1) {
var _init = Get.put(LogKirimanController());
_init.onInit();
}
_indexTap.value = index;
}
@override
void onInit() {
log("sini on init pengirim index");
_indexTap.value = argumicData['tap'] ?? 0;
pageController =
PageController(initialPage: _indexTap.value, keepPage: true);
super.onInit();
}
BottomNavigationBar bottomNavigationBar(context) {
return BottomNavigationBar(
type: BottomNavigationBarType.fixed,
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.motorcycle_rounded),
label: 'Kirim Barang',
),
BottomNavigationBarItem(
icon: Icon(Icons.list_alt_rounded),
label: 'Log Kiriman',
),
BottomNavigationBarItem(
icon: Icon(Icons.people_alt_rounded),
label: 'List Kurir',
),
BottomNavigationBarItem(
icon: Icon(Icons.account_circle),
label: 'Profile',
),
],
currentIndex: _indexTap.value,
selectedItemColor: const Color.fromARGB(255, 148, 183, 229),
onTap: (index) => _onItemTapped(index, context),
);
}
_onItemTapped(int index, BuildContext context) {
log("sini on item tapped");
if (index == 3) {
Get.offAllNamed('/profilePengirim');
}
_indexTap.value = index;
FocusScope.of(context).unfocus();
// Get.delete<PengaturanKurirController>();
pageController.animateToPage(index,
duration: const Duration(milliseconds: 300), curve: Curves.ease);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,414 @@
// ignore_for_file: file_names, non_constant_identifier_names
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter_polyline_points/flutter_polyline_points.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:get/get.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:intl/intl.dart';
import 'package:kurir/api/pengirimApi.dart';
import 'package:kurir/function/allFunction.dart';
import 'package:kurir/models/pengirimimanModel.dart';
import 'package:kurir/globals.dart' as globals;
class LogKirimanController extends GetxController {
Rx<Widget> widgetLogKiriman = const Center(
child: CircularProgressIndicator(),
).obs;
RxBool isPortrait = true.obs;
late GoogleMapController mapController;
Set<Marker> _markers = {};
Set<Polyline> _polylines = {};
List<LatLng> _polylineCoordinates = [];
PolylinePoints _polylinePoints = PolylinePoints();
String _googleAPiKey = globals.api_key;
List<LatLng>? _listLatLng;
// late GoogleMapController mapController;
final _initialCameraPosition = const CameraPosition(
target: LatLng(-3.5621854706823193, 119.7612856634139),
zoom: 12.5,
);
@override
void onInit() {
// ignore: todo
// TODO: implement onInit
log("sini on init log kiriman");
checkAllLogKiriman();
// BuildContext? context;
log(Get.context!.isLandscape.toString() + " is landscape");
log(Get.context!.isPortrait.toString() + " is potret");
super.onInit();
}
checkScreenOrientation() {
if (Get.context!.isLandscape) {
isPortrait.value = false;
} else {
isPortrait.value = true;
}
}
checkAllLogKiriman() async {
Map<String, dynamic> _data = await PengirimApi.getLogKiriman();
log(_data.toString());
// await 4 sec
widgetLogKiriman.value = const Center(
child: CircularProgressIndicator(),
);
if (_data['data'].length > 0) {
List<Widget> _listWidget = [];
for (var item in _data['data']) {
PengirimanModel? _pengirimanModel = PengirimanModel.fromJson(item);
// log(_pengiriman.kurir!.id.toString());
_listWidget.add(_widgetLogKiriman(_pengirimanModel));
// _listWidget.add(_widgetLogKiriman());
}
Widget _listview = Column(
children: [
..._listWidget,
],
);
widgetLogKiriman.value = Center(
child: Obx(
() => Container(
constraints: BoxConstraints(
// maxHeight: Get.height * 0.65,
maxHeight:
(isPortrait.value) ? Get.height * 0.62 : Get.height * 0.42,
minHeight: Get.context!.height * 0.42,
),
child: SingleChildScrollView(child: _listview),
),
),
);
} else {
widgetLogKiriman.value = const Center(
child: Text("Tidak ada log kiriman"),
);
}
}
_widgetLogKiriman(PengirimanModel? _pengirimanModel) {
var _createdAtPlus8 = DateTime.parse(_pengirimanModel!.createdAt!)
.add(const Duration(hours: 8));
String _tanggal = DateFormat('dd-MM-yyyy').format(_createdAtPlus8);
// add am/pm to jam
String _jam = DateFormat('HH:mm:ss').format(_createdAtPlus8);
String _nama_kurir = _pengirimanModel.kurir!.nama!;
String _status = _pengirimanModel.statusPengiriman!;
String _foto_pengiriman = _pengirimanModel.fotoPengiriman!;
// log(_foto_pengiriman + " foto pengiriman");
var _kordinat_pengiriman = _pengirimanModel.kordinatPengiriman!;
var _kordinat_permulaan = _pengirimanModel.kordinatPermulaan!;
Widget _listTilenya = Card(
elevation: 2,
child: Slidable(
key: const ValueKey(1),
startActionPane: ActionPane(
motion: const DrawerMotion(),
extentRatio: 0.80,
// dismissible: DismissiblePane(onDismissed: () {}),
children: [
SlidableAction(
flex: 2,
onPressed: (context) {},
backgroundColor: const Color.fromARGB(255, 70, 192, 232),
foregroundColor: Colors.white,
icon: Icons.info_outline_rounded,
label: 'Info',
),
SlidableAction(
flex: 3,
onPressed: (context) {
_lihat_foto_kiriman(context, _foto_pengiriman);
},
backgroundColor: const Color.fromARGB(255, 71, 92, 250),
foregroundColor: Colors.white,
icon: Icons.photo_rounded,
label: 'Barang Kiriman',
),
],
),
endActionPane: ActionPane(
motion: const DrawerMotion(),
extentRatio: 0.5,
children: [
SlidableAction(
onPressed: (context) {
_lihat_rute_pengiriman(
context, _kordinat_pengiriman, _kordinat_permulaan);
},
backgroundColor: Color.fromARGB(255, 242, 78, 23),
foregroundColor: Colors.white,
icon: Icons.maps_home_work_rounded,
label: "Rute Pengiriman",
),
],
),
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 10,
),
child: Row(
children: [
Expanded(
flex: 3,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
" $_tanggal",
style: const TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
),
),
Text(
" $_jam",
style: const TextStyle(
fontSize: 15,
),
),
],
),
),
Expanded(
flex: 3,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
_nama_kurir,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
],
),
),
Expanded(
flex: 3,
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
_status,
style: const TextStyle(
fontSize: 15,
// fontWeight: FontWeight.bold,
),
),
],
),
)
],
),
),
),
);
return _listTilenya;
}
_lihat_foto_kiriman(BuildContext context, String foto_pengiriman) {
log(foto_pengiriman);
if (foto_pengiriman != null && foto_pengiriman != "") {
Get.dialog(
AlertDialog(
title: const Text("Foto Pengiriman"),
content: Container(
height: Get.height * 0.5,
width: Get.width * 0.6,
decoration: const BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.grey,
spreadRadius: 1,
blurRadius: 10,
),
],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/loading.gif'),
fit: BoxFit.cover,
),
),
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(foto_pengiriman),
fit: BoxFit.cover,
),
),
),
),
),
),
),
);
} else {
Get.snackbar(
"Info",
"Foto Barang Pengiriman Masih Dalam Proses Upload",
icon: Icon(
Icons.info_outline_rounded,
color: Colors.white,
),
backgroundColor: Color.fromARGB(255, 71, 203, 240),
duration: Duration(seconds: 3),
snackPosition: SnackPosition.TOP,
);
}
}
_lihat_rute_pengiriman(
BuildContext context,
KordinatPengiriman kordinat_pengiriman,
KordinatPermulaan kordinat_permulaan) async {
_markers.clear();
_polylines.clear();
_polylineCoordinates = [];
_listLatLng = null;
// _polylinePoints.clear();
LatLng _latLng_pengiriman = LatLng(
double.parse(kordinat_pengiriman.lat!),
double.parse(kordinat_pengiriman.lng!),
);
LatLng _latLng_permulaan = LatLng(
double.parse(kordinat_permulaan.lat!),
double.parse(kordinat_permulaan.lng!),
);
_listLatLng = [
LatLng(
double.parse(kordinat_permulaan.lat!),
double.parse(kordinat_permulaan.lng!),
),
LatLng(
double.parse(kordinat_pengiriman.lat!),
double.parse(kordinat_pengiriman.lng!),
),
];
await setPolylines(
_latLng_pengiriman,
_latLng_permulaan,
);
_markers.add(
Marker(
markerId: const MarkerId("permulaan"),
position: LatLng(double.parse(kordinat_permulaan.lat!),
double.parse(kordinat_permulaan.lng!)),
infoWindow: InfoWindow(
title: "Lokasi Permulaan",
),
),
);
_markers.add(
Marker(
markerId: const MarkerId("pengiriman"),
position: LatLng(double.parse(kordinat_pengiriman.lat!),
double.parse(kordinat_pengiriman.lng!)),
infoWindow: InfoWindow(
title: "LokasiPengiriman",
),
),
);
// await 1 sec
await Future.delayed(Duration(seconds: 1));
Get.dialog(
AlertDialog(
content: Container(
height: Get.height * 0.5,
child: GoogleMap(
mapType: MapType.hybrid,
mapToolbarEnabled: true,
rotateGesturesEnabled: true,
myLocationButtonEnabled: true,
markers: _markers,
polylines: _polylines,
// liteModeEnabled: true,
initialCameraPosition: _initialCameraPosition,
onMapCreated: _onBounds,
// onCameraMove: _onCameraMove,
),
),
),
);
}
setPolylines(LatLng latLng_pengiriman, LatLng latLng_permulaan) async {
log("sini dia berlaku");
PolylineResult _result = await _polylinePoints.getRouteBetweenCoordinates(
_googleAPiKey,
PointLatLng(latLng_permulaan.latitude, latLng_permulaan.longitude),
PointLatLng(latLng_pengiriman.latitude, latLng_pengiriman.longitude),
travelMode: TravelMode.driving,
// travelMode: TravelMode.driving,
);
// log(_result.points.toString() + "ini dia");
if (_result.points.isNotEmpty) {
// loop through all PointLatLng points and convert them
// to a list of LatLng, required by the Polyline
_result.points.forEach((PointLatLng point) {
_polylineCoordinates.add(LatLng(point.latitude, point.longitude));
});
Polyline polyline = Polyline(
polylineId: PolylineId("poly"),
color: Color.fromARGB(255, 40, 122, 198),
points: _polylineCoordinates,
width: 3,
);
_polylines.add(polyline);
double distance = await PengirimApi.jarak_route(
latLng_permulaan.latitude,
latLng_permulaan.longitude,
latLng_pengiriman.latitude,
latLng_pengiriman.longitude,
);
log(distance.toString() + "ini dia");
}
}
void _onBounds(GoogleMapController controller) {
mapController = controller;
mapController.animateCamera(
CameraUpdate.newLatLngBounds(
AllFunction.computeBounds(_listLatLng!),
15,
),
);
}
}

View File

@ -0,0 +1,228 @@
// ignore_for_file: file_names, invalid_use_of_protected_member
import 'dart:convert';
import 'dart:developer';
import 'package:crypto/crypto.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get/get.dart';
import '../../api/beforeLoginAPI.dart';
class LoginController extends GetxController {
var formKey = GlobalKey<FormState>();
dynamic argumicData = Get.arguments; // get argument from routes.
final Rx<int> _indexTap = 0.obs; // bottom navigation index tap
late final RxList _historyIndex = [].obs; // navigation history
// for login page
List<String> role = ['Kurir', 'Pengirim'];
final Rx<String> selectedRole = 'Kurir'.obs;
final usernameController = TextEditingController();
final passwordController = TextEditingController();
final RxBool passwordVisible = false.obs;
final FocusNode usernameFocusNode = FocusNode();
final FocusNode passwordFocusNode = FocusNode();
@override
void onInit() {
log("sini on init");
// print(argumicData);
_indexTap.value = argumicData['tap'];
// push to _historyIndex
_historyIndex.value = argumicData['history'];
log(_historyIndex.value.toString() + " ini history");
// print(_historyIndex.length.toString() + " ini panjangnya di oninit");
// BackButtonInterceptor.add(myInterceptor);
super.onInit();
}
@override
void dispose() {
formKey.currentState!.dispose();
super.dispose();
}
// back button history navigation
Future<bool> willPopScopeWidget() async {
log('sini willpopscope');
log(_historyIndex.toString() + ' ini history listnya');
final int lastIndex = _historyIndex[_historyIndex.length - 2];
log("sini last index " + lastIndex.toString());
late String _routeName;
switch (lastIndex) {
case 0:
_routeName = '/index';
break;
case 1:
_routeName = '/login';
break;
case 2:
_routeName = '/daftar';
break;
}
// log("ini route name " + _routeName);
_historyIndex.removeLast();
selectedRole.value = role[0];
usernameController.clear();
passwordController.clear();
_indexTap.value = lastIndex;
// Get.back();
// await Get.delete<LoginController>();
Get.offAllNamed(
_routeName,
arguments: {
"tap": lastIndex,
"history": _historyIndex.value,
},
);
return false;
}
// bottom navigation index tapping
void _onItemTapped(int index) async {
if (index == _indexTap.value) return;
_indexTap.value = index;
late String _routeName;
switch (index) {
case 0:
_routeName = '/index';
break;
case 1:
_routeName = '/login';
break;
case 2:
_routeName = '/daftar';
break;
}
// Get.delete<LoginController>();
log("sini on item tapped");
if (index == 0) {
_historyIndex.clear();
_historyIndex.add(0);
} else {
_historyIndex.add(index);
}
//clear all the input in login before navigate to another page
selectedRole.value = role[0];
usernameController.clear();
passwordController.clear();
// await Get.delete<LoginController>();
await Get.offAllNamed(
_routeName,
arguments: {
"tap": index,
"history": _historyIndex.value,
},
);
// Get.toNamed('/second');
}
void login() async {
await EasyLoading.show(
status: 'Loading...',
maskType: EasyLoadingMaskType.black,
);
log("sini proses login");
late bool _wrongPassword;
late String _message;
String _username = usernameController.text;
String _password = passwordController.text;
String _role = selectedRole.value;
log(_username.toString() + " ini usernamenya");
log(_password.toString() + " ini passwordnya");
log(_role.toString() + " ini role nya");
Map<String, dynamic> _data = await BeforeLoginApi.log_in_user(
_username, generateMd5(_password), _role.toLowerCase());
await EasyLoading.dismiss();
// log(_data.toString() + " ini data");
switch (_data['status']) {
case 200:
_wrongPassword = true;
_message = _data['message'];
break;
case 400:
_wrongPassword = false;
_message = _data['message'];
usernameFocusNode.requestFocus();
break;
default:
_wrongPassword = false;
_message = _data['message'];
break;
}
if (!_wrongPassword) {
// focus to username
// usernameFocusNode.requestFocus();
// put validator in username
Get.snackbar(
"Error",
_message,
icon: const Icon(
Icons.error,
color: Colors.red,
),
backgroundColor: Colors.white,
colorText: Colors.black,
);
} else {
Get.snackbar(
"Sukses Login",
_message,
icon: const Icon(
Icons.check,
color: Colors.green,
),
backgroundColor: Colors.white,
colorText: Colors.black,
);
// await 2 second then navigate to index page
await Future.delayed(const Duration(milliseconds: 1500));
Get.offAllNamed('/beforeEnter');
}
}
// for input checker
String generateMd5(String input) {
return md5.convert(utf8.encode(input)).toString();
}
// bottom navigation bar
BottomNavigationBar bottomNavigationBar() {
return BottomNavigationBar(
type: BottomNavigationBarType.fixed,
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.login),
label: 'Login',
),
BottomNavigationBarItem(
icon: Icon(Icons.app_registration),
label: 'Daftar',
),
],
currentIndex: _indexTap.value,
selectedItemColor: const Color.fromARGB(255, 148, 183, 229),
onTap: _onItemTapped,
);
}
}

View File

@ -0,0 +1,499 @@
// ignore_for_file: file_names, non_constant_identifier_names
import 'dart:developer';
import 'dart:typed_data';
import 'dart:io';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get/get.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:kurir/api/beforeLoginAPI.dart';
// sini coba
import 'package:path_provider/path_provider.dart';
import 'dart:convert';
import 'package:crypto/crypto.dart';
class PendaftaranKurirController extends GetxController {
final formKey = GlobalKey<FormState>();
// ini untuk detail login
final usernameController = TextEditingController();
final passwordController = TextEditingController();
final konfirmasiPasswordController = TextEditingController();
RxBool passwordVisible = true.obs;
RxBool konfirmasiPasswordVisible = true.obs;
final FocusNode usernameFocusNode = FocusNode();
final FocusNode passwordFocusNode = FocusNode();
final FocusNode konfirmasiPasswordFocusNode = FocusNode();
// ini untuk detail kurir
final nikController = TextEditingController();
final namaController = TextEditingController();
final emailController = TextEditingController();
final noTelpController = TextEditingController();
final alamatController = TextEditingController();
final noPlatController = TextEditingController();
final FocusNode nikFocusNode = FocusNode();
final FocusNode namaFocusNode = FocusNode();
final FocusNode emailFocusNode = FocusNode();
final FocusNode noTelpFocusNode = FocusNode();
final FocusNode alamatFocusNode = FocusNode();
final FocusNode noPlatFocusNode = FocusNode();
final FocusNode fotoProfilFocusNode = FocusNode();
final FocusNode fotoKTPFocusNode = FocusNode();
final FocusNode fotoKendaraanFocusNode = FocusNode();
final FocusNode fotoHoldingKTPFocusNode = FocusNode();
// ini untuk foto
RxBool isAdaFotoProfil = false.obs;
RxBool isAdaFotoKTP = false.obs;
RxBool isAdaFotoKTPHolding = false.obs;
RxBool isAdaKenderaan = false.obs;
// storing image path
String? imgProfil;
String? imgKTP;
String? imgKendaraan;
String? imgHoldingKTP;
final ImagePicker _picker = ImagePicker();
XFile? _imageFile;
// create onimagebuttonpressed
Future<void> _onImageButtonPressed(ImageSource source, String option) async {
log('sini on image button pressed + $option');
try {
final XFile? pickedFile = await _picker.pickImage(source: source);
_imageFile = pickedFile;
// log("ini dia ");
log(_imageFile!.path.toString());
switch (option) {
case "profil":
imgProfil = _imageFile!.path.toString();
isAdaFotoProfil.value = true;
break;
case "ktp":
imgKTP = _imageFile!.path.toString();
isAdaFotoKTP.value = true;
break;
case "kendaraan":
imgKendaraan = _imageFile!.path.toString();
isAdaKenderaan.value = true;
break;
case "ktp_holding":
imgHoldingKTP = _imageFile!.path.toString();
isAdaFotoKTPHolding.value = true;
break;
}
// log("ini dia " + imgKTP!);
} catch (e) {
log(e.toString());
}
}
// show foto
Future showFoto(String option) async {
Uint8List? _bytes;
// log("ini dia img ktp" + imgKTP!);
// final appStorage = await getTemporaryDirectory();
late String _initialPath;
switch (option) {
case "profil":
_initialPath = imgProfil!;
break;
case "ktp":
_initialPath = imgKTP!;
break;
case "kendaraan":
_initialPath = imgKendaraan!;
break;
case "ktp_holding":
_initialPath = imgHoldingKTP!;
break;
}
final _file = File(_initialPath);
if (_file.existsSync()) {
log("ada");
Uint8List bytes = await _file.readAsBytes();
_bytes = bytes;
//
return await Get.bottomSheet(
Container(
height: MediaQuery.of(Get.context!).size.height / 2,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
image: DecorationImage(
image: MemoryImage(_bytes),
fit: BoxFit.fill,
),
),
),
);
} else {
log("tidak ada");
}
// show getx bottom sheet
}
//delete foto on cache and storage
Future _cek_and_delete() async {
final appStorage = await getTemporaryDirectory();
// // if (appStorage.existsSync()) {
// // log("ada file");
// // print all filename in directory
final fileList = appStorage.listSync();
log(fileList.toString() + "ini file list");
if (fileList.isNotEmpty) {
log("ada file");
// print(fileList);
for (var i = 0; i < fileList.length; i++) {
final file = fileList[i];
log(file.path);
if (file.toString().contains(".jpg") ||
file.toString().contains(".png") ||
file.toString().contains(".jpeg") ||
file.toString().contains(".JPG") ||
file.toString().contains(".PNG") ||
file.toString().contains(".JPEG")) {
log("delete");
await file.delete(recursive: true);
}
}
} else {
log("tidak ada file");
// print(fileList);
}
}
// choose option of photo
Future<void> onChooseOption(String option) async {
return Get.dialog(
AlertDialog(
// title: Text('Pilih'),
content: const Text(
"Pilih",
textAlign: TextAlign.center,
),
actions: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const SizedBox(),
ElevatedButton(
onPressed: () {
_onImageButtonPressed(ImageSource.camera, option);
Get.back();
},
child: const Text("Camera"),
),
const SizedBox(),
ElevatedButton(
onPressed: () {
_onImageButtonPressed(ImageSource.gallery, option);
Get.back();
},
child: const Text("Galeri"),
),
const SizedBox(),
],
)
],
),
);
}
@override
void onInit() {
log('Sini contoller pendaftaran kurir');
// intro_message();
super.onInit();
}
@override
void onReady() {
// log('Sini contoller pendaftaran kurir');
intro_message();
super.onReady();
}
@override
void dispose() {
// dispose formKey
// ignore: invalid_use_of_protected_member
formKey.currentState?.dispose();
// dispose controller
usernameController.dispose();
passwordController.dispose();
konfirmasiPasswordController.dispose();
nikController.dispose();
namaController.dispose();
emailController.dispose();
noTelpController.dispose();
alamatController.dispose();
noPlatController.dispose();
// dispose focusNode
usernameFocusNode.dispose();
passwordFocusNode.dispose();
konfirmasiPasswordFocusNode.dispose();
nikFocusNode.dispose();
namaFocusNode.dispose();
emailFocusNode.dispose();
noTelpFocusNode.dispose();
alamatFocusNode.dispose();
noPlatFocusNode.dispose();
fotoProfilFocusNode.dispose();
fotoKTPFocusNode.dispose();
fotoHoldingKTPFocusNode.dispose();
fotoKendaraanFocusNode.dispose();
super.dispose();
}
// intro message
Future intro_message() {
return Get.dialog(
WillPopScope(
onWillPop: () async => false,
child: AlertDialog(
title: const Text('Info Penting', textAlign: TextAlign.center),
content: const Text(
"Silahkan isi data diri anda dengan benar\nData anda akan dievaluasi oleh admin sebelum anda dapat mendaftar ke dalam sistem",
textAlign: TextAlign.center,
),
actions: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const SizedBox(),
ElevatedButton(
onPressed: () {
Get.back();
},
child: const Text("OK"),
),
const SizedBox(),
],
)
],
),
),
);
}
// before sign up and sign up process
before_sign_up() {
log("ini before sign up");
// show get dialog
return Get.dialog(AlertDialog(
title: const Text("Pendaftaran Kurir", textAlign: TextAlign.center),
content: const Text(
"Yakin dengan data yang anda masukkan benar?\nAdmin akan mengevaluasi data yang anda masukkan sebelum menerima pendaftaran",
textAlign: TextAlign.center),
actions: [
ElevatedButton(
child: const Text('Tidak'),
onPressed: () {
Get.back();
},
),
ElevatedButton(
child: const Text('Ya'),
style: ElevatedButton.styleFrom(
primary: Colors.red,
),
onPressed: () {
sign_up();
// await _cek_and_delete();
// await Get.offAllNamed(
// '/index',
// arguments: {"tap": 0},
// );
},
),
],
));
}
void sign_up() async {
Get.back();
String username = usernameController.text;
String password = passwordController.text;
String nik = nikController.text;
String nama = namaController.text;
String email = emailController.text;
String noTelp = noTelpController.text;
String alamat = alamatController.text;
String noPlat = noPlatController.text;
String fotoProfil = imgProfil!;
String fotoKTP = imgKTP!;
String fotoHoldingKTP = imgHoldingKTP!;
String fotoKendaraan = imgKendaraan!;
Map<String, dynamic> data = {
"username": username,
"password": generateMd5(password),
"nik": nik,
"nama": nama,
"email": email,
"no_telp": noTelp,
"alamat": alamat,
"no_kenderaan": noPlat,
"role": "kurir",
};
try {
await EasyLoading.show(
status: 'Loading...',
maskType: EasyLoadingMaskType.black,
);
Map<String, dynamic> inidia = await BeforeLoginApi.sign_up_kurir(
data, fotoKTP, fotoHoldingKTP, fotoKendaraan, fotoProfil);
late String title, content;
// ignore: prefer_typing_uninitialized_variables
late var color, icon;
switch (inidia['status']) {
case 200:
title = "Pendaftaran Berhasil ";
content = inidia['message'];
color = Colors.green;
icon = Icons.check;
break;
case 400:
title = "Pendaftaran Gagal ";
content = inidia['message'];
color = Colors.orange[400];
icon = Icons.error;
break;
case 500:
title = "Koneksi Bermasalah ";
content = inidia['message'];
color = Colors.red;
icon = Icons.error;
break;
}
Get.snackbar(
title,
content,
icon: Icon(icon, color: Colors.white),
backgroundColor: color,
colorText: Colors.white,
duration: const Duration(seconds: 3),
);
Get.dialog(
WillPopScope(
onWillPop: () {
// Get.back();
return Future.value(false);
},
child: AlertDialog(
title: Text(title, textAlign: TextAlign.center),
content: Text(content, textAlign: TextAlign.justify),
actions: [
ElevatedButton(
child: const Text('OK'),
onPressed: () async {
if (inidia['status'] == 200) {
await _cek_and_delete();
await Get.offAllNamed(
'/index',
arguments: {
"tap": 0,
'history': [0]
},
);
} else {
Get.back();
switch (inidia['focus']) {
case 'nik':
nikFocusNode.requestFocus();
break;
case 'no_telp':
noTelpFocusNode.requestFocus();
break;
case 'email':
emailFocusNode.requestFocus();
break;
}
}
},
),
],
),
),
);
//
await EasyLoading.dismiss();
} catch (e) {
log(e.toString());
}
// return BeforeLoginApi.sign_up(
// data, fotoKTP, fotoHoldingKTP, fotoKendaraan, fotoProfil)
// .then((response) {
// log(response.toString());
// }).catchError((e) {
// log(e.toString());
// }).whenComplete(() {
// log("complete");
// });
// log("sini berlaku proses sign up");
}
// for input checker
String generateMd5(String input) {
return md5.convert(utf8.encode(input)).toString();
}
bool email_checker(String email) {
RegExp regex = RegExp(
r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$');
return regex.hasMatch(email);
// return false;
}
// back button alert box
willPopScopeWidget() {
// create get dialog
return Get.dialog(
AlertDialog(
title: const Text('Konfirmasi'),
content: const Text('Anda yakin ingin keluar dari halaman ini?'),
actions: [
ElevatedButton(
child: const Text('Tidak'),
onPressed: () {
Get.back();
},
),
ElevatedButton(
child: const Text('Ya'),
style: ElevatedButton.styleFrom(
primary: Colors.red,
),
onPressed: () async {
await _cek_and_delete();
await Get.offAllNamed(
'/index',
arguments: {
"tap": 0,
'history': [0]
},
);
},
),
],
),
);
}
}

View File

@ -0,0 +1,427 @@
// ignore_for_file: file_names, non_constant_identifier_names
import 'dart:convert';
import 'dart:developer';
import 'dart:io';
import 'dart:typed_data';
import 'package:crypto/crypto.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get/get.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path_provider/path_provider.dart';
// import 'package:provider/provider.dart';
import '../../api/beforeLoginAPI.dart';
class PendaftaranPengirimController extends GetxController {
final formKey = GlobalKey<FormState>(); // form key
// ini untuk detail login
final usernameController = TextEditingController();
final passwordController = TextEditingController();
final konfirmasiPasswordController = TextEditingController();
RxBool passwordVisible = false.obs;
RxBool konfirmasiPasswordVisible = false.obs;
final FocusNode usernameFocusNode = FocusNode();
final FocusNode passwordFocusNode = FocusNode();
final FocusNode konfirmasiPasswordFocusNode = FocusNode();
// ini untuk detail pengirim
final namaController = TextEditingController();
final emailController = TextEditingController();
final noTelpController = TextEditingController();
final alamatController = TextEditingController();
final FocusNode namaFocusNode = FocusNode();
final FocusNode emailFocusNode = FocusNode();
final FocusNode noTelpFocusNode = FocusNode();
final FocusNode alamatFocusNode = FocusNode();
// ini untuk foto
RxBool isAdaFotoProfil = false.obs;
// stroing image path
String? imgProfil;
final ImagePicker _picker = ImagePicker();
XFile? _imageFile;
@override
void onInit() {
log('sini init controller pendaftran pengirim');
super.onInit();
}
@override
void onReady() {
intro_message();
super.onReady();
}
// intro message
Future intro_message() {
return Get.dialog(
WillPopScope(
onWillPop: () async => false,
child: AlertDialog(
title: const Text('Info Penting', textAlign: TextAlign.center),
content: const Text(
"Silahkan isi data diri anda dengan benar\nData anda akan dievaluasi oleh admin sebelum anda dapat mendaftar ke dalam sistem",
textAlign: TextAlign.center,
),
actions: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const SizedBox(),
ElevatedButton(
onPressed: () {
Get.back();
},
child: const Text("OK"),
),
const SizedBox(),
],
)
],
),
),
);
}
// choose option of photo
Future<void> onChooseOption(String option) async {
return Get.dialog(
AlertDialog(
// title: Text('Pilih'),
content: const Text(
"Pilih",
textAlign: TextAlign.center,
),
actions: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const SizedBox(),
ElevatedButton(
onPressed: () {
_onImageButtonPressed(ImageSource.camera, option);
Get.back();
},
child: const Text("Camera"),
),
const SizedBox(),
ElevatedButton(
onPressed: () {
_onImageButtonPressed(ImageSource.gallery, option);
Get.back();
},
child: const Text("Galeri"),
),
const SizedBox(),
],
)
],
),
);
}
// create onimagebuttonpressed
Future<void> _onImageButtonPressed(ImageSource source, String option) async {
log('sini on image button pressed + $option');
try {
final XFile? pickedFile = await _picker.pickImage(source: source);
_imageFile = pickedFile;
// log("ini dia ");
log(_imageFile!.path.toString());
switch (option) {
case "profil":
imgProfil = _imageFile!.path.toString();
isAdaFotoProfil.value = true;
break;
}
// log("ini dia " + imgKTP!);
} catch (e) {
log(e.toString());
}
}
// show foto
Future showFoto(String option) async {
Uint8List? _bytes;
// log("ini dia img ktp" + imgKTP!);
// final appStorage = await getTemporaryDirectory();
late String _initialPath;
switch (option) {
case "profil":
_initialPath = imgProfil!;
break;
}
final _file = File(_initialPath);
if (_file.existsSync()) {
log("ada");
Uint8List bytes = await _file.readAsBytes();
_bytes = bytes;
//
return await Get.bottomSheet(
Container(
height: MediaQuery.of(Get.context!).size.height / 2,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
image: DecorationImage(
image: MemoryImage(_bytes),
fit: BoxFit.fill,
),
),
),
);
} else {
log("tidak ada");
}
// show getx bottom sheet
}
//delete foto on cache and storage
Future _cek_and_delete() async {
final appStorage = await getTemporaryDirectory();
// // if (appStorage.existsSync()) {
// // log("ada file");
// // print all filename in directory
final fileList = appStorage.listSync();
log(fileList.toString() + "ini file list");
if (fileList.isNotEmpty) {
log("ada file");
// print(fileList);
for (var i = 0; i < fileList.length; i++) {
final file = fileList[i];
log(file.path);
if (file.toString().contains(".jpg") ||
file.toString().contains(".png") ||
file.toString().contains(".jpeg") ||
file.toString().contains(".JPG") ||
file.toString().contains(".PNG") ||
file.toString().contains(".JPEG")) {
log("delete");
await file.delete(recursive: true);
}
}
} else {
log("tidak ada file");
// print(fileList);
}
}
// before sign up and sign up process
before_sign_up(BuildContext context) async {
log("ini before sign up");
// show get dialog
return Get.dialog(AlertDialog(
title: const Text("Pendaftaran Kurir", textAlign: TextAlign.center),
content: const Text(
"Yakin dengan data yang anda masukkan benar?\nAdmin akan mengevaluasi data yang anda masukkan sebelum menerima pendaftaran",
textAlign: TextAlign.center),
actions: [
ElevatedButton(
child: const Text('Tidak'),
onPressed: () {
Get.back();
},
),
ElevatedButton(
child: const Text('Ya'),
style: ElevatedButton.styleFrom(
primary: Colors.red,
),
onPressed: () {
// log("sini sign up");
_sign_up(context);
// await _cek_and_delete();
// await Get.offAllNamed(
// '/index',
// arguments: {"tap": 0},
// );
},
),
],
));
}
void _sign_up(BuildContext context) async {
Get.back();
String username = usernameController.text;
String password = passwordController.text;
String nama = namaController.text;
String email = emailController.text;
String noTelp = noTelpController.text;
String alamat = alamatController.text;
String fotoProfil = imgProfil!;
Map<String, dynamic> data = {
"username": username,
"password": generateMd5(password),
"nama": nama,
"email": email,
"no_telp": noTelp,
"alamat": alamat,
"role": "pengirim",
};
// final BeforeLoginApi _api =
// Provider.of<BeforeLoginApi>(context, listen: false);
try {
await EasyLoading.show(
status: 'Cek Koneksi...',
maskType: EasyLoadingMaskType.black,
);
Map<String, dynamic> _inidia =
await BeforeLoginApi.sign_up_pengirim(data, fotoProfil);
// final Map<String, dynamic> _inidia = await _api.sign_up_pengirim(
// data,
// fotoProfil,
// );
await EasyLoading.dismiss();
log(_inidia.toString());
late String title, content;
// ignore: prefer_typing_uninitialized_variables
late var color, icon;
switch (_inidia['status']) {
case 200:
title = "Pendaftaran Berhasil ";
content = _inidia['message'];
color = Colors.green;
icon = Icons.check;
break;
case 400:
title = "Pendaftaran Gagal ";
content = _inidia['message'];
color = Colors.orange[400];
icon = Icons.error;
break;
case 500:
title = "Koneksi Bermasalah ";
content = _inidia['message'];
color = Colors.red;
icon = Icons.error;
break;
}
Get.snackbar(
title,
content,
icon: Icon(icon, color: Colors.white),
backgroundColor: color,
colorText: Colors.white,
duration: const Duration(seconds: 3),
);
Get.dialog(
WillPopScope(
onWillPop: () {
// Get.back();
return Future.value(false);
},
child: AlertDialog(
title: Text(title, textAlign: TextAlign.center),
content: Text(content, textAlign: TextAlign.justify),
actions: [
ElevatedButton(
child: const Text('OK'),
onPressed: () async {
if (_inidia['status'] == 200) {
// Get.back();
await _cek_and_delete();
await Get.offAllNamed(
'/index',
arguments: {
"tap": 0,
'history': [0]
},
);
} else {
Get.back();
switch (_inidia['focus']) {
case 'no_telp':
noTelpFocusNode.requestFocus();
break;
case 'email':
emailFocusNode.requestFocus();
break;
}
}
},
),
],
),
),
);
//
await EasyLoading.dismiss();
} catch (e) {
log(e.toString());
}
// return BeforeLoginApi.sign_up(
// data, fotoKTP, fotoHoldingKTP, fotoKendaraan, fotoProfil)
// .then((response) {
// log(response.toString());
// }).catchError((e) {
// log(e.toString());
// }).whenComplete(() {
// log("complete");
// });
// log("sini berlaku proses sign up");
}
// for input checker
String generateMd5(String input) {
return md5.convert(utf8.encode(input)).toString();
}
bool email_checker(String email) {
RegExp regex = RegExp(
r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$');
return regex.hasMatch(email);
// return false;
}
willPopScopeWidget() {
// create get dialog
return Get.dialog(
AlertDialog(
title: const Text('Konfirmasi'),
content: const Text(
'Anda yakin ingin keluar dari halaman ini?\nPendaftran anda akan dibatalkan'),
actions: [
ElevatedButton(
child: const Text('Tidak'),
onPressed: () {
Get.back();
},
),
ElevatedButton(
child: const Text('Ya'),
style: ElevatedButton.styleFrom(
primary: Colors.red,
),
onPressed: () async {
// await _cek_and_delete();
await Get.offAllNamed(
'/index',
arguments: {
"tap": 0,
'history': [0]
},
);
},
),
],
),
);
}
}

View File

@ -0,0 +1,33 @@
// ignore_for_file: file_names
import 'dart:developer';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
class SplashController extends GetxController {
final storage = GetStorage();
@override
void onInit() {
super.onInit();
Future.delayed(const Duration(milliseconds: 2500), () {
log('SplashController onInit');
// Get.offAllNamed('/index');
// goto to /index with argument tap : 0
final _role = (storage.read('role') != null) ? storage.read('role') : '';
if (_role == 'pengirim' || _role == 'kurir') {
Get.offAllNamed('/beforeEnter');
} else {
Get.offAllNamed(
'/index',
arguments: {
"tap": 0,
"history": [0],
},
);
}
});
}
}

View File

@ -0,0 +1,93 @@
// ignore_for_file: file_names, non_constant_identifier_names
import 'dart:developer' as dev;
import 'dart:math';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:intl/intl.dart';
import 'package:maps_toolkit/maps_toolkit.dart' as mp;
class AllFunction {
static LatLngBounds computeBounds(List<LatLng> list) {
// assert(list.isNotEmpty);
var firstLatLng = list.first;
var s = firstLatLng.latitude,
n = firstLatLng.latitude,
w = firstLatLng.longitude,
e = firstLatLng.longitude;
for (var i = 1; i < list.length; i++) {
var latlng = list[i];
s = min(s, latlng.latitude);
n = max(n, latlng.latitude);
w = min(w, latlng.longitude);
e = max(e, latlng.longitude);
}
return LatLngBounds(southwest: LatLng(s, w), northeast: LatLng(n, e));
}
static LatLng centerBounds(List<LatLng> list) {
// assert(list.isNotEmpty);
var firstLatLng = list.first;
var s = firstLatLng.latitude,
n = firstLatLng.latitude,
w = firstLatLng.longitude,
e = firstLatLng.longitude;
for (var i = 1; i < list.length; i++) {
var latlng = list[i];
s = min(s, latlng.latitude);
n = max(n, latlng.latitude);
w = min(w, latlng.longitude);
e = max(e, latlng.longitude);
}
return LatLng(
(s + n) / 2,
(w + e) / 2,
);
}
static bool cekMarkerOffside(LatLng latLng, List<LatLng> polyline) {
// dev.log("cek marker offside");
// dev.log(latLng.toString() + "ini latlng");
// dev.log(polyline.toString() + "ini polyline");
final MPLatLng = mp.LatLng(latLng.latitude, latLng.longitude);
final MPLatLngList =
polyline.map((e) => mp.LatLng(e.latitude, e.longitude)).toList();
bool isOffside = mp.PolygonUtil.containsLocation(
MPLatLng,
MPLatLngList,
false,
);
return isOffside;
}
static String thousandsSeperator(int number) {
final formatter = NumberFormat('#,###');
final numbernya = formatter.format(number);
// log(numbernya + " ini numbernya");
return numbernya.toString();
}
static removeComma(String number) {
final numbernya = number.replaceAll(RegExp(r','), '');
return numbernya;
}
static double check_distance_between(LatLng latLng1, LatLng latLng2) {
var distance = mp.SphericalUtil.computeDistanceBetween(
mp.LatLng(latLng1.latitude, latLng1.longitude),
mp.LatLng(latLng2.latitude, latLng2.longitude),
);
distance = distance / 1000;
double result = double.parse(distance.toStringAsFixed(2));
return result;
}
static double calculateDistance(lat1, lon1, lat2, lon2) {
dev.log("sini berlaku");
var p = 0.017453292519943295;
var a = 0.5 -
cos((lat2 - lat1) * p) / 2 +
cos(lat1 * p) * cos(lat2 * p) * (1 - cos((lon2 - lon1) * p)) / 2;
return 12742 * asin(sqrt(a));
}
}

43
lib/main.dart Normal file
View File

@ -0,0 +1,43 @@
import 'dart:io';
import 'package:flutter/material.dart';
// import 'package:provider/provider.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import 'package:kurir/routes/routes.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
// import 'api/beforeLoginAPI.dart';
void main() async {
HttpOverrides.global = MyHttpOverrides();
await GetStorage.init();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return GetMaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
getPages: Routes().routes,
initialRoute: '/splash',
builder: EasyLoading.init(),
);
}
}
class MyHttpOverrides extends HttpOverrides {
@override
HttpClient createHttpClient(SecurityContext? context) {
return super.createHttpClient(context)
..badCertificateCallback =
(X509Certificate cert, String host, int port) => true;
}
}

View File

@ -0,0 +1,26 @@
// ignore_for_file: file_names
class PengaturanBiayaKurirModel {
int? minimalBiayaPengiriman;
int? maksimalBiayaPengiriman;
int? biayaPerKilo;
PengaturanBiayaKurirModel({
this.minimalBiayaPengiriman,
this.maksimalBiayaPengiriman,
this.biayaPerKilo,
});
factory PengaturanBiayaKurirModel.fromJson(Map<String, dynamic> json) =>
PengaturanBiayaKurirModel(
minimalBiayaPengiriman: json["biaya_minimal"],
maksimalBiayaPengiriman: json["biaya_maksimal"],
biayaPerKilo: json["biaya_per_kilo"],
);
Map<String, dynamic> toJson() => {
"biaya_minimal": minimalBiayaPengiriman,
"biaya_maksimal": maksimalBiayaPengiriman,
"biaya_per_kilo": biayaPerKilo,
};
}

View File

@ -0,0 +1,147 @@
// ignore_for_file: file_names
import 'package:kurir/models/usersModel.dart';
class PengirimanModel {
KordinatPengiriman? kordinatPengiriman;
KordinatPermulaan? kordinatPermulaan;
Biaya? biaya;
String? sId;
String? namaPenerima;
String? noTelponPenerima;
String? alamatPenerima;
String? statusPengiriman;
KurirModel? kurir;
String? pengirim;
String? createdAt;
String? updatedAt;
int? iV;
String? fotoPengiriman;
PengirimanModel(
{this.kordinatPengiriman,
this.kordinatPermulaan,
this.biaya,
this.sId,
this.namaPenerima,
this.noTelponPenerima,
this.alamatPenerima,
this.statusPengiriman,
this.kurir,
this.pengirim,
this.createdAt,
this.updatedAt,
this.iV,
this.fotoPengiriman});
PengirimanModel.fromJson(Map<String, dynamic> json) {
kordinatPengiriman = json['kordinat_pengiriman'] != null
? KordinatPengiriman.fromJson(json['kordinat_pengiriman'])
: null;
kordinatPermulaan = json['kordinat_permulaan'] != null
? KordinatPermulaan.fromJson(json['kordinat_permulaan'])
: null;
biaya = json['biaya'] != null ? Biaya.fromJson(json['biaya']) : null;
sId = json['_id'];
namaPenerima = json['nama_penerima'];
noTelponPenerima = json['no_telpon_penerima'];
alamatPenerima = json['alamat_penerima'];
statusPengiriman = json['status_pengiriman'];
kurir = json['kurir'] != null ? KurirModel.fromJson(json['kurir']) : null;
pengirim = json['pengirim'];
createdAt = json['created_at'];
updatedAt = json['updated_at'];
iV = json['__v'];
fotoPengiriman = json['foto_pengiriman'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
if (kordinatPengiriman != null) {
data['kordinat_pengiriman'] = kordinatPengiriman!.toJson();
}
if (kordinatPermulaan != null) {
data['kordinat_permulaan'] = kordinatPermulaan!.toJson();
}
if (biaya != null) {
data['biaya'] = biaya!.toJson();
}
data['_id'] = sId;
data['nama_penerima'] = namaPenerima;
data['no_telpon_penerima'] = noTelponPenerima;
data['alamat_penerima'] = alamatPenerima;
data['status_pengiriman'] = statusPengiriman;
if (kurir != null) {
data['kurir'] = kurir!.toJson();
}
data['pengirim'] = pengirim;
data['created_at'] = createdAt;
data['updated_at'] = updatedAt;
data['__v'] = iV;
data['foto_pengiriman'] = fotoPengiriman;
return data;
}
}
class KordinatPengiriman {
String? lat;
String? lng;
String? kelurahanDesa;
KordinatPengiriman({this.lat, this.lng, this.kelurahanDesa});
KordinatPengiriman.fromJson(Map<String, dynamic> json) {
lat = json['lat'];
lng = json['lng'];
kelurahanDesa = json['kelurahan_desa'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['lat'] = lat;
data['lng'] = lng;
data['kelurahan_desa'] = kelurahanDesa;
return data;
}
}
class KordinatPermulaan {
String? lat;
String? lng;
KordinatPermulaan({this.lat, this.lng});
KordinatPermulaan.fromJson(Map<String, dynamic> json) {
lat = json['lat'];
lng = json['lng'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['lat'] = lat;
data['lng'] = lng;
return data;
}
}
class Biaya {
int? biayaMinimal;
int? biayaMaksimal;
int? biayaPerKilo;
Biaya({this.biayaMinimal, this.biayaMaksimal, this.biayaPerKilo});
Biaya.fromJson(Map<String, dynamic> json) {
biayaMinimal = json['biaya_minimal'];
biayaMaksimal = json['biaya_maksimal'];
biayaPerKilo = json['biaya_per_kilo'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['biaya_minimal'] = biayaMinimal;
data['biaya_maksimal'] = biayaMaksimal;
data['biaya_per_kilo'] = biayaPerKilo;
return data;
}
}

51
lib/models/petaModel.dart Normal file
View File

@ -0,0 +1,51 @@
// ignore_for_file: file_names, non_constant_identifier_names
class PetaKecamatanModel {
String kecamatan;
List<dynamic> polygon;
PetaKecamatanModel({
required this.kecamatan,
required this.polygon,
});
factory PetaKecamatanModel.fromJson(Map<String, dynamic> json) =>
PetaKecamatanModel(
kecamatan: json["kecamatan"],
polygon: List<dynamic>.from(json["polygon"].map((x) => x)),
);
}
class LatitudeLongitude {
double latitude;
double longitude;
LatitudeLongitude({
required this.latitude,
required this.longitude,
});
factory LatitudeLongitude.fromJson(Map<String, dynamic> json) =>
LatitudeLongitude(
latitude: json["lat"].toDouble(),
longitude: json["lng"].toDouble(),
);
}
class PetaKelurahanDesaModel {
String kelurahan_desa;
List<dynamic>? polygon;
PetaKelurahanDesaModel({
required this.kelurahan_desa,
this.polygon,
});
factory PetaKelurahanDesaModel.fromJson(Map<String, dynamic> json) =>
PetaKelurahanDesaModel(
kelurahan_desa: json["kelurahan_desa"],
polygon: json["polygon"] == null
? null
: List<dynamic>.from(json["polygon"].map((x) => x)),
);
}

View File

@ -0,0 +1,59 @@
// dart model for kurir
// ignore_for_file: file_names, camel_case_types, non_constant_identifier_names
class KurirModel {
String? id;
String? nama;
String? email;
String? no_telp;
String? alamat;
String? no_kenderaan;
String? status;
String? photo_url;
String? ktp_url;
String? ktp_holding_url;
String? kenderaan_url;
KurirModel({
this.id,
this.nama,
this.email,
this.no_telp,
this.alamat,
this.no_kenderaan,
this.status,
this.photo_url,
this.ktp_url,
this.ktp_holding_url,
this.kenderaan_url,
});
factory KurirModel.fromJson(Map<String, dynamic> json) => KurirModel(
id: json["_id"],
nama: json["nama"],
email: json["email"],
no_telp: json["no_telp"],
alamat: json["alamat"],
no_kenderaan: json["no_kenderaan"],
status: json["status"],
photo_url: json["photo_url"],
ktp_url: json["ktp_url"],
ktp_holding_url: json["ktp_holding_url"],
kenderaan_url: json["kenderaan_url"],
);
Map<String, dynamic> toJson() => {
"_id": id,
"nama": nama,
"email": email,
"no_telp": no_telp,
"alamat": alamat,
"no_kenderaan": no_kenderaan,
"status": status,
"photo_url": photo_url,
"ktp_url": ktp_url,
"ktp_holding_url": ktp_holding_url,
"kenderaan_url": kenderaan_url,
};
}

View File

@ -0,0 +1,52 @@
import 'package:flutter/material.dart';
// import 'package:get/get.dart';
class BeforeEnterPage extends StatelessWidget {
const BeforeEnterPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
// appBar: AppBar(
// title: const Text('Login'),
// actions: [
// IconButton(
// icon: Icon(Icons.close),
// onPressed: () => Get.offAllNamed(
// '/index',
// arguments: {
// "tap": 0,
// "history": [0],
// },
// ),
// ),
// ],
// ),
body: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
//decoration to gradient
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color.fromARGB(255, 199, 214, 234),
Color.fromARGB(255, 104, 164, 164),
Color.fromARGB(255, 4, 103, 103),
Color.fromARGB(255, 2, 72, 72),
],
),
),
//put logo image in center
child: Center(
child: Image.asset(
'assets/logo.png',
width: MediaQuery.of(context).size.width / 2,
height: MediaQuery.of(context).size.height / 2,
),
),
),
);
}
}

View File

@ -0,0 +1,42 @@
// ignore_for_file: file_names
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:kurir/controller/after_login/kurir/indexController.dart';
import 'package:kurir/pages/after_login/kurir/logHistoryPage.dart';
import 'package:kurir/pages/after_login/kurir/pengaturanPage.dart';
import 'package:kurir/pages/after_login/kurir/pengirimanPage.dart';
import 'package:double_back_to_close_app/double_back_to_close_app.dart';
class KurirIndexPage extends GetView<KurirIndexController> {
const KurirIndexPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: DoubleBackToCloseApp(
child: PageView(
controller: controller.pageController,
children: const [
PengaturanKurirPage(),
PengirimanKurirPage(),
LogHistoryKurirPage(),
],
onPageChanged: (index) {
log("sini on page changed" + index.toString());
// Get.delete<PengaturanKurirController>();
FocusScope.of(context).unfocus();
controller.pageChanged(index);
},
),
snackBar: const SnackBar(
content: Text('Tekan tombol kembali lagi untuk keluar'),
),
),
bottomNavigationBar: Obx(() => controller.bottomNavigationBar(context)),
);
}
}

View File

@ -0,0 +1,26 @@
// ignore_for_file: file_names
import 'package:flutter/material.dart';
import '../../../widgets/boxBackgroundDecoration.dart';
class LogHistoryKurirPage extends StatelessWidget {
const LogHistoryKurirPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const Scaffold(
body: BoxBackgroundDecoration(
child: Center(
child: Text(
'Log History',
style: TextStyle(
fontSize: 30,
color: Colors.white,
),
),
),
),
);
}
}

View File

@ -0,0 +1,233 @@
// ignore_for_file: file_names
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:kurir/controller/after_login/kurir/pengaturanController.dart';
import 'package:kurir/widgets/focusToTextFormField.dart';
import 'package:kurir/widgets/ourContainer.dart';
import 'package:kurir/widgets/thousandSeparator.dart';
import '../../../widgets/boxBackgroundDecoration.dart';
class PengaturanKurirPage extends GetView<PengaturanKurirController> {
const PengaturanKurirPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
// controller.onInit();
return Scaffold(
body: BoxBackgroundDecoration(
child: SingleChildScrollView(
child: Column(
children: [
Image.asset(
'assets/logo.png',
height: MediaQuery.of(context).size.height * 0.30,
width: MediaQuery.of(context).size.width * 0.30,
),
OurContainer(
child: Form(
// autovalidateMode: AutovalidateMode.onUserInteraction,
key: controller.formKey,
child: Column(
children: <Widget>[
const SizedBox(height: 5),
const Text(
'Pengaturan Biaya Pengiriman',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
),
),
const SizedBox(
height: 15,
),
EnsureVisibleWhenFocused(
focusNode: controller.minimalBiayaPengirimanFocusNode,
child: TextFormField(
// initialValue: 700.toString(),
controller:
controller.minimalBiayaPengirimanController,
focusNode: controller.minimalBiayaPengirimanFocusNode,
keyboardType: TextInputType.number,
maxLength: 6,
inputFormatters: [ThousandsSeparatorInputFormatter()],
decoration: InputDecoration(
// suffix: ,
// suffixText: ' / kg',
// put suffixText before prefixText
prefixText: 'Rp . ',
hintText: 'Minimal Biaya Pengiriman',
labelText: 'Minimal Biaya Pengiriman',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
),
validator: (value) {
if (value!.isEmpty) {
return 'Minimal Biaya Pengiriman tidak boleh kosong';
}
if (controller.removeComma(controller
.maksimalBiayaPengirimanController.text) <
controller.removeComma(value)) {
return 'Minimal Biaya Pengiriman tidak boleh lebih besar dari Maksimal Biaya Pengiriman';
}
return null;
},
),
),
const SizedBox(
height: 15,
),
EnsureVisibleWhenFocused(
focusNode: controller.maksimalBiayaPengirimanFocusNode,
child: TextFormField(
controller:
controller.maksimalBiayaPengirimanController,
focusNode:
controller.maksimalBiayaPengirimanFocusNode,
keyboardType: TextInputType.number,
maxLength: 6,
inputFormatters: [ThousandsSeparatorInputFormatter()],
decoration: InputDecoration(
// suffix: ,
// suffixText: ' / kg',
// put suffixText before prefixText
prefixText: 'Rp . ',
hintText: 'Maksimal Biaya Pengiriman',
labelText: 'Maksimal Biaya Pengiriman',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
),
validator: (value) {
if (value!.isEmpty) {
return 'Maksimal Biaya Pengiriman tidak boleh kosong';
}
return null;
},
),
),
const SizedBox(
height: 15,
),
EnsureVisibleWhenFocused(
focusNode: controller.biayaPerKiloFocusNode,
child: TextFormField(
controller: controller.biayaPerKiloController,
focusNode: controller.biayaPerKiloFocusNode,
keyboardType: TextInputType.number,
maxLength: 6,
inputFormatters: [ThousandsSeparatorInputFormatter()],
decoration: InputDecoration(
// suffix: ,
suffixText: ' / km',
// put suffixText before prefixText
prefixText: 'Rp . ',
hintText: 'Biaya Per Kilometer',
labelText: 'Biaya Per Kilometer',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
),
validator: (value) {
if (value!.isEmpty) {
return 'Biaya Per Kilometer tidak boleh kosong';
}
return null;
},
),
),
const SizedBox(
height: 15,
),
ElevatedButton(
onPressed: () {
// log()
if (controller.formKey.currentState!.validate()) {
FocusScope.of(context).unfocus();
// create alert dialog
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: const Text('Konfirmasi'),
content: Text(controller.status.value ==
'Simpan'
? 'Informasi Biaya Pengiriman akan disimpan '
: 'Info Biaya Pengiriman akan diubah '),
actions: [
ElevatedButton(
child: const Text('Tidak'),
style: ElevatedButton.styleFrom(
primary:
Colors.red[400], //background color
// onPrimary: Colors.black, //ripple color
),
onPressed: () {
Navigator.of(context).pop();
},
),
ElevatedButton(
child: const Text('Ya'),
onPressed: () {
controller.simpan();
Navigator.of(context).pop();
},
),
],
);
},
);
}
},
child: Obx(() => Text(
controller.status.value == 'Simpan'
? 'Simpan'
: 'Ubah')),
),
],
),
),
),
const SizedBox(height: 10),
],
),
),
),
// bottomNavigationBar: BottomNavigationBar(
// items: [
// BottomNavigationBarItem(
// icon: Icon(Icons.home),
// label: "Pengaturan",
// ),
// BottomNavigationBarItem(
// icon: Icon(Icons.history),
// label: "Log History",
// ),
// BottomNavigationBarItem(
// icon: Icon(Icons.arrow_back),
// label: "Pengiriman",
// ),
// ],
// currentIndex: 0,
// selectedItemColor: const Color.fromARGB(255, 148, 183, 229),
// ),
);
}
}

View File

@ -0,0 +1,26 @@
// ignore_for_file: file_names
import 'package:flutter/material.dart';
import '../../../widgets/boxBackgroundDecoration.dart';
class PengirimanKurirPage extends StatelessWidget {
const PengirimanKurirPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const Scaffold(
// ignore: unnecessary_const
body: const BoxBackgroundDecoration(
child: Center(
child: Text(
'Pengiriman',
style: TextStyle(
fontSize: 30,
color: Colors.white,
),
)),
),
);
}
}

View File

@ -0,0 +1,62 @@
// ignore_for_file: file_names
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:kurir/controller/after_login/kurir/profileController.dart';
class ProfileKurirPage extends GetView<KurirProfileController> {
const ProfileKurirPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Profile'),
actions: [
IconButton(
icon: const Icon(Icons.logout_outlined),
onPressed: () {
// log("ini untuk logout");
// create get alert dialog
Get.dialog(AlertDialog(
title: const Text('Logout'),
content: const Text('Anda yakin ingin logout?'),
actions: [
ElevatedButton(
child: const Text('Yes'),
onPressed: () {
// log("ini untuk logout");
Get.back();
controller.logout();
},
),
ElevatedButton(
child: const Text('No'),
style: ElevatedButton.styleFrom(
primary: Colors.red[400], //background color
// onPrimary: Colors.black, //ripple color
),
onPressed: () {
Get.back();
},
),
],
));
},
),
],
),
body: WillPopScope(
onWillPop: () async {
Get.offAllNamed(
'/kurirIndex',
);
return false;
},
child: const Center(
child: Text('Profile'),
),
),
);
}
}

View File

@ -0,0 +1,43 @@
// ignore_for_file: file_names
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:kurir/controller/after_login/pengirim/indexController.dart';
import 'package:double_back_to_close_app/double_back_to_close_app.dart';
import 'package:kurir/pages/after_login/pengirim/kirimBarangPage.dart';
import 'package:kurir/pages/after_login/pengirim/listKurirPage.dart';
import 'package:kurir/pages/after_login/pengirim/logKirimanPage.dart';
class PengirimIndexPage extends GetView<PengirimIndexController> {
const PengirimIndexPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
// ignore: unnecessary_const
body: DoubleBackToCloseApp(
child: PageView(
controller: controller.pageController,
children: const [
KirimBarangPage(),
LogKirimanPage(),
ListKurirPage(),
],
onPageChanged: (index) {
log("sini on page changed" + index.toString());
// Get.delete<PengaturanKurirController>();
FocusScope.of(context).unfocus();
controller.pageChanged(index);
},
),
snackBar: const SnackBar(
content: Text('Tekan tombol kembali lagi untuk keluar'),
),
),
bottomNavigationBar: Obx(() => controller.bottomNavigationBar(context)),
);
}
}

View File

@ -0,0 +1,352 @@
// ignore_for_file: file_names
// ignore: unused_import
import 'dart:developer' as dev;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:kurir/controller/after_login/pengirim/kirimBarangController.dart';
import 'package:kurir/widgets/boxBackgroundDecoration.dart';
import 'package:kurir/widgets/ourContainer.dart';
class KirimBarangPage extends GetView<KirimBarangController> {
const KirimBarangPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
// Get.lazyPut<KirimBarangController>(() => KirimBarangController());
return BoxBackgroundDecoration(
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const SizedBox(height: 25),
OurContainer(
child: Form(
key: controller.formKey,
child: Column(
children: [
const SizedBox(height: 5),
GestureDetector(
onTap: () => controller.show_foto(context),
child: Center(
child: Container(
width: 80,
height: 80,
decoration: BoxDecoration(
color: Colors.grey,
borderRadius: BorderRadius.circular(100),
boxShadow: const [
BoxShadow(
color: Colors.grey,
blurRadius: 5,
spreadRadius: 1,
),
],
),
child: Obx(
() => Stack(
// put icon on rigth bottom corner
alignment: Alignment.center,
children: [
(controller.adaFoto.value)
? Container(
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(100),
image: const DecorationImage(
image: AssetImage(
'assets/loading.gif',
),
fit: BoxFit.fill,
),
),
child: Container(
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(100),
image: DecorationImage(
image: MemoryImage(
controller.imagebytes,
),
fit: BoxFit.fill,
),
),
),
)
: const Icon(Icons.add,
color: Colors.white, size: 22),
Positioned(
bottom: 0,
right: 0,
child: GestureDetector(
onTap: () =>
controller.onChooseOption(context),
child: Container(
width: 40,
height: 40,
decoration: BoxDecoration(
color: Colors.blue,
borderRadius:
BorderRadius.circular(100),
),
child: const Icon(
Icons.add_a_photo_outlined,
color: Colors.black,
size: 30,
),
),
),
),
],
),
),
),
),
),
const SizedBox(height: 10),
TextFormField(
controller: controller.namaPenerimaController,
focusNode: controller.namaPenerimaFocusNode,
decoration: InputDecoration(
hintText: 'Masukkan Nama Penerima',
labelText: 'Nama Penerima',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
),
validator: (value) {
if (value!.isEmpty) {
return 'Nama Penerima Tidak Boleh Kosong';
}
return null;
},
),
const SizedBox(height: 20),
TextFormField(
keyboardType: TextInputType.number,
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp(r'[0-9]'),
),
],
controller: controller.noTelponPenerimaController,
focusNode: controller.noTelponPenerimaFocusNode,
maxLength: 13,
decoration: InputDecoration(
hintText: 'Masukkan No Telpon Penerima',
labelText: 'No Telpon Penerima',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
),
validator: (value) {
if (value!.isEmpty) {
return 'Nama Penerima Tidak Boleh Kosong';
}
if (value[0] != '0' && value[1] != '8') {
return 'No Telpon Penerima Tidak Valid';
}
if (value.length < 11) {
return 'Minimal No Telpon Penerima 11 Digit';
}
return null;
},
),
const SizedBox(height: 20),
GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
// log("sini untuk pilih kurir");
controller.pilih_kurir(context);
},
child: TextFormField(
enabled: false,
// initialValue: (controller.selectedKurirNama.value == '')
// ? 'Klik Untuk Pilih Kurir'
// : "ada",
controller: controller.kurirOutroTextController,
style: const TextStyle(
color: Colors.grey,
),
decoration: InputDecoration(
labelText: 'Kurir Penghantar',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
errorStyle: const TextStyle(
color: Colors.red,
),
),
// validator: (value) {
// if (value! == 'Klik Untuk Pilih Kurir') {
// return 'Nama Penerima Tidak Boleh Kosong';
// }
// return null;
// },
),
),
const SizedBox(height: 20),
TextFormField(
controller: controller.alamatPenerimaController,
focusNode: controller.alamatPenerimaFocusNode,
keyboardType: TextInputType.multiline,
textInputAction: TextInputAction.newline,
// minLines: 1,
maxLines: 4,
decoration: InputDecoration(
hintText: 'Masukkan Alamat Penerima',
labelText: 'Alamat Penerima',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
),
validator: (value) {
if (value!.isEmpty) {
return 'Nama Penerima Tidak Boleh Kosong';
}
return null;
},
),
const SizedBox(height: 20),
TextFormField(
controller: controller.biayaKirimController,
enabled: false,
style: const TextStyle(
color: Colors.grey,
),
decoration: InputDecoration(
labelText: 'Biaya Pengiriman',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
errorStyle: const TextStyle(
color: Colors.red,
),
),
// validator: (value) {
// if (value!.isEmpty) {
// return 'Kurir Belum Dipilih @\nLokasi Pengiriman Belum Ditanda @\nLokasi Permulaan Belum Ditanda';
// }
// return null;
// },
),
const SizedBox(height: 20),
TextFormField(
controller: controller.jarakTempuhController,
enabled: false,
style: const TextStyle(
color: Colors.grey,
),
decoration: InputDecoration(
labelText: 'Jarak Tempuh (Km) Kurir',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
errorStyle: const TextStyle(
color: Colors.red,
),
),
// validator: (value) {
// if (value!.isEmpty) {
// return 'Lokasi Pengiriman atau Lokasi Permulaan Belum Ditanda';
// }
// return null;
// },
),
const SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(
width: MediaQuery.of(context).size.width * 0.3,
child: ElevatedButton(
onPressed: () {
// log("sini pin lokasi");
controller.pin_lokasi(context);
},
child: const Text(
'Lokasi Pengiriman',
textAlign: TextAlign.center,
),
),
),
const SizedBox(),
SizedBox(
width: MediaQuery.of(context).size.width * 0.3,
child: ElevatedButton(
onPressed: () {
// create random number
// String number =
// Random().nextInt(99999999).toString();
// controller.kurirOutroTextController.text = number;
// if (controller.formKey.currentState!.validate()) {
// FocusScope.of(context).unfocus();
// controller.konfirmasi_all(context);
// }
controller.pin_lokasi_permulaan(context, "awal");
},
child: const Text(
'Lokasi Permulaan',
textAlign: TextAlign.center,
),
),
),
],
),
Center(
child: SizedBox(
width: MediaQuery.of(context).size.width * 0.3,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.green,
),
onPressed: () {
WidgetsBinding.instance?.focusManager.primaryFocus
?.unfocus();
if (controller.formKey.currentState!.validate()) {
FocusScope.of(context).unfocus();
controller.konfirmasi_all(context);
}
},
child: const Text(
'Konfirmasi',
textAlign: TextAlign.center,
),
),
),
),
],
),
),
),
const SizedBox(
height: 20,
),
],
),
),
);
}
}

View File

@ -0,0 +1,23 @@
// ignore_for_file: file_names
import 'package:flutter/material.dart';
import 'package:kurir/widgets/boxBackgroundDecoration.dart';
class ListKurirPage extends StatelessWidget {
const ListKurirPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const BoxBackgroundDecoration(
child: Center(
child: Text(
'List Kurir',
style: TextStyle(
fontSize: 30,
color: Colors.white,
),
),
),
);
}
}

View File

@ -0,0 +1,91 @@
// ignore_for_file: file_names
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:kurir/controller/after_login/pengirim/logKirimanController.dart';
import 'package:kurir/widgets/boxBackgroundDecoration.dart';
import 'package:kurir/widgets/ourContainer.dart';
class LogKirimanPage extends GetView<LogKirimanController> {
const LogKirimanPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
controller.checkScreenOrientation();
return BoxBackgroundDecoration(
child: SingleChildScrollView(
child: Column(
children: [
const SizedBox(
height: 25,
),
Center(
child: Container(
constraints: BoxConstraints(
maxHeight: MediaQuery.of(context).size.height * 0.85,
minHeight: MediaQuery.of(context).size.height * 0.75,
maxWidth: MediaQuery.of(context).size.width,
),
child: OurContainer(
child: Column(
children: [
const Center(
child: Text(
'Log Kiriman',
style: TextStyle(
fontSize: 20, fontWeight: FontWeight.bold,
// color: Colors.white,
),
),
),
const SizedBox(
height: 20,
),
TextFormField(
decoration: InputDecoration(
hintText: 'Cari Kiriman',
labelText: 'Cari Kiriman',
prefixIcon: Padding(
padding:
const EdgeInsetsDirectional.only(start: 10),
child: GestureDetector(
child: const Icon(
Icons.list_alt_rounded,
color: Colors.blueAccent,
),
onTap: () {},
),
),
suffixIcon: const Icon(Icons.search),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
),
validator: (value) {
if (value!.isEmpty) {
return 'Nama Penerima Tidak Boleh Kosong';
}
return null;
},
),
const SizedBox(
height: 10,
),
Obx(() => controller.widgetLogKiriman.value),
],
),
),
),
),
const SizedBox(
height: 20,
),
],
),
),
);
}
}

View File

@ -0,0 +1,50 @@
// ignore_for_file: file_names
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:kurir/widgets/boxBackgroundDecoration.dart';
class PengirimProfilePage extends StatelessWidget {
const PengirimProfilePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Pengirim Profile'),
actions: [
IconButton(
icon: const Icon(Icons.exit_to_app),
onPressed: () {
log("logout");
},
),
],
),
body: WillPopScope(
onWillPop: () async {
Get.offAllNamed(
'/pengirimIndex',
arguments: {
'tap': 1,
},
);
return false;
},
child: const BoxBackgroundDecoration(
child: Center(
child: Text(
'Pengirim Profile',
style: TextStyle(
fontSize: 30,
color: Colors.white,
),
),
),
),
),
);
}
}

View File

@ -0,0 +1,101 @@
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:kurir/controller/before_login/loginController.dart';
// import 'package:kurir/controller/before_login/indexController.dart';
import '../../widgets/boxBackgroundDecoration.dart';
import '../../widgets/ourContainer.dart';
// class DaftarPage extends GetView<IndexController> {
class DaftarPage extends GetView<LoginController> {
const DaftarPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async => controller.willPopScopeWidget(),
child: Scaffold(
appBar: AppBar(
title: const Text('Daftar'),
),
body: BoxBackgroundDecoration(
child: SingleChildScrollView(
child: Center(
child: Column(
children: [
// set logo.png on top center of screen
Image.asset(
'assets/logo.png',
height: MediaQuery.of(context).size.height * 0.30,
width: MediaQuery.of(context).size.width * 0.30,
),
OurContainer(
child: Column(
children: [
SizedBox(
height: MediaQuery.of(context).size.height * 0.03,
),
SizedBox(
width: double.infinity,
child: Obx(
() => DropdownButtonFormField(
decoration: InputDecoration(
labelText: 'Daftar Sebagai',
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
),
value: controller.selectedRole.value,
items: controller.role.map((String value) {
return DropdownMenuItem(
value: value,
child: Text(value),
);
}).toList(),
onChanged: (item) {
// log(item.toString() + " ini item");
controller.selectedRole.value = item.toString();
},
),
),
),
const SizedBox(
height: 15,
),
SizedBox(
width: MediaQuery.of(context).size.width * 0.3,
child: ElevatedButton(
onPressed: () {
log(controller.selectedRole.value);
if (controller.selectedRole.value == 'Kurir') {
// Get.delete<LoginController>();
Get.offAllNamed('/pendaftaranKurir');
} else if (controller.selectedRole.value ==
'Pengirim') {
Get.offAllNamed('/pendaftaranPengirim');
}
},
child: const Text('Daftar'),
),
),
],
),
),
SizedBox(
height: MediaQuery.of(context).size.height * 0.03,
),
],
),
),
),
),
bottomNavigationBar: Obx(() => controller.bottomNavigationBar()),
),
);
}
}

View File

@ -0,0 +1,39 @@
import 'package:double_back_to_close_app/double_back_to_close_app.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:kurir/controller/before_login/loginController.dart';
// import 'package:kurir/controller/before_login/indexController.dart';
import '../../widgets/boxBackgroundDecoration.dart';
// class IndexPage extends GetView<IndexController> {
class IndexPage extends GetView<LoginController> {
const IndexPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Hompage'),
automaticallyImplyLeading: false,
),
body: const DoubleBackToCloseApp(
child: BoxBackgroundDecoration(
child: Center(
child: Text(
'Hompage',
style: TextStyle(
fontSize: 30,
color: Colors.white,
),
),
),
),
snackBar: SnackBar(
content: Text('Tekan tombol kembali lagi untuk keluar'),
),
),
bottomNavigationBar: Obx(() => controller.bottomNavigationBar()),
);
}
}

View File

@ -0,0 +1,175 @@
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:kurir/widgets/focusToTextFormField.dart';
import 'package:kurir/widgets/ourContainer.dart';
import '../../controller/before_login/loginController.dart';
import '../../widgets/boxBackgroundDecoration.dart';
class LoginPage extends GetView<LoginController> {
const LoginPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async => controller.willPopScopeWidget(),
child: Scaffold(
appBar: AppBar(
title: const Text('Login'),
),
body: BoxBackgroundDecoration(
child: SingleChildScrollView(
child: Center(
child: Form(
key: controller.formKey,
child: Column(
children: [
// set logo.png on top center of screen
Image.asset(
'assets/logo.png',
height: MediaQuery.of(context).size.height * 0.30,
width: MediaQuery.of(context).size.width * 0.30,
),
OurContainer(
child: Column(
children: [
SizedBox(
height: MediaQuery.of(context).size.height * 0.03,
),
SizedBox(
width: double.infinity,
child: Obx(
() => DropdownButtonFormField(
decoration: InputDecoration(
labelText: 'Login Sebagai',
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
),
value: controller.selectedRole.value,
items: controller.role.map((String value) {
return DropdownMenuItem(
value: value,
child: Text(value),
);
}).toList(),
onChanged: (item) {
// log(item.toString() + " ini item");
controller.selectedRole.value =
item.toString();
},
),
),
),
const SizedBox(
height: 15,
),
EnsureVisibleWhenFocused(
focusNode: controller.usernameFocusNode,
child: TextFormField(
//focus node
focusNode: controller.usernameFocusNode,
controller: controller.usernameController,
decoration: InputDecoration(
hintText: 'Masukkan Username',
labelText: 'Username',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
),
validator: (value) {
if (value!.isEmpty) {
controller.usernameFocusNode.requestFocus();
return 'Masukkan Username';
}
return null;
},
),
),
const SizedBox(
height: 15,
),
Obx(
() => EnsureVisibleWhenFocused(
focusNode: controller.passwordFocusNode,
child: TextFormField(
//focus node
focusNode: controller.passwordFocusNode,
controller: controller.passwordController,
obscureText: !controller.passwordVisible.value,
decoration: InputDecoration(
hintText: 'Masukkan Password',
labelText: 'Password',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
suffixIcon: IconButton(
icon: Icon(
Icons.remove_red_eye,
color: controller.passwordVisible.value
? Colors.black
: Colors.grey,
),
onPressed: () {
controller.passwordVisible.value =
!controller.passwordVisible.value;
},
),
),
validator: (value) {
if (value!.isEmpty) {
controller.passwordFocusNode.requestFocus();
return 'Masukkan Password';
}
return null;
},
),
),
),
const SizedBox(
height: 15,
),
SizedBox(
width: MediaQuery.of(context).size.width * 0.3,
child: ElevatedButton(
onPressed: () {
log(controller.selectedRole.value +
" ini selected role di login");
FocusScope.of(context).unfocus();
if (controller.formKey.currentState!
.validate()) {
// controller.wrongPassword.value = true;
controller.login();
}
},
child: const Text('Login'),
),
),
],
),
),
SizedBox(
height: MediaQuery.of(context).size.height * 0.03,
),
],
),
),
),
),
),
bottomNavigationBar: Obx(() => controller.bottomNavigationBar()),
),
);
}
}

View File

@ -0,0 +1,668 @@
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:kurir/controller/before_login/pendaftaranKurirController.dart';
import 'package:kurir/widgets/focusToTextFormField.dart';
import '../../widgets/boxBackgroundDecoration.dart';
import '../../widgets/ourContainer.dart';
// import 'package:image_picker/image_picker.dart';
class PendaftaranKurirPage extends GetView<PendaftaranKurirController> {
const PendaftaranKurirPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
// FocusScope.of(context).unfocus();
return WillPopScope(
onWillPop: () => controller.willPopScopeWidget(),
child: Scaffold(
appBar: AppBar(
title: const Text('Pendaftaran Kurir'),
actions: [
IconButton(
icon: const Icon(Icons.info_outline),
onPressed: () {
controller.intro_message();
// controller.getHttp();
},
),
],
),
body: BoxBackgroundDecoration(
child: SingleChildScrollView(
reverse: false,
child: Center(
child: Form(
key: controller.formKey,
child: Column(
children: [
SizedBox(
height: MediaQuery.of(context).size.height * 0.03,
),
OurContainer(
child: Column(
children: [
SizedBox(
height: MediaQuery.of(context).size.height * 0.02,
),
const Text(
'Detail Login',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
const SizedBox(
height: 15,
),
EnsureVisibleWhenFocused(
focusNode: controller.usernameFocusNode,
child: TextFormField(
//focus node
focusNode: controller.usernameFocusNode,
controller: controller.usernameController,
decoration: InputDecoration(
hintText: 'Username',
labelText: 'Username',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
),
validator: (value) {
if (value!.isEmpty) {
// request focus
// FocusScope.of(context).unfocus();
controller.usernameFocusNode.requestFocus();
return 'Username Harus Terisi';
}
return null;
},
),
),
const SizedBox(
height: 15,
),
Obx(
() => EnsureVisibleWhenFocused(
focusNode: controller.passwordFocusNode,
child: TextFormField(
//focus node
focusNode: controller.passwordFocusNode,
controller: controller.passwordController,
obscureText: controller.passwordVisible.value,
decoration: InputDecoration(
hintText: 'Password',
labelText: 'Password',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
suffixIcon: IconButton(
icon: Icon(
Icons.remove_red_eye,
color: !controller.passwordVisible.value
? Colors.black
: Colors.grey,
),
onPressed: () {
controller.passwordVisible.value =
!controller.passwordVisible.value;
},
),
),
validator: (value) {
// log(value!.length.toString() +
// "ini panjangnya");
if (value!.isEmpty) {
controller.passwordFocusNode.requestFocus();
return 'Password Harus Terisi';
} else if (value.length < 8) {
controller.passwordFocusNode.requestFocus();
return 'Password Minimal 8 Karakter';
} else if (value.toString() !=
controller
.konfirmasiPasswordController.text
.toString()) {
controller.passwordFocusNode.requestFocus();
return 'Password tidak sama dengan konfirmasi password';
}
return null;
},
),
),
),
const SizedBox(
height: 15,
),
Obx(
() => EnsureVisibleWhenFocused(
focusNode: controller.konfirmasiPasswordFocusNode,
child: TextFormField(
//focus node
focusNode:
controller.konfirmasiPasswordFocusNode,
controller:
controller.konfirmasiPasswordController,
obscureText:
controller.konfirmasiPasswordVisible.value,
decoration: InputDecoration(
hintText: 'Konfirmasi Password',
labelText: 'Konfirmasi Password',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
suffixIcon: IconButton(
icon: Icon(
Icons.remove_red_eye,
color: !controller
.konfirmasiPasswordVisible.value
? Colors.black
: Colors.grey,
),
onPressed: () {
controller
.konfirmasiPasswordVisible.value =
!controller
.konfirmasiPasswordVisible.value;
},
),
),
validator: (value) {
// log('konfirmasi pasword = $value');
if (value!.isEmpty) {
controller.konfirmasiPasswordFocusNode
.requestFocus();
return 'Konfirmasi Password Harus Terisi';
} else if (value.toString() !=
controller.passwordController.text
.toString()) {
controller.konfirmasiPasswordFocusNode
.requestFocus();
return 'Password tidak sama dengan konfirmasi password';
}
return null;
},
),
),
),
],
),
),
SizedBox(
height: MediaQuery.of(context).size.height * 0.03,
),
OurContainer(
child: Column(
children: [
SizedBox(
height: MediaQuery.of(context).size.height * 0.02,
),
const Text(
'Detail Kurir',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
const SizedBox(
height: 15,
),
EnsureVisibleWhenFocused(
focusNode: controller.nikFocusNode,
child: TextFormField(
//focus node
focusNode: controller.nikFocusNode,
controller: controller.nikController,
maxLength: 16,
keyboardType: TextInputType.number,
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp(r'[0-9]'),
),
],
decoration: InputDecoration(
hintText: 'NIK',
labelText: 'NIK',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
),
validator: (value) {
if (value!.isEmpty) {
controller.nikFocusNode.requestFocus();
return 'NIK Harus Terisi';
} else if (value.length < 16) {
controller.nikFocusNode.requestFocus();
return 'NIK Harus 16 Karakter';
}
return null;
},
),
),
const SizedBox(
height: 15,
),
EnsureVisibleWhenFocused(
focusNode: controller.namaFocusNode,
child: TextFormField(
//focus node
focusNode: controller.namaFocusNode,
controller: controller.namaController,
decoration: InputDecoration(
hintText: 'Nama Sesuai KTP',
labelText: 'Nama',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
),
validator: (value) {
if (value!.isEmpty) {
controller.namaFocusNode.requestFocus();
return 'Nama Harus Terisi \n Sesuai Nama Di KTP';
}
return null;
},
),
),
const SizedBox(
height: 15,
),
EnsureVisibleWhenFocused(
focusNode: controller.emailFocusNode,
child: TextFormField(
//focus node
focusNode: controller.emailFocusNode,
controller: controller.emailController,
decoration: InputDecoration(
hintText: 'Email',
labelText: 'Email',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
),
validator: (value) {
// log(controller
// .email_checker(value!)
// .toString());
if (value!.isEmpty) {
controller.emailFocusNode.requestFocus();
return 'Email Harus Terisi \n Untuk Konfimasi Pendaftaran Akun \n Pastikan Gunakan Email Yang Valid';
} else if (!controller.email_checker(value)) {
controller.emailFocusNode.requestFocus();
return 'Email Tidak Valid';
}
return null;
},
),
),
const SizedBox(
height: 15,
),
EnsureVisibleWhenFocused(
focusNode: controller.noTelpFocusNode,
child: TextFormField(
//focus node
focusNode: controller.noTelpFocusNode,
controller: controller.noTelpController,
maxLength: 13,
keyboardType: TextInputType.number,
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp(r'[0-9]'),
),
],
decoration: InputDecoration(
hintText: 'No Telpon',
labelText: 'No Telpon',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
),
validator: (value) {
if (value!.isEmpty) {
controller.noTelpFocusNode.requestFocus();
return 'No Telpon Harus Terisi \n Dengan Nomor Yang Valid';
} else if (value.length < 11) {
controller.noTelpFocusNode.requestFocus();
return 'No Telpon Minimal Harus 11 Karakter';
// ignore: unrelated_type_equality_checks
} else if (int.parse(value[0]) != 0 &&
// ignore: unrelated_type_equality_checks
int.parse(value[1]) != 8) {
controller.noTelpFocusNode.requestFocus();
return 'Format No Telpon Tidak Valid';
}
return null;
},
),
),
const SizedBox(
height: 15,
),
EnsureVisibleWhenFocused(
focusNode: controller.alamatFocusNode,
child: TextFormField(
//focus node
focusNode: controller.alamatFocusNode,
controller: controller.alamatController,
decoration: InputDecoration(
hintText: 'Alamat',
labelText: 'Alamat',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
),
validator: (value) {
if (value!.isEmpty) {
controller.alamatFocusNode.requestFocus();
return 'Alamat Harus Terisi';
}
return null;
},
),
),
const SizedBox(
height: 15,
),
EnsureVisibleWhenFocused(
focusNode: controller.noPlatFocusNode,
child: TextFormField(
//focus node
focusNode: controller.noPlatFocusNode,
controller: controller.noPlatController,
decoration: InputDecoration(
hintText: 'No Plat Kenderaan',
labelText: 'No Plat Kenderaan',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
),
validator: (value) {
if (value!.isEmpty) {
controller.noPlatFocusNode.requestFocus();
return 'No Plat Kenderaan Harus Terisi';
}
return null;
},
),
),
const SizedBox(
height: 15,
),
Obx(
() => GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
// log("sini ontap foto profil");
controller.onChooseOption('profil');
},
onDoubleTap: () => [
controller.isAdaFotoProfil.value
? controller.showFoto('profil')
: log("tidak ada profil"),
FocusScope.of(context).unfocus()
],
child: EnsureVisibleWhenFocused(
focusNode: controller.fotoProfilFocusNode,
child: TextFormField(
//focus node
focusNode: controller.fotoProfilFocusNode,
initialValue: '',
enabled: false,
decoration: InputDecoration(
labelText: controller.isAdaFotoProfil.value
? 'Klik 2x Untuk Melihat Foto Profil'
: 'Foto Profil Belum Di Upload',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
errorStyle: const TextStyle(
color: Colors.red,
// fontSize: 12,
),
),
validator: (value) {
if (!controller.isAdaFotoProfil.value) {
FocusScope.of(context).unfocus();
controller.fotoProfilFocusNode
.requestFocus();
return 'Foto Profil Belum Di Upload\nKlik Field Ini Untuk Upload Foto Profil';
}
return null;
},
),
),
),
),
const SizedBox(
height: 15,
),
Obx(
() => GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
// log("sini ontap foto");
controller.onChooseOption('ktp');
},
onDoubleTap: () => [
controller.isAdaFotoKTP.value
? controller.showFoto('ktp')
: log("tidak ada foto"),
FocusScope.of(context).unfocus()
],
child: EnsureVisibleWhenFocused(
focusNode: controller.fotoKTPFocusNode,
child: TextFormField(
//focus node
focusNode: controller.fotoKTPFocusNode,
initialValue: '',
enabled: false,
decoration: InputDecoration(
labelText: controller.isAdaFotoKTP.value
? 'Klik 2x Untuk Melihat Foto KTP'
: 'Foto KTP Belum Di Upload',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
errorStyle: const TextStyle(
color: Colors.red,
// fontSize: 12,
),
),
validator: (value) {
if (!controller.isAdaFotoKTP.value) {
FocusScope.of(context).unfocus();
controller.fotoKTPFocusNode
.requestFocus();
return 'Foto KTP Belum Di Upload\nKlik Field Ini Untuk Upload Foto KTP';
}
return null;
},
),
),
),
),
const SizedBox(
height: 15,
),
Obx(
() => GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
// log("sini ontap ktp holding");
controller.onChooseOption('ktp_holding');
},
onDoubleTap: () => [
controller.isAdaFotoKTPHolding.value
? controller.showFoto('ktp_holding')
: log("tidak ada foto"),
FocusScope.of(context).unfocus()
],
child: EnsureVisibleWhenFocused(
focusNode: controller.fotoHoldingKTPFocusNode,
child: TextFormField(
//focus node
focusNode: controller.fotoHoldingKTPFocusNode,
enabled: false,
initialValue: '',
decoration: InputDecoration(
labelText: controller
.isAdaFotoKTPHolding.value
? 'Klik 2x Untuk Melihat Foto Memegang KTP'
: 'Foto Memegang KTP ',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
errorStyle: const TextStyle(
color: Colors.red,
// fontSize: 12,
),
),
validator: (value) {
if (!controller.isAdaFotoKTPHolding.value) {
FocusScope.of(context).unfocus();
controller.fotoHoldingKTPFocusNode
.requestFocus();
return 'Foto Memegang KTP Belum Di Upload\nKlik Field Ini Untuk Upload Foto Memegang KTP';
}
return null;
},
),
),
),
),
const SizedBox(
height: 15,
),
Obx(
() => GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
// log("sini ontap kendaraan");
controller.onChooseOption('kendaraan');
},
onDoubleTap: () => [
controller.isAdaKenderaan.value
? controller.showFoto('kendaraan')
: log("tidak ada foto"),
FocusScope.of(context).unfocus()
],
child: EnsureVisibleWhenFocused(
focusNode: controller.fotoKendaraanFocusNode,
child: TextFormField(
//focus node
focusNode: controller.fotoKendaraanFocusNode,
enabled: false,
initialValue: '',
decoration: InputDecoration(
labelText: controller.isAdaKenderaan.value
? 'Klik 2x Untuk Melihat Foto Kendaraan'
: 'Foto Kendaraan ',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
errorStyle: const TextStyle(
color: Colors.red,
// fontSize: 12,
),
),
validator: (value) {
if (!controller.isAdaKenderaan.value) {
FocusScope.of(context).unfocus();
controller.fotoKendaraanFocusNode
.requestFocus();
return 'Foto Kendaraan Belum Di Upload\nKlik Field Ini Untuk Upload Foto Kendaraan';
}
return null;
},
),
),
),
),
],
),
),
SizedBox(
height: MediaQuery.of(context).size.height * 0.03,
),
SizedBox(
width: MediaQuery.of(context).size.width * 0.3,
child: ElevatedButton(
onPressed: () {
if (controller.formKey.currentState!.validate()) {
FocusScope.of(context).unfocus();
// log("jalankan");
controller.before_sign_up();
} else {
Get.snackbar(
'Error',
'Mohon Lengkapi Data',
icon: const Icon(
Icons.error,
color: Colors.white,
),
backgroundColor: Colors.orange[400],
colorText: Colors.white,
);
}
},
child: const Text('Daftar'),
),
),
SizedBox(
height: MediaQuery.of(context).size.height * 0.03,
),
],
),
),
),
),
),
),
);
}
}

View File

@ -0,0 +1,431 @@
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:kurir/controller/before_login/pendaftaranPengirimController.dart';
import 'package:kurir/widgets/boxBackgroundDecoration.dart';
import 'package:kurir/widgets/focusToTextFormField.dart';
import 'package:kurir/widgets/ourContainer.dart';
class PendaftaranPengirimPage extends GetView<PendaftaranPengirimController> {
const PendaftaranPengirimPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async => controller.willPopScopeWidget(),
child: Scaffold(
appBar: AppBar(
title: const Text('Pendaftaran Pengirim'),
actions: [
IconButton(
onPressed: () => controller.intro_message(),
icon: const Icon(Icons.info_outline),
),
],
),
body: BoxBackgroundDecoration(
child: SingleChildScrollView(
child: Center(
child: Form(
key: controller.formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
height: MediaQuery.of(context).size.height * 0.03,
),
OurContainer(
child: Column(
children: [
SizedBox(
height: MediaQuery.of(context).size.height * 0.01,
),
const Text(
'Pendaftaran Pengirim',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
const SizedBox(
height: 15,
),
EnsureVisibleWhenFocused(
focusNode: controller.usernameFocusNode,
child: TextFormField(
focusNode: controller.usernameFocusNode,
controller: controller.usernameController,
decoration: InputDecoration(
hintText: 'Username',
labelText: 'Username',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
),
validator: (value) {
if (value!.isEmpty) {
// request focus
controller.usernameFocusNode.requestFocus();
return 'Username Harus Terisi';
} else if (value.length < 6) {
return 'Username Minimal 6 Karakter';
}
return null;
},
),
),
const SizedBox(
height: 15,
),
Obx(
() => EnsureVisibleWhenFocused(
focusNode: controller.passwordFocusNode,
child: TextFormField(
//focus node
focusNode: controller.passwordFocusNode,
controller: controller.passwordController,
obscureText: !controller.passwordVisible.value,
decoration: InputDecoration(
hintText: 'Password',
labelText: 'Password',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
suffixIcon: IconButton(
icon: Icon(
Icons.remove_red_eye,
color: controller.passwordVisible.value
? Colors.black
: Colors.grey,
),
onPressed: () {
controller.passwordVisible.value =
!controller.passwordVisible.value;
},
),
),
validator: (value) {
// log(value!.length.toString() +
// "ini panjangnya");
if (value!.isEmpty) {
controller.passwordFocusNode.requestFocus();
return 'Password Harus Terisi';
} else if (value.length < 8) {
controller.passwordFocusNode.requestFocus();
return 'Password Minimal 8 Karakter';
} else if (value.toString() !=
controller
.konfirmasiPasswordController.text
.toString()) {
controller.passwordFocusNode.requestFocus();
return 'Password tidak sama dengan konfirmasi password';
}
return null;
},
),
),
),
const SizedBox(
height: 15,
),
Obx(
() => EnsureVisibleWhenFocused(
focusNode: controller.konfirmasiPasswordFocusNode,
child: TextFormField(
//focus node
focusNode:
controller.konfirmasiPasswordFocusNode,
controller:
controller.konfirmasiPasswordController,
obscureText:
!controller.konfirmasiPasswordVisible.value,
decoration: InputDecoration(
hintText: 'Konfirmasi Password',
labelText: 'Konfirmasi Password',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
suffixIcon: IconButton(
icon: Icon(
Icons.remove_red_eye,
color: controller
.konfirmasiPasswordVisible.value
? Colors.black
: Colors.grey,
),
onPressed: () {
controller
.konfirmasiPasswordVisible.value =
!controller
.konfirmasiPasswordVisible.value;
},
),
),
validator: (value) {
// log('konfirmasi pasword = $value');
if (value!.isEmpty) {
controller.konfirmasiPasswordFocusNode
.requestFocus();
return 'Konfirmasi Password Harus Terisi';
} else if (value.toString() !=
controller.passwordController.text
.toString()) {
controller.konfirmasiPasswordFocusNode
.requestFocus();
return 'Password tidak sama dengan konfirmasi password';
}
return null;
},
),
),
),
],
),
),
SizedBox(
height: MediaQuery.of(context).size.height * 0.03,
),
OurContainer(
child: Column(
children: [
SizedBox(
height: MediaQuery.of(context).size.height * 0.01,
),
const Text(
'Detail Pengirim',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
const SizedBox(
height: 15,
),
EnsureVisibleWhenFocused(
focusNode: controller.namaFocusNode,
child: TextFormField(
focusNode: controller.namaFocusNode,
controller: controller.namaController,
decoration: InputDecoration(
hintText: 'Masukkan Nama',
labelText: 'Nama',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
),
validator: (value) {
if (value!.isEmpty) {
// request focus
controller.usernameFocusNode.requestFocus();
return 'Nama Harus Terisi';
}
return null;
},
),
),
const SizedBox(
height: 15,
),
EnsureVisibleWhenFocused(
focusNode: controller.emailFocusNode,
child: TextFormField(
focusNode: controller.emailFocusNode,
controller: controller.emailController,
decoration: InputDecoration(
hintText: 'Masukkan Email',
labelText: 'Email',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
),
validator: (value) {
if (value!.isEmpty) {
// request focus
controller.emailFocusNode.requestFocus();
return 'Email Harus Terisi';
} else if (controller
.email_checker(value.toString()) ==
false) {
controller.emailFocusNode.requestFocus();
return 'Email Tidak Valid';
}
return null;
},
),
),
const SizedBox(
height: 15,
),
EnsureVisibleWhenFocused(
focusNode: controller.noTelpFocusNode,
child: TextFormField(
//focus node
focusNode: controller.noTelpFocusNode,
controller: controller.noTelpController,
maxLength: 13,
keyboardType: TextInputType.number,
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp(r'[0-9]'),
),
],
decoration: InputDecoration(
hintText: ' Masukkan No Telpon',
labelText: 'No Telpon',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
),
validator: (value) {
if (value!.isEmpty) {
controller.noTelpFocusNode.requestFocus();
return 'No Telpon Harus Terisi \n Dengan Nomor Yang Valid';
} else if (value.length < 11) {
controller.noTelpFocusNode.requestFocus();
return 'No Telpon Minimal Harus 11 Karakter';
// ignore: unrelated_type_equality_checks
} else if (int.parse(value[0]) != 0 &&
// ignore: unrelated_type_equality_checks
int.parse(value[1]) != 8) {
controller.noTelpFocusNode.requestFocus();
return 'Format No Telpon Tidak Valid';
}
return null;
},
),
),
const SizedBox(
height: 15,
),
EnsureVisibleWhenFocused(
focusNode: controller.alamatFocusNode,
child: TextFormField(
//focus node
focusNode: controller.alamatFocusNode,
controller: controller.alamatController,
decoration: InputDecoration(
hintText: ' Masukkan Alamat',
labelText: 'Alamat',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
),
validator: (value) {
if (value!.isEmpty) {
controller.alamatFocusNode.requestFocus();
return 'Alamat Harus Terisi';
}
return null;
},
),
),
const SizedBox(
height: 15,
),
Obx(
() => GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
// log("sini ontap foto profil");
controller.onChooseOption('profil');
},
onDoubleTap: () => [
controller.isAdaFotoProfil.value
? controller.showFoto('profil')
: log("tidak ada profil"),
FocusScope.of(context).unfocus()
],
child: TextFormField(
initialValue: '',
enabled: false,
decoration: InputDecoration(
labelText: controller.isAdaFotoProfil.value
? 'Klik 2x Untuk Melihat Foto Profil'
: 'Foto Profil Belum Di Upload',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
errorStyle: const TextStyle(
color: Colors.red,
// fontSize: 12,
),
),
validator: (value) {
if (!controller.isAdaFotoProfil.value) {
FocusScope.of(context).unfocus();
return 'Foto Profil Belum Di Upload\nKlik Field Ini Untuk Upload Foto Profil';
}
return null;
},
),
),
),
],
),
),
SizedBox(
height: MediaQuery.of(context).size.height * 0.03,
),
SizedBox(
width: MediaQuery.of(context).size.width * 0.3,
child: ElevatedButton(
onPressed: () {
if (controller.formKey.currentState!.validate()) {
FocusScope.of(context).unfocus();
// log("jalankan");
controller.before_sign_up(context);
} else {
Get.snackbar(
'Error',
'Mohon Lengkapi Data',
icon: const Icon(
Icons.error,
color: Colors.white,
),
backgroundColor: Colors.orange[400],
colorText: Colors.white,
);
}
},
child: const Text('Daftar'),
),
),
SizedBox(
height: MediaQuery.of(context).size.height * 0.03,
),
],
),
),
),
),
),
),
);
}
}

117
lib/routes/routes.dart Normal file
View File

@ -0,0 +1,117 @@
import 'package:flutter/animation.dart';
import 'package:get/get.dart';
import 'package:kurir/binding/beforeEnterBinding.dart';
import 'package:kurir/binding/kurirIndexBinding.dart';
import 'package:kurir/binding/kurirProfileBinding.dart';
// import 'package:kurir/binding/indexBinding.dart';
import 'package:kurir/binding/pendaftaranKurirBinding.dart';
import 'package:kurir/binding/pengirimIndexBinding.dart';
import 'package:kurir/pages/after_login/before_enter.dart';
import 'package:kurir/pages/after_login/kurir/profilePage.dart';
import 'package:kurir/pages/after_login/pengirim/pengirimProfilePage.dart';
import 'package:kurir/pages/before_login/daftar.dart';
import 'package:kurir/pages/before_login/login.dart';
import '../binding/loginBinding.dart';
import '../binding/pendaftaranPengirim.dart';
import '../binding/splashBinding.dart';
import '../pages/after_login/kurir/indexPage.dart';
import '../pages/after_login/pengirim/indexPage.dart';
import '../pages/before_login/index.dart';
import '../pages/before_login/pendaftaran_kurir.dart';
import '../pages/before_login/pendaftaran_pengirirm.dart';
import '../splashScreen.dart';
class Routes {
List<GetPage<dynamic>> get routes {
return [
GetPage(
name: '/splash',
page: () => const SplashScreen(),
binding: SplashBinding(),
transition: Transition.native,
transitionDuration: const Duration(seconds: 1),
curve: Curves.easeInOut,
),
GetPage(
name: '/index',
page: () => const IndexPage(),
// binding: IndexBinding(),
binding: LoginBinding(),
transition: Transition.cupertino,
transitionDuration: const Duration(seconds: 1),
curve: Curves.easeInOut,
),
GetPage(
name: '/daftar',
page: () => const DaftarPage(),
binding: LoginBinding(),
// binding: IndexBinding(),
transition: Transition.cupertino,
transitionDuration: const Duration(seconds: 1),
curve: Curves.easeInOut,
),
GetPage(
name: '/login',
page: () => const LoginPage(),
binding: LoginBinding(),
transition: Transition.cupertino,
transitionDuration: const Duration(seconds: 1),
curve: Curves.easeInOut,
),
GetPage(
name: '/pendaftaranKurir',
page: () => const PendaftaranKurirPage(),
binding: PendaftaranKurirBinding(),
transition: Transition.cupertino,
transitionDuration: const Duration(seconds: 1),
curve: Curves.easeInOut,
),
GetPage(
name: '/pendaftaranPengirim',
page: () => const PendaftaranPengirimPage(),
binding: PendaftaranPengirimBinding(),
transition: Transition.native,
transitionDuration: const Duration(seconds: 1),
curve: Curves.easeInOut,
),
GetPage(
name: '/beforeEnter',
page: () => const BeforeEnterPage(),
binding: BeforeEnterBinding(),
transition: Transition.native,
transitionDuration: const Duration(seconds: 1),
curve: Curves.easeInOut,
),
GetPage(
name: '/kurirIndex',
page: () => const KurirIndexPage(),
binding: KurirIndexBinding(),
transition: Transition.native,
transitionDuration: const Duration(seconds: 1),
curve: Curves.easeInOut,
),
GetPage(
name: '/profileKurir',
page: () => const ProfileKurirPage(),
binding: KurirProfileBinding(),
transition: Transition.native,
transitionDuration: const Duration(seconds: 1),
curve: Curves.easeInOut,
),
GetPage(
name: '/pengirimIndex',
page: () => const PengirimIndexPage(),
binding: PengirimIndexBinding(),
transition: Transition.native,
transitionDuration: const Duration(seconds: 1),
),
GetPage(
name: '/profilePengirim',
page: () => const PengirimProfilePage(),
transition: Transition.native,
transitionDuration: const Duration(seconds: 1),
)
];
}
}

38
lib/splashScreen.dart Normal file
View File

@ -0,0 +1,38 @@
// ignore_for_file: file_names
import 'package:flutter/material.dart';
class SplashScreen extends StatelessWidget {
const SplashScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
//decoration to gradient
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color.fromARGB(255, 199, 214, 234),
Color.fromARGB(255, 104, 164, 164),
Color.fromARGB(255, 4, 103, 103),
Color.fromARGB(255, 2, 72, 72),
],
),
),
//put logo image in center
child: Center(
child: Image.asset(
'assets/logo.png',
width: MediaQuery.of(context).size.width / 2,
height: MediaQuery.of(context).size.height / 2,
),
),
),
);
}
}

View File

@ -0,0 +1,33 @@
// ignore_for_file: file_names
import 'package:flutter/material.dart';
class BoxBackgroundDecoration extends StatelessWidget {
final Widget? child;
const BoxBackgroundDecoration({
Key? key,
this.child,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
// decoration gradient
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color.fromARGB(255, 199, 214, 234),
Color.fromARGB(255, 104, 164, 164),
Color.fromARGB(255, 4, 103, 103),
Color.fromARGB(255, 2, 72, 72),
],
),
),
child: child,
);
}
}

View File

@ -0,0 +1,166 @@
// ignore_for_file: file_names
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
// import 'package:meta/meta.dart';
///
/// Helper class that ensures a Widget is visible when it has the focus
/// For example, for a TextFormField when the keyboard is displayed
///
/// How to use it:
///
/// In the class that implements the Form,
/// Instantiate a FocusNode
/// FocusNode _focusNode = new FocusNode();
///
/// In the build(BuildContext context), wrap the TextFormField as follows:
///
/// new EnsureVisibleWhenFocused(
/// focusNode: _focusNode,
/// child: new TextFormField(
/// ...
/// focusNode: _focusNode,
/// ),
/// ),
///
/// Initial source code written by Collin Jackson.
/// Extended (see highlighting) to cover the case when the keyboard is dismissed and the
/// user clicks the TextFormField/TextField which still has the focus.
///
class EnsureVisibleWhenFocused extends StatefulWidget {
const EnsureVisibleWhenFocused({
Key? key,
required this.child,
required this.focusNode,
this.curve = Curves.ease,
this.duration = const Duration(milliseconds: 100),
}) : super(key: key);
/// The node we will monitor to determine if the child is focused
final FocusNode focusNode;
/// The child widget that we are wrapping
final Widget child;
/// The curve we will use to scroll ourselves into view.
///
/// Defaults to Curves.ease.
final Curve curve;
/// The duration we will use to scroll ourselves into view
///
/// Defaults to 100 milliseconds.
final Duration duration;
@override
_EnsureVisibleWhenFocusedState createState() =>
_EnsureVisibleWhenFocusedState();
}
///
/// We implement the WidgetsBindingObserver to be notified of any change to the window metrics
///
class _EnsureVisibleWhenFocusedState extends State<EnsureVisibleWhenFocused>
with WidgetsBindingObserver {
@override
void initState() {
super.initState();
widget.focusNode.addListener(_ensureVisible);
WidgetsBinding.instance!.addObserver(this);
}
@override
void dispose() {
WidgetsBinding.instance!.removeObserver(this);
widget.focusNode.removeListener(_ensureVisible);
super.dispose();
}
///
/// This routine is invoked when the window metrics have changed.
/// This happens when the keyboard is open or dismissed, among others.
/// It is the opportunity to check if the field has the focus
/// and to ensure it is fully visible in the viewport when
/// the keyboard is displayed
///
@override
void didChangeMetrics() {
if (widget.focusNode.hasFocus) {
_ensureVisible();
}
}
///
/// This routine waits for the keyboard to come into view.
/// In order to prevent some issues if the Widget is dismissed in the
/// middle of the loop, we need to check the "mounted" property
///
/// This method was suggested by Peter Yuen (see discussion).
///
Future<void> _keyboardToggled() async {
if (mounted) {
EdgeInsets edgeInsets = MediaQuery.of(context).viewInsets;
while (mounted && MediaQuery.of(context).viewInsets == edgeInsets) {
await Future.delayed(const Duration(milliseconds: 10));
}
}
return;
}
Future<void> _ensureVisible() async {
// Wait for the keyboard to come into view
await Future.any([
Future.delayed(const Duration(milliseconds: 300)),
_keyboardToggled()
]);
// No need to go any further if the node has not the focus
if (!widget.focusNode.hasFocus) {
return;
}
// Find the object which has the focus
final RenderObject? object = context.findRenderObject();
final RenderAbstractViewport? viewport = RenderAbstractViewport.of(object);
// If we are not working in a Scrollable, skip this routine
if (viewport == null) {
return;
}
// Get the Scrollable state (in order to retrieve its offset)
ScrollableState? scrollableState = Scrollable.of(context);
assert(scrollableState != null);
// Get its offset
ScrollPosition position = scrollableState!.position;
double alignment;
if (position.pixels > viewport.getOffsetToReveal(object!, 0.0).offset) {
// Move down to the top of the viewport
alignment = 0.0;
} else if (position.pixels <
viewport.getOffsetToReveal(object, 1.0).offset) {
// Move up to the bottom of the viewport
alignment = 1.0;
} else {
// No scrolling is necessary to reveal the child
return;
}
position.ensureVisible(
object,
alignment: alignment,
duration: widget.duration,
curve: widget.curve,
);
}
@override
Widget build(BuildContext context) {
return widget.child;
}
}

View File

@ -0,0 +1,35 @@
// ignore_for_file: file_names
import 'package:flutter/material.dart';
class OurContainer extends StatelessWidget {
final Widget? child;
const OurContainer({Key? key, this.child}) : super(key: key);
@override
Widget build(BuildContext context) {
final double left = (MediaQuery.of(context).size.width -
(MediaQuery.of(context).size.width * 0.9)) /
2;
return Container(
width: MediaQuery.of(context).size.width * 0.9,
margin: EdgeInsets.only(left: left, right: left),
padding: const EdgeInsets.only(left: 20, right: 15, bottom: 20, top: 10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
boxShadow: const [
BoxShadow(
color: Colors.grey,
blurRadius: 10,
spreadRadius: 1,
offset: Offset(
4,
4,
),
),
]),
child: child,
);
}
}

View File

@ -0,0 +1,50 @@
// ignore_for_file: file_names
import 'package:flutter/services.dart';
class ThousandsSeparatorInputFormatter extends TextInputFormatter {
static const separator = ','; // Change this to '.' for other locales
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue, TextEditingValue newValue) {
// Short-circuit if the new value is empty
if (newValue.text.isEmpty) {
return newValue.copyWith(text: '');
}
// Handle "deletion" of separator character
String oldValueText = oldValue.text.replaceAll(separator, '');
String newValueText = newValue.text.replaceAll(separator, '');
if (oldValue.text.endsWith(separator) &&
oldValue.text.length == newValue.text.length + 1) {
newValueText = newValueText.substring(0, newValueText.length - 1);
}
// Only process if the old value and new value are different
if (oldValueText != newValueText) {
int selectionIndex =
newValue.text.length - newValue.selection.extentOffset;
final chars = newValueText.split('');
String newString = '';
for (int i = chars.length - 1; i >= 0; i--) {
if ((chars.length - 1 - i) % 3 == 0 && i != chars.length - 1) {
newString = separator + newString;
}
newString = chars[i] + newString;
}
return TextEditingValue(
text: newString.toString(),
selection: TextSelection.collapsed(
offset: newString.length - selectionIndex,
),
);
}
// If the new value and old value are the same, just return as-is
return newValue;
}
}

551
pubspec.lock Normal file
View File

@ -0,0 +1,551 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.8.2"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
charcode:
dependency: transitive
description:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.1"
clock:
dependency: transitive
description:
name: clock
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.15.0"
cross_file:
dependency: transitive
description:
name: cross_file
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.2"
crypto:
dependency: "direct main"
description:
name: crypto
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
cupertino_icons:
dependency: "direct main"
description:
name: cupertino_icons
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.4"
double_back_to_close_app:
dependency: "direct main"
description:
name: double_back_to_close_app
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
fake_async:
dependency: transitive
description:
name: fake_async
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
ffi:
dependency: transitive
description:
name: ffi
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.2"
file:
dependency: transitive
description:
name: file
url: "https://pub.dartlang.org"
source: hosted
version: "6.1.2"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_easyloading:
dependency: "direct main"
description:
name: flutter_easyloading
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.3"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.4"
flutter_plugin_android_lifecycle:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.5"
flutter_polyline_points:
dependency: "direct main"
description:
name: flutter_polyline_points
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
flutter_slidable:
dependency: "direct main"
description:
name: flutter_slidable
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0"
flutter_spinkit:
dependency: transitive
description:
name: flutter_spinkit
url: "https://pub.dartlang.org"
source: hosted
version: "5.1.0"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
flutter_web_plugins:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
geocoding:
dependency: "direct main"
description:
name: geocoding
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.4"
geocoding_platform_interface:
dependency: transitive
description:
name: geocoding_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
get:
dependency: "direct main"
description:
name: get
url: "https://pub.dartlang.org"
source: hosted
version: "4.6.1"
get_storage:
dependency: "direct main"
description:
name: get_storage
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.3"
google_maps_flutter:
dependency: "direct main"
description:
name: google_maps_flutter
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.6"
google_maps_flutter_platform_interface:
dependency: transitive
description:
name: google_maps_flutter_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.7"
http:
dependency: "direct main"
description:
name: http
url: "https://pub.dartlang.org"
source: hosted
version: "0.13.4"
http_parser:
dependency: transitive
description:
name: http_parser
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.0"
image_picker:
dependency: "direct main"
description:
name: image_picker
url: "https://pub.dartlang.org"
source: hosted
version: "0.8.5"
image_picker_android:
dependency: transitive
description:
name: image_picker_android
url: "https://pub.dartlang.org"
source: hosted
version: "0.8.4+11"
image_picker_for_web:
dependency: transitive
description:
name: image_picker_for_web
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.6"
image_picker_ios:
dependency: transitive
description:
name: image_picker_ios
url: "https://pub.dartlang.org"
source: hosted
version: "0.8.4+11"
image_picker_platform_interface:
dependency: transitive
description:
name: image_picker_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.4.4"
intl:
dependency: "direct main"
description:
name: intl
url: "https://pub.dartlang.org"
source: hosted
version: "0.17.0"
js:
dependency: transitive
description:
name: js
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.3"
lints:
dependency: transitive
description:
name: lints
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
location:
dependency: "direct main"
description:
name: location
url: "https://pub.dartlang.org"
source: hosted
version: "4.4.0"
location_platform_interface:
dependency: transitive
description:
name: location_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.3.0"
location_web:
dependency: transitive
description:
name: location_web
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.1"
logging:
dependency: transitive
description:
name: logging
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
maps_toolkit:
dependency: "direct main"
description:
name: maps_toolkit
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
matcher:
dependency: transitive
description:
name: matcher
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.11"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.3"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.0"
path:
dependency: transitive
description:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0"
path_provider:
dependency: "direct main"
description:
name: path_provider
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.9"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.12"
path_provider_ios:
dependency: transitive
description:
name: path_provider_ios
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.8"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.5"
path_provider_macos:
dependency: transitive
description:
name: path_provider_macos
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.5"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.3"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.5"
platform:
dependency: transitive
description:
name: platform
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.0"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.2"
process:
dependency: transitive
description:
name: process
url: "https://pub.dartlang.org"
source: hosted
version: "4.2.4"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
socket_io_client:
dependency: "direct main"
description:
name: socket_io_client
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0-beta.4-nullsafety.0"
socket_io_common:
dependency: transitive
description:
name: socket_io_common
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
source_span:
dependency: transitive
description:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.1"
stack_trace:
dependency: transitive
description:
name: stack_trace
url: "https://pub.dartlang.org"
source: hosted
version: "1.10.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
stream_transform:
dependency: transitive
description:
name: stream_transform
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
string_scanner:
dependency: transitive
description:
name: string_scanner
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
term_glyph:
dependency: transitive
description:
name: term_glyph
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.8"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0"
url_launcher:
dependency: "direct main"
description:
name: url_launcher
url: "https://pub.dartlang.org"
source: hosted
version: "6.1.2"
url_launcher_android:
dependency: transitive
description:
name: url_launcher_android
url: "https://pub.dartlang.org"
source: hosted
version: "6.0.17"
url_launcher_ios:
dependency: transitive
description:
name: url_launcher_ios
url: "https://pub.dartlang.org"
source: hosted
version: "6.0.17"
url_launcher_linux:
dependency: transitive
description:
name: url_launcher_linux
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
url_launcher_macos:
dependency: transitive
description:
name: url_launcher_macos
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
url_launcher_platform_interface:
dependency: transitive
description:
name: url_launcher_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.5"
url_launcher_web:
dependency: transitive
description:
name: url_launcher_web
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.6"
url_launcher_windows:
dependency: transitive
description:
name: url_launcher_windows
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
win32:
dependency: transitive
description:
name: win32
url: "https://pub.dartlang.org"
source: hosted
version: "2.5.1"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.0+1"
sdks:
dart: ">=2.16.0-134.5.beta <3.0.0"
flutter: ">=2.8.0"

114
pubspec.yaml Normal file
View File

@ -0,0 +1,114 @@
name: kurir
description: A new Flutter project.
# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.0.0+1
environment:
sdk: ">=2.16.0-134.5.beta <3.0.0"
# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
# consider running `flutter pub upgrade --major-versions`. Alternatively,
# dependencies can be manually updated by changing the version numbers below to
# the latest version available on pub.dev. To see which dependencies have newer
# versions available, run `flutter pub outdated`.
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
get: ^4.6.1
# navigation_history_observer: ^1.1.0
double_back_to_close_app: ^2.0.1
# back_button_interceptor: ^5.0.2
image_picker: ^0.8.5
path_provider: ^2.0.9
# flutter_cache_manager: ^3.3.0
# ensure_visible_when_focused: ^1.0.0+1
http: ^0.13.4
flutter_easyloading: ^3.0.3
crypto: ^3.0.1
# provider: ^6.0.2
get_storage: ^2.0.3
# dio: ^4.0.6
intl: ^0.17.0
google_maps_flutter: ^2.1.6
maps_toolkit: ^2.0.0
flutter_slidable:
socket_io_client:
# geolocator:
geocoding:
location: ^4.2.0
flutter_polyline_points:
url_launcher: ^6.0.1
dev_dependencies:
flutter_test:
sdk: flutter
# The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is
# activated in the `analysis_options.yaml` file located at the root of your
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^1.0.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add assets to your application, add an assets section, like this:
assets:
- assets/
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware.
# For details regarding adding assets from package dependencies, see
# https://flutter.dev/assets-and-images/#from-packages
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages

30
test/widget_test.dart Normal file
View File

@ -0,0 +1,30 @@
// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility that Flutter provides. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:kurir/main.dart';
void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(const MyApp());
// Verify that our counter starts at 0.
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsNothing);
// Tap the '+' icon and trigger a frame.
await tester.tap(find.byIcon(Icons.add));
await tester.pump();
// Verify that our counter has incremented.
expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget);
});
}