Commit 5cde9512 authored by Dio Maulana's avatar Dio Maulana

all api implemented

parent 12f09488
This diff is collapsed.
import 'package:tour_travel_agr/models/profile_model.dart';
class EditProfileArguments {
ProfileModel profile;
void Function(bool)? onSuccessUpdate;
EditProfileArguments({
required this.profile,
this.onSuccessUpdate,
});
}
import 'package:tour_travel_agr/models/profile_model.dart';
class ProfileArguments {
ProfileModel profile;
ProfileArguments({required this.profile});
}
class VerificationArguments {
String id;
String phone;
String otpExpiredTime;
VerificationArguments({
required this.id,
required this.phone,
required this.otpExpiredTime,
});
}
import 'package:flutter/material.dart';
import 'package:shimmer/shimmer.dart';
import 'package:tour_travel_agr/resource/assets.dart';
import 'package:tour_travel_agr/resource/colors.dart';
import 'package:tour_travel_agr/resource/font.dart';
......@@ -8,14 +9,14 @@ import 'package:tour_travel_agr/resource/style.dart';
class ListTransaction extends StatelessWidget {
const ListTransaction({
super.key,
required this.date,
required this.title,
required this.subtitle,
this.date,
this.title,
this.subtitle,
});
final String date;
final String title;
final String subtitle;
final String? date;
final String? title;
final String? subtitle;
@override
Widget build(BuildContext context) {
......@@ -53,14 +54,27 @@ class ListTransaction extends StatelessWidget {
Row(
children: [
const Spacer(),
Text(
date,
style: getRegularStyle(
color: ColorManager.grey,
fontFamily: FontConstants.openSans,
fontSize: FontSize.s12,
),
)
(date != null)
? Text(
date!,
style: getRegularStyle(
color: ColorManager.grey,
fontFamily: FontConstants.openSans,
fontSize: FontSize.s12,
),
)
: Shimmer.fromColors(
baseColor: ColorManager.baseColorShimmer,
highlightColor: ColorManager.highlightColorShimmer,
child: Container(
width: 50,
height: 10,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: ColorManager.primary,
),
),
)
],
),
Row(
......@@ -93,21 +107,50 @@ class ListTransaction extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: getBoldStyle(
color: Colors.black,
fontFamily: FontConstants.mulish,
fontSize: 18,
),
),
Text(
subtitle,
style: getSemiBoldStyle(
color: ColorManager.primary,
fontFamily: FontConstants.openSans,
),
),
(title != null)
? Text(
title!,
style: getBoldStyle(
color: Colors.black,
fontFamily: FontConstants.mulish,
fontSize: 18,
),
)
: Shimmer.fromColors(
baseColor: ColorManager.baseColorShimmer,
highlightColor: ColorManager.highlightColorShimmer,
child: Container(
width: 80,
height: 15,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: ColorManager.primary,
),
),
),
(subtitle != null)
? Text(
subtitle!,
style: getSemiBoldStyle(
color: ColorManager.primary,
fontFamily: FontConstants.openSans,
),
)
: Shimmer.fromColors(
baseColor: ColorManager.baseColorShimmer,
highlightColor: ColorManager.highlightColorShimmer,
child: Container(
margin: const EdgeInsets.only(
top: 10,
),
width: 70,
height: 13,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: ColorManager.primary,
),
),
),
],
),
)
......
// memberikan format number untuk setiap ribuan,
import 'package:intl/intl.dart';
const String separatorThousand = '.';
NumberFormat formatNumber() {
// tentukan separator di file constanta.dart
if (separatorThousand == ',') {
return NumberFormat('#,###');
} else if (separatorThousand == '.') {
return NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0);
} else {
return NumberFormat('#,###');
}
}
// parsing amount dari String backend, contoh string 10000.00
String parsingAmountBackend(String amount) {
double d = double.tryParse(amount) ?? 0.0;
int result = d.toInt();
return formatNumber().format(result);
}
......@@ -69,14 +69,17 @@ String dateLocal(String dateTime, {bool fullDateTime = false}) {
String year = splitDate[0];
String month = DateFormatCustom.monthLocal(splitDate[1]);
String tgl = splitDate[2];
String result;
if (fullDateTime) {
return "$tgl $month $year ${split[1]}";
result = "$tgl $month $year ${split[1]}";
} else {
return "$tgl $month $year";
result = "$tgl $month $year";
}
return result;
}
DateTime toInternationFormat(String dateLocal, {bool fullDateTime = false}) {
DateTime toInternationFormat(String dateLocal,
{bool fullDateTime = false, timeInclude = true}) {
List<String> splitDate = dateLocal.split(" ");
String? time;
if (fullDateTime) {
......@@ -94,3 +97,9 @@ DateTime toInternationFormat(String dateLocal, {bool fullDateTime = false}) {
}
return result!;
}
String getOnlyDate(DateTime fullDateTime) {
String f = fullDateTime.toString();
List<String> s = f.split(" ");
return s[0];
}
import 'package:tour_travel_agr/helper/prefs.dart';
Future<bool> checkSession() async {
if (getSessionId() == "") {
return false;
}
return true;
}
Map<String, dynamic> differenceTimeFromNow(String time) {
DateTime from = DateTime.now().toLocal();
DateTime to = DateTime.parse(time).toLocal();
int hours = to.difference(from).inHours % 60;
int minutes = to.difference(from).inMinutes % 60;
int seconds = to.difference(from).inSeconds % 60;
Map<String, dynamic> results = {
"hour": hours.toString().padLeft(2, '0'),
"minutes": minutes.toString().padLeft(2, '0'),
"seconds": seconds.toString().padLeft(2, '0'),
// "time_left": (hours > 0)
// ? "${hours.toString().padLeft(2, '0')}:${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}"
// : "${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}",
};
return results;
}
......@@ -10,7 +10,7 @@ late SharedPreferences prefs;
bool debug = true;
String titleApp = 'Tour & Travel Agency';
String brandCode = 'AGR';
String baseUrl = "https://hibiscus-dev.ravku.com/";
String baseUrl = "https://neo-agr.ravku.com/";
String endPoint = "agency/api/";
String initialRoute = Routes.splashRoute;
......
......@@ -2,11 +2,13 @@ class ProfileModel {
String fullName;
String mobilePhone;
String nik;
String avatarUrl;
ProfileModel({
required this.fullName,
required this.mobilePhone,
required this.nik,
required this.avatarUrl,
});
factory ProfileModel.json(Map<String, dynamic> json) {
......@@ -14,6 +16,7 @@ class ProfileModel {
fullName: json['full_name'],
mobilePhone: json['mobile_phone'],
nik: json['nik'],
avatarUrl: json['image_profile_url'] ?? "",
);
}
}
class TransactionModel {
int transactionCount;
String transactionCount;
String totalTransaction;
List<ListTransactionModel> listTransaction;
......
// ignore_for_file: avoid_unnecessary_containers
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:tour_travel_agr/api/all_api.dart';
import 'package:tour_travel_agr/helper/components_widget/custom_appbar.dart';
import 'package:tour_travel_agr/helper/components_widget/widget_button.dart';
......@@ -10,6 +11,7 @@ import 'package:tour_travel_agr/helper/widget_responsive.dart';
import 'package:tour_travel_agr/resource/assets.dart';
import 'package:tour_travel_agr/resource/colors.dart';
import 'package:tour_travel_agr/resource/size.dart';
import 'package:tour_travel_agr/resource/strings.dart';
import 'package:tour_travel_agr/resource/style.dart';
class ForgotPasswordView extends StatefulWidget {
......@@ -146,10 +148,15 @@ class _ForgotPasswordViewState extends State<ForgotPasswordView> {
CustomButton(
text: "Submit",
colorButton: (!buttonActive) ? Colors.grey : null,
onTap: () {
onTap: () async {
if (buttonActive) {
await EasyLoading.show(
status: Strings.pleaseWait,
maskType: EasyLoadingMaskType.none,
);
Api.forgotPassword(whatsappController.text)
.then((response) {
EasyLoading.dismiss();
modalDialogGlobal(
context: context,
title: (response.error) ? "Gagal" : "Berhasil",
......
import 'package:flutter/material.dart';
import 'package:shimmer/shimmer.dart';
import 'package:tour_travel_agr/api/all_api.dart';
import 'package:tour_travel_agr/helper/components_widget/custom_appbar.dart';
import 'package:tour_travel_agr/helper/components_widget/modal_select_date.dart';
import 'package:tour_travel_agr/helper/components_widget/transaction_list.dart';
import 'package:tour_travel_agr/helper/function/number.dart';
import 'package:tour_travel_agr/helper/function/replace_date.dart';
import 'package:tour_travel_agr/helper/function/session_check.dart';
import 'package:tour_travel_agr/helper/modal_dialog.dart';
import 'package:tour_travel_agr/helper/prefs.dart';
import 'package:tour_travel_agr/helper/widget_responsive.dart';
import 'package:tour_travel_agr/models/transaction_model.dart';
import 'package:tour_travel_agr/resource/assets.dart';
import 'package:tour_travel_agr/resource/colors.dart';
import 'package:tour_travel_agr/resource/constanta_string.dart';
import 'package:tour_travel_agr/resource/font.dart';
import 'package:tour_travel_agr/resource/routes.dart';
import 'package:tour_travel_agr/resource/size.dart';
import 'package:tour_travel_agr/resource/strings.dart';
import 'package:tour_travel_agr/resource/style.dart';
class HistoryView extends StatelessWidget {
......@@ -43,10 +51,23 @@ class _BodyWidgetState extends State<BodyWidget> {
bool? customDateActive;
String? startDate;
String? endDate;
TransactionModel? transactions;
@override
void initState() {
resetFilter();
checkSession().then((isLogin) {
if (isLogin) {
resetFilter().then((_) {
getTransactionData(startDate, endDate);
});
} else {
Navigator.pushNamedAndRemoveUntil(
context,
Routes.loginRoute,
(route) => false,
);
}
});
super.initState();
}
......@@ -56,7 +77,7 @@ class _BodyWidgetState extends State<BodyWidget> {
super.dispose();
}
void resetFilter() {
Future<void> resetFilter() async {
String reimburseDate = getHistoryDate();
if (reimburseDate != '') {
List<String> split = reimburseDate.split(" - ");
......@@ -79,6 +100,44 @@ class _BodyWidgetState extends State<BodyWidget> {
}
}
void getTransactionData(String? start, String? end) {
Api.transaction(start, end).then((apiResponse) {
if (apiResponse.error) {
if (apiResponse.data["code"] == "WRONG_SESSION_ID") {
modalDialogGlobal(
context: context,
title: "Session Expired",
contentBody: Strings.sessionExpired,
buttonText: "OK",
tapButton: () {
removeSessionId();
Navigator.pushNamedAndRemoveUntil(
context,
Routes.loginRoute,
(route) => false,
);
},
);
} else {
modalDialogGlobal(
context: context,
title: "Error",
contentBody: apiResponse.msg,
buttonText: "OK",
tapButton: () {
Navigator.pop(context);
Navigator.pop(context);
},
);
}
} else {
setState(() {
transactions = apiResponse.data as TransactionModel;
});
}
});
}
@override
Widget build(BuildContext context) {
return Container(
......@@ -130,10 +189,13 @@ class _BodyWidgetState extends State<BodyWidget> {
builder: (context) {
return ModalSelectDate(
onTapWidget: () {
Navigator.pop(context);
resetFilter();
setState(() {
dateSelected = getHistoryDate();
transactions = null;
});
Navigator.pop(context);
resetFilter().then((_) {
getTransactionData(startDate, endDate);
});
},
todayActive: todayActive!,
......@@ -160,7 +222,9 @@ class _BodyWidgetState extends State<BodyWidget> {
text: "Transaksi",
icon: Assets.moneyIcon,
iconColor: ColorManager.pink,
countText: "10",
countText: (transactions == null)
? null
: transactions?.transactionCount.toString(),
countTextColor: ColorManager.primary,
),
SizedBox(
......@@ -170,7 +234,10 @@ class _BodyWidgetState extends State<BodyWidget> {
text: "Total",
icon: Assets.totalIcon,
iconColor: ColorManager.softGreen,
countText: "Rp 1.200.000",
countText: (transactions == null)
? null
: parsingAmountBackend(
"Rp ${transactions?.totalTransaction}"),
countTextColor: ColorManager.green,
),
],
......@@ -179,17 +246,50 @@ class _BodyWidgetState extends State<BodyWidget> {
height: AppMargin.m20,
),
Expanded(
child: ListView.builder(
padding: EdgeInsets.zero,
itemCount: 10,
itemBuilder: (c, index) {
return const ListTransaction(
date: "10 Maret 2023",
title: "AGR Surabaya",
subtitle: "Rp 520.000",
);
},
),
child: (transactions == null)
? ListView.builder(
padding: EdgeInsets.zero,
itemCount: 10,
itemBuilder: (c, index) {
return const ListTransaction(
date: null,
title: null,
subtitle: null,
);
},
)
: (transactions!.listTransaction.isEmpty)
? Container(
width: double.infinity,
height: double.infinity,
padding: EdgeInsets.symmetric(
horizontal: AppPadding.p20,
),
child: Center(
child: Text(
Strings.transactionNotFound,
style: getSemiBoldStyle(
color: Colors.grey,
fontSize: FontSize.s20,
),
textAlign: TextAlign.center,
),
),
)
: ListView.builder(
padding: EdgeInsets.zero,
itemCount: transactions!.listTransaction.length,
itemBuilder: (c, index) {
return ListTransaction(
date: dateLocal(transactions!
.listTransaction[index].bussinesDate),
title:
transactions!.listTransaction[index].brandCode,
subtitle:
"Rp ${transactions!.listTransaction[index].total}",
);
},
),
),
],
),
......@@ -202,7 +302,7 @@ class WidgetHead extends StatelessWidget {
super.key,
required this.text,
required this.icon,
required this.countText,
this.countText,
required this.iconColor,
required this.countTextColor,
});
......@@ -210,7 +310,7 @@ class WidgetHead extends StatelessWidget {
final String text;
final String icon;
final Color iconColor;
final String countText;
final String? countText;
final Color countTextColor;
@override
Widget build(BuildContext context) {
......@@ -270,14 +370,24 @@ class WidgetHead extends StatelessWidget {
Row(
children: [
const Spacer(),
Text(
countText,
style: getSemiBoldStyle(
color: countTextColor,
fontSize: 16,
fontFamily: FontConstants.openSans,
),
)
(countText != null)
? Text(
countText!,
style: getSemiBoldStyle(
color: countTextColor,
fontSize: 16,
fontFamily: FontConstants.openSans,
),
)
: Shimmer.fromColors(
baseColor: ColorManager.baseColorShimmer,
highlightColor: ColorManager.highlightColorShimmer,
child: Container(
width: 25,
height: 15,
color: ColorManager.primary,
),
)
],
)
],
......
This diff is collapsed.
// ignore_for_file: sized_box_for_whitespace, avoid_unnecessary_containers
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:tour_travel_agr/api/all_api.dart';
import 'package:tour_travel_agr/helper/components_widget/custom_appbar.dart';
import 'package:tour_travel_agr/helper/function/timer_date.dart';
import 'package:tour_travel_agr/helper/modal_dialog.dart';
import 'package:tour_travel_agr/helper/widget_responsive.dart';
import 'package:tour_travel_agr/resource/assets.dart';
......@@ -19,10 +22,12 @@ class OtpVerificationView extends StatefulWidget {
super.key,
required this.id,
required this.phone,
required this.otpExpiredTime,
});
final String id;
final String phone;
final String otpExpiredTime;
@override
State<OtpVerificationView> createState() => _OtpVerificationViewState();
......@@ -113,7 +118,10 @@ class _OtpVerificationViewState extends State<OtpVerificationView> {
),
),
),
const CountDownTimeOtp(),
CountDownTimeOtp(
idRegistration: widget.id,
otpExpiredTime: widget.otpExpiredTime,
),
Container(
margin: EdgeInsets.only(
top: AppMargin.m16,
......@@ -184,7 +192,10 @@ class _OtpVerificationViewState extends State<OtpVerificationView> {
});
// ignore: use_build_context_synchronously
FocusScope.of(context).unfocus();
Api.resendOtpVerification(widget.id).then((apiResponse) {
Api.confirmRegistration(
widget.id,
finalText,
).then((apiResponse) {
EasyLoading.dismiss();
if (apiResponse.error) {
setState(() {
......@@ -229,13 +240,61 @@ class _OtpVerificationViewState extends State<OtpVerificationView> {
class CountDownTimeOtp extends StatefulWidget {
const CountDownTimeOtp({
Key? key,
required this.idRegistration,
required this.otpExpiredTime,
}) : super(key: key);
final String idRegistration;
final String otpExpiredTime;
@override
State<CountDownTimeOtp> createState() => _CountDownTimeOtpState();
}
class _CountDownTimeOtpState extends State<CountDownTimeOtp> {
late Timer? _timer;
late String hours = "00";
late String minutes = "00";
late String seconds = "00";
late bool isTimerExpired = false;
late String? timerExpired;
@override
void initState() {
timerExpired = widget.otpExpiredTime;
startTimer();
super.initState();
}
@override
void dispose() {
_timer?.cancel();
super.dispose();
}
void startTimer() {
Duration oneSec = const Duration(seconds: 1);
_timer = Timer.periodic(
oneSec,
(Timer timer) {
setState(() {
Map<String, dynamic> diffTime = differenceTimeFromNow(timerExpired!);
hours = diffTime['hour'];
minutes = diffTime['minutes'];
seconds = diffTime['seconds'];
if (hours == "00" && minutes == "00" && seconds == "00") {
isTimerExpired = true;
cancelTimer();
}
});
},
);
}
void cancelTimer() {
_timer?.cancel();
}
@override
Widget build(BuildContext context) {
return Container(
......@@ -245,42 +304,70 @@ class _CountDownTimeOtpState extends State<CountDownTimeOtp> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
"00 :",
style: getRegularStyle(
color: ColorManager.primary,
fontSize: 20,
fontFamily: FontConstants.mulish,
),
),
Text(
" 02 :",
style: getRegularStyle(
color: ColorManager.primary,
fontSize: 20,
fontFamily: FontConstants.mulish,
),
),
Text(
" 59",
style: getRegularStyle(
color: ColorManager.primary,
fontSize: 20,
fontFamily: FontConstants.mulish,
(isTimerExpired == false)
? Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
"$hours :",
style: getRegularStyle(
color: ColorManager.primary,
fontSize: 20,
fontFamily: FontConstants.mulish,
),
),
Text(
" $minutes :",
style: getRegularStyle(
color: ColorManager.primary,
fontSize: 20,
fontFamily: FontConstants.mulish,
),
),
Text(
" $seconds",
style: getRegularStyle(
color: ColorManager.primary,
fontSize: 20,
fontFamily: FontConstants.mulish,
),
)
],
)
: GestureDetector(
onTap: () async {
await EasyLoading.show(
status: Strings.pleaseWait,
maskType: EasyLoadingMaskType.none,
);
Api.resendOtpVerification(widget.idRegistration)
.then((apiResponse) {
EasyLoading.dismiss();
if (apiResponse.error) {
modalDialogGlobal(
context: context,
title: "Gagal",
contentBody: apiResponse.msg,
buttonText: "Ok",
tapButton: () => Navigator.pop(context),
);
return;
}
setState(() {
isTimerExpired = false;
timerExpired = apiResponse.data["can_resend_after"];
startTimer();
});
});
},
child: Text(
"Resend otp",
style: getRegularStyle(
color: ColorManager.primary,
fontSize: FontSize.s16,
),
),
),
)
],
),
// Text(
// "Resend otp",
// style: getRegularStyle(
// color: ColorManager.primary,
// fontSize: FontSize.s16,
// ),
// ),
],
),
);
......
// ignore_for_file: use_build_context_synchronously
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:tour_travel_agr/api/all_api.dart';
import 'package:tour_travel_agr/helper/components_widget/custom_appbar.dart';
import 'package:tour_travel_agr/helper/components_widget/password_input.dart';
import 'package:tour_travel_agr/helper/components_widget/widget_button.dart';
import 'package:tour_travel_agr/helper/function/session_check.dart';
import 'package:tour_travel_agr/helper/modal_dialog.dart';
import 'package:tour_travel_agr/helper/prefs.dart';
import 'package:tour_travel_agr/helper/widget_responsive.dart';
import 'package:tour_travel_agr/resource/colors.dart';
import 'package:tour_travel_agr/resource/font.dart';
import 'package:tour_travel_agr/resource/routes.dart';
import 'package:tour_travel_agr/resource/size.dart';
import 'package:tour_travel_agr/resource/strings.dart';
import 'package:tour_travel_agr/resource/style.dart';
class ChangePasswordView extends StatefulWidget {
......@@ -26,6 +35,15 @@ class _ChangePasswordViewState extends State<ChangePasswordView> {
bool buttonActive = false;
@override
void initState() {
checkSession().then((isLogin) {
if (isLogin == false) {
Navigator.pushNamedAndRemoveUntil(
context,
Routes.loginRoute,
(route) => false,
);
}
});
super.initState();
}
......@@ -130,7 +148,9 @@ class _ChangePasswordViewState extends State<ChangePasswordView> {
buttonActive = true;
});
} else {
buttonActive = false;
setState(() {
buttonActive = false;
});
}
},
),
......@@ -141,9 +161,69 @@ class _ChangePasswordViewState extends State<ChangePasswordView> {
child: CustomButton(
text: "Update",
colorButton: (buttonActive) ? null : Colors.grey,
onTap: () {
onTap: () async {
if (buttonActive) {
// TODO: do something here
if (newPasswordController.text !=
confirmNewPasswordController.text) {
modalDialogGlobal(
context: context,
title: "Informasi",
contentBody: "Konfirmasi password tidak cocok",
buttonText: "Ok",
tapButton: () => Navigator.pop(context),
);
}
await EasyLoading.show(
status: Strings.pleaseWait,
maskType: EasyLoadingMaskType.none,
);
Api.changePassword(
nowPasswordController.text,
newPasswordController.text,
confirmNewPasswordController.text)
.then(
(apiresponse) {
EasyLoading.dismiss();
if (apiresponse.error) {
if (apiresponse.data['code'] ==
"WRONG_SESSION_ID") {
modalDialogGlobal(
context: context,
title: "Session Expired",
contentBody: Strings.sessionExpired,
buttonText: "OK",
tapButton: () {
removeSessionId();
Navigator.pushNamedAndRemoveUntil(
context,
Routes.loginRoute,
(route) => false,
);
},
);
} else {
modalDialogGlobal(
context: context,
title: "Gagal",
contentBody: apiresponse.msg,
buttonText: "OK",
tapButton: () => Navigator.pop(context),
);
}
} else {
modalDialogGlobal(
context: context,
title: "Sukses",
contentBody: apiresponse.msg,
buttonText: "Ok",
tapButton: () {
Navigator.pop(context);
Navigator.pop(context);
},
);
}
},
);
}
},
),
......
import 'dart:convert';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:tour_travel_agr/api/all_api.dart';
import 'package:tour_travel_agr/helper/components_widget/custom_appbar.dart';
import 'package:tour_travel_agr/helper/components_widget/widget_button.dart';
import 'package:tour_travel_agr/helper/components_widget/widget_text_field.dart';
import 'package:tour_travel_agr/helper/modal_dialog.dart';
import 'package:tour_travel_agr/helper/prefs.dart';
import 'package:tour_travel_agr/helper/widget_responsive.dart';
import 'package:tour_travel_agr/models/profile_model.dart';
import 'package:tour_travel_agr/resource/assets.dart';
import 'package:tour_travel_agr/resource/colors.dart';
import 'package:tour_travel_agr/resource/routes.dart';
import 'package:tour_travel_agr/resource/size.dart';
import 'package:tour_travel_agr/resource/strings.dart';
class EditProfileView extends StatefulWidget {
const EditProfileView({super.key});
const EditProfileView({
super.key,
required this.profile,
this.onSuccessUpdate,
});
final ProfileModel profile;
final void Function(bool)? onSuccessUpdate;
@override
State<EditProfileView> createState() => _EditProfileViewState();
}
class _EditProfileViewState extends State<EditProfileView> {
final TextEditingController nameController = TextEditingController();
final TextEditingController nikController = TextEditingController();
final TextEditingController hpController = TextEditingController();
TextEditingController nameController = TextEditingController();
TextEditingController nikController = TextEditingController();
TextEditingController hpController = TextEditingController();
Uint8List? byteImage;
String? base64Image;
@override
void initState() {
setState(() {
nameController.text = widget.profile.fullName;
nikController.text = widget.profile.nik;
hpController.text = widget.profile.mobilePhone;
});
super.initState();
}
@override
Widget build(BuildContext context) {
......@@ -64,6 +91,7 @@ class _EditProfileViewState extends State<EditProfileView> {
// print(file);
setState(() {
byteImage = file.bytes;
base64Image = base64Encode(byteImage!);
});
// print(file.path);
} else {
......@@ -124,8 +152,62 @@ class _EditProfileViewState extends State<EditProfileView> {
),
Container(
margin: const EdgeInsets.only(top: 30),
child: const CustomButton(
child: CustomButton(
text: "Update",
onTap: () async {
await EasyLoading.show(
status: Strings.pleaseWait,
maskType: EasyLoadingMaskType.none,
);
Api.changeProfile(
nameController.text,
nikController.text,
hpController.text,
base64Image,
).then((apiResponse) {
EasyLoading.dismiss();
if (apiResponse.error) {
if (apiResponse.data["code"] ==
"WRONG_SESSION_ID") {
modalDialogGlobal(
context: context,
title: "Session Expired",
contentBody: Strings.sessionExpired,
buttonText: "OK",
tapButton: () {
removeSessionId();
Navigator.pushNamedAndRemoveUntil(
context,
Routes.loginRoute,
(route) => false,
);
},
);
} else {
modalDialogGlobal(
context: context,
title: "Error",
contentBody: apiResponse.msg,
buttonText: "OK",
tapButton: () {
Navigator.pop(context);
},
);
}
} else {
modalDialogGlobal(
context: context,
title: "Success",
contentBody: apiResponse.msg,
buttonText: "Ok",
tapButton: () {
widget.onSuccessUpdate!(true);
Navigator.pop(context);
Navigator.pop(context);
});
}
});
},
),
)
],
......
This diff is collapsed.
......@@ -36,7 +36,7 @@ class _RegisterViewState extends State<RegisterView> {
TextEditingController();
bool isChecked = false;
bool buttonRregisterActive = false;
bool buttonRegisterActive = false;
@override
Widget build(BuildContext context) {
......@@ -121,7 +121,7 @@ class _RegisterViewState extends State<RegisterView> {
value: isChecked,
onChanged: (bool? value) {
setState(() {
buttonRregisterActive = value!;
buttonRegisterActive = value!;
isChecked = value;
});
},
......@@ -151,11 +151,11 @@ class _RegisterViewState extends State<RegisterView> {
),
child: CustomButton(
text: "Register",
colorButton: buttonRregisterActive
colorButton: buttonRegisterActive
? ColorManager.primary
: Colors.grey,
onTap: () async {
if (buttonRregisterActive) {
if (buttonRegisterActive) {
if (nameController.text.isEmpty ||
nikController.text.isEmpty ||
noHpController.text.isEmpty ||
......@@ -212,8 +212,10 @@ class _RegisterViewState extends State<RegisterView> {
context,
Routes.verificationRoute,
arguments: VerificationArguments(
id: "ASAS",
id: apiResponse.data['register_id'],
phone: noHpController.text,
otpExpiredTime:
apiResponse.data['can_resend_after'],
),
);
});
......
// ignore_for_file: sized_box_for_whitespace
import 'package:flutter/material.dart';
import 'package:tour_travel_agr/api/all_api.dart';
import 'package:tour_travel_agr/helper/components_widget/custom_appbar.dart';
import 'package:tour_travel_agr/helper/components_widget/modal_select_date.dart';
import 'package:tour_travel_agr/helper/components_widget/transaction_list.dart';
import 'package:tour_travel_agr/helper/function/number.dart';
import 'package:tour_travel_agr/helper/function/replace_date.dart';
import 'package:tour_travel_agr/helper/function/session_check.dart';
import 'package:tour_travel_agr/helper/modal_dialog.dart';
import 'package:tour_travel_agr/helper/prefs.dart';
import 'package:tour_travel_agr/helper/widget_responsive.dart';
import 'package:tour_travel_agr/models/reimburse_model.dart';
import 'package:tour_travel_agr/resource/assets.dart';
import 'package:tour_travel_agr/resource/colors.dart';
import 'package:tour_travel_agr/resource/constanta_string.dart';
import 'package:tour_travel_agr/resource/font.dart';
import 'package:tour_travel_agr/resource/routes.dart';
import 'package:tour_travel_agr/resource/size.dart';
import 'package:tour_travel_agr/resource/strings.dart';
import 'package:tour_travel_agr/resource/style.dart';
class ReimbursementView extends StatelessWidget {
......@@ -45,10 +52,25 @@ class _BodyWidgetState extends State<BodyWidget> {
bool? customDateActive;
String? startDate;
String? endDate;
List<ReimburseModel>? dataReimburse;
bool responseApiError = false;
@override
void initState() {
resetFilter();
checkSession().then((isLogin) {
if (isLogin) {
resetFilter().then((_) {
getReimburseData(startDate, endDate);
});
} else {
Navigator.pushNamedAndRemoveUntil(
context,
Routes.loginRoute,
(route) => false,
);
}
});
super.initState();
}
......@@ -58,7 +80,45 @@ class _BodyWidgetState extends State<BodyWidget> {
super.dispose();
}
void resetFilter() {
void getReimburseData(String? start, String? end) {
Api.reimburse(start, end).then((apiResponse) {
if (apiResponse.error) {
if (apiResponse.data["code"] == "WRONG_SESSION_ID") {
modalDialogGlobal(
context: context,
title: "Session Expired",
contentBody: Strings.sessionExpired,
buttonText: "OK",
tapButton: () {
removeSessionId();
Navigator.pushNamedAndRemoveUntil(
context,
Routes.loginRoute,
(route) => false,
);
},
);
} else {
modalDialogGlobal(
context: context,
title: "Error",
contentBody: apiResponse.msg,
buttonText: "OK",
tapButton: () {
Navigator.pop(context);
Navigator.pop(context);
},
);
}
} else {
setState(() {
dataReimburse = apiResponse.data as List<ReimburseModel>;
});
}
});
}
Future<void> resetFilter() async {
String reimburseDate = getReimburseDate();
if (reimburseDate != '') {
List<String> split = reimburseDate.split(" - ");
......@@ -131,10 +191,13 @@ class _BodyWidgetState extends State<BodyWidget> {
builder: (context) {
return ModalSelectDate(
onTapWidget: () {
Navigator.pop(context);
resetFilter();
setState(() {
dateSelected = getReimburseDate();
dataReimburse = null;
});
Navigator.pop(context);
resetFilter().then((_) {
getReimburseData(startDate, endDate);
});
},
todayActive: todayActive!,
......@@ -159,17 +222,50 @@ class _BodyWidgetState extends State<BodyWidget> {
height: 12,
),
Expanded(
child: ListView.builder(
padding: EdgeInsets.zero,
itemCount: 10,
itemBuilder: (c, index) {
return const ListTransaction(
date: "24 Maret 2023",
title: "15 Transaksi",
subtitle: "Rp 320.000",
);
},
),
child: (dataReimburse == null)
? ListView.builder(
padding: EdgeInsets.zero,
itemCount: 5,
itemBuilder: (c, index) {
return const ListTransaction(
date: null,
title: null,
subtitle: null,
);
},
)
: (dataReimburse!.isEmpty)
? Container(
width: double.infinity,
height: double.infinity,
padding: EdgeInsets.symmetric(
horizontal: AppPadding.p20,
),
child: Center(
child: Text(
Strings.reimbursementNotFound,
style: getSemiBoldStyle(
color: Colors.grey,
fontSize: FontSize.s20,
),
textAlign: TextAlign.center,
),
),
)
: ListView.builder(
padding: EdgeInsets.zero,
itemCount: dataReimburse!.length,
itemBuilder: (c, index) {
return ListTransaction(
date: dateLocal(dataReimburse![index].date),
title:
"${dataReimburse![index].transactionCount} Transaksi",
subtitle: "Rp ${parsingAmountBackend(
dataReimburse![index].comissionAmount,
)}",
);
},
),
),
],
),
......
// ignore_for_file: use_build_context_synchronously
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:tour_travel_agr/api/all_api.dart';
import 'package:tour_travel_agr/helper/argument_route/error_arguments.dart';
import 'package:tour_travel_agr/helper/components_widget/custom_appbar.dart';
......@@ -10,6 +13,7 @@ import 'package:tour_travel_agr/resource/assets.dart';
import 'package:tour_travel_agr/resource/colors.dart';
import 'package:tour_travel_agr/resource/routes.dart';
import 'package:tour_travel_agr/resource/size.dart';
import 'package:tour_travel_agr/resource/strings.dart';
import 'package:tour_travel_agr/resource/style.dart';
class ResetPasswordView extends StatefulWidget {
......@@ -166,14 +170,41 @@ class _ResetPasswordViewState extends State<ResetPasswordView> {
CustomButton(
text: "Submit",
colorButton: (!buttonActive) ? Colors.grey : null,
onTap: () {
onTap: () async {
if (buttonActive) {
if (newPasswordController.text.isEmpty) {
modalDialogGlobal(
context: context,
title: "Info",
contentBody: "Password tidak boleh kosong",
buttonText: "Ok",
tapButton: () => Navigator.pop(context),
);
return;
}
if (newPasswordController.text !=
passwordController.text) {
modalDialogGlobal(
context: context,
title: "Info",
contentBody: "Password tidak sama",
buttonText: "Ok",
tapButton: () => Navigator.pop(context),
);
return;
}
await EasyLoading.show(
status: Strings.pleaseWait,
maskType: EasyLoadingMaskType.none,
);
Api.resetPassword(
widget.idPath,
passwordController.text,
newPasswordController.text,
).then(
(apiResponse) {
EasyLoading.dismiss();
if (apiResponse.error) {
modalDialogGlobal(
context: context,
......
......@@ -8,4 +8,6 @@ class ColorManager {
static Color grey = const Color(0xff595959);
static Color softGreen = const Color(0xffA4D8C8);
static Color green = const Color(0xff3CA786);
static Color baseColorShimmer = Colors.grey;
static Color highlightColorShimmer = const Color.fromARGB(255, 226, 225, 225);
}
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:tour_travel_agr/helper/argument_route/edit_profile_arguments.dart';
import 'package:tour_travel_agr/helper/argument_route/error_arguments.dart';
import 'package:tour_travel_agr/helper/argument_route/verification_otp.dart';
import 'package:tour_travel_agr/main.dart';
......@@ -54,6 +55,7 @@ class RouteGenerator {
OtpVerificationView(
id: args.id,
phone: args.phone,
otpExpiredTime: args.otpExpiredTime,
),
nameRoute: Routes.verificationRoute,
routeSettings: routeSettings,
......@@ -92,8 +94,16 @@ class RouteGenerator {
return pageRouteCustom(const ChangePasswordView(),
nameRoute: Routes.changePasswordRoute);
} else if (routeSettings.name == Routes.editProfileRoute) {
return pageRouteCustom(const EditProfileView(),
nameRoute: Routes.editProfileRoute);
EditProfileArguments args =
routeSettings.arguments as EditProfileArguments;
return pageRouteCustom(
EditProfileView(
profile: args.profile,
onSuccessUpdate: args.onSuccessUpdate,
),
nameRoute: Routes.editProfileRoute,
routeSettings: routeSettings,
);
} else if (routeSettings.name == Routes.reimburseRoute) {
return pageRouteCustom(const ReimbursementView(),
nameRoute: Routes.reimburseRoute);
......@@ -134,6 +144,7 @@ class RouteGenerator {
pageBuilder: (context, a, b) => OtpVerificationView(
id: args.id,
phone: args.phone,
otpExpiredTime: args.otpExpiredTime,
),
transitionDuration: Duration.zero,
reverseTransitionDuration: Duration.zero,
......@@ -153,6 +164,20 @@ class RouteGenerator {
settings: RouteSettings(name: nameRoute.replaceFirst("/", "")),
);
}
if (nameRoute == Routes.editProfileRoute) {
EditProfileArguments args =
routeSettings!.arguments as EditProfileArguments;
return PageRouteBuilder(
pageBuilder: (context, a, b) => EditProfileView(
profile: args.profile,
onSuccessUpdate: args.onSuccessUpdate,
),
transitionDuration: Duration.zero,
reverseTransitionDuration: Duration.zero,
settings: RouteSettings(name: nameRoute.replaceFirst("/", "")),
);
}
return PageRouteBuilder(
pageBuilder: (context, a, b) => target,
transitionDuration: Duration.zero,
......
......@@ -14,4 +14,11 @@ class Strings {
static String succesGetData = "Success get data";
static String pleaseWait = "Please wait...";
static String notFoundPage = 'Halaman yang anda cari tidak ditemukan';
static String sessionExpired =
"Sesi anda telah berakhir, silakan login kembali";
static String reimbursementNotFound =
"Reimbursement tidak ditemukan, silakan pilih filter tanggal yang lain";
static String transactionNotFound =
"Transaksi tidak ditemukan, silakan pilih filter tanggal yang lain";
}
......@@ -216,6 +216,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.0.17"
intl:
dependency: "direct main"
description:
name: intl
sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
url: "https://pub.dev"
source: hosted
version: "0.18.1"
js:
dependency: transitive
description:
......@@ -408,6 +416,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.2.0"
shimmer:
dependency: "direct main"
description:
name: shimmer
sha256: "5f88c883a22e9f9f299e5ba0e4f7e6054857224976a5d9f839d4ebdc94a14ac9"
url: "https://pub.dev"
source: hosted
version: "3.0.0"
sky_engine:
dependency: transitive
description: flutter
......
......@@ -37,8 +37,10 @@ dependencies:
flutter_native_splash: ^2.3.1
go_router: ^7.1.1
http: ^1.0.0
intl: ^0.18.1
package_info_plus: ^4.0.2
shared_preferences: ^2.1.1
shimmer: ^3.0.0
url_strategy: ^0.2.0
dev_dependencies:
......
Markdown is supported
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