changes the area to kecamatan , kelurahan and tps
@ -2,7 +2,7 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<application
|
<application
|
||||||
android:label="cek_suara_app"
|
android:label="Survei Suara"
|
||||||
android:name="${applicationName}"
|
android:name="${applicationName}"
|
||||||
android:icon="@mipmap/ic_launcher">
|
android:icon="@mipmap/ic_launcher">
|
||||||
<activity
|
<activity
|
||||||
|
Before Width: | Height: | Size: 544 B After Width: | Height: | Size: 87 KiB |
Before Width: | Height: | Size: 442 B After Width: | Height: | Size: 87 KiB |
Before Width: | Height: | Size: 721 B After Width: | Height: | Size: 87 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 87 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 87 KiB |
@ -11,6 +11,7 @@ import '../ui/views/login_screen/login_screen_view.dart';
|
|||||||
import '../ui/views/splash_screen/splash_screen_view.dart';
|
import '../ui/views/splash_screen/splash_screen_view.dart';
|
||||||
import '../ui/views/tim_survei_index_tracking/first_page/first_page_view.dart';
|
import '../ui/views/tim_survei_index_tracking/first_page/first_page_view.dart';
|
||||||
import '../ui/views/tim_survei_index_tracking/halaman_history/halaman_history_view.dart';
|
import '../ui/views/tim_survei_index_tracking/halaman_history/halaman_history_view.dart';
|
||||||
|
import '../ui/views/tim_survei_index_tracking/halaman_pengaturan/ganti_password_dialog/ganti_password_dialog_view.dart';
|
||||||
import '../ui/views/tim_survei_index_tracking/halaman_pengaturan/halaman_pengaturan_view.dart';
|
import '../ui/views/tim_survei_index_tracking/halaman_pengaturan/halaman_pengaturan_view.dart';
|
||||||
|
|
||||||
import '../ui/views/tim_survei_index_tracking/halaman_survei/bottom_sheet_cari_area/bottom_sheet_cari_area_view.dart';
|
import '../ui/views/tim_survei_index_tracking/halaman_survei/bottom_sheet_cari_area/bottom_sheet_cari_area_view.dart';
|
||||||
@ -32,11 +33,10 @@ import '../ui/views/tim_survei_index_tracking/tim_survei_index_tracking_view.dar
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
dialogs: [
|
||||||
// dialogs: [
|
StackedDialog(classType: GantiPasswordDialogView),
|
||||||
// StackedDialog(classType: BottomSheetCariAreaView),
|
// StackedDialog(classType: TambahDetailTimSurveiView)
|
||||||
// // StackedDialog(classType: TambahDetailTimSurveiView)
|
],
|
||||||
// ],
|
|
||||||
dependencies: [
|
dependencies: [
|
||||||
LazySingleton(classType: NavigationService),
|
LazySingleton(classType: NavigationService),
|
||||||
LazySingleton(classType: DialogService),
|
LazySingleton(classType: DialogService),
|
||||||
|
25
lib/app/app.dialogs.dart
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// StackedDialogGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
import 'package:stacked_services/stacked_services.dart';
|
||||||
|
|
||||||
|
import 'app.locator.dart';
|
||||||
|
import '../ui/views/tim_survei_index_tracking/halaman_pengaturan/ganti_password_dialog/ganti_password_dialog_view.dart';
|
||||||
|
|
||||||
|
enum DialogType {
|
||||||
|
gantiPasswordDialogView,
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupDialogUi() {
|
||||||
|
final dialogService = locator<DialogService>();
|
||||||
|
|
||||||
|
final Map<DialogType, DialogBuilder> builders = {
|
||||||
|
DialogType.gantiPasswordDialogView: (context, request, completer) =>
|
||||||
|
GantiPasswordDialogView(request: request, completer: completer),
|
||||||
|
};
|
||||||
|
|
||||||
|
dialogService.registerCustomDialogBuilders(builders);
|
||||||
|
}
|
@ -1,5 +1,3 @@
|
|||||||
// ignore_for_file: deprecated_member_use
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'app_colors.dart';
|
import 'app_colors.dart';
|
||||||
@ -17,9 +15,9 @@ ThemeData appTheme = ThemeData(
|
|||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
),
|
),
|
||||||
textTheme: TextTheme(
|
textTheme: TextTheme(
|
||||||
headline1: regularTextStyle.copyWith(fontSize: 32),
|
displayLarge: regularTextStyle.copyWith(fontSize: 32),
|
||||||
headline2: regularTextStyle.copyWith(fontSize: 20),
|
displayMedium: regularTextStyle.copyWith(fontSize: 20),
|
||||||
headline3: regularTextStyle.copyWith(fontSize: 18),
|
displaySmall: regularTextStyle.copyWith(fontSize: 18),
|
||||||
),
|
),
|
||||||
elevatedButtonTheme: ElevatedButtonThemeData(
|
elevatedButtonTheme: ElevatedButtonThemeData(
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||||
@ -5,12 +7,14 @@ import 'package:stacked_services/stacked_services.dart';
|
|||||||
|
|
||||||
// import 'app/app.bottomsheets.dart';
|
// import 'app/app.bottomsheets.dart';
|
||||||
import 'app/app.bottomsheets.dart';
|
import 'app/app.bottomsheets.dart';
|
||||||
|
import 'app/app.dialogs.dart';
|
||||||
import 'app/app.locator.dart';
|
import 'app/app.locator.dart';
|
||||||
import 'app/app.router.dart';
|
import 'app/app.router.dart';
|
||||||
import 'app/themes/app_theme.dart';
|
import 'app/themes/app_theme.dart';
|
||||||
|
|
||||||
Future main() async {
|
Future main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
HttpOverrides.global = MyHttpOverrides();
|
||||||
// await Future.wait([
|
// await Future.wait([
|
||||||
// dotenv.load(fileName: ".env"),
|
// dotenv.load(fileName: ".env"),
|
||||||
// setupLocator(),
|
// setupLocator(),
|
||||||
@ -27,7 +31,7 @@ class MyApp extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
title: 'Cek Suara',
|
title: 'Cek Suara App',
|
||||||
theme: appTheme,
|
theme: appTheme,
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
navigatorKey: StackedService.navigatorKey,
|
navigatorKey: StackedService.navigatorKey,
|
||||||
@ -39,7 +43,16 @@ class MyApp extends StatelessWidget {
|
|||||||
|
|
||||||
Future<void> setupAllLocator() async {
|
Future<void> setupAllLocator() async {
|
||||||
await setupLocator();
|
await setupLocator();
|
||||||
// setupDialogUi();
|
setupDialogUi();
|
||||||
setupBottomSheetUi();
|
setupBottomSheetUi();
|
||||||
// setupSnackbarUi();
|
// setupSnackbarUi();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class MyHttpOverrides extends HttpOverrides {
|
||||||
|
@override
|
||||||
|
HttpClient createHttpClient(SecurityContext? context) {
|
||||||
|
return super.createHttpClient(context)
|
||||||
|
..badCertificateCallback =
|
||||||
|
(X509Certificate cert, String host, int port) => true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
class AreaListModel {
|
class KecamatanDetail {
|
||||||
List<AreaModel>? area;
|
List<KecamatanModel>? kecamatan;
|
||||||
int? jumlah;
|
int? jumlah;
|
||||||
|
|
||||||
AreaListModel({this.area, this.jumlah});
|
KecamatanDetail({this.kecamatan, this.jumlah});
|
||||||
|
|
||||||
AreaListModel.fromJson(Map<String, dynamic> json) {
|
KecamatanDetail.fromJson(Map<String, dynamic> json) {
|
||||||
if (json['area'] != null) {
|
if (json['kecamatan'] != null) {
|
||||||
area = <AreaModel>[];
|
kecamatan = <KecamatanModel>[];
|
||||||
json['area'].forEach((v) {
|
json['kecamatan'].forEach((v) {
|
||||||
area!.add(AreaModel.fromJson(v));
|
kecamatan!.add(KecamatanModel.fromJson(v));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
jumlah = json['jumlah'];
|
jumlah = json['jumlah'];
|
||||||
@ -16,29 +16,77 @@ class AreaListModel {
|
|||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
final Map<String, dynamic> data = <String, dynamic>{};
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
if (area != null) {
|
if (kecamatan != null) {
|
||||||
data['area'] = area!.map((v) => v.toJson()).toList();
|
data['kecamatan'] = kecamatan!.map((v) => v.toJson()).toList();
|
||||||
}
|
}
|
||||||
data['jumlah'] = jumlah;
|
data['jumlah'] = jumlah;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AreaModel {
|
class KecamatanModel {
|
||||||
int? idArea;
|
String? kecamatanId;
|
||||||
String? namaArea;
|
String? name;
|
||||||
|
|
||||||
AreaModel({this.idArea, this.namaArea});
|
KecamatanModel({this.kecamatanId, this.name});
|
||||||
|
|
||||||
AreaModel.fromJson(Map<String, dynamic> json) {
|
KecamatanModel.fromJson(Map<String, dynamic> json) {
|
||||||
idArea = json['id_area'];
|
kecamatanId = json['kecamatan_id'];
|
||||||
namaArea = json['nama_area'];
|
name = json['name'];
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
final Map<String, dynamic> data = <String, dynamic>{};
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
data['id_area'] = idArea;
|
data['kecamatan_id'] = kecamatanId;
|
||||||
data['nama_area'] = namaArea;
|
data['name'] = name;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class KelurahanDetail {
|
||||||
|
List<KelurahanModel>? kelurahan;
|
||||||
|
int? jumlah;
|
||||||
|
|
||||||
|
KelurahanDetail({this.kelurahan, this.jumlah});
|
||||||
|
|
||||||
|
KelurahanDetail.fromJson(Map<String, dynamic> json) {
|
||||||
|
if (json['kelurahan'] != null) {
|
||||||
|
kelurahan = <KelurahanModel>[];
|
||||||
|
json['kelurahan'].forEach((v) {
|
||||||
|
kelurahan!.add(KelurahanModel.fromJson(v));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
jumlah = json['jumlah'];
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
if (kelurahan != null) {
|
||||||
|
data['kelurahan'] = kelurahan!.map((v) => v.toJson()).toList();
|
||||||
|
}
|
||||||
|
data['jumlah'] = jumlah;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class KelurahanModel {
|
||||||
|
String? kelurahanId;
|
||||||
|
String? kecamatanId;
|
||||||
|
String? name;
|
||||||
|
|
||||||
|
KelurahanModel({this.kelurahanId, this.kecamatanId, this.name});
|
||||||
|
|
||||||
|
KelurahanModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
kelurahanId = json['kelurahan_id'];
|
||||||
|
kecamatanId = json['kecamatan_id'];
|
||||||
|
name = json['name'];
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
data['kelurahan_id'] = kelurahanId;
|
||||||
|
data['kecamatan_id'] = kecamatanId;
|
||||||
|
data['name'] = name;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import '../app/app.locator.dart';
|
import '../app/app.locator.dart';
|
||||||
import '../services/other_function.dart';
|
import '../services/other_function.dart';
|
||||||
|
|
||||||
class PemilihDetailModel {
|
class PemilihDetail {
|
||||||
List<PemilihModel>? pemilihModel;
|
List<PemilihModel>? pemilihModel;
|
||||||
int? jumlah;
|
int? jumlah;
|
||||||
|
|
||||||
PemilihDetailModel({this.pemilihModel, this.jumlah});
|
PemilihDetail({this.pemilihModel, this.jumlah});
|
||||||
|
|
||||||
PemilihDetailModel.fromJson(Map<String, dynamic> json) {
|
PemilihDetail.fromJson(Map<String, dynamic> json) {
|
||||||
if (json['data'] != null) {
|
if (json['data'] != null) {
|
||||||
pemilihModel = <PemilihModel>[];
|
pemilihModel = <PemilihModel>[];
|
||||||
json['data'].forEach((v) {
|
json['data'].forEach((v) {
|
||||||
@ -36,7 +36,9 @@ class PemilihModel {
|
|||||||
String? nikTimSurvei;
|
String? nikTimSurvei;
|
||||||
String? namaTimSurvei;
|
String? namaTimSurvei;
|
||||||
String? namaCaleg;
|
String? namaCaleg;
|
||||||
String? namaArea;
|
String? kecamatan;
|
||||||
|
String? kelurahan;
|
||||||
|
int? tps;
|
||||||
String? createdAt;
|
String? createdAt;
|
||||||
|
|
||||||
PemilihModel(
|
PemilihModel(
|
||||||
@ -46,7 +48,9 @@ class PemilihModel {
|
|||||||
this.nikTimSurvei,
|
this.nikTimSurvei,
|
||||||
this.namaTimSurvei,
|
this.namaTimSurvei,
|
||||||
this.namaCaleg,
|
this.namaCaleg,
|
||||||
this.namaArea,
|
this.kecamatan,
|
||||||
|
this.kelurahan,
|
||||||
|
this.tps,
|
||||||
this.createdAt});
|
this.createdAt});
|
||||||
|
|
||||||
PemilihModel.fromJson(Map<String, dynamic> json) {
|
PemilihModel.fromJson(Map<String, dynamic> json) {
|
||||||
@ -56,7 +60,9 @@ class PemilihModel {
|
|||||||
nikTimSurvei = json['nik_tim_survei'];
|
nikTimSurvei = json['nik_tim_survei'];
|
||||||
namaTimSurvei = json['nama_tim_survei'];
|
namaTimSurvei = json['nama_tim_survei'];
|
||||||
namaCaleg = json['nama_caleg'];
|
namaCaleg = json['nama_caleg'];
|
||||||
namaArea = json['nama_area'];
|
kecamatan = json['kecamatan'];
|
||||||
|
kelurahan = json['kelurahan'];
|
||||||
|
tps = json['tps'];
|
||||||
createdAt = myFunction.convertDateTime(json['created_at']);
|
createdAt = myFunction.convertDateTime(json['created_at']);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +74,9 @@ class PemilihModel {
|
|||||||
data['nik_tim_survei'] = nikTimSurvei;
|
data['nik_tim_survei'] = nikTimSurvei;
|
||||||
data['nama_tim_survei'] = namaTimSurvei;
|
data['nama_tim_survei'] = namaTimSurvei;
|
||||||
data['nama_caleg'] = namaCaleg;
|
data['nama_caleg'] = namaCaleg;
|
||||||
data['nama_area'] = namaArea;
|
data['kecamatan'] = kecamatan;
|
||||||
|
data['kelurahan'] = kelurahan;
|
||||||
|
data['tps'] = tps;
|
||||||
data['created_at'] = createdAt;
|
data['created_at'] = createdAt;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
// import '../../../app/app.router.dart';
|
|
||||||
|
|
||||||
import 'package:cek_suara_app/app/app.router.dart';
|
|
||||||
import 'package:cek_suara_app/model/my_response.model.dart';
|
|
||||||
import 'package:cek_suara_app/model/tim_survei_model.dart';
|
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../../../app/app.router.dart';
|
||||||
import '../../../app/app.logger.dart';
|
import '../../../app/app.logger.dart';
|
||||||
import '../../../app/core/custom_base_view_model.dart';
|
import '../../../app/core/custom_base_view_model.dart';
|
||||||
|
import '../../../model/my_response.model.dart';
|
||||||
|
import '../../../model/tim_survei_model.dart';
|
||||||
|
|
||||||
class LoginScreenViewModel extends CustomBaseViewModel {
|
class LoginScreenViewModel extends CustomBaseViewModel {
|
||||||
final log = getLogger('LoginScreenViewModel');
|
final log = getLogger('LoginScreenViewModel');
|
||||||
@ -42,6 +40,7 @@ class LoginScreenViewModel extends CustomBaseViewModel {
|
|||||||
mySharedPrefs.setString('nama', timSurveiModel.nama!);
|
mySharedPrefs.setString('nama', timSurveiModel.nama!);
|
||||||
mySharedPrefs.setString('id_caleg', timSurveiModel.idCaleg.toString());
|
mySharedPrefs.setString('id_caleg', timSurveiModel.idCaleg.toString());
|
||||||
mySharedPrefs.setString('level', 'tim_survei');
|
mySharedPrefs.setString('level', 'tim_survei');
|
||||||
|
mySharedPrefs.setString('password', passwordController.text);
|
||||||
snackbarService.showSnackbar(
|
snackbarService.showSnackbar(
|
||||||
message: 'Selamat datang kembali ${timSurveiModel.nama}',
|
message: 'Selamat datang kembali ${timSurveiModel.nama}',
|
||||||
title: 'Login Berhasil',
|
title: 'Login Berhasil',
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:stacked/stacked.dart';
|
import 'package:stacked/stacked.dart';
|
||||||
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
import '../../../../app/themes/app_colors.dart';
|
import '../../../../app/themes/app_colors.dart';
|
||||||
import '../../../../app/themes/app_text.dart';
|
import '../../../../app/themes/app_text.dart';
|
||||||
@ -124,11 +125,33 @@ class FirstPageView extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () async {
|
||||||
|
final url = Uri.parse('https://www.kicap-karan.com');
|
||||||
|
if (!await launchUrl(url)) {
|
||||||
|
throw 'Could not launch $url';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Text(
|
||||||
|
'www.kicap-karan.com',
|
||||||
|
style: boldTextStyle.copyWith(
|
||||||
|
color: mainColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
floatingActionButton: FloatingActionButton(
|
||||||
|
backgroundColor: warningColor,
|
||||||
|
onPressed: () {
|
||||||
|
model.gantiPassword();
|
||||||
|
},
|
||||||
|
child: const Icon(Icons.settings, color: fontColor),
|
||||||
|
),
|
||||||
|
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import '../../../../app/app.dialogs.dart';
|
||||||
import '../../../../app/app.logger.dart';
|
import '../../../../app/app.logger.dart';
|
||||||
import '../../../../app/core/custom_base_view_model.dart';
|
import '../../../../app/core/custom_base_view_model.dart';
|
||||||
import '../../../../model/my_response.model.dart';
|
import '../../../../model/my_response.model.dart';
|
||||||
@ -27,4 +28,17 @@ class FirstPageViewModel extends CustomBaseViewModel {
|
|||||||
setBusy(false);
|
setBusy(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gantiPassword() async {
|
||||||
|
var res = await dialogService.showCustomDialog(
|
||||||
|
variant: DialogType.gantiPasswordDialogView,
|
||||||
|
title: 'Ganti Password',
|
||||||
|
mainButtonTitle: 'Simpan',
|
||||||
|
barrierDismissible: false,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (res!.confirmed) {
|
||||||
|
snackbarService.showSnackbar(message: 'Password berhasil diubah');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,6 +96,18 @@ class DetailSuaraPemilihBottomSheetView extends StatelessWidget {
|
|||||||
title: 'Tanggal/\nWaktu',
|
title: 'Tanggal/\nWaktu',
|
||||||
value: request.data!.createdAt!,
|
value: request.data!.createdAt!,
|
||||||
),
|
),
|
||||||
|
_DetailChildWidget(
|
||||||
|
title: 'Kecamatan',
|
||||||
|
value: request.data!.kecamatan!,
|
||||||
|
),
|
||||||
|
_DetailChildWidget(
|
||||||
|
title: 'Kelurahan/\nDesa',
|
||||||
|
value: request.data!.kelurahan!,
|
||||||
|
),
|
||||||
|
_DetailChildWidget(
|
||||||
|
title: 'TPS',
|
||||||
|
value: request.data!.tps!.toString(),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -104,8 +104,26 @@ class HalamanHistoryView extends StatelessWidget {
|
|||||||
model.listPemilih[i].namaPemilih!,
|
model.listPemilih[i].namaPemilih!,
|
||||||
style: boldTextStyle,
|
style: boldTextStyle,
|
||||||
),
|
),
|
||||||
subtitle: Text(
|
subtitle: Column(
|
||||||
model.listPemilih[i].namaArea!,
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment:
|
||||||
|
CrossAxisAlignment.start,
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
CardWidget(
|
||||||
|
title: 'Kec',
|
||||||
|
value: model
|
||||||
|
.listPemilih[i].kecamatan!),
|
||||||
|
CardWidget(
|
||||||
|
title: 'Kel / Desa',
|
||||||
|
value: model
|
||||||
|
.listPemilih[i].kelurahan!),
|
||||||
|
CardWidget(
|
||||||
|
title: 'TPS',
|
||||||
|
value: model.listPemilih[i].tps!
|
||||||
|
.toString()),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
trailing: IconButton(
|
trailing: IconButton(
|
||||||
icon: const Icon(
|
icon: const Icon(
|
||||||
@ -151,3 +169,48 @@ class HalamanHistoryView extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CardWidget extends StatelessWidget {
|
||||||
|
const CardWidget({
|
||||||
|
super.key,
|
||||||
|
required this.title,
|
||||||
|
required this.value,
|
||||||
|
});
|
||||||
|
|
||||||
|
final String title;
|
||||||
|
final String value;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
flex: 3,
|
||||||
|
child: Text(
|
||||||
|
title,
|
||||||
|
style: italicTextStyle.copyWith(
|
||||||
|
fontSize: 12,
|
||||||
|
),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Expanded(
|
||||||
|
flex: 1,
|
||||||
|
child: Text(
|
||||||
|
' : ',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
flex: 6,
|
||||||
|
child: Text(
|
||||||
|
value,
|
||||||
|
style: boldTextStyle.copyWith(
|
||||||
|
fontSize: 12,
|
||||||
|
),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import 'package:cek_suara_app/model/my_response.model.dart';
|
|
||||||
import 'package:cek_suara_app/model/pemilih_model.dart';
|
|
||||||
|
|
||||||
import '../../../../app/app.bottomsheets.dart';
|
import '../../../../app/app.bottomsheets.dart';
|
||||||
import '../../../../app/app.logger.dart';
|
import '../../../../app/app.logger.dart';
|
||||||
import '../../../../app/core/custom_base_view_model.dart';
|
import '../../../../app/core/custom_base_view_model.dart';
|
||||||
|
import '../../../../model/my_response.model.dart';
|
||||||
|
import '../../../../model/pemilih_model.dart';
|
||||||
|
|
||||||
class HalamanHistoryViewModel extends CustomBaseViewModel {
|
class HalamanHistoryViewModel extends CustomBaseViewModel {
|
||||||
final log = getLogger('HalamanHistoryViewModel');
|
final log = getLogger('HalamanHistoryViewModel');
|
||||||
@ -13,6 +12,7 @@ class HalamanHistoryViewModel extends CustomBaseViewModel {
|
|||||||
|
|
||||||
String namaCaleg = '...';
|
String namaCaleg = '...';
|
||||||
Future<void> init() async {
|
Future<void> init() async {
|
||||||
|
globalVar.backPressed = 'exitApp';
|
||||||
await getData();
|
await getData();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,13 +23,13 @@ class HalamanHistoryViewModel extends CustomBaseViewModel {
|
|||||||
String? nik = await mySharedPrefs.getString('nik');
|
String? nik = await mySharedPrefs.getString('nik');
|
||||||
var response = await httpService.get('tim_survei/$nik');
|
var response = await httpService.get('tim_survei/$nik');
|
||||||
MyResponseModel myResponseModel = MyResponseModel.fromJson(response.data);
|
MyResponseModel myResponseModel = MyResponseModel.fromJson(response.data);
|
||||||
PemilihDetailModel pemilihDetailModel =
|
PemilihDetail pemilihDetail =
|
||||||
PemilihDetailModel.fromJson(myResponseModel.data);
|
PemilihDetail.fromJson(myResponseModel.data);
|
||||||
listPemilih = pemilihDetailModel.pemilihModel!;
|
listPemilih = pemilihDetail.pemilihModel ?? [];
|
||||||
log.i('listPemilih: $listPemilih');
|
// log.i('listPemilih: $listPemilih');
|
||||||
namaCaleg = listPemilih[0].namaCaleg!;
|
counter = pemilihDetail.jumlah!;
|
||||||
counter = pemilihDetailModel.jumlah!;
|
namaCaleg = counter > 0 ? listPemilih[0].namaCaleg! : '...';
|
||||||
log.i('counter: $counter');
|
// log.i('counter: $counter');
|
||||||
status = true;
|
status = true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log.e(e.toString());
|
log.e(e.toString());
|
||||||
|
@ -0,0 +1,190 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:stacked/stacked.dart';
|
||||||
|
import 'package:stacked_services/stacked_services.dart';
|
||||||
|
import 'package:validatorless/validatorless.dart';
|
||||||
|
|
||||||
|
import '../../../../../app/themes/app_colors.dart';
|
||||||
|
import '../../../../../app/themes/app_text.dart';
|
||||||
|
import '../../../../widgets/my_textformfield.dart';
|
||||||
|
import './ganti_password_dialog_view_model.dart';
|
||||||
|
|
||||||
|
class GantiPasswordDialogView extends StatelessWidget {
|
||||||
|
final DialogRequest? request;
|
||||||
|
final Function(DialogResponse)? completer;
|
||||||
|
|
||||||
|
const GantiPasswordDialogView({
|
||||||
|
Key? key,
|
||||||
|
this.request,
|
||||||
|
this.completer,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return ViewModelBuilder<GantiPasswordDialogViewModel>.reactive(
|
||||||
|
viewModelBuilder: () => GantiPasswordDialogViewModel(),
|
||||||
|
onViewModelReady: (GantiPasswordDialogViewModel model) async {
|
||||||
|
await model.init();
|
||||||
|
},
|
||||||
|
builder: (
|
||||||
|
BuildContext context,
|
||||||
|
GantiPasswordDialogViewModel model,
|
||||||
|
Widget? child,
|
||||||
|
) {
|
||||||
|
return Dialog(
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.all(20),
|
||||||
|
child: Form(
|
||||||
|
key: model.globalKey,
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Ganti Password',
|
||||||
|
style: boldTextStyle.copyWith(fontSize: 18),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
MyTextFormField(
|
||||||
|
labelText: 'Password Lama',
|
||||||
|
hintText: 'Masukkan password lama',
|
||||||
|
obscureText: model.isPasswordLamaObscure,
|
||||||
|
suffixIcon: IconButton(
|
||||||
|
onPressed: () {
|
||||||
|
model.isPasswordLamaObscure =
|
||||||
|
!model.isPasswordLamaObscure;
|
||||||
|
model.notifyListeners();
|
||||||
|
},
|
||||||
|
icon: Icon(
|
||||||
|
model.isPasswordLamaObscure
|
||||||
|
? Icons.visibility_off
|
||||||
|
: Icons.visibility,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
controller: model.passwordLamaController,
|
||||||
|
validator: Validatorless.multiple(
|
||||||
|
[
|
||||||
|
Validatorless.required(
|
||||||
|
'Password lama tidak boleh kosong'),
|
||||||
|
Validatorless.min(
|
||||||
|
8, 'Password lama minimal 8 karakter'),
|
||||||
|
Validatorless.compare(
|
||||||
|
model.thePasswordLamaController,
|
||||||
|
'Password lama tidak sama',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
MyTextFormField(
|
||||||
|
labelText: 'Password Baru',
|
||||||
|
hintText: 'Masukkan password baru',
|
||||||
|
obscureText: model.isPasswordBaruObscure,
|
||||||
|
controller: model.passwordBaruController,
|
||||||
|
suffixIcon: IconButton(
|
||||||
|
onPressed: () {
|
||||||
|
model.isPasswordBaruObscure =
|
||||||
|
!model.isPasswordBaruObscure;
|
||||||
|
model.notifyListeners();
|
||||||
|
},
|
||||||
|
icon: Icon(
|
||||||
|
model.isPasswordBaruObscure
|
||||||
|
? Icons.visibility_off
|
||||||
|
: Icons.visibility,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
validator: Validatorless.multiple(
|
||||||
|
[
|
||||||
|
Validatorless.required(
|
||||||
|
'Password baru tidak boleh kosong'),
|
||||||
|
Validatorless.min(
|
||||||
|
8, 'Password baru minimal 8 karakter'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
MyTextFormField(
|
||||||
|
labelText: 'Konfirmasi Password Baru',
|
||||||
|
hintText: 'Masukkan konfirmasi password baru',
|
||||||
|
obscureText: model.isKonfirmasiPasswordBaruObscure,
|
||||||
|
controller: model.konfirmasiPasswordBaruController,
|
||||||
|
suffixIcon: IconButton(
|
||||||
|
onPressed: () {
|
||||||
|
model.isKonfirmasiPasswordBaruObscure =
|
||||||
|
!model.isKonfirmasiPasswordBaruObscure;
|
||||||
|
model.notifyListeners();
|
||||||
|
},
|
||||||
|
icon: Icon(
|
||||||
|
model.isKonfirmasiPasswordBaruObscure
|
||||||
|
? Icons.visibility_off
|
||||||
|
: Icons.visibility,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
validator: Validatorless.multiple(
|
||||||
|
[
|
||||||
|
Validatorless.required(
|
||||||
|
'Konfirmasi password baru tidak boleh kosong'),
|
||||||
|
Validatorless.min(
|
||||||
|
8, 'Konfirmasi password baru minimal 8 karakter'),
|
||||||
|
Validatorless.compare(
|
||||||
|
model.passwordBaruController,
|
||||||
|
'Password baru tidak sama',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
if (model.globalKey.currentState!.validate()) {
|
||||||
|
// remove keyboard
|
||||||
|
FocusScope.of(context).unfocus();
|
||||||
|
|
||||||
|
model.dialogService
|
||||||
|
.showConfirmationDialog(
|
||||||
|
title: 'Konfirmasi',
|
||||||
|
description:
|
||||||
|
'Apakah anda yakin ingin mengubah password?',
|
||||||
|
cancelTitle: 'Batal',
|
||||||
|
confirmationTitle: 'Ya',
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
(response) async {
|
||||||
|
if (response!.confirmed) {
|
||||||
|
// completer!(DialogResponse(confirmed: true));
|
||||||
|
// model.log.i('Password berhasil diubah');
|
||||||
|
bool res = await model.gantiPassword();
|
||||||
|
// model.log.i('res: $res');
|
||||||
|
if (res) {
|
||||||
|
completer!(DialogResponse(confirmed: true));
|
||||||
|
model.log.i('Password berhasil diubah');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
model.log.i('Password gagal diubah');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: const Text('Simpan'),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () =>
|
||||||
|
completer!(DialogResponse(confirmed: false)),
|
||||||
|
child: const Text(
|
||||||
|
'Batal',
|
||||||
|
style: TextStyle(color: dangerColor),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../../../../../app/app.logger.dart';
|
||||||
|
import '../../../../../app/core/custom_base_view_model.dart';
|
||||||
|
|
||||||
|
class GantiPasswordDialogViewModel extends CustomBaseViewModel {
|
||||||
|
final log = getLogger('GantiPasswordDialogViewModel');
|
||||||
|
|
||||||
|
// form variable
|
||||||
|
final globalKey = GlobalKey<FormState>();
|
||||||
|
TextEditingController passwordLamaController = TextEditingController();
|
||||||
|
TextEditingController passwordBaruController = TextEditingController();
|
||||||
|
TextEditingController konfirmasiPasswordBaruController =
|
||||||
|
TextEditingController();
|
||||||
|
|
||||||
|
TextEditingController thePasswordLamaController = TextEditingController();
|
||||||
|
|
||||||
|
bool isPasswordLamaObscure = true;
|
||||||
|
bool isPasswordBaruObscure = true;
|
||||||
|
bool isKonfirmasiPasswordBaruObscure = true;
|
||||||
|
|
||||||
|
// String? passwordLama;
|
||||||
|
|
||||||
|
Future<void> init() async {
|
||||||
|
globalVar.backPressed = 'exitApp';
|
||||||
|
String? passwordLama = await mySharedPrefs.getString('password');
|
||||||
|
thePasswordLamaController.text = passwordLama!;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> gantiPassword() async {
|
||||||
|
setBusy(true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
String? nik = await mySharedPrefs.getString('nik');
|
||||||
|
var formData = FormData.fromMap({
|
||||||
|
'nik': nik,
|
||||||
|
'password_lama': passwordLamaController.text,
|
||||||
|
'password_baru': passwordBaruController.text,
|
||||||
|
});
|
||||||
|
await httpService.postWithFormData(
|
||||||
|
'login/ganti_pass_tim_survei', formData);
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
log.e(e.toString());
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
setBusy(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
import 'package:cek_suara_app/ui/views/tim_survei_index_tracking/first_page/first_page_view.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:stacked/stacked.dart';
|
import 'package:stacked/stacked.dart';
|
||||||
|
|
||||||
|
import '../first_page/first_page_view.dart';
|
||||||
import './halaman_pengaturan_view_model.dart';
|
import './halaman_pengaturan_view_model.dart';
|
||||||
|
|
||||||
class HalamanPengaturanView extends StatelessWidget {
|
class HalamanPengaturanView extends StatelessWidget {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import 'package:cek_suara_app/ui/widgets/my_textformfield.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:stacked/stacked.dart';
|
import 'package:stacked/stacked.dart';
|
||||||
import 'package:stacked_services/stacked_services.dart';
|
import 'package:stacked_services/stacked_services.dart';
|
||||||
|
|
||||||
|
import '../../../../widgets/my_textformfield.dart';
|
||||||
import './bottom_sheet_cari_area_view_model.dart';
|
import './bottom_sheet_cari_area_view_model.dart';
|
||||||
|
|
||||||
class BottomSheetCariAreaView extends StatelessWidget {
|
class BottomSheetCariAreaView extends StatelessWidget {
|
||||||
|
@ -120,11 +120,11 @@ class HalamanSurveiView extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
const Text(
|
const Text(
|
||||||
' Pilih Area',
|
' Pilih Kecamatan',
|
||||||
),
|
),
|
||||||
if (model.isBusy)
|
if (model.isBusy)
|
||||||
const Center(child: CircularProgressIndicator()),
|
const Center(child: CircularProgressIndicator()),
|
||||||
if (!model.isBusy && model.selectedArea != null)
|
if (!model.isBusy && model.selectedKecamatan != null)
|
||||||
Container(
|
Container(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
height: 60,
|
height: 60,
|
||||||
@ -135,46 +135,97 @@ class HalamanSurveiView extends StatelessWidget {
|
|||||||
color: sixthGrey,
|
color: sixthGrey,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
// icon search
|
|
||||||
IconButton(
|
|
||||||
onPressed: () async =>
|
|
||||||
await model.searchArea(),
|
|
||||||
icon: const Icon(
|
|
||||||
Icons.search,
|
|
||||||
color: sixthGrey,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 10),
|
|
||||||
Expanded(
|
|
||||||
child: DropdownButtonHideUnderline(
|
child: DropdownButtonHideUnderline(
|
||||||
child: DropdownButton<String>(
|
child: DropdownButton<String>(
|
||||||
isExpanded: true,
|
isExpanded: true,
|
||||||
value: model.selectedArea!,
|
value: model.selectedKecamatan!,
|
||||||
icon: const Icon(Icons.arrow_drop_down),
|
icon: const Icon(Icons.arrow_drop_down),
|
||||||
iconSize: 24,
|
iconSize: 24,
|
||||||
elevation: 16,
|
elevation: 16,
|
||||||
style: const TextStyle(
|
style: const TextStyle(color: Colors.black),
|
||||||
color: Colors.black),
|
|
||||||
onChanged: (String? newValue) {
|
onChanged: (String? newValue) {
|
||||||
model.log.i(newValue);
|
model.log.i(newValue);
|
||||||
model.selectedArea = newValue!;
|
model.selectedKecamatan = newValue!;
|
||||||
|
String kecamatanId = model
|
||||||
|
.listKecamatanModel[model
|
||||||
|
.listKecamatanString
|
||||||
|
.indexOf(newValue)]
|
||||||
|
.kecamatanId!;
|
||||||
|
model.getKelurahan(kecamatanId);
|
||||||
// model.changeArea(newValue);
|
// model.changeArea(newValue);
|
||||||
model.notifyListeners();
|
model.notifyListeners();
|
||||||
},
|
},
|
||||||
items: model.listAreaString
|
items: model.listKecamatanString
|
||||||
.map<DropdownMenuItem<String>>(
|
.map<DropdownMenuItem<String>>(
|
||||||
(String value) {
|
(String value) {
|
||||||
return DropdownMenuItem<String>(
|
return DropdownMenuItem<String>(
|
||||||
value: value,
|
value: value,
|
||||||
child: Text(value,
|
child: Text(value,
|
||||||
overflow:
|
overflow: TextOverflow.ellipsis),
|
||||||
TextOverflow.ellipsis),
|
|
||||||
);
|
);
|
||||||
}).toList()),
|
}).toList()),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
const Text(
|
||||||
|
' Pilih Kelurahan / Desa',
|
||||||
|
),
|
||||||
|
if (model.isBusy)
|
||||||
|
const Center(child: CircularProgressIndicator()),
|
||||||
|
if (!model.isBusy && model.selectedKelurahan != null)
|
||||||
|
Container(
|
||||||
|
width: double.infinity,
|
||||||
|
height: 60,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(25),
|
||||||
|
border: Border.all(
|
||||||
|
color: sixthGrey,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: DropdownButtonHideUnderline(
|
||||||
|
child: DropdownButton<String>(
|
||||||
|
isExpanded: true,
|
||||||
|
value: model.selectedKelurahan!,
|
||||||
|
icon: const Icon(Icons.arrow_drop_down),
|
||||||
|
iconSize: 24,
|
||||||
|
elevation: 16,
|
||||||
|
style: const TextStyle(color: Colors.black),
|
||||||
|
onChanged: (String? newValue) {
|
||||||
|
model.log.i(newValue);
|
||||||
|
model.selectedKelurahan = newValue!;
|
||||||
|
// model.changeArea(newValue);
|
||||||
|
model.notifyListeners();
|
||||||
|
},
|
||||||
|
items: model.listKelurahanString
|
||||||
|
.map<DropdownMenuItem<String>>(
|
||||||
|
(String value) {
|
||||||
|
return DropdownMenuItem<String>(
|
||||||
|
value: value,
|
||||||
|
child: Text(value,
|
||||||
|
overflow: TextOverflow.ellipsis),
|
||||||
|
);
|
||||||
|
}).toList()),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
MyTextFormField(
|
||||||
|
hintText: 'Masukkan No TPS',
|
||||||
|
labelText: 'Nomor TPS',
|
||||||
|
maxLength: 2,
|
||||||
|
suffixIcon: const Icon(Icons.account_balance),
|
||||||
|
controller: model.noTPScontroller,
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
validator: Validatorless.multiple(
|
||||||
|
[
|
||||||
|
Validatorless.required(
|
||||||
|
'Nomor TPS tidak boleh kosong'),
|
||||||
|
Validatorless.number('Nomor TPS harus angka'),
|
||||||
|
Validatorless.min(1, 'Nomor TPS minimal 1 digit'),
|
||||||
|
Validatorless.max(
|
||||||
|
2, 'Nomor TPS maksimal 2 digit'),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -4,7 +4,6 @@ import 'package:dio/dio.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:http_parser/http_parser.dart';
|
import 'package:http_parser/http_parser.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
import '../../../../app/app.bottomsheets.dart';
|
|
||||||
import '../../../../app/app.logger.dart';
|
import '../../../../app/app.logger.dart';
|
||||||
import '../../../../app/core/custom_base_view_model.dart';
|
import '../../../../app/core/custom_base_view_model.dart';
|
||||||
import '../../../../model/area_model.dart';
|
import '../../../../model/area_model.dart';
|
||||||
@ -17,6 +16,7 @@ class HalamanSurveiViewModel extends CustomBaseViewModel {
|
|||||||
final formKey = GlobalKey<FormState>();
|
final formKey = GlobalKey<FormState>();
|
||||||
TextEditingController ktpController = TextEditingController();
|
TextEditingController ktpController = TextEditingController();
|
||||||
TextEditingController namaController = TextEditingController();
|
TextEditingController namaController = TextEditingController();
|
||||||
|
TextEditingController noTPScontroller = TextEditingController();
|
||||||
|
|
||||||
// image picker
|
// image picker
|
||||||
String? _imagePath;
|
String? _imagePath;
|
||||||
@ -25,11 +25,14 @@ class HalamanSurveiViewModel extends CustomBaseViewModel {
|
|||||||
Uint8List? imageBytes;
|
Uint8List? imageBytes;
|
||||||
|
|
||||||
// area
|
// area
|
||||||
List<AreaModel> listAreaModel = [];
|
List<KecamatanModel> listKecamatanModel = [];
|
||||||
List<String> listAreaString = [];
|
List<String> listKecamatanString = [];
|
||||||
List<AreaModel> allListAreaModel = [];
|
List<KelurahanModel> listKelurahanModel = [];
|
||||||
String? selectedArea;
|
List<String> listKelurahanString = [];
|
||||||
int areaIndex = 0;
|
// List<AreaModel> allListKecamatanModel = [];
|
||||||
|
String? selectedKecamatan;
|
||||||
|
String? selectedKelurahan;
|
||||||
|
// int areaIndex = 0;
|
||||||
|
|
||||||
// // caleg
|
// // caleg
|
||||||
// List<CalegModel> listCalegModel = [];
|
// List<CalegModel> listCalegModel = [];
|
||||||
@ -59,17 +62,31 @@ class HalamanSurveiViewModel extends CustomBaseViewModel {
|
|||||||
|
|
||||||
// String? nik = await mySharedPrefs.getString('nik');
|
// String? nik = await mySharedPrefs.getString('nik');
|
||||||
var response = await httpService.get('area/cek_area/$nik');
|
var response = await httpService.get('area/cek_area/$nik');
|
||||||
log.i(response.data);
|
// log.i(response.data);
|
||||||
MyResponseModel myResponseModel = MyResponseModel.fromJson(response.data);
|
MyResponseModel myResponseModel = MyResponseModel.fromJson(response.data);
|
||||||
AreaListModel areaListModel =
|
KecamatanDetail kecamatanDetail =
|
||||||
AreaListModel.fromJson(myResponseModel.data);
|
KecamatanDetail.fromJson(myResponseModel.data);
|
||||||
listAreaModel = areaListModel.area!;
|
|
||||||
allListAreaModel = areaListModel.area!;
|
listKecamatanModel = kecamatanDetail.kecamatan!;
|
||||||
for (var element in listAreaModel) {
|
selectedKecamatan = listKecamatanModel[0].name!;
|
||||||
listAreaString.add(element.namaArea!);
|
for (var element in listKecamatanModel) {
|
||||||
|
listKecamatanString.add(element.name!);
|
||||||
}
|
}
|
||||||
selectedArea = listAreaString[0];
|
|
||||||
// int idArea = listAreaModel[0].idArea!;
|
// log.i('kecamatanDetail: ${kecamatanDetail.kecamatan}');
|
||||||
|
|
||||||
|
String idKecamatan = listKecamatanModel[0].kecamatanId!;
|
||||||
|
await getKelurahan(idKecamatan);
|
||||||
|
|
||||||
|
// AreaListModel areaListModel =
|
||||||
|
// AreaListModel.fromJson(myResponseModel.data);
|
||||||
|
// listKecamatanModel = areaListModel.area!;
|
||||||
|
// allListKecamatanModel = areaListModel.area!;
|
||||||
|
// for (var element in listKecamatanModel) {
|
||||||
|
// listKecamatanString.add(element.namaArea!);
|
||||||
|
// }
|
||||||
|
// selectedKecamatan = listKecamatanString[0];
|
||||||
|
// // int idArea = listKecamatanModel[0].idArea!;
|
||||||
// await getCaleg(idArea);
|
// await getCaleg(idArea);
|
||||||
|
|
||||||
// getCaleg()
|
// getCaleg()
|
||||||
@ -81,40 +98,30 @@ class HalamanSurveiViewModel extends CustomBaseViewModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// getCaleg(int idArea) async {
|
getKelurahan(String idKecamatan) async {
|
||||||
// log.i('getCaleg');
|
log.i('getKelurahan');
|
||||||
// log.i('idArea: $idArea');
|
listKelurahanModel = [];
|
||||||
// selectedCaleg = null;
|
listKelurahanString = [];
|
||||||
// listCalegModel = [];
|
selectedKelurahan = null;
|
||||||
// listCalegString = [];
|
setBusy(true);
|
||||||
// setBusy(true);
|
try {
|
||||||
// try {
|
var response = await httpService.get('area/kelurahan/$idKecamatan');
|
||||||
// var response = await httpService.get('caleg/area/$idArea');
|
|
||||||
// log.i(response.data);
|
// log.i(response.data);
|
||||||
// MyResponseModel myResponseModel = MyResponseModel.fromJson(response.data);
|
MyResponseModel myResponseModel = MyResponseModel.fromJson(response.data);
|
||||||
// // log.i(myResponseModel.data);
|
KelurahanDetail kelurahanDetail =
|
||||||
// CalegListModel calegListModel =
|
KelurahanDetail.fromJson(myResponseModel.data);
|
||||||
// CalegListModel.fromJson(myResponseModel.data);
|
// log.i('kelurahanDetail: ${kelurahanDetail.kelurahan}');
|
||||||
// listCalegModel = calegListModel.caleg!;
|
listKelurahanModel = kelurahanDetail.kelurahan!;
|
||||||
// for (var element in listCalegModel) {
|
for (var element in listKelurahanModel) {
|
||||||
// listCalegString.add(element.namaCaleg!);
|
listKelurahanString.add(element.name!);
|
||||||
// }
|
}
|
||||||
// selectedCaleg = listCalegString[0];
|
selectedKelurahan = listKelurahanString[0];
|
||||||
// // log.i('listCalegModel: $listCalegModel');
|
} catch (e) {
|
||||||
// // log.i('listCalegString: $listCalegString');
|
log.e(e);
|
||||||
// // log.i('selectedCaleg: $selectedCaleg');
|
} finally {
|
||||||
// } catch (e) {
|
setBusy(false);
|
||||||
// log.e(e);
|
}
|
||||||
// } finally {
|
}
|
||||||
// setBusy(false);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// changeArea(String? value) async {
|
|
||||||
// int idArea = listAreaModel[listAreaString.indexOf(value!)].idArea!;
|
|
||||||
// // log.i('idArea: $idArea');
|
|
||||||
// await getCaleg(idArea);
|
|
||||||
// }
|
|
||||||
|
|
||||||
void addImage() async {
|
void addImage() async {
|
||||||
try {
|
try {
|
||||||
@ -132,47 +139,19 @@ class HalamanSurveiViewModel extends CustomBaseViewModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
searchArea() async {
|
|
||||||
var res = await bottomSheetService.showCustomSheet(
|
|
||||||
variant: BottomSheetType.bottomSheetCariAreaView,
|
|
||||||
ignoreSafeArea: false,
|
|
||||||
isScrollControlled: true,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (res!.confirmed) {
|
|
||||||
log.i('res.data: ${res.data}');
|
|
||||||
|
|
||||||
String area = res.data;
|
|
||||||
if (area == '') {
|
|
||||||
listAreaModel = allListAreaModel;
|
|
||||||
} else {
|
|
||||||
listAreaModel = [];
|
|
||||||
for (var element in allListAreaModel) {
|
|
||||||
if (element.namaArea!.toLowerCase().contains(area.toLowerCase())) {
|
|
||||||
listAreaModel.add(element);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
listAreaString = [];
|
|
||||||
for (var element in listAreaModel) {
|
|
||||||
listAreaString.add(element.namaArea!);
|
|
||||||
}
|
|
||||||
selectedArea = listAreaString[0];
|
|
||||||
// int idArea = listAreaModel[0].idArea!;
|
|
||||||
// await getCaleg(idArea);
|
|
||||||
notifyListeners();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uploadData() async {
|
uploadData() async {
|
||||||
log.i('uploadData');
|
log.i('uploadData');
|
||||||
setBusy(true);
|
setBusy(true);
|
||||||
easyLoading.customLoading('Uploading data...');
|
easyLoading.customLoading('Uploading data...');
|
||||||
globalVar.backPressed = 'cantBack';
|
globalVar.backPressed = 'cantBack';
|
||||||
try {
|
try {
|
||||||
String idArea = listAreaModel[listAreaString.indexOf(selectedArea!)]
|
String idKecamatan =
|
||||||
.idArea
|
listKecamatanModel[listKecamatanString.indexOf(selectedKecamatan!)]
|
||||||
|
.kecamatanId
|
||||||
|
.toString();
|
||||||
|
String idKelurahan =
|
||||||
|
listKelurahanModel[listKelurahanString.indexOf(selectedKelurahan!)]
|
||||||
|
.kelurahanId
|
||||||
.toString();
|
.toString();
|
||||||
var fomData = FormData.fromMap(
|
var fomData = FormData.fromMap(
|
||||||
{
|
{
|
||||||
@ -184,8 +163,10 @@ class HalamanSurveiViewModel extends CustomBaseViewModel {
|
|||||||
filename: imageFile!.name,
|
filename: imageFile!.name,
|
||||||
contentType: MediaType('image', 'jpg'),
|
contentType: MediaType('image', 'jpg'),
|
||||||
),
|
),
|
||||||
'idArea': idArea,
|
'idKecamatan': idKecamatan,
|
||||||
|
'idKelurahan': idKelurahan,
|
||||||
'nik': nik,
|
'nik': nik,
|
||||||
|
'noTPS': noTPScontroller.text,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
await httpService.postWithFormData('tim_survei', fomData);
|
await httpService.postWithFormData('tim_survei', fomData);
|
||||||
@ -200,6 +181,7 @@ class HalamanSurveiViewModel extends CustomBaseViewModel {
|
|||||||
_imagePath = null;
|
_imagePath = null;
|
||||||
imageFile = null;
|
imageFile = null;
|
||||||
imageBytes = null;
|
imageBytes = null;
|
||||||
|
noTPScontroller.clear();
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log.e(e);
|
log.e(e);
|
||||||
|
@ -26,6 +26,26 @@ class TimSurveiIndexTrackingView extends StatelessWidget {
|
|||||||
) {
|
) {
|
||||||
return SafeArea(
|
return SafeArea(
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Text(
|
||||||
|
model.header,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: fontColor,
|
||||||
|
fontSize: 20,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
backgroundColor: warningColor,
|
||||||
|
elevation: 0,
|
||||||
|
automaticallyImplyLeading: false,
|
||||||
|
actions: [
|
||||||
|
IconButton(
|
||||||
|
onPressed: () {
|
||||||
|
model.logout();
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.logout, color: fontColor),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
extendBody: false,
|
extendBody: false,
|
||||||
body: ExtendedNavigator(
|
body: ExtendedNavigator(
|
||||||
router: TimSurveiIndexTrackingViewRouter(),
|
router: TimSurveiIndexTrackingViewRouter(),
|
||||||
|
@ -14,6 +14,7 @@ class TimSurveiIndexTrackingViewModel extends IndexTrackingViewModel {
|
|||||||
final navigationService = locator<NavigationService>();
|
final navigationService = locator<NavigationService>();
|
||||||
final snackbarService = locator<SnackbarService>();
|
final snackbarService = locator<SnackbarService>();
|
||||||
final globalVar = locator<GlobalVar>();
|
final globalVar = locator<GlobalVar>();
|
||||||
|
final dialogService = locator<DialogService>();
|
||||||
|
|
||||||
final _bottomNavBarList = [
|
final _bottomNavBarList = [
|
||||||
{
|
{
|
||||||
@ -68,4 +69,20 @@ class TimSurveiIndexTrackingViewModel extends IndexTrackingViewModel {
|
|||||||
id: 5,
|
id: 5,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logout() async {
|
||||||
|
dialogService
|
||||||
|
.showConfirmationDialog(
|
||||||
|
title: 'Konfirmasi',
|
||||||
|
description: 'Apakah anda yakin ingin keluar?',
|
||||||
|
cancelTitle: 'Batal',
|
||||||
|
confirmationTitle: 'Keluar',
|
||||||
|
)
|
||||||
|
.then((value) async {
|
||||||
|
if (value!.confirmed) {
|
||||||
|
await mySharedPrefs.clear();
|
||||||
|
navigationService.clearStackAndShow(Routes.loginScreenView);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,9 +7,13 @@
|
|||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
#include <file_selector_linux/file_selector_plugin.h>
|
#include <file_selector_linux/file_selector_plugin.h>
|
||||||
|
#include <url_launcher_linux/url_launcher_plugin.h>
|
||||||
|
|
||||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||||
g_autoptr(FlPluginRegistrar) file_selector_linux_registrar =
|
g_autoptr(FlPluginRegistrar) file_selector_linux_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin");
|
||||||
file_selector_plugin_register_with_registrar(file_selector_linux_registrar);
|
file_selector_plugin_register_with_registrar(file_selector_linux_registrar);
|
||||||
|
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
|
||||||
|
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
|
||||||
|
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
file_selector_linux
|
file_selector_linux
|
||||||
|
url_launcher_linux
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||||
|
@ -8,9 +8,11 @@ import Foundation
|
|||||||
import file_selector_macos
|
import file_selector_macos
|
||||||
import path_provider_foundation
|
import path_provider_foundation
|
||||||
import shared_preferences_foundation
|
import shared_preferences_foundation
|
||||||
|
import url_launcher_macos
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
|
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
|
||||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||||
|
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||||
}
|
}
|
||||||
|
66
pubspec.lock
@ -877,6 +877,70 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.2"
|
version: "2.2.2"
|
||||||
|
url_launcher:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: url_launcher
|
||||||
|
sha256: "47e208a6711459d813ba18af120d9663c20bdf6985d6ad39fe165d2538378d27"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.1.14"
|
||||||
|
url_launcher_android:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: url_launcher_android
|
||||||
|
sha256: "31222ffb0063171b526d3e569079cf1f8b294075ba323443fdc690842bfd4def"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.2.0"
|
||||||
|
url_launcher_ios:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: url_launcher_ios
|
||||||
|
sha256: "4ac97281cf60e2e8c5cc703b2b28528f9b50c8f7cebc71df6bdf0845f647268a"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.2.0"
|
||||||
|
url_launcher_linux:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: url_launcher_linux
|
||||||
|
sha256: "9f2d390e096fdbe1e6e6256f97851e51afc2d9c423d3432f1d6a02a8a9a8b9fd"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.0"
|
||||||
|
url_launcher_macos:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: url_launcher_macos
|
||||||
|
sha256: b7244901ea3cf489c5335bdacda07264a6e960b1c1b1a9f91e4bc371d9e68234
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.0"
|
||||||
|
url_launcher_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: url_launcher_platform_interface
|
||||||
|
sha256: "980e8d9af422f477be6948bdfb68df8433be71f5743a188968b0c1b887807e50"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.0"
|
||||||
|
url_launcher_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: url_launcher_web
|
||||||
|
sha256: ba140138558fcc3eead51a1c42e92a9fb074a1b1149ed3c73e66035b2ccd94f2
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.19"
|
||||||
|
url_launcher_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: url_launcher_windows
|
||||||
|
sha256: "7754a1ad30ee896b265f8d14078b0513a4dba28d358eabb9d5f339886f4a1adc"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.0"
|
||||||
validatorless:
|
validatorless:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -935,4 +999,4 @@ packages:
|
|||||||
version: "3.1.2"
|
version: "3.1.2"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.1.0-163.1.beta <4.0.0"
|
dart: ">=3.1.0-163.1.beta <4.0.0"
|
||||||
flutter: ">=3.7.0"
|
flutter: ">=3.10.0"
|
||||||
|
@ -42,17 +42,13 @@ dependencies:
|
|||||||
path_provider: ^2.0.9
|
path_provider: ^2.0.9
|
||||||
dio:
|
dio:
|
||||||
flutter_easyloading:
|
flutter_easyloading:
|
||||||
# location: ^4.4.0
|
|
||||||
# flutter_inappwebview:
|
|
||||||
# webview_flutter: ^3.0.4
|
|
||||||
# google_fonts:
|
|
||||||
# flutter_svg:
|
|
||||||
stylish_bottom_bar:
|
stylish_bottom_bar:
|
||||||
validatorless: ^1.2.3
|
validatorless: ^1.2.3
|
||||||
http_parser:
|
http_parser:
|
||||||
intl:
|
intl:
|
||||||
shared_preferences:
|
shared_preferences:
|
||||||
easy_image_viewer:
|
easy_image_viewer:
|
||||||
|
url_launcher:
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
@ -7,8 +7,11 @@
|
|||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
#include <file_selector_windows/file_selector_windows.h>
|
#include <file_selector_windows/file_selector_windows.h>
|
||||||
|
#include <url_launcher_windows/url_launcher_windows.h>
|
||||||
|
|
||||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||||
FileSelectorWindowsRegisterWithRegistrar(
|
FileSelectorWindowsRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("FileSelectorWindows"));
|
registry->GetRegistrarForPlugin("FileSelectorWindows"));
|
||||||
|
UrlLauncherWindowsRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
file_selector_windows
|
file_selector_windows
|
||||||
|
url_launcher_windows
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||||
|