Compare commits
16 Commits
83211e76f9
...
89a79276a6
Author | SHA1 | Date | |
---|---|---|---|
89a79276a6 | |||
4737a91ab1 | |||
ff135dd47b | |||
2e98c1a234 | |||
c4c0479341 | |||
e510aaefd7 | |||
dfb947dce5 | |||
9761dc369c | |||
9e2304990c | |||
8b1b3e950f | |||
aa987fe320 | |||
ad6195061d | |||
b5a382ce96 | |||
fdca27233b | |||
bd065242e6 | |||
a35110af71 |
BIN
assets/icons/icon-navigation-home.png
Normal file
BIN
assets/icons/icon-navigation-home.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
BIN
assets/icons/icon-navigation-plan.png
Normal file
BIN
assets/icons/icon-navigation-plan.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
assets/icons/icon-navigation-portfolio.png
Normal file
BIN
assets/icons/icon-navigation-portfolio.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
BIN
assets/icons/icon-navigation-profile.png
Normal file
BIN
assets/icons/icon-navigation-profile.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
BIN
assets/icons/icon-navigation-transaction.png
Normal file
BIN
assets/icons/icon-navigation-transaction.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 899 B |
|
@ -49,6 +49,11 @@ class PathAssets {
|
|||
static const String iconTicket = 'assets/icons/icon-ticket.png';
|
||||
static const String iconGadget = 'assets/icons/icon-gadget.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
|
||||
static const String imgSplashLogo = 'assets/images/splash-logo.png';
|
||||
|
|
144
lib/application/component/date_picker/date_picker_view.dart
Normal file
144
lib/application/component/date_picker/date_picker_view.dart
Normal 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});
|
||||
}
|
|
@ -24,11 +24,10 @@ class _TotalPaymentViewState extends State<TotalPaymentView> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
return SingleChildScrollView(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(16)
|
||||
),
|
||||
color: Colors.white, borderRadius: BorderRadius.circular(16)),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
|
@ -37,56 +36,54 @@ class _TotalPaymentViewState extends State<TotalPaymentView> {
|
|||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Text('Your Investment Today',
|
||||
const Text(
|
||||
'Your Investment Today',
|
||||
style: TextStyle(
|
||||
color: ColorPalette.slate800,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 16
|
||||
),
|
||||
fontSize: 16),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () => Navigator.pop(context),
|
||||
child: const Icon(Icons.close_rounded)
|
||||
)
|
||||
child: const Icon(Icons.close_rounded))
|
||||
],
|
||||
),
|
||||
),
|
||||
...widget.listProduct.asMap().entries.map((e) {
|
||||
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(
|
||||
border: Border(
|
||||
left: BorderSide(
|
||||
width: 8,
|
||||
color: ColorPalette.investTypeColor[e.value.type]!
|
||||
)
|
||||
)
|
||||
),
|
||||
color:
|
||||
ColorPalette.investTypeColor[e.value.type]!))),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 5,
|
||||
child: Text(e.value.name ?? '',
|
||||
child: Text(
|
||||
e.value.name ?? '',
|
||||
style: const TextStyle(
|
||||
color: ColorPalette.slate400,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 16
|
||||
),
|
||||
)
|
||||
),
|
||||
fontSize: 16),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 7,
|
||||
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,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w700,
|
||||
fontSize: 18,
|
||||
color: ColorPalette.slate800
|
||||
),
|
||||
)
|
||||
)
|
||||
color: ColorPalette.slate800),
|
||||
))
|
||||
],
|
||||
),
|
||||
);
|
||||
|
@ -97,44 +94,47 @@ class _TotalPaymentViewState extends State<TotalPaymentView> {
|
|||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('Purchase Commission',
|
||||
Text(
|
||||
'Purchase Commission',
|
||||
style: TextStyle(
|
||||
color: ColorPalette.slate400,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 16
|
||||
fontSize: 16),
|
||||
),
|
||||
),
|
||||
Text('Free',
|
||||
Text(
|
||||
'Free',
|
||||
style: TextStyle(
|
||||
color: ColorPalette.primary,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w700
|
||||
),
|
||||
fontWeight: FontWeight.w700),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16,),
|
||||
const SizedBox(
|
||||
height: 16,
|
||||
),
|
||||
Container(
|
||||
color: ColorPalette.slate200.withOpacity(0.5),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Text('Total',
|
||||
const Text(
|
||||
'Total',
|
||||
style: TextStyle(
|
||||
color: ColorPalette.slate400,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 16
|
||||
fontSize: 16),
|
||||
),
|
||||
),
|
||||
Text(NumberFormatter.numberCurrency(widget.totalInvest, 'Rp ', 'id_ID'),
|
||||
Text(
|
||||
NumberFormatter.numberCurrency(
|
||||
widget.totalInvest, 'Rp ', 'id_ID'),
|
||||
textAlign: TextAlign.end,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w700,
|
||||
fontSize: 18,
|
||||
color: ColorPalette.slate800
|
||||
),
|
||||
color: ColorPalette.slate800),
|
||||
)
|
||||
],
|
||||
),
|
||||
|
@ -145,20 +145,21 @@ class _TotalPaymentViewState extends State<TotalPaymentView> {
|
|||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Text('Total Payment',
|
||||
const Text(
|
||||
'Total Payment',
|
||||
style: TextStyle(
|
||||
color: ColorPalette.slate400,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 16
|
||||
fontSize: 16),
|
||||
),
|
||||
),
|
||||
Text(NumberFormatter.numberCurrency(widget.totalInvest, 'Rp ', 'id_ID'),
|
||||
Text(
|
||||
NumberFormatter.numberCurrency(
|
||||
widget.totalInvest, 'Rp ', 'id_ID'),
|
||||
textAlign: TextAlign.end,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w700,
|
||||
fontSize: 18,
|
||||
color: ColorPalette.slate800
|
||||
),
|
||||
color: ColorPalette.slate800),
|
||||
)
|
||||
],
|
||||
),
|
||||
|
@ -167,7 +168,8 @@ class _TotalPaymentViewState extends State<TotalPaymentView> {
|
|||
disabled: !isAgreement,
|
||||
name: 'Subscribe Now',
|
||||
onPressed: () {
|
||||
routePush(context, page: PaymentMethodView(
|
||||
routePush(context,
|
||||
page: PaymentMethodView(
|
||||
totalInvest: widget.totalInvest,
|
||||
));
|
||||
},
|
||||
|
@ -179,6 +181,7 @@ class _TotalPaymentViewState extends State<TotalPaymentView> {
|
|||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -205,48 +208,46 @@ class _TotalPaymentViewState extends State<TotalPaymentView> {
|
|||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
border: Border.all(
|
||||
color: isAgree ? ColorPalette.primary : ColorPalette.slate200
|
||||
)
|
||||
),
|
||||
color: isAgree
|
||||
? ColorPalette.primary
|
||||
: ColorPalette.slate200)),
|
||||
child: AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: isAgree ? ColorPalette.primary : ColorPalette.white,
|
||||
shape: BoxShape.circle
|
||||
color:
|
||||
isAgree ? ColorPalette.primary : ColorPalette.white,
|
||||
shape: BoxShape.circle),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
const SizedBox(width: 12,),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
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(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: ColorPalette.slate400
|
||||
),
|
||||
color: ColorPalette.slate400),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
|
||||
},
|
||||
child: const Text('Read More',
|
||||
onTap: () {},
|
||||
child: const Text(
|
||||
'Read More',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
decoration: TextDecoration.underline,
|
||||
color: ColorPalette.primary
|
||||
),
|
||||
)
|
||||
)
|
||||
color: ColorPalette.primary),
|
||||
))
|
||||
],
|
||||
)
|
||||
)
|
||||
))
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
|
@ -12,6 +12,7 @@ import 'package:cims_apps/features/auth/registration/viewmodel/submission_data_v
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'dart:math' as math;
|
||||
|
||||
class DisplayPictureScreen extends StatefulWidget {
|
||||
final String imagePath, content;
|
||||
|
@ -106,7 +107,14 @@ class _DisplayPictureScreenState extends State<DisplayPictureScreen> {
|
|||
SizedBox(
|
||||
width: SizeConfig.width,
|
||||
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(
|
||||
padding: EdgeInsets.symmetric(vertical: 16.0),
|
||||
child: Text(
|
||||
|
|
|
@ -141,7 +141,7 @@ class TextFormView extends StatelessWidget {
|
|||
style: TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 14,
|
||||
color: fontColorDisabled ?? ColorPalette.slate500,
|
||||
color: fontColorDisabled ?? ColorPalette.slate800,
|
||||
),
|
||||
readOnly: readOnly,
|
||||
validator: validator,
|
||||
|
@ -163,7 +163,7 @@ class TextFormView extends StatelessWidget {
|
|||
hintStyle: hintTextStyle ??
|
||||
const TextStyle(
|
||||
fontSize: 14,
|
||||
color: ColorPalette.greyFont,
|
||||
color: ColorPalette.slate400,
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
isDense: true,
|
||||
|
|
|
@ -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/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/core/route/route.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/phone_number_view.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:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class LoginView extends StatefulWidget {
|
||||
|
@ -90,7 +83,11 @@ class _LoginViewState extends State<LoginView> {
|
|||
currentPage++;
|
||||
pageController.jumpToPage(1);
|
||||
} else {
|
||||
routePush(context, page: BottomNavigationView());
|
||||
routePush(
|
||||
context,
|
||||
page: const BottomNavigationView(),
|
||||
routeType: RouteType.pushReplace,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,16 +10,19 @@ import 'package:provider/provider.dart';
|
|||
class PasswordView extends StatelessWidget {
|
||||
final void Function() nextStep;
|
||||
final TextEditingController controller;
|
||||
const PasswordView({super.key, required this.nextStep, required this.controller});
|
||||
const PasswordView(
|
||||
{super.key, required this.nextStep, required this.controller});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Consumer<LoginViewModel>(
|
||||
builder: (context, provider, child) {
|
||||
return Consumer<LoginViewModel>(builder: (context, provider, child) {
|
||||
return Container(
|
||||
width: SizeConfig.width,
|
||||
height: SizeConfig.height,
|
||||
padding: const EdgeInsets.all(24),
|
||||
child: Form(
|
||||
key: provider.formKey,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
|
@ -32,6 +35,15 @@ class PasswordView extends StatelessWidget {
|
|||
ctrl: controller,
|
||||
obscureText: !provider.showPassword,
|
||||
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(
|
||||
onTap: () {
|
||||
provider.changeShowPassword();
|
||||
|
@ -45,19 +57,14 @@ class PasswordView extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
padding: EdgeInsets.all(0)
|
||||
),
|
||||
onPressed: () {
|
||||
|
||||
},
|
||||
style: TextButton.styleFrom(padding: EdgeInsets.all(0)),
|
||||
onPressed: () {},
|
||||
child: Text(
|
||||
'Forget the password?',
|
||||
style: TextStyle(
|
||||
color: ColorPalette.primary,
|
||||
),
|
||||
)
|
||||
),
|
||||
)),
|
||||
SizedBox(
|
||||
height: 16,
|
||||
),
|
||||
|
@ -67,13 +74,19 @@ class PasswordView extends StatelessWidget {
|
|||
width: SizeConfig.width,
|
||||
textSize: 18,
|
||||
marginVertical: 0,
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
onPressed: nextStep,
|
||||
contentPadding:
|
||||
EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
onPressed: () {
|
||||
if (provider.formKey.currentState!.validate()) {
|
||||
nextStep();
|
||||
}
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,31 +1,42 @@
|
|||
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/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_title/text_title.dart';
|
||||
import 'package:cims_apps/application/theme/color_palette.dart';
|
||||
import 'package:cims_apps/core/route/route.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:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class PhoneNumberView extends StatelessWidget {
|
||||
final void Function() nextStep;
|
||||
final TextEditingController controller;
|
||||
const PhoneNumberView({super.key, required this.nextStep, required this.controller});
|
||||
const PhoneNumberView(
|
||||
{super.key, required this.nextStep, required this.controller});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChangeNotifierProvider(
|
||||
create: (context) => LoginViewModel(),
|
||||
builder: (context, child) {
|
||||
return Container(
|
||||
width: SizeConfig.width,
|
||||
height: SizeConfig.height,
|
||||
padding: const EdgeInsets.all(24),
|
||||
child:
|
||||
Consumer<LoginViewModel>(builder: (context, provider, child) {
|
||||
return Form(
|
||||
key: provider.formKey,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const TextTitle(title: 'Enter your phone number', fontSize: 24),
|
||||
const TextTitle(
|
||||
title: 'Enter your phone number', fontSize: 24),
|
||||
SizedBox(
|
||||
height: 24,
|
||||
),
|
||||
|
@ -82,8 +93,13 @@ class PhoneNumberView extends StatelessWidget {
|
|||
heightWrapContent: true,
|
||||
width: SizeConfig.width,
|
||||
marginVertical: 0,
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
onPressed: nextStep,
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 16, vertical: 12),
|
||||
onPressed: () {
|
||||
if (provider.formKey.currentState!.validate()) {
|
||||
nextStep();
|
||||
}
|
||||
},
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
|
@ -99,20 +115,21 @@ class PhoneNumberView extends StatelessWidget {
|
|||
routePush(context, page: RegistrationView());
|
||||
},
|
||||
style: TextButton.styleFrom(
|
||||
padding: EdgeInsets.all(0)
|
||||
),
|
||||
padding: EdgeInsets.all(0)),
|
||||
child: Text(
|
||||
'Sign Up',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: ColorPalette.primary
|
||||
),
|
||||
)
|
||||
)
|
||||
color: ColorPalette.primary),
|
||||
))
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class LoginViewModel extends ChangeNotifier {
|
||||
bool showPassword = false;
|
||||
var formKey = GlobalKey<FormState>();
|
||||
|
||||
void changeShowPassword() {
|
||||
showPassword = !showPassword;
|
||||
|
|
|
@ -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/utils/size_config.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';
|
||||
|
||||
class InitialRegistrationStep extends StatelessWidget {
|
||||
|
@ -203,7 +203,7 @@ class InitialRegistrationStep extends StatelessWidget {
|
|||
isOutlined: true,
|
||||
onPressed: () {
|
||||
routePush(context,
|
||||
page: const DashboardPublicView(),
|
||||
page: const BottomNavigationView(),
|
||||
routeType: RouteType.pushReplace);
|
||||
},
|
||||
),
|
||||
|
|
|
@ -45,7 +45,7 @@ class RegistrationPasswordView extends StatelessWidget {
|
|||
validator: (value) {
|
||||
if (value!.isEmpty) {
|
||||
return 'Password must filled';
|
||||
} else if (value.length <= 8) {
|
||||
} else if (value.length < 8) {
|
||||
return 'Minimum password 8 Character';
|
||||
} else {
|
||||
return null;
|
||||
|
|
|
@ -29,7 +29,8 @@ class SubmitBankAccount extends StatelessWidget {
|
|||
return SizedBox(
|
||||
child: Consumer<SubmissionDataViewModel>(
|
||||
builder: (context, provider, child) {
|
||||
return Column(
|
||||
return SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const TextCaption(title: 'Input your bank account data'),
|
||||
|
@ -43,13 +44,15 @@ class SubmitBankAccount extends StatelessWidget {
|
|||
TextFormView(
|
||||
name: 'Account Number',
|
||||
hintText: 'Input Account Number',
|
||||
keyboardType: TextInputType.number,
|
||||
trailingTitleWidget: SizedBox(
|
||||
width: 24,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
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: () {
|
||||
provider.next(context).then((value) {
|
||||
if (value) {
|
||||
routePush(context, page: const ConfirmBankAccount());
|
||||
routePush(context,
|
||||
page: const ConfirmBankAccount());
|
||||
}
|
||||
});
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}),
|
||||
);
|
||||
|
|
|
@ -24,13 +24,13 @@ class SubmissionParent extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _SubmissionParentState extends State<SubmissionParent> {
|
||||
Widget _stepItem({bool isCurrentStep = false, bool isDone = false}) {
|
||||
Widget _stepItem({bool isCurrentStep = false}) {
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(right: 0.0, left: 4.0),
|
||||
height: 6,
|
||||
width: SizeConfig.width * .08,
|
||||
decoration: BoxDecoration(
|
||||
color: isCurrentStep || isDone
|
||||
color: isCurrentStep
|
||||
? ColorPalette.primary
|
||||
: ColorPalette.greyBorderNeutrals,
|
||||
borderRadius: BorderRadius.circular(50),
|
||||
|
@ -91,15 +91,10 @@ class _SubmissionParentState extends State<SubmissionParent> {
|
|||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children:
|
||||
List.generate(provider.stepAmount, (index) {
|
||||
// print('indd $index');
|
||||
// print(
|
||||
// 'getCurrentStep ${provider.getCurrentStep}');
|
||||
return _stepItem(
|
||||
isCurrentStep: provider.getCurrentStep ==
|
||||
index + 1 ||
|
||||
provider.getCurrentStep - 1 == index + 1,
|
||||
// isDone:
|
||||
// index + 1 != provider.getCurrentStep + 1,
|
||||
isCurrentStep:
|
||||
provider.getCurrentStep == index + 1 ||
|
||||
provider.getCurrentStep - 1 > index,
|
||||
);
|
||||
}),
|
||||
),
|
||||
|
|
|
@ -2,6 +2,7 @@ import 'dart:io';
|
|||
|
||||
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/date_picker/date_picker_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_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:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'dart:math' as math;
|
||||
|
||||
class SubmitDataIdCard extends StatelessWidget {
|
||||
const SubmitDataIdCard({Key? key}) : super(key: key);
|
||||
|
@ -29,7 +31,7 @@ class SubmitDataIdCard extends StatelessWidget {
|
|||
color: Colors.white,
|
||||
borderRadius:
|
||||
BorderRadius.vertical(top: Radius.circular(18))),
|
||||
height: SizeConfig.height * .32,
|
||||
height: SizeConfig.height * .35,
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
|
@ -107,17 +109,24 @@ class SubmitDataIdCard extends StatelessWidget {
|
|||
SizedBox(
|
||||
height: SizeConfig.height * .18,
|
||||
width: SizeConfig.width * .45,
|
||||
child: Transform(
|
||||
alignment: Alignment.center,
|
||||
transform: e.key == 'selfie'
|
||||
? Matrix4.rotationY(math.pi)
|
||||
: Matrix4.rotationY(0),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: Image.file(
|
||||
File(e.image),
|
||||
fit: BoxFit.fill,
|
||||
errorBuilder: (context, error, stackTrace) {
|
||||
return const Icon(Icons.image_not_supported_outlined);
|
||||
return const Icon(
|
||||
Icons.image_not_supported_outlined);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: SizeConfig.width * .43,
|
||||
child: Row(
|
||||
|
@ -172,15 +181,17 @@ class SubmitDataIdCard extends StatelessWidget {
|
|||
children: [
|
||||
const TextCaption(
|
||||
title: 'Check your ID card data for accuracy'),
|
||||
TextFormView(name: 'NIK'),
|
||||
TextFormView(name: 'Full Name'),
|
||||
TextFormView(
|
||||
name: 'NIK',
|
||||
keyboardType: TextInputType.number,
|
||||
),
|
||||
TextFormView(name: 'Full Name'),
|
||||
DatePickerView(
|
||||
name: 'Birth Date',
|
||||
suffixIcon: const Icon(
|
||||
Icons.calendar_today_rounded,
|
||||
color: ColorPalette.slate400,
|
||||
),
|
||||
),
|
||||
ctrl: provider.ctrlBirthDate,
|
||||
maxDate: DateTime.now(),
|
||||
isMultipleSelection: false,
|
||||
enabled: true),
|
||||
photoDocument(provider),
|
||||
Container(
|
||||
width: SizeConfig.width,
|
||||
|
|
|
@ -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/core/route/route.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/viewmodel/submission_data_viewmodel.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
|
@ -32,10 +33,7 @@ class SubmitEmail extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
TextSpan(
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () {
|
||||
print('object');
|
||||
},
|
||||
recognizer: TapGestureRecognizer()..onTap = () {},
|
||||
text: 'verification',
|
||||
style: const TextStyle(
|
||||
color: Colors.blue,
|
||||
|
@ -74,6 +72,16 @@ class SubmitEmail extends StatelessWidget {
|
|||
? TextFormView(
|
||||
name: '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: () {
|
||||
// provider.submitEmail();
|
||||
// },
|
||||
|
|
|
@ -19,6 +19,7 @@ class SubmissionDataViewModel extends ChangeNotifier {
|
|||
TextEditingController ctrlMarital = TextEditingController();
|
||||
TextEditingController ctrlSourceFund = TextEditingController();
|
||||
TextEditingController ctrlBankName = TextEditingController();
|
||||
TextEditingController ctrlBirthDate = TextEditingController();
|
||||
int step = 1;
|
||||
|
||||
List<ItemSelectForm> listOccupation = [
|
||||
|
@ -51,8 +52,8 @@ class SubmissionDataViewModel extends ChangeNotifier {
|
|||
];
|
||||
|
||||
List<ItemSelectForm> listImg = [
|
||||
ItemSelectForm('', 'ID Card', image: ''),
|
||||
ItemSelectForm('', 'Selfie with ID Card', image: ''),
|
||||
ItemSelectForm('ktp', 'ID Card', image: ''),
|
||||
ItemSelectForm('selfie', 'Selfie with ID Card', image: ''),
|
||||
];
|
||||
|
||||
Future<List<CameraDescription>> initCamera() async {
|
||||
|
|
|
@ -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/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/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/profile/view/profile_view.dart';
|
||||
import 'package:cims_apps/features/transaction/view/transaction_view.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 {
|
||||
const BottomNavigationView({Key? key}) : super(key: key);
|
||||
|
@ -18,41 +26,28 @@ class _BottomNavigationViewState extends State<BottomNavigationView> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
///TODO: masukan pagenya dilistWidget ini
|
||||
List<Widget> listWidget = [
|
||||
List<Widget> listWidget = const [
|
||||
HomeView(),
|
||||
PlanView(),
|
||||
Container(),
|
||||
TransactionView(),
|
||||
PortofolioView(),
|
||||
Container(),
|
||||
ProfileView(),
|
||||
];
|
||||
|
||||
List<BottomNavigationBarItem> listNavigation = const [
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(Icons.home_outlined),
|
||||
label: 'Home',
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
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',
|
||||
),
|
||||
List<BottomNavigationItem> listNavigation = [
|
||||
BottomNavigationItem(PathAssets.iconNavigationHome, 'Home'),
|
||||
BottomNavigationItem(PathAssets.iconNavigationPlan, 'Plan'),
|
||||
BottomNavigationItem(PathAssets.iconNavigationTransaction, 'Transaction'),
|
||||
BottomNavigationItem(PathAssets.iconNavigationPortfolio, 'Portfolio'),
|
||||
BottomNavigationItem(PathAssets.iconNavigationProfile, 'Profile')
|
||||
];
|
||||
|
||||
return Scaffold(
|
||||
body: listWidget[_selectedIndex],
|
||||
bottomNavigationBar: Padding(
|
||||
bottomNavigationBar: Container(
|
||||
decoration: const BoxDecoration(
|
||||
border: Border(top: BorderSide(color: ColorPalette.slate200))
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(vertical: 12),
|
||||
child: BottomNavigationBar(
|
||||
elevation: 0,
|
||||
|
@ -62,13 +57,25 @@ class _BottomNavigationViewState extends State<BottomNavigationView> {
|
|||
});
|
||||
},
|
||||
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,
|
||||
showUnselectedLabels: true,
|
||||
selectedItemColor: ColorPalette.primary,
|
||||
unselectedItemColor: Colors.black,
|
||||
selectedLabelStyle: const TextStyle(color: ColorPalette.primary),
|
||||
unselectedLabelStyle: const TextStyle(color: Colors.black),
|
||||
selectedLabelStyle: const TextStyle(color: ColorPalette.primary, fontSize: 12),
|
||||
unselectedLabelStyle: const TextStyle(color: Colors.black, fontSize: 12),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -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/utils/size_config.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:flutter/material.dart';
|
||||
|
||||
|
@ -50,14 +49,22 @@ class _HomeViewState extends State<HomeView> {
|
|||
InvestType('Sharia', PathAssets.iconPortofolioSharia)
|
||||
];
|
||||
|
||||
StepVerification listStepVerification = StepVerification(0, [
|
||||
'Registration', 'Verification', 'Complete'
|
||||
]);
|
||||
StepVerification listStepVerification =
|
||||
StepVerification(0, ['Registration', 'Verification', 'Complete']);
|
||||
|
||||
List<Article> listArticle = [
|
||||
Article('Education', '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),
|
||||
Article(
|
||||
'Education',
|
||||
'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
|
||||
|
@ -85,22 +92,17 @@ class _HomeViewState extends State<HomeView> {
|
|||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w700
|
||||
),
|
||||
fontWeight: FontWeight.w700),
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
|
||||
},
|
||||
onPressed: () {},
|
||||
style: ElevatedButton.styleFrom(
|
||||
padding: const EdgeInsets.all(0),
|
||||
backgroundColor: Colors.white,
|
||||
foregroundColor: const Color(0xff2563EB),
|
||||
elevation: 0,
|
||||
shape: const CircleBorder()
|
||||
),
|
||||
child: const Icon(Icons.notifications_outlined)
|
||||
)
|
||||
shape: const CircleBorder()),
|
||||
child: const Icon(Icons.notifications_outlined))
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -148,7 +150,8 @@ class _HomeViewState extends State<HomeView> {
|
|||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const Text('Portofolio Value', style: TextStyle(color: Colors.white)),
|
||||
const Text('Portofolio Value',
|
||||
style: TextStyle(color: Colors.white)),
|
||||
const SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
|
@ -158,8 +161,11 @@ class _HomeViewState extends State<HomeView> {
|
|||
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(
|
||||
|
@ -170,11 +176,17 @@ class _HomeViewState extends State<HomeView> {
|
|||
AnimatedCrossFade(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
alignment: Alignment.center,
|
||||
crossFadeState: seePortofolioValue ? CrossFadeState.showSecond : CrossFadeState.showFirst,
|
||||
crossFadeState: seePortofolioValue
|
||||
? CrossFadeState.showSecond
|
||||
: CrossFadeState.showFirst,
|
||||
firstChild: RichText(
|
||||
text: const TextSpan(
|
||||
text: 'Rp ',
|
||||
style: TextStyle(fontSize: 32, color: Color(0xff93C5FD), fontFamily: 'Manrope',),
|
||||
style: TextStyle(
|
||||
fontSize: 32,
|
||||
color: Color(0xff93C5FD),
|
||||
fontFamily: 'Manrope',
|
||||
),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: '22.500.000',
|
||||
|
@ -185,9 +197,7 @@ class _HomeViewState extends State<HomeView> {
|
|||
fontFamily: 'Manrope',
|
||||
),
|
||||
)
|
||||
]
|
||||
)
|
||||
),
|
||||
])),
|
||||
secondChild: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||
child: Wrap(
|
||||
|
@ -197,7 +207,8 @@ class _HomeViewState extends State<HomeView> {
|
|||
Container(
|
||||
width: 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(
|
||||
spreadRadius: 2,
|
||||
blurRadius: 4,
|
||||
color: const Color(0xff1E293B).withOpacity(0.04)
|
||||
)
|
||||
]
|
||||
),
|
||||
color: const Color(0xff1E293B).withOpacity(0.04))
|
||||
]),
|
||||
child: Wrap(
|
||||
spacing: 10,
|
||||
children: listPortofolioType.asMap().entries.map((e) {
|
||||
|
@ -235,7 +244,11 @@ class _HomeViewState extends State<HomeView> {
|
|||
width: SizeConfig.width * .18,
|
||||
child: Column(
|
||||
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(
|
||||
height: 8,
|
||||
),
|
||||
|
@ -244,9 +257,7 @@ class _HomeViewState extends State<HomeView> {
|
|||
overflow: TextOverflow.ellipsis,
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600
|
||||
),
|
||||
fontSize: 12, fontWeight: FontWeight.w600),
|
||||
)
|
||||
],
|
||||
),
|
||||
|
@ -271,21 +282,22 @@ class _HomeViewState extends State<HomeView> {
|
|||
const SizedBox(
|
||||
height: 24,
|
||||
),
|
||||
if(listStepVerification.currentStep == 1)...[
|
||||
if (listStepVerification.currentStep == 1) ...[
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Row(
|
||||
children: [
|
||||
Icon(Icons.verified, size: 18,),
|
||||
Icon(
|
||||
Icons.verified,
|
||||
size: 18,
|
||||
),
|
||||
SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
Text(
|
||||
'Verified by PT Gemilang',
|
||||
style: TextStyle(
|
||||
color: ColorPalette.slate500
|
||||
),
|
||||
style: TextStyle(color: ColorPalette.slate500),
|
||||
)
|
||||
],
|
||||
),
|
||||
|
@ -294,9 +306,9 @@ class _HomeViewState extends State<HomeView> {
|
|||
height: 16,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: Border.all(color: const Color(0xffCBD5E1), width: 1.5),
|
||||
shape: BoxShape.circle
|
||||
),
|
||||
border: Border.all(
|
||||
color: const Color(0xffCBD5E1), width: 1.5),
|
||||
shape: BoxShape.circle),
|
||||
)
|
||||
],
|
||||
),
|
||||
|
@ -309,15 +321,16 @@ class _HomeViewState extends State<HomeView> {
|
|||
const Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Icon(Icons.verified, size: 18,),
|
||||
Icon(
|
||||
Icons.verified,
|
||||
size: 18,
|
||||
),
|
||||
SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
Text(
|
||||
'Verified by KSEI',
|
||||
style: TextStyle(
|
||||
color: ColorPalette.slate500
|
||||
),
|
||||
style: TextStyle(color: ColorPalette.slate500),
|
||||
)
|
||||
],
|
||||
),
|
||||
|
@ -326,9 +339,9 @@ class _HomeViewState extends State<HomeView> {
|
|||
height: 16,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: Border.all(color: const Color(0xffCBD5E1), width: 1.5),
|
||||
shape: BoxShape.circle
|
||||
),
|
||||
border: Border.all(
|
||||
color: const Color(0xffCBD5E1), width: 1.5),
|
||||
shape: BoxShape.circle),
|
||||
)
|
||||
],
|
||||
),
|
||||
|
@ -339,15 +352,12 @@ class _HomeViewState extends State<HomeView> {
|
|||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
color: ColorPalette.blue50,
|
||||
borderRadius: BorderRadius.circular(12)
|
||||
),
|
||||
borderRadius: BorderRadius.circular(12)),
|
||||
child: const Column(
|
||||
children: [
|
||||
Text(
|
||||
'Your registration is currently being verified by PT Gemilang',
|
||||
style: TextStyle(
|
||||
color: ColorPalette.slate500
|
||||
),
|
||||
style: TextStyle(color: ColorPalette.slate500),
|
||||
),
|
||||
SizedBox(
|
||||
height: 16,
|
||||
|
@ -355,37 +365,32 @@ class _HomeViewState extends State<HomeView> {
|
|||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('Estimated:',
|
||||
style: TextStyle(
|
||||
color: ColorPalette.slate500
|
||||
),
|
||||
Text(
|
||||
'Estimated:',
|
||||
style: TextStyle(color: ColorPalette.slate500),
|
||||
),
|
||||
Text(
|
||||
'January 30 2024',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xff1E293B)
|
||||
),
|
||||
color: Color(0xff1E293B)),
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
]else if(listStepVerification.currentStep == 0)...[
|
||||
] else if (listStepVerification.currentStep == 0) ...[
|
||||
Container(
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
color: ColorPalette.blue50,
|
||||
borderRadius: BorderRadius.circular(12)
|
||||
),
|
||||
borderRadius: BorderRadius.circular(12)),
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
"Let's start registering your data to start mutual fund investment at PT Gemilang Indonesia",
|
||||
style: TextStyle(
|
||||
color: ColorPalette.slate500
|
||||
),
|
||||
style: TextStyle(color: ColorPalette.slate500),
|
||||
),
|
||||
SizedBox(
|
||||
height: 16,
|
||||
|
@ -416,11 +421,15 @@ class _HomeViewState extends State<HomeView> {
|
|||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if(e.key != 0)
|
||||
if (e.key != 0)
|
||||
SizedBox(
|
||||
width: 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(
|
||||
children: [
|
||||
|
@ -429,18 +438,31 @@ class _HomeViewState extends State<HomeView> {
|
|||
height: 30,
|
||||
decoration: BoxDecoration(
|
||||
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(
|
||||
color: listStepVerification.currentStep < e.key ? const Color(0xffCBD5E1) : const Color(0xff2563EB),
|
||||
width: 2
|
||||
)
|
||||
color: listStepVerification.currentStep < e.key
|
||||
? 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(
|
||||
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,15 +477,22 @@ class _HomeViewState extends State<HomeView> {
|
|||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const TextTitle(title: 'Info and Special Promo', color: ColorPalette.slate800,),
|
||||
const TextTitle(
|
||||
title: 'Info and Special Promo',
|
||||
color: ColorPalette.slate800,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 16,
|
||||
),
|
||||
CarouselSlider(
|
||||
items: [1,2,3].map((e) {
|
||||
items: [1, 2, 3].map((e) {
|
||||
return Padding(
|
||||
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(),
|
||||
options: CarouselOptions(
|
||||
|
@ -493,14 +522,13 @@ class _HomeViewState extends State<HomeView> {
|
|||
children: [
|
||||
const TextTitle(title: 'Article', color: ColorPalette.slate800),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
|
||||
},
|
||||
child: const Text('See More',
|
||||
onTap: () {},
|
||||
child: const Text(
|
||||
'See More',
|
||||
style: TextStyle(
|
||||
color: ColorPalette.primary,
|
||||
fontWeight: FontWeight.bold
|
||||
),),
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
|
@ -511,10 +539,12 @@ class _HomeViewState extends State<HomeView> {
|
|||
...listArticle.asMap().entries.map((e) {
|
||||
return Column(
|
||||
children: [
|
||||
if(e.key != 0)...[
|
||||
if (e.key != 0) ...[
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 12),
|
||||
child: Divider(color: ColorPalette.slate200,),
|
||||
child: Divider(
|
||||
color: ColorPalette.slate200,
|
||||
),
|
||||
)
|
||||
],
|
||||
cardArticle(e.value),
|
||||
|
@ -531,7 +561,12 @@ class _HomeViewState extends State<HomeView> {
|
|||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
child: Row(
|
||||
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(
|
||||
width: 16,
|
||||
),
|
||||
|
@ -539,7 +574,8 @@ class _HomeViewState extends State<HomeView> {
|
|||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(article.title,
|
||||
Text(
|
||||
article.title,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
|
@ -548,22 +584,20 @@ class _HomeViewState extends State<HomeView> {
|
|||
height: 8,
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 12),
|
||||
padding:
|
||||
const EdgeInsets.symmetric(vertical: 4, horizontal: 12),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(30),
|
||||
color: ColorPalette.green100
|
||||
),
|
||||
color: ColorPalette.green100),
|
||||
child: Text(
|
||||
article.type,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: ColorPalette.green500
|
||||
),
|
||||
color: ColorPalette.green500),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
)
|
||||
))
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
|
@ -20,11 +20,25 @@ class InvestTypeView extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _InvestTypeViewState extends State<InvestTypeView> {
|
||||
|
||||
List<Product> listProduct = [
|
||||
Product(name: 'Gemilang Dana Kas Maxima', 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)
|
||||
Product(
|
||||
name: 'Gemilang Dana Kas Maxima',
|
||||
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
|
||||
|
@ -41,8 +55,7 @@ class _InvestTypeViewState extends State<InvestTypeView> {
|
|||
Widget build(BuildContext context) {
|
||||
return ChangeNotifierProvider<ProductViewModel>(
|
||||
create: (context) => ProductViewModel(),
|
||||
child: Consumer<ProductViewModel>(
|
||||
builder: (context, provider, child) {
|
||||
child: Consumer<ProductViewModel>(builder: (context, provider, child) {
|
||||
return Scaffold(
|
||||
body: SizedBox(
|
||||
width: SizeConfig.width,
|
||||
|
@ -52,8 +65,8 @@ class _InvestTypeViewState extends State<InvestTypeView> {
|
|||
const ImageView(image: PathAssets.imgDashboardAccount),
|
||||
Column(
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 50,
|
||||
SizedBox(
|
||||
height: SizeConfig.height * .1,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
|
@ -71,12 +84,14 @@ class _InvestTypeViewState extends State<InvestTypeView> {
|
|||
const SizedBox(
|
||||
height: 24,
|
||||
),
|
||||
Container(
|
||||
Expanded(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(24),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
color: Colors.white
|
||||
),
|
||||
color: Colors.white),
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.vertical,
|
||||
child: Column(
|
||||
children: [
|
||||
filters(),
|
||||
|
@ -86,10 +101,12 @@ class _InvestTypeViewState extends State<InvestTypeView> {
|
|||
return GestureDetector(
|
||||
onTap: () {
|
||||
provider.setSelectedProduct(e.value);
|
||||
routePush(context, page: ProductView(widget.title));
|
||||
routePush(context,
|
||||
page: ProductView(widget.title));
|
||||
},
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(top: e.key != 0 ? 24 : 0),
|
||||
padding: EdgeInsets.only(
|
||||
top: e.key != 0 ? 24 : 0),
|
||||
child: cardProduct(e.value),
|
||||
),
|
||||
);
|
||||
|
@ -98,14 +115,15 @@ class _InvestTypeViewState extends State<InvestTypeView> {
|
|||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
),
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -115,9 +133,25 @@ class _InvestTypeViewState extends State<InvestTypeView> {
|
|||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
segmentFilter(const Icon(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', () { }),
|
||||
segmentFilter(
|
||||
const Icon(
|
||||
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),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: ColorPalette.slate200),
|
||||
borderRadius: BorderRadius.circular(56)
|
||||
),
|
||||
borderRadius: BorderRadius.circular(56)),
|
||||
child: Row(
|
||||
children: [
|
||||
leading,
|
||||
|
@ -142,9 +175,7 @@ class _InvestTypeViewState extends State<InvestTypeView> {
|
|||
text,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(
|
||||
color: ColorPalette.slate500,
|
||||
fontWeight: FontWeight.w700
|
||||
),
|
||||
color: ColorPalette.slate500, fontWeight: FontWeight.w700),
|
||||
)
|
||||
],
|
||||
),
|
||||
|
@ -163,7 +194,10 @@ class _InvestTypeViewState extends State<InvestTypeView> {
|
|||
children: [
|
||||
Row(
|
||||
children: [
|
||||
ImageView(image: PathAssets.imgProduct, width: SizeConfig.width * .12,),
|
||||
ImageView(
|
||||
image: PathAssets.imgProduct,
|
||||
width: SizeConfig.width * .12,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 8,
|
||||
),
|
||||
|
@ -171,9 +205,7 @@ class _InvestTypeViewState extends State<InvestTypeView> {
|
|||
child: Text(
|
||||
product.name ?? '',
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 18
|
||||
),
|
||||
fontWeight: FontWeight.bold, fontSize: 18),
|
||||
),
|
||||
)
|
||||
],
|
||||
|
@ -187,36 +219,53 @@ class _InvestTypeViewState extends State<InvestTypeView> {
|
|||
children: [
|
||||
Column(
|
||||
children: [
|
||||
const Text('Yield', style: TextStyle(color: ColorPalette.slate400, fontWeight: FontWeight.w600),),
|
||||
const Text(
|
||||
'Yield',
|
||||
style: TextStyle(
|
||||
color: ColorPalette.slate400,
|
||||
fontWeight: FontWeight.w600),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'${product.yield.toString()}%',
|
||||
style: const TextStyle(
|
||||
color: ColorPalette.green400,
|
||||
fontWeight: FontWeight.w600
|
||||
),
|
||||
fontWeight: FontWeight.w600),
|
||||
),
|
||||
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(
|
||||
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(
|
||||
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(
|
||||
width: 2,
|
||||
),
|
||||
Text(
|
||||
NumberFormatter.numberCurrency(product.priceUnit, 'Rp', 'id_ID'),
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w600
|
||||
),
|
||||
NumberFormatter.numberCurrency(
|
||||
product.priceUnit, 'Rp', 'id_ID'),
|
||||
style: const TextStyle(fontWeight: FontWeight.w600),
|
||||
),
|
||||
],
|
||||
)
|
||||
|
@ -224,14 +273,18 @@ class _InvestTypeViewState extends State<InvestTypeView> {
|
|||
),
|
||||
Column(
|
||||
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(
|
||||
children: [
|
||||
Text(
|
||||
NumberFormatter.compactCurrency(product.funds, 'Rp ', 'id_ID'),
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w600
|
||||
),
|
||||
NumberFormatter.compactCurrency(
|
||||
product.funds, 'Rp ', 'id_ID'),
|
||||
style: const TextStyle(fontWeight: FontWeight.w600),
|
||||
),
|
||||
],
|
||||
)
|
||||
|
@ -243,5 +296,4 @@ class _InvestTypeViewState extends State<InvestTypeView> {
|
|||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import 'dart:math';
|
||||
|
||||
import 'package:cims_apps/application/assets/path_assets.dart';
|
||||
import 'package:cims_apps/application/component/image/image_view.dart';
|
||||
import 'package:cims_apps/application/theme/color_palette.dart';
|
||||
|
@ -70,7 +68,7 @@ class _PortofolioViewState extends State<PortofolioView> {
|
|||
),
|
||||
const Center(
|
||||
child: Text(
|
||||
'Portofolio',
|
||||
'Portfolio',
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w700,
|
||||
|
@ -125,20 +123,22 @@ class _PortofolioViewState extends State<PortofolioView> {
|
|||
),
|
||||
Column(
|
||||
children: [
|
||||
const Text('Total Mutual Fund',
|
||||
const Text(
|
||||
'Total Mutual Fund',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 18,
|
||||
color: ColorPalette.slate400
|
||||
color: ColorPalette.slate400),
|
||||
),
|
||||
),
|
||||
Text(listInvestmentType.map((e) => e.mutualFunds).reduce((value, element) => value + element).toString(),
|
||||
Text(
|
||||
listInvestmentType
|
||||
.map((e) => e.mutualFunds)
|
||||
.reduce(
|
||||
(value, element) => value + element)
|
||||
.toString(),
|
||||
style: const TextStyle(
|
||||
fontSize: 44,
|
||||
fontWeight: FontWeight.w700
|
||||
)
|
||||
)
|
||||
,
|
||||
fontWeight: FontWeight.w700)),
|
||||
],
|
||||
)
|
||||
]),
|
||||
|
@ -168,7 +168,7 @@ class _PortofolioViewState extends State<PortofolioView> {
|
|||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const Text('Portofolio Value',
|
||||
const Text('Portfolio Value',
|
||||
style: TextStyle(color: Colors.white)),
|
||||
const SizedBox(
|
||||
width: 8,
|
||||
|
@ -179,8 +179,11 @@ class _PortofolioViewState extends State<PortofolioView> {
|
|||
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(
|
||||
|
@ -197,7 +200,10 @@ class _PortofolioViewState extends State<PortofolioView> {
|
|||
firstChild: RichText(
|
||||
text: const TextSpan(
|
||||
text: 'Rp ',
|
||||
style: TextStyle(fontSize: 32, color: Color(0xff93C5FD), fontFamily: 'Manrope'),
|
||||
style: TextStyle(
|
||||
fontSize: 32,
|
||||
color: Color(0xff93C5FD),
|
||||
fontFamily: 'Manrope'),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: '22.500.000',
|
||||
|
@ -205,8 +211,7 @@ class _PortofolioViewState extends State<PortofolioView> {
|
|||
fontSize: 32,
|
||||
fontFamily: 'Manrope',
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.white
|
||||
),
|
||||
color: Colors.white),
|
||||
)
|
||||
])),
|
||||
secondChild: Padding(
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
}
|
|
@ -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/utils/size_config.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/dashboard/dashboard_public/viewmodel/dashboard_public_viewmodel.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class DashboardPublicView extends StatelessWidget {
|
||||
static const routeName = '/DashboardPublicView';
|
||||
|
@ -37,6 +38,9 @@ class DashboardPublicView extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChangeNotifierProvider(
|
||||
create: (context) => DashboardPublicViewModel(),
|
||||
builder: (context, child) {
|
||||
return Scaffold(
|
||||
body: SingleChildScrollView(
|
||||
padding: const EdgeInsets.only(
|
||||
|
@ -45,7 +49,9 @@ class DashboardPublicView extends StatelessWidget {
|
|||
left: 24.0,
|
||||
right: 24.0,
|
||||
),
|
||||
child: Column(
|
||||
child: Consumer<DashboardPublicViewModel>(
|
||||
builder: (context, provider, child) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
|
@ -96,9 +102,10 @@ class DashboardPublicView extends StatelessWidget {
|
|||
width: 26,
|
||||
),
|
||||
onPressed: () {
|
||||
routePush(context, page: const InitialRegistrationStep());
|
||||
provider.loginGoogle(context);
|
||||
},
|
||||
),
|
||||
SizedBox(height: SizeConfig.height * .15),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
|
@ -117,8 +124,10 @@ class DashboardPublicView extends StatelessWidget {
|
|||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
14
lib/features/profile/view/profile_view.dart
Normal file
14
lib/features/profile/view/profile_view.dart
Normal 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'),
|
||||
);
|
||||
}
|
||||
}
|
15
lib/features/transaction/view/transaction_view.dart
Normal file
15
lib/features/transaction/view/transaction_view.dart
Normal 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'),
|
||||
);
|
||||
}
|
||||
}
|
68
pubspec.lock
68
pubspec.lock
|
@ -49,6 +49,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -256,6 +264,54 @@ packages:
|
|||
description: flutter
|
||||
source: sdk
|
||||
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:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -292,10 +348,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: js
|
||||
sha256: "4186c61b32f99e60f011f7160e32c89a758ae9b1d0c6d28e2c02ef0382300e2b"
|
||||
sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.0"
|
||||
version: "0.7.1"
|
||||
lints:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -625,18 +681,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: syncfusion_flutter_core
|
||||
sha256: e8580e201c7197feac830b501889e877796a9fabbe20dcdbe90a981603939101
|
||||
sha256: "9f98e2726af42967497eaef68f3373261700bbfcd33bd97da4ec85cb56fcdaf7"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "24.2.4"
|
||||
version: "24.2.7"
|
||||
syncfusion_flutter_signaturepad:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: syncfusion_flutter_signaturepad
|
||||
sha256: "878e1063b909a83c83677627261780d42d532d0b5e7e259d84da805008e7fb0d"
|
||||
sha256: d51d5e346c70b938a8e1f2318a073213172aea7b99e33073c379657b1066c001
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "24.2.4"
|
||||
version: "24.2.7"
|
||||
synchronized:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
@ -51,6 +51,9 @@ dependencies:
|
|||
syncfusion_flutter_signaturepad: ^24.2.4
|
||||
dotted_border: ^2.1.0
|
||||
shared_preferences: ^2.2.2
|
||||
calendar_date_picker2: ^0.5.3
|
||||
google_sign_in: ^6.2.1
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user