From 39050f625b21a5866482735d6d85a5ac8dbe09d6 Mon Sep 17 00:00:00 2001 From: fleetimee Date: Mon, 28 Nov 2022 21:13:48 +0700 Subject: [PATCH 1/6] feat: upload --- lib/app/common/constant.dart | 8 +- .../provider/media/save_mediaprovider.dart | 48 ++ .../debitur_model/insight_debitur.model.dart | 50 ++ .../modules/asuransi/views/asuransi_view.dart | 1 - .../bindings/gallery_image_binding.dart | 12 + .../controllers/gallery_image_controller.dart | 23 + .../views/gallery_image_view.dart | 24 + .../views/ijin_legitimasi_view.dart | 23 +- .../views/insight_debitur_view.dart | 15 +- .../modules/media/bindings/media_binding.dart | 12 + .../media/controllers/media_controller.dart | 57 ++ lib/app/modules/media/views/media_view.dart | 152 ++++ lib/app/routes/app_pages.dart | 24 +- lib/app/routes/app_routes.dart | 4 + thunder-tests/thunderCollection.json | 85 +-- thunder-tests/thunderEnvironment.json | 4 +- thunder-tests/thunderclient.json | 675 ++---------------- 17 files changed, 488 insertions(+), 729 deletions(-) create mode 100644 lib/app/data/provider/media/save_mediaprovider.dart create mode 100644 lib/app/modules/gallery_image/bindings/gallery_image_binding.dart create mode 100644 lib/app/modules/gallery_image/controllers/gallery_image_controller.dart create mode 100644 lib/app/modules/gallery_image/views/gallery_image_view.dart create mode 100644 lib/app/modules/media/bindings/media_binding.dart create mode 100644 lib/app/modules/media/controllers/media_controller.dart create mode 100644 lib/app/modules/media/views/media_view.dart diff --git a/lib/app/common/constant.dart b/lib/app/common/constant.dart index 20ea6064..382c6402 100644 --- a/lib/app/common/constant.dart +++ b/lib/app/common/constant.dart @@ -2,7 +2,7 @@ // const baseUrl = 'http://127.0.0.1:3000/api/v1/'; // For mobile based -// const baseUrl = 'http://10.0.2.2:3000/api/v1/'; +const baseUrl = 'http://10.0.2.2:3000/api/v1/'; // check if platform is web @@ -16,8 +16,8 @@ // const baseUrl = // 'https://9bf0-2001-448a-4049-68c4-c80c-e641-b21d-cb5c.ap.ngrok.io/api/v1/'; -const baseUrl = - 'https://number-41-bagooska-the-terribly-tired-tapir-3.fleetimee.repl.co/api/v1/'; +// const baseUrl = +// 'https://number-41-bagooska-the-terribly-tired-tapir-3.fleetimee.repl.co/api/v1/'; // List debitur field string const field = @@ -25,4 +25,4 @@ const field = // Insight debitur query string const joinTable = - 'join=inputNeraca&join=inputRugiLaba&join=inputKeuangan&join=analisaKeuangan&join=analisaKarakter&join=analisaBisnis&join=analisaJenisUsaha&join=agunan&join=agunan.form_tanah&join=agunan.form_kendaraan&join=agunan.form_los&join=agunan.form_peralatan&join=agunan.form_cash&join=agunan.form_lainnya&join=agunan.form_tanah_bangunan&join=syaratLain&join=analisaAgunan&join=ijinLegitimasi&join=asuransi'; + 'join=inputNeraca&join=inputRugiLaba&join=inputKeuangan&join=analisaKeuangan&join=analisaKarakter&join=analisaBisnis&join=analisaJenisUsaha&join=agunan&join=agunan.form_tanah&join=agunan.form_kendaraan&join=agunan.form_los&join=agunan.form_peralatan&join=agunan.form_cash&join=agunan.form_lainnya&join=agunan.form_tanah_bangunan&join=syaratLain&join=analisaAgunan&join=ijinLegitimasi&join=asuransi&join=upload'; diff --git a/lib/app/data/provider/media/save_mediaprovider.dart b/lib/app/data/provider/media/save_mediaprovider.dart new file mode 100644 index 00000000..22291281 --- /dev/null +++ b/lib/app/data/provider/media/save_mediaprovider.dart @@ -0,0 +1,48 @@ +// 🎯 Dart imports: + +// 🐦 Flutter imports: + +// 📦 Package imports: +import 'dart:convert'; + +import 'package:akm/app/common/constant.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:http/http.dart' as http; + +// 🌎 Project imports: +import 'package:akm/app/models/debitur_model/insight_debitur.model.dart'; + +class MediaProvider { + final httpClient = http.Client(); + + Future saveMedia(int id, body) async { + try { + final response = http.MultipartRequest( + 'POST', + Uri.parse('${baseUrl}debiturs/$id/uploads/'), + ) + ..headers.addAll( + {'Content-Type': 'application/json', 'Accept': 'application/json'}, + ) + ..files.add(await http.MultipartFile.fromPath('file', body['file'])); + + response.fields.addAll( + Map.from(body), + ); + + var res = await response.send(); + + final resBody = await res.stream.bytesToString(); + + debugPrint(resBody); + + if (res.statusCode == 201) { + return Upload.fromJson(jsonDecode(resBody)); + } else { + throw Exception('Failed to load data'); + } + } catch (e) { + return Future.error(e); + } + } +} diff --git a/lib/app/models/debitur_model/insight_debitur.model.dart b/lib/app/models/debitur_model/insight_debitur.model.dart index e218973c..3d4ecaeb 100644 --- a/lib/app/models/debitur_model/insight_debitur.model.dart +++ b/lib/app/models/debitur_model/insight_debitur.model.dart @@ -58,6 +58,7 @@ class DebiturInsight { this.syaratLain, this.asuransi, this.analisaAgunan, + this.upload, }); int? id; @@ -109,6 +110,7 @@ class DebiturInsight { List? agunan; List? syaratLain; AnalisaAgunan? analisaAgunan; + List? upload; factory DebiturInsight.fromJson(Map json) => DebiturInsight( id: json["id"], @@ -188,6 +190,9 @@ class DebiturInsight { analisaAgunan: json["analisaAgunan"] == null ? null : AnalisaAgunan.fromJson(json["analisaAgunan"]), + upload: json["upload"] == null + ? null + : List.from(json["upload"].map((x) => Upload.fromJson(x))), ); Map toJson() => { @@ -249,6 +254,51 @@ class DebiturInsight { ? null : List.from(syaratLain!.map((x) => x.toJson())), "analisaAgunan": analisaAgunan == null ? null : analisaAgunan?.toJson(), + "upload": upload == null + ? null + : List.from(upload!.map((x) => x.toJson())), + }; +} + +class Upload { + Upload({ + this.id, + this.keterangan, + this.file, + this.createdDate, + this.updatedDate, + this.debiturId, + }); + + int? id; + String? keterangan; + String? file; + DateTime? createdDate; + DateTime? updatedDate; + int? debiturId; + + factory Upload.fromJson(Map json) => Upload( + id: json["id"] ?? null, + keterangan: json["keterangan"] ?? null, + file: json["file"] ?? null, + createdDate: json["createdDate"] == null + ? null + : DateTime.parse(json["createdDate"]), + updatedDate: json["updatedDate"] == null + ? null + : DateTime.parse(json["updatedDate"]), + debiturId: json["debiturId"] ?? null, + ); + + Map toJson() => { + "id": id ?? null, + "keterangan": keterangan ?? null, + "file": file ?? null, + "createdDate": + createdDate == null ? null : createdDate?.toIso8601String(), + "updatedDate": + updatedDate == null ? null : updatedDate?.toIso8601String(), + "debiturId": debiturId ?? null, }; } diff --git a/lib/app/modules/asuransi/views/asuransi_view.dart b/lib/app/modules/asuransi/views/asuransi_view.dart index 1e5c482a..5647ee90 100644 --- a/lib/app/modules/asuransi/views/asuransi_view.dart +++ b/lib/app/modules/asuransi/views/asuransi_view.dart @@ -155,7 +155,6 @@ class AsuransiView extends GetView { keyboardType: TextInputType.number, validator: FormBuilderValidators.compose([ FormBuilderValidators.required(), - FormBuilderValidators.numeric(), ]), autovalidateMode: AutovalidateMode.onUserInteraction, decoration: const InputDecoration( diff --git a/lib/app/modules/gallery_image/bindings/gallery_image_binding.dart b/lib/app/modules/gallery_image/bindings/gallery_image_binding.dart new file mode 100644 index 00000000..32849bc2 --- /dev/null +++ b/lib/app/modules/gallery_image/bindings/gallery_image_binding.dart @@ -0,0 +1,12 @@ +import 'package:get/get.dart'; + +import '../controllers/gallery_image_controller.dart'; + +class GalleryImageBinding extends Bindings { + @override + void dependencies() { + Get.lazyPut( + () => GalleryImageController(), + ); + } +} diff --git a/lib/app/modules/gallery_image/controllers/gallery_image_controller.dart b/lib/app/modules/gallery_image/controllers/gallery_image_controller.dart new file mode 100644 index 00000000..cd888a6d --- /dev/null +++ b/lib/app/modules/gallery_image/controllers/gallery_image_controller.dart @@ -0,0 +1,23 @@ +import 'package:get/get.dart'; + +class GalleryImageController extends GetxController { + //TODO: Implement GalleryImageController + + final count = 0.obs; + @override + void onInit() { + super.onInit(); + } + + @override + void onReady() { + super.onReady(); + } + + @override + void onClose() { + super.onClose(); + } + + void increment() => count.value++; +} diff --git a/lib/app/modules/gallery_image/views/gallery_image_view.dart b/lib/app/modules/gallery_image/views/gallery_image_view.dart new file mode 100644 index 00000000..bf79ab79 --- /dev/null +++ b/lib/app/modules/gallery_image/views/gallery_image_view.dart @@ -0,0 +1,24 @@ +import 'package:flutter/material.dart'; + +import 'package:get/get.dart'; + +import '../controllers/gallery_image_controller.dart'; + +class GalleryImageView extends GetView { + const GalleryImageView({Key? key}) : super(key: key); + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('GalleryImageView'), + centerTitle: true, + ), + body: const Center( + child: Text( + 'GalleryImageView is working', + style: TextStyle(fontSize: 20), + ), + ), + ); + } +} diff --git a/lib/app/modules/ijin_legitimasi/views/ijin_legitimasi_view.dart b/lib/app/modules/ijin_legitimasi/views/ijin_legitimasi_view.dart index ec093ab8..4fdef77b 100644 --- a/lib/app/modules/ijin_legitimasi/views/ijin_legitimasi_view.dart +++ b/lib/app/modules/ijin_legitimasi/views/ijin_legitimasi_view.dart @@ -75,18 +75,19 @@ class IjinLegitimasiView extends GetView { // inherits the delay & duration from move, ), FormBuilderTextField( - name: 'jenisIjinLegitimasi', - validator: FormBuilderValidators.required(), - autovalidateMode: AutovalidateMode.onUserInteraction, - decoration: const InputDecoration( - prefixIcon: Icon( - FontAwesomeIcons.solidFileLines, - ), - labelText: 'Jenis Ijin', - border: OutlineInputBorder(), - hintText: 'Surat Keterangan Usaha', + name: 'jenisIjinLegitimasi', + validator: FormBuilderValidators.required(), + autovalidateMode: AutovalidateMode.onUserInteraction, + decoration: const InputDecoration( + prefixIcon: Icon( + FontAwesomeIcons.solidFileLines, ), - controller: controller.jenisIjinLegitimasi), + labelText: 'Jenis Ijin', + border: OutlineInputBorder(), + hintText: 'Surat Keterangan Usaha', + ), + controller: controller.jenisIjinLegitimasi, + ), const SizedBox( height: 20.0, ), diff --git a/lib/app/modules/insight_debitur/views/insight_debitur_view.dart b/lib/app/modules/insight_debitur/views/insight_debitur_view.dart index 4363b474..dea96b25 100644 --- a/lib/app/modules/insight_debitur/views/insight_debitur_view.dart +++ b/lib/app/modules/insight_debitur/views/insight_debitur_view.dart @@ -59,7 +59,9 @@ class InsightDebiturView extends GetView { body: CustomScrollView( slivers: [ SliverAppBar( - iconTheme: const IconThemeData(color: primaryColor), + iconTheme: const IconThemeData( + color: primaryColor, + ), backgroundColor: Colors.transparent, bottom: PreferredSize( preferredSize: const Size.fromHeight(0), @@ -206,6 +208,17 @@ class InsightDebiturView extends GetView { }, icon: const Icon(FontAwesomeIcons.pencil), ), + IconButton( + onPressed: () { + Get.toNamed(Routes.MEDIA, + arguments: controller.insightDebitur.value); + }, + icon: const Icon( + FontAwesomeIcons.photoFilm, + ), + enableFeedback: true, + color: primaryColor, + ), IconButton( color: primaryColor, enableFeedback: true, diff --git a/lib/app/modules/media/bindings/media_binding.dart b/lib/app/modules/media/bindings/media_binding.dart new file mode 100644 index 00000000..46df7bf7 --- /dev/null +++ b/lib/app/modules/media/bindings/media_binding.dart @@ -0,0 +1,12 @@ +import 'package:get/get.dart'; + +import '../controllers/media_controller.dart'; + +class MediaBinding extends Bindings { + @override + void dependencies() { + Get.lazyPut( + () => MediaController(), + ); + } +} diff --git a/lib/app/modules/media/controllers/media_controller.dart b/lib/app/modules/media/controllers/media_controller.dart new file mode 100644 index 00000000..3fe157aa --- /dev/null +++ b/lib/app/modules/media/controllers/media_controller.dart @@ -0,0 +1,57 @@ +import 'package:akm/app/data/provider/media/save_mediaprovider.dart'; +import 'package:akm/app/modules/insight_debitur/controllers/insight_debitur_controller.dart'; +import 'package:awesome_dialog/awesome_dialog.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:get/get.dart'; + +class MediaController extends GetxController { + var keterangan = TextEditingController(); + + final debiturController = Get.put(InsightDebiturController()); + + final formKey = GlobalKey(); + + final isMediaProcessing = false.obs; + + void saveMedia(id) { + final body = { + 'keterangan': keterangan.text, + 'file': formKey.currentState?.fields['file']?.value[0].path, + }; + + try { + isMediaProcessing(true); + MediaProvider().saveMedia(id, body).then((resp) { + isMediaProcessing(false); + debiturController.fetchOneDebitur(id); + Get.snackbar( + 'Success', + 'Data berhasil disimpan', + backgroundColor: Colors.green, + colorText: Colors.white, + ); + }, onError: (e) { + isMediaProcessing(false); + AwesomeDialog( + context: Get.context!, + dialogType: DialogType.error, + animType: AnimType.bottomSlide, + title: 'Error', + desc: e.toString(), + btnOkOnPress: () {}, + ).show(); + }); + } catch (e) { + isMediaProcessing(false); + AwesomeDialog( + context: Get.context!, + dialogType: DialogType.error, + animType: AnimType.bottomSlide, + title: 'Error', + desc: e.toString(), + btnOkOnPress: () {}, + ).show(); + } + } +} diff --git a/lib/app/modules/media/views/media_view.dart b/lib/app/modules/media/views/media_view.dart new file mode 100644 index 00000000..617636e8 --- /dev/null +++ b/lib/app/modules/media/views/media_view.dart @@ -0,0 +1,152 @@ +import 'package:akm/app/common/style.dart'; +import 'package:empty_widget/empty_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_animate/flutter_animate.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:form_builder_image_picker/form_builder_image_picker.dart'; +import 'package:form_builder_validators/form_builder_validators.dart'; + +import 'package:get/get.dart'; +import 'package:getwidget/getwidget.dart'; + +import '../controllers/media_controller.dart'; + +class MediaView extends GetView { + MediaView({Key? key}) : super(key: key); + + final data = Get.arguments; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Upload Gambar'), + centerTitle: true, + ), + body: FormBuilder( + key: controller.formKey, + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Animate( + child: const GFCard( + boxFit: BoxFit.cover, + titlePosition: GFPosition.start, + showOverlayImage: true, + imageOverlay: AssetImage( + 'assets/images/home/bi_fast.png', + ), + title: GFListTile( + title: Text( + '', + style: TextStyle( + color: Colors.white, + fontSize: 47, + fontWeight: FontWeight.bold, + ), + ), + ), + content: Text( + '', + style: TextStyle( + color: Colors.white, + fontSize: 20, + fontWeight: FontWeight.bold), + ), + ) + .animate() + .fadeIn() // uses `Animate.defaultDuration` + .scale() // inherits duration from fadeIn + .move( + delay: 300.ms, + duration: + 600.ms) // runs after the above w/new duration + // inherits the delay & duration from move, + ), + FormBuilderTextField( + name: 'keterangan', + validator: FormBuilderValidators.required(), + autovalidateMode: AutovalidateMode.onUserInteraction, + decoration: const InputDecoration( + prefixIcon: Icon( + FontAwesomeIcons.solidFileLines, + ), + labelText: 'Keterangan', + border: OutlineInputBorder(), + hintText: 'Gambar / Dokumen', + ), + controller: controller.keterangan, + ), + const SizedBox( + height: 20, + ), + FormBuilderImagePicker( + name: 'file', + bottomSheetPadding: const EdgeInsets.all(16), + fit: BoxFit.cover, + cameraLabel: const Text('Ambil Foto'), + previewAutoSizeWidth: true, + galleryLabel: const Text('Pilih dari Galeri'), + loadingWidget: ((context) => const Center( + child: CircularProgressIndicator(), + )), + placeholderWidget: EmptyWidget( + image: null, + title: 'Tidak ada gambar', + subTitle: 'Silahkan pilih gambar', + packageImage: PackageImage.Image_1, + ), + imageQuality: 50, + showDecoration: true, + maxImages: 1, + validator: FormBuilderValidators.required(), + autovalidateMode: AutovalidateMode.onUserInteraction, + decoration: const InputDecoration( + border: OutlineInputBorder( + borderSide: BorderSide( + color: Colors.grey, + width: 0.0, + ), + ), + hintText: 'Gambar / Dokumen', + ), + ) + ], + ), + Obx( + () => controller.isMediaProcessing.value + ? const Center( + child: CircularProgressIndicator(), + ) + : GFButton( + color: primaryColor, + size: GFSize.LARGE, + fullWidthButton: true, + onPressed: () { + if (controller.formKey.currentState + ?.saveAndValidate() ?? + false) { + controller.saveMedia(data.id); + } else { + debugPrint(controller.formKey.currentState?.value + .toString()); + debugPrint('validation failed'); + } + }, + text: 'Upload', + ), + ) + ], + ), + ), + ), + ); + } +} diff --git a/lib/app/routes/app_pages.dart b/lib/app/routes/app_pages.dart index cf38eb24..7bee9bb4 100644 --- a/lib/app/routes/app_pages.dart +++ b/lib/app/routes/app_pages.dart @@ -1,9 +1,5 @@ -// 📦 Package imports: import 'package:get/get.dart'; -// 🌎 Project imports: -import 'package:akm/app/modules/asuransi/views/edit_asuransi_view.dart'; -import 'package:akm/app/modules/asuransi/views/lihat_asuransi_view.dart'; import '../modules/agunan_analisis/bindings/agunan_analisis_binding.dart'; import '../modules/agunan_analisis/views/agunan_analisis_view.dart'; import '../modules/agunan_analisis/views/lihat_agunan_analisis_view_view.dart'; @@ -15,6 +11,8 @@ import '../modules/agunan_pilih/bindings/agunan_pilih_binding.dart'; import '../modules/agunan_pilih/views/agunan_pilih_view.dart'; import '../modules/asuransi/bindings/asuransi_binding.dart'; import '../modules/asuransi/views/asuransi_view.dart'; +import '../modules/asuransi/views/edit_asuransi_view.dart'; +import '../modules/asuransi/views/lihat_asuransi_view.dart'; import '../modules/bisnis_analisis/bindings/bisnis_analisis_binding.dart'; import '../modules/bisnis_analisis/views/bisnis_analisis_view.dart'; import '../modules/bisnis_analisis/views/edit_bisnis_analisis_view.dart'; @@ -24,6 +22,8 @@ import '../modules/debitur_deploy/views/debitur_deploy_view.dart'; import '../modules/debitur_real/bindings/debitur_real_binding.dart'; import '../modules/debitur_real/views/debitur_edit_view.dart'; import '../modules/debitur_real/views/debitur_onboarding_view.dart'; +import '../modules/gallery_image/bindings/gallery_image_binding.dart'; +import '../modules/gallery_image/views/gallery_image_view.dart'; import '../modules/home/bindings/home_binding.dart'; import '../modules/home/views/home_view.dart'; import '../modules/ijin_legitimasi/bindings/ijin_legitimasi_binding.dart'; @@ -78,6 +78,8 @@ import '../modules/list_debitur/bindings/list_debitur_binding.dart'; import '../modules/list_debitur/views/list_debitur_view.dart'; import '../modules/list_syarat_lainnya/bindings/list_syarat_lainnya_binding.dart'; import '../modules/list_syarat_lainnya/views/list_syarat_lainnya_view.dart'; +import '../modules/media/bindings/media_binding.dart'; +import '../modules/media/views/media_view.dart'; import '../modules/porsekot_table/bindings/porsekot_table_binding.dart'; import '../modules/porsekot_table/views/porsekot_table_view.dart'; import '../modules/rugi_laba/bindings/rugi_laba_binding.dart'; @@ -95,6 +97,10 @@ import '../modules/usaha_analisis/views/edit_usaha_analisis_view.dart'; import '../modules/usaha_analisis/views/lihat_usaha_analisis_view.dart'; import '../modules/usaha_analisis/views/usaha_analisis_view.dart'; +// 📦 Package imports: + +// 🌎 Project imports: + // ignore_for_file: constant_identifier_names part 'app_routes.dart'; @@ -442,5 +448,15 @@ class AppPages { page: () => EditAsuransiView(), binding: AsuransiBinding(), ), + GetPage( + name: _Paths.MEDIA, + page: () => MediaView(), + binding: MediaBinding(), + ), + GetPage( + name: _Paths.GALLERY_IMAGE, + page: () => const GalleryImageView(), + binding: GalleryImageBinding(), + ), ]; } diff --git a/lib/app/routes/app_routes.dart b/lib/app/routes/app_routes.dart index 954cdf59..75bd50da 100644 --- a/lib/app/routes/app_routes.dart +++ b/lib/app/routes/app_routes.dart @@ -77,6 +77,8 @@ abstract class Routes { static const ASURANSI = _Paths.ASURANSI; static const LIHAT_ASURANSI = _Paths.LIHAT_ASURANSI; static const EDIT_ASURANSI = _Paths.EDIT_ASURANSI; + static const MEDIA = _Paths.MEDIA; + static const GALLERY_IMAGE = _Paths.GALLERY_IMAGE; } abstract class _Paths { @@ -152,4 +154,6 @@ abstract class _Paths { static const ASURANSI = '/asuransi'; static const LIHAT_ASURANSI = '/lihat-asurans'; static const EDIT_ASURANSI = '/edit-asuransi'; + static const MEDIA = '/media'; + static const GALLERY_IMAGE = '/gallery-image'; } diff --git a/thunder-tests/thunderCollection.json b/thunder-tests/thunderCollection.json index 954ad8bc..23d56cdd 100644 --- a/thunder-tests/thunderCollection.json +++ b/thunder-tests/thunderCollection.json @@ -1,82 +1,4 @@ [ - { - "_id": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "colName": "Accesscode Talker", - "created": "2022-07-01T21:32:19.213Z", - "sortNum": 10000, - "folders": [ - { - "_id": "856c36ff-0fa5-49eb-b2b5-b199bfefc8fa", - "name": "Debitur", - "containerId": "", - "created": "2022-07-06T02:33:40.463Z", - "sortNum": 10000 - }, - { - "_id": "11269e40-da53-4a29-8635-bdae288ca8e5", - "name": "Penghasilan Tetap", - "containerId": "", - "created": "2022-07-06T02:33:58.928Z", - "sortNum": 20000 - }, - { - "_id": "2c98df92-734e-49b1-afdd-d4f583ee77a2", - "name": "Penghasilan Tidak Tetap", - "containerId": "", - "created": "2022-07-06T04:08:40.212Z", - "sortNum": 30000 - }, - { - "_id": "afeb3855-8ba9-4e18-8445-d35fe3fb1b8d", - "name": "Users", - "containerId": "", - "created": "2022-07-11T01:02:59.920Z", - "sortNum": 40000 - }, - { - "_id": "37cc2a2e-484a-42af-8e69-ce87ba83bffc", - "name": "Role", - "containerId": "", - "created": "2022-07-11T01:03:35.951Z", - "sortNum": 50000 - }, - { - "_id": "a37e001a-b116-4dda-8452-246da85dd8e2", - "name": "Pro Pengajuan", - "containerId": "", - "created": "2022-07-11T03:12:35.785Z", - "sortNum": 60000 - }, - { - "_id": "0e776d57-21a5-43fe-b762-89c20d81d1ef", - "name": "File Upload", - "containerId": "", - "created": "2022-07-13T02:39:09.533Z", - "sortNum": 70000 - }, - { - "_id": "4109a690-be92-431c-b24a-4d6748a6c18c", - "name": "Agunan", - "containerId": "", - "created": "2022-07-13T07:11:11.865Z", - "sortNum": 80000 - }, - { - "_id": "0c58901b-fee7-4c4e-8907-9415f57bd1dc", - "name": "Business Analytics", - "containerId": "", - "created": "2022-07-13T07:11:32.363Z", - "sortNum": 90000 - }, - { - "_id": "5b184829-c3d6-499a-b09a-774c34893892", - "name": "Character Analysis", - "containerId": "", - "created": "2022-07-13T15:02:02.707Z", - "sortNum": 100000 - } - ] - }, { "_id": "3e42347a-acbf-4266-ae30-f61da3c0cc82", "colName": "Neo Claudius", @@ -236,6 +158,13 @@ "containerId": "", "created": "2022-11-09T01:34:35.377Z", "sortNum": 200000 + }, + { + "_id": "3b567af2-0207-4ab8-ad8a-d6f6169ebd11", + "name": "Upload Image", + "containerId": "", + "created": "2022-11-28T04:38:45.294Z", + "sortNum": 210000 } ] } diff --git a/thunder-tests/thunderEnvironment.json b/thunder-tests/thunderEnvironment.json index e5870389..502fa896 100644 --- a/thunder-tests/thunderEnvironment.json +++ b/thunder-tests/thunderEnvironment.json @@ -2,7 +2,7 @@ { "_id": "664f5f60-ada2-4f7b-9346-3664891144d4", "name": "neo-claudius", - "default": true, + "default": false, "sortNum": 10000, "created": "2022-07-05T23:42:20.152Z", "modified": "2022-11-13T21:48:56.624Z", @@ -16,7 +16,7 @@ { "_id": "484e6cb8-b6c0-48a9-b8f7-edaa58016485", "name": "A", - "default": false, + "default": true, "sortNum": 20000, "created": "2022-09-20T05:25:05.997Z", "modified": "2022-11-11T03:26:23.446Z", diff --git a/thunder-tests/thunderclient.json b/thunder-tests/thunderclient.json index 22757bc2..01126b2b 100644 --- a/thunder-tests/thunderclient.json +++ b/thunder-tests/thunderclient.json @@ -1,600 +1,14 @@ [ - { - "_id": "6ad95a8e-22b2-4b66-b5e5-362286edfc40", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "856c36ff-0fa5-49eb-b2b5-b199bfefc8fa", - "name": "Get all debitur", - "url": "http://localhost:3000/debiturs/", - "method": "GET", - "sortNum": 10000, - "created": "2022-07-01T21:33:08.123Z", - "modified": "2022-08-24T04:19:41.862Z", - "headers": [], - "params": [], - "tests": [] - }, - { - "_id": "41791ff4-03bd-4dd1-8e3f-8e6911a8b1fc", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "856c36ff-0fa5-49eb-b2b5-b199bfefc8fa", - "name": "Get debitur by id", - "url": "http://localhost:3000/debiturs/1", - "method": "GET", - "sortNum": 30000, - "created": "2022-07-02T12:33:20.525Z", - "modified": "2022-07-06T04:25:04.692Z", - "headers": [], - "params": [], - "tests": [] - }, - { - "_id": "fc459d0e-98b4-4cbd-88c8-435449b29002", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "856c36ff-0fa5-49eb-b2b5-b199bfefc8fa", - "name": "Delete debitur", - "url": "http://localhost:3000/debiturs/3", - "method": "DELETE", - "sortNum": 40000, - "created": "2022-07-02T12:40:04.374Z", - "modified": "2022-07-14T02:19:26.373Z", - "headers": [], - "params": [], - "tests": [] - }, - { - "_id": "156119f0-d287-4494-aeec-27cc40bdca34", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "11269e40-da53-4a29-8635-bdae288ca8e5", - "name": "Get fixed income", - "url": "http://localhost:3000/fixeds", - "method": "GET", - "sortNum": 10000, - "created": "2022-07-05T02:08:52.999Z", - "modified": "2022-07-11T04:58:15.711Z", - "headers": [], - "params": [ - { - "name": "limit", - "value": "2", - "isDisabled": true, - "isPath": false - }, - { - "name": "fields", - "value": "jenis_pengajuan,jenis_penggunaan", - "isDisabled": true, - "isPath": false - } - ], - "tests": [] - }, - { - "_id": "1e99e827-8277-4bfa-8ecf-51ab01c0933d", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "11269e40-da53-4a29-8635-bdae288ca8e5", - "name": "Get fixed income by id", - "url": "http://localhost:3000/fixeds/2", - "method": "GET", - "sortNum": 40000, - "created": "2022-07-05T02:10:11.631Z", - "modified": "2022-07-06T02:34:04.451Z", - "headers": [], - "params": [], - "tests": [] - }, - { - "_id": "ced545f2-4482-4da3-8289-1cbf8a8375dc", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "11269e40-da53-4a29-8635-bdae288ca8e5", - "name": "Delete fixed income", - "url": "http://localhost:3000/fixeds/27", - "method": "DELETE", - "sortNum": 50000, - "created": "2022-07-05T02:19:55.484Z", - "modified": "2022-07-14T02:18:21.656Z", - "headers": [], - "params": [], - "tests": [] - }, - { - "_id": "f3e8f1e5-9ca8-4ea3-a078-30ffef116b0f", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "11269e40-da53-4a29-8635-bdae288ca8e5", - "name": "Update fixed income", - "url": "http://localhost:3000/fixeds", - "method": "POST", - "sortNum": 30000, - "created": "2022-07-05T06:52:25.886Z", - "modified": "2022-08-24T23:54:35.308Z", - "headers": [], - "params": [], - "body": { - "type": "json", - "raw": "{\n \"jenis_pengajuan\": \"BARU\",\n \"plafon_fasilitas\": \"1000000\",\n \"jenis_penggunaan\": \"INVESTASI\",\n \"tujuan_penggunaan\": \"Membeli hewan qurban\",\n \"jangka_waktu\": \"5 Bulan\",\n \"penghasilan_pemohon\": \"250000\",\n \"potongan_gaji\": \"10000\",\n \"sisa_penghasilan\": \"230000\",\n \"nama_pejabat_penanggung_jawab\": \"Evil La Twin\",\n \"jabatan_pejabat_penanggung_jawab\": \"Platinum\",\n \"nama_pejabat_pemotong_gaji\": \"Eldlich\",\n \"jabatan_pejabat_pemotong_gaji\": \"Gold\",\n \"no_rekening\": \"552454212\",\n \"tanggal_mulai_kredit\": \"2022-06-11\",\n \"jangka_waktu_kredit\": \"1 Tahun\",\n \"plafon_kredit\": \"10000000\",\n \"debitur\": \"76\",\n \"createdBy\": 3\n}", - "form": [] - }, - "tests": [] - }, - { - "_id": "63660606-5a7c-4052-8a15-889ded7f2dd7", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "856c36ff-0fa5-49eb-b2b5-b199bfefc8fa", - "name": "Edit debitur", - "url": "http://localhost:3000/debiturs/", - "method": "POST", - "sortNum": 25000, - "created": "2022-07-06T04:25:16.463Z", - "modified": "2022-07-19T07:38:19.016Z", - "headers": [], - "params": [], - "body": { - "type": "json", - "raw": "{\n \"nik\": \"15421\",\n \"nama_debitur\": \"Novian Andika\",\n \"alamat\": \"Jln Affandi No 20\",\n \"tempat_lahir\": \"Yogyakarta\",\n \"tanggal_lahir\": \"1994-11-09\",\n \"pekerjaan\": \"Customer Service\",\n \"agama\": \"Islam\",\n \"gender\": \"Perempuan\",\n \"no_telp\": \"084545245454\",\n \"no_seluler\": \"0828783232\",\n \"instansi\": \"Swasta\",\n \"email\": \"soniaekap2@gmail.com\",\n \"nama_ibu\": \"Dunno\",\n \"relationship\": \"Menikah\",\n \"nama_pasangan\": \"Novian Andika\",\n \"pekerjaan_pasangan\": \"Software Developer\",\n \"tgl_lahir_pasangan\": \"1997-09-04\",\n \"tempat_lahir_pasangan\": \"Jakarta\",\n \"nik_pasangan\": 54545454,\n \"total_income\": \"9999999999\",\n \"bidang_usaha\": \"Jasa Pengiriman\",\n \"jumlah_tanggungan\": \"0\",\n \"provinsi\": \"Daerah Istimewa Yogyakarta\",\n \"kabupaten\": \"Sleman\",\n \"kecamatan\": \"Depok\",\n \"kelurahan\": \"Condongcatur\",\n \"rt\": \"01\",\n \"rw\": \"05\",\n \"kode_pos\": \"14045\",\n \"createdBy\": 3\n}", - "form": [] - }, - "tests": [] - }, - { - "_id": "d7d446fa-8354-48f0-9ab8-7d24188fda86", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "856c36ff-0fa5-49eb-b2b5-b199bfefc8fa", - "name": "Filtering", - "url": "http://localhost:3000/debiturs/?s={\"no_ktp1\": \"12345678\"}", - "method": "GET", - "sortNum": 15000, - "created": "2022-07-06T04:26:15.140Z", - "modified": "2022-08-21T06:54:37.368Z", - "headers": [], - "params": [ - { - "name": "s", - "value": "{\"no_ktp1\": \"12345678\"}", - "isPath": false - }, - { - "name": "filter", - "value": "nik||$eq||500000", - "isDisabled": true, - "isPath": false - }, - { - "name": "limit", - "value": "1", - "isDisabled": true, - "isPath": false - }, - { - "name": "fields", - "value": "id,nama_debitur", - "isDisabled": true, - "isPath": false - } - ], - "tests": [] - }, - { - "_id": "01242775-ea13-4a12-b5a5-5bf34a6fabdb", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "2c98df92-734e-49b1-afdd-d4f583ee77a2", - "name": "Get non-fixed income", - "url": "http://localhost:3000/non-fixeds", - "method": "GET", - "sortNum": 60000, - "created": "2022-07-06T04:46:52.344Z", - "modified": "2022-07-06T13:40:27.085Z", - "headers": [], - "params": [], - "tests": [] - }, - { - "_id": "11a9d56d-2e2c-49f1-ac91-46ff091e8f55", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "2c98df92-734e-49b1-afdd-d4f583ee77a2", - "name": "Create non-fixed income", - "url": "http://localhost:3000/non-fixeds", - "method": "POST", - "sortNum": 70000, - "created": "2022-07-06T04:47:20.033Z", - "modified": "2022-07-14T16:17:51.952Z", - "headers": [], - "params": [], - "body": { - "type": "json", - "raw": "{\n \"jenis_pengajuan\": \"ADENDUM\",\n \"plafon_fasilitas\": 2500,\n \"jenis_penggunaan\": \"KONSUMSI\",\n \"tujuan_penggunaan\": \"Bermain Slot\",\n \"jangka_waktu\": \"6 Bulan\",\n \"no_rekening\": 8545454545,\n \"plafon_kredit\": 2001000,\n \"tanggal_mulai_kredit\": \"2022-05-21\",\n \"jangka_waktu_kredit\": \"8 Bulan\",\n \"debitur\": 5,\n \"createdBy\": 3\n}", - "form": [] - }, - "tests": [] - }, - { - "_id": "960054fb-126a-43f8-a495-6ab23a01c2fe", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "2c98df92-734e-49b1-afdd-d4f583ee77a2", - "name": "Get non-fixed income by id", - "url": "http://localhost:3000/non-fixeds/2", - "method": "GET", - "sortNum": 77500, - "created": "2022-07-06T04:57:01.911Z", - "modified": "2022-07-06T05:09:57.682Z", - "headers": [], - "params": [], - "tests": [] - }, - { - "_id": "60561953-9af4-4944-84f7-f7a0615318a7", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "2c98df92-734e-49b1-afdd-d4f583ee77a2", - "name": "Delete non-fixed income", - "url": "localhost:3000/non-fixeds/11", - "method": "DELETE", - "sortNum": 80000, - "created": "2022-07-06T04:58:17.074Z", - "modified": "2022-07-11T04:58:31.435Z", - "headers": [], - "params": [], - "tests": [] - }, - { - "_id": "af892903-b7e2-481b-9f32-3392b15844e1", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "2c98df92-734e-49b1-afdd-d4f583ee77a2", - "name": "Edit non-fixed income", - "url": "http://localhost:3000/non-fixeds/17", - "method": "PUT", - "sortNum": 75000, - "created": "2022-07-06T05:09:32.030Z", - "modified": "2022-07-11T06:20:31.002Z", - "headers": [], - "params": [], - "body": { - "type": "json", - "raw": "{\n \"jenis_pengajuan\": \"ADENDUM\",\n \"plafon_fasilitas\": 2500,\n \"jenis_penggunaan\": \"KONSUMSI\",\n \"tujuan_penggunaan\": \"Bermain Slot\",\n \"jangka_waktu\": \"6 Bulan\",\n \"no_rekening\": 21313131313,\n \"plafon_kredit\": 2000000,\n \"tanggal_mulai_kredit\": \"2022-05-21\",\n \"jangka_waktu_kredit\": \"8 Bulan\",\n \"debitur\": 1,\n \"createdBy\": 1,\n \"submission\": [{\n \"id\": 1\n }]\n}", - "form": [] - }, - "tests": [] - }, - { - "_id": "548969f7-aff0-4e10-8e46-de44855ff4bc", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "37cc2a2e-484a-42af-8e69-ce87ba83bffc", - "name": "Create roles", - "url": "http://localhost:3000/roles/", - "method": "POST", - "sortNum": 10000, - "created": "2022-07-08T06:54:23.768Z", - "modified": "2022-09-06T15:08:06.971Z", - "headers": [], - "params": [], - "body": { - "type": "json", - "raw": "{\n \"name\": \"User\"\n \n}", - "form": [] - }, - "tests": [] - }, - { - "_id": "bf3aaf6f-c6fa-47d4-aa87-6a02db4568c1", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "afeb3855-8ba9-4e18-8445-d35fe3fb1b8d", - "name": "Get users", - "url": "{{baseUrl}}api/v1/users", - "method": "GET", - "sortNum": 110000, - "created": "2022-07-11T01:03:10.735Z", - "modified": "2022-09-29T02:49:04.509Z", - "headers": [], - "params": [], - "tests": [] - }, - { - "_id": "654b5e70-7ea5-4fcd-816c-61cc80a21981", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "afeb3855-8ba9-4e18-8445-d35fe3fb1b8d", - "name": "Create user", - "url": "http://localhost:3000/users", - "method": "POST", - "sortNum": 120000, - "created": "2022-07-11T01:28:32.372Z", - "modified": "2022-09-06T15:04:44.315Z", - "headers": [], - "params": [], - "body": { - "type": "json", - "raw": "{\n \"username\": \"asu\",\n \"password\": \"123\",\n \"roles\": [\n {\n \"name\": \"Admin\"\n }\n ]\n}", - "form": [] - }, - "tests": [] - }, - { - "_id": "9c9adf22-b62b-46fc-b17b-8fd54d2db4f1", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "a37e001a-b116-4dda-8452-246da85dd8e2", - "name": "Get ProPengajuan", - "url": "localhost:3000/submissions", - "method": "GET", - "sortNum": 130000, - "created": "2022-07-11T03:12:44.732Z", - "modified": "2022-07-13T15:37:58.497Z", - "headers": [], - "params": [], - "tests": [] - }, - { - "_id": "84f0fcbb-6e7a-4e31-a36c-e8a9426241b4", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "a37e001a-b116-4dda-8452-246da85dd8e2", - "name": "Edit ProPengajuan", - "url": "localhost:3000/submissions/1", - "method": "PUT", - "sortNum": 132500, - "created": "2022-07-11T03:21:26.759Z", - "modified": "2022-07-13T13:15:57.680Z", - "headers": [], - "params": [], - "body": { - "type": "json", - "raw": "{\n \"createdBy\": 1,\n \"fixed\": [{\n \"id\": 27,\n \"is_approved\": false\n }]\n}", - "form": [] - }, - "tests": [] - }, - { - "_id": "47866816-d485-4edf-a5e3-c2b6ab94ab51", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "a37e001a-b116-4dda-8452-246da85dd8e2", - "name": "Delete ProPengajuan", - "url": "localhost:3000/submissions/1", - "method": "DELETE", - "sortNum": 150000, - "created": "2022-07-11T04:57:32.902Z", - "modified": "2022-07-14T02:17:49.253Z", - "headers": [], - "params": [], - "tests": [] - }, - { - "_id": "db867624-c99f-4d60-add1-a3e851cd8945", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "0e776d57-21a5-43fe-b762-89c20d81d1ef", - "name": "Upload file", - "url": "localhost:3000/uploads/", - "method": "POST", - "sortNum": 10000, - "created": "2022-07-12T02:10:15.768Z", - "modified": "2022-09-11T10:37:29.235Z", - "headers": [], - "params": [], - "body": { - "type": "formdata", - "raw": "", - "form": [ - { - "name": "submission", - "value": "9", - "isDisabled": true - }, - { - "name": "createdBy", - "value": "1", - "isDisabled": true - }, - { - "name": "test", - "value": "1" - } - ], - "files": [ - { - "name": "files", - "value": "D:\\Download\\Pengumuman Jasa Lainnya Perorangan.pdf", - "isDisabled": true - } - ] - }, - "tests": [] - }, - { - "_id": "08a8c536-9e6b-4aac-a1a0-d9ccedf21df0", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "0e776d57-21a5-43fe-b762-89c20d81d1ef", - "name": "List of uploaded files", - "url": "localhost:3000/uploads/", - "method": "GET", - "sortNum": 5000, - "created": "2022-07-13T02:39:23.039Z", - "modified": "2022-07-13T02:39:36.459Z", - "headers": [], - "params": [], - "tests": [] - }, - { - "_id": "056404e2-35b4-4da7-8f4d-7927292fbc24", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "0e776d57-21a5-43fe-b762-89c20d81d1ef", - "name": "Delete file", - "url": "localhost:3000/uploads/11", - "method": "DELETE", - "sortNum": 180000, - "created": "2022-07-13T02:40:03.818Z", - "modified": "2022-07-13T02:40:26.283Z", - "headers": [], - "params": [], - "tests": [] - }, - { - "_id": "4663bd02-79c5-4afb-8d92-36c33036ef80", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "0c58901b-fee7-4c4e-8907-9415f57bd1dc", - "name": "Get business analysis", - "url": "localhost:3000/business_analysis/", - "method": "GET", - "sortNum": 190000, - "created": "2022-07-13T07:11:54.075Z", - "modified": "2022-07-13T14:23:10.900Z", - "headers": [], - "params": [], - "tests": [] - }, - { - "_id": "d3647b4c-9208-4387-8b57-bddc40898c51", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "a37e001a-b116-4dda-8452-246da85dd8e2", - "name": "Create ProPengajuan", - "url": "localhost:3000/submissions/", - "method": "POST", - "sortNum": 131250, - "created": "2022-07-13T13:15:53.014Z", - "modified": "2022-08-24T23:55:23.590Z", - "headers": [], - "params": [], - "body": { - "type": "json", - "raw": "{\n \"createdBy\": 3,\n \"fixed\": [{\n \"id\": 36,\n \"is_approved\": true\n }]\n}", - "form": [] - }, - "tests": [] - }, - { - "_id": "5499835a-f4d6-41e8-9a5b-dabedba7f37d", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "4109a690-be92-431c-b24a-4d6748a6c18c", - "name": "Get Collateral", - "url": "localhost:3000/collaterals", - "method": "GET", - "sortNum": 200000, - "created": "2022-07-13T13:24:19.678Z", - "modified": "2022-07-13T13:24:32.967Z", - "headers": [], - "params": [], - "tests": [] - }, - { - "_id": "b2d89564-0b69-4373-a887-22d67f0106ed", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "4109a690-be92-431c-b24a-4d6748a6c18c", - "name": "Create Collateral", - "url": "localhost:3000/collaterals", - "method": "POST", - "sortNum": 210000, - "created": "2022-07-13T13:24:45.272Z", - "modified": "2022-07-13T13:43:08.857Z", - "headers": [], - "params": [], - "body": { - "type": "json", - "raw": "{\n \"barang_agunan\": \"Mobil\",\n \"asuransi\": \"takimata iriure erat nulla est lobortis volutpat kasd\",\n \"nilai_agunan\": 100000,\n \"bukti_agunan\": \"Lorem ipsum\",\n \"ijin_milik\": \"magna hendrerit labore velit placerat\",\n \"deskripsi_agunan\": \"Consetetur ut sed ut feugait dolor labore eirmod est magna sadipscing elitr labore ipsum labore sanctus nonumy velit magna takimata invidunt magna hendrerit labore velit placerat no dolore dolores diam et sadipscing commodo voluptua consequat gubergren voluptua takimata elitr amet et amet no voluptua in stet doming nulla et sanctus\",\n \"createdBy\": 1,\n \"submission\": 1\n}", - "form": [] - }, - "tests": [] - }, - { - "_id": "54568c69-081c-4e0d-8cd5-1906350e2eb6", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "37cc2a2e-484a-42af-8e69-ce87ba83bffc", - "name": "Get role", - "url": "{{baseUrl}}api/v1/roles", - "method": "GET", - "sortNum": 5000, - "created": "2022-07-13T14:18:25.189Z", - "modified": "2022-09-29T02:50:48.439Z", - "headers": [], - "params": [], - "tests": [] - }, - { - "_id": "54735a63-317a-4f32-9904-deb3bc7b6ac0", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "0c58901b-fee7-4c4e-8907-9415f57bd1dc", - "name": "Create business analysis", - "url": "localhost:3000/business_analysis/", - "method": "POST", - "sortNum": 230000, - "created": "2022-07-13T14:23:43.132Z", - "modified": "2022-07-13T14:28:59.118Z", - "headers": [], - "params": [], - "body": { - "type": "json", - "raw": "{\n \"omset_penjualan\": \"erat nulla est lobortis volutpat kasd\",\n \"harga_bersaing\": \"lorem lorem delenit ut dolore et\",\n \"persaingan\": \"sed at et elitr at sadipscing\",\n \"lokasi\": \"strategis\",\n \"kualitas\": \"bagus\",\n \"deskripsi_bisnis\": \"Kasd accusam sea accusam iriure enim est elitr et sed sadipscing veniam nonumy lorem nonumy illum gubergren quod vel sea aliquam consetetur imperdiet aliquip et tempor tempor ut diam ipsum rebum sadipscing et stet option iriure voluptua sed sed consetetur nonumy sit consetetur takimata rebum amet clita ex et consetetur\",\n \"createdBy\": 1,\n \"submission\": 1\n}", - "form": [] - }, - "tests": [] - }, - { - "_id": "b24f94a4-fc72-4d27-b72c-db84a0f7af53", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "5b184829-c3d6-499a-b09a-774c34893892", - "name": "Get character analysis", - "url": "localhost:3000/character_analysis", - "method": "GET", - "sortNum": 240000, - "created": "2022-07-13T15:02:17.299Z", - "modified": "2022-07-13T15:03:39.686Z", - "headers": [], - "params": [], - "tests": [] - }, - { - "_id": "e41dde0b-60c9-48e7-80e2-d1a58b88bdbd", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "5b184829-c3d6-499a-b09a-774c34893892", - "name": "Create character analysis", - "url": "localhost:3000/character_analysis", - "method": "POST", - "sortNum": 250000, - "created": "2022-07-13T15:03:51.708Z", - "modified": "2022-07-14T01:04:48.794Z", - "headers": [], - "params": [], - "body": { - "type": "json", - "raw": "{\n \"ulet_dalam_bisnis\": 75,\n \"flexible_kaku\": 80,\n \"kreatif_inovatif\": 87,\n \"jujur_dlm_bisnis\": 95,\n \"deskripsi_karakter\": \"Consequat erat rebum odio est sit dolor sea amet sed eirmod ipsum eu eirmod dolor no et ut invidunt nostrud est stet euismod clita voluptua tempor ipsum rebum et sit consetetur tempor tation kasd dolore erat diam labore sed eirmod feugiat et vero adipiscing diam consequat sanctus ut enim voluptua\",\n \"createdBy\": 1,\n \"submission\": 1\n}", - "form": [] - }, - "tests": [] - }, - { - "_id": "50f04b4e-a3d7-46f6-a4af-89a0e86ecbc0", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "a37e001a-b116-4dda-8452-246da85dd8e2", - "name": "Patch one or many items", - "url": "localhost:3000/submissions/10", - "method": "PATCH", - "sortNum": 260000, - "created": "2022-07-14T01:20:18.173Z", - "modified": "2022-07-15T01:28:59.558Z", - "headers": [], - "params": [], - "body": { - "type": "json", - "raw": "{\n \"character_analysis\": {\n \"ulet_dalam_bisnis\": 75,\n \"flexible_kaku\": 65,\n \"kreatif_inovatif\": 87,\n \"jujur_dlm_bisnis\": 95,\n \"deskripsi_karakter\": \"Consequat erat rebum odio est sit dolor sea amet sed eirmod ipsum eu eirmod dolor no et ut invidunt nostrud est stet euismod clita voluptua tempor ipsum rebum et sit consetetur tempor tation kasd dolore erat diam labore sed eirmod feugiat et vero adipiscing diam consequat sanctus ut enim voluptua\",\n \"createdById\": 3\n },\n \"collateral\": {\n \"barang_agunan\": \"Mobil\",\n \"asuransi\": \"takimata iriure erat nulla est lobortis volutpat kasd\",\n \"nilai_agunan\": 100000,\n \"bukti_agunan\": \"Lorem ipsum\",\n \"ijin_milik\": \"magna hendrerit labore velit placerat\",\n \"deskripsi_agunan\": \"Consetetur ut sed ut feugait dolor labore eirmod est magna sadipscing elitr labore ipsum labore sanctus nonumy velit magna takimata invidunt magna hendrerit labore velit placerat no dolore dolores diam et sadipscing commodo voluptua consequat gubergren voluptua takimata elitr amet et amet no voluptua in stet doming nulla et sanctus\",\n \"createdBy\": 3\n },\n \"business_analysis\": {\n \"omset_penjualan\": \"erat nulla est lobortis volutpat kasd\",\n \"harga_bersaing\": \"lorem lorem delenit ut dolore et\",\n \"persaingan\": \"sed at et elitr at sadipscing\",\n \"lokasi\": \"strategis\",\n \"kualitas\": \"bagus\",\n \"deskripsi_bisnis\": \"Kasd accusam sea accusam iriure enim est elitr et sed sadipscing veniam nonumy lorem nonumy illum gubergren quod vel sea aliquam consetetur imperdiet aliquip et tempor tempor ut diam ipsum rebum sadipscing et stet option iriure voluptua sed sed consetetur nonumy sit consetetur takimata rebum amet clita ex et consetetur\",\n \"createdBy\": 3\n }\n \n}", - "form": [] - }, - "tests": [] - }, - { - "_id": "6b2b27f6-c917-4379-9336-405ba243c773", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "5b184829-c3d6-499a-b09a-774c34893892", - "name": "Delete character analysis", - "url": "localhost:3000/character_analysis/11", - "method": "DELETE", - "sortNum": 270000, - "created": "2022-07-14T02:16:46.794Z", - "modified": "2022-07-14T02:17:13.803Z", - "headers": [], - "params": [], - "tests": [] - }, { "_id": "5c653682-4cba-4d3a-ad5d-5ec209f6aa76", "colId": "3e42347a-acbf-4266-ae30-f61da3c0cc82", "containerId": "e9deb1b2-3088-4fc0-9c9f-4ae39119ec95", "name": "Get Debitur By Id", - "url": "{{baseUrl}}api/v1/debiturs/9?join=ijinLegitimasi&join=syaratLain&join=asuransi&join=inputNeraca&join=inputRugiLaba&join=inputKeuangan&join=analisaKeuangan&join=analisaKarakter&join=analisaBisnis&join=analisaJenisUsaha&join=agunan&join=agunan.form_tanah&join=agunan.form_kendaraan&join=agunan.form_los&join=agunan.form_peralatan&join=agunan.form_cash&join=agunan.form_lainnya&join=agunan.form_tanah_bangunan&join=analisaAgunan", + "url": "{{baseUrl}}api/v1/debiturs/3?join=ijinLegitimasi&join=syaratLain&join=asuransi&join=inputNeraca&join=inputRugiLaba&join=inputKeuangan&join=analisaKeuangan&join=analisaKarakter&join=analisaBisnis&join=analisaJenisUsaha&join=agunan&join=agunan.form_tanah&join=agunan.form_kendaraan&join=agunan.form_los&join=agunan.form_peralatan&join=agunan.form_cash&join=agunan.form_lainnya&join=agunan.form_tanah_bangunan&join=analisaAgunan&join=upload", "method": "GET", "sortNum": 280000, "created": "2022-08-20T00:12:21.220Z", - "modified": "2022-11-11T04:53:54.735Z", + "modified": "2022-11-28T08:26:35.538Z", "headers": [], "params": [ { @@ -694,8 +108,7 @@ }, { "name": "join", - "value": "ijinLegitimasi", - "isDisabled": true, + "value": "upload", "isPath": false } ], @@ -753,44 +166,6 @@ "params": [], "tests": [] }, - { - "_id": "d283dc2e-b7d9-4f5a-9a61-e9fd0d8a4a33", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "afeb3855-8ba9-4e18-8445-d35fe3fb1b8d", - "name": "edit roles", - "url": "localhost:3000/users/3", - "method": "PATCH", - "sortNum": 330000, - "created": "2022-08-26T04:11:06.664Z", - "modified": "2022-08-26T04:15:32.617Z", - "headers": [], - "params": [], - "body": { - "type": "json", - "raw": "{\n \"roles\": [\n {\n \"id\": 13,\n \"name\": \"122\"\n }\n ]\n}", - "form": [] - }, - "tests": [] - }, - { - "_id": "0d6fa835-11f2-49af-8d80-5d7eabe06c0b", - "colId": "55df9d89-9cac-4748-9c41-d53dff5232d8", - "containerId": "afeb3855-8ba9-4e18-8445-d35fe3fb1b8d", - "name": "edittt", - "url": "http://localhost:3000/users/18", - "method": "PUT", - "sortNum": 340000, - "created": "2022-08-26T04:20:14.040Z", - "modified": "2022-09-06T15:08:16.971Z", - "headers": [], - "params": [], - "body": { - "type": "json", - "raw": "{\n \"username\": \"fleetimeeeeee11\",\n \"password\": \"123\",\n \"roles\": [\n {\n \"id\": 18\n }\n ]\n}", - "form": [] - }, - "tests": [] - }, { "_id": "bbfc6e76-a84f-43a9-b5aa-219dc7cf9121", "colId": "3e42347a-acbf-4266-ae30-f61da3c0cc82", @@ -1804,5 +1179,49 @@ "headers": [], "params": [], "tests": [] + }, + { + "_id": "a84302fa-7db7-4277-af82-ac1092c99b64", + "colId": "3e42347a-acbf-4266-ae30-f61da3c0cc82", + "containerId": "3b567af2-0207-4ab8-ad8a-d6f6169ebd11", + "name": "Get", + "url": "{{baseUrl}}api/v1/debiturs/5/uploads/", + "method": "GET", + "sortNum": 880000, + "created": "2022-11-28T04:38:57.552Z", + "modified": "2022-11-28T13:49:03.651Z", + "headers": [], + "params": [], + "tests": [] + }, + { + "_id": "39151a13-b8a9-4a34-8f20-a17c5546fb7e", + "colId": "3e42347a-acbf-4266-ae30-f61da3c0cc82", + "containerId": "3b567af2-0207-4ab8-ad8a-d6f6169ebd11", + "name": "Post", + "url": "{{baseUrl}}api/v1/debiturs/5/uploads/", + "method": "POST", + "sortNum": 890000, + "created": "2022-11-28T04:42:22.215Z", + "modified": "2022-11-28T14:13:13.682Z", + "headers": [], + "params": [], + "body": { + "type": "formdata", + "raw": "", + "form": [ + { + "name": "keterangan", + "value": "adada" + } + ], + "files": [ + { + "name": "file", + "value": "c:\\Users\\Novian Andika\\Desktop\\278122273_5151241421581206_3504391876146381605_n.jpg" + } + ] + }, + "tests": [] } ] \ No newline at end of file From 457e6a9c9b6088e6756b4c131306962a6a321974 Mon Sep 17 00:00:00 2001 From: fleetimee Date: Tue, 29 Nov 2022 10:10:05 +0700 Subject: [PATCH 2/6] feat: upload progress --- assets/images/home/process-upload.zip | Bin 0 -> 24714 bytes assets/images/home/upload-files.zip | Bin 0 -> 4701 bytes .../provider/media/save_mediaprovider.dart | 5 +- .../media/controllers/media_controller.dart | 14 ++- lib/app/modules/media/views/media_view.dart | 83 +++++++++++------- lib/app/widget/upload_screen.dart | 65 ++++++++++++++ pubspec.lock | 16 ++++ pubspec.yaml | 4 + thunder-tests/thunderclient.json | 8 +- 9 files changed, 155 insertions(+), 40 deletions(-) create mode 100644 assets/images/home/process-upload.zip create mode 100644 assets/images/home/upload-files.zip create mode 100644 lib/app/widget/upload_screen.dart diff --git a/assets/images/home/process-upload.zip b/assets/images/home/process-upload.zip new file mode 100644 index 0000000000000000000000000000000000000000..06a3396fe89163f7cb589528d167be57cb48f1f8 GIT binary patch literal 24714 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 literal 0 HcmV?d00001 diff --git a/lib/app/data/provider/media/save_mediaprovider.dart b/lib/app/data/provider/media/save_mediaprovider.dart index 22291281..c77ac97a 100644 --- a/lib/app/data/provider/media/save_mediaprovider.dart +++ b/lib/app/data/provider/media/save_mediaprovider.dart @@ -22,7 +22,10 @@ class MediaProvider { Uri.parse('${baseUrl}debiturs/$id/uploads/'), ) ..headers.addAll( - {'Content-Type': 'application/json', 'Accept': 'application/json'}, + { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + }, ) ..files.add(await http.MultipartFile.fromPath('file', body['file'])); diff --git a/lib/app/modules/media/controllers/media_controller.dart b/lib/app/modules/media/controllers/media_controller.dart index 3fe157aa..9644bb66 100644 --- a/lib/app/modules/media/controllers/media_controller.dart +++ b/lib/app/modules/media/controllers/media_controller.dart @@ -1,5 +1,6 @@ import 'package:akm/app/data/provider/media/save_mediaprovider.dart'; import 'package:akm/app/modules/insight_debitur/controllers/insight_debitur_controller.dart'; +import 'package:akm/app/widget/upload_screen.dart'; import 'package:awesome_dialog/awesome_dialog.dart'; import 'package:flutter/material.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart'; @@ -22,12 +23,18 @@ class MediaController extends GetxController { try { isMediaProcessing(true); + Get.dialog( + const UploadScreen(), + barrierDismissible: false, + ); MediaProvider().saveMedia(id, body).then((resp) { isMediaProcessing(false); + clearForm(); + Get.back(); debiturController.fetchOneDebitur(id); Get.snackbar( 'Success', - 'Data berhasil disimpan', + 'File berhasil disimpan', backgroundColor: Colors.green, colorText: Colors.white, ); @@ -54,4 +61,9 @@ class MediaController extends GetxController { ).show(); } } + + void clearForm() { + formKey.currentState?.fields['file']?.reset(); + keterangan.clear(); + } } diff --git a/lib/app/modules/media/views/media_view.dart b/lib/app/modules/media/views/media_view.dart index 617636e8..2359437c 100644 --- a/lib/app/modules/media/views/media_view.dart +++ b/lib/app/modules/media/views/media_view.dart @@ -1,5 +1,4 @@ import 'package:akm/app/common/style.dart'; -import 'package:empty_widget/empty_widget.dart'; import 'package:flutter/material.dart'; import 'package:flutter_animate/flutter_animate.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart'; @@ -9,6 +8,7 @@ import 'package:form_builder_validators/form_builder_validators.dart'; import 'package:get/get.dart'; import 'package:getwidget/getwidget.dart'; +import 'package:lottie/lottie.dart'; import '../controllers/media_controller.dart'; @@ -73,7 +73,6 @@ class MediaView extends GetView { FormBuilderTextField( name: 'keterangan', validator: FormBuilderValidators.required(), - autovalidateMode: AutovalidateMode.onUserInteraction, decoration: const InputDecoration( prefixIcon: Icon( FontAwesomeIcons.solidFileLines, @@ -97,11 +96,36 @@ class MediaView extends GetView { loadingWidget: ((context) => const Center( child: CircularProgressIndicator(), )), - placeholderWidget: EmptyWidget( - image: null, - title: 'Tidak ada gambar', - subTitle: 'Silahkan pilih gambar', - packageImage: PackageImage.Image_1, + placeholderWidget: Center( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Center( + child: Lottie.asset( + 'assets/images/home/upload-files.zip', + frameRate: FrameRate.max, + height: 112, + repeat: true, + errorBuilder: (context, error, stackTrace) { + return const Text( + 'Gagal memuat animasi', + style: TextStyle( + color: Colors.red, + ), + ); + }, + ), + ), + const Center( + child: Text( + 'Klik untuk memilih gambar / dokumen ', + style: TextStyle( + color: Colors.grey, + ), + ), + ), + ], + ), ), imageQuality: 50, showDecoration: true, @@ -109,39 +133,30 @@ class MediaView extends GetView { validator: FormBuilderValidators.required(), autovalidateMode: AutovalidateMode.onUserInteraction, decoration: const InputDecoration( - border: OutlineInputBorder( - borderSide: BorderSide( - color: Colors.grey, - width: 0.0, - ), - ), + border: OutlineInputBorder(), hintText: 'Gambar / Dokumen', ), ) ], ), Obx( - () => controller.isMediaProcessing.value - ? const Center( - child: CircularProgressIndicator(), - ) - : GFButton( - color: primaryColor, - size: GFSize.LARGE, - fullWidthButton: true, - onPressed: () { - if (controller.formKey.currentState - ?.saveAndValidate() ?? - false) { - controller.saveMedia(data.id); - } else { - debugPrint(controller.formKey.currentState?.value - .toString()); - debugPrint('validation failed'); - } - }, - text: 'Upload', - ), + () => GFButton( + color: primaryColor, + size: GFSize.LARGE, + fullWidthButton: true, + onPressed: () { + if (controller.formKey.currentState?.saveAndValidate() ?? + false) { + controller.saveMedia(data.id); + } else { + debugPrint( + controller.formKey.currentState?.value.toString()); + debugPrint('validation failed'); + } + }, + text: + controller.isMediaProcessing.value ? 'Loading' : 'Upload', + ), ) ], ), diff --git a/lib/app/widget/upload_screen.dart b/lib/app/widget/upload_screen.dart new file mode 100644 index 00000000..fb3f5875 --- /dev/null +++ b/lib/app/widget/upload_screen.dart @@ -0,0 +1,65 @@ +import 'package:flutter/material.dart'; +import 'package:lottie/lottie.dart'; +import 'package:scaffold_gradient_background/scaffold_gradient_background.dart'; + +class UploadScreen extends StatelessWidget { + const UploadScreen({super.key}); + + @override + Widget build(BuildContext context) { + return ScaffoldGradientBackground( + gradient: LinearGradient( + begin: Alignment.topLeft, + end: Alignment.bottomRight, + colors: [ + Colors.blue, + Colors.blue.shade900, + ], + ), + body: Align( + alignment: Alignment.center, + child: Container( + padding: const EdgeInsets.all(32), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Center( + child: Text( + 'Sedang Mengupload', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 35, + fontWeight: FontWeight.bold, + ), + ), + ), + Center( + child: Lottie.asset( + 'assets/images/home/process-upload.zip', + frameRate: FrameRate.max, + fit: BoxFit.cover, + repeat: true, + errorBuilder: (context, error, stackTrace) { + return const Text( + 'Gagal memuat animasi', + style: TextStyle( + color: Colors.red, + ), + ); + }, + ), + ), + const Center( + child: CircularProgressIndicator( + color: Colors.white, + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index cd79784d..d7fa4fa4 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -325,6 +325,15 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.0" + flutter_easyloading: + dependency: "direct main" + description: + path: "." + ref: develop + resolved-ref: "0d811bf4f2a8359e9988033339c2ef48883e4df9" + url: "https://github.com/fleetimee/flutter_easyloading" + source: git + version: "3.0.4" flutter_echarts: dependency: "direct main" description: @@ -428,6 +437,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.0" + flutter_spinkit: + dependency: transitive + description: + name: flutter_spinkit + url: "https://pub.dartlang.org" + source: hosted + version: "5.1.0" flutter_styled_toast: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index b8811019..e65c7808 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -26,6 +26,10 @@ dependencies: ref: patch-1 flutter: sdk: flutter + flutter_easyloading: + git: + url: https://github.com/fleetimee/flutter_easyloading + ref: develop flutter_animate: ^2.0.1 flutter_custom_clippers: ^2.0.0 flutter_echarts: ^2.4.0 diff --git a/thunder-tests/thunderclient.json b/thunder-tests/thunderclient.json index 01126b2b..5f67b472 100644 --- a/thunder-tests/thunderclient.json +++ b/thunder-tests/thunderclient.json @@ -4,11 +4,11 @@ "colId": "3e42347a-acbf-4266-ae30-f61da3c0cc82", "containerId": "e9deb1b2-3088-4fc0-9c9f-4ae39119ec95", "name": "Get Debitur By Id", - "url": "{{baseUrl}}api/v1/debiturs/3?join=ijinLegitimasi&join=syaratLain&join=asuransi&join=inputNeraca&join=inputRugiLaba&join=inputKeuangan&join=analisaKeuangan&join=analisaKarakter&join=analisaBisnis&join=analisaJenisUsaha&join=agunan&join=agunan.form_tanah&join=agunan.form_kendaraan&join=agunan.form_los&join=agunan.form_peralatan&join=agunan.form_cash&join=agunan.form_lainnya&join=agunan.form_tanah_bangunan&join=analisaAgunan&join=upload", + "url": "{{baseUrl}}api/v1/debiturs/5?join=ijinLegitimasi&join=syaratLain&join=asuransi&join=inputNeraca&join=inputRugiLaba&join=inputKeuangan&join=analisaKeuangan&join=analisaKarakter&join=analisaBisnis&join=analisaJenisUsaha&join=agunan&join=agunan.form_tanah&join=agunan.form_kendaraan&join=agunan.form_los&join=agunan.form_peralatan&join=agunan.form_cash&join=agunan.form_lainnya&join=agunan.form_tanah_bangunan&join=analisaAgunan&join=upload", "method": "GET", "sortNum": 280000, "created": "2022-08-20T00:12:21.220Z", - "modified": "2022-11-28T08:26:35.538Z", + "modified": "2022-11-28T14:51:32.701Z", "headers": [], "params": [ { @@ -1185,11 +1185,11 @@ "colId": "3e42347a-acbf-4266-ae30-f61da3c0cc82", "containerId": "3b567af2-0207-4ab8-ad8a-d6f6169ebd11", "name": "Get", - "url": "{{baseUrl}}api/v1/debiturs/5/uploads/", + "url": "{{baseUrl}}api/v1/debiturs/2/uploads/", "method": "GET", "sortNum": 880000, "created": "2022-11-28T04:38:57.552Z", - "modified": "2022-11-28T13:49:03.651Z", + "modified": "2022-11-29T01:27:52.826Z", "headers": [], "params": [], "tests": [] From 0c8919223e9ad1a53f990217fc16c2b8bbb814d7 Mon Sep 17 00:00:00 2001 From: fleetimee Date: Tue, 29 Nov 2022 14:31:07 +0700 Subject: [PATCH 3/6] =?UTF-8?q?feat:=20upload=20done=20=F0=9F=91=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../provider/media/save_mediaprovider.dart | 23 ++++++++ .../controllers/gallery_image_controller.dart | 34 ++++++++---- .../views/gallery_image_view.dart | 55 ++++++++++++++++--- .../views/insight_debitur_view.dart | 2 +- .../media/controllers/media_controller.dart | 4 ++ lib/app/routes/app_pages.dart | 2 +- pubspec.lock | 7 +++ pubspec.yaml | 9 +-- thunder-tests/thunderclient.json | 14 +++++ 9 files changed, 125 insertions(+), 25 deletions(-) diff --git a/lib/app/data/provider/media/save_mediaprovider.dart b/lib/app/data/provider/media/save_mediaprovider.dart index c77ac97a..993e014d 100644 --- a/lib/app/data/provider/media/save_mediaprovider.dart +++ b/lib/app/data/provider/media/save_mediaprovider.dart @@ -15,6 +15,29 @@ import 'package:akm/app/models/debitur_model/insight_debitur.model.dart'; class MediaProvider { final httpClient = http.Client(); + Future> fetchMedia(int id) async { + try { + final response = await httpClient.get( + Uri.parse('${baseUrl}debiturs/$id/uploads/'), + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json' + }, + ); + debugPrint(response.body); + + if (response.statusCode == 200) { + var data = jsonDecode(response.body); + debugPrint(data.toString()); + return (data as List).map((e) => Upload.fromJson(e)).toList(); + } else { + throw Exception('Failed to load data'); + } + } catch (e) { + return Future.error(e); + } + } + Future saveMedia(int id, body) async { try { final response = http.MultipartRequest( diff --git a/lib/app/modules/gallery_image/controllers/gallery_image_controller.dart b/lib/app/modules/gallery_image/controllers/gallery_image_controller.dart index cd888a6d..3ccadbf4 100644 --- a/lib/app/modules/gallery_image/controllers/gallery_image_controller.dart +++ b/lib/app/modules/gallery_image/controllers/gallery_image_controller.dart @@ -1,23 +1,33 @@ +import 'package:akm/app/data/provider/media/save_mediaprovider.dart'; +import 'package:akm/app/models/debitur_model/insight_debitur.model.dart'; import 'package:get/get.dart'; class GalleryImageController extends GetxController { - //TODO: Implement GalleryImageController - - final count = 0.obs; @override void onInit() { + getImages(debiturId.id); super.onInit(); } - @override - void onReady() { - super.onReady(); - } + var imageList = List.empty(growable: true).obs; - @override - void onClose() { - super.onClose(); - } + final isImageLoading = false.obs; + + final debiturId = Get.arguments; - void increment() => count.value++; + void getImages(int id) { + try { + isImageLoading(true); + MediaProvider().fetchMedia(id).then((resp) { + isImageLoading(false); + imageList.addAll(resp); + }, onError: (e) { + isImageLoading(false); + Get.snackbar('Error', e.toString()); + }); + } catch (e) { + isImageLoading(false); + Get.snackbar('Error', e.toString()); + } + } } diff --git a/lib/app/modules/gallery_image/views/gallery_image_view.dart b/lib/app/modules/gallery_image/views/gallery_image_view.dart index bf79ab79..0e113b04 100644 --- a/lib/app/modules/gallery_image/views/gallery_image_view.dart +++ b/lib/app/modules/gallery_image/views/gallery_image_view.dart @@ -1,23 +1,64 @@ +import 'package:akm/app/routes/app_pages.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; +import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; +import 'package:photo_view/photo_view.dart'; import '../controllers/gallery_image_controller.dart'; class GalleryImageView extends GetView { - const GalleryImageView({Key? key}) : super(key: key); + GalleryImageView({Key? key}) : super(key: key); + + final data = Get.arguments; + @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: const Text('GalleryImageView'), + title: const Text('Gallery View'), centerTitle: true, ), - body: const Center( - child: Text( - 'GalleryImageView is working', - style: TextStyle(fontSize: 20), - ), + body: Obx(() { + if (controller.isImageLoading.value) { + return const Center( + child: CircularProgressIndicator(), + ); + } else { + return GridView.builder( + itemCount: controller.imageList.length, + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + ), + itemBuilder: (context, index) { + return InkWell( + onTap: () { + showBarModalBottomSheet( + context: context, + builder: (context) { + return PhotoView( + imageProvider: NetworkImage( + controller.imageList[index].file!, + ), + ); + }); + }, + child: Card( + child: Image.network( + controller.imageList[index].file.toString(), + fit: BoxFit.cover, + ), + ), + ); + }, + ); + } + }), + floatingActionButton: FloatingActionButton( + onPressed: () { + Get.toNamed(Routes.MEDIA, arguments: data); + }, + child: const Icon(Icons.add), ), ); } diff --git a/lib/app/modules/insight_debitur/views/insight_debitur_view.dart b/lib/app/modules/insight_debitur/views/insight_debitur_view.dart index dea96b25..3da46ca7 100644 --- a/lib/app/modules/insight_debitur/views/insight_debitur_view.dart +++ b/lib/app/modules/insight_debitur/views/insight_debitur_view.dart @@ -210,7 +210,7 @@ class InsightDebiturView extends GetView { ), IconButton( onPressed: () { - Get.toNamed(Routes.MEDIA, + Get.toNamed(Routes.GALLERY_IMAGE, arguments: controller.insightDebitur.value); }, icon: const Icon( diff --git a/lib/app/modules/media/controllers/media_controller.dart b/lib/app/modules/media/controllers/media_controller.dart index 9644bb66..23f9edf7 100644 --- a/lib/app/modules/media/controllers/media_controller.dart +++ b/lib/app/modules/media/controllers/media_controller.dart @@ -1,4 +1,5 @@ import 'package:akm/app/data/provider/media/save_mediaprovider.dart'; +import 'package:akm/app/modules/gallery_image/controllers/gallery_image_controller.dart'; import 'package:akm/app/modules/insight_debitur/controllers/insight_debitur_controller.dart'; import 'package:akm/app/widget/upload_screen.dart'; import 'package:awesome_dialog/awesome_dialog.dart'; @@ -10,6 +11,7 @@ class MediaController extends GetxController { var keterangan = TextEditingController(); final debiturController = Get.put(InsightDebiturController()); + final galleryController = Get.put(GalleryImageController()); final formKey = GlobalKey(); @@ -30,6 +32,8 @@ class MediaController extends GetxController { MediaProvider().saveMedia(id, body).then((resp) { isMediaProcessing(false); clearForm(); + galleryController.imageList.clear(); + galleryController.getImages(id); Get.back(); debiturController.fetchOneDebitur(id); Get.snackbar( diff --git a/lib/app/routes/app_pages.dart b/lib/app/routes/app_pages.dart index 7bee9bb4..9d7e5524 100644 --- a/lib/app/routes/app_pages.dart +++ b/lib/app/routes/app_pages.dart @@ -455,7 +455,7 @@ class AppPages { ), GetPage( name: _Paths.GALLERY_IMAGE, - page: () => const GalleryImageView(), + page: () => GalleryImageView(), binding: GalleryImageBinding(), ), ]; diff --git a/pubspec.lock b/pubspec.lock index d7fa4fa4..9119de44 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -939,6 +939,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "5.0.0" + photo_view: + dependency: "direct main" + description: + name: photo_view + url: "https://pub.dartlang.org" + source: hosted + version: "0.14.0" platform: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index e65c7808..c10e804d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -26,12 +26,12 @@ dependencies: ref: patch-1 flutter: sdk: flutter - flutter_easyloading: - git: - url: https://github.com/fleetimee/flutter_easyloading - ref: develop flutter_animate: ^2.0.1 flutter_custom_clippers: ^2.0.0 + flutter_easyloading: + git: + url: https://github.com/fleetimee/flutter_easyloading + ref: develop flutter_echarts: ^2.4.0 flutter_form_builder: ^7.7.0 flutter_localizations: @@ -66,6 +66,7 @@ dependencies: open_filex: ^4.3.1 open_street_map_search_and_pick: ^0.0.15 pdf: ^3.8.4 + photo_view: ^0.14.0 printing: ^5.9.3 responsive_framework: git: diff --git a/thunder-tests/thunderclient.json b/thunder-tests/thunderclient.json index 5f67b472..980517e8 100644 --- a/thunder-tests/thunderclient.json +++ b/thunder-tests/thunderclient.json @@ -1223,5 +1223,19 @@ ] }, "tests": [] + }, + { + "_id": "f6559a9b-4679-432c-8be5-5cf255a4fdd8", + "colId": "3e42347a-acbf-4266-ae30-f61da3c0cc82", + "containerId": "3b567af2-0207-4ab8-ad8a-d6f6169ebd11", + "name": "Delete", + "url": "{{baseUrl}}api/v1/debiturs/2/uploads/18", + "method": "DELETE", + "sortNum": 900000, + "created": "2022-11-29T06:31:13.541Z", + "modified": "2022-11-29T06:31:23.074Z", + "headers": [], + "params": [], + "tests": [] } ] \ No newline at end of file From bf0d3b91843c47280a382b7424bb1d175e30086f Mon Sep 17 00:00:00 2001 From: fleetimee Date: Tue, 29 Nov 2022 15:58:11 +0700 Subject: [PATCH 4/6] feat: final --- android/app/src/main/AndroidManifest.xml | 1 + .../controllers/gallery_image_controller.dart | 2 + .../views/gallery_image_view.dart | 136 ++++++++++++++---- pubspec.lock | 67 ++++++++- pubspec.yaml | 5 + .../flutter/generated_plugin_registrant.cc | 3 + windows/flutter/generated_plugins.cmake | 1 + 7 files changed, 189 insertions(+), 26 deletions(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 22b09b84..3b12ba4c 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -34,6 +34,7 @@ android:value="2" /> + diff --git a/lib/app/modules/gallery_image/controllers/gallery_image_controller.dart b/lib/app/modules/gallery_image/controllers/gallery_image_controller.dart index 3ccadbf4..a5ed82ec 100644 --- a/lib/app/modules/gallery_image/controllers/gallery_image_controller.dart +++ b/lib/app/modules/gallery_image/controllers/gallery_image_controller.dart @@ -13,6 +13,8 @@ class GalleryImageController extends GetxController { final isImageLoading = false.obs; + final isImageListView = false.obs; + final debiturId = Get.arguments; void getImages(int id) { diff --git a/lib/app/modules/gallery_image/views/gallery_image_view.dart b/lib/app/modules/gallery_image/views/gallery_image_view.dart index 0e113b04..390cda03 100644 --- a/lib/app/modules/gallery_image/views/gallery_image_view.dart +++ b/lib/app/modules/gallery_image/views/gallery_image_view.dart @@ -2,6 +2,8 @@ import 'package:akm/app/routes/app_pages.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; +import 'package:getwidget/getwidget.dart'; +import 'package:intl/intl.dart'; import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; import 'package:photo_view/photo_view.dart'; @@ -16,8 +18,37 @@ class GalleryImageView extends GetView { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: const Text('Gallery View'), + title: Text('Gallery: ${data.peminjam1}'), centerTitle: true, + actions: [ + Obx(() => PopupMenuButton( + icon: controller.isImageListView.value + ? const Icon( + // gridview icon + Icons.list, + ) + : const Icon( + // listview icon + Icons.grid_view, + ), + itemBuilder: (_) { + return [ + PopupMenuItem( + child: TextButton( + onPressed: () { + Get.back(); + controller.isImageListView.toggle(); + // Get.toNamed(Routes.GALLERY_IMAGE, arguments: data); + }, + child: controller.isImageListView.value + ? const Text('Grid view') + : const Text('List view'), + ), + ), + ]; + }, + )) + ], ), body: Obx(() { if (controller.isImageLoading.value) { @@ -25,33 +56,88 @@ class GalleryImageView extends GetView { child: CircularProgressIndicator(), ); } else { - return GridView.builder( - itemCount: controller.imageList.length, - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, - ), - itemBuilder: (context, index) { - return InkWell( - onTap: () { - showBarModalBottomSheet( - context: context, - builder: (context) { - return PhotoView( - imageProvider: NetworkImage( - controller.imageList[index].file!, + return controller.isImageListView.value + ? ListView.builder( + itemCount: controller.imageList.length, + itemBuilder: (context, index) { + return GestureDetector( + onTap: () { + showMaterialModalBottomSheet( + context: context, + builder: (context) => PhotoView( + imageProvider: NetworkImage( + controller.imageList[index].file!, + ), ), ); - }); - }, - child: Card( - child: Image.network( - controller.imageList[index].file.toString(), - fit: BoxFit.cover, + }, + child: GFListTile( + avatar: GFAvatar( + backgroundImage: NetworkImage( + controller.imageList[index].file!, + ), + shape: GFAvatarShape.square, + ), + titleText: controller.imageList[index].keterangan, + subTitleText: DateFormat('dd MMMM yyyy') + .format(controller.imageList[index].createdDate!), + // description: GFButton( + // onPressed: () async { + // try { + // var imageId = await ImageDownloader.downloadImage( + // controller.imageList[index].file!, + // ); + // if (imageId == null) { + // return; + // } + // var filename = + // await ImageDownloader.findName(imageId); + // var path = + // await ImageDownloader.findPath(imageId); + // var size = + // await ImageDownloader.findByteSize(imageId); + // var mimeType = + // await ImageDownloader.findMimeType(imageId); + // Get.snackbar('Success', 'Image downloaded'); + // } on Exception catch (error) { + // Get.snackbar('Error', error.toString()); + // } + // }, + // text: 'Download', + // color: Colors.red, + // type: GFButtonType.outline, + // ), + ), + ); + }, + ) + : GridView.builder( + itemCount: controller.imageList.length, + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, ), - ), - ); - }, - ); + itemBuilder: (context, index) { + return GestureDetector( + onTap: () { + showMaterialModalBottomSheet( + context: context, + builder: (context) => PhotoView( + imageProvider: NetworkImage( + controller.imageList[index].file!, + ), + ), + ); + }, + child: Container( + margin: const EdgeInsets.all(5), + child: Image.network( + controller.imageList[index].file!, + fit: BoxFit.cover, + ), + ), + ); + }, + ); } }), floatingActionButton: FloatingActionButton( diff --git a/pubspec.lock b/pubspec.lock index 9119de44..42420a3c 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -134,6 +134,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.16.0" + community_material_icon: + dependency: transitive + description: + name: community_material_icon + url: "https://pub.dartlang.org" + source: hosted + version: "5.9.55" convert: dependency: transitive description: @@ -276,6 +283,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "6.1.2" + file_picker: + dependency: transitive + description: + name: file_picker + url: "https://pub.dartlang.org" + source: hosted + version: "5.2.2" finance: dependency: "direct main" description: @@ -519,6 +533,15 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "8.3.0" + form_builder_file_picker: + dependency: "direct main" + description: + path: "." + ref: main + resolved-ref: e3144ef0732d430a75ec75873c285619089c211f + url: "https://github.com/flutter-form-builder-ecosystem/form_builder_file_picker" + source: git + version: "2.3.0" form_builder_image_picker: dependency: "direct main" description: @@ -652,6 +675,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.2.2" + image_downloader: + dependency: "direct main" + description: + name: image_downloader + url: "https://pub.dartlang.org" + source: hosted + version: "0.31.0" image_picker: dependency: "direct main" description: @@ -932,6 +962,41 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.8.4" + permission_handler: + dependency: transitive + description: + name: permission_handler + url: "https://pub.dartlang.org" + source: hosted + version: "10.2.0" + permission_handler_android: + dependency: transitive + description: + name: permission_handler_android + url: "https://pub.dartlang.org" + source: hosted + version: "10.2.0" + permission_handler_apple: + dependency: transitive + description: + name: permission_handler_apple + url: "https://pub.dartlang.org" + source: hosted + version: "9.0.7" + permission_handler_platform_interface: + dependency: transitive + description: + name: permission_handler_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "3.9.0" + permission_handler_windows: + dependency: transitive + description: + name: permission_handler_windows + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.2" petitparser: dependency: transitive description: @@ -1267,7 +1332,7 @@ packages: name: win32 url: "https://pub.dartlang.org" source: hosted - version: "2.7.0" + version: "3.1.2" wkt_parser: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index c10e804d..3dbf364f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -46,6 +46,10 @@ dependencies: flutter_tex_js: ^1.2.17 font_awesome_flutter: ^10.2.1 form_builder_extra_fields: ^8.3.0 + form_builder_file_picker: + git: + url: https://github.com/flutter-form-builder-ecosystem/form_builder_file_picker + ref: main form_builder_image_picker: ^3.1.0 form_builder_validators: ^8.4.0 geocoding: ^2.0.5 @@ -55,6 +59,7 @@ dependencies: google_fonts: ^3.0.1 http: ^0.13.5 image_picker: ^0.8.6 + image_downloader: 0.31.0 intl: ^0.17.0 latlong2: ^0.8.1 lottie: ^2.0.0 diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 1c757696..e9d9dc41 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -7,12 +7,15 @@ #include "generated_plugin_registrant.h" #include +#include #include #include void RegisterPlugins(flutter::PluginRegistry* registry) { GeolocatorWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("GeolocatorWindows")); + PermissionHandlerWindowsPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin")); PrintingPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("PrintingPlugin")); UrlLauncherWindowsRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index de1c4c0f..fe7551e8 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -4,6 +4,7 @@ list(APPEND FLUTTER_PLUGIN_LIST geolocator_windows + permission_handler_windows printing url_launcher_windows ) From 5f4399ce5d85e34d298f4f91c8f069b52b6765ab Mon Sep 17 00:00:00 2001 From: fleetimee Date: Wed, 30 Nov 2022 06:26:09 +0700 Subject: [PATCH 5/6] feat: photo gallery done --- .../views/gallery_image_view.dart | 220 +++++++++++++----- macos/Flutter/GeneratedPluginRegistrant.swift | 2 + pubspec.lock | 98 ++++++++ pubspec.yaml | 6 +- 4 files changed, 267 insertions(+), 59 deletions(-) diff --git a/lib/app/modules/gallery_image/views/gallery_image_view.dart b/lib/app/modules/gallery_image/views/gallery_image_view.dart index 390cda03..269a7cd1 100644 --- a/lib/app/modules/gallery_image/views/gallery_image_view.dart +++ b/lib/app/modules/gallery_image/views/gallery_image_view.dart @@ -1,11 +1,15 @@ import 'package:akm/app/routes/app_pages.dart'; +import 'package:fancy_shimmer_image/fancy_shimmer_image.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:getwidget/getwidget.dart'; +import 'package:image_downloader/image_downloader.dart'; import 'package:intl/intl.dart'; import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; import 'package:photo_view/photo_view.dart'; +import 'package:photo_view/photo_view_gallery.dart'; +import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; import '../controllers/gallery_image_controller.dart'; @@ -62,14 +66,14 @@ class GalleryImageView extends GetView { itemBuilder: (context, index) { return GestureDetector( onTap: () { - showMaterialModalBottomSheet( - context: context, - builder: (context) => PhotoView( - imageProvider: NetworkImage( - controller.imageList[index].file!, - ), - ), - ); + // showMaterialModalBottomSheet( + // context: context, + // builder: (context) => PhotoView( + // imageProvider: NetworkImage( + // controller.imageList[index].file!, + // ), + // ), + // ); }, child: GFListTile( avatar: GFAvatar( @@ -77,66 +81,113 @@ class GalleryImageView extends GetView { controller.imageList[index].file!, ), shape: GFAvatarShape.square, + backgroundColor: Colors.transparent, ), titleText: controller.imageList[index].keterangan, subTitleText: DateFormat('dd MMMM yyyy') .format(controller.imageList[index].createdDate!), - // description: GFButton( - // onPressed: () async { - // try { - // var imageId = await ImageDownloader.downloadImage( - // controller.imageList[index].file!, - // ); - // if (imageId == null) { - // return; - // } - // var filename = - // await ImageDownloader.findName(imageId); - // var path = - // await ImageDownloader.findPath(imageId); - // var size = - // await ImageDownloader.findByteSize(imageId); - // var mimeType = - // await ImageDownloader.findMimeType(imageId); - // Get.snackbar('Success', 'Image downloaded'); - // } on Exception catch (error) { - // Get.snackbar('Error', error.toString()); - // } - // }, - // text: 'Download', - // color: Colors.red, - // type: GFButtonType.outline, - // ), + icon: GFButton( + onPressed: () async { + try { + var imageId = await ImageDownloader.downloadImage( + controller.imageList[index].file!, + ); + if (imageId == null) { + return; + } + var filename = + await ImageDownloader.findName(imageId); + var path = + await ImageDownloader.findPath(imageId); + var size = + await ImageDownloader.findByteSize(imageId); + var mimeType = + await ImageDownloader.findMimeType(imageId); + Get.snackbar( + 'Downloaded', + 'Image downloaded to $path', + snackPosition: SnackPosition.TOP, + icon: const Icon(Icons.download_done), + colorText: Colors.white, + backgroundColor: Colors.green, + ); + } on Exception catch (error) { + Get.snackbar('Error', error.toString()); + } + }, + text: 'Download', + color: GFColors.SUCCESS, + type: GFButtonType.solid, + size: GFSize.LARGE, + shape: GFButtonShape.pills, + ), ), ); }, ) - : GridView.builder( - itemCount: controller.imageList.length, - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, + : GridView.custom( + gridDelegate: SliverQuiltedGridDelegate( + crossAxisCount: 4, + mainAxisSpacing: 4, + crossAxisSpacing: 4, + repeatPattern: QuiltedGridRepeatPattern.inverted, + pattern: [ + const QuiltedGridTile(2, 2), + const QuiltedGridTile(1, 1), + const QuiltedGridTile(1, 1), + const QuiltedGridTile(1, 2), + ], ), - itemBuilder: (context, index) { - return GestureDetector( - onTap: () { - showMaterialModalBottomSheet( - context: context, - builder: (context) => PhotoView( - imageProvider: NetworkImage( - controller.imageList[index].file!, + childrenDelegate: SliverChildBuilderDelegate( + (context, index) { + return GestureDetector( + onTap: () { + showMaterialModalBottomSheet( + context: context, + builder: (context) => PhotoViewGallery.builder( + pageController: PageController( + initialPage: index, + ), + scrollPhysics: const BouncingScrollPhysics(), + itemCount: controller.imageList.length, + onPageChanged: (index) { + controller.imageList[index].id; + }, + builder: (context, index) { + return PhotoViewGalleryPageOptions( + imageProvider: NetworkImage( + controller.imageList[index].file!), + heroAttributes: PhotoViewHeroAttributes( + tag: controller.imageList[index].id + .toString(), + ), + ); + }, + loadingBuilder: (context, event) => Center( + child: SizedBox( + width: 20.0, + height: 20.0, + child: CircularProgressIndicator( + value: event == null + ? 0 + : event.cumulativeBytesLoaded / + event.expectedTotalBytes!, + ), + ), + ), ), - ), - ); - }, - child: Container( - margin: const EdgeInsets.all(5), - child: Image.network( - controller.imageList[index].file!, - fit: BoxFit.cover, + ); + }, + child: FancyShimmerImage( + boxFit: BoxFit.cover, + imageUrl: controller.imageList[index].file!, + shimmerBaseColor: Colors.grey[300]!, + shimmerHighlightColor: Colors.grey[100]!, ), - ), - ); - }, + ); + }, + childCount: controller.imageList.length, + ), ); } }), @@ -149,3 +200,58 @@ class GalleryImageView extends GetView { ); } } + +// GridView.builder( +// itemCount: controller.imageList.length, +// gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( +// crossAxisCount: 2, +// ), +// itemBuilder: (context, index) { +// return GestureDetector( +// onTap: () { +// showMaterialModalBottomSheet( +// context: context, +// builder: (context) => PhotoViewGallery.builder( +// pageController: PageController( +// initialPage: index, +// ), +// scrollPhysics: const BouncingScrollPhysics(), +// itemCount: controller.imageList.length, +// onPageChanged: (index) { +// controller.imageList[index].id; +// }, +// builder: (context, index) { +// return PhotoViewGalleryPageOptions( +// imageProvider: NetworkImage( +// controller.imageList[index].file!), +// heroAttributes: PhotoViewHeroAttributes( +// tag: +// controller.imageList[index].id.toString(), +// ), +// ); +// }, +// loadingBuilder: (context, event) => Center( +// child: SizedBox( +// width: 20.0, +// height: 20.0, +// child: CircularProgressIndicator( +// value: event == null +// ? 0 +// : event.cumulativeBytesLoaded / +// event.expectedTotalBytes!, +// ), +// ), +// ), +// ), +// ); +// }, +// child: Container( +// margin: const EdgeInsets.all(5), +// child: FancyShimmerImage( +// boxFit: BoxFit.cover, +// imageUrl: controller.imageList[index].file!, +// ), +// ), +// ); +// }, +// ); \ No newline at end of file diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 320ab1cf..5a5390d1 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -9,6 +9,7 @@ import device_info_plus import geolocator_apple import path_provider_macos import printing +import sqflite import url_launcher_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { @@ -16,5 +17,6 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) PrintingPlugin.register(with: registry.registrar(forPlugin: "PrintingPlugin")) + SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) } diff --git a/pubspec.lock b/pubspec.lock index 42420a3c..11547e6a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -85,6 +85,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.0" + cached_network_image: + dependency: transitive + description: + name: cached_network_image + url: "https://pub.dartlang.org" + source: hosted + version: "3.2.3" + cached_network_image_platform_interface: + dependency: transitive + description: + name: cached_network_image_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + cached_network_image_web: + dependency: transitive + description: + name: cached_network_image_web + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" change_app_package_name: dependency: "direct dev" description: @@ -269,6 +290,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.1.11" + fancy_shimmer_image: + dependency: "direct main" + description: + name: fancy_shimmer_image + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" ffi: dependency: transitive description: @@ -311,6 +339,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.1" + flutter_blurhash: + dependency: transitive + description: + name: flutter_blurhash + url: "https://pub.dartlang.org" + source: hosted + version: "0.7.0" + flutter_cache_manager: + dependency: transitive + description: + name: flutter_cache_manager + url: "https://pub.dartlang.org" + source: hosted + version: "3.3.0" flutter_chips_input: dependency: transitive description: @@ -458,6 +500,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "5.1.0" + flutter_staggered_grid_view: + dependency: "direct main" + description: + name: flutter_staggered_grid_view + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.2" flutter_styled_toast: dependency: "direct main" description: @@ -864,6 +913,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.0" + octo_image: + dependency: transitive + description: + name: octo_image + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" open_filex: dependency: "direct main" description: @@ -962,6 +1018,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.8.4" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.11.1" permission_handler: dependency: transitive description: @@ -1118,6 +1181,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.9.1" + rxdart: + dependency: transitive + description: + name: rxdart + url: "https://pub.dartlang.org" + source: hosted + version: "0.27.7" scaffold_gradient_background: dependency: "direct main" description: @@ -1158,6 +1228,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.8.2" + sqflite: + dependency: transitive + description: + name: sqflite + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.0+3" + sqflite_common: + dependency: transitive + description: + name: sqflite_common + url: "https://pub.dartlang.org" + source: hosted + version: "2.4.0+2" stack_trace: dependency: transitive description: @@ -1172,6 +1256,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.0" + synchronized: + dependency: transitive + description: + name: synchronized + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0+3" terbilang_id: dependency: "direct main" description: @@ -1277,6 +1368,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.0.1" + uuid: + dependency: transitive + description: + name: uuid + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.7" vector_math: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 3dbf364f..1e0bd686 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -20,6 +20,7 @@ dependencies: empty_widget: ^0.0.5 extended_masked_text: ^2.3.1 faker_dart: ^0.1.11 + fancy_shimmer_image: ^2.0.2 finance: git: url: https://github.com/yuvaraja2303/finance/ @@ -41,12 +42,13 @@ dependencies: flutter_markdown: ^0.6.13 flutter_native_splash: ^2.2.15 flutter_slidable: ^2.0.0 + flutter_staggered_grid_view: ^0.6.2 flutter_styled_toast: ^2.1.3 flutter_svg: ^1.1.6 flutter_tex_js: ^1.2.17 font_awesome_flutter: ^10.2.1 form_builder_extra_fields: ^8.3.0 - form_builder_file_picker: + form_builder_file_picker: git: url: https://github.com/flutter-form-builder-ecosystem/form_builder_file_picker ref: main @@ -58,8 +60,8 @@ dependencies: getwidget: ^3.0.1 google_fonts: ^3.0.1 http: ^0.13.5 - image_picker: ^0.8.6 image_downloader: 0.31.0 + image_picker: ^0.8.6 intl: ^0.17.0 latlong2: ^0.8.1 lottie: ^2.0.0 From 51fb7e6496a6442194eca59fb4be59d3472516e0 Mon Sep 17 00:00:00 2001 From: fleetimee Date: Wed, 30 Nov 2022 11:19:54 +0700 Subject: [PATCH 6/6] feat: share dan download done --- lib/app/common/constant.dart | 6 +- .../controllers/gallery_image_controller.dart | 43 +++++++ .../views/gallery_image_view.dart | 110 ++++++++++-------- macos/Flutter/GeneratedPluginRegistrant.swift | 2 + pubspec.lock | 41 ++++++- pubspec.yaml | 6 +- .../flutter/generated_plugin_registrant.cc | 3 + windows/flutter/generated_plugins.cmake | 1 + 8 files changed, 158 insertions(+), 54 deletions(-) diff --git a/lib/app/common/constant.dart b/lib/app/common/constant.dart index 382c6402..790a5209 100644 --- a/lib/app/common/constant.dart +++ b/lib/app/common/constant.dart @@ -2,7 +2,7 @@ // const baseUrl = 'http://127.0.0.1:3000/api/v1/'; // For mobile based -const baseUrl = 'http://10.0.2.2:3000/api/v1/'; +// const baseUrl = 'http://10.0.2.2:3000/api/v1/'; // check if platform is web @@ -16,8 +16,8 @@ const baseUrl = 'http://10.0.2.2:3000/api/v1/'; // const baseUrl = // 'https://9bf0-2001-448a-4049-68c4-c80c-e641-b21d-cb5c.ap.ngrok.io/api/v1/'; -// const baseUrl = -// 'https://number-41-bagooska-the-terribly-tired-tapir-3.fleetimee.repl.co/api/v1/'; +const baseUrl = + 'https://number-41-bagooska-the-terribly-tired-tapir.fleetimee.repl.co/api/v1/'; // List debitur field string const field = diff --git a/lib/app/modules/gallery_image/controllers/gallery_image_controller.dart b/lib/app/modules/gallery_image/controllers/gallery_image_controller.dart index a5ed82ec..39f9642d 100644 --- a/lib/app/modules/gallery_image/controllers/gallery_image_controller.dart +++ b/lib/app/modules/gallery_image/controllers/gallery_image_controller.dart @@ -1,6 +1,13 @@ +import 'dart:io'; + import 'package:akm/app/data/provider/media/save_mediaprovider.dart'; import 'package:akm/app/models/debitur_model/insight_debitur.model.dart'; +import 'package:dio/dio.dart'; +import 'package:flutter/material.dart'; +import 'package:gallery_saver/gallery_saver.dart'; import 'package:get/get.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:share_plus/share_plus.dart'; class GalleryImageController extends GetxController { @override @@ -32,4 +39,40 @@ class GalleryImageController extends GetxController { Get.snackbar('Error', e.toString()); } } + + void shareNetworkImage(String url, String filename) async { + Directory tempDir = await getTemporaryDirectory(); + + final path = tempDir.path; + + await Dio().download(url, '$path/$filename.jpg'); + + Share.shareFiles(['$path/$filename.jpg']); + } + + void downloadNetworkImage( + String url, String filename, String albumname) async { + Directory tempDir = await getTemporaryDirectory(); + + final path = tempDir.path; + + await Dio().download( + url, + '$path/$filename.jpg', + ); + + GallerySaver.saveImage('$path/$filename.jpg', albumName: albumname); + + Get.snackbar( + 'Success', + 'Image saved', + snackPosition: SnackPosition.BOTTOM, + colorText: Colors.white, + backgroundColor: Colors.green, + icon: const Icon( + Icons.check_circle, + color: Colors.white, + ), + ); + } } diff --git a/lib/app/modules/gallery_image/views/gallery_image_view.dart b/lib/app/modules/gallery_image/views/gallery_image_view.dart index 269a7cd1..ac0b45cd 100644 --- a/lib/app/modules/gallery_image/views/gallery_image_view.dart +++ b/lib/app/modules/gallery_image/views/gallery_image_view.dart @@ -4,7 +4,6 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:getwidget/getwidget.dart'; -import 'package:image_downloader/image_downloader.dart'; import 'package:intl/intl.dart'; import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; import 'package:photo_view/photo_view.dart'; @@ -86,40 +85,43 @@ class GalleryImageView extends GetView { titleText: controller.imageList[index].keterangan, subTitleText: DateFormat('dd MMMM yyyy') .format(controller.imageList[index].createdDate!), - icon: GFButton( - onPressed: () async { - try { - var imageId = await ImageDownloader.downloadImage( - controller.imageList[index].file!, - ); - if (imageId == null) { - return; - } - var filename = - await ImageDownloader.findName(imageId); - var path = - await ImageDownloader.findPath(imageId); - var size = - await ImageDownloader.findByteSize(imageId); - var mimeType = - await ImageDownloader.findMimeType(imageId); - Get.snackbar( - 'Downloaded', - 'Image downloaded to $path', - snackPosition: SnackPosition.TOP, - icon: const Icon(Icons.download_done), - colorText: Colors.white, - backgroundColor: Colors.green, - ); - } on Exception catch (error) { - Get.snackbar('Error', error.toString()); - } - }, - text: 'Download', - color: GFColors.SUCCESS, - type: GFButtonType.solid, - size: GFSize.LARGE, - shape: GFButtonShape.pills, + icon: Row( + children: [ + GFButton( + onPressed: () { + controller.shareNetworkImage( + controller.imageList[index].file!, + controller.imageList[index].keterangan!, + ); + }, + text: 'Share', + color: GFColors.INFO, + type: GFButtonType.solid, + size: GFSize.LARGE, + shape: GFButtonShape.pills, + ), + const SizedBox( + width: 5, + ), + GFButton( + onPressed: () async { + try { + controller.downloadNetworkImage( + controller.imageList[index].file!, + controller.imageList[index].keterangan!, + 'AKM-${data.peminjam1}', + ); + } on Exception catch (error) { + Get.snackbar('Error', error.toString()); + } + }, + text: 'Download', + color: GFColors.SUCCESS, + type: GFButtonType.solid, + size: GFSize.LARGE, + shape: GFButtonShape.pills, + ), + ], ), ), ); @@ -143,8 +145,19 @@ class GalleryImageView extends GetView { return GestureDetector( onTap: () { showMaterialModalBottomSheet( + backgroundColor: Colors.transparent, context: context, builder: (context) => PhotoViewGallery.builder( + backgroundDecoration: const BoxDecoration( + color: Colors.black, + ), + allowImplicitScrolling: true, + enableRotation: true, + loadingBuilder: (context, event) => const Center( + child: CircularProgressIndicator( + color: Colors.red, + ), + ), pageController: PageController( initialPage: index, ), @@ -163,18 +176,21 @@ class GalleryImageView extends GetView { ), ); }, - loadingBuilder: (context, event) => Center( - child: SizedBox( - width: 20.0, - height: 20.0, - child: CircularProgressIndicator( - value: event == null - ? 0 - : event.cumulativeBytesLoaded / - event.expectedTotalBytes!, - ), - ), - ), + // loadingBuilder: (context, event) => Container( + // color: Colors.grey[200], + // child: Center( + // child: SizedBox( + // width: 20.0, + // height: 20.0, + // child: CircularProgressIndicator( + // value: event == null + // ? 0 + // : event.cumulativeBytesLoaded / + // event.expectedTotalBytes!, + // ), + // ), + // ), + // ), ), ); }, diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 5a5390d1..b40527f5 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -9,6 +9,7 @@ import device_info_plus import geolocator_apple import path_provider_macos import printing +import share_plus import sqflite import url_launcher_macos @@ -17,6 +18,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) PrintingPlugin.register(with: registry.registrar(forPlugin: "PrintingPlugin")) + SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) } diff --git a/pubspec.lock b/pubspec.lock index 11547e6a..f3495053 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -175,7 +175,7 @@ packages: name: cross_file url: "https://pub.dartlang.org" source: hosted - version: "0.3.3+1" + version: "0.3.3+2" crypto: dependency: transitive description: @@ -255,6 +255,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "7.0.0" + dio: + dependency: "direct main" + description: + name: dio + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.6" double_back_to_close_app: dependency: "direct main" description: @@ -605,6 +612,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "8.4.0" + gallery_saver: + dependency: "direct main" + description: + name: gallery_saver + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.2" geocoding: dependency: "direct main" description: @@ -878,6 +892,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.0" + mime: + dependency: transitive + description: + name: mime + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" modal_bottom_sheet: dependency: "direct main" description: @@ -963,7 +984,7 @@ packages: source: hosted version: "1.0.1" path_provider: - dependency: transitive + dependency: "direct main" description: name: path_provider url: "https://pub.dartlang.org" @@ -1195,6 +1216,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.3+1" + share_plus: + dependency: "direct main" + description: + name: share_plus + url: "https://pub.dartlang.org" + source: hosted + version: "6.3.0" + share_plus_platform_interface: + dependency: transitive + description: + name: share_plus_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "3.2.0" shimmer: dependency: "direct main" description: @@ -1353,7 +1388,7 @@ packages: name: url_launcher_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.1.1" url_launcher_web: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 1e0bd686..6431a0e4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: akm -version: 1.0.6+14 +version: 1.0.7+15 publish_to: none description: Mobile app untuk Analisis Kredit Mikro built with Flutter and NodeJS. environment: @@ -16,6 +16,7 @@ dependencies: ref: master data_table_2: ^2.3.8 device_info_plus: ^8.0.0 + dio: ^4.0.6 double_back_to_close_app: ^2.1.0 empty_widget: ^0.0.5 extended_masked_text: ^2.3.1 @@ -54,6 +55,7 @@ dependencies: ref: main form_builder_image_picker: ^3.1.0 form_builder_validators: ^8.4.0 + gallery_saver: ^2.3.2 geocoding: ^2.0.5 geolocator: ^9.0.2 get: 4.6.5 @@ -72,6 +74,7 @@ dependencies: numerus: ^2.0.0 open_filex: ^4.3.1 open_street_map_search_and_pick: ^0.0.15 + path_provider: ^2.0.11 pdf: ^3.8.4 photo_view: ^0.14.0 printing: ^5.9.3 @@ -80,6 +83,7 @@ dependencies: url: https://github.com/Codelessly/ResponsiveFramework ref: master scaffold_gradient_background: ^1.0.3+1 + share_plus: ^6.3.0 shimmer: ^2.0.0 terbilang_id: ^0.1.0 url_launcher: ^6.1.7 diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index e9d9dc41..fa212a0f 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -9,6 +9,7 @@ #include #include #include +#include #include void RegisterPlugins(flutter::PluginRegistry* registry) { @@ -18,6 +19,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin")); PrintingPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("PrintingPlugin")); + SharePlusWindowsPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi")); UrlLauncherWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("UrlLauncherWindows")); } diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index fe7551e8..a6e52f19 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -6,6 +6,7 @@ list(APPEND FLUTTER_PLUGIN_LIST geolocator_windows permission_handler_windows printing + share_plus url_launcher_windows )