first commit

This commit is contained in:
kicap
2024-02-04 20:57:23 +08:00
commit 27c529dad9
162 changed files with 8557 additions and 0 deletions

View File

@ -0,0 +1,86 @@
import 'package:flutter/material.dart';
import 'package:kamus_kesehatan/app/themes/app_text.dart';
import 'package:kamus_kesehatan/ui/widgets/my_textformfield.dart';
import 'package:stacked/stacked.dart';
import './list_kamus_kesehatan_view_model.dart';
class ListKamusKesehatanView extends StatelessWidget {
const ListKamusKesehatanView({super.key});
@override
Widget build(BuildContext context) {
return ViewModelBuilder<ListKamusKesehatanViewModel>.reactive(
viewModelBuilder: () => ListKamusKesehatanViewModel(),
onViewModelReady: (ListKamusKesehatanViewModel model) async {
await model.init();
},
builder: (
BuildContext context,
ListKamusKesehatanViewModel model,
Widget? child,
) {
return 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.dialogs.dart';
import '../../../../app/app.locator.dart';
import '../../../../app/app.logger.dart';
import '../../../../app/core/custom_base_view_model.dart';
import '../../../../model/istilah_model.dart';
import '../../../../services/my_tts.dart';
class ListKamusKesehatanViewModel extends CustomBaseViewModel {
final log = getLogger('ListKamusKesehatanViewModel');
final myTts = locator<MyTts>();
TextEditingController searchController = TextEditingController();
List<IstilahModel> listIstilah = [];
List<IstilahModel> allListIstilah = [];
Future<void> init() async {
// await myTts.init();
// myTts.getVoices();
listIstilah = await rootBundle.loadString('assets/dataset.json').then(
(String data) {
final List<dynamic> jsonData = json.decode(data);
return jsonData.map((dynamic item) {
return IstilahModel.fromJson(item as Map<String, dynamic>);
}).toList();
},
);
allListIstilah = listIstilah;
notifyListeners();
}
cekSuara(IstilahModel 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((IstilahModel istilah) => istilah.istilah!
.toLowerCase()
.contains(searchController.text.toLowerCase()))
.toList();
}
notifyListeners();
}
bukaDialogAksi(IstilahModel listIstilah) async {
var res = await dialogService.showCustomDialog(
variant: DialogType.actionDialogView,
title: 'Form Aksi',
data: listIstilah,
);
if (res!.confirmed) {
log.i('confirmed');
// do something
}
}
}

View File

@ -0,0 +1,171 @@
import 'package:flutter/material.dart';
import 'package:stacked/stacked.dart';
import '../../../../app/themes/app_colors.dart';
import '../../../../app/themes/app_text.dart';
import './profil_user_view_model.dart';
class ProfilUserView extends StatelessWidget {
const ProfilUserView({super.key});
@override
Widget build(BuildContext context) {
return ViewModelBuilder<ProfilUserViewModel>.reactive(
viewModelBuilder: () => ProfilUserViewModel(),
onViewModelReady: (ProfilUserViewModel model) async {
await model.init();
},
builder: (
BuildContext context,
ProfilUserViewModel model,
Widget? child,
) {
return 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 == null
? const Center(
child: CircularProgressIndicator(),
)
: model.listIstilah!.isEmpty
? const Center(
child: Text('Belum ada bookmark'),
)
: ListView.builder(
itemCount: model.listIstilah!.length,
itemBuilder: (
BuildContext context,
int index,
) {
return Card(
child: ListTile(
onTap: () =>
model.cekSuara(model.listIstilah![index]),
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.phone),
),
IconButton(
onPressed: () {
// model.bukaDialogAksi(
// model.listIstilah[index]);
},
icon: const Icon(Icons.delete_forever),
),
],
),
),
);
},
),
),
],
),
);
// return const Scaffold(
// body: Padding(
// padding: EdgeInsets.all(30),
// child: Column(
// mainAxisAlignment: MainAxisAlignment.center,
// crossAxisAlignment: CrossAxisAlignment.start,
// mainAxisSize: MainAxisSize.min,
// children: [
// Center(
// child: CircleAvatar(
// radius: 65,
// backgroundColor: fontParagraphColor,
// child: Icon(
// Icons.person,
// size: 50,
// color: Colors.white,
// ),
// ),
// ),
// SizedBox(height: 20),
// _ChildWidget(
// icon: Icons.person,
// text: 'ini nama developer',
// ),
// SizedBox(height: 20),
// _ChildWidget(
// icon: Icons.list_alt,
// text: 'Kamus Medis Dan Kesehatan',
// ),
// SizedBox(height: 20),
// _ChildWidget(
// // icon multiple person
// icon: Icons.people,
// text: 'Pembimbing 1',
// ),
// SizedBox(height: 20),
// _ChildWidget(
// // icon multiple person
// icon: Icons.people,
// text: 'Pembimbing 2',
// ),
// ],
// ),
// ),
// );
},
);
}
}
// ignore: unused_element
class _ChildWidget extends StatelessWidget {
const _ChildWidget({
required this.icon,
required this.text,
});
final IconData icon;
final String text;
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const SizedBox(width: 30),
Icon(
icon,
size: 30,
color: mainColor,
),
const SizedBox(width: 40),
Text(
text,
style: regularTextStyle,
),
const Expanded(child: SizedBox(width: 30)),
],
);
}
}

View File

@ -0,0 +1,44 @@
import 'package:kamus_kesehatan/model/istilah_model.dart';
import '../../../../app/app.locator.dart';
import '../../../../app/app.logger.dart';
import '../../../../app/core/custom_base_view_model.dart';
import '../../../../services/my_storage.dart';
import '../../../../services/my_tts.dart';
class ProfilUserViewModel extends CustomBaseViewModel {
final log = getLogger('ProfilUserViewModel');
final myTts = locator<MyTts>();
final myStorage = locator<MyStorage>();
List<IstilahModel>? listIstilah;
List<IstilahModel>? allListIstilah;
Future<void> init() async {
List<dynamic>? listBookmark;
listBookmark = await myStorage.read('listBookmark');
listBookmark ??= [];
log.i('ini panjang listBookmark ${listBookmark.length}');
log.i('ini listBookmark $listBookmark');
listIstilah = listBookmark.map((dynamic item) {
return IstilahModel.fromJson(item as Map<String, dynamic>);
}).toList();
allListIstilah = listIstilah;
notifyListeners();
}
cekSuara(IstilahModel 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!);
});
}
}

View File

@ -0,0 +1,94 @@
import 'package:flutter/material.dart';
import 'package:kamus_kesehatan/app/app.router.dart';
import 'package:stacked/stacked.dart';
import 'package:stacked_services/stacked_services.dart';
import 'package:stylish_bottom_bar/model/bar_items.dart';
import 'package:stylish_bottom_bar/stylish_bottom_bar.dart';
import '../../../app/themes/app_colors.dart';
import '../../../app/themes/app_text.dart';
import './user_tracking_index_view_model.dart';
class UserTrackingIndexView extends StatelessWidget {
const UserTrackingIndexView({super.key});
@override
Widget build(BuildContext context) {
return ViewModelBuilder<UserTrackingIndexViewModel>.reactive(
viewModelBuilder: () => UserTrackingIndexViewModel(),
onViewModelReady: (UserTrackingIndexViewModel model) async {
await model.init();
},
builder: (
BuildContext context,
UserTrackingIndexViewModel model,
Widget? child,
) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
backgroundColor: mainColor,
title: Text(
model.header,
style: const TextStyle(
color: fontColor,
fontSize: 20,
),
),
elevation: 0,
automaticallyImplyLeading: false,
actions: [
IconButton(
onPressed: () {
model.exitApp();
},
icon: const Icon(Icons.logout, color: fontColor),
),
],
),
extendBody: false,
body: ExtendedNavigator(
router: UserTrackingIndexViewRouter(),
navigatorKey: StackedService.nestedNavigationKey(2),
initialRoute: UserTrackingIndexViewRoutes.listKamusKesehatanView,
),
bottomNavigationBar: StylishBottomBar(
items: [
for (var item in model.bottomNavBarList)
BottomBarItem(
icon: Icon(item['icon'],
color: model.currentIndex ==
model.bottomNavBarList.indexOf(item)
? mainColor
: fontColor),
title: Text(
item['name'],
style: regularTextStyle.copyWith(
color: model.currentIndex ==
model.bottomNavBarList.indexOf(item)
? mainColor
: fontColor,
),
// textAlign: TextAlign.l,
),
backgroundColor: model.currentIndex ==
model.bottomNavBarList.indexOf(item)
? fontColor
: fontColor,
),
],
currentIndex: model.currentIndex,
option: BubbleBarOptions(),
hasNotch: true,
backgroundColor: mainColor,
onTap: (value) {
model.handleNavigation(value);
},
// fabLocation: StylishBarFabLocation.center,
),
),
);
},
);
}
}

View File

@ -0,0 +1,72 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:stacked/stacked.dart';
import 'package:stacked_services/stacked_services.dart';
import '../../../app/app.locator.dart';
import '../../../app/app.logger.dart';
import '../../../app/app.router.dart';
import '../../../services/global_var.dart';
class UserTrackingIndexViewModel extends IndexTrackingViewModel {
final log = getLogger('UserTrackingIndexViewModel');
final globalVar = locator<GlobalVar>();
final navigationService = locator<NavigationService>();
final dialogService = locator<DialogService>();
final _bottomNavBarList = [
{
'name': 'List Kamus',
'icon': Icons.list_alt_outlined,
'header': 'List Kamus',
},
{
'name': 'Profil Developer',
'icon': Icons.person_outline_outlined,
'header': 'Profil Developer',
},
];
String header = 'List Kamus';
List<Map<String, dynamic>> get bottomNavBarList => _bottomNavBarList;
final List<String> _views = [
// UserTrackingIndexViewRoutes.tampilkanListView,
UserTrackingIndexViewRoutes.listKamusKesehatanView,
UserTrackingIndexViewRoutes.profilUserView,
];
Future<void> init() async {
// setIndex(0);
// handleNavigation(0);
}
void handleNavigation(int index) {
// log.d("handleNavigation: $index");
// log.d("currentIndex: $currentIndex");
if (currentIndex == index) return;
setIndex(index);
header = _bottomNavBarList[index]['header'] as String;
navigationService.navigateTo(
_views[index],
id: 2,
);
}
exitApp() async {
dialogService
.showConfirmationDialog(
title: 'Konfirmasi',
description: 'Apakah anda yakin ingin keluar?',
cancelTitle: 'Batal',
confirmationTitle: 'Keluar',
)
.then((value) async {
if (value!.confirmed) {
SystemNavigator.pop();
}
});
}
}