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

all api implemented

parent 12f09488
import 'dart:convert'; import 'dart:convert';
import 'package:tour_travel_agr/api/response_api.dart'; import 'package:tour_travel_agr/api/response_api.dart';
import 'package:tour_travel_agr/helper/function/replace_date.dart';
import 'package:tour_travel_agr/helper/prefs.dart'; import 'package:tour_travel_agr/helper/prefs.dart';
import 'package:tour_travel_agr/main.dart'; import 'package:tour_travel_agr/main.dart';
import 'package:tour_travel_agr/models/profile_model.dart';
import 'package:tour_travel_agr/models/reimburse_model.dart';
import 'package:tour_travel_agr/models/transaction_model.dart';
import 'package:tour_travel_agr/resource/routes.dart'; import 'package:tour_travel_agr/resource/routes.dart';
import 'package:tour_travel_agr/resource/strings.dart'; import 'package:tour_travel_agr/resource/strings.dart';
...@@ -51,7 +55,7 @@ class Api { ...@@ -51,7 +55,7 @@ class Api {
Map<String, dynamic> data = { Map<String, dynamic> data = {
"name": name, "name": name,
"nik": nik, "nik": nik,
"mobile_phoen": mobile, "mobile_phone": mobile,
"password": password, "password": password,
"confirm_password": cPassword, "confirm_password": cPassword,
"brand_code": brandCode, "brand_code": brandCode,
...@@ -70,6 +74,7 @@ class Api { ...@@ -70,6 +74,7 @@ class Api {
if (jsonObject['status'] == 'ok') { if (jsonObject['status'] == 'ok') {
Map<String, dynamic> returnData = { Map<String, dynamic> returnData = {
"register_id": jsonObject['data']['register_id'], "register_id": jsonObject['data']['register_id'],
"can_resend_after": jsonObject['data']['can_resend_after'],
}; };
return ApiResponse( return ApiResponse(
error: false, error: false,
...@@ -100,7 +105,7 @@ class Api { ...@@ -100,7 +105,7 @@ class Api {
"brand_code": brandCode, "brand_code": brandCode,
}; };
String bodies = jsonEncode(data); String bodies = jsonEncode(data);
dynamic jsonObject = httpRequest( dynamic jsonObject = await httpRequest(
typePost, typePost,
apiUrl, apiUrl,
"forgotPassword", "forgotPassword",
...@@ -146,7 +151,10 @@ class Api { ...@@ -146,7 +151,10 @@ class Api {
return ApiResponse(error: true, msg: Strings.cantConnectToServer); return ApiResponse(error: true, msg: Strings.cantConnectToServer);
} else { } else {
if (jsonObject['status'] == 'ok') { if (jsonObject['status'] == 'ok') {
return ApiResponse(error: false, msg: "Success"); Map<String, dynamic> returnData = {
"can_resend_after": jsonObject['data']['can_resend_after'],
};
return ApiResponse(error: false, msg: "Success", data: returnData);
} else { } else {
return ApiResponse( return ApiResponse(
error: true, error: true,
...@@ -224,4 +232,257 @@ class Api { ...@@ -224,4 +232,257 @@ class Api {
return ApiResponse(error: true, msg: Strings.serverError); return ApiResponse(error: true, msg: Strings.serverError);
} }
} }
static Future<ApiResponse> confirmRegistration(
String regId, String code) async {
String apiUrl = "$baseUrl${endPoint}confirm_registration";
try {
Map<String, dynamic> data = {
"registration_id": regId,
"confirmation_number": code,
"brand_code": brandCode,
};
String bodies = jsonEncode(data);
dynamic jsonObject = await httpRequest(
typePost,
apiUrl,
"confirmRegistration",
bodies: bodies,
);
if (jsonObject == false) {
return ApiResponse(error: true, msg: Strings.cantConnectToServer);
} else {
if (jsonObject['status'] == 'ok') {
return ApiResponse(error: false, msg: "Success");
} else {
return ApiResponse(
error: true,
msg: jsonObject['msg'],
);
}
}
} catch (e) {
return ApiResponse(error: true, msg: Strings.serverError);
}
}
static Future<ApiResponse> getProfile() async {
String apiUrl = "$baseUrl${endPoint}profile";
try {
Map<String, dynamic> data = {
"session_id": getSessionId(),
"brand_code": brandCode,
};
String bodies = jsonEncode(data);
dynamic jsonObject = await httpRequest(
typePost,
apiUrl,
"getProfile",
bodies: bodies,
);
if (jsonObject == false) {
return ApiResponse(error: true, msg: Strings.cantConnectToServer);
} else {
if (jsonObject['status'] == 'ok') {
ProfileModel profile = ProfileModel.json(jsonObject['data']);
return ApiResponse(
error: false,
msg: jsonObject['msg'],
data: profile,
);
} else {
return ApiResponse(error: true, msg: jsonObject['msg'], data: {
"code": jsonObject["code"],
});
}
}
} catch (e) {
return ApiResponse(error: true, msg: Strings.serverError);
}
}
static Future<ApiResponse> reimburse(String? dateFrom, String? dateTo) async {
String apiUrl = "$baseUrl${endPoint}reimburse_list";
try {
Map<String, dynamic> data = {
"session_id": getSessionId(),
"date_from": (dateFrom == null)
? getOnlyDate(toInternationFormat(
dateLocal(DateTime.now().toLocal().toString())))
: getOnlyDate(toInternationFormat(dateFrom)),
"date_to": (dateTo == null)
? getOnlyDate(toInternationFormat(
dateLocal(DateTime.now().toLocal().toString())))
: getOnlyDate(toInternationFormat(dateTo)),
"brand_code": brandCode,
};
String bodies = jsonEncode(data);
dynamic jsonObject = await httpRequest(
typePost,
apiUrl,
"reimburse",
bodies: bodies,
);
if (jsonObject == false) {
return ApiResponse(error: true, msg: Strings.cantConnectToServer);
} else {
if (jsonObject['status'] == 'ok') {
List<ReimburseModel> dataReimburse = [];
List<dynamic> reimburse = jsonObject['data']['reimburses'];
for (int i = 0; i < reimburse.length; i++) {
dataReimburse.add(
ReimburseModel.json(
reimburse[i],
),
);
}
return ApiResponse(
error: false,
msg: jsonObject['msg'],
data: dataReimburse,
);
} else {
return ApiResponse(error: true, msg: jsonObject['msg'], data: {
"code": jsonObject["code"],
});
}
}
} catch (e) {
return ApiResponse(error: true, msg: Strings.serverError);
}
}
static Future<ApiResponse> transaction(
String? dateFrom, String? dateTo) async {
String apiUrl = "$baseUrl${endPoint}summary_list";
try {
Map<String, dynamic> data = {
"session_id": getSessionId(),
"date_from": (dateFrom == null)
? getOnlyDate(toInternationFormat(
dateLocal(DateTime.now().toLocal().toString())))
: getOnlyDate(toInternationFormat(dateFrom)),
"date_to": (dateTo == null)
? getOnlyDate(toInternationFormat(
dateLocal(DateTime.now().toLocal().toString())))
: getOnlyDate(toInternationFormat(dateTo)),
"brand": brandCode,
};
String bodies = jsonEncode(data);
dynamic jsonObject = await httpRequest(
typePost,
apiUrl,
"transaction",
bodies: bodies,
);
if (jsonObject == false) {
return ApiResponse(error: true, msg: Strings.cantConnectToServer);
} else {
if (jsonObject['status'] == 'ok') {
List<ListTransactionModel> listTransaction = [];
List<dynamic> transactions = jsonObject['data']['transactions'];
for (int i = 0; i < transactions.length; i++) {
listTransaction.add(ListTransactionModel.json(transactions[i]));
}
Map<String, dynamic> mapTransactionModel = {
"count_transaction":
jsonObject['data']['count_transaction'].toString(),
"total_transaction":
jsonObject['data']['total_transaction'].toString(),
"transactions": listTransaction,
};
TransactionModel dataTransaction =
TransactionModel.json(mapTransactionModel);
return ApiResponse(
error: false,
msg: jsonObject['msg'],
data: dataTransaction,
);
} else {
return ApiResponse(error: true, msg: jsonObject['msg'], data: {
"code": jsonObject["code"],
});
}
}
} catch (e) {
return ApiResponse(error: true, msg: Strings.serverError);
}
}
static Future<ApiResponse> changePassword(
String oldPassword, String newPassword, String cNewPassword) async {
String apiUrl = "$baseUrl${endPoint}change_password";
try {
Map<String, dynamic> data = {
"session_id": getSessionId(),
"old_password": oldPassword,
"password": newPassword,
"password_confirmation": cNewPassword,
"brand_code": brandCode,
};
String bodies = jsonEncode(data);
dynamic jsonObject = await httpRequest(
typePost,
apiUrl,
"changePassword",
bodies: bodies,
);
if (jsonObject == false) {
return ApiResponse(error: true, msg: Strings.cantConnectToServer);
} else {
if (jsonObject['status'] == 'ok') {
return ApiResponse(
error: false,
msg: "Berhasil ganti password",
);
} else {
return ApiResponse(error: true, msg: jsonObject['msg'], data: {
"code": jsonObject["code"],
});
}
}
} catch (e) {
return ApiResponse(error: true, msg: Strings.serverError);
}
}
static Future<ApiResponse> changeProfile(
String name, String nik, String phone, String? photo) async {
String apiUrl = "$baseUrl${endPoint}profile/edit";
try {
Map<String, dynamic> data = {
"session_id": getSessionId(),
"brand_code": brandCode,
"name": name,
"nik": nik,
"mobile_phone": phone,
"photo_base64": photo,
};
String bodies = jsonEncode(data);
dynamic jsonObject = await httpRequest(
typePost,
apiUrl,
"changeProfile",
bodies: bodies,
);
if (jsonObject == false) {
return ApiResponse(error: true, msg: Strings.cantConnectToServer);
} else {
if (jsonObject['status'] == 'ok') {
return ApiResponse(
error: false,
msg: "Berhasil ubah profile",
);
} else {
return ApiResponse(error: true, msg: jsonObject['msg'], data: {
"code": jsonObject["code"],
});
}
}
} catch (e) {
return ApiResponse(error: true, msg: Strings.serverError);
}
}
} }
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 { class VerificationArguments {
String id; String id;
String phone; String phone;
String otpExpiredTime;
VerificationArguments({ VerificationArguments({
required this.id, required this.id,
required this.phone, required this.phone,
required this.otpExpiredTime,
}); });
} }
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:shimmer/shimmer.dart';
import 'package:tour_travel_agr/resource/assets.dart'; import 'package:tour_travel_agr/resource/assets.dart';
import 'package:tour_travel_agr/resource/colors.dart'; import 'package:tour_travel_agr/resource/colors.dart';
import 'package:tour_travel_agr/resource/font.dart'; import 'package:tour_travel_agr/resource/font.dart';
...@@ -8,14 +9,14 @@ import 'package:tour_travel_agr/resource/style.dart'; ...@@ -8,14 +9,14 @@ import 'package:tour_travel_agr/resource/style.dart';
class ListTransaction extends StatelessWidget { class ListTransaction extends StatelessWidget {
const ListTransaction({ const ListTransaction({
super.key, super.key,
required this.date, this.date,
required this.title, this.title,
required this.subtitle, this.subtitle,
}); });
final String date; final String? date;
final String title; final String? title;
final String subtitle; final String? subtitle;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
...@@ -53,14 +54,27 @@ class ListTransaction extends StatelessWidget { ...@@ -53,14 +54,27 @@ class ListTransaction extends StatelessWidget {
Row( Row(
children: [ children: [
const Spacer(), const Spacer(),
Text( (date != null)
date, ? Text(
style: getRegularStyle( date!,
color: ColorManager.grey, style: getRegularStyle(
fontFamily: FontConstants.openSans, color: ColorManager.grey,
fontSize: FontSize.s12, 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( Row(
...@@ -93,21 +107,50 @@ class ListTransaction extends StatelessWidget { ...@@ -93,21 +107,50 @@ class ListTransaction extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( (title != null)
title, ? Text(
style: getBoldStyle( title!,
color: Colors.black, style: getBoldStyle(
fontFamily: FontConstants.mulish, color: Colors.black,
fontSize: 18, fontFamily: FontConstants.mulish,
), fontSize: 18,
), ),
Text( )
subtitle, : Shimmer.fromColors(
style: getSemiBoldStyle( baseColor: ColorManager.baseColorShimmer,
color: ColorManager.primary, highlightColor: ColorManager.highlightColorShimmer,
fontFamily: FontConstants.openSans, 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}) { ...@@ -69,14 +69,17 @@ String dateLocal(String dateTime, {bool fullDateTime = false}) {
String year = splitDate[0]; String year = splitDate[0];
String month = DateFormatCustom.monthLocal(splitDate[1]); String month = DateFormatCustom.monthLocal(splitDate[1]);
String tgl = splitDate[2]; String tgl = splitDate[2];
String result;
if (fullDateTime) { if (fullDateTime) {
return "$tgl $month $year ${split[1]}"; result = "$tgl $month $year ${split[1]}";
} else { } 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(" "); List<String> splitDate = dateLocal.split(" ");
String? time; String? time;
if (fullDateTime) { if (fullDateTime) {
...@@ -94,3 +97,9 @@ DateTime toInternationFormat(String dateLocal, {bool fullDateTime = false}) { ...@@ -94,3 +97,9 @@ DateTime toInternationFormat(String dateLocal, {bool fullDateTime = false}) {
} }
return result!; 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; ...@@ -10,7 +10,7 @@ late SharedPreferences prefs;
bool debug = true; bool debug = true;
String titleApp = 'Tour & Travel Agency'; String titleApp = 'Tour & Travel Agency';
String brandCode = 'AGR'; String brandCode = 'AGR';
String baseUrl = "https://hibiscus-dev.ravku.com/"; String baseUrl = "https://neo-agr.ravku.com/";
String endPoint = "agency/api/"; String endPoint = "agency/api/";
String initialRoute = Routes.splashRoute; String initialRoute = Routes.splashRoute;
......
...@@ -2,11 +2,13 @@ class ProfileModel { ...@@ -2,11 +2,13 @@ class ProfileModel {
String fullName; String fullName;
String mobilePhone; String mobilePhone;
String nik; String nik;
String avatarUrl;
ProfileModel({ ProfileModel({
required this.fullName, required this.fullName,
required this.mobilePhone, required this.mobilePhone,
required this.nik, required this.nik,
required this.avatarUrl,
}); });
factory ProfileModel.json(Map<String, dynamic> json) { factory ProfileModel.json(Map<String, dynamic> json) {
...@@ -14,6 +16,7 @@ class ProfileModel { ...@@ -14,6 +16,7 @@ class ProfileModel {
fullName: json['full_name'], fullName: json['full_name'],
mobilePhone: json['mobile_phone'], mobilePhone: json['mobile_phone'],
nik: json['nik'], nik: json['nik'],
avatarUrl: json['image_profile_url'] ?? "",
); );
} }
} }
class TransactionModel { class TransactionModel {
int transactionCount; String transactionCount;
String totalTransaction; String totalTransaction;
List<ListTransactionModel> listTransaction; List<ListTransactionModel> listTransaction;
......
// ignore_for_file: avoid_unnecessary_containers // ignore_for_file: avoid_unnecessary_containers
import 'package:flutter/material.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/api/all_api.dart';
import 'package:tour_travel_agr/helper/components_widget/custom_appbar.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_button.dart';
...@@ -10,6 +11,7 @@ import 'package:tour_travel_agr/helper/widget_responsive.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/assets.dart';
import 'package:tour_travel_agr/resource/colors.dart'; import 'package:tour_travel_agr/resource/colors.dart';
import 'package:tour_travel_agr/resource/size.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'; import 'package:tour_travel_agr/resource/style.dart';
class ForgotPasswordView extends StatefulWidget { class ForgotPasswordView extends StatefulWidget {
...@@ -146,10 +148,15 @@ class _ForgotPasswordViewState extends State<ForgotPasswordView> { ...@@ -146,10 +148,15 @@ class _ForgotPasswordViewState extends State<ForgotPasswordView> {
CustomButton( CustomButton(
text: "Submit", text: "Submit",
colorButton: (!buttonActive) ? Colors.grey : null, colorButton: (!buttonActive) ? Colors.grey : null,
onTap: () { onTap: () async {
if (buttonActive) { if (buttonActive) {
await EasyLoading.show(
status: Strings.pleaseWait,
maskType: EasyLoadingMaskType.none,
);
Api.forgotPassword(whatsappController.text) Api.forgotPassword(whatsappController.text)
.then((response) { .then((response) {
EasyLoading.dismiss();
modalDialogGlobal( modalDialogGlobal(
context: context, context: context,
title: (response.error) ? "Gagal" : "Berhasil", title: (response.error) ? "Gagal" : "Berhasil",
......
import 'package:flutter/material.dart'; 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/custom_appbar.dart';
import 'package:tour_travel_agr/helper/components_widget/modal_select_date.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/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/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/prefs.dart';
import 'package:tour_travel_agr/helper/widget_responsive.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/assets.dart';
import 'package:tour_travel_agr/resource/colors.dart'; import 'package:tour_travel_agr/resource/colors.dart';
import 'package:tour_travel_agr/resource/constanta_string.dart'; import 'package:tour_travel_agr/resource/constanta_string.dart';
import 'package:tour_travel_agr/resource/font.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/size.dart';
import 'package:tour_travel_agr/resource/strings.dart';
import 'package:tour_travel_agr/resource/style.dart'; import 'package:tour_travel_agr/resource/style.dart';
class HistoryView extends StatelessWidget { class HistoryView extends StatelessWidget {
...@@ -43,10 +51,23 @@ class _BodyWidgetState extends State<BodyWidget> { ...@@ -43,10 +51,23 @@ class _BodyWidgetState extends State<BodyWidget> {
bool? customDateActive; bool? customDateActive;
String? startDate; String? startDate;
String? endDate; String? endDate;
TransactionModel? transactions;
@override @override
void initState() { void initState() {
resetFilter(); checkSession().then((isLogin) {
if (isLogin) {
resetFilter().then((_) {
getTransactionData(startDate, endDate);
});
} else {
Navigator.pushNamedAndRemoveUntil(
context,
Routes.loginRoute,
(route) => false,
);
}
});
super.initState(); super.initState();
} }
...@@ -56,7 +77,7 @@ class _BodyWidgetState extends State<BodyWidget> { ...@@ -56,7 +77,7 @@ class _BodyWidgetState extends State<BodyWidget> {
super.dispose(); super.dispose();
} }
void resetFilter() { Future<void> resetFilter() async {
String reimburseDate = getHistoryDate(); String reimburseDate = getHistoryDate();
if (reimburseDate != '') { if (reimburseDate != '') {
List<String> split = reimburseDate.split(" - "); List<String> split = reimburseDate.split(" - ");
...@@ -79,6 +100,44 @@ class _BodyWidgetState extends State<BodyWidget> { ...@@ -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 @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
...@@ -130,10 +189,13 @@ class _BodyWidgetState extends State<BodyWidget> { ...@@ -130,10 +189,13 @@ class _BodyWidgetState extends State<BodyWidget> {
builder: (context) { builder: (context) {
return ModalSelectDate( return ModalSelectDate(
onTapWidget: () { onTapWidget: () {
Navigator.pop(context);
resetFilter();
setState(() { setState(() {
dateSelected = getHistoryDate(); dateSelected = getHistoryDate();
transactions = null;
});
Navigator.pop(context);
resetFilter().then((_) {
getTransactionData(startDate, endDate);
}); });
}, },
todayActive: todayActive!, todayActive: todayActive!,
...@@ -160,7 +222,9 @@ class _BodyWidgetState extends State<BodyWidget> { ...@@ -160,7 +222,9 @@ class _BodyWidgetState extends State<BodyWidget> {
text: "Transaksi", text: "Transaksi",
icon: Assets.moneyIcon, icon: Assets.moneyIcon,
iconColor: ColorManager.pink, iconColor: ColorManager.pink,
countText: "10", countText: (transactions == null)
? null
: transactions?.transactionCount.toString(),
countTextColor: ColorManager.primary, countTextColor: ColorManager.primary,
), ),
SizedBox( SizedBox(
...@@ -170,7 +234,10 @@ class _BodyWidgetState extends State<BodyWidget> { ...@@ -170,7 +234,10 @@ class _BodyWidgetState extends State<BodyWidget> {
text: "Total", text: "Total",
icon: Assets.totalIcon, icon: Assets.totalIcon,
iconColor: ColorManager.softGreen, iconColor: ColorManager.softGreen,
countText: "Rp 1.200.000", countText: (transactions == null)
? null
: parsingAmountBackend(
"Rp ${transactions?.totalTransaction}"),
countTextColor: ColorManager.green, countTextColor: ColorManager.green,
), ),
], ],
...@@ -179,17 +246,50 @@ class _BodyWidgetState extends State<BodyWidget> { ...@@ -179,17 +246,50 @@ class _BodyWidgetState extends State<BodyWidget> {
height: AppMargin.m20, height: AppMargin.m20,
), ),
Expanded( Expanded(
child: ListView.builder( child: (transactions == null)
padding: EdgeInsets.zero, ? ListView.builder(
itemCount: 10, padding: EdgeInsets.zero,
itemBuilder: (c, index) { itemCount: 10,
return const ListTransaction( itemBuilder: (c, index) {
date: "10 Maret 2023", return const ListTransaction(
title: "AGR Surabaya", date: null,
subtitle: "Rp 520.000", 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 { ...@@ -202,7 +302,7 @@ class WidgetHead extends StatelessWidget {
super.key, super.key,
required this.text, required this.text,
required this.icon, required this.icon,
required this.countText, this.countText,
required this.iconColor, required this.iconColor,
required this.countTextColor, required this.countTextColor,
}); });
...@@ -210,7 +310,7 @@ class WidgetHead extends StatelessWidget { ...@@ -210,7 +310,7 @@ class WidgetHead extends StatelessWidget {
final String text; final String text;
final String icon; final String icon;
final Color iconColor; final Color iconColor;
final String countText; final String? countText;
final Color countTextColor; final Color countTextColor;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
...@@ -270,14 +370,24 @@ class WidgetHead extends StatelessWidget { ...@@ -270,14 +370,24 @@ class WidgetHead extends StatelessWidget {
Row( Row(
children: [ children: [
const Spacer(), const Spacer(),
Text( (countText != null)
countText, ? Text(
style: getSemiBoldStyle( countText!,
color: countTextColor, style: getSemiBoldStyle(
fontSize: 16, color: countTextColor,
fontFamily: FontConstants.openSans, fontSize: 16,
), fontFamily: FontConstants.openSans,
) ),
)
: Shimmer.fromColors(
baseColor: ColorManager.baseColorShimmer,
highlightColor: ColorManager.highlightColorShimmer,
child: Container(
width: 25,
height: 15,
color: ColorManager.primary,
),
)
], ],
) )
], ],
......
...@@ -49,8 +49,10 @@ class BodyWidget extends StatefulWidget { ...@@ -49,8 +49,10 @@ class BodyWidget extends StatefulWidget {
class _BodyWidgetState extends State<BodyWidget> { class _BodyWidgetState extends State<BodyWidget> {
bool buttonLoginActive = false; bool buttonLoginActive = false;
bool alreadyLogin = true;
@override @override
void initState() { void initState() {
getProfileUser();
super.initState(); super.initState();
} }
...@@ -59,184 +61,208 @@ class _BodyWidgetState extends State<BodyWidget> { ...@@ -59,184 +61,208 @@ class _BodyWidgetState extends State<BodyWidget> {
super.dispose(); super.dispose();
} }
void getProfileUser() async {
Api.getProfile().then((apiResponse) {
if (apiResponse.error == false) {
Navigator.pushNamedAndRemoveUntil(
context,
Routes.homeRoute,
(route) => false,
);
} else {
setState(() {
alreadyLogin = false;
});
}
});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Stack( return (alreadyLogin == false)
children: [ ? Stack(
Container(
padding: EdgeInsets.only(
left: AppPadding.p20,
right: AppPadding.p20,
top: AppPadding.safeAreaTop(context),
bottom: AppPadding.safeAreaBot(context),
),
child: Column(
children: [ children: [
Center( Container(
child: Container( padding: EdgeInsets.only(
padding: const EdgeInsets.only( left: AppPadding.p20,
top: 40, right: AppPadding.p20,
), top: AppPadding.safeAreaTop(context),
child: Image( bottom: AppPadding.safeAreaBot(context),
width: 197,
height: 73,
image: AssetImage(
Assets.logoGreen,
),
),
), ),
), child: Column(
Expanded( children: [
child: SingleChildScrollView( Center(
child: Column( child: Container(
children: [ padding: const EdgeInsets.only(
const SizedBox( top: 40,
height: 148,
),
InputTextField(
controller: widget.whatsappController,
labelText: "No. Whatsapp",
hintText: "628...",
marginActive: false,
onChanged: (val) {
if (widget.whatsappController.text.length >= 7 &&
widget.passwordController.text.isNotEmpty) {
setState(() {
buttonLoginActive = true;
});
} else {
setState(() {
buttonLoginActive = false;
});
}
},
),
SizedBox(
height: AppMargin.m20,
),
PasswordInput(
passwordController: widget.passwordController,
onChanged: (val) {
if (widget.whatsappController.text.length >= 7 &&
widget.passwordController.text.isNotEmpty) {
setState(() {
buttonLoginActive = true;
});
} else {
setState(() {
buttonLoginActive = false;
});
}
},
),
Container(
margin: EdgeInsets.only(
top: AppMargin.m20,
bottom: AppMargin.m25,
), ),
child: Row( child: Image(
children: [ width: 197,
const Spacer(), height: 73,
GestureDetector( image: AssetImage(
onTap: () { Assets.logoGreen,
Navigator.pushNamed( ),
context,
Routes.forgotPasswordRoute,
);
},
child: Text(
"Lupa kata sandi",
style: getRegularStyle(
color: ColorManager.primary,
),
),
),
],
), ),
), ),
CustomButton( ),
text: "Login", Expanded(
colorButton: buttonLoginActive child: SingleChildScrollView(
? ColorManager.primary child: Column(
: Colors.grey,
onTap: () async {
if (buttonLoginActive) {
await EasyLoading.show(
status: Strings.pleaseWait,
maskType: EasyLoadingMaskType.none,
);
Api.login(
widget.whatsappController.text,
widget.passwordController.text,
).then((apiResponse) {
EasyLoading.dismiss();
if (apiResponse.error) {
modalDialogGlobal(
context: context,
size: MediaQuery.of(context).size,
title: "Gagal",
contentBody: apiResponse.msg,
buttonText: 'Ok',
tapButton: () {
Navigator.pop(context);
},
);
} else {
Navigator.pushNamedAndRemoveUntil(context,
Routes.homeRoute, (route) => false);
}
});
}
},
),
Container(
margin: const EdgeInsets.only(
top: 28,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Text( const SizedBox(
"Belum mempunyai akun ? ", height: 148,
style: getRegularStyle(
color: Colors.black,
),
), ),
GestureDetector( InputTextField(
onTap: () { controller: widget.whatsappController,
Navigator.pushNamed( labelText: "No. Whatsapp",
context, hintText: "628...",
Routes.registerRoute, marginActive: false,
); onChanged: (val) {
if (widget.whatsappController.text.length >=
7 &&
widget.passwordController.text.isNotEmpty) {
setState(() {
buttonLoginActive = true;
});
} else {
setState(() {
buttonLoginActive = false;
});
}
}, },
child: Text( ),
"Daftar", SizedBox(
style: getSemiBoldStyle( height: AppMargin.m20,
color: ColorManager.link, ),
), PasswordInput(
passwordController: widget.passwordController,
onChanged: (val) {
if (widget.whatsappController.text.length >=
7 &&
widget.passwordController.text.isNotEmpty) {
setState(() {
buttonLoginActive = true;
});
} else {
setState(() {
buttonLoginActive = false;
});
}
},
),
Container(
margin: EdgeInsets.only(
top: AppMargin.m20,
bottom: AppMargin.m25,
), ),
child: Row(
children: [
const Spacer(),
GestureDetector(
onTap: () {
Navigator.pushNamed(
context,
Routes.forgotPasswordRoute,
);
},
child: Text(
"Lupa kata sandi",
style: getRegularStyle(
color: ColorManager.primary,
),
),
),
],
),
),
CustomButton(
text: "Login",
colorButton: buttonLoginActive
? ColorManager.primary
: Colors.grey,
onTap: () async {
if (buttonLoginActive) {
await EasyLoading.show(
status: Strings.pleaseWait,
maskType: EasyLoadingMaskType.none,
);
Api.login(
widget.whatsappController.text,
widget.passwordController.text,
).then((apiResponse) {
EasyLoading.dismiss();
if (apiResponse.error) {
modalDialogGlobal(
context: context,
size: MediaQuery.of(context).size,
title: "Gagal",
contentBody: apiResponse.msg,
buttonText: 'Ok',
tapButton: () {
Navigator.pop(context);
},
);
} else {
Navigator.pushNamedAndRemoveUntil(context,
Routes.homeRoute, (route) => false);
}
});
}
},
), ),
Container(
margin: const EdgeInsets.only(
top: 28,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Belum mempunyai akun ? ",
style: getRegularStyle(
color: Colors.black,
),
),
GestureDetector(
onTap: () {
Navigator.pushNamed(
context,
Routes.registerRoute,
);
},
child: Text(
"Daftar",
style: getSemiBoldStyle(
color: ColorManager.link,
),
),
),
],
),
)
], ],
), ),
) ),
], )
],
),
),
Positioned(
top: 0,
left: 0,
child: Image(
height: 150,
image: AssetImage(
Assets.elipse,
), ),
), ),
) ),
], ],
), )
), : Center(
Positioned( child: CircularProgressIndicator(
top: 0, color: ColorManager.primary,
left: 0,
child: Image(
height: 150,
image: AssetImage(
Assets.elipse,
), ),
), );
),
],
);
} }
} }
// ignore_for_file: sized_box_for_whitespace, avoid_unnecessary_containers // ignore_for_file: sized_box_for_whitespace, avoid_unnecessary_containers
import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:tour_travel_agr/api/all_api.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/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/modal_dialog.dart';
import 'package:tour_travel_agr/helper/widget_responsive.dart'; import 'package:tour_travel_agr/helper/widget_responsive.dart';
import 'package:tour_travel_agr/resource/assets.dart'; import 'package:tour_travel_agr/resource/assets.dart';
...@@ -19,10 +22,12 @@ class OtpVerificationView extends StatefulWidget { ...@@ -19,10 +22,12 @@ class OtpVerificationView extends StatefulWidget {
super.key, super.key,
required this.id, required this.id,
required this.phone, required this.phone,
required this.otpExpiredTime,
}); });
final String id; final String id;
final String phone; final String phone;
final String otpExpiredTime;
@override @override
State<OtpVerificationView> createState() => _OtpVerificationViewState(); State<OtpVerificationView> createState() => _OtpVerificationViewState();
...@@ -113,7 +118,10 @@ class _OtpVerificationViewState extends State<OtpVerificationView> { ...@@ -113,7 +118,10 @@ class _OtpVerificationViewState extends State<OtpVerificationView> {
), ),
), ),
), ),
const CountDownTimeOtp(), CountDownTimeOtp(
idRegistration: widget.id,
otpExpiredTime: widget.otpExpiredTime,
),
Container( Container(
margin: EdgeInsets.only( margin: EdgeInsets.only(
top: AppMargin.m16, top: AppMargin.m16,
...@@ -184,7 +192,10 @@ class _OtpVerificationViewState extends State<OtpVerificationView> { ...@@ -184,7 +192,10 @@ class _OtpVerificationViewState extends State<OtpVerificationView> {
}); });
// ignore: use_build_context_synchronously // ignore: use_build_context_synchronously
FocusScope.of(context).unfocus(); FocusScope.of(context).unfocus();
Api.resendOtpVerification(widget.id).then((apiResponse) { Api.confirmRegistration(
widget.id,
finalText,
).then((apiResponse) {
EasyLoading.dismiss(); EasyLoading.dismiss();
if (apiResponse.error) { if (apiResponse.error) {
setState(() { setState(() {
...@@ -229,13 +240,61 @@ class _OtpVerificationViewState extends State<OtpVerificationView> { ...@@ -229,13 +240,61 @@ class _OtpVerificationViewState extends State<OtpVerificationView> {
class CountDownTimeOtp extends StatefulWidget { class CountDownTimeOtp extends StatefulWidget {
const CountDownTimeOtp({ const CountDownTimeOtp({
Key? key, Key? key,
required this.idRegistration,
required this.otpExpiredTime,
}) : super(key: key); }) : super(key: key);
final String idRegistration;
final String otpExpiredTime;
@override @override
State<CountDownTimeOtp> createState() => _CountDownTimeOtpState(); State<CountDownTimeOtp> createState() => _CountDownTimeOtpState();
} }
class _CountDownTimeOtpState extends State<CountDownTimeOtp> { 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 @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
...@@ -245,42 +304,70 @@ class _CountDownTimeOtpState extends State<CountDownTimeOtp> { ...@@ -245,42 +304,70 @@ class _CountDownTimeOtpState extends State<CountDownTimeOtp> {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Row( (isTimerExpired == false)
crossAxisAlignment: CrossAxisAlignment.center, ? Row(
children: [ crossAxisAlignment: CrossAxisAlignment.center,
Text( children: [
"00 :", Text(
style: getRegularStyle( "$hours :",
color: ColorManager.primary, style: getRegularStyle(
fontSize: 20, color: ColorManager.primary,
fontFamily: FontConstants.mulish, fontSize: 20,
), fontFamily: FontConstants.mulish,
), ),
Text( ),
" 02 :", Text(
style: getRegularStyle( " $minutes :",
color: ColorManager.primary, style: getRegularStyle(
fontSize: 20, color: ColorManager.primary,
fontFamily: FontConstants.mulish, fontSize: 20,
), fontFamily: FontConstants.mulish,
), ),
Text( ),
" 59", Text(
style: getRegularStyle( " $seconds",
color: ColorManager.primary, style: getRegularStyle(
fontSize: 20, color: ColorManager.primary,
fontFamily: FontConstants.mulish, 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/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/custom_appbar.dart';
import 'package:tour_travel_agr/helper/components_widget/password_input.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/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/helper/widget_responsive.dart';
import 'package:tour_travel_agr/resource/colors.dart'; import 'package:tour_travel_agr/resource/colors.dart';
import 'package:tour_travel_agr/resource/font.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/size.dart';
import 'package:tour_travel_agr/resource/strings.dart';
import 'package:tour_travel_agr/resource/style.dart'; import 'package:tour_travel_agr/resource/style.dart';
class ChangePasswordView extends StatefulWidget { class ChangePasswordView extends StatefulWidget {
...@@ -26,6 +35,15 @@ class _ChangePasswordViewState extends State<ChangePasswordView> { ...@@ -26,6 +35,15 @@ class _ChangePasswordViewState extends State<ChangePasswordView> {
bool buttonActive = false; bool buttonActive = false;
@override @override
void initState() { void initState() {
checkSession().then((isLogin) {
if (isLogin == false) {
Navigator.pushNamedAndRemoveUntil(
context,
Routes.loginRoute,
(route) => false,
);
}
});
super.initState(); super.initState();
} }
...@@ -130,7 +148,9 @@ class _ChangePasswordViewState extends State<ChangePasswordView> { ...@@ -130,7 +148,9 @@ class _ChangePasswordViewState extends State<ChangePasswordView> {
buttonActive = true; buttonActive = true;
}); });
} else { } else {
buttonActive = false; setState(() {
buttonActive = false;
});
} }
}, },
), ),
...@@ -141,9 +161,69 @@ class _ChangePasswordViewState extends State<ChangePasswordView> { ...@@ -141,9 +161,69 @@ class _ChangePasswordViewState extends State<ChangePasswordView> {
child: CustomButton( child: CustomButton(
text: "Update", text: "Update",
colorButton: (buttonActive) ? null : Colors.grey, colorButton: (buttonActive) ? null : Colors.grey,
onTap: () { onTap: () async {
if (buttonActive) { 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:file_picker/file_picker.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.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/custom_appbar.dart';
import 'package:tour_travel_agr/helper/components_widget/widget_button.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/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/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/assets.dart';
import 'package:tour_travel_agr/resource/colors.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/size.dart';
import 'package:tour_travel_agr/resource/strings.dart';
class EditProfileView extends StatefulWidget { 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 @override
State<EditProfileView> createState() => _EditProfileViewState(); State<EditProfileView> createState() => _EditProfileViewState();
} }
class _EditProfileViewState extends State<EditProfileView> { class _EditProfileViewState extends State<EditProfileView> {
final TextEditingController nameController = TextEditingController(); TextEditingController nameController = TextEditingController();
final TextEditingController nikController = TextEditingController(); TextEditingController nikController = TextEditingController();
final TextEditingController hpController = TextEditingController(); TextEditingController hpController = TextEditingController();
Uint8List? byteImage; 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 @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
...@@ -64,6 +91,7 @@ class _EditProfileViewState extends State<EditProfileView> { ...@@ -64,6 +91,7 @@ class _EditProfileViewState extends State<EditProfileView> {
// print(file); // print(file);
setState(() { setState(() {
byteImage = file.bytes; byteImage = file.bytes;
base64Image = base64Encode(byteImage!);
}); });
// print(file.path); // print(file.path);
} else { } else {
...@@ -124,8 +152,62 @@ class _EditProfileViewState extends State<EditProfileView> { ...@@ -124,8 +152,62 @@ class _EditProfileViewState extends State<EditProfileView> {
), ),
Container( Container(
margin: const EdgeInsets.only(top: 30), margin: const EdgeInsets.only(top: 30),
child: const CustomButton( child: CustomButton(
text: "Update", 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);
});
}
});
},
), ),
) )
], ],
......
// ignore_for_file: avoid_unnecessary_containers, sized_box_for_whitespace // ignore_for_file: avoid_unnecessary_containers, sized_box_for_whitespace
import 'package:flutter/material.dart'; 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/argument_route/edit_profile_arguments.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/prefs.dart';
import 'package:tour_travel_agr/helper/widget_responsive.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/assets.dart';
import 'package:tour_travel_agr/resource/colors.dart'; import 'package:tour_travel_agr/resource/colors.dart';
import 'package:tour_travel_agr/resource/font.dart'; import 'package:tour_travel_agr/resource/font.dart';
import 'package:tour_travel_agr/resource/routes.dart'; import 'package:tour_travel_agr/resource/routes.dart';
import 'package:tour_travel_agr/resource/size.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'; import 'package:tour_travel_agr/resource/style.dart';
class ProfileView extends StatelessWidget { class ProfileView extends StatelessWidget {
const ProfileView({super.key}); const ProfileView({
super.key,
});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
...@@ -25,11 +34,77 @@ class ProfileView extends StatelessWidget { ...@@ -25,11 +34,77 @@ class ProfileView extends StatelessWidget {
} }
} }
class BodyWidget extends StatelessWidget { class BodyWidget extends StatefulWidget {
const BodyWidget({ const BodyWidget({
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@override
State<BodyWidget> createState() => _BodyWidgetState();
}
class _BodyWidgetState extends State<BodyWidget> {
ProfileModel? profile;
@override
void initState() {
checkSession().then((isLogin) {
if (isLogin) {
getProfileUser();
} else {
Navigator.pushNamedAndRemoveUntil(
context,
Routes.loginRoute,
(route) => false,
);
}
});
super.initState();
}
@override
void dispose() {
super.dispose();
}
void getProfileUser() async {
Api.getProfile().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(() {
profile = apiResponse.data as ProfileModel;
});
}
});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Stack( return Stack(
...@@ -94,10 +169,22 @@ class BodyWidget extends StatelessWidget { ...@@ -94,10 +169,22 @@ class BodyWidget extends StatelessWidget {
const Spacer(), const Spacer(),
GestureDetector( GestureDetector(
onTap: () { onTap: () {
Navigator.pushNamed( if (profile != null) {
context, Navigator.pushNamed(
Routes.editProfileRoute, context,
); Routes.editProfileRoute,
arguments: EditProfileArguments(
profile: profile!,
onSuccessUpdate: ((isSuccess) {
if (isSuccess) {
setState(() {
profile == null;
});
getProfileUser();
}
})),
);
}
}, },
child: Container( child: Container(
width: 24, width: 24,
...@@ -116,41 +203,90 @@ class BodyWidget extends StatelessWidget { ...@@ -116,41 +203,90 @@ class BodyWidget extends StatelessWidget {
], ],
), ),
), ),
Container( (profile != null)
width: 120, ? Container(
height: 120, width: 120,
decoration: BoxDecoration( height: 120,
borderRadius: BorderRadius.circular( decoration: BoxDecoration(
100, borderRadius: BorderRadius.circular(
), 100,
image: DecorationImage( ),
fit: BoxFit.fill, image: (profile!.avatarUrl == "")
image: AssetImage( ? DecorationImage(
Assets.profileSample, fit: BoxFit.fill,
image: AssetImage(Assets.profileSample),
)
: DecorationImage(
fit: BoxFit.fill,
image: NetworkImage(profile!.avatarUrl),
),
),
)
: Shimmer.fromColors(
baseColor: ColorManager.baseColorShimmer,
highlightColor: ColorManager.highlightColorShimmer,
child: Container(
width: 120,
height: 120,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(
100,
),
image: DecorationImage(
fit: BoxFit.fill,
image: AssetImage(
Assets.profileSample,
),
),
),
),
), ),
),
),
),
SizedBox( SizedBox(
height: AppMargin.m16, height: AppMargin.m16,
), ),
Text( (profile != null)
"Dio Maulana", ? Text(
style: getSemiBoldStyle( profile!.fullName,
color: Colors.white, style: getSemiBoldStyle(
fontSize: 20, color: Colors.white,
), fontSize: 20,
), ),
)
: Shimmer.fromColors(
baseColor: ColorManager.baseColorShimmer,
highlightColor: ColorManager.highlightColorShimmer,
child: Container(
width: 200,
height: 15,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: ColorManager.green,
),
),
),
SizedBox( SizedBox(
height: AppMargin.m8, height: AppMargin.m8,
), ),
Text( (profile != null)
"ID 33040000000000000083", ? Text(
style: getRegularStyle( "NIK: ${profile!.nik}",
color: Colors.white, style: getRegularStyle(
fontSize: 12, color: Colors.white,
), fontSize: 12,
), ),
)
: Shimmer.fromColors(
baseColor: ColorManager.baseColorShimmer,
highlightColor: ColorManager.highlightColorShimmer,
child: Container(
width: 200,
height: 15,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: ColorManager.green,
),
),
),
const SizedBox( const SizedBox(
height: 40, height: 40,
), ),
...@@ -164,12 +300,26 @@ class BodyWidget extends StatelessWidget { ...@@ -164,12 +300,26 @@ class BodyWidget extends StatelessWidget {
Assets.phoneIcon, Assets.phoneIcon,
), ),
), ),
Text( (profile != null)
"+62-8127-535-1256", ? Text(
style: getRegularStyle( "+${profile!.mobilePhone}",
color: Colors.white, style: getRegularStyle(
), color: Colors.white,
) ),
)
: Shimmer.fromColors(
baseColor: ColorManager.baseColorShimmer,
highlightColor:
ColorManager.highlightColorShimmer,
child: Container(
width: 150,
height: 15,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: ColorManager.green,
),
),
)
], ],
) )
], ],
...@@ -177,10 +327,12 @@ class BodyWidget extends StatelessWidget { ...@@ -177,10 +327,12 @@ class BodyWidget extends StatelessWidget {
), ),
GestureDetector( GestureDetector(
onTap: () { onTap: () {
Navigator.pushNamed( if (profile != null) {
context, Navigator.pushNamed(
Routes.changePasswordRoute, context,
); Routes.changePasswordRoute,
);
}
}, },
child: ProfileButton( child: ProfileButton(
marginTop: 32, marginTop: 32,
...@@ -190,12 +342,14 @@ class BodyWidget extends StatelessWidget { ...@@ -190,12 +342,14 @@ class BodyWidget extends StatelessWidget {
), ),
GestureDetector( GestureDetector(
onTap: () { onTap: () {
removeSessionId(); if (profile != null) {
Navigator.pushNamedAndRemoveUntil( removeSessionId();
context, Navigator.pushNamedAndRemoveUntil(
Routes.loginRoute, context,
(route) => false, Routes.loginRoute,
); (route) => false,
);
}
}, },
child: ProfileButton( child: ProfileButton(
marginTop: 16, marginTop: 16,
......
...@@ -36,7 +36,7 @@ class _RegisterViewState extends State<RegisterView> { ...@@ -36,7 +36,7 @@ class _RegisterViewState extends State<RegisterView> {
TextEditingController(); TextEditingController();
bool isChecked = false; bool isChecked = false;
bool buttonRregisterActive = false; bool buttonRegisterActive = false;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
...@@ -121,7 +121,7 @@ class _RegisterViewState extends State<RegisterView> { ...@@ -121,7 +121,7 @@ class _RegisterViewState extends State<RegisterView> {
value: isChecked, value: isChecked,
onChanged: (bool? value) { onChanged: (bool? value) {
setState(() { setState(() {
buttonRregisterActive = value!; buttonRegisterActive = value!;
isChecked = value; isChecked = value;
}); });
}, },
...@@ -151,11 +151,11 @@ class _RegisterViewState extends State<RegisterView> { ...@@ -151,11 +151,11 @@ class _RegisterViewState extends State<RegisterView> {
), ),
child: CustomButton( child: CustomButton(
text: "Register", text: "Register",
colorButton: buttonRregisterActive colorButton: buttonRegisterActive
? ColorManager.primary ? ColorManager.primary
: Colors.grey, : Colors.grey,
onTap: () async { onTap: () async {
if (buttonRregisterActive) { if (buttonRegisterActive) {
if (nameController.text.isEmpty || if (nameController.text.isEmpty ||
nikController.text.isEmpty || nikController.text.isEmpty ||
noHpController.text.isEmpty || noHpController.text.isEmpty ||
...@@ -212,8 +212,10 @@ class _RegisterViewState extends State<RegisterView> { ...@@ -212,8 +212,10 @@ class _RegisterViewState extends State<RegisterView> {
context, context,
Routes.verificationRoute, Routes.verificationRoute,
arguments: VerificationArguments( arguments: VerificationArguments(
id: "ASAS", id: apiResponse.data['register_id'],
phone: noHpController.text, phone: noHpController.text,
otpExpiredTime:
apiResponse.data['can_resend_after'],
), ),
); );
}); });
......
// ignore_for_file: sized_box_for_whitespace // ignore_for_file: sized_box_for_whitespace
import 'package:flutter/material.dart'; 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/custom_appbar.dart';
import 'package:tour_travel_agr/helper/components_widget/modal_select_date.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/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/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/prefs.dart';
import 'package:tour_travel_agr/helper/widget_responsive.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/assets.dart';
import 'package:tour_travel_agr/resource/colors.dart'; import 'package:tour_travel_agr/resource/colors.dart';
import 'package:tour_travel_agr/resource/constanta_string.dart'; import 'package:tour_travel_agr/resource/constanta_string.dart';
import 'package:tour_travel_agr/resource/font.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/size.dart';
import 'package:tour_travel_agr/resource/strings.dart';
import 'package:tour_travel_agr/resource/style.dart'; import 'package:tour_travel_agr/resource/style.dart';
class ReimbursementView extends StatelessWidget { class ReimbursementView extends StatelessWidget {
...@@ -45,10 +52,25 @@ class _BodyWidgetState extends State<BodyWidget> { ...@@ -45,10 +52,25 @@ class _BodyWidgetState extends State<BodyWidget> {
bool? customDateActive; bool? customDateActive;
String? startDate; String? startDate;
String? endDate; String? endDate;
List<ReimburseModel>? dataReimburse;
bool responseApiError = false;
@override @override
void initState() { void initState() {
resetFilter(); checkSession().then((isLogin) {
if (isLogin) {
resetFilter().then((_) {
getReimburseData(startDate, endDate);
});
} else {
Navigator.pushNamedAndRemoveUntil(
context,
Routes.loginRoute,
(route) => false,
);
}
});
super.initState(); super.initState();
} }
...@@ -58,7 +80,45 @@ class _BodyWidgetState extends State<BodyWidget> { ...@@ -58,7 +80,45 @@ class _BodyWidgetState extends State<BodyWidget> {
super.dispose(); 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(); String reimburseDate = getReimburseDate();
if (reimburseDate != '') { if (reimburseDate != '') {
List<String> split = reimburseDate.split(" - "); List<String> split = reimburseDate.split(" - ");
...@@ -131,10 +191,13 @@ class _BodyWidgetState extends State<BodyWidget> { ...@@ -131,10 +191,13 @@ class _BodyWidgetState extends State<BodyWidget> {
builder: (context) { builder: (context) {
return ModalSelectDate( return ModalSelectDate(
onTapWidget: () { onTapWidget: () {
Navigator.pop(context);
resetFilter();
setState(() { setState(() {
dateSelected = getReimburseDate(); dateSelected = getReimburseDate();
dataReimburse = null;
});
Navigator.pop(context);
resetFilter().then((_) {
getReimburseData(startDate, endDate);
}); });
}, },
todayActive: todayActive!, todayActive: todayActive!,
...@@ -159,17 +222,50 @@ class _BodyWidgetState extends State<BodyWidget> { ...@@ -159,17 +222,50 @@ class _BodyWidgetState extends State<BodyWidget> {
height: 12, height: 12,
), ),
Expanded( Expanded(
child: ListView.builder( child: (dataReimburse == null)
padding: EdgeInsets.zero, ? ListView.builder(
itemCount: 10, padding: EdgeInsets.zero,
itemBuilder: (c, index) { itemCount: 5,
return const ListTransaction( itemBuilder: (c, index) {
date: "24 Maret 2023", return const ListTransaction(
title: "15 Transaksi", date: null,
subtitle: "Rp 320.000", 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/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:tour_travel_agr/api/all_api.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/argument_route/error_arguments.dart';
import 'package:tour_travel_agr/helper/components_widget/custom_appbar.dart'; import 'package:tour_travel_agr/helper/components_widget/custom_appbar.dart';
...@@ -10,6 +13,7 @@ import 'package:tour_travel_agr/resource/assets.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/colors.dart';
import 'package:tour_travel_agr/resource/routes.dart'; import 'package:tour_travel_agr/resource/routes.dart';
import 'package:tour_travel_agr/resource/size.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'; import 'package:tour_travel_agr/resource/style.dart';
class ResetPasswordView extends StatefulWidget { class ResetPasswordView extends StatefulWidget {
...@@ -166,14 +170,41 @@ class _ResetPasswordViewState extends State<ResetPasswordView> { ...@@ -166,14 +170,41 @@ class _ResetPasswordViewState extends State<ResetPasswordView> {
CustomButton( CustomButton(
text: "Submit", text: "Submit",
colorButton: (!buttonActive) ? Colors.grey : null, colorButton: (!buttonActive) ? Colors.grey : null,
onTap: () { onTap: () async {
if (buttonActive) { 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( Api.resetPassword(
widget.idPath, widget.idPath,
passwordController.text, passwordController.text,
newPasswordController.text, newPasswordController.text,
).then( ).then(
(apiResponse) { (apiResponse) {
EasyLoading.dismiss();
if (apiResponse.error) { if (apiResponse.error) {
modalDialogGlobal( modalDialogGlobal(
context: context, context: context,
......
...@@ -8,4 +8,6 @@ class ColorManager { ...@@ -8,4 +8,6 @@ class ColorManager {
static Color grey = const Color(0xff595959); static Color grey = const Color(0xff595959);
static Color softGreen = const Color(0xffA4D8C8); static Color softGreen = const Color(0xffA4D8C8);
static Color green = const Color(0xff3CA786); 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/material.dart';
import 'package:flutter/services.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/error_arguments.dart';
import 'package:tour_travel_agr/helper/argument_route/verification_otp.dart'; import 'package:tour_travel_agr/helper/argument_route/verification_otp.dart';
import 'package:tour_travel_agr/main.dart'; import 'package:tour_travel_agr/main.dart';
...@@ -54,6 +55,7 @@ class RouteGenerator { ...@@ -54,6 +55,7 @@ class RouteGenerator {
OtpVerificationView( OtpVerificationView(
id: args.id, id: args.id,
phone: args.phone, phone: args.phone,
otpExpiredTime: args.otpExpiredTime,
), ),
nameRoute: Routes.verificationRoute, nameRoute: Routes.verificationRoute,
routeSettings: routeSettings, routeSettings: routeSettings,
...@@ -92,8 +94,16 @@ class RouteGenerator { ...@@ -92,8 +94,16 @@ class RouteGenerator {
return pageRouteCustom(const ChangePasswordView(), return pageRouteCustom(const ChangePasswordView(),
nameRoute: Routes.changePasswordRoute); nameRoute: Routes.changePasswordRoute);
} else if (routeSettings.name == Routes.editProfileRoute) { } else if (routeSettings.name == Routes.editProfileRoute) {
return pageRouteCustom(const EditProfileView(), EditProfileArguments args =
nameRoute: Routes.editProfileRoute); routeSettings.arguments as EditProfileArguments;
return pageRouteCustom(
EditProfileView(
profile: args.profile,
onSuccessUpdate: args.onSuccessUpdate,
),
nameRoute: Routes.editProfileRoute,
routeSettings: routeSettings,
);
} else if (routeSettings.name == Routes.reimburseRoute) { } else if (routeSettings.name == Routes.reimburseRoute) {
return pageRouteCustom(const ReimbursementView(), return pageRouteCustom(const ReimbursementView(),
nameRoute: Routes.reimburseRoute); nameRoute: Routes.reimburseRoute);
...@@ -134,6 +144,7 @@ class RouteGenerator { ...@@ -134,6 +144,7 @@ class RouteGenerator {
pageBuilder: (context, a, b) => OtpVerificationView( pageBuilder: (context, a, b) => OtpVerificationView(
id: args.id, id: args.id,
phone: args.phone, phone: args.phone,
otpExpiredTime: args.otpExpiredTime,
), ),
transitionDuration: Duration.zero, transitionDuration: Duration.zero,
reverseTransitionDuration: Duration.zero, reverseTransitionDuration: Duration.zero,
...@@ -153,6 +164,20 @@ class RouteGenerator { ...@@ -153,6 +164,20 @@ class RouteGenerator {
settings: RouteSettings(name: nameRoute.replaceFirst("/", "")), 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( return PageRouteBuilder(
pageBuilder: (context, a, b) => target, pageBuilder: (context, a, b) => target,
transitionDuration: Duration.zero, transitionDuration: Duration.zero,
......
...@@ -14,4 +14,11 @@ class Strings { ...@@ -14,4 +14,11 @@ class Strings {
static String succesGetData = "Success get data"; static String succesGetData = "Success get data";
static String pleaseWait = "Please wait..."; static String pleaseWait = "Please wait...";
static String notFoundPage = 'Halaman yang anda cari tidak ditemukan'; 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: ...@@ -216,6 +216,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.0.17" version: "4.0.17"
intl:
dependency: "direct main"
description:
name: intl
sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
url: "https://pub.dev"
source: hosted
version: "0.18.1"
js: js:
dependency: transitive dependency: transitive
description: description:
...@@ -408,6 +416,14 @@ packages: ...@@ -408,6 +416,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.0" 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: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
......
...@@ -37,8 +37,10 @@ dependencies: ...@@ -37,8 +37,10 @@ dependencies:
flutter_native_splash: ^2.3.1 flutter_native_splash: ^2.3.1
go_router: ^7.1.1 go_router: ^7.1.1
http: ^1.0.0 http: ^1.0.0
intl: ^0.18.1
package_info_plus: ^4.0.2 package_info_plus: ^4.0.2
shared_preferences: ^2.1.1 shared_preferences: ^2.1.1
shimmer: ^3.0.0
url_strategy: ^0.2.0 url_strategy: ^0.2.0
dev_dependencies: 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