Fakultas Ilmu Komputer UI

Commit be04391b authored by Yoga Pratama's avatar Yoga Pratama
Browse files

[GREEN] Implement add kegiatan page

parent b9648864
Pipeline #77382 passed with stages
in 13 minutes and 15 seconds
......@@ -4,6 +4,7 @@ import 'package:bisaGo/model/kegiatan.dart';
import 'package:bisaGo/network/data/network_model.dart';
import 'package:bisaGo/repository/kegiatan_repository.dart';
import 'package:get_it/get_it.dart';
import 'package:http/http.dart';
import 'package:rxdart/rxdart.dart';
class KegiatanBloc {
......@@ -34,6 +35,15 @@ class KegiatanBloc {
}
}
Future<dynamic> addNewKegiatan(
Map<String, dynamic> newKegiatanData, String placeId) async {
try {
return await _kegiatanRepository.createKegiatan(newKegiatanData, placeId);
} catch (e) {
return Response('Failed to register komentar', 400);
}
}
void resetKegiatanList() {
kegiatanListSink
.add(NetworkModel.completed(KegiatanList(allKegiatanFromApi)));
......
import 'dart:async';
import 'dart:io';
import 'package:bisaGo/bloc/kegiatan_bloc.dart';
import 'package:bisaGo/component/bisago_appbar.dart';
import 'package:bisaGo/component/image_preview_holder.dart';
import 'package:bisaGo/config/styles.dart';
import 'package:bisaGo/model/kegiatan.dart';
import 'package:bisaGo/utils/custom_button.dart';
import 'package:bisaGo/utils/custom_text_field.dart';
import 'package:bisaGo/utils/validator.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:image_picker/image_picker.dart';
import 'package:intl/intl.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
class AddKegiatan extends StatefulWidget {
AddKegiatan({
Key key,
@required this.nama,
@required this.placeId,
}) : super(key: key);
final String nama;
final String placeId;
@override
_AddKegiatanState createState() => _AddKegiatanState();
}
class _AddKegiatanState extends State<AddKegiatan> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
TextEditingController nameController = TextEditingController();
TextEditingController phoneController = TextEditingController();
TextEditingController penyelenggaraController = TextEditingController();
TextEditingController narahubungController = TextEditingController();
TextEditingController deskripsiController = TextEditingController();
String tanggalKegiatan =
'${DateFormat('yyyy-MM-dd hh:mm').format(DateTime.now())}';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: const Size.fromHeight(55),
child: BisaGoAppBar(
title: 'Tambah Kegiatan',
leading: InkWell(
onTap: () => Navigator.pop(context, 'Take me back'),
child: const Icon(Icons.arrow_back_ios),
),
),
),
body: SingleChildScrollView(
child: Form(
key: _formKey,
child: Stack(
children: <Widget>[
Container(
key: const Key('Body Add Kegiatan Page'),
alignment: Alignment.topCenter,
padding: EdgeInsets.only(
top: MediaQuery.of(context).size.height * .04,
left: tripleSpace,
right: tripleSpace,
bottom: tripleSpace),
child: ListBody(
children: <Widget>[
CustomTextField(
title: 'Nama Kegiatan',
required: true,
key: const Key('Text Field Nama'),
validator: FieldValidator.validateName,
controller: nameController,
),
CustomTextField(
title: 'Penyelenggara',
required: true,
key: const Key('Text Field Penyelenggara'),
validator: FieldValidator.validateName,
controller: penyelenggaraController,
),
CustomTextField(
title: 'Nomor Telepon Narahubung',
required: true,
key: const Key('Text Field Nomor Telepon Narahubung'),
validator: FieldValidator.validateName,
controller: narahubungController,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
const Text(
'Tanggal Kegiatan',
style: TextStyle(fontSize: 18),
textAlign: TextAlign.left,
),
const SizedBox(height: 10.0),
TextButton(
key: const Key('Button Tanggal Kegiatan'),
style: TextButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
padding: const EdgeInsets.all(13.0),
backgroundColor: greenPrimary,
),
onPressed: () {
DatePicker.showDateTimePicker(
context,
currentTime: DateTime.parse(tanggalKegiatan),
onChanged: (date) {
setState(() {
tanggalKegiatan =
'${DateFormat('yyyy-MM-dd hh:mm').format(date)}';
});
},
);
},
child: Text(
tanggalKegiatan,
style: const TextStyle(
fontSize: 15.0, color: Colors.white),
),
),
],
),
SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'Foto',
style: TextStyle(fontSize: 18),
textAlign: TextAlign.left,
),
TextButton(
key: const Key('Button Input Foto Gallery'),
style: TextButton.styleFrom(padding: EdgeInsets.zero),
onPressed: () async {
final imageSelected = await _getImage();
setState(() {
_image = imageSelected;
});
},
child: Container(
width: MediaQuery.of(context).size.width * 0.35,
padding: const EdgeInsets.all(9.0),
alignment: Alignment.centerLeft,
decoration: BoxDecoration(
boxShadow: regularShadow,
borderRadius: BorderRadius.circular(10.0),
color: greenPrimary),
child: Row(
children: [
const Icon(
MdiIcons.imagePlus,
color: Colors.white,
size: 14.0,
),
const SizedBox(width: regularSpace),
const Text(
'Dari Gallery',
style: TextStyle(
color: Colors.white, fontSize: 14.0),
),
],
),
),
),
TextButton(
key: const Key('Button Input Foto Camera'),
style: TextButton.styleFrom(padding: EdgeInsets.zero),
onPressed: () async {
final imageSelected = await _getCameraImage();
setState(() {
_image = imageSelected;
});
},
child: Container(
width: MediaQuery.of(context).size.width * 0.35,
padding: const EdgeInsets.all(9.0),
alignment: Alignment.centerLeft,
decoration: BoxDecoration(
boxShadow: regularShadow,
borderRadius: BorderRadius.circular(10.0),
color: greenPrimary),
child: Row(
children: [
const Icon(
MdiIcons.imagePlus,
color: Colors.white,
size: 14.0,
),
const SizedBox(width: regularSpace),
const Text(
'Dari Kamera',
style: TextStyle(
color: Colors.white, fontSize: 14.0),
),
],
),
),
)
],
),
_showImagePreview(),
SizedBox(height: 16),
TextFormField(
key: const Key('Text Field Deskripsi'),
keyboardType: TextInputType.multiline,
maxLines: null,
minLines: 3,
validator: FieldValidator.validateInfo,
controller: deskripsiController,
style: const TextStyle(
fontSize: 18,
),
decoration: InputDecoration(
hintStyle: const TextStyle(
fontWeight: FontWeight.bold, fontSize: 15),
hintText: 'Tulis deskripsi...',
contentPadding: const EdgeInsets.all(8.0),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Theme.of(context).primaryColor,
),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Theme.of(context).primaryColor,
),
),
),
),
Container(
margin: const EdgeInsets.fromLTRB(
0, tripleSpace, 0, regularSpace),
alignment: Alignment.center,
child: ButtonTheme(
key: const Key('Button Simpan'),
minWidth: double.infinity,
height: 40,
child: submitButton('Simpan', _validateLoginInput),
)),
],
),
),
],
),
),
),
);
}
Future<void> _validateLoginInput() async {
final form = _formKey.currentState;
if (_formKey.currentState.validate()) {
form.save();
final fileName = _image.path.split('/').last;
final _imageFile = await MultipartFile.fromFile(
_image.path,
filename: fileName,
);
final newKegiatan = KegiatanModel(
namaKegiatan: nameController.text,
deskripsi: deskripsiController.text,
narahubung: narahubungController.text,
penyelenggara: penyelenggaraController.text,
timeStart: DateTime.parse(tanggalKegiatan),
timeEnd: DateTime.parse(tanggalKegiatan).add(
Duration(days: 1),
),
);
final newKegiatanData = newKegiatan.toJson();
newKegiatanData['images'] = _imageFile;
final _bloc = KegiatanBloc(widget.placeId);
await _bloc.addNewKegiatan(
newKegiatanData,
widget.placeId,
);
successDialog(context);
Timer(const Duration(seconds: 2), () {
Navigator.pop(context);
Navigator.pop(context);
});
} else {
failedDialog(context, '');
}
}
Widget _showImagePreview() {
return _image == null
? const SizedBox(height: 0)
: ImagePreviewHolder(
image: Image.file(_image),
onPressed: () async {
setState(() {
_image = null;
});
},
);
}
void successDialog(BuildContext context) {
const alertDialog = AlertDialog(
title: Text('Tambah informasi berhasil'),
content: Icon(FontAwesomeIcons.checkCircle),
);
showDialog(
context: context,
builder: (BuildContext context) {
return alertDialog;
});
}
void failedDialog(BuildContext context, String message) {
var newMessage = message;
if (message == 'default') {
newMessage = 'Gagal menambahkan informasi';
}
final alertDialog = AlertDialog(
title: Text(newMessage),
content: const Icon(
FontAwesomeIcons.exclamationCircle,
),
);
showDialog(
context: context,
builder: (BuildContext context) {
return alertDialog;
});
}
final picker = ImagePicker();
File _image;
Future _getImage() async {
final image = await picker.getImage(source: ImageSource.gallery);
return File(image.path);
}
Future _getCameraImage() async {
final image =
await picker.getImage(source: ImageSource.camera, imageQuality: 50);
return File(image.path);
}
}
......@@ -3,6 +3,7 @@ import 'package:bisaGo/bloc/lokasi_response_bloc.dart';
import 'package:bisaGo/component/image_holder.dart';
import 'package:bisaGo/model/kegiatan.dart';
import 'package:bisaGo/model/lokasi.dart';
import 'package:bisaGo/page/filter_fasilitas/add_kegiatan.dart';
import 'package:flutter/material.dart';
import 'package:bisaGo/bloc/komentar_bloc.dart';
import 'package:bisaGo/component/bisago_appbar.dart';
......@@ -229,7 +230,7 @@ class _FasilitasState extends State<Fasilitas> {
color: Colors.transparent))),
),
onPressed: () {
checkLoginStatus();
checkLoginStatus('informasi');
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
......@@ -353,7 +354,7 @@ class _FasilitasState extends State<Fasilitas> {
color: Colors.transparent))),
),
onPressed: () {
checkLoginStatus();
checkLoginStatus('kegiatan');
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
......@@ -467,13 +468,13 @@ class _FasilitasState extends State<Fasilitas> {
super.dispose();
}
void checkLoginStatus() async {
void checkLoginStatus(String type) async {
final sharedPreferences = await SharedPreferences.getInstance();
if (sharedPreferences.getString('token') == null) {
await Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (BuildContext context) => const Login()),
(Route<dynamic> route) => false);
} else {
} else if (type == 'informasi') {
await Navigator.of(context)
.push(MaterialPageRoute(
builder: (BuildContext context) => AddInformasi(
......@@ -482,6 +483,18 @@ class _FasilitasState extends State<Fasilitas> {
)))
.then((value) =>
_komentarBloc.fetchKomentarList(widget.lokasi.placeId));
} else {
await Navigator.of(context)
.push(MaterialPageRoute(
builder: (BuildContext context) => AddKegiatan(
nama: widget.lokasi.name,
placeId: widget.lokasi.placeId,
)))
.then(
(value) => _kegiatanBloc.fetchKegiatanList(
widget.lokasi.placeId,
),
);
}
}
......
......@@ -5,6 +5,8 @@ import 'package:bisaGo/network/network_interface.dart';
abstract class BaseKegiatanRepository {
Future<KegiatanList> fetchKegiatan(String placeId);
Future<List<String>> fetchImages(String placeId, int id);
Future<dynamic> createKegiatan(
Map<String, dynamic> newKegiatanData, String placeId);
}
class KegiatanRepository implements BaseKegiatanRepository {
......@@ -32,11 +34,25 @@ class KegiatanRepository implements BaseKegiatanRepository {
final response = await _network.get(url: url, isLogin: false);
var allImages = [];
for (var _index=0; _index < response.length; _index++) {
var fotoUrl = ApiFlavor.getBaseUrl() + response.values.toList()[_index]['foto'];
for (var _index = 0; _index < response.length; _index++) {
var fotoUrl =
ApiFlavor.getBaseUrl() + response.values.toList()[_index]['foto'];
allImages.add(fotoUrl);
}
allImages = allImages.cast<String>();
return allImages;
}
@override
Future<dynamic> createKegiatan(
Map<String, dynamic> newKegiatanData,
String placeId,
) async {
print(newKegiatanData);
final response = await _network.post(
url: '/informasi-fasilitas/lokasi/add-kegiatan/$placeId/',
bodyParams: newKegiatanData,
);
return response;
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment