Compare commits

..

16 Commits

Author SHA1 Message Date
89a79276a6 feat: new icon bottom navigation bar 2024-02-20 19:33:32 +07:00
4737a91ab1 Merge pull request 'bayu/dev' (#15) from bayu/dev into dev
Reviewed-on: #15
2024-02-20 18:49:59 +07:00
ff135dd47b fix: styling 2024-02-20 18:49:14 +07:00
2e98c1a234 fix: rotate photo selfie 2024-02-20 18:21:04 +07:00
c4c0479341 fix: add validation submit sign in 2024-02-20 15:38:21 +07:00
e510aaefd7 fix: widget overflow 2024-02-20 15:22:05 +07:00
dfb947dce5 fix: widget overflow 2024-02-20 15:14:25 +07:00
9761dc369c feat: profile and transaction page 2024-02-20 14:53:30 +07:00
9e2304990c feat: login gmail 2024-02-20 14:43:43 +07:00
8b1b3e950f Merge branch 'dev' of https://git.empatnusabangsa.com/nugrohob825/cims_apps into bayu/dev 2024-02-20 12:06:56 +07:00
aa987fe320 Merge pull request 'yoga' (#14) from yoga into dev
Reviewed-on: #14
2024-02-20 12:02:39 +07:00
ad6195061d fix: widget overflow 2024-02-20 10:24:32 +07:00
b5a382ce96 Merge pull request 'bayu/dev' (#13) from bayu/dev into dev
Reviewed-on: #13
2024-02-19 22:51:02 +07:00
fdca27233b fix: registration features 2024-02-19 22:50:07 +07:00
bd065242e6 feat: component date picker 2024-02-19 22:49:43 +07:00
a35110af71 fix: stepper registration 2024-02-19 21:47:46 +07:00
32 changed files with 1238 additions and 773 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 899 B

View File

@ -49,6 +49,11 @@ class PathAssets {
static const String iconTicket = 'assets/icons/icon-ticket.png'; static const String iconTicket = 'assets/icons/icon-ticket.png';
static const String iconGadget = 'assets/icons/icon-gadget.png'; static const String iconGadget = 'assets/icons/icon-gadget.png';
static const String iconCar = 'assets/icons/icon-car.png'; static const String iconCar = 'assets/icons/icon-car.png';
static const String iconNavigationHome = 'assets/icons/icon-navigation-home.png';
static const String iconNavigationPlan = 'assets/icons/icon-navigation-plan.png';
static const String iconNavigationTransaction = 'assets/icons/icon-navigation-transaction.png';
static const String iconNavigationPortfolio = 'assets/icons/icon-navigation-portfolio.png';
static const String iconNavigationProfile = 'assets/icons/icon-navigation-profile.png';
/// IMAGE /// IMAGE
static const String imgSplashLogo = 'assets/images/splash-logo.png'; static const String imgSplashLogo = 'assets/images/splash-logo.png';

View File

@ -0,0 +1,144 @@
import 'package:calendar_date_picker2/calendar_date_picker2.dart';
import 'package:cims_apps/application/component/button/button_view.dart';
import 'package:cims_apps/application/component/text_form/text_form_view.dart';
import 'package:cims_apps/application/theme/color_palette.dart';
import 'package:cims_apps/core/utils/size_config.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class DatePickerView extends StatelessWidget {
final String name;
final TextEditingController ctrl;
final DateTime? minDate, maxDate;
final String? hintText, buttonName;
final bool isMultipleSelection, enabled;
final List<DateTime>? initialValue;
final ValueChanged<OnChangedDatePickerModel>? onChanged;
final ValueChanged<List<DateTime?>>? onFinish;
final FormFieldValidator<String>? validatorDate;
const DatePickerView(
{Key? key,
required this.name,
required this.ctrl,
this.minDate,
this.maxDate,
this.hintText,
this.buttonName,
required this.isMultipleSelection,
required this.enabled,
this.initialValue,
this.onChanged,
this.onFinish,
this.validatorDate})
: super(key: key);
String _dateFormat(DateTime? dateTime) =>
dateTime != null ? DateFormat('dd/MM/yyyy').format(dateTime) : "";
@override
Widget build(BuildContext context) {
List<DateTime?> initData = initialValue ?? [];
List<DateTime?> dateList = [];
String dateLabel() {
return dateList.map((e) => _dateFormat(e)).join(" - ");
}
onChangedDatePicker(List<DateTime?> value) {
if (isMultipleSelection) {
final pickerDateRange = PickerDateRange(
startDate: value[0] ?? DateTime.now(),
endDate:
value.length > 1 ? value[1] ?? DateTime.now() : DateTime.now(),
);
onChanged
?.call(OnChangedDatePickerModel(pickerDateRange: pickerDateRange));
} else {
onChanged?.call(OnChangedDatePickerModel(dateTime: value[0]));
}
dateList = value;
}
dialogDatePicker() {
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (BuildContext context) {
return Container(
padding: const EdgeInsets.only(top: 16.0),
height: SizeConfig.height * .65,
child: Column(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.min,
children: [
CalendarDatePicker2(
value: [...initData],
config: CalendarDatePicker2Config(
centerAlignModePicker: true,
calendarType: isMultipleSelection
? CalendarDatePicker2Type.range
: CalendarDatePicker2Type.single,
customModePickerIcon: const SizedBox(),
firstDate: minDate ?? DateTime(1900),
lastDate: maxDate,
),
// initialValue: [...initData],
onValueChanged: (value) {
onChangedDatePicker(value);
},
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: ButtonView(
width: SizeConfig.width,
onPressed: () {
if (dateList.isNotEmpty) {
onFinish?.call(dateList);
ctrl.text = dateLabel();
initData = dateList;
}
Navigator.pop(context);
},
name: 'OK',
),
),
],
),
);
},
);
}
return TextFormView(
name: name,
hintText: hintText,
readOnly: true,
ctrl: ctrl,
validator: validatorDate,
enabled: enabled,
onTap: () {
if (enabled) dialogDatePicker();
},
suffixIcon: const UnconstrainedBox(
child: Icon(
Icons.calendar_today_rounded,
color: ColorPalette.slate400,
),
),
);
}
}
class OnChangedDatePickerModel {
final DateTime? dateTime;
final PickerDateRange? pickerDateRange;
OnChangedDatePickerModel({this.dateTime, this.pickerDateRange});
}
class PickerDateRange {
final DateTime startDate;
final DateTime endDate;
PickerDateRange({required this.startDate, required this.endDate});
}

View File

@ -24,11 +24,10 @@ class _TotalPaymentViewState extends State<TotalPaymentView> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return SingleChildScrollView(
child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: Colors.white, borderRadius: BorderRadius.circular(16)),
borderRadius: BorderRadius.circular(16)
),
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
@ -37,56 +36,54 @@ class _TotalPaymentViewState extends State<TotalPaymentView> {
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
const Text('Your Investment Today', const Text(
'Your Investment Today',
style: TextStyle( style: TextStyle(
color: ColorPalette.slate800, color: ColorPalette.slate800,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
fontSize: 16 fontSize: 16),
),
), ),
GestureDetector( GestureDetector(
onTap: () => Navigator.pop(context), onTap: () => Navigator.pop(context),
child: const Icon(Icons.close_rounded) child: const Icon(Icons.close_rounded))
)
], ],
), ),
), ),
...widget.listProduct.asMap().entries.map((e) { ...widget.listProduct.asMap().entries.map((e) {
return Container( return Container(
padding: const EdgeInsets.only(left: 16, right: 24, bottom: 16, top: 16), padding: const EdgeInsets.only(
left: 16, right: 24, bottom: 16, top: 16),
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border( border: Border(
left: BorderSide( left: BorderSide(
width: 8, width: 8,
color: ColorPalette.investTypeColor[e.value.type]! color:
) ColorPalette.investTypeColor[e.value.type]!))),
)
),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Expanded( Expanded(
flex: 5, flex: 5,
child: Text(e.value.name ?? '', child: Text(
e.value.name ?? '',
style: const TextStyle( style: const TextStyle(
color: ColorPalette.slate400, color: ColorPalette.slate400,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
fontSize: 16 fontSize: 16),
), )),
)
),
Expanded( Expanded(
flex: 7, flex: 7,
child: Text( child: Text(
NumberFormatter.numberCurrency(widget.totalInvest * e.value.totalPercent!, 'Rp ', 'id_ID'), NumberFormatter.numberCurrency(
widget.totalInvest * e.value.totalPercent!,
'Rp ',
'id_ID'),
textAlign: TextAlign.end, textAlign: TextAlign.end,
style: const TextStyle( style: const TextStyle(
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
fontSize: 18, fontSize: 18,
color: ColorPalette.slate800 color: ColorPalette.slate800),
), ))
)
)
], ],
), ),
); );
@ -97,44 +94,47 @@ class _TotalPaymentViewState extends State<TotalPaymentView> {
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text('Purchase Commission', Text(
'Purchase Commission',
style: TextStyle( style: TextStyle(
color: ColorPalette.slate400, color: ColorPalette.slate400,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
fontSize: 16 fontSize: 16),
), ),
), Text(
Text('Free', 'Free',
style: TextStyle( style: TextStyle(
color: ColorPalette.primary, color: ColorPalette.primary,
fontSize: 18, fontSize: 18,
fontWeight: FontWeight.w700 fontWeight: FontWeight.w700),
),
) )
], ],
), ),
), ),
const SizedBox(height: 16,), const SizedBox(
height: 16,
),
Container( Container(
color: ColorPalette.slate200.withOpacity(0.5), color: ColorPalette.slate200.withOpacity(0.5),
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16), padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
const Text('Total', const Text(
'Total',
style: TextStyle( style: TextStyle(
color: ColorPalette.slate400, color: ColorPalette.slate400,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
fontSize: 16 fontSize: 16),
), ),
), Text(
Text(NumberFormatter.numberCurrency(widget.totalInvest, 'Rp ', 'id_ID'), NumberFormatter.numberCurrency(
widget.totalInvest, 'Rp ', 'id_ID'),
textAlign: TextAlign.end, textAlign: TextAlign.end,
style: const TextStyle( style: const TextStyle(
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
fontSize: 18, fontSize: 18,
color: ColorPalette.slate800 color: ColorPalette.slate800),
),
) )
], ],
), ),
@ -145,20 +145,21 @@ class _TotalPaymentViewState extends State<TotalPaymentView> {
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
const Text('Total Payment', const Text(
'Total Payment',
style: TextStyle( style: TextStyle(
color: ColorPalette.slate400, color: ColorPalette.slate400,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
fontSize: 16 fontSize: 16),
), ),
), Text(
Text(NumberFormatter.numberCurrency(widget.totalInvest, 'Rp ', 'id_ID'), NumberFormatter.numberCurrency(
widget.totalInvest, 'Rp ', 'id_ID'),
textAlign: TextAlign.end, textAlign: TextAlign.end,
style: const TextStyle( style: const TextStyle(
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
fontSize: 18, fontSize: 18,
color: ColorPalette.slate800 color: ColorPalette.slate800),
),
) )
], ],
), ),
@ -167,7 +168,8 @@ class _TotalPaymentViewState extends State<TotalPaymentView> {
disabled: !isAgreement, disabled: !isAgreement,
name: 'Subscribe Now', name: 'Subscribe Now',
onPressed: () { onPressed: () {
routePush(context, page: PaymentMethodView( routePush(context,
page: PaymentMethodView(
totalInvest: widget.totalInvest, totalInvest: widget.totalInvest,
)); ));
}, },
@ -179,6 +181,7 @@ class _TotalPaymentViewState extends State<TotalPaymentView> {
) )
], ],
), ),
),
); );
} }
@ -205,48 +208,46 @@ class _TotalPaymentViewState extends State<TotalPaymentView> {
decoration: BoxDecoration( decoration: BoxDecoration(
shape: BoxShape.circle, shape: BoxShape.circle,
border: Border.all( border: Border.all(
color: isAgree ? ColorPalette.primary : ColorPalette.slate200 color: isAgree
) ? ColorPalette.primary
), : ColorPalette.slate200)),
child: AnimatedContainer( child: AnimatedContainer(
duration: const Duration(milliseconds: 200), duration: const Duration(milliseconds: 200),
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
color: isAgree ? ColorPalette.primary : ColorPalette.white, color:
shape: BoxShape.circle isAgree ? ColorPalette.primary : ColorPalette.white,
shape: BoxShape.circle),
), ),
), ),
), ),
), ),
const SizedBox(
width: 12,
), ),
const SizedBox(width: 12,),
Expanded( Expanded(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
const Text('I agree to buy the mutual fund on this page and have read and agreed to all the contents of the Prospectus and summary information and understand the risks of my investment decision.', const Text(
'I agree to buy the mutual fund on this page and have read and agreed to all the contents of the Prospectus and summary information and understand the risks of my investment decision.',
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: ColorPalette.slate400 color: ColorPalette.slate400),
),
), ),
GestureDetector( GestureDetector(
onTap: () { onTap: () {},
child: const Text(
}, 'Read More',
child: const Text('Read More',
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
decoration: TextDecoration.underline, decoration: TextDecoration.underline,
color: ColorPalette.primary color: ColorPalette.primary),
), ))
)
)
], ],
) ))
)
], ],
), ),
); );

View File

@ -12,6 +12,7 @@ import 'package:cims_apps/features/auth/registration/viewmodel/submission_data_v
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'dart:math' as math;
class DisplayPictureScreen extends StatefulWidget { class DisplayPictureScreen extends StatefulWidget {
final String imagePath, content; final String imagePath, content;
@ -106,7 +107,14 @@ class _DisplayPictureScreenState extends State<DisplayPictureScreen> {
SizedBox( SizedBox(
width: SizeConfig.width, width: SizeConfig.width,
height: SizeConfig.height * .4, height: SizeConfig.height * .4,
child: Image.file(File(widget.imagePath))), child: Transform(
alignment: Alignment.center,
transform: widget.content == 'selfie'
? Matrix4.rotationY(math.pi)
: Matrix4.rotationY(0),
child: Image.file(
File(widget.imagePath),
))),
const Padding( const Padding(
padding: EdgeInsets.symmetric(vertical: 16.0), padding: EdgeInsets.symmetric(vertical: 16.0),
child: Text( child: Text(

View File

@ -141,7 +141,7 @@ class TextFormView extends StatelessWidget {
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
fontSize: 14, fontSize: 14,
color: fontColorDisabled ?? ColorPalette.slate500, color: fontColorDisabled ?? ColorPalette.slate800,
), ),
readOnly: readOnly, readOnly: readOnly,
validator: validator, validator: validator,
@ -163,7 +163,7 @@ class TextFormView extends StatelessWidget {
hintStyle: hintTextStyle ?? hintStyle: hintTextStyle ??
const TextStyle( const TextStyle(
fontSize: 14, fontSize: 14,
color: ColorPalette.greyFont, color: ColorPalette.slate400,
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
), ),
isDense: true, isDense: true,

View File

@ -1,19 +1,12 @@
import 'package:cims_apps/application/assets/path_assets.dart';
import 'package:cims_apps/application/component/button/back_button_view.dart'; import 'package:cims_apps/application/component/button/back_button_view.dart';
import 'package:cims_apps/application/component/button/button_view.dart';
import 'package:cims_apps/application/component/image/image_view.dart';
import 'package:cims_apps/application/component/text_form/text_form_view.dart';
import 'package:cims_apps/application/component/text_title/text_title.dart';
import 'package:cims_apps/application/theme/color_palette.dart'; import 'package:cims_apps/application/theme/color_palette.dart';
import 'package:cims_apps/core/route/route.dart'; import 'package:cims_apps/core/route/route.dart';
import 'package:cims_apps/core/utils/size_config.dart'; import 'package:cims_apps/core/utils/size_config.dart';
import 'package:cims_apps/features/auth/login/view/password_view.dart'; import 'package:cims_apps/features/auth/login/view/password_view.dart';
import 'package:cims_apps/features/auth/login/view/phone_number_view.dart'; import 'package:cims_apps/features/auth/login/view/phone_number_view.dart';
import 'package:cims_apps/features/auth/login/view_model/login_view_model.dart'; import 'package:cims_apps/features/auth/login/view_model/login_view_model.dart';
import 'package:cims_apps/features/auth/registration/view/submission_data/risk_profile/risk_profile_view.dart';
import 'package:cims_apps/features/bottom_navigation_view.dart'; import 'package:cims_apps/features/bottom_navigation_view.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class LoginView extends StatefulWidget { class LoginView extends StatefulWidget {
@ -90,7 +83,11 @@ class _LoginViewState extends State<LoginView> {
currentPage++; currentPage++;
pageController.jumpToPage(1); pageController.jumpToPage(1);
} else { } else {
routePush(context, page: BottomNavigationView()); routePush(
context,
page: const BottomNavigationView(),
routeType: RouteType.pushReplace,
);
} }
} }
} }

View File

@ -10,16 +10,19 @@ import 'package:provider/provider.dart';
class PasswordView extends StatelessWidget { class PasswordView extends StatelessWidget {
final void Function() nextStep; final void Function() nextStep;
final TextEditingController controller; final TextEditingController controller;
const PasswordView({super.key, required this.nextStep, required this.controller}); const PasswordView(
{super.key, required this.nextStep, required this.controller});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Consumer<LoginViewModel>( return Consumer<LoginViewModel>(builder: (context, provider, child) {
builder: (context, provider, child) {
return Container( return Container(
width: SizeConfig.width, width: SizeConfig.width,
height: SizeConfig.height, height: SizeConfig.height,
padding: const EdgeInsets.all(24), padding: const EdgeInsets.all(24),
child: Form(
key: provider.formKey,
child: SingleChildScrollView(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -32,6 +35,15 @@ class PasswordView extends StatelessWidget {
ctrl: controller, ctrl: controller,
obscureText: !provider.showPassword, obscureText: !provider.showPassword,
contentPadding: EdgeInsets.all(12), contentPadding: EdgeInsets.all(12),
validator: (value) {
if (value!.isEmpty) {
return 'Password must filled';
} else if (value.length < 8) {
return 'Minimum password 8 Character';
} else {
return null;
}
},
suffixIcon: GestureDetector( suffixIcon: GestureDetector(
onTap: () { onTap: () {
provider.changeShowPassword(); provider.changeShowPassword();
@ -45,19 +57,14 @@ class PasswordView extends StatelessWidget {
), ),
), ),
TextButton( TextButton(
style: TextButton.styleFrom( style: TextButton.styleFrom(padding: EdgeInsets.all(0)),
padding: EdgeInsets.all(0) onPressed: () {},
),
onPressed: () {
},
child: Text( child: Text(
'Forget the password?', 'Forget the password?',
style: TextStyle( style: TextStyle(
color: ColorPalette.primary, color: ColorPalette.primary,
), ),
) )),
),
SizedBox( SizedBox(
height: 16, height: 16,
), ),
@ -67,13 +74,19 @@ class PasswordView extends StatelessWidget {
width: SizeConfig.width, width: SizeConfig.width,
textSize: 18, textSize: 18,
marginVertical: 0, marginVertical: 0,
contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 12), contentPadding:
onPressed: nextStep, EdgeInsets.symmetric(horizontal: 16, vertical: 12),
onPressed: () {
if (provider.formKey.currentState!.validate()) {
nextStep();
}
},
) )
], ],
), ),
),
),
); );
} });
);
} }
} }

View File

@ -1,31 +1,42 @@
import 'package:cims_apps/application/assets/path_assets.dart'; import 'package:cims_apps/application/assets/path_assets.dart';
import 'package:cims_apps/application/component/button/button_view.dart'; import 'package:cims_apps/application/component/button/button_view.dart';
import 'package:cims_apps/application/component/image/image_view.dart'; import 'package:cims_apps/application/component/image/image_view.dart';
import 'package:cims_apps/application/component/numeric_pad/numeric_pad.dart';
import 'package:cims_apps/application/component/text_form/text_form_view.dart'; import 'package:cims_apps/application/component/text_form/text_form_view.dart';
import 'package:cims_apps/application/component/text_title/text_title.dart'; import 'package:cims_apps/application/component/text_title/text_title.dart';
import 'package:cims_apps/application/theme/color_palette.dart'; import 'package:cims_apps/application/theme/color_palette.dart';
import 'package:cims_apps/core/route/route.dart'; import 'package:cims_apps/core/route/route.dart';
import 'package:cims_apps/core/utils/size_config.dart'; import 'package:cims_apps/core/utils/size_config.dart';
import 'package:cims_apps/features/auth/login/view_model/login_view_model.dart';
import 'package:cims_apps/features/auth/registration/view/registration_view.dart'; import 'package:cims_apps/features/auth/registration/view/registration_view.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
class PhoneNumberView extends StatelessWidget { class PhoneNumberView extends StatelessWidget {
final void Function() nextStep; final void Function() nextStep;
final TextEditingController controller; final TextEditingController controller;
const PhoneNumberView({super.key, required this.nextStep, required this.controller}); const PhoneNumberView(
{super.key, required this.nextStep, required this.controller});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => LoginViewModel(),
builder: (context, child) {
return Container( return Container(
width: SizeConfig.width, width: SizeConfig.width,
height: SizeConfig.height, height: SizeConfig.height,
padding: const EdgeInsets.all(24), padding: const EdgeInsets.all(24),
child:
Consumer<LoginViewModel>(builder: (context, provider, child) {
return Form(
key: provider.formKey,
child: SingleChildScrollView(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
const TextTitle(title: 'Enter your phone number', fontSize: 24), const TextTitle(
title: 'Enter your phone number', fontSize: 24),
SizedBox( SizedBox(
height: 24, height: 24,
), ),
@ -82,8 +93,13 @@ class PhoneNumberView extends StatelessWidget {
heightWrapContent: true, heightWrapContent: true,
width: SizeConfig.width, width: SizeConfig.width,
marginVertical: 0, marginVertical: 0,
contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 12), contentPadding: const EdgeInsets.symmetric(
onPressed: nextStep, horizontal: 16, vertical: 12),
onPressed: () {
if (provider.formKey.currentState!.validate()) {
nextStep();
}
},
), ),
Row( Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
@ -99,20 +115,21 @@ class PhoneNumberView extends StatelessWidget {
routePush(context, page: RegistrationView()); routePush(context, page: RegistrationView());
}, },
style: TextButton.styleFrom( style: TextButton.styleFrom(
padding: EdgeInsets.all(0) padding: EdgeInsets.all(0)),
),
child: Text( child: Text(
'Sign Up', 'Sign Up',
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: ColorPalette.primary color: ColorPalette.primary),
), ))
)
)
], ],
), ),
], ],
), ),
),
); );
}),
);
});
} }
} }

View File

@ -1,7 +1,8 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart';
class LoginViewModel extends ChangeNotifier { class LoginViewModel extends ChangeNotifier {
bool showPassword = false; bool showPassword = false;
var formKey = GlobalKey<FormState>();
void changeShowPassword() { void changeShowPassword() {
showPassword = !showPassword; showPassword = !showPassword;

View File

@ -6,7 +6,7 @@ import 'package:cims_apps/application/theme/color_palette.dart';
import 'package:cims_apps/core/route/route.dart'; import 'package:cims_apps/core/route/route.dart';
import 'package:cims_apps/core/utils/size_config.dart'; import 'package:cims_apps/core/utils/size_config.dart';
import 'package:cims_apps/features/auth/registration/view/submission_data/submission_parent.dart'; import 'package:cims_apps/features/auth/registration/view/submission_data/submission_parent.dart';
import 'package:cims_apps/features/dashboard/dashboard_public/view/dashboard_public_view.dart'; import 'package:cims_apps/features/bottom_navigation_view.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class InitialRegistrationStep extends StatelessWidget { class InitialRegistrationStep extends StatelessWidget {
@ -203,7 +203,7 @@ class InitialRegistrationStep extends StatelessWidget {
isOutlined: true, isOutlined: true,
onPressed: () { onPressed: () {
routePush(context, routePush(context,
page: const DashboardPublicView(), page: const BottomNavigationView(),
routeType: RouteType.pushReplace); routeType: RouteType.pushReplace);
}, },
), ),

View File

@ -45,7 +45,7 @@ class RegistrationPasswordView extends StatelessWidget {
validator: (value) { validator: (value) {
if (value!.isEmpty) { if (value!.isEmpty) {
return 'Password must filled'; return 'Password must filled';
} else if (value.length <= 8) { } else if (value.length < 8) {
return 'Minimum password 8 Character'; return 'Minimum password 8 Character';
} else { } else {
return null; return null;

View File

@ -29,7 +29,8 @@ class SubmitBankAccount extends StatelessWidget {
return SizedBox( return SizedBox(
child: Consumer<SubmissionDataViewModel>( child: Consumer<SubmissionDataViewModel>(
builder: (context, provider, child) { builder: (context, provider, child) {
return Column( return SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
const TextCaption(title: 'Input your bank account data'), const TextCaption(title: 'Input your bank account data'),
@ -43,13 +44,15 @@ class SubmitBankAccount extends StatelessWidget {
TextFormView( TextFormView(
name: 'Account Number', name: 'Account Number',
hintText: 'Input Account Number', hintText: 'Input Account Number',
keyboardType: TextInputType.number,
trailingTitleWidget: SizedBox( trailingTitleWidget: SizedBox(
width: 24, width: 24,
child: GestureDetector( child: GestureDetector(
onTap: () { onTap: () {
routePush(context, page: const GuideScreen()); routePush(context, page: const GuideScreen());
}, },
child: const ImageView(image: PathAssets.iconQuestion), child:
const ImageView(image: PathAssets.iconQuestion),
), ),
), ),
), ),
@ -69,12 +72,14 @@ class SubmitBankAccount extends StatelessWidget {
onPressed: () { onPressed: () {
provider.next(context).then((value) { provider.next(context).then((value) {
if (value) { if (value) {
routePush(context, page: const ConfirmBankAccount()); routePush(context,
page: const ConfirmBankAccount());
} }
}); });
}, },
) )
], ],
),
); );
}), }),
); );

View File

@ -24,13 +24,13 @@ class SubmissionParent extends StatefulWidget {
} }
class _SubmissionParentState extends State<SubmissionParent> { class _SubmissionParentState extends State<SubmissionParent> {
Widget _stepItem({bool isCurrentStep = false, bool isDone = false}) { Widget _stepItem({bool isCurrentStep = false}) {
return Container( return Container(
margin: const EdgeInsets.only(right: 0.0, left: 4.0), margin: const EdgeInsets.only(right: 0.0, left: 4.0),
height: 6, height: 6,
width: SizeConfig.width * .08, width: SizeConfig.width * .08,
decoration: BoxDecoration( decoration: BoxDecoration(
color: isCurrentStep || isDone color: isCurrentStep
? ColorPalette.primary ? ColorPalette.primary
: ColorPalette.greyBorderNeutrals, : ColorPalette.greyBorderNeutrals,
borderRadius: BorderRadius.circular(50), borderRadius: BorderRadius.circular(50),
@ -91,15 +91,10 @@ class _SubmissionParentState extends State<SubmissionParent> {
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: children:
List.generate(provider.stepAmount, (index) { List.generate(provider.stepAmount, (index) {
// print('indd $index');
// print(
// 'getCurrentStep ${provider.getCurrentStep}');
return _stepItem( return _stepItem(
isCurrentStep: provider.getCurrentStep == isCurrentStep:
index + 1 || provider.getCurrentStep == index + 1 ||
provider.getCurrentStep - 1 == index + 1, provider.getCurrentStep - 1 > index,
// isDone:
// index + 1 != provider.getCurrentStep + 1,
); );
}), }),
), ),

View File

@ -2,6 +2,7 @@ import 'dart:io';
import 'package:cims_apps/application/assets/path_assets.dart'; import 'package:cims_apps/application/assets/path_assets.dart';
import 'package:cims_apps/application/component/button/button_view.dart'; import 'package:cims_apps/application/component/button/button_view.dart';
import 'package:cims_apps/application/component/date_picker/date_picker_view.dart';
import 'package:cims_apps/application/component/image/image_view.dart'; import 'package:cims_apps/application/component/image/image_view.dart';
import 'package:cims_apps/application/component/text_caption/text_caption.dart'; import 'package:cims_apps/application/component/text_caption/text_caption.dart';
import 'package:cims_apps/application/component/text_form/text_form_view.dart'; import 'package:cims_apps/application/component/text_form/text_form_view.dart';
@ -12,6 +13,7 @@ import 'package:cims_apps/features/auth/registration/view/submission_data/submis
import 'package:cims_apps/features/auth/registration/viewmodel/submission_data_viewmodel.dart'; import 'package:cims_apps/features/auth/registration/viewmodel/submission_data_viewmodel.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'dart:math' as math;
class SubmitDataIdCard extends StatelessWidget { class SubmitDataIdCard extends StatelessWidget {
const SubmitDataIdCard({Key? key}) : super(key: key); const SubmitDataIdCard({Key? key}) : super(key: key);
@ -29,7 +31,7 @@ class SubmitDataIdCard extends StatelessWidget {
color: Colors.white, color: Colors.white,
borderRadius: borderRadius:
BorderRadius.vertical(top: Radius.circular(18))), BorderRadius.vertical(top: Radius.circular(18))),
height: SizeConfig.height * .32, height: SizeConfig.height * .35,
padding: const EdgeInsets.all(16.0), padding: const EdgeInsets.all(16.0),
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -107,17 +109,24 @@ class SubmitDataIdCard extends StatelessWidget {
SizedBox( SizedBox(
height: SizeConfig.height * .18, height: SizeConfig.height * .18,
width: SizeConfig.width * .45, width: SizeConfig.width * .45,
child: Transform(
alignment: Alignment.center,
transform: e.key == 'selfie'
? Matrix4.rotationY(math.pi)
: Matrix4.rotationY(0),
child: ClipRRect( child: ClipRRect(
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
child: Image.file( child: Image.file(
File(e.image), File(e.image),
fit: BoxFit.fill, fit: BoxFit.fill,
errorBuilder: (context, error, stackTrace) { errorBuilder: (context, error, stackTrace) {
return const Icon(Icons.image_not_supported_outlined); return const Icon(
Icons.image_not_supported_outlined);
}, },
), ),
), ),
), ),
),
SizedBox( SizedBox(
width: SizeConfig.width * .43, width: SizeConfig.width * .43,
child: Row( child: Row(
@ -172,15 +181,17 @@ class SubmitDataIdCard extends StatelessWidget {
children: [ children: [
const TextCaption( const TextCaption(
title: 'Check your ID card data for accuracy'), title: 'Check your ID card data for accuracy'),
TextFormView(name: 'NIK'),
TextFormView(name: 'Full Name'),
TextFormView( TextFormView(
name: 'NIK',
keyboardType: TextInputType.number,
),
TextFormView(name: 'Full Name'),
DatePickerView(
name: 'Birth Date', name: 'Birth Date',
suffixIcon: const Icon( ctrl: provider.ctrlBirthDate,
Icons.calendar_today_rounded, maxDate: DateTime.now(),
color: ColorPalette.slate400, isMultipleSelection: false,
), enabled: true),
),
photoDocument(provider), photoDocument(provider),
Container( Container(
width: SizeConfig.width, width: SizeConfig.width,

View File

@ -5,6 +5,7 @@ import 'package:cims_apps/application/component/text_caption/text_caption.dart';
import 'package:cims_apps/application/component/text_form/text_form_view.dart'; import 'package:cims_apps/application/component/text_form/text_form_view.dart';
import 'package:cims_apps/core/route/route.dart'; import 'package:cims_apps/core/route/route.dart';
import 'package:cims_apps/core/utils/size_config.dart'; import 'package:cims_apps/core/utils/size_config.dart';
import 'package:cims_apps/core/utils/string_utils.dart';
import 'package:cims_apps/features/auth/registration/view/submission_data/submission_parent.dart'; import 'package:cims_apps/features/auth/registration/view/submission_data/submission_parent.dart';
import 'package:cims_apps/features/auth/registration/viewmodel/submission_data_viewmodel.dart'; import 'package:cims_apps/features/auth/registration/viewmodel/submission_data_viewmodel.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
@ -32,10 +33,7 @@ class SubmitEmail extends StatelessWidget {
), ),
), ),
TextSpan( TextSpan(
recognizer: TapGestureRecognizer() recognizer: TapGestureRecognizer()..onTap = () {},
..onTap = () {
print('object');
},
text: 'verification', text: 'verification',
style: const TextStyle( style: const TextStyle(
color: Colors.blue, color: Colors.blue,
@ -74,6 +72,16 @@ class SubmitEmail extends StatelessWidget {
? TextFormView( ? TextFormView(
name: 'E-mail Address', name: 'E-mail Address',
hintText: 'Input e-mail address', hintText: 'Input e-mail address',
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value!.isEmpty) {
return 'Filled cannot be empty';
} else if (!StringUtils.emailValidation(value)) {
return 'Format email wrong';
} else {
return null;
}
},
// onTap: () { // onTap: () {
// provider.submitEmail(); // provider.submitEmail();
// }, // },

View File

@ -19,6 +19,7 @@ class SubmissionDataViewModel extends ChangeNotifier {
TextEditingController ctrlMarital = TextEditingController(); TextEditingController ctrlMarital = TextEditingController();
TextEditingController ctrlSourceFund = TextEditingController(); TextEditingController ctrlSourceFund = TextEditingController();
TextEditingController ctrlBankName = TextEditingController(); TextEditingController ctrlBankName = TextEditingController();
TextEditingController ctrlBirthDate = TextEditingController();
int step = 1; int step = 1;
List<ItemSelectForm> listOccupation = [ List<ItemSelectForm> listOccupation = [
@ -51,8 +52,8 @@ class SubmissionDataViewModel extends ChangeNotifier {
]; ];
List<ItemSelectForm> listImg = [ List<ItemSelectForm> listImg = [
ItemSelectForm('', 'ID Card', image: ''), ItemSelectForm('ktp', 'ID Card', image: ''),
ItemSelectForm('', 'Selfie with ID Card', image: ''), ItemSelectForm('selfie', 'Selfie with ID Card', image: ''),
]; ];
Future<List<CameraDescription>> initCamera() async { Future<List<CameraDescription>> initCamera() async {

View File

@ -1,10 +1,18 @@
import 'package:cims_apps/application/assets/path_assets.dart';
import 'package:cims_apps/application/theme/color_palette.dart'; import 'package:cims_apps/application/theme/color_palette.dart';
import 'package:cims_apps/core/utils/size_config.dart';
import 'package:cims_apps/features/dashboard/dashboard_account/view/homepage/homepage_view.dart'; import 'package:cims_apps/features/dashboard/dashboard_account/view/homepage/homepage_view.dart';
import 'package:cims_apps/features/dashboard/dashboard_account/view/plan/view/plan_view.dart'; import 'package:cims_apps/features/dashboard/dashboard_account/view/plan/view/plan_view.dart';
import 'package:cims_apps/features/dashboard/dashboard_account/view/plan/view_model/plan_view_model.dart';
import 'package:cims_apps/features/dashboard/dashboard_account/view/portfolio/portfolio_view.dart'; import 'package:cims_apps/features/dashboard/dashboard_account/view/portfolio/portfolio_view.dart';
import 'package:cims_apps/features/profile/view/profile_view.dart';
import 'package:cims_apps/features/transaction/view/transaction_view.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class BottomNavigationItem {
String icon, label;
BottomNavigationItem(this.icon, this.label);
}
class BottomNavigationView extends StatefulWidget { class BottomNavigationView extends StatefulWidget {
const BottomNavigationView({Key? key}) : super(key: key); const BottomNavigationView({Key? key}) : super(key: key);
@ -18,41 +26,28 @@ class _BottomNavigationViewState extends State<BottomNavigationView> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
///TODO: masukan pagenya dilistWidget ini List<Widget> listWidget = const [
List<Widget> listWidget = [
HomeView(), HomeView(),
PlanView(), PlanView(),
Container(), TransactionView(),
PortofolioView(), PortofolioView(),
Container(), ProfileView(),
]; ];
List<BottomNavigationBarItem> listNavigation = const [ List<BottomNavigationItem> listNavigation = [
BottomNavigationBarItem( BottomNavigationItem(PathAssets.iconNavigationHome, 'Home'),
icon: Icon(Icons.home_outlined), BottomNavigationItem(PathAssets.iconNavigationPlan, 'Plan'),
label: 'Home', BottomNavigationItem(PathAssets.iconNavigationTransaction, 'Transaction'),
), BottomNavigationItem(PathAssets.iconNavigationPortfolio, 'Portfolio'),
BottomNavigationBarItem( BottomNavigationItem(PathAssets.iconNavigationProfile, 'Profile')
icon: Icon(Icons.file_open),
label: 'Plan',
),
BottomNavigationBarItem(
icon: Icon(Icons.compare_arrows),
label: 'Transaction',
),
BottomNavigationBarItem(
icon: Icon(Icons.pie_chart_rounded),
label: 'Portfolio',
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: 'Profile',
),
]; ];
return Scaffold( return Scaffold(
body: listWidget[_selectedIndex], body: listWidget[_selectedIndex],
bottomNavigationBar: Padding( bottomNavigationBar: Container(
decoration: const BoxDecoration(
border: Border(top: BorderSide(color: ColorPalette.slate200))
),
padding: const EdgeInsets.symmetric(vertical: 12), padding: const EdgeInsets.symmetric(vertical: 12),
child: BottomNavigationBar( child: BottomNavigationBar(
elevation: 0, elevation: 0,
@ -62,13 +57,25 @@ class _BottomNavigationViewState extends State<BottomNavigationView> {
}); });
}, },
currentIndex: _selectedIndex, currentIndex: _selectedIndex,
items: listNavigation, items: listNavigation.asMap().entries.map((e) {
return BottomNavigationBarItem(
icon: Padding(
padding: const EdgeInsets.only(bottom: 4),
child: Image.asset(
e.value.icon,
width: SizeConfig.width * 0.06,
color: e.key == _selectedIndex ? ColorPalette.primary : ColorPalette.slate800
),
),
label: e.value.label
);
}).toList(),
type: BottomNavigationBarType.fixed, type: BottomNavigationBarType.fixed,
showUnselectedLabels: true, showUnselectedLabels: true,
selectedItemColor: ColorPalette.primary, selectedItemColor: ColorPalette.primary,
unselectedItemColor: Colors.black, unselectedItemColor: Colors.black,
selectedLabelStyle: const TextStyle(color: ColorPalette.primary), selectedLabelStyle: const TextStyle(color: ColorPalette.primary, fontSize: 12),
unselectedLabelStyle: const TextStyle(color: Colors.black), unselectedLabelStyle: const TextStyle(color: Colors.black, fontSize: 12),
), ),
), ),
); );

View File

@ -7,7 +7,6 @@ import 'package:cims_apps/application/theme/color_palette.dart';
import 'package:cims_apps/core/route/route.dart'; import 'package:cims_apps/core/route/route.dart';
import 'package:cims_apps/core/utils/size_config.dart'; import 'package:cims_apps/core/utils/size_config.dart';
import 'package:cims_apps/features/auth/registration/view/initial_registration_step.dart'; import 'package:cims_apps/features/auth/registration/view/initial_registration_step.dart';
import 'package:cims_apps/features/auth/registration/view/registration_view.dart';
import 'package:cims_apps/features/dashboard/dashboard_account/view/invest_type/invest_type_view.dart'; import 'package:cims_apps/features/dashboard/dashboard_account/view/invest_type/invest_type_view.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -50,14 +49,22 @@ class _HomeViewState extends State<HomeView> {
InvestType('Sharia', PathAssets.iconPortofolioSharia) InvestType('Sharia', PathAssets.iconPortofolioSharia)
]; ];
StepVerification listStepVerification = StepVerification(0, [ StepVerification listStepVerification =
'Registration', 'Verification', 'Complete' StepVerification(0, ['Registration', 'Verification', 'Complete']);
]);
List<Article> listArticle = [ List<Article> listArticle = [
Article('Education', 'Menggali Potensi Pasar: Analisis Sebelum Memulai Investasi', PathAssets.imgArticles), Article(
Article('News', 'Tren Investasi 2024: Peluang dan Risiko yang Perlu Diketahui', PathAssets.imgArticles), 'Education',
Article('Education', 'Investasi Berkelanjutan: Mengenal Portofolio Hijau untuk Masa Depan', PathAssets.imgArticles), 'Menggali Potensi Pasar: Analisis Sebelum Memulai Investasi',
PathAssets.imgArticles),
Article(
'News',
'Tren Investasi 2024: Peluang dan Risiko yang Perlu Diketahui',
PathAssets.imgArticles),
Article(
'Education',
'Investasi Berkelanjutan: Mengenal Portofolio Hijau untuk Masa Depan',
PathAssets.imgArticles),
]; ];
@override @override
@ -85,22 +92,17 @@ class _HomeViewState extends State<HomeView> {
style: TextStyle( style: TextStyle(
color: Colors.white, color: Colors.white,
fontSize: 20, fontSize: 20,
fontWeight: FontWeight.w700 fontWeight: FontWeight.w700),
),
), ),
ElevatedButton( ElevatedButton(
onPressed: () { onPressed: () {},
},
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
padding: const EdgeInsets.all(0), padding: const EdgeInsets.all(0),
backgroundColor: Colors.white, backgroundColor: Colors.white,
foregroundColor: const Color(0xff2563EB), foregroundColor: const Color(0xff2563EB),
elevation: 0, elevation: 0,
shape: const CircleBorder() shape: const CircleBorder()),
), child: const Icon(Icons.notifications_outlined))
child: const Icon(Icons.notifications_outlined)
)
], ],
), ),
), ),
@ -148,7 +150,8 @@ class _HomeViewState extends State<HomeView> {
children: [ children: [
Row( Row(
children: [ children: [
const Text('Portofolio Value', style: TextStyle(color: Colors.white)), const Text('Portofolio Value',
style: TextStyle(color: Colors.white)),
const SizedBox( const SizedBox(
width: 12, width: 12,
), ),
@ -158,8 +161,11 @@ class _HomeViewState extends State<HomeView> {
seePortofolioValue = !seePortofolioValue; seePortofolioValue = !seePortofolioValue;
}); });
}, },
child: const Icon(Icons.visibility_outlined, color: Color(0xff93C5FD)) child: Icon(
) seePortofolioValue
? Icons.visibility_off_outlined
: Icons.visibility_outlined,
color: const Color(0xff93C5FD)))
], ],
), ),
const SizedBox( const SizedBox(
@ -170,11 +176,17 @@ class _HomeViewState extends State<HomeView> {
AnimatedCrossFade( AnimatedCrossFade(
duration: const Duration(milliseconds: 300), duration: const Duration(milliseconds: 300),
alignment: Alignment.center, alignment: Alignment.center,
crossFadeState: seePortofolioValue ? CrossFadeState.showSecond : CrossFadeState.showFirst, crossFadeState: seePortofolioValue
? CrossFadeState.showSecond
: CrossFadeState.showFirst,
firstChild: RichText( firstChild: RichText(
text: const TextSpan( text: const TextSpan(
text: 'Rp ', text: 'Rp ',
style: TextStyle(fontSize: 32, color: Color(0xff93C5FD), fontFamily: 'Manrope',), style: TextStyle(
fontSize: 32,
color: Color(0xff93C5FD),
fontFamily: 'Manrope',
),
children: [ children: [
TextSpan( TextSpan(
text: '22.500.000', text: '22.500.000',
@ -185,9 +197,7 @@ class _HomeViewState extends State<HomeView> {
fontFamily: 'Manrope', fontFamily: 'Manrope',
), ),
) )
] ])),
)
),
secondChild: Padding( secondChild: Padding(
padding: const EdgeInsets.symmetric(vertical: 16), padding: const EdgeInsets.symmetric(vertical: 16),
child: Wrap( child: Wrap(
@ -197,7 +207,8 @@ class _HomeViewState extends State<HomeView> {
Container( Container(
width: 12, width: 12,
height: 12, height: 12,
decoration: const BoxDecoration(color: Colors.white, shape: BoxShape.circle), decoration: const BoxDecoration(
color: Colors.white, shape: BoxShape.circle),
), ),
], ],
), ),
@ -219,10 +230,8 @@ class _HomeViewState extends State<HomeView> {
BoxShadow( BoxShadow(
spreadRadius: 2, spreadRadius: 2,
blurRadius: 4, blurRadius: 4,
color: const Color(0xff1E293B).withOpacity(0.04) color: const Color(0xff1E293B).withOpacity(0.04))
) ]),
]
),
child: Wrap( child: Wrap(
spacing: 10, spacing: 10,
children: listPortofolioType.asMap().entries.map((e) { children: listPortofolioType.asMap().entries.map((e) {
@ -235,7 +244,11 @@ class _HomeViewState extends State<HomeView> {
width: SizeConfig.width * .18, width: SizeConfig.width * .18,
child: Column( child: Column(
children: [ children: [
ImageView(image: e.value.iconImage, height: SizeConfig.width * .12, width: SizeConfig.width * .12,), ImageView(
image: e.value.iconImage,
height: SizeConfig.width * .12,
width: SizeConfig.width * .12,
),
const SizedBox( const SizedBox(
height: 8, height: 8,
), ),
@ -244,9 +257,7 @@ class _HomeViewState extends State<HomeView> {
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: const TextStyle( style: const TextStyle(
fontSize: 12, fontSize: 12, fontWeight: FontWeight.w600),
fontWeight: FontWeight.w600
),
) )
], ],
), ),
@ -277,15 +288,16 @@ class _HomeViewState extends State<HomeView> {
children: [ children: [
const Row( const Row(
children: [ children: [
Icon(Icons.verified, size: 18,), Icon(
Icons.verified,
size: 18,
),
SizedBox( SizedBox(
width: 12, width: 12,
), ),
Text( Text(
'Verified by PT Gemilang', 'Verified by PT Gemilang',
style: TextStyle( style: TextStyle(color: ColorPalette.slate500),
color: ColorPalette.slate500
),
) )
], ],
), ),
@ -294,9 +306,9 @@ class _HomeViewState extends State<HomeView> {
height: 16, height: 16,
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: Colors.white,
border: Border.all(color: const Color(0xffCBD5E1), width: 1.5), border: Border.all(
shape: BoxShape.circle color: const Color(0xffCBD5E1), width: 1.5),
), shape: BoxShape.circle),
) )
], ],
), ),
@ -309,15 +321,16 @@ class _HomeViewState extends State<HomeView> {
const Row( const Row(
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
Icon(Icons.verified, size: 18,), Icon(
Icons.verified,
size: 18,
),
SizedBox( SizedBox(
width: 12, width: 12,
), ),
Text( Text(
'Verified by KSEI', 'Verified by KSEI',
style: TextStyle( style: TextStyle(color: ColorPalette.slate500),
color: ColorPalette.slate500
),
) )
], ],
), ),
@ -326,9 +339,9 @@ class _HomeViewState extends State<HomeView> {
height: 16, height: 16,
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: Colors.white,
border: Border.all(color: const Color(0xffCBD5E1), width: 1.5), border: Border.all(
shape: BoxShape.circle color: const Color(0xffCBD5E1), width: 1.5),
), shape: BoxShape.circle),
) )
], ],
), ),
@ -339,15 +352,12 @@ class _HomeViewState extends State<HomeView> {
padding: const EdgeInsets.all(12), padding: const EdgeInsets.all(12),
decoration: BoxDecoration( decoration: BoxDecoration(
color: ColorPalette.blue50, color: ColorPalette.blue50,
borderRadius: BorderRadius.circular(12) borderRadius: BorderRadius.circular(12)),
),
child: const Column( child: const Column(
children: [ children: [
Text( Text(
'Your registration is currently being verified by PT Gemilang', 'Your registration is currently being verified by PT Gemilang',
style: TextStyle( style: TextStyle(color: ColorPalette.slate500),
color: ColorPalette.slate500
),
), ),
SizedBox( SizedBox(
height: 16, height: 16,
@ -355,17 +365,15 @@ class _HomeViewState extends State<HomeView> {
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text('Estimated:', Text(
style: TextStyle( 'Estimated:',
color: ColorPalette.slate500 style: TextStyle(color: ColorPalette.slate500),
),
), ),
Text( Text(
'January 30 2024', 'January 30 2024',
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: Color(0xff1E293B) color: Color(0xff1E293B)),
),
) )
], ],
) )
@ -377,15 +385,12 @@ class _HomeViewState extends State<HomeView> {
padding: const EdgeInsets.all(12), padding: const EdgeInsets.all(12),
decoration: BoxDecoration( decoration: BoxDecoration(
color: ColorPalette.blue50, color: ColorPalette.blue50,
borderRadius: BorderRadius.circular(12) borderRadius: BorderRadius.circular(12)),
),
child: Column( child: Column(
children: [ children: [
Text( Text(
"Let's start registering your data to start mutual fund investment at PT Gemilang Indonesia", "Let's start registering your data to start mutual fund investment at PT Gemilang Indonesia",
style: TextStyle( style: TextStyle(color: ColorPalette.slate500),
color: ColorPalette.slate500
),
), ),
SizedBox( SizedBox(
height: 16, height: 16,
@ -420,7 +425,11 @@ class _HomeViewState extends State<HomeView> {
SizedBox( SizedBox(
width: 30, width: 30,
height: 30, height: 30,
child: Divider(color: listStepVerification.currentStep >= e.key ? const Color(0xff2563EB) : const Color(0xffCBD5E1),), child: Divider(
color: listStepVerification.currentStep >= e.key
? const Color(0xff2563EB)
: const Color(0xffCBD5E1),
),
), ),
Column( Column(
children: [ children: [
@ -429,18 +438,31 @@ class _HomeViewState extends State<HomeView> {
height: 30, height: 30,
decoration: BoxDecoration( decoration: BoxDecoration(
shape: BoxShape.circle, shape: BoxShape.circle,
color: listStepVerification.currentStep <= e.key ? Colors.white : const Color(0xff2563EB), color: listStepVerification.currentStep <= e.key
? Colors.white
: const Color(0xff2563EB),
border: Border.all( border: Border.all(
color: listStepVerification.currentStep < e.key ? const Color(0xffCBD5E1) : const Color(0xff2563EB), color: listStepVerification.currentStep < e.key
width: 2 ? const Color(0xffCBD5E1)
) : const Color(0xff2563EB),
width: 2)),
child: listStepVerification.currentStep <= e.key
? const SizedBox()
: const Icon(
Icons.done_rounded,
color: Colors.white,
), ),
child: listStepVerification.currentStep <= e.key ? const SizedBox() : const Icon(Icons.done_rounded, color: Colors.white,),
), ),
const SizedBox( const SizedBox(
height: 8, height: 8,
), ),
Text(e.value, style: TextStyle(color: listStepVerification.currentStep == e.key ? const Color(0xff2563EB) : Colors.black),) Text(
e.value,
style: TextStyle(
color: listStepVerification.currentStep == e.key
? const Color(0xff2563EB)
: Colors.black),
)
], ],
), ),
], ],
@ -455,7 +477,10 @@ class _HomeViewState extends State<HomeView> {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
const TextTitle(title: 'Info and Special Promo', color: ColorPalette.slate800,), const TextTitle(
title: 'Info and Special Promo',
color: ColorPalette.slate800,
),
const SizedBox( const SizedBox(
height: 16, height: 16,
), ),
@ -463,7 +488,11 @@ class _HomeViewState extends State<HomeView> {
items: [1, 2, 3].map((e) { items: [1, 2, 3].map((e) {
return Padding( return Padding(
padding: const EdgeInsets.symmetric(horizontal: 8), padding: const EdgeInsets.symmetric(horizontal: 8),
child: ImageView(image: PathAssets.imgCarousel, height: 150, width: SizeConfig.width * .9,), child: ImageView(
image: PathAssets.imgCarousel,
height: 150,
width: SizeConfig.width * .9,
),
); );
}).toList(), }).toList(),
options: CarouselOptions( options: CarouselOptions(
@ -493,14 +522,13 @@ class _HomeViewState extends State<HomeView> {
children: [ children: [
const TextTitle(title: 'Article', color: ColorPalette.slate800), const TextTitle(title: 'Article', color: ColorPalette.slate800),
GestureDetector( GestureDetector(
onTap: () { onTap: () {},
child: const Text(
}, 'See More',
child: const Text('See More',
style: TextStyle( style: TextStyle(
color: ColorPalette.primary, color: ColorPalette.primary,
fontWeight: FontWeight.bold fontWeight: FontWeight.bold),
),), ),
) )
], ],
), ),
@ -514,7 +542,9 @@ class _HomeViewState extends State<HomeView> {
if (e.key != 0) ...[ if (e.key != 0) ...[
const Padding( const Padding(
padding: EdgeInsets.symmetric(vertical: 12), padding: EdgeInsets.symmetric(vertical: 12),
child: Divider(color: ColorPalette.slate200,), child: Divider(
color: ColorPalette.slate200,
),
) )
], ],
cardArticle(e.value), cardArticle(e.value),
@ -531,7 +561,12 @@ class _HomeViewState extends State<HomeView> {
padding: const EdgeInsets.symmetric(horizontal: 24), padding: const EdgeInsets.symmetric(horizontal: 24),
child: Row( child: Row(
children: [ children: [
ImageView(image: PathAssets.imgArticles, width: SizeConfig.width * .17, height: SizeConfig.height * .08, borderRadius: 8,), ImageView(
image: PathAssets.imgArticles,
width: SizeConfig.width * .17,
height: SizeConfig.height * .08,
borderRadius: 8,
),
const SizedBox( const SizedBox(
width: 16, width: 16,
), ),
@ -539,7 +574,8 @@ class _HomeViewState extends State<HomeView> {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text(article.title, Text(
article.title,
style: const TextStyle( style: const TextStyle(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
@ -548,22 +584,20 @@ class _HomeViewState extends State<HomeView> {
height: 8, height: 8,
), ),
Container( Container(
padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 12), padding:
const EdgeInsets.symmetric(vertical: 4, horizontal: 12),
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30), borderRadius: BorderRadius.circular(30),
color: ColorPalette.green100 color: ColorPalette.green100),
),
child: Text( child: Text(
article.type, article.type,
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: ColorPalette.green500 color: ColorPalette.green500),
),
), ),
), ),
], ],
) ))
)
], ],
), ),
); );

View File

@ -20,11 +20,25 @@ class InvestTypeView extends StatefulWidget {
} }
class _InvestTypeViewState extends State<InvestTypeView> { class _InvestTypeViewState extends State<InvestTypeView> {
List<Product> listProduct = [ List<Product> listProduct = [
Product(name: 'Gemilang Dana Kas Maxima', type: '', yield: 8.17, priceUnit: 2600.79, funds: 6300000), Product(
Product(name: 'Gemilang Dana Likuid', type: '', yield: 6.42, priceUnit: 1600.79, funds: 2340000), name: 'Gemilang Dana Kas Maxima',
Product(name: 'Gemilang Income Fund', type: '', yield: 8.17, priceUnit: 2600.79, funds: 6300000) type: '',
yield: 8.17,
priceUnit: 2600.79,
funds: 6300000),
Product(
name: 'Gemilang Dana Likuid',
type: '',
yield: 6.42,
priceUnit: 1600.79,
funds: 2340000),
Product(
name: 'Gemilang Income Fund',
type: '',
yield: 8.17,
priceUnit: 2600.79,
funds: 6300000)
]; ];
@override @override
@ -41,8 +55,7 @@ class _InvestTypeViewState extends State<InvestTypeView> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ChangeNotifierProvider<ProductViewModel>( return ChangeNotifierProvider<ProductViewModel>(
create: (context) => ProductViewModel(), create: (context) => ProductViewModel(),
child: Consumer<ProductViewModel>( child: Consumer<ProductViewModel>(builder: (context, provider, child) {
builder: (context, provider, child) {
return Scaffold( return Scaffold(
body: SizedBox( body: SizedBox(
width: SizeConfig.width, width: SizeConfig.width,
@ -52,8 +65,8 @@ class _InvestTypeViewState extends State<InvestTypeView> {
const ImageView(image: PathAssets.imgDashboardAccount), const ImageView(image: PathAssets.imgDashboardAccount),
Column( Column(
children: [ children: [
const SizedBox( SizedBox(
height: 50, height: SizeConfig.height * .1,
), ),
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 24), padding: const EdgeInsets.symmetric(horizontal: 24),
@ -71,12 +84,14 @@ class _InvestTypeViewState extends State<InvestTypeView> {
const SizedBox( const SizedBox(
height: 24, height: 24,
), ),
Container( Expanded(
child: Container(
padding: const EdgeInsets.all(24), padding: const EdgeInsets.all(24),
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
color: Colors.white color: Colors.white),
), child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column( child: Column(
children: [ children: [
filters(), filters(),
@ -86,10 +101,12 @@ class _InvestTypeViewState extends State<InvestTypeView> {
return GestureDetector( return GestureDetector(
onTap: () { onTap: () {
provider.setSelectedProduct(e.value); provider.setSelectedProduct(e.value);
routePush(context, page: ProductView(widget.title)); routePush(context,
page: ProductView(widget.title));
}, },
child: Padding( child: Padding(
padding: EdgeInsets.only(top: e.key != 0 ? 24 : 0), padding: EdgeInsets.only(
top: e.key != 0 ? 24 : 0),
child: cardProduct(e.value), child: cardProduct(e.value),
), ),
); );
@ -98,14 +115,15 @@ class _InvestTypeViewState extends State<InvestTypeView> {
], ],
), ),
), ),
),
),
], ],
) )
], ],
), ),
), ),
); );
} }),
),
); );
} }
@ -115,9 +133,25 @@ class _InvestTypeViewState extends State<InvestTypeView> {
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
segmentFilter(const Icon(Icons.filter_alt_outlined, color: ColorPalette.slate400,), 'Filter', () { }), segmentFilter(
segmentFilter(const RotatedBox(quarterTurns: 1, child: Icon(Icons.compare_arrows, color: ColorPalette.slate400)), 'Sort', () { }), const Icon(
segmentFilter(const Icon(Icons.dashboard_outlined, color: ColorPalette.slate400), 'Compare', () { }), Icons.filter_alt_outlined,
color: ColorPalette.slate400,
),
'Filter',
() {}),
segmentFilter(
const RotatedBox(
quarterTurns: 1,
child:
Icon(Icons.compare_arrows, color: ColorPalette.slate400)),
'Sort',
() {}),
segmentFilter(
const Icon(Icons.dashboard_outlined,
color: ColorPalette.slate400),
'Compare',
() {}),
], ],
), ),
); );
@ -130,8 +164,7 @@ class _InvestTypeViewState extends State<InvestTypeView> {
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border.all(color: ColorPalette.slate200), border: Border.all(color: ColorPalette.slate200),
borderRadius: BorderRadius.circular(56) borderRadius: BorderRadius.circular(56)),
),
child: Row( child: Row(
children: [ children: [
leading, leading,
@ -142,9 +175,7 @@ class _InvestTypeViewState extends State<InvestTypeView> {
text, text,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: const TextStyle( style: const TextStyle(
color: ColorPalette.slate500, color: ColorPalette.slate500, fontWeight: FontWeight.w700),
fontWeight: FontWeight.w700
),
) )
], ],
), ),
@ -163,7 +194,10 @@ class _InvestTypeViewState extends State<InvestTypeView> {
children: [ children: [
Row( Row(
children: [ children: [
ImageView(image: PathAssets.imgProduct, width: SizeConfig.width * .12,), ImageView(
image: PathAssets.imgProduct,
width: SizeConfig.width * .12,
),
const SizedBox( const SizedBox(
width: 8, width: 8,
), ),
@ -171,9 +205,7 @@ class _InvestTypeViewState extends State<InvestTypeView> {
child: Text( child: Text(
product.name ?? '', product.name ?? '',
style: const TextStyle( style: const TextStyle(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold, fontSize: 18),
fontSize: 18
),
), ),
) )
], ],
@ -187,36 +219,53 @@ class _InvestTypeViewState extends State<InvestTypeView> {
children: [ children: [
Column( Column(
children: [ children: [
const Text('Yield', style: TextStyle(color: ColorPalette.slate400, fontWeight: FontWeight.w600),), const Text(
'Yield',
style: TextStyle(
color: ColorPalette.slate400,
fontWeight: FontWeight.w600),
),
Row( Row(
children: [ children: [
Text( Text(
'${product.yield.toString()}%', '${product.yield.toString()}%',
style: const TextStyle( style: const TextStyle(
color: ColorPalette.green400, color: ColorPalette.green400,
fontWeight: FontWeight.w600 fontWeight: FontWeight.w600),
),
), ),
const Text('/'), const Text('/'),
const Text('3year', style: TextStyle(color: ColorPalette.slate400, fontWeight: FontWeight.w600),) const Text(
'3year',
style: TextStyle(
color: ColorPalette.slate400,
fontWeight: FontWeight.w600),
)
], ],
) )
], ],
), ),
Column( Column(
children: [ children: [
const Text('Price/unit', style: TextStyle(color: ColorPalette.slate400, fontWeight: FontWeight.w600),), const Text(
'Price/unit',
style: TextStyle(
color: ColorPalette.slate400,
fontWeight: FontWeight.w600),
),
Row( Row(
children: [ children: [
const Icon(Icons.trending_up_outlined, size: 18, color: ColorPalette.green400,), const Icon(
Icons.trending_up_outlined,
size: 18,
color: ColorPalette.green400,
),
const SizedBox( const SizedBox(
width: 2, width: 2,
), ),
Text( Text(
NumberFormatter.numberCurrency(product.priceUnit, 'Rp', 'id_ID'), NumberFormatter.numberCurrency(
style: const TextStyle( product.priceUnit, 'Rp', 'id_ID'),
fontWeight: FontWeight.w600 style: const TextStyle(fontWeight: FontWeight.w600),
),
), ),
], ],
) )
@ -224,14 +273,18 @@ class _InvestTypeViewState extends State<InvestTypeView> {
), ),
Column( Column(
children: [ children: [
const Text('Managed funds', style: TextStyle(color: ColorPalette.slate400, fontWeight: FontWeight.w600),), const Text(
'Managed funds',
style: TextStyle(
color: ColorPalette.slate400,
fontWeight: FontWeight.w600),
),
Row( Row(
children: [ children: [
Text( Text(
NumberFormatter.compactCurrency(product.funds, 'Rp ', 'id_ID'), NumberFormatter.compactCurrency(
style: const TextStyle( product.funds, 'Rp ', 'id_ID'),
fontWeight: FontWeight.w600 style: const TextStyle(fontWeight: FontWeight.w600),
),
), ),
], ],
) )
@ -243,5 +296,4 @@ class _InvestTypeViewState extends State<InvestTypeView> {
), ),
); );
} }
} }

View File

@ -1,5 +1,3 @@
import 'dart:math';
import 'package:cims_apps/application/assets/path_assets.dart'; import 'package:cims_apps/application/assets/path_assets.dart';
import 'package:cims_apps/application/component/image/image_view.dart'; import 'package:cims_apps/application/component/image/image_view.dart';
import 'package:cims_apps/application/theme/color_palette.dart'; import 'package:cims_apps/application/theme/color_palette.dart';
@ -70,7 +68,7 @@ class _PortofolioViewState extends State<PortofolioView> {
), ),
const Center( const Center(
child: Text( child: Text(
'Portofolio', 'Portfolio',
style: TextStyle( style: TextStyle(
fontSize: 20, fontSize: 20,
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
@ -125,20 +123,22 @@ class _PortofolioViewState extends State<PortofolioView> {
), ),
Column( Column(
children: [ children: [
const Text('Total Mutual Fund', const Text(
'Total Mutual Fund',
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
fontSize: 18, fontSize: 18,
color: ColorPalette.slate400 color: ColorPalette.slate400),
), ),
), Text(
Text(listInvestmentType.map((e) => e.mutualFunds).reduce((value, element) => value + element).toString(), listInvestmentType
.map((e) => e.mutualFunds)
.reduce(
(value, element) => value + element)
.toString(),
style: const TextStyle( style: const TextStyle(
fontSize: 44, fontSize: 44,
fontWeight: FontWeight.w700 fontWeight: FontWeight.w700)),
)
)
,
], ],
) )
]), ]),
@ -168,7 +168,7 @@ class _PortofolioViewState extends State<PortofolioView> {
children: [ children: [
Row( Row(
children: [ children: [
const Text('Portofolio Value', const Text('Portfolio Value',
style: TextStyle(color: Colors.white)), style: TextStyle(color: Colors.white)),
const SizedBox( const SizedBox(
width: 8, width: 8,
@ -179,8 +179,11 @@ class _PortofolioViewState extends State<PortofolioView> {
seePortofolioValue = !seePortofolioValue; seePortofolioValue = !seePortofolioValue;
}); });
}, },
child: const Icon(Icons.visibility_outlined, child: Icon(
color: Color(0xff93C5FD))) seePortofolioValue
? Icons.visibility_off_outlined
: Icons.visibility_outlined,
color: const Color(0xff93C5FD)))
], ],
), ),
const SizedBox( const SizedBox(
@ -197,7 +200,10 @@ class _PortofolioViewState extends State<PortofolioView> {
firstChild: RichText( firstChild: RichText(
text: const TextSpan( text: const TextSpan(
text: 'Rp ', text: 'Rp ',
style: TextStyle(fontSize: 32, color: Color(0xff93C5FD), fontFamily: 'Manrope'), style: TextStyle(
fontSize: 32,
color: Color(0xff93C5FD),
fontFamily: 'Manrope'),
children: [ children: [
TextSpan( TextSpan(
text: '22.500.000', text: '22.500.000',
@ -205,8 +211,7 @@ class _PortofolioViewState extends State<PortofolioView> {
fontSize: 32, fontSize: 32,
fontFamily: 'Manrope', fontFamily: 'Manrope',
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: Colors.white color: Colors.white),
),
) )
])), ])),
secondChild: Padding( secondChild: Padding(

View File

@ -0,0 +1,14 @@
class LoginGmailModel {
String idToken;
String accessToken;
LoginGmailModel({
required this.idToken,
required this.accessToken,
});
Map<String, String> toJson() => {
"idToken": idToken,
"accessToken": accessToken,
};
}

View File

@ -5,9 +5,10 @@ import 'package:cims_apps/application/theme/color_palette.dart';
import 'package:cims_apps/core/route/route.dart'; import 'package:cims_apps/core/route/route.dart';
import 'package:cims_apps/core/utils/size_config.dart'; import 'package:cims_apps/core/utils/size_config.dart';
import 'package:cims_apps/features/auth/login/view/login_view.dart'; import 'package:cims_apps/features/auth/login/view/login_view.dart';
import 'package:cims_apps/features/auth/registration/view/initial_registration_step.dart';
import 'package:cims_apps/features/auth/registration/view/registration_view.dart'; import 'package:cims_apps/features/auth/registration/view/registration_view.dart';
import 'package:cims_apps/features/dashboard/dashboard_public/viewmodel/dashboard_public_viewmodel.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class DashboardPublicView extends StatelessWidget { class DashboardPublicView extends StatelessWidget {
static const routeName = '/DashboardPublicView'; static const routeName = '/DashboardPublicView';
@ -37,6 +38,9 @@ class DashboardPublicView extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => DashboardPublicViewModel(),
builder: (context, child) {
return Scaffold( return Scaffold(
body: SingleChildScrollView( body: SingleChildScrollView(
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
@ -45,7 +49,9 @@ class DashboardPublicView extends StatelessWidget {
left: 24.0, left: 24.0,
right: 24.0, right: 24.0,
), ),
child: Column( child: Consumer<DashboardPublicViewModel>(
builder: (context, provider, child) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
@ -96,9 +102,10 @@ class DashboardPublicView extends StatelessWidget {
width: 26, width: 26,
), ),
onPressed: () { onPressed: () {
routePush(context, page: const InitialRegistrationStep()); provider.loginGoogle(context);
}, },
), ),
SizedBox(height: SizeConfig.height * .15),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
@ -117,8 +124,10 @@ class DashboardPublicView extends StatelessWidget {
], ],
) )
], ],
), );
}),
), ),
); );
});
} }
} }

View File

@ -0,0 +1,50 @@
import 'package:cims_apps/core/route/route.dart';
import 'package:cims_apps/features/auth/registration/view/initial_registration_step.dart';
import 'package:cims_apps/features/dashboard/dashboard_public/model/login_gmail_model.dart';
import 'package:flutter/material.dart';
import 'package:google_sign_in/google_sign_in.dart';
class DashboardPublicViewModel extends ChangeNotifier {
String emailGoogle = '';
final GoogleSignIn googleSignIn = GoogleSignIn(
scopes: [
'email',
'https://www.googleapis.com/auth/contacts.readonly',
],
);
Future<LoginGmailModel?> _getGmail() async {
LoginGmailModel? loginGmailModel;
try {
final signInResult = await googleSignIn.signIn();
if (signInResult != null) {
emailGoogle = signInResult.email;
final signInAuth = await signInResult.authentication;
final accessToken = signInAuth.accessToken;
final idToken = signInAuth.idToken;
if (idToken != null && accessToken != null) {
loginGmailModel = LoginGmailModel(
accessToken: accessToken,
idToken: idToken,
);
}
}
} catch (e) {
debugPrint('catch error $e');
}
return loginGmailModel;
}
Future<bool> loginGoogle(BuildContext context) async {
bool loginSuccess = false;
loginSuccess = await _getGmail().then((payload) async {
bool result = false;
if (payload != null) {
debugPrint('objectzz ${payload.toJson()}');
routePush(context, page: InitialRegistrationStep());
googleSignIn.disconnect();
}
return result;
});
return loginSuccess;
}
}

View File

@ -0,0 +1,14 @@
import 'package:cims_apps/application/component/custom_app_bar/custom_app_bar.dart';
import 'package:cims_apps/core/utils/size_config.dart';
import 'package:flutter/material.dart';
class ProfileView extends StatelessWidget {
const ProfileView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(height: SizeConfig.height * .1, title: 'Profile'),
);
}
}

View File

@ -0,0 +1,15 @@
import 'package:cims_apps/application/component/custom_app_bar/custom_app_bar.dart';
import 'package:cims_apps/core/utils/size_config.dart';
import 'package:flutter/material.dart';
class TransactionView extends StatelessWidget {
const TransactionView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar:
CustomAppBar(height: SizeConfig.height * .1, title: 'Transaction'),
);
}
}

View File

@ -49,6 +49,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.1" version: "1.1.1"
calendar_date_picker2:
dependency: "direct main"
description:
name: calendar_date_picker2
sha256: b91d51b8d0928f9745e0113e86d06b161ac48c52b7530337a3b77283cbc6be27
url: "https://pub.dev"
source: hosted
version: "0.5.3"
camera: camera:
dependency: "direct main" dependency: "direct main"
description: description:
@ -256,6 +264,54 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
google_identity_services_web:
dependency: transitive
description:
name: google_identity_services_web
sha256: "0c56c2c5d60d6dfaf9725f5ad4699f04749fb196ee5a70487a46ef184837ccf6"
url: "https://pub.dev"
source: hosted
version: "0.3.0+2"
google_sign_in:
dependency: "direct main"
description:
name: google_sign_in
sha256: "0b8787cb9c1a68ad398e8010e8c8766bfa33556d2ab97c439fb4137756d7308f"
url: "https://pub.dev"
source: hosted
version: "6.2.1"
google_sign_in_android:
dependency: transitive
description:
name: google_sign_in_android
sha256: bfd42c81c30c6faba16e0f62968d5505a87504aaa672b3155ee931461abb0a49
url: "https://pub.dev"
source: hosted
version: "6.1.21"
google_sign_in_ios:
dependency: transitive
description:
name: google_sign_in_ios
sha256: f3336d9e44d4d28063ac90271f6db5caf99f0480cb07281330e7a432edb95226
url: "https://pub.dev"
source: hosted
version: "5.7.3"
google_sign_in_platform_interface:
dependency: transitive
description:
name: google_sign_in_platform_interface
sha256: "1f6e5787d7a120cc0359ddf315c92309069171306242e181c09472d1b00a2971"
url: "https://pub.dev"
source: hosted
version: "2.4.5"
google_sign_in_web:
dependency: transitive
description:
name: google_sign_in_web
sha256: a278ea2d01013faf341cbb093da880d0f2a552bbd1cb6ee90b5bebac9ba69d77
url: "https://pub.dev"
source: hosted
version: "0.12.3+2"
group_button: group_button:
dependency: "direct main" dependency: "direct main"
description: description:
@ -292,10 +348,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: js name: js
sha256: "4186c61b32f99e60f011f7160e32c89a758ae9b1d0c6d28e2c02ef0382300e2b" sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.0" version: "0.7.1"
lints: lints:
dependency: transitive dependency: transitive
description: description:
@ -625,18 +681,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: syncfusion_flutter_core name: syncfusion_flutter_core
sha256: e8580e201c7197feac830b501889e877796a9fabbe20dcdbe90a981603939101 sha256: "9f98e2726af42967497eaef68f3373261700bbfcd33bd97da4ec85cb56fcdaf7"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "24.2.4" version: "24.2.7"
syncfusion_flutter_signaturepad: syncfusion_flutter_signaturepad:
dependency: "direct main" dependency: "direct main"
description: description:
name: syncfusion_flutter_signaturepad name: syncfusion_flutter_signaturepad
sha256: "878e1063b909a83c83677627261780d42d532d0b5e7e259d84da805008e7fb0d" sha256: d51d5e346c70b938a8e1f2318a073213172aea7b99e33073c379657b1066c001
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "24.2.4" version: "24.2.7"
synchronized: synchronized:
dependency: transitive dependency: transitive
description: description:

View File

@ -51,6 +51,9 @@ dependencies:
syncfusion_flutter_signaturepad: ^24.2.4 syncfusion_flutter_signaturepad: ^24.2.4
dotted_border: ^2.1.0 dotted_border: ^2.1.0
shared_preferences: ^2.2.2 shared_preferences: ^2.2.2
calendar_date_picker2: ^0.5.3
google_sign_in: ^6.2.1