change the main list to row

This commit is contained in:
kicap 2024-07-27 20:06:56 +08:00
parent 1607b6eb00
commit fb63a2b177
20 changed files with 15114 additions and 225 deletions

3
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"cmake.configureOnOpen": false
}

14378
assets/dataset1.json Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,4 @@
import 'package:kamus_kesehatan/ui/views/user_tracking_index/list_detail_istilah/list_detail_istilah_view.dart';
import 'package:stacked_services/stacked_services.dart'; import 'package:stacked_services/stacked_services.dart';
import 'package:stacked/stacked_annotations.dart'; import 'package:stacked/stacked_annotations.dart';
@ -9,7 +10,8 @@ import '../services/other_function.dart';
import '../ui/views/action_dialog/action_dialog_view.dart'; import '../ui/views/action_dialog/action_dialog_view.dart';
import '../ui/views/nomor_telpon_dialog/nomor_telpon_dialog_view.dart'; import '../ui/views/nomor_telpon_dialog/nomor_telpon_dialog_view.dart';
import '../ui/views/splash_screen/splash_screen_view.dart'; import '../ui/views/splash_screen/splash_screen_view.dart';
import '../ui/views/user_tracking_index/list_kamus_kesehatan/list_kamus_kesehatan_view.dart'; import '../ui/views/user_tracking_index/halaman_utama/halaman_utama_view.dart';
// import '../ui/views/user_tracking_index/list_kamus_kesehatan/list_kamus_kesehatan_view.dart';
import '../ui/views/user_tracking_index/profil_user/profil_user_view.dart'; import '../ui/views/user_tracking_index/profil_user/profil_user_view.dart';
import '../ui/views/user_tracking_index/user_tracking_index_view.dart'; import '../ui/views/user_tracking_index/user_tracking_index_view.dart';
@ -19,11 +21,12 @@ import '../ui/views/user_tracking_index/user_tracking_index_view.dart';
MaterialRoute( MaterialRoute(
page: UserTrackingIndexView, page: UserTrackingIndexView,
children: [ children: [
MaterialRoute(page: ListKamusKesehatanView), MaterialRoute(page: HalamanUtamaView),
// MaterialRoute(page: TampilkanListView), // MaterialRoute(page: TampilkanListView),
MaterialRoute(page: ProfilUserView), MaterialRoute(page: ProfilUserView),
], ],
), ),
MaterialRoute(page: ListDetailIstilahView),
], ],
dialogs: [ dialogs: [
StackedDialog(classType: ActionDialogView), StackedDialog(classType: ActionDialogView),

View File

@ -6,7 +6,6 @@
import 'package:stacked_services/stacked_services.dart'; import 'package:stacked_services/stacked_services.dart';
import '../model/istilah_model.dart';
import 'app.locator.dart'; import 'app.locator.dart';
import '../ui/views/action_dialog/action_dialog_view.dart'; import '../ui/views/action_dialog/action_dialog_view.dart';
import '../ui/views/nomor_telpon_dialog/nomor_telpon_dialog_view.dart'; import '../ui/views/nomor_telpon_dialog/nomor_telpon_dialog_view.dart';
@ -21,9 +20,7 @@ void setupDialogUi() {
final Map<DialogType, DialogBuilder> builders = { final Map<DialogType, DialogBuilder> builders = {
DialogType.actionDialogView: (context, request, completer) => DialogType.actionDialogView: (context, request, completer) =>
ActionDialogView( ActionDialogView(request: request, completer: completer),
request: request as DialogRequest<IstilahModel>,
completer: completer),
DialogType.nomorTelponDialogView: (context, request, completer) => DialogType.nomorTelponDialogView: (context, request, completer) =>
NomorTelponDialogView(request: request, completer: completer), NomorTelponDialogView(request: request, completer: completer),
}; };

View File

@ -5,27 +5,32 @@
// ************************************************************************** // **************************************************************************
// ignore_for_file: no_leading_underscores_for_library_prefixes // ignore_for_file: no_leading_underscores_for_library_prefixes
import 'package:flutter/material.dart' as _i4; import 'package:flutter/material.dart' as _i5;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:kamus_kesehatan/ui/views/splash_screen/splash_screen_view.dart' import 'package:kamus_kesehatan/ui/views/splash_screen/splash_screen_view.dart'
as _i2; as _i2;
import 'package:kamus_kesehatan/ui/views/user_tracking_index/list_kamus_kesehatan/list_kamus_kesehatan_view.dart' import 'package:kamus_kesehatan/ui/views/user_tracking_index/halaman_utama/halaman_utama_view.dart'
as _i5;
import 'package:kamus_kesehatan/ui/views/user_tracking_index/profil_user/profil_user_view.dart'
as _i6; as _i6;
import 'package:kamus_kesehatan/ui/views/user_tracking_index/list_detail_istilah/list_detail_istilah_view.dart'
as _i4;
import 'package:kamus_kesehatan/ui/views/user_tracking_index/profil_user/profil_user_view.dart'
as _i7;
import 'package:kamus_kesehatan/ui/views/user_tracking_index/user_tracking_index_view.dart' import 'package:kamus_kesehatan/ui/views/user_tracking_index/user_tracking_index_view.dart'
as _i3; as _i3;
import 'package:stacked/stacked.dart' as _i1; import 'package:stacked/stacked.dart' as _i1;
import 'package:stacked_services/stacked_services.dart' as _i7; import 'package:stacked_services/stacked_services.dart' as _i8;
class Routes { class Routes {
static const splashScreenView = '/'; static const splashScreenView = '/';
static const userTrackingIndexView = '/user-tracking-index-view'; static const userTrackingIndexView = '/user-tracking-index-view';
static const listDetailIstilahView = '/list-detail-istilah-view';
static const all = <String>{ static const all = <String>{
splashScreenView, splashScreenView,
userTrackingIndexView, userTrackingIndexView,
listDetailIstilahView,
}; };
} }
@ -39,21 +44,33 @@ class StackedRouter extends _i1.RouterBase {
Routes.userTrackingIndexView, Routes.userTrackingIndexView,
page: _i3.UserTrackingIndexView, page: _i3.UserTrackingIndexView,
), ),
_i1.RouteDef(
Routes.listDetailIstilahView,
page: _i4.ListDetailIstilahView,
),
]; ];
final _pagesMap = <Type, _i1.StackedRouteFactory>{ final _pagesMap = <Type, _i1.StackedRouteFactory>{
_i2.SplashScreenView: (data) { _i2.SplashScreenView: (data) {
return _i4.MaterialPageRoute<dynamic>( return _i5.MaterialPageRoute<dynamic>(
builder: (context) => const _i2.SplashScreenView(), builder: (context) => const _i2.SplashScreenView(),
settings: data, settings: data,
); );
}, },
_i3.UserTrackingIndexView: (data) { _i3.UserTrackingIndexView: (data) {
return _i4.MaterialPageRoute<dynamic>( return _i5.MaterialPageRoute<dynamic>(
builder: (context) => const _i3.UserTrackingIndexView(), builder: (context) => const _i3.UserTrackingIndexView(),
settings: data, settings: data,
); );
}, },
_i4.ListDetailIstilahView: (data) {
final args = data.getArgs<ListDetailIstilahViewArguments>(nullOk: false);
return _i5.MaterialPageRoute<dynamic>(
builder: (context) =>
_i4.ListDetailIstilahView(key: args.key, kategori: args.kategori),
settings: data,
);
},
}; };
@override @override
@ -63,13 +80,40 @@ class StackedRouter extends _i1.RouterBase {
Map<Type, _i1.StackedRouteFactory> get pagesMap => _pagesMap; Map<Type, _i1.StackedRouteFactory> get pagesMap => _pagesMap;
} }
class ListDetailIstilahViewArguments {
const ListDetailIstilahViewArguments({
this.key,
required this.kategori,
});
final _i5.Key? key;
final String kategori;
@override
String toString() {
return '{"key": "$key", "kategori": "$kategori"}';
}
@override
bool operator ==(covariant ListDetailIstilahViewArguments other) {
if (identical(this, other)) return true;
return other.key == key && other.kategori == kategori;
}
@override
int get hashCode {
return key.hashCode ^ kategori.hashCode;
}
}
class UserTrackingIndexViewRoutes { class UserTrackingIndexViewRoutes {
static const listKamusKesehatanView = 'list-kamus-kesehatan-view'; static const halamanUtamaView = 'halaman-utama-view';
static const profilUserView = 'profil-user-view'; static const profilUserView = 'profil-user-view';
static const all = <String>{ static const all = <String>{
listKamusKesehatanView, halamanUtamaView,
profilUserView, profilUserView,
}; };
} }
@ -77,25 +121,25 @@ class UserTrackingIndexViewRoutes {
class UserTrackingIndexViewRouter extends _i1.RouterBase { class UserTrackingIndexViewRouter extends _i1.RouterBase {
final _routes = <_i1.RouteDef>[ final _routes = <_i1.RouteDef>[
_i1.RouteDef( _i1.RouteDef(
UserTrackingIndexViewRoutes.listKamusKesehatanView, UserTrackingIndexViewRoutes.halamanUtamaView,
page: _i5.ListKamusKesehatanView, page: _i6.HalamanUtamaView,
), ),
_i1.RouteDef( _i1.RouteDef(
UserTrackingIndexViewRoutes.profilUserView, UserTrackingIndexViewRoutes.profilUserView,
page: _i6.ProfilUserView, page: _i7.ProfilUserView,
), ),
]; ];
final _pagesMap = <Type, _i1.StackedRouteFactory>{ final _pagesMap = <Type, _i1.StackedRouteFactory>{
_i5.ListKamusKesehatanView: (data) { _i6.HalamanUtamaView: (data) {
return _i4.MaterialPageRoute<dynamic>( return _i5.MaterialPageRoute<dynamic>(
builder: (context) => const _i5.ListKamusKesehatanView(), builder: (context) => const _i6.HalamanUtamaView(),
settings: data, settings: data,
); );
}, },
_i6.ProfilUserView: (data) { _i7.ProfilUserView: (data) {
return _i4.MaterialPageRoute<dynamic>( return _i5.MaterialPageRoute<dynamic>(
builder: (context) => const _i6.ProfilUserView(), builder: (context) => const _i7.ProfilUserView(),
settings: data, settings: data,
); );
}, },
@ -108,7 +152,7 @@ class UserTrackingIndexViewRouter extends _i1.RouterBase {
Map<Type, _i1.StackedRouteFactory> get pagesMap => _pagesMap; Map<Type, _i1.StackedRouteFactory> get pagesMap => _pagesMap;
} }
extension NavigatorStateExtension on _i7.NavigationService { extension NavigatorStateExtension on _i8.NavigationService {
Future<dynamic> navigateToSplashScreenView([ Future<dynamic> navigateToSplashScreenView([
int? routerId, int? routerId,
bool preventDuplicates = true, bool preventDuplicates = true,
@ -137,16 +181,32 @@ extension NavigatorStateExtension on _i7.NavigationService {
transition: transition); transition: transition);
} }
Future<dynamic> navigateToListDetailIstilahView({
_i5.Key? key,
required String kategori,
int? routerId,
bool preventDuplicates = true,
Map<String, String>? parameters,
Widget Function(BuildContext, Animation<double>, Animation<double>, Widget)?
transition,
}) async {
return navigateTo<dynamic>(Routes.listDetailIstilahView,
arguments: ListDetailIstilahViewArguments(key: key, kategori: kategori),
id: routerId,
preventDuplicates: preventDuplicates,
parameters: parameters,
transition: transition);
}
Future<dynamic> Future<dynamic>
navigateToNestedListKamusKesehatanViewInUserTrackingIndexViewRouter([ navigateToNestedHalamanUtamaViewInUserTrackingIndexViewRouter([
int? routerId, int? routerId,
bool preventDuplicates = true, bool preventDuplicates = true,
Map<String, String>? parameters, Map<String, String>? parameters,
Widget Function(BuildContext, Animation<double>, Animation<double>, Widget)? Widget Function(BuildContext, Animation<double>, Animation<double>, Widget)?
transition, transition,
]) async { ]) async {
return navigateTo<dynamic>( return navigateTo<dynamic>(UserTrackingIndexViewRoutes.halamanUtamaView,
UserTrackingIndexViewRoutes.listKamusKesehatanView,
id: routerId, id: routerId,
preventDuplicates: preventDuplicates, preventDuplicates: preventDuplicates,
parameters: parameters, parameters: parameters,
@ -195,16 +255,32 @@ extension NavigatorStateExtension on _i7.NavigationService {
transition: transition); transition: transition);
} }
Future<dynamic> replaceWithListDetailIstilahView({
_i5.Key? key,
required String kategori,
int? routerId,
bool preventDuplicates = true,
Map<String, String>? parameters,
Widget Function(BuildContext, Animation<double>, Animation<double>, Widget)?
transition,
}) async {
return replaceWith<dynamic>(Routes.listDetailIstilahView,
arguments: ListDetailIstilahViewArguments(key: key, kategori: kategori),
id: routerId,
preventDuplicates: preventDuplicates,
parameters: parameters,
transition: transition);
}
Future<dynamic> Future<dynamic>
replaceWithNestedListKamusKesehatanViewInUserTrackingIndexViewRouter([ replaceWithNestedHalamanUtamaViewInUserTrackingIndexViewRouter([
int? routerId, int? routerId,
bool preventDuplicates = true, bool preventDuplicates = true,
Map<String, String>? parameters, Map<String, String>? parameters,
Widget Function(BuildContext, Animation<double>, Animation<double>, Widget)? Widget Function(BuildContext, Animation<double>, Animation<double>, Widget)?
transition, transition,
]) async { ]) async {
return replaceWith<dynamic>( return replaceWith<dynamic>(UserTrackingIndexViewRoutes.halamanUtamaView,
UserTrackingIndexViewRoutes.listKamusKesehatanView,
id: routerId, id: routerId,
preventDuplicates: preventDuplicates, preventDuplicates: preventDuplicates,
parameters: parameters, parameters: parameters,

View File

@ -0,0 +1,21 @@
class IstilahModel1 {
String? istilah;
String? arti;
String? kategori;
IstilahModel1({this.istilah, this.arti});
IstilahModel1.fromJson(Map<String, dynamic> json) {
istilah = json['ISTILAH KESEHATAN'];
arti = json['PENGERTIAN'];
kategori = json['KATEGORI'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['ISTILAH KESEHATAN'] = istilah;
data['PENGERTIAN'] = arti;
data['KATEGORI'] = kategori;
return data;
}
}

View File

@ -13,4 +13,6 @@ class MyFunction {
input = input.replaceAll('| ', '\n'); input = input.replaceAll('| ', '\n');
return input; return input;
} }
String capitalize(String s) => s[0].toUpperCase() + s.substring(1);
} }

View File

@ -1,19 +1,20 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:kamus_kesehatan/model/istilah_model.dart';
import 'package:stacked/stacked.dart'; import 'package:stacked/stacked.dart';
import 'package:stacked_services/stacked_services.dart'; import 'package:stacked_services/stacked_services.dart';
import '../../../model/istilah_model1.dart';
import './action_dialog_view_model.dart'; import './action_dialog_view_model.dart';
class ActionDialogView extends StatelessWidget { class ActionDialogView extends StatelessWidget {
final DialogRequest<IstilahModel> request; final DialogRequest<IstilahModel1> request;
final Function(DialogResponse) completer; final Function(DialogResponse) completer;
const ActionDialogView({ const ActionDialogView({
Key? key, Key? key,
required this.request, required DialogRequest request,
required this.completer, required this.completer,
}) : super(key: key); }) : request = request as DialogRequest<IstilahModel1>,
super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View File

@ -2,15 +2,15 @@ import '../../../app/app.dialogs.dart';
import '../../../app/app.locator.dart'; import '../../../app/app.locator.dart';
import '../../../app/app.logger.dart'; import '../../../app/app.logger.dart';
import '../../../app/core/custom_base_view_model.dart'; import '../../../app/core/custom_base_view_model.dart';
import '../../../model/istilah_model.dart'; import '../../../model/istilah_model1.dart';
import '../../../services/my_storage.dart'; import '../../../services/my_storage.dart';
class ActionDialogViewModel extends CustomBaseViewModel { class ActionDialogViewModel extends CustomBaseViewModel {
final log = getLogger('ActionDialogViewModel'); final log = getLogger('ActionDialogViewModel');
final myStorage = locator<MyStorage>(); final myStorage = locator<MyStorage>();
IstilahModel? data; IstilahModel1? data;
Future<void> init(IstilahModel? data) async { Future<void> init(IstilahModel1? data) async {
// log.i('init'); // log.i('init');
// log.i(data!.istilah.toString()); // log.i(data!.istilah.toString());
// log.i(data.arti.toString()); // log.i(data.arti.toString());
@ -18,7 +18,7 @@ class ActionDialogViewModel extends CustomBaseViewModel {
// await myStorage.clear(); // await myStorage.clear();
} }
addBookmark(IstilahModel istilahModel) async { addBookmark(IstilahModel1 istilahModel) async {
List<dynamic>? listBookmark; List<dynamic>? listBookmark;
listBookmark = await myStorage.read('listBookmark'); listBookmark = await myStorage.read('listBookmark');

View File

@ -4,16 +4,23 @@ import 'package:url_launcher/url_launcher.dart';
import '../../../app/app.logger.dart'; import '../../../app/app.logger.dart';
import '../../../app/core/custom_base_view_model.dart'; import '../../../app/core/custom_base_view_model.dart';
import '../../../model/istilah_model.dart'; import '../../../model/istilah_model.dart';
import '../../../model/istilah_model1.dart';
class NomorTelponDialogViewModel extends CustomBaseViewModel { class NomorTelponDialogViewModel extends CustomBaseViewModel {
final log = getLogger('NomorTelponDialogViewModel'); final log = getLogger('NomorTelponDialogViewModel');
TextEditingController nomorTelponController = TextEditingController(); TextEditingController nomorTelponController = TextEditingController();
final formKey = GlobalKey<FormState>(); final formKey = GlobalKey<FormState>();
IstilahModel? data; IstilahModel? data;
Future<void> init(IstilahModel data) async { Future<void> init(dynamic data) async {
log.i('init'); log.i(data);
log.i(data.istilah.toString()); if (data is IstilahModel1) {
log.i(data.arti.toString()); log.i("data is IstilahModel1");
// change data to IstilahModel
data = IstilahModel(
istilah: data.istilah,
arti: data.arti,
);
}
this.data = data; this.data = data;
// await myStorage.clear(); // await myStorage.clear();
} }

View File

@ -0,0 +1,107 @@
import 'package:flutter/material.dart';
import 'package:kamus_kesehatan/app/themes/app_text.dart';
import 'package:stacked/stacked.dart';
import '../list_detail_istilah/list_detail_istilah_view.dart';
import './halaman_utama_view_model.dart';
class HalamanUtamaView extends StatelessWidget {
const HalamanUtamaView({super.key});
@override
Widget build(BuildContext context) {
return ViewModelBuilder<HalamanUtamaViewModel>.reactive(
viewModelBuilder: () => HalamanUtamaViewModel(),
onViewModelReady: (HalamanUtamaViewModel model) async {
await model.init();
},
builder: (
BuildContext context,
HalamanUtamaViewModel model,
Widget? child,
) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(20),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
for (var element in model.kategoriIstilah)
Padding(
padding: const EdgeInsets.only(bottom: 20),
child: GestureDetector(
onTap: () {
model.navigationService
.navigateToView(ListDetailIstilahView(
kategori: element['kategori'],
));
},
child: Container(
padding: const EdgeInsets.all(10),
width: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: element['color'],
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
element['icon'],
const SizedBox(height: 10),
Text(
model.myFunction
.capitalize(element['kategori']),
style: boldTextStyle.copyWith(
color: Colors.white,
fontSize: 15,
),
),
const SizedBox(height: 10),
if (element['kategori'] == 'anggota tubuh')
ForCount(
count: model.anggotaTubuhCount.toString()),
if (element['kategori'] == 'penyakit')
ForCount(count: model.penyakitCount.toString()),
if (element['kategori'] == 'obat')
ForCount(count: model.obatCount.toString()),
if (element['kategori'] == 'alat')
ForCount(count: model.alatCount.toString()),
if (element['kategori'] == 'umum')
ForCount(count: model.umumCount.toString()),
if (element['kategori'] == 'hormon')
ForCount(count: model.hormonCount.toString()),
],
),
),
),
),
],
),
),
),
);
},
);
}
}
class ForCount extends StatelessWidget {
const ForCount({
super.key,
required this.count,
});
final String count;
@override
Widget build(BuildContext context) {
return Text(
count,
style: boldTextStyle.copyWith(
color: Colors.white,
fontSize: 13,
),
);
}
}

View File

@ -0,0 +1,83 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../../../../app/app.logger.dart';
import '../../../../app/core/custom_base_view_model.dart';
import '../../../../model/istilah_model1.dart';
class HalamanUtamaViewModel extends CustomBaseViewModel {
final log = getLogger('HalamanUtamaViewModel');
List<IstilahModel1> listIstilah = [];
List<Map<String, dynamic>> kategoriIstilah = [];
int penyakitCount = 0;
int anggotaTubuhCount = 0;
int obatCount = 0;
int alatCount = 0;
int umumCount = 0;
int hormonCount = 0;
Future<void> init() async {
setBusy(true);
listIstilah = await rootBundle.loadString('assets/dataset1.json').then(
(String data) {
final List<dynamic> jsonData = json.decode(data);
return jsonData.map((dynamic item) {
return IstilahModel1.fromJson(item as Map<String, dynamic>);
}).toList();
},
);
log.i(listIstilah.length);
for (var element in listIstilah) {
Icon? icon;
Color? color;
switch (element.kategori) {
case 'penyakit':
icon = const Icon(Icons.health_and_safety, color: Colors.white);
color = Colors.red;
penyakitCount++;
break;
case 'anggota tubuh':
icon = const Icon(Icons.heart_broken, color: Colors.white);
color = Colors.red;
anggotaTubuhCount++;
break;
case 'obat':
icon = const Icon(Icons.medication_liquid, color: Colors.white);
color = Colors.blue;
obatCount++;
break;
case 'alat':
icon = const Icon(Icons.medical_information, color: Colors.white);
color = Colors.blue;
alatCount++;
case 'umum':
icon = const Icon(Icons.medical_information, color: Colors.white);
color = Colors.blue;
umumCount++;
case 'hormon':
icon = const Icon(Icons.medical_information, color: Colors.white);
color = Colors.blue;
hormonCount++;
default:
break;
}
// add to kategoriIstilah and if the kategori is not in the list, add it
if (!kategoriIstilah.any((k) => k['kategori'] == element.kategori)) {
kategoriIstilah.add({
'icon': icon,
'color': color,
'kategori': element.kategori,
});
}
// add count to the kategoriIstilah
}
kategoriIstilah.sort((a, b) => a['kategori'].compareTo(b['kategori']));
setBusy(false);
}
}

View File

@ -0,0 +1,99 @@
import 'package:flutter/material.dart';
import 'package:stacked/stacked.dart';
import '../../../../app/themes/app_colors.dart';
import '../../../../app/themes/app_text.dart';
import '../../../widgets/my_textformfield.dart';
import './list_detail_istilah_view_model.dart';
class ListDetailIstilahView extends StatelessWidget {
const ListDetailIstilahView({super.key, required this.kategori});
final String kategori;
@override
Widget build(BuildContext context) {
return ViewModelBuilder<ListDetailIstilahViewModel>.reactive(
viewModelBuilder: () => ListDetailIstilahViewModel(),
onViewModelReady: (ListDetailIstilahViewModel model) async {
await model.init(kategori);
},
builder: (
BuildContext context,
ListDetailIstilahViewModel model,
Widget? child,
) {
return Scaffold(
appBar: AppBar(
backgroundColor: mainColor,
title: Text(
'List ${model.myFunction.capitalize(kategori)}',
),
),
body: Padding(
padding: const EdgeInsets.all(25),
child: Column(
children: [
MyTextFormField(
hintText: 'Cari istilah',
labelText: 'Cari istilah',
controller: model.searchController,
suffixIcon: const Icon(Icons.search),
onChanged: (String value) {
model.searchIstilah();
},
),
const SizedBox(
height: 20,
),
Expanded(
child: model.listIstilah.isEmpty
? const Center(
child: CircularProgressIndicator(),
)
: ListView.builder(
itemCount: model.listIstilah.length,
itemBuilder: (
BuildContext context,
int index,
) {
return Card(
child: ListTile(
title: Text(
model.listIstilah[index].istilah!
.toUpperCase(),
style: boldTextStyle,
),
subtitle: Text(model.listIstilah[index].arti!),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
GestureDetector(
onTap: () {
model
.cekSuara(model.listIstilah[index]);
},
child: const Icon(Icons.volume_up),
),
IconButton(
onPressed: () {
model.bukaDialogAksi(
model.listIstilah[index]);
},
icon: const Icon(Icons.info),
),
],
),
),
);
},
),
),
],
),
),
);
},
);
}
}

View File

@ -0,0 +1,72 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../../../../app/app.dialogs.dart';
import '../../../../app/app.locator.dart';
import '../../../../app/app.logger.dart';
import '../../../../app/core/custom_base_view_model.dart';
import '../../../../model/istilah_model1.dart';
import '../../../../services/my_tts.dart';
class ListDetailIstilahViewModel extends CustomBaseViewModel {
final log = getLogger('ListDetailIstilahViewModel');
final myTts = locator<MyTts>();
TextEditingController searchController = TextEditingController();
List<IstilahModel1> listIstilah = [];
List<IstilahModel1> allListIstilah = [];
Future<void> init(String kategori) async {
// await myTts.init();
// myTts.getVoices();
var data = await rootBundle.loadString('assets/dataset1.json');
final List<dynamic> jsonData = json.decode(data);
listIstilah = jsonData
.map((dynamic item) =>
IstilahModel1.fromJson(item as Map<String, dynamic>))
.where((IstilahModel1 istilah) => istilah.kategori == kategori)
.toList();
allListIstilah = listIstilah;
notifyListeners();
}
cekSuara(IstilahModel1 listIstilah) {
myTts.stop();
// speak the listIstilah.istilah and wait 2 seconds then speak the listIstilah.arti
myTts.speak(listIstilah.istilah!);
Future.delayed(const Duration(seconds: 2), () {
myTts.speak(listIstilah.arti!);
});
}
searchIstilah() {
if (searchController.text.isEmpty) {
listIstilah = allListIstilah;
} else {
listIstilah = allListIstilah
.where((IstilahModel1 istilah) => istilah.istilah!
.toLowerCase()
.contains(searchController.text.toLowerCase()))
.toList();
}
notifyListeners();
}
bukaDialogAksi(IstilahModel1 listIstilah) async {
var res = await dialogService.showCustomDialog(
variant: DialogType.actionDialogView,
title: 'Form Aksi',
data: listIstilah,
barrierDismissible: true,
);
if (res!.confirmed) {
log.i('confirmed');
// do something
}
}
}

View File

@ -20,7 +20,9 @@ class ListKamusKesehatanView extends StatelessWidget {
ListKamusKesehatanViewModel model, ListKamusKesehatanViewModel model,
Widget? child, Widget? child,
) { ) {
return Padding( return WillPopScope(
onWillPop: () async => false,
child: Padding(
padding: const EdgeInsets.all(25), padding: const EdgeInsets.all(25),
child: Column( child: Column(
children: [ children: [
@ -50,7 +52,8 @@ class ListKamusKesehatanView extends StatelessWidget {
return Card( return Card(
child: ListTile( child: ListTile(
title: Text( title: Text(
model.listIstilah[index].istilah!.toUpperCase(), model.listIstilah[index].istilah!
.toUpperCase(),
style: boldTextStyle, style: boldTextStyle,
), ),
subtitle: Text(model.listIstilah[index].arti!), subtitle: Text(model.listIstilah[index].arti!),
@ -59,7 +62,8 @@ class ListKamusKesehatanView extends StatelessWidget {
children: [ children: [
GestureDetector( GestureDetector(
onTap: () { onTap: () {
model.cekSuara(model.listIstilah[index]); model
.cekSuara(model.listIstilah[index]);
}, },
child: const Icon(Icons.volume_up), child: const Icon(Icons.volume_up),
), ),
@ -79,6 +83,7 @@ class ListKamusKesehatanView extends StatelessWidget {
), ),
], ],
), ),
),
); );
}, },
); );

View File

@ -20,7 +20,9 @@ class ProfilUserView extends StatelessWidget {
ProfilUserViewModel model, ProfilUserViewModel model,
Widget? child, Widget? child,
) { ) {
return Padding( return WillPopScope(
onWillPop: () async => false,
child: Padding(
padding: const EdgeInsets.all(25), padding: const EdgeInsets.all(25),
child: Column( child: Column(
children: [ children: [
@ -53,8 +55,8 @@ class ProfilUserView extends StatelessWidget {
) { ) {
return Card( return Card(
child: ListTile( child: ListTile(
onTap: () => onTap: () => model
model.cekSuara(model.listIstilah![index]), .cekSuara(model.listIstilah![index]),
title: Text( title: Text(
model.listIstilah![index].istilah! model.listIstilah![index].istilah!
.toUpperCase(), .toUpperCase(),
@ -68,6 +70,9 @@ class ProfilUserView extends StatelessWidget {
GestureDetector( GestureDetector(
onTap: () { onTap: () {
// model.cekSuara(model.listIstilah[index]); // model.cekSuara(model.listIstilah[index]);
model.openWhatsapp(
model.listIstilah![index],
);
}, },
child: const Icon(Icons.phone), child: const Icon(Icons.phone),
), ),
@ -75,8 +80,12 @@ class ProfilUserView extends StatelessWidget {
onPressed: () { onPressed: () {
// model.bukaDialogAksi( // model.bukaDialogAksi(
// model.listIstilah[index]); // model.listIstilah[index]);
model.deleteBookmark(
model.listIstilah![index],
);
}, },
icon: const Icon(Icons.delete_forever), icon:
const Icon(Icons.delete_forever),
), ),
], ],
), ),
@ -87,6 +96,7 @@ class ProfilUserView extends StatelessWidget {
), ),
], ],
), ),
),
); );
// return const Scaffold( // return const Scaffold(
// body: Padding( // body: Padding(

View File

@ -1,5 +1,6 @@
import 'package:kamus_kesehatan/model/istilah_model.dart'; import 'package:kamus_kesehatan/model/istilah_model.dart';
import '../../../../app/app.dialogs.dart';
import '../../../../app/app.locator.dart'; import '../../../../app/app.locator.dart';
import '../../../../app/app.logger.dart'; import '../../../../app/app.logger.dart';
import '../../../../app/core/custom_base_view_model.dart'; import '../../../../app/core/custom_base_view_model.dart';
@ -41,4 +42,23 @@ class ProfilUserViewModel extends CustomBaseViewModel {
myTts.speak(listIstilah.arti!); myTts.speak(listIstilah.arti!);
}); });
} }
deleteBookmark(IstilahModel listIstilah) async {
List<dynamic> listBookmark = await myStorage.read('listBookmark');
log.i('ini listBookmark $listBookmark');
listBookmark.removeWhere(
(element) => element['istilah'] == listIstilah.istilah,
);
log.i('ini listBookmark $listBookmark');
await myStorage.write('listBookmark', listBookmark);
await init();
notifyListeners();
}
openWhatsapp(IstilahModel data) async {
await dialogService.showCustomDialog(
variant: DialogType.nomorTelponDialogView,
data: data,
);
}
} }

View File

@ -25,6 +25,8 @@ class UserTrackingIndexView extends StatelessWidget {
Widget? child, Widget? child,
) { ) {
return SafeArea( return SafeArea(
child: WillPopScope(
onWillPop: () async => false,
child: Scaffold( child: Scaffold(
appBar: AppBar( appBar: AppBar(
backgroundColor: mainColor, backgroundColor: mainColor,
@ -50,7 +52,7 @@ class UserTrackingIndexView extends StatelessWidget {
body: ExtendedNavigator( body: ExtendedNavigator(
router: UserTrackingIndexViewRouter(), router: UserTrackingIndexViewRouter(),
navigatorKey: StackedService.nestedNavigationKey(2), navigatorKey: StackedService.nestedNavigationKey(2),
initialRoute: UserTrackingIndexViewRoutes.listKamusKesehatanView, initialRoute: UserTrackingIndexViewRoutes.halamanUtamaView,
), ),
bottomNavigationBar: StylishBottomBar( bottomNavigationBar: StylishBottomBar(
items: [ items: [
@ -87,6 +89,7 @@ class UserTrackingIndexView extends StatelessWidget {
// fabLocation: StylishBarFabLocation.center, // fabLocation: StylishBarFabLocation.center,
), ),
), ),
),
); );
}, },
); );

View File

@ -32,7 +32,8 @@ class UserTrackingIndexViewModel extends IndexTrackingViewModel {
final List<String> _views = [ final List<String> _views = [
// UserTrackingIndexViewRoutes.tampilkanListView, // UserTrackingIndexViewRoutes.tampilkanListView,
UserTrackingIndexViewRoutes.listKamusKesehatanView, // UserTrackingIndexViewRoutes.listKamusKesehatanView,
UserTrackingIndexViewRoutes.halamanUtamaView,
UserTrackingIndexViewRoutes.profilUserView, UserTrackingIndexViewRoutes.profilUserView,
]; ];

View File

@ -82,6 +82,7 @@ flutter:
assets: assets:
- assets/logo.png - assets/logo.png
- assets/dataset.json - assets/dataset.json
- assets/dataset1.json
# - images/a_dot_burr.jpeg # - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg # - images/a_dot_ham.jpeg