Initial commit: Penyerahan final Source code Tugas Akhir
This commit is contained in:
205
lib/screens/coupon/coupon_page.dart
Normal file
205
lib/screens/coupon/coupon_page.dart
Normal file
@ -0,0 +1,205 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:initial_folder/screens/coupon/success_radem_coupon_page.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:initial_folder/widgets/custom_navigator_bottom.dart';
|
||||
import 'package:initial_folder/widgets/login_regist/default_button.dart';
|
||||
import 'package:initial_folder/widgets/login_regist/loading_button.dart';
|
||||
import 'package:tap_debouncer/tap_debouncer.dart';
|
||||
|
||||
class CouponPage extends StatefulWidget {
|
||||
CouponPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<CouponPage> createState() => _CouponPageState();
|
||||
}
|
||||
|
||||
class _CouponPageState extends State<CouponPage> {
|
||||
final kuponController = TextEditingController();
|
||||
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
|
||||
bool isLoading = false;
|
||||
bool failed = false;
|
||||
String _iconPath = 'assets/icons/not_checklist.svg';
|
||||
String? errorMessage;
|
||||
|
||||
handleRadeem() {
|
||||
setState(() {
|
||||
isLoading = true;
|
||||
});
|
||||
|
||||
if (kuponController.text.isEmpty) {
|
||||
setState(() {
|
||||
isLoading = false;
|
||||
errorMessage = 'Kupon tidak boleh kosong';
|
||||
});
|
||||
} else if (kuponController.text.length <= 3) {
|
||||
setState(() {
|
||||
isLoading = false;
|
||||
errorMessage = 'Kupon tidak valid';
|
||||
});
|
||||
} else {
|
||||
setState(() {
|
||||
errorMessage = null;
|
||||
});
|
||||
Navigator.pushReplacement(
|
||||
context,
|
||||
CustomNavigatorBottom(
|
||||
child: SuccessRademCouponPage(
|
||||
coupon: kuponController.text,
|
||||
),
|
||||
),
|
||||
);
|
||||
setState(() {
|
||||
_iconPath = 'assets/icons/not_checklist.svg';
|
||||
isLoading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void _validateInputs() {
|
||||
if (this._formKey.currentState!.validate()) {
|
||||
handleRadeem();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
height: MediaQuery.of(context).viewInsets.bottom > 0
|
||||
? MediaQuery.of(context).size.height / 1.6
|
||||
: MediaQuery.of(context).size.height / 2.4,
|
||||
child: SingleChildScrollView(
|
||||
child: Center(
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(
|
||||
right: getProportionateScreenWidth(5),
|
||||
top: getProportionateScreenHeight(5),
|
||||
),
|
||||
child: IconButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
icon: Icon(Icons.close),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Text(
|
||||
'Tukarkan Voucher',
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(12)),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(5)),
|
||||
Text(
|
||||
'Masukkan kode voucher untuk klaim promo menarik dari\nVocasia',
|
||||
textAlign: TextAlign.center,
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize: getProportionateScreenWidth(10)),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(20)),
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(30)),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? seventeenColor
|
||||
: secondaryColor.withOpacity(0.3),
|
||||
),
|
||||
height: 40,
|
||||
child: Form(
|
||||
key: _formKey,
|
||||
child: TextFormField(
|
||||
autofocus: false,
|
||||
controller: kuponController,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
if (value.isEmpty) {
|
||||
_iconPath = 'assets/images/not_checklist.svg';
|
||||
} else if (value.length > 2) {
|
||||
_iconPath = 'assets/icons/checklist.svg';
|
||||
} else {
|
||||
_iconPath = 'assets/icons/wrong.svg';
|
||||
}
|
||||
});
|
||||
},
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
letterSpacing: 0.5,
|
||||
),
|
||||
cursorColor: secondaryColor,
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(color: sevenColor),
|
||||
borderRadius: BorderRadius.circular(10)),
|
||||
contentPadding: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(20),
|
||||
bottom: getProportionateScreenHeight(8),
|
||||
top: getProportionateScreenHeight(2),
|
||||
),
|
||||
hintText: 'Masukkan Kode Voucher',
|
||||
hintStyle: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12),
|
||||
color: secondaryColor,
|
||||
letterSpacing: 0.5,
|
||||
),
|
||||
suffixIcon: Transform.scale(
|
||||
scale: 0.5,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(
|
||||
right: getProportionateScreenWidth(15)),
|
||||
child: SvgPicture.asset(_iconPath),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(10)),
|
||||
if (errorMessage != null)
|
||||
Text(
|
||||
errorMessage!,
|
||||
style: TextStyle(color: Colors.red),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(16),
|
||||
right: getProportionateScreenWidth(16),
|
||||
top: getProportionateScreenHeight(10),
|
||||
),
|
||||
child: isLoading
|
||||
? LoadingButton(
|
||||
backgroundButtonColor: primaryColor,
|
||||
textButtonColor: Colors.white,
|
||||
)
|
||||
: TapDebouncer(
|
||||
cooldown: const Duration(milliseconds: 3000),
|
||||
onTap: () async => await {_validateInputs()},
|
||||
builder:
|
||||
(BuildContext context, TapDebouncerFunc? onTap) {
|
||||
return DefaultButton(
|
||||
text: 'Tukarkan',
|
||||
press: onTap,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
369
lib/screens/coupon/success_radem_coupon_page.dart
Normal file
369
lib/screens/coupon/success_radem_coupon_page.dart
Normal file
@ -0,0 +1,369 @@
|
||||
import 'package:cherry_toast/cherry_toast.dart';
|
||||
import 'package:cherry_toast/resources/arrays.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||
import 'package:initial_folder/base_service.dart';
|
||||
import 'package:initial_folder/helper/validator.dart';
|
||||
import 'package:initial_folder/models/discount_course_model.dart';
|
||||
import 'package:initial_folder/providers/search_provider.dart';
|
||||
import 'package:initial_folder/providers/total_price_provider.dart';
|
||||
import 'package:initial_folder/screens/detail_course/detail_course_voucher_screen.dart';
|
||||
import 'package:initial_folder/screens/home/components/body_comp/product_card/product_card_coupon.dart';
|
||||
import 'package:initial_folder/screens/search_course/component/filter.dart';
|
||||
import 'package:initial_folder/services/coupon_service.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:initial_folder/widgets/custom_navigator.dart';
|
||||
import 'package:initial_folder/widgets/search_not_found.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:initial_folder/providers/filters_course_provider.dart'
|
||||
as filterCourseProvider;
|
||||
import 'package:initial_folder/providers/coupon_course_provider.dart'
|
||||
as couponProv;
|
||||
|
||||
class SuccessRademCouponPage extends StatefulWidget {
|
||||
const SuccessRademCouponPage({
|
||||
required this.coupon,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
final coupon;
|
||||
|
||||
@override
|
||||
State<SuccessRademCouponPage> createState() => _SuccessRademCouponPageState();
|
||||
}
|
||||
|
||||
class _SuccessRademCouponPageState extends State<SuccessRademCouponPage> {
|
||||
bool _hasShownErrorToast = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final selected = Provider.of<TotalPriceProvider>(context);
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
scrolledUnderElevation: 0.0,
|
||||
backgroundColor: Theme.of(context).colorScheme.background,
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
child: ChangeNotifierProvider(
|
||||
create: (_) => couponProv.CouponCourseProvider(
|
||||
couponService: CouponService(), coupon: widget.coupon),
|
||||
child: Consumer<couponProv.CouponCourseProvider>(
|
||||
builder: (context, state, _) {
|
||||
if (state.state == couponProv.ResultState.Loading) {
|
||||
return Container(
|
||||
height: MediaQuery.of(context).size.height,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
child: Center(
|
||||
child: CircularProgressIndicator(
|
||||
color: secondaryColor,
|
||||
strokeWidth: 2,
|
||||
),
|
||||
),
|
||||
);
|
||||
} else if (state.state == couponProv.ResultState.HasData) {
|
||||
_hasShownErrorToast = false;
|
||||
if (state.result is List) {
|
||||
List<DiscountCourseModel> discountCourse = state.result;
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(height: getProportionateScreenHeight(10)),
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(16)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
height: getProportionateScreenHeight(110),
|
||||
width: MediaQuery.of(context).size.width,
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: getProportionateScreenWidth(8),
|
||||
vertical: getProportionateScreenHeight(16)),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).brightness ==
|
||||
Brightness.dark
|
||||
? fifteenColor
|
||||
: baruTextutih,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.25),
|
||||
spreadRadius: 0,
|
||||
blurRadius: 4,
|
||||
offset: Offset(0, 4),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
'Voucher Berhasil DItukar',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: semiBold,
|
||||
fontSize:
|
||||
getProportionateScreenWidth(12)),
|
||||
),
|
||||
Text(
|
||||
'Ayo pilih kursus yang sesuai dengan keinginan kamu',
|
||||
style: thirdTextStyle.copyWith(
|
||||
fontWeight: reguler,
|
||||
fontSize:
|
||||
getProportionateScreenWidth(10)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// SizedBox(height: getProportionateScreenHeight(15)),
|
||||
// PreferredSize(
|
||||
// preferredSize: Size.fromHeight(
|
||||
// getProportionateScreenWidth(57)),
|
||||
// child: AppBar(
|
||||
// automaticallyImplyLeading: false,
|
||||
// scrolledUnderElevation: 0,
|
||||
// backgroundColor:
|
||||
// Theme.of(context).colorScheme.background,
|
||||
// leadingWidth: 30,
|
||||
// actions: [
|
||||
// IconButton(
|
||||
// padding: EdgeInsets.zero,
|
||||
// onPressed: () => Navigator.of(context,
|
||||
// rootNavigator: true)
|
||||
// .push(
|
||||
// CustomNavigator(
|
||||
// child: const Filter(),
|
||||
// ),
|
||||
// ),
|
||||
// icon: Icon(
|
||||
// Icons.tune_rounded,
|
||||
// color: primaryColor,
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// title: Container(
|
||||
// decoration: BoxDecoration(
|
||||
// borderRadius: BorderRadius.circular(10),
|
||||
// color: Theme.of(context).brightness ==
|
||||
// Brightness.dark
|
||||
// ? seventeenColor
|
||||
// : secondaryColor.withOpacity(0.3),
|
||||
// ),
|
||||
// height: 40,
|
||||
// child: Consumer<SearchProvider>(
|
||||
// builder: (context, state, _) => TextField(
|
||||
// autofocus: false,
|
||||
// onSubmitted: (value) {
|
||||
// Provider.of<
|
||||
// filterCourseProvider
|
||||
// .FilterCourseProvider>(
|
||||
// context,
|
||||
// listen: false)
|
||||
// .isSearchsFalse();
|
||||
// filterCourseProvider
|
||||
// .FilterCourseProvider
|
||||
// filterCourseProv = Provider.of<
|
||||
// filterCourseProvider
|
||||
// .FilterCourseProvider>(
|
||||
// context,
|
||||
// listen: false);
|
||||
// state.searchText =
|
||||
// validatorSearch(value);
|
||||
// state.initSearchCourse(
|
||||
// price: filterCourseProv
|
||||
// .currentIndexPrice,
|
||||
// level:
|
||||
// filterCourseProv.levels.join(','),
|
||||
// rating: filterCourseProv
|
||||
// .currentIndexRating,
|
||||
// );
|
||||
// },
|
||||
// style: primaryTextStyle.copyWith(
|
||||
// fontSize:
|
||||
// getProportionateScreenWidth(14),
|
||||
// letterSpacing: 0.5,
|
||||
// ),
|
||||
// onChanged: (value) {
|
||||
// state.searchText =
|
||||
// validatorSearch(value);
|
||||
// },
|
||||
// cursorColor: secondaryColor,
|
||||
// decoration: InputDecoration(
|
||||
// border: InputBorder.none,
|
||||
// errorBorder: OutlineInputBorder(
|
||||
// borderSide:
|
||||
// BorderSide(color: sevenColor),
|
||||
// borderRadius:
|
||||
// BorderRadius.circular(10)),
|
||||
// contentPadding: EdgeInsets.only(
|
||||
// top: getProportionateScreenHeight(
|
||||
// 2)),
|
||||
// prefixIcon: Icon(
|
||||
// FeatherIcons.search,
|
||||
// size: 20,
|
||||
// color: primaryColor,
|
||||
// ),
|
||||
// hintText: 'Cari Kursus',
|
||||
// hintStyle: primaryTextStyle.copyWith(
|
||||
// fontSize:
|
||||
// getProportionateScreenWidth(12),
|
||||
// color: secondaryColor,
|
||||
// letterSpacing: 0.5,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
SizedBox(height: getProportionateScreenHeight(24)),
|
||||
Text(
|
||||
'Kursus Terkait',
|
||||
textAlign: TextAlign.start,
|
||||
style: thirdTextStyle.copyWith(
|
||||
letterSpacing: 1,
|
||||
fontWeight: semiBold,
|
||||
fontSize: getProportionateScreenWidth(14)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: getProportionateScreenHeight(16)),
|
||||
GridView.builder(
|
||||
padding: EdgeInsets.only(
|
||||
right: getProportionateScreenWidth(20),
|
||||
left: getProportionateScreenWidth(5),
|
||||
bottom: getProportionateScreenHeight(13),
|
||||
),
|
||||
physics: ScrollPhysics(),
|
||||
shrinkWrap: true,
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 2,
|
||||
childAspectRatio: discountCourse[0].typeCoupon == "1"
|
||||
? 3.1 / 4
|
||||
: 2.8 / 4,
|
||||
crossAxisSpacing: 16,
|
||||
mainAxisSpacing: 14,
|
||||
),
|
||||
itemCount: discountCourse.length,
|
||||
itemBuilder: (context, index) {
|
||||
var course = discountCourse[index];
|
||||
var finalPriceReal =
|
||||
course.finalPrice.toString().replaceAll(".", "");
|
||||
return Container(
|
||||
margin: EdgeInsets.only(
|
||||
bottom: getProportionateScreenHeight(12)),
|
||||
child: ProductCardCoupon(
|
||||
totalDiscount: int.parse(course.value!) > 99 ||
|
||||
course.typeCoupon == "1"
|
||||
? 0
|
||||
: int.parse(course.value!),
|
||||
students: course.students ?? '0',
|
||||
id: course.idCourse,
|
||||
thumbnail: course.thumbnail ??
|
||||
'$baseUrl/uploads/courses_thumbnail/course_thumbnail_default_57.jpg',
|
||||
title: course.title,
|
||||
instructorName: course.instructorName,
|
||||
specificRating: (course.rating.isNotEmpty &&
|
||||
course.rating[0]?.avgRating != null)
|
||||
? course.rating[0]!.avgRating.toString()
|
||||
: '0',
|
||||
rating: (course.rating.isNotEmpty &&
|
||||
course.rating[0]?.avgRating != null)
|
||||
? course.rating[0]!.avgRating.toString()
|
||||
: '5.0',
|
||||
numberOfRatings: (course.rating.isNotEmpty &&
|
||||
course.rating[0]?.totalReview != null)
|
||||
? course.rating[0]!.totalReview!
|
||||
: '0',
|
||||
isTopCourse: course.topCourse ?? '',
|
||||
price: (course.finalPrice.toString() == '0')
|
||||
? 'Gratis'
|
||||
: numberFormat(course.finalPrice.toString()),
|
||||
realPrice: (course.price == '0')
|
||||
? ''
|
||||
: course.typeCoupon != "1"
|
||||
? numberFormat(course.price)
|
||||
: "",
|
||||
press: () {
|
||||
selected.selectedPriceCoupon =
|
||||
int.parse(course.price);
|
||||
selected.selectedTypeCoupon =
|
||||
course.typeCoupon.toString();
|
||||
selected.selectedCouponText = widget.coupon;
|
||||
selected.selectedFinalPriceCoupon =
|
||||
int.parse(finalPriceReal);
|
||||
selected.selectedTotalPrice =
|
||||
int.parse(finalPriceReal);
|
||||
selected.selectedPotonganKupon = int.parse(
|
||||
course.hargaTotalDiscount.toString());
|
||||
selected.selectedValuePrice =
|
||||
course.value.toString();
|
||||
Navigator.of(context, rootNavigator: true).push(
|
||||
CustomNavigator(
|
||||
child: DetailVoucherScreen(
|
||||
idcourse: course.idCourse,
|
||||
coupon: widget.coupon,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
)
|
||||
],
|
||||
);
|
||||
} else if (state.result is String) {
|
||||
String message = state.result;
|
||||
|
||||
return Center(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(15),
|
||||
right: getProportionateScreenWidth(15),
|
||||
top: getProportionateScreenHeight(140),
|
||||
),
|
||||
child: Text(
|
||||
textAlign: TextAlign.center,
|
||||
message,
|
||||
style: thirdTextStyle,
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Center(child: Text(''));
|
||||
}
|
||||
} else if (state.state == couponProv.ResultState.NoData) {
|
||||
_hasShownErrorToast = false;
|
||||
return SearchNotFound();
|
||||
} else if (state.state == couponProv.ResultState.Error) {
|
||||
if (!_hasShownErrorToast) {
|
||||
_hasShownErrorToast = true;
|
||||
Future.delayed(Duration.zero, () {
|
||||
Navigator.pop(context);
|
||||
CherryToast.error(
|
||||
animationDuration: Durations.long1,
|
||||
title: Text(
|
||||
"Kupon Tidak Valid",
|
||||
style: TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
animationType: AnimationType.fromTop,
|
||||
).show(context);
|
||||
});
|
||||
}
|
||||
return SearchNotFound();
|
||||
} else {
|
||||
return Center(child: Text(''));
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user