Fakultas Ilmu Komputer UI

add_informasi.dart 17.3 KB
Newer Older
1
import 'dart:async';
2
3
import 'dart:io';
import 'package:bisaGo/bloc/komentar_bloc.dart';
4
import 'package:bisaGo/component/disabilitas_button_grid.dart';
5
import 'package:bisaGo/component/image_preview_holder.dart';
6
7
8
9

import 'package:bisaGo/config/strings.dart';
import 'package:bisaGo/config/styles.dart';
import 'package:bisaGo/page/login/login.dart';
10
import 'package:bisaGo/utils/custom_button.dart';
11
12
13
14
15
import 'package:bisaGo/utils/custom_alert_dialog.dart';
import 'package:bisaGo/utils/custom_dropdown.dart';
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
16
import 'package:bisaGo/utils/custom_deskripsi_field.dart';
17
18
19
20
21
22
23
24
25
26
27
import 'package:bisaGo/utils/validator.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:image_picker/image_picker.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';

class AddInformasi extends StatefulWidget {
  final String nama;
  @override
  AddInformasiState createState() => AddInformasiState();

28
  const AddInformasi({this.nama, Key key}) : super(key: key);
29
30
31
32
33
34
35
36
37
38
39
}

class AddInformasiState extends State<AddInformasi> {
  Map<String, dynamic> newKomentarData = {};
  KomentarBloc _bloc;
  TextEditingController deskripsiController = TextEditingController();
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
  final picker = ImagePicker();
  File _image;

  Future _getImage() async {
40
    final image = await picker.getImage(source: ImageSource.gallery);
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
    return File(image.path);
//    setState(() {
//      _image = File(image.path);
//      print('_image : $_image');
//    });
  }

  Future _clearImage() async {
    setState(() {
      _image = null;
    });
  }

  @override
  void initState() {
    super.initState();
    _jumlahFasilitas = 0;
    _fisikClicked = false;
    _intelektualClicked = false;
    _mentalClicked = false;
    _sensorikClicked = false;
    _isCounterValid = true;
    _isDisabilitasValid = true;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
70
          title: const Text('Tambah Informasi'),
71
          centerTitle: true,
72
          backgroundColor: const Color(0xff3A903A),
73
74
75
76
77
        ),
        body: SingleChildScrollView(
            child: Form(
          key: _formKey,
          child: Container(
78
            margin: const EdgeInsets.symmetric(horizontal: 25.0),
79
80
81
82
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
83
                const SizedBox(height: doubleSpace),
84
85
                Text(
                  widget.nama,
86
87
                  key: const Key('Text Location Name'),
                  style: const TextStyle(
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
                    fontSize: 28,
                    fontWeight: FontWeight.w800,
                    color: Colors.black,
                    fontFamily: 'Comfortaa',
                  ),
                ),
                // GridView.count(
                //   key: Key('Input Gambar'),
                //   shrinkWrap: true,
                //   primary: false,
                //   padding: const EdgeInsets.all(10),
                //   crossAxisSpacing: 10,
                //   crossAxisCount: 2,
                //   children: <Widget>[
                //     GestureDetector(
                //       onTap: () async {
                //         var imageSelected = await _getImage();
                //         setState(() {
                //           _image = imageSelected;
                //         });
                //         },
                //       child: Container(
                //         padding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 2.0),
                //         decoration: BoxDecoration(
                //           borderRadius: BorderRadius.only(
                //             topLeft: Radius.circular(20.0),
                //             topRight: Radius.circular(20.0),
                //             bottomLeft: Radius.circular(20.0),
                //             bottomRight: Radius.circular(20.0),
                //           ),
                //           color: Colors.black12,
                //         ),
                //         child: _image == null ? Icon(FontAwesomeIcons.plus) : Image.file(_image),
                //       ),
                //     )
                //   ],
                // ),
125
                const SizedBox(height: doubleSpace),
126
127
                CustomDropdown(
                    title: 'Fasilitas / Layanan',
128
                    key: const Key('Dropdown Fasilitas Layanan'),
129
                    dropdownList: fasilitas,
130
131
132
133
134
135
136
                    validator: FieldValidator.validateDropdown,
                    hint: 'Pilih fasilitas / layanan',
                    onChanged: (value) {
                      setState(() {
                        _jenisFasilitas = value;
                      });
                    }),
137
                const SizedBox(height: 10),
138
                const Text(
139
140
141
142
                  'Jumlah fasilitas / layanan',
                  style: TextStyle(fontSize: 18),
                  textAlign: TextAlign.left,
                ),
143
                const SizedBox(height: 10),
144
145
146
                Row(
                  children: [
                    iconButton(
147
148
149
                        const Key('Button Decrement'),
                        const Icon(MdiIcons.minus,
                            color: Colors.black, size: 18),
150
151
152
                        _decrementCount,
                        30,
                        30),
153
                    const SizedBox(width: regularSpace),
154
                    Container(
155
                      key: const Key('Counter Fasilitas Layanan'),
156
157
158
159
160
161
162
163
164
165
166
167
                      alignment: Alignment.center,
                      decoration: BoxDecoration(
                          color: Colors.white,
                          boxShadow: regularShadow,
                          borderRadius: BorderRadius.circular(5.0),
                          border: Border.all(
                              color:
                                  _isCounterValid ? greenPrimary : Colors.red)),
                      height: 30,
                      width: 45,
                      child: Text(
                        _jumlahFasilitas.toString(),
168
                        style: const TextStyle(fontSize: 18.0),
169
170
                      ),
                    ),
171
                    const SizedBox(width: regularSpace),
172
                    iconButton(
173
174
175
                        const Key('Button Increment'),
                        const Icon(MdiIcons.plus,
                            color: Colors.black, size: 18),
176
177
178
179
180
181
182
                        _incrementCount,
                        30,
                        30),
                  ],
                ),
                SizedBox(height: _isCounterValid == true ? 0 : regularSpace),
                FieldValidator.validateCustomFieldAlert(_isCounterValid),
183
                const SizedBox(height: 10),
184
185
                CustomDeskripsiField(
                  title: 'Cara menggunakan',
186
                  key: const Key('Text Field Informasi'),
187
188
189
190
191
                  hint: 'Masukkan cara menggunakan',
                  onSaved: (input) {},
                  validator: FieldValidator.validateInfo,
                  controller: deskripsiController,
                ),
192
                const SizedBox(height: 10),
193
194
195
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
196
                    const Text(
197
198
199
200
201
                      'Foto',
                      style: TextStyle(fontSize: 18),
                      textAlign: TextAlign.left,
                    ),
                    FlatButton(
202
                      key: const Key('Button Input Foto'),
203
204
                      padding: EdgeInsets.zero,
                      onPressed: () async {
205
                        final imageSelected = await _getImage();
206
207
208
209
210
211
                        setState(() {
                          _image = imageSelected;
                        });
                      },
                      child: Container(
                        width: MediaQuery.of(context).size.width * 0.45,
212
                        padding: const EdgeInsets.all(9.0),
213
214
215
                        alignment: Alignment.centerLeft,
                        decoration: BoxDecoration(
                            boxShadow: regularShadow,
216
                            borderRadius: BorderRadius.circular(10.0),
217
218
219
                            color: greenPrimary),
                        child: Row(
                          children: [
220
                            const Icon(
221
222
                              MdiIcons.imagePlus,
                              color: Colors.white,
223
                              size: 14.0,
224
                            ),
225
226
                            const SizedBox(width: regularSpace),
                            const Text(
227
228
                              'Pilih foto',
                              style: TextStyle(
229
                                  color: Colors.white, fontSize: 14.0),
230
231
232
233
234
235
236
                            ),
                          ],
                        ),
                      ),
                    )
                  ],
                ),
wilson's avatar
wilson committed
237
                _showImagePreview(),
238
                const SizedBox(height: 10),
239
                const Text(
240
241
242
243
244
                  'Jenis Disabilitas',
                  style: TextStyle(fontSize: 18),
                  textAlign: TextAlign.left,
                ),
                FieldValidator.validateCustomFieldAlert(_isDisabilitasValid),
245
                const SizedBox(height: 10),
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
                DisabilitasButtonGrid(
                  boolFisik: _fisikClicked,
                  boolIntelektual: _intelektualClicked,
                  boolMental: _mentalClicked,
                  boolSensorik: _sensorikClicked,
                  onPressedFisik: () {
                    setState(() {
                      _fisikClicked = !_fisikClicked;
                    });
                  },
                  onPressedIntelektual: () {
                    setState(() {
                      _intelektualClicked = !_intelektualClicked;
                    });
                  },
                  onPressedMental: () {
                    setState(() {
                      _mentalClicked = !_mentalClicked;
                    });
                  },
                  onPressedSensorik: () {
                    setState(() {
                      _sensorikClicked = !_sensorikClicked;
                    });
                  },
                ),
272
                Container(
273
274
                    key: const Key('Button Simpan'),
                    margin: const EdgeInsets.fromLTRB(0, 30, 0, 10),
275
276
277
278
279
280
281
282
283
284
285
                    alignment: Alignment.center,
                    decoration: BoxDecoration(boxShadow: regularShadow),
                    child: ButtonTheme(
                      height: 55.0,
                      child: FlatButton(
                        color: greenPrimary,
                        shape: RoundedRectangleBorder(
                            borderRadius: BorderRadius.circular(10.0)),
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: [
286
                            const Icon(MdiIcons.check,
287
                                color: Colors.white, size: 30.0),
288
289
                            const SizedBox(width: 5.0),
                            const Text('Simpan',
290
291
292
293
                                style: TextStyle(
                                    color: Colors.white, fontSize: 20.0)),
                          ],
                        ),
294
                        padding: const EdgeInsets.symmetric(vertical: 10.0),
295
296
297
                        onPressed: _validateInformationInput,
                      ),
                    )),
298
                const SizedBox(
299
300
301
302
303
304
305
306
307
                  height: doubleSpace,
                )
              ],
            ),
          ),
        )));
  }

  String _jenisFasilitas;
308
  int _jumlahFasilitas;
309
310
311
312
313
314
315
316
317
318
319
320
321
  bool _fisikClicked;
  bool _intelektualClicked;
  bool _mentalClicked;
  bool _sensorikClicked;
  bool _isCounterValid;
  bool _isDisabilitasValid;
  String _disabilitas = '';

  void _showConfirmationPopUp() {
    showDialog(
        context: context,
        builder: (BuildContext context) {
          return CustomAlertDialog(
322
            key: const Key('Pop Up Konfirmasi'),
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
            title:
                'Apakah kamu sudah yakin informasi yang diberikan sudah benar?',
            leftText: 'Tidak',
            leftIcon: MdiIcons.close,
            leftFunction: () {
              Navigator.of(context).pop(true);
              _resetInput();
            },
            rightText: 'Ya',
            rightIcon: MdiIcons.check,
            rightFunction: () async {
              Navigator.of(context).pop(true);
              await submitKomentar();
            },
          );
        });
  }

341
342
  Future<void> submitKomentar() async {
    final sharedPreferences = await SharedPreferences.getInstance();
343
    if (sharedPreferences.getString('token') == null) {
344
345
      await Navigator.push(
          context, MaterialPageRoute(builder: (_) => const Login()));
346
    } else {
347
      final _namaLokasi = widget.nama.replaceAll(' ', '%20');
348
349
      _bloc = KomentarBloc(_namaLokasi);
      final response = await _bloc.addNewKomentar(newKomentarData, _namaLokasi);
wilson's avatar
wilson committed
350
351
      if (response.containsKey('id')) {
        successDialog(context);
352
        Timer(const Duration(seconds: 2), () {
wilson's avatar
wilson committed
353
354
355
          Navigator.pop(context);
          Navigator.pop(context);
        });
wilson's avatar
wilson committed
356
357
      } else if (response['response'] == 'fasilitas already exist') {
        failedDialog(context, 'Fasilitas/Layanan sudah ditambahkan sebelumnya');
wilson's avatar
wilson committed
358
      } else {
wilson's avatar
wilson committed
359
        failedDialog(context, 'default');
360
361
362
363
      }
    }
  }

364
  Future<void> setKomentarData() async {
365
366
367
368
369
    newKomentarData['deskripsi'] = deskripsiController.text.toString();
    newKomentarData['tag'] = _jenisFasilitas;
    _setJenisDisabilitas();
    newKomentarData['disabilitas'] = _disabilitas;
    newKomentarData['rating'] = 5; //temporary
wilson's avatar
wilson committed
370
    newKomentarData['jumlah'] = _jumlahFasilitas;
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
    newKomentarData['image'] = '';
    if (_image != null) {
      final fileName = _image.path.split('/').last;
      newKomentarData['image'] = await MultipartFile.fromFile(
        _image.path,
        filename: fileName,
      );
    }
  }

  void _setJenisDisabilitas() {
    _disabilitas = '';
    if (_fisikClicked == true && !_disabilitas.contains('DF')) {
      _disabilitas += 'DF ';
    }
    if (_intelektualClicked == true && !_disabilitas.contains('DI')) {
      _disabilitas += 'DI ';
    }
    if (_mentalClicked == true && !_disabilitas.contains('DM')) {
      _disabilitas += 'DM ';
    }
    if (_sensorikClicked == true && !_disabilitas.contains('DS')) {
      _disabilitas += 'DS ';
    }
  }

  void successDialog(BuildContext context) {
398
399
    const alertDialog = AlertDialog(
      title: Text('Tambah informasi berhasil'),
400
401
402
403
404
405
406
407
408
      content: Icon(FontAwesomeIcons.checkCircle),
    );
    showDialog(
        context: context,
        builder: (BuildContext context) {
          return alertDialog;
        });
  }

wilson's avatar
wilson committed
409
  void failedDialog(BuildContext context, String message) {
410
    var newMessage = message;
wilson's avatar
wilson committed
411
    if (message == 'default') {
412
      newMessage = 'Gagal menambahkan informasi';
wilson's avatar
wilson committed
413
    }
414
    final alertDialog = AlertDialog(
415
      title: Text(newMessage),
416
      content: const Icon(FontAwesomeIcons.exclamationCircle),
417
418
419
420
421
422
423
424
    );
    showDialog(
        context: context,
        builder: (BuildContext context) {
          return alertDialog;
        });
  }

wilson's avatar
wilson committed
425
426
  Widget _showImagePreview() {
    return _image == null
427
        ? const SizedBox(height: 0)
428
429
430
431
432
433
434
        : ImagePreviewHolder(
            image: Image.file(_image),
            onPressed: () async {
              setState(() {
                _image = null;
              });
            },
wilson's avatar
wilson committed
435
436
437
          );
  }

438
  Future<void> _validateInformationInput() async {
439
440
441
    final form = _formKey.currentState;
    if (_validateCustomFields() && _formKey.currentState.validate()) {
      form.save();
442
      await setKomentarData();
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
      _showConfirmationPopUp();
    }
  }

  bool _validateCustomFields() {
    return _validateJumlahFasilitas() && _validatePilihDisabilitas();
  }

  bool _validateJumlahFasilitas() {
    if (_jumlahFasilitas >= 1) {
      setState(() {
        _isCounterValid = true;
      });
      return true;
    } else {
      setState(() {
        _isCounterValid = false;
      });
      return false;
    }
  }

  bool _validatePilihDisabilitas() {
    if (_fisikClicked ||
        _intelektualClicked ||
        _mentalClicked ||
        _sensorikClicked) {
      setState(() {
        _isDisabilitasValid = true;
      });
      return true;
    } else {
      setState(() {
        _isDisabilitasValid = false;
      });
      return false;
    }
  }

482
  Future<void> _resetInput() async {
483
484
    deskripsiController.clear();
    await _clearImage();
wilson's avatar
wilson committed
485
486
487
488
489
490
491
    setState(() {
      _fisikClicked = false;
      _intelektualClicked = false;
      _mentalClicked = false;
      _sensorikClicked = false;
      _jumlahFasilitas = 0;
    });
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
  }

  void _incrementCount() {
    setState(() {
      _jumlahFasilitas = _jumlahFasilitas + 1;
    });
  }

  void _decrementCount() {
    if (_jumlahFasilitas > 0) {
      setState(() {
        _jumlahFasilitas = _jumlahFasilitas - 1;
      });
    }
  }
}