Initial commit

This commit is contained in:
kicap
2024-03-02 08:48:26 +08:00
commit 758f5f3d8f
181 changed files with 9753 additions and 0 deletions

View File

@ -0,0 +1,103 @@
import 'package:flutter/material.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/app.router.dart';
import '../../../app/themes/app_colors.dart';
import '../../../app/themes/app_text.dart';
import '../../../model/penyewa_model.dart';
import './penyewa_index_view_model.dart';
class PenyewaIndexView extends StatelessWidget {
final DetailPenyewaModel penyewa;
const PenyewaIndexView({super.key, required this.penyewa});
@override
Widget build(BuildContext context) {
return ViewModelBuilder<PenyewaIndexViewModel>.reactive(
viewModelBuilder: () => PenyewaIndexViewModel(),
onViewModelReady: (PenyewaIndexViewModel model) async {
await model.init(penyewa);
},
builder: (
BuildContext context,
PenyewaIndexViewModel model,
Widget? child,
) {
return WillPopScope(
onWillPop: () async {
return false;
},
child: Scaffold(
appBar: AppBar(
title: Text(
model.header,
style: const TextStyle(
color: Colors.white,
fontSize: 20,
),
),
backgroundColor: mainColor,
elevation: 0,
automaticallyImplyLeading: false,
actions: [
IconButton(
onPressed: () {
model.logout();
},
icon: const Icon(Icons.logout, color: Colors.white),
),
],
),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 15),
child: ExtendedNavigator(
navigatorKey: StackedService.nestedNavigationKey(4),
router: PenyewaIndexViewRouter(),
initialRoute: PenyewaIndexViewRoutes.penyewaLogView,
),
),
bottomNavigationBar: StylishBottomBar(
items: [
for (var item in model.bottomNavBarList)
BottomBarItem(
icon: Icon(item['icon'],
color: model.currentIndex ==
model.bottomNavBarList.indexOf(item)
? sixthGrey
: backgroundColor),
title: Text(
item['name'],
style: regularTextStyle.copyWith(
color: model.currentIndex ==
model.bottomNavBarList.indexOf(item)
? sixthGrey
: mainGrey,
),
),
backgroundColor: model.currentIndex ==
model.bottomNavBarList.indexOf(item)
? fontColor
: mainGrey,
),
],
currentIndex: model.currentIndex,
hasNotch: true,
backgroundColor: mainColor,
onTap: (value) {
model.handleNavigation(value);
},
option: BubbleBarOptions(
barStyle: BubbleBarStyle.horizotnal,
bubbleFillStyle: BubbleFillStyle.fill,
opacity: 0.3),
),
),
);
},
);
}
}

View File

@ -0,0 +1,93 @@
import 'package:flutter/material.dart';
import 'package:rfid_app/app/app.locator.dart';
import 'package:rfid_app/model/penyewa_model.dart';
import 'package:stacked/stacked.dart';
import 'package:stacked_services/stacked_services.dart';
import '../../../app/app.logger.dart';
import '../../../app/app.router.dart';
import '../../../services/shared_prefs.dart';
class PenyewaIndexViewModel extends IndexTrackingViewModel {
final log = getLogger('PenyewaIndexViewModel');
final mySharedPrefs = locator<MySharedPrefs>();
final _navigationService = locator<NavigationService>();
final dialogService = locator<DialogService>();
final snackbarService = locator<SnackbarService>();
// final socketIoClient = locator<MySocketIoClient>();
final _bottomNavBarList = [
{
'name': 'Tempat Sewa',
'icon': Icons.home_outlined,
'header': 'List Tempat Sewa',
},
{
'name': 'Log History',
'icon': Icons.work_history_outlined,
'header': 'Log History',
},
{
'name': 'Detail User',
'icon': Icons.mobile_friendly_outlined,
'header': 'Detail User',
},
];
List<Map<String, dynamic>> get bottomNavBarList => _bottomNavBarList;
final List<String> _views = [
PenyewaIndexViewRoutes.tempatSewaanView,
PenyewaIndexViewRoutes.penyewaLogView,
PenyewaIndexViewRoutes.pulsaDetailView,
];
String header = 'Log History';
String? level;
Future<void> init(DetailPenyewaModel penyewa) async {
level = await mySharedPrefs.getString('level');
if (level != 'penyewa') {
snackbarService.showSnackbar(
message: 'Hanya Penyewa yang dapat mengakses halaman ini',
);
_navigationService.navigateTo(Routes.loginScreenView);
return;
}
setIndex(1);
// String nikAtprefs = await mySharedPrefs.getString('nik') ?? 'tidak ada';
// log.i("ini nikAtprefs $nikAtprefs");
// log.i(penyewa.nik);
}
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: 4,
);
}
logout() async {
dialogService
.showConfirmationDialog(
title: 'Konfirmasi',
description: 'Apakah anda yakin ingin keluar?',
cancelTitle: 'Batal',
confirmationTitle: 'Keluar',
)
.then((value) async {
if (value!.confirmed) {
await mySharedPrefs.clear();
_navigationService.clearStackAndShow(Routes.loginScreenView);
}
});
}
}

View File

@ -0,0 +1,103 @@
import 'package:flutter/material.dart';
import 'package:stacked/stacked.dart';
import '../../../../app/themes/app_colors.dart';
import '../../../../app/themes/app_text.dart';
import './penyewa_log_view_model.dart';
class PenyewaLogView extends StatelessWidget {
const PenyewaLogView({super.key});
@override
Widget build(BuildContext context) {
return ViewModelBuilder<PenyewaLogViewModel>.reactive(
viewModelBuilder: () => PenyewaLogViewModel(),
onViewModelReady: (PenyewaLogViewModel model) async {
await model.init();
},
fireOnViewModelReadyOnce: true,
builder: (
BuildContext context,
PenyewaLogViewModel model,
Widget? child,
) {
return WillPopScope(
onWillPop: () async => false,
child: Scaffold(
body: Column(
children: [
Expanded(
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: mainGrey.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset:
const Offset(0, 3), // changes position of shadow
),
],
),
child: model.logHistorySewaanList == null
? const Center(child: CircularProgressIndicator())
: ListView.builder(
padding: const EdgeInsets.symmetric(
horizontal: 15, vertical: 10),
itemCount: model.logHistorySewaanList!.length,
itemBuilder: (context, index) {
// model.log
// .i(model.logHistorySewaanList![index].date);
return GestureDetector(
onTap: () {
// model.log.i('clicked on index $index');
model.checkKet(
model.logHistorySewaanList![index],
);
},
child: Card(
child: ListTile(
title: Text(
model.logHistorySewaanList![index].jenis!,
style:
boldTextStyle.copyWith(fontSize: 15),
),
subtitle: const Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
// Text(
// 'Tempat : ${model.logHistorySewaanList![index].}',
// style: regularTextStyle,
// ),
// Text(
// model.logHistorySewaanList![index]
// .jenis!,
// style: italicTextStyle,
// ),
],
),
// dummy date and time
trailing: Text(
model.otherFunction.formatDateString(model
.logHistorySewaanList![index].date!),
style: regularTextStyle,
),
),
),
);
},
),
),
)
],
),
),
);
},
);
}
}

View File

@ -0,0 +1,39 @@
import '../../../../app/app.bottomsheets.dart';
import '../../../../app/app.logger.dart';
import '../../../../app/core/custom_base_view_model.dart';
import '../../../../model/my_response_model.dart';
import '../../../../model/penyewa_model.dart';
class PenyewaLogViewModel extends CustomBaseViewModel {
final log = getLogger('PenyewaLogViewModel');
List<PenyewaModel>? logHistorySewaanList;
String? nik;
Future<void> init() async {
nik = await mySharedPrefs.getString('nik');
await getData(nik);
}
getData(String? nik) async {
try {
var response = await httpService.get('user/log_user/$nik');
MyResponseModel myResponseModel = MyResponseModel.fromJson(response.data);
log.i(myResponseModel.data);
logHistorySewaanList = [];
myResponseModel.data.forEach((item) {
PenyewaModel penyewa = PenyewaModel.fromJson(item);
logHistorySewaanList!.add(penyewa);
log.d(penyewa);
});
notifyListeners();
} catch (e) {
log.e(e);
}
}
checkKet(PenyewaModel penyewaModel) async {
await bottomSheetService.showCustomSheet(
variant: BottomSheetType.detailLogHistoryView,
data: penyewaModel,
);
}
}

View File

@ -0,0 +1,105 @@
import 'package:flutter/material.dart';
import 'package:rfid_app/app/themes/app_text.dart';
import 'package:rfid_app/ui/widgets/my_button.dart';
import 'package:stacked/stacked.dart';
import '../../../../app/themes/app_colors.dart';
import './pulsa_detail_view_model.dart';
class PulsaDetailView extends StatelessWidget {
const PulsaDetailView({super.key});
@override
Widget build(BuildContext context) {
return ViewModelBuilder<PulsaDetailViewModel>.reactive(
viewModelBuilder: () => PulsaDetailViewModel(),
onViewModelReady: (PulsaDetailViewModel model) async {
await model.init();
},
builder: (
BuildContext context,
PulsaDetailViewModel model,
Widget? child,
) {
return Scaffold(
body: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
border: Border.all(
color: mainColor,
),
borderRadius: BorderRadius.circular(10),
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
_RowChildren(
title: 'NIK',
value: model.detailPenyewaModel!.nik ?? '...',
),
const SizedBox(height: 5),
_RowChildren(
title: 'Nama',
value: model.detailPenyewaModel!.nama ?? '...',
),
const SizedBox(height: 5),
_RowChildren(
title: 'Pulsa',
value:
'Rp. ${model.otherFunction.commaFormat(model.detailPenyewaModel!.saldo ?? 0)}',
),
const SizedBox(height: 5),
_RowChildren(
title: 'Card ID',
value: model.detailPenyewaModel!.rfid ?? '...',
),
],
),
),
const SizedBox(height: 20),
MyButton(text: 'Ganti Password')
],
),
);
},
);
}
}
class _RowChildren extends StatelessWidget {
const _RowChildren({
required this.title,
required this.value,
});
final String title;
final String value;
@override
Widget build(BuildContext context) {
return Row(
children: [
Expanded(
flex: 2,
child: Text(
title,
style: regularTextStyle,
),
),
const Expanded(flex: 1, child: Text(':')),
Expanded(
flex: 5,
child: Text(
value,
style: boldTextStyle,
),
),
],
);
}
}

View File

@ -0,0 +1,25 @@
import '../../../../app/app.logger.dart';
import '../../../../app/core/custom_base_view_model.dart';
import '../../../../model/my_response_model.dart';
import '../../../../model/penyewa_model.dart';
class PulsaDetailViewModel extends CustomBaseViewModel {
final log = getLogger('PulsaDetailViewModel');
String? nik;
DetailPenyewaModel? detailPenyewaModel;
Future<void> init() async {
nik = await mySharedPrefs.getString('nik');
await getData(nik);
}
getData(String? nik) async {
try {
var response = await httpService.get('user/user/$nik');
MyResponseModel myResponseModel = MyResponseModel.fromJson(response.data);
detailPenyewaModel = DetailPenyewaModel.fromJson(myResponseModel.data);
notifyListeners();
} catch (e) {
log.e(e);
}
}
}

View File

@ -0,0 +1,168 @@
import 'package:flutter/material.dart';
import 'package:stacked/stacked.dart';
import '../../../../app/themes/app_colors.dart';
import '../../../../app/themes/app_text.dart';
import './tempat_sewaan_view_model.dart';
class TempatSewaanView extends StatelessWidget {
const TempatSewaanView({super.key});
@override
Widget build(BuildContext context) {
return ViewModelBuilder<TempatSewaanViewModel>.reactive(
viewModelBuilder: () => TempatSewaanViewModel(),
onViewModelReady: (TempatSewaanViewModel model) async {
await model.init();
},
fireOnViewModelReadyOnce: true,
builder: (
BuildContext context,
TempatSewaanViewModel model,
Widget? child,
) {
return WillPopScope(
onWillPop: () async => false,
child: Scaffold(
body: Column(
children: [
Container(
padding:
const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
width: double.infinity,
decoration: BoxDecoration(
color: mainColor,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: mainGrey.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset:
const Offset(0, 3), // changes position of shadow
),
],
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Total Tempat Retribusi',
style: regularTextStyle.copyWith(
color: Colors.white,
fontSize: 15,
),
),
Text(
model.tempatSewaanList?.length.toString() ?? '...',
style: regularTextStyle.copyWith(
color: Colors.white,
fontSize: 15,
),
),
],
),
),
const SizedBox(height: 25),
Expanded(
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: mainGrey.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset:
const Offset(0, 3), // changes position of shadow
),
],
),
child: model.tempatSewaanList == null
? const Center(
child: CircularProgressIndicator(),
)
: ListView.builder(
padding: const EdgeInsets.symmetric(
horizontal: 15, vertical: 10),
itemCount: model.tempatSewaanList!.length,
itemBuilder: (context, index) {
model.log.i(model.tempatSewaanList![index]);
return Card(
child: ListTile(
title: Text(
model.tempatSewaanList![index]
.namaTempatSewa ??
'',
style: boldTextStyle.copyWith(
fontSize: 15,
),
),
subtitle: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
// Text(
// 'Penyewa : ${model.tempatSewaanList![index].nama}',
// ),
Text(
'Sewa / Bulan : Rp. ${model.otherFunction.commaFormat(model.tempatSewaanList![index].hargaSewa!)}',
),
],
),
// circle avatar
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
GestureDetector(
onTap: () => model.snackbarService
.showSnackbar(
message:
'Fitur sedang dalam tahap pengembangan'),
child: Container(
width: 40,
height: 40,
decoration: BoxDecoration(
color: mainColor,
borderRadius:
BorderRadius.circular(40),
),
child: const Icon(
Icons.list_alt_outlined,
color: Colors.white,
size: 20,
),
),
),
// const SizedBox(width: 5),
// Container(
// width: 50,
// height: 50,
// decoration: BoxDecoration(
// color: mainColor,
// borderRadius:
// BorderRadius.circular(50),
// ),
// child: const Icon(
// Icons.edit_square,
// color: Colors.white,
// ),
// ),
],
),
),
);
},
),
),
),
],
),
),
);
},
);
}
}

View File

@ -0,0 +1,31 @@
import '../../../../app/app.logger.dart';
import '../../../../app/core/custom_base_view_model.dart';
import '../../../../model/my_response_model.dart';
import '../../../../model/penyewa_model.dart';
class TempatSewaanViewModel extends CustomBaseViewModel {
final log = getLogger('TempatSewaanViewModel');
List<PenyewaModel>? tempatSewaanList;
String? nik;
Future<void> init() async {
nik = await mySharedPrefs.getString('nik');
await getData(nik);
}
getData(String? nik) async {
try {
var response = await httpService.get('user/tempat_sewa/$nik');
MyResponseModel myResponseModel = MyResponseModel.fromJson(response.data);
log.i(myResponseModel.data);
tempatSewaanList = [];
myResponseModel.data.forEach((item) {
PenyewaModel penyewa = PenyewaModel.fromJson(item);
tempatSewaanList!.add(penyewa);
log.d(penyewa);
});
notifyListeners();
} catch (e) {
log.e(e);
}
}
}