Fakultas Ilmu Komputer UI

Commit 44991b58 authored by Muhammad Ariq Basyar's avatar Muhammad Ariq Basyar
Browse files

Merge branch 'dev-bugfix' into 'PBI-9-info_kegiatan'

Dev bugfix

See merge request !36
parents 9f86f284 d4cb01b0
Pipeline #77417 passed with stages
in 14 minutes and 21 seconds
3.3.0:
- New feature for add kegiatan
- Fix bugs
3.2.1:
- Fix cant update fasilitas
......
......@@ -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 {
......@@ -12,9 +13,9 @@ class KegiatanBloc {
List<KegiatanModel> allKegiatanFromApi;
StreamSink<NetworkModel<KegiatanList>> get kegiatanListSink =>
_kegiatanListController.sink;
_kegiatanListController.sink;
Stream<NetworkModel<KegiatanList>> get kegiatanListStream =>
_kegiatanListController.stream;
_kegiatanListController.stream;
KegiatanBloc(String placeId) {
_kegiatanListController = BehaviorSubject<NetworkModel<KegiatanList>>();
......@@ -25,8 +26,8 @@ class KegiatanBloc {
Future<void> fetchKegiatanList(String placeId) async {
kegiatanListSink.add(NetworkModel.loading('Getting Kegiatan'));
try {
final kegiatanListResponse =
await _kegiatanRepository.fetchKegiatan(placeId);
final kegiatanListResponse =
await _kegiatanRepository.fetchKegiatan(placeId);
allKegiatanFromApi = List.from(kegiatanListResponse.allKegiatan);
kegiatanListSink.add(NetworkModel.completed(kegiatanListResponse));
} catch (e) {
......@@ -34,12 +35,21 @@ 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)));
.add(NetworkModel.completed(KegiatanList(allKegiatanFromApi)));
}
void dispose() {
_kegiatanListController?.close();
}
}
\ No newline at end of file
}
......@@ -16,7 +16,8 @@ class KegiatanTerdekatBloc {
KegiatanTerdekatBloc() {
_kegiatanTerdekatController = BehaviorSubject<NetworkModel>();
_kegiatanTerdekatRepository = GetIt.instance.get<BaseKegiatanTerdekatRepository>();
_kegiatanTerdekatRepository =
GetIt.instance.get<BaseKegiatanTerdekatRepository>();
fetchKegiatanTerdekat();
}
......@@ -24,10 +25,11 @@ class KegiatanTerdekatBloc {
kegiatanTerdekatSink.add(NetworkModel.loading('Loading Kegiatan'));
try {
final kegiatanTerdekatResponse =
await _kegiatanTerdekatRepository.fetchKegiatanTerdekatResponse();
kegiatanTerdekatSink.add(NetworkModel.completed(kegiatanTerdekatResponse));
await _kegiatanTerdekatRepository.fetchKegiatanTerdekatResponse();
kegiatanTerdekatSink
.add(NetworkModel.completed(kegiatanTerdekatResponse));
} catch (e) {
kegiatanTerdekatSink.add(NetworkModel.error(e.toString()));
}
}
}
\ No newline at end of file
}
......@@ -10,24 +10,28 @@ class KomentarPostingKegiatanBloc {
StreamController _komentarPostingKegiatanListController;
List<KomentarPostingKegiatanModel> allKomentarPositngKegiatanFromApi;
StreamSink<NetworkModel<KomentarPostingKegiatanList>> get komentarPostingKegiatanListSink =>
_komentarPostingKegiatanListController.sink;
Stream<NetworkModel<KomentarPostingKegiatanList>> get komentarPostingKegiatanListStream =>
_komentarPostingKegiatanListController.stream;
StreamSink<NetworkModel<KomentarPostingKegiatanList>>
get komentarPostingKegiatanListSink =>
_komentarPostingKegiatanListController.sink;
Stream<NetworkModel<KomentarPostingKegiatanList>>
get komentarPostingKegiatanListStream =>
_komentarPostingKegiatanListController.stream;
KomentarPostingKegiatanBloc(String namaLokasi, int id) {
KomentarPostingKegiatanBloc(String placeId, int id) {
_komentarPostingKegiatanListController =
StreamController<NetworkModel<KomentarPostingKegiatanList>>();
_komentarPostingKegiatanRepository =
GetIt.instance.get<BaseKomentarPostingKegiatanRepository>();
fetchKomentarPostingKegiatanList(namaLokasi, id);
fetchKomentarPostingKegiatanList(placeId, id);
}
Future<void> fetchKomentarPostingKegiatanList(String namaLokasi, int id) async {
komentarPostingKegiatanListSink.add(NetworkModel.loading('Getting Komentar'));
Future<void> fetchKomentarPostingKegiatanList(String placeId, int id) async {
komentarPostingKegiatanListSink
.add(NetworkModel.loading('Getting Komentar'));
try {
final komentarPostingKegiatanListResponse =
await _komentarPostingKegiatanRepository.fetchKomentarPostingKegiatan(namaLokasi, id);
await _komentarPostingKegiatanRepository.fetchKomentarPostingKegiatan(
placeId, id);
allKomentarPositngKegiatanFromApi =
List.from(komentarPostingKegiatanListResponse.allKomentarKegiatan);
......@@ -40,19 +44,20 @@ class KomentarPostingKegiatanBloc {
Future<dynamic> addKomentarPostingKegiatan(
Map<String, dynamic> newKomentarPostingKegiatanData,
String namaLokasi,
String placeId,
int id) async {
try {
return await _komentarPostingKegiatanRepository.createKomentarPostingKegiatan(
newKomentarPostingKegiatanData, namaLokasi, id);
return await _komentarPostingKegiatanRepository
.createKomentarPostingKegiatan(
newKomentarPostingKegiatanData, placeId, id);
} catch (e) {
return Response('Failed to add komentar', 400);
}
}
void resetKomentarPostingKegiatanList() {
komentarPostingKegiatanListSink.add(
NetworkModel.completed(KomentarPostingKegiatanList(allKomentarPositngKegiatanFromApi)));
komentarPostingKegiatanListSink.add(NetworkModel.completed(
KomentarPostingKegiatanList(allKomentarPositngKegiatanFromApi)));
}
void dispose() {
......
......@@ -3,6 +3,8 @@ import 'package:bisaGo/model/komentar.dart';
import 'package:bisaGo/model/lokasi.dart';
import 'package:bisaGo/bloc/kegiatan_terdekat_bloc.dart';
import 'package:bisaGo/model/kegiatan.dart';
import 'package:bisaGo/page/filter_fasilitas/postingan/detail_post_kegiatan.dart';
import 'package:bisaGo/repository/kegiatan_repository.dart';
import 'package:bisaGo/utils/custom_kegiatan_terdekat_button.dart';
import 'package:bisaGo/network/data/network_model.dart';
import 'package:bisaGo/page/filter_fasilitas/postingan/detail_post.dart';
......@@ -92,157 +94,150 @@ class DashboardState extends State<Dashboard> {
children: <Widget>[
Container(
padding: EdgeInsets.only(top: 35),
child:_buildGoogleMap(context)),
Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
child: _buildGoogleMap(context)),
Column(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <
Widget>[
Container(
height: 40,
alignment: Alignment.center,
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(10.0),
bottomRight: Radius.circular(10.0)
),
bottomLeft: Radius.circular(10.0),
bottomRight: Radius.circular(10.0)),
),
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: doubleSpace),
child: StreamBuilder<NetworkModel>(
stream: blocKegiatanTerdekat.kegiatanTerdekatStream,
builder: (context, snapshot) {
if (snapshot.hasData) {
switch (snapshot.data.status) {
case Status.loading:
return Container(
child: const Center(
child: LinearProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(
greenPrimary),
)
)
);
break;
case Status.completed:
final kegiatanTerdekat =
snapshot.data.data;
return _buildKegiatanTerdekatWidget(
kegiatanTerdekat);
break;
case Status.error:
return Container(
child: const Center(child:
Text('Tidak ada kegiatan dalam waktu dekat',
style: TextStyle(
color: greenPrimary,
fontSize: 16,
fontFamily: 'Muli',
)),));
break;
}
return Container();
}
return Container();
}
)
)
), // Container info kegiatan
Container(
height: 285,
alignment: Alignment.bottomCenter,
decoration: const BoxDecoration(
color: white,
borderRadius: BorderRadius.all(
Radius.circular(10.0),
),
),
padding: const EdgeInsets.symmetric(
horizontal: doubleSpace, vertical: doubleSpace),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
InkWell(
key: const Key('Navigate to Pencarian'),
onTap: () => _navigateToPencarianPage(context),
child: Container(
key: const Key('Container Text Field'),
padding: EdgeInsets.zero,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: regularBorderRadius,
border: Border.all(color: greenPrimary),
boxShadow: regularShadow),
child: TextFormField(
enabled: false,
key: const Key('Text Field Mau Kemana'),
decoration: const InputDecoration(
prefixIcon: Icon(
Icons.search,
color: greenPrimary,
size: 25,
),
border: InputBorder.none,
fillColor: Colors.white,
labelText: 'Tekan untuk mencari tempat',
labelStyle: TextStyle(
color: greenPrimary,
fontSize: 20,
fontFamily: 'Muli',
fontWeight: FontWeight.w700),
),
),
),
),
const SizedBox(height: doubleSpace),
const Text(
'Paling sering dicari',
style: TextStyle(
color: Colors.black,
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 10),
StreamBuilder<NetworkModel<LokasiListResponse>>(
stream: bloc.lokasiListStream,
padding:
const EdgeInsets.symmetric(horizontal: doubleSpace),
child: StreamBuilder<NetworkModel>(
stream: blocKegiatanTerdekat.kegiatanTerdekatStream,
builder: (context, snapshot) {
if (snapshot.hasData) {
switch (snapshot.data.status) {
case Status.loading:
return Container(
height: 130,
child: const Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(
greenPrimary),
),
),
);
child: const Center(
child: LinearProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(
greenPrimary),
)));
break;
case Status.completed:
final places = snapshot.data.data.listLokasi;
return _buildLokasiWidget(places);
final kegiatanTerdekat = snapshot.data.data;
return _buildKegiatanTerdekatWidget(
kegiatanTerdekat);
break;
case Status.error:
return Container(
height: 130,
child: const Center(
child: Text('Gagal untuk mendapatkan tempat'),
),
);
child: const Center(
child: Text(
'Tidak ada kegiatan dalam waktu dekat',
style: TextStyle(
color: greenPrimary,
fontSize: 16,
fontFamily: 'Muli',
)),
));
break;
}
return Container();
}
return Container();
}),
],
}))), // Container info kegiatan
Container(
height: 285,
alignment: Alignment.bottomCenter,
decoration: const BoxDecoration(
color: white,
borderRadius: BorderRadius.all(
Radius.circular(10.0),
),
),
]
)
),
padding: const EdgeInsets.symmetric(
horizontal: doubleSpace, vertical: doubleSpace),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
InkWell(
key: const Key('Navigate to Pencarian'),
onTap: () => _navigateToPencarianPage(context),
child: Container(
key: const Key('Container Text Field'),
padding: EdgeInsets.zero,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: regularBorderRadius,
border: Border.all(color: greenPrimary),
boxShadow: regularShadow),
child: TextFormField(
enabled: false,
key: const Key('Text Field Mau Kemana'),
decoration: const InputDecoration(
prefixIcon: Icon(
Icons.search,
color: greenPrimary,
size: 25,
),
border: InputBorder.none,
fillColor: Colors.white,
labelText: 'Tekan untuk mencari tempat',
labelStyle: TextStyle(
color: greenPrimary,
fontSize: 20,
fontFamily: 'Muli',
fontWeight: FontWeight.w700),
),
),
),
),
const SizedBox(height: doubleSpace),
const Text(
'Paling sering dicari',
style: TextStyle(
color: Colors.black,
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 10),
StreamBuilder<NetworkModel<LokasiListResponse>>(
stream: bloc.lokasiListStream,
builder: (context, snapshot) {
if (snapshot.hasData) {
switch (snapshot.data.status) {
case Status.loading:
return Container(
height: 130,
child: const Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(
greenPrimary),
),
),
);
break;
case Status.completed:
final places = snapshot.data.data.listLokasi;
return _buildLokasiWidget(places);
break;
case Status.error:
return Container(
height: 130,
child: const Center(
child: Text('Gagal untuk mendapatkan tempat'),
),
);
break;
}
return Container();
}
return Container();
}),
],
),
),
])
],
),
// floatingActionButton: FloatingActionButton.extended(
......@@ -281,9 +276,7 @@ class DashboardState extends State<Dashboard> {
}
Widget _buildKegiatanTerdekatWidget(KegiatanModel kegiatanModel) {
return Container(
child: KegiatanTerdekatButton(kegiatan:kegiatanModel)
);
return Container(child: KegiatanTerdekatButton(kegiatan: kegiatanModel));
}
Widget _buildGoogleMap(BuildContext context) {
......@@ -328,7 +321,8 @@ class DashboardState extends State<Dashboard> {
'name',
],
);
return details.result.name;
final result = details.result;
return result == null ? 'INVALID' : result.name;
}
void _navigateToDetailFasilitasPage(
......@@ -361,6 +355,36 @@ class DashboardState extends State<Dashboard> {
await Navigator.of(context).push(fasilitasRoute);
}
void _navigateToDetailKegiatanPage(
BuildContext context, String placeId, int fasilitasId) async {
final fetches = await Future.wait([
KegiatanRepository().fetchDetailKegiatan(placeId, fasilitasId),
getLokasiName(placeId),
]);
final KegiatanModel kegiatan = fetches[0];
final String namaLokasi = fetches[1] ?? 'INVALID';
final lokasi = Lokasi()
..placeId = placeId
..name = namaLokasi;
final fasilitasRoute = MaterialPageRoute(
builder: (BuildContext context) => DetailPostKegiatanPage(
lokasi: lokasi,
kegiatan: KegiatanModel(
id: kegiatan.id,
placeId: lokasi.placeId,
creator: kegiatan.creator,
namaKegiatan: kegiatan.namaKegiatan,
penyelenggara: kegiatan.penyelenggara,
narahubung: kegiatan.narahubung,
deskripsi: kegiatan.deskripsi,
timeStart: kegiatan.timeStart,
timeEnd: kegiatan.timeEnd,
image: kegiatan.image,
),
));
await Navigator.of(context).push(fasilitasRoute);
}
void initDynamicLinks() async {
final data = await FirebaseDynamicLinks.instance.getInitialLink();
......@@ -385,7 +409,7 @@ class DashboardState extends State<Dashboard> {
if (type == 'fasilitas') {
_navigateToDetailFasilitasPage(context, placeId, id);
} else if (type == 'kegiatan') {
// TODO(:ariqbasyar) navigate kegiatan
_navigateToDetailKegiatanPage(context, placeId, id);
}
}
}
......
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,