Compare commits
	
		
			8 Commits
		
	
	
		
			6e2516d9c8
			...
			0a347f5e6d
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 0a347f5e6d | |||
| 4d58a7dced | |||
| 81231505b1 | |||
| 96c676ac4c | |||
| e1cabe0a09 | |||
| d82d427bcc | |||
| f407eca735 | |||
| 0e7ad81345 | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/icon-portofolio-bonds.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 2.9 KiB | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/icon-portofolio-moneymarket.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 3.3 KiB | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/icon-portofolio-shares.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 2.4 KiB | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/icon-portofolio-sharia.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 3.9 KiB | 
							
								
								
									
										
											BIN
										
									
								
								assets/images/img-articles.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 154 KiB | 
							
								
								
									
										
											BIN
										
									
								
								assets/images/img-carousel.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 636 KiB | 
							
								
								
									
										
											BIN
										
									
								
								assets/images/img-dashboard-account.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 1.3 MiB | 
							
								
								
									
										
											BIN
										
									
								
								assets/images/img-product.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 4.5 KiB | 
| @@ -10,6 +10,10 @@ class PathAssets { | |||||||
|   static const String iconGoogle = 'assets/icons/icon-google.png'; |   static const String iconGoogle = 'assets/icons/icon-google.png'; | ||||||
|   static const String icon1 = 'assets/icons/icon-1.png'; |   static const String icon1 = 'assets/icons/icon-1.png'; | ||||||
|   static const String iconConnect = 'assets/icons/icon-connect.png'; |   static const String iconConnect = 'assets/icons/icon-connect.png'; | ||||||
|  |   static const String iconPortofolioBonds = 'assets/icons/icon-portofolio-bonds.png'; | ||||||
|  |   static const String iconPortofolioShares = 'assets/icons/icon-portofolio-shares.png'; | ||||||
|  |   static const String iconPortofolioSharia = 'assets/icons/icon-portofolio-sharia.png'; | ||||||
|  |   static const String iconPortofolioMoneyMarket = 'assets/icons/icon-portofolio-moneymarket.png'; | ||||||
|   static const String iconShield = 'assets/icons/icon-shield.png'; |   static const String iconShield = 'assets/icons/icon-shield.png'; | ||||||
|   static const String iconFlag = 'assets/icons/icon-flag.png'; |   static const String iconFlag = 'assets/icons/icon-flag.png'; | ||||||
|  |  | ||||||
| @@ -24,5 +28,9 @@ class PathAssets { | |||||||
|   static const String imgKtpCropped = 'assets/images/img-ktp-cropped.png'; |   static const String imgKtpCropped = 'assets/images/img-ktp-cropped.png'; | ||||||
|   static const String imgKtpClear = 'assets/images/img-ktp-clear.png'; |   static const String imgKtpClear = 'assets/images/img-ktp-clear.png'; | ||||||
|   static const String imgKtpBlur = 'assets/images/img-ktp-blur.png'; |   static const String imgKtpBlur = 'assets/images/img-ktp-blur.png'; | ||||||
|  |   static const String imgDashboardAccount = 'assets/images/img-dashboard-account.png'; | ||||||
|  |   static const String imgCarousel = 'assets/images/img-carousel.png'; | ||||||
|  |   static const String imgArticles = 'assets/images/img-articles.png'; | ||||||
|  |   static const String imgProduct = 'assets/images/img-product.png'; | ||||||
|   static const String imgSuccessSignup = 'assets/images/img-success-signup.png'; |   static const String imgSuccessSignup = 'assets/images/img-success-signup.png'; | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										23
									
								
								lib/application/component/button/button_back.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,23 @@ | |||||||
|  | import 'package:cims_apps/core/utils/size_config.dart'; | ||||||
|  | import 'package:flutter/material.dart'; | ||||||
|  |  | ||||||
|  | class ButtonBack extends StatelessWidget { | ||||||
|  |   const ButtonBack({super.key}); | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) { | ||||||
|  |     return SizedBox( | ||||||
|  |       width: SizeConfig.width * 0.1, | ||||||
|  |       child: IconButton( | ||||||
|  |           style: IconButton.styleFrom( | ||||||
|  |               backgroundColor: Colors.white, | ||||||
|  |               shape: const CircleBorder() | ||||||
|  |           ), | ||||||
|  |           onPressed: () { | ||||||
|  |             Navigator.pop(context); | ||||||
|  |           }, | ||||||
|  |           icon: const Icon(Icons.arrow_back) | ||||||
|  |       ), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -9,13 +9,14 @@ class ButtonView extends StatelessWidget { | |||||||
|   final double? height, width, widthSuffix, widthPrefix, marginVertical; |   final double? height, width, widthSuffix, widthPrefix, marginVertical; | ||||||
|   final EdgeInsetsGeometry? contentPadding; |   final EdgeInsetsGeometry? contentPadding; | ||||||
|   final bool isSecondaryColor, isOutlined, heightWrapContent, disabled; |   final bool isSecondaryColor, isOutlined, heightWrapContent, disabled; | ||||||
|   final Color? backgroundColor, textColor; |   final Color? backgroundColor, textColor, borderColor; | ||||||
|   final MainAxisAlignment? mainAxisAlignmentContent; |   final MainAxisAlignment? mainAxisAlignmentContent; | ||||||
|   // final _widthBtn = SizeConfig.screenWidth / 1.5; |   // final _widthBtn = SizeConfig.screenWidth / 1.5; | ||||||
|   final _widthBtn = SizeConfig.width * .9; |   final _widthBtn = SizeConfig.width * .9; | ||||||
|   // final _heightBtn = SizeConfig.screenHeight / 12; |   // final _heightBtn = SizeConfig.screenHeight / 12; | ||||||
|   final _heightBtn = SizeConfig.height * .07; |   final _heightBtn = SizeConfig.height * .07; | ||||||
|   final FontWeight textWeight; |   final FontWeight textWeight; | ||||||
|  |   final TextAlign textAlign; | ||||||
|   final double? textSize, sizeBorderRadius; |   final double? textSize, sizeBorderRadius; | ||||||
|   final int? maxLines; |   final int? maxLines; | ||||||
|  |  | ||||||
| @@ -31,9 +32,11 @@ class ButtonView extends StatelessWidget { | |||||||
|       this.width, |       this.width, | ||||||
|       this.contentPadding, |       this.contentPadding, | ||||||
|       this.backgroundColor, |       this.backgroundColor, | ||||||
|  |       this.borderColor, | ||||||
|       this.textColor, |       this.textColor, | ||||||
|       this.textWeight = FontWeight.bold, |       this.textWeight = FontWeight.bold, | ||||||
|       this.textSize, |       this.textSize, | ||||||
|  |       this.textAlign = TextAlign.center, | ||||||
|       this.mainAxisAlignmentContent, |       this.mainAxisAlignmentContent, | ||||||
|       this.disabled = false, |       this.disabled = false, | ||||||
|       this.heightWrapContent = false, |       this.heightWrapContent = false, | ||||||
| @@ -75,11 +78,11 @@ class ButtonView extends StatelessWidget { | |||||||
|               borderRadius: BorderRadius.circular(sizeBorderRadius ?? 48), |               borderRadius: BorderRadius.circular(sizeBorderRadius ?? 48), | ||||||
|               side: isOutlined |               side: isOutlined | ||||||
|                   ? BorderSide( |                   ? BorderSide( | ||||||
|                       color: disabled |                       color: borderColor ?? (disabled | ||||||
|                           ? ColorPalette.greyBorder |                           ? color.surface | ||||||
|                           : isSecondaryColor |                           : isSecondaryColor | ||||||
|                               ? ColorPalette.greyBorder |                           ? ColorPalette.greyBorder | ||||||
|                               : ColorPalette.primary, |                           : ColorPalette.primary), | ||||||
|                     ) |                     ) | ||||||
|                   : BorderSide.none, |                   : BorderSide.none, | ||||||
|             ), |             ), | ||||||
| @@ -101,7 +104,7 @@ class ButtonView extends StatelessWidget { | |||||||
|               Flexible( |               Flexible( | ||||||
|                 child: Text( |                 child: Text( | ||||||
|                   name, |                   name, | ||||||
|                   textAlign: TextAlign.center, |                   textAlign: textAlign, | ||||||
|                   maxLines: maxLines, |                   maxLines: maxLines, | ||||||
|                   overflow: TextOverflow.ellipsis, |                   overflow: TextOverflow.ellipsis, | ||||||
|                   style: TextStyle( |                   style: TextStyle( | ||||||
|   | |||||||
							
								
								
									
										26
									
								
								lib/application/component/text_title/text_title.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,26 @@ | |||||||
|  | import 'package:cims_apps/application/theme/color_palette.dart'; | ||||||
|  | import 'package:flutter/cupertino.dart'; | ||||||
|  |  | ||||||
|  | class TextTitle extends StatelessWidget { | ||||||
|  |   final String title; | ||||||
|  |   final Color? color; | ||||||
|  |   final double? fontSize; | ||||||
|  |   const TextTitle({ | ||||||
|  |     Key? key, | ||||||
|  |     required this.title, | ||||||
|  |     this.color, | ||||||
|  |     this.fontSize, | ||||||
|  |   }) : super(key: key); | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) { | ||||||
|  |     return Text( | ||||||
|  |       title, | ||||||
|  |       style: TextStyle( | ||||||
|  |         fontSize: fontSize ?? 20, | ||||||
|  |         fontWeight: FontWeight.w700, | ||||||
|  |         color: color ?? ColorPalette.slate800, | ||||||
|  |       ), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -74,5 +74,37 @@ class ColorPalette { | |||||||
|   static const Color background = Color(0xFFDADADA); |   static const Color background = Color(0xFFDADADA); | ||||||
|   static const Color backgroundBlueLight = Color(0xFFEBF3FD); |   static const Color backgroundBlueLight = Color(0xFFEBF3FD); | ||||||
|   static const Color slate500 = Color(0xFF64748B); |   static const Color slate500 = Color(0xFF64748B); | ||||||
|  |   static const Color blue50 = Color(0xFFEFF6FF); | ||||||
|  |   static const Color blue200 = Color(0xFFBFDBFE); | ||||||
|  |   static const Color slate50 = Color(0xFFF8FAFC); | ||||||
|  |   static const Color slate200 = Color(0xFFE2E8F0); | ||||||
|  |   static const Color slate300 = Color(0xFFCBD5E1); | ||||||
|  |   static const Color slate400 = Color(0xFF94A3B8); | ||||||
|  |   static const Color slate500 = Color(0xFF64748B); | ||||||
|   static const Color slate800 = Color(0xFF1E293B); |   static const Color slate800 = Color(0xFF1E293B); | ||||||
|  |   static const Color purple100 = Color(0xFFEDE9FE); | ||||||
|  |   static const Color purple500 = Color(0xFF8B5CF6); | ||||||
|  |   static const Color orange50 = Color(0xFFFFF7ED); | ||||||
|  |   static const Color orange100 = Color(0xFFFFEDD5); | ||||||
|  |   static const Color orange500 = Color(0xFFF97316); | ||||||
|  |   static const Color cyan100 = Color(0xFFCFFAFE); | ||||||
|  |   static const Color cyan500 = Color(0xFF06B6D4); | ||||||
|  |   static const Color green100 = Color(0xFFDCFCE7); | ||||||
|  |   static const Color green400 = Color(0xFF4ADE80); | ||||||
|  |   static const Color green500 = Color(0xFF16A34A); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   static const Map<String, Color> investTypeColor = { | ||||||
|  |     'Money Market': purple500, | ||||||
|  |     'Shares': orange500, | ||||||
|  |     'Sharia': green500, | ||||||
|  |     'Bonds': cyan500 | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   static const Map<String, Color> investTypeBgColor = { | ||||||
|  |     'Money Market': purple100, | ||||||
|  |     'Shares': orange100, | ||||||
|  |     'Sharia': green100, | ||||||
|  |     'Bonds': cyan100 | ||||||
|  |   }; | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										3
									
								
								lib/core/utils/date_formatter.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,3 @@ | |||||||
|  | class DateFormatter { | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										19
									
								
								lib/core/utils/number_formatter.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,19 @@ | |||||||
|  | import 'package:intl/intl.dart'; | ||||||
|  |  | ||||||
|  | class NumberFormatter { | ||||||
|  |   NumberFormatter._(); | ||||||
|  |  | ||||||
|  |   static String numberCurrency(dynamic value, String symbol, String locale, {int? decimalDigits = 2}) { | ||||||
|  |     NumberFormat numberFormat = NumberFormat.currency(locale: locale, symbol: symbol, decimalDigits: decimalDigits); | ||||||
|  |     String formatValue = numberFormat.format(value); | ||||||
|  |  | ||||||
|  |     return formatValue; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static compactCurrency(dynamic value, String symbol, String locale) { | ||||||
|  |     NumberFormat numberFormat = NumberFormat.compactCurrency(locale: locale, symbol: symbol); | ||||||
|  |     String formatValue = numberFormat.format(value); | ||||||
|  |  | ||||||
|  |     return formatValue; | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -1,4 +1,6 @@ | |||||||
| import 'package:cims_apps/application/theme/color_palette.dart'; | import 'package:cims_apps/application/theme/color_palette.dart'; | ||||||
|  | import 'package:cims_apps/features/dashboard/dashboard_account/view/homepage/homepage_view.dart'; | ||||||
|  | import 'package:cims_apps/features/dashboard/dashboard_account/view/portfolio/portfolio_view.dart'; | ||||||
| import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||||
|  |  | ||||||
| class BottomNavigationView extends StatefulWidget { | class BottomNavigationView extends StatefulWidget { | ||||||
| @@ -15,15 +17,12 @@ class _BottomNavigationViewState extends State<BottomNavigationView> { | |||||||
|   Widget build(BuildContext context) { |   Widget build(BuildContext context) { | ||||||
|     ///TODO: masukan pagenya dilistWidget ini |     ///TODO: masukan pagenya dilistWidget ini | ||||||
|     List<Widget> listWidget = [ |     List<Widget> listWidget = [ | ||||||
|       Container( |       HomeView(), | ||||||
|         color: Colors.amberAccent, |  | ||||||
|       ), |  | ||||||
|       Container( |       Container( | ||||||
|         color: Colors.redAccent, |         color: Colors.redAccent, | ||||||
|       ), |       ), | ||||||
|       Container(), |       Container(), | ||||||
|       Container(), |       PortofolioView(), | ||||||
|       Container(), |  | ||||||
|       Container(), |       Container(), | ||||||
|     ]; |     ]; | ||||||
|  |  | ||||||
| @@ -60,6 +59,7 @@ class _BottomNavigationViewState extends State<BottomNavigationView> { | |||||||
|         }, |         }, | ||||||
|         currentIndex: _selectedIndex, |         currentIndex: _selectedIndex, | ||||||
|         items: listNavigation, |         items: listNavigation, | ||||||
|  |         type: BottomNavigationBarType.fixed, | ||||||
|         showUnselectedLabels: true, |         showUnselectedLabels: true, | ||||||
|         selectedItemColor: ColorPalette.primary, |         selectedItemColor: ColorPalette.primary, | ||||||
|         unselectedItemColor: Colors.black, |         unselectedItemColor: Colors.black, | ||||||
|   | |||||||
| @@ -0,0 +1,529 @@ | |||||||
|  | import 'package:carousel_slider/carousel_slider.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/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/dashboard/dashboard_account/view/invest_type/invest_type_view.dart'; | ||||||
|  | import 'package:flutter/material.dart'; | ||||||
|  |  | ||||||
|  | class InvestType { | ||||||
|  |   String name; | ||||||
|  |   String iconImage; | ||||||
|  |  | ||||||
|  |   InvestType(this.name, this.iconImage); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class StepVerification { | ||||||
|  |   int currentStep; | ||||||
|  |   List<String> nameStep; | ||||||
|  |  | ||||||
|  |   StepVerification(this.currentStep, this.nameStep); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class Article { | ||||||
|  |   String image; | ||||||
|  |   String title; | ||||||
|  |   String type; | ||||||
|  |  | ||||||
|  |   Article(this.type, this.title, this.image); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class HomeView extends StatefulWidget { | ||||||
|  |   const HomeView({super.key}); | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   State<HomeView> createState() => _HomeViewState(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class _HomeViewState extends State<HomeView> { | ||||||
|  |   bool seePortofolioValue = false; | ||||||
|  |  | ||||||
|  |   List<InvestType> listPortofolioType = [ | ||||||
|  |     InvestType('Money Market', PathAssets.iconPortofolioMoneyMarket), | ||||||
|  |     InvestType('Shares', PathAssets.iconPortofolioShares), | ||||||
|  |     InvestType('Bonds', PathAssets.iconPortofolioBonds), | ||||||
|  |     InvestType('Sharia', PathAssets.iconPortofolioSharia) | ||||||
|  |   ]; | ||||||
|  |  | ||||||
|  |   StepVerification listStepVerification = StepVerification(1, [ | ||||||
|  |     '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), | ||||||
|  |   ]; | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) { | ||||||
|  |     return Scaffold( | ||||||
|  |       backgroundColor: const Color(0xffF8FAFC), | ||||||
|  |       body: SizedBox( | ||||||
|  |         width: SizeConfig.width, | ||||||
|  |         height: SizeConfig.height, | ||||||
|  |         child: Stack( | ||||||
|  |           children: [ | ||||||
|  |             const ImageView(image: PathAssets.imgDashboardAccount), | ||||||
|  |             Column( | ||||||
|  |               children: [ | ||||||
|  |                 const SizedBox( | ||||||
|  |                   height: 50, | ||||||
|  |                 ), | ||||||
|  |                 Padding( | ||||||
|  |                   padding: const EdgeInsets.only(left: 24, right: 16), | ||||||
|  |                   child: Row( | ||||||
|  |                     mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||||
|  |                     children: [ | ||||||
|  |                       const Text( | ||||||
|  |                         'Home', | ||||||
|  |                         style: TextStyle( | ||||||
|  |                             color: Colors.white, | ||||||
|  |                             fontSize: 20, | ||||||
|  |                             fontWeight: FontWeight.w700 | ||||||
|  |                         ), | ||||||
|  |                       ), | ||||||
|  |                       ElevatedButton( | ||||||
|  |                           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) | ||||||
|  |                       ) | ||||||
|  |                     ], | ||||||
|  |                   ), | ||||||
|  |                 ), | ||||||
|  |                 const SizedBox( | ||||||
|  |                   height: 32, | ||||||
|  |                 ), | ||||||
|  |                 Padding( | ||||||
|  |                   padding: const EdgeInsets.symmetric(horizontal: 24), | ||||||
|  |                   child: portofolioValue(), | ||||||
|  |                 ), | ||||||
|  |                 const SizedBox( | ||||||
|  |                   height: 24, | ||||||
|  |                 ), | ||||||
|  |                 cardInvestType(), | ||||||
|  |                 const SizedBox( | ||||||
|  |                   height: 32, | ||||||
|  |                 ), | ||||||
|  |                 Expanded( | ||||||
|  |                   child: ListView( | ||||||
|  |                     padding: const EdgeInsets.all(0), | ||||||
|  |                     children: [ | ||||||
|  |                       cardVerification(), | ||||||
|  |                       const SizedBox( | ||||||
|  |                         height: 24, | ||||||
|  |                       ), | ||||||
|  |                       infoAndPromo(), | ||||||
|  |                       const SizedBox( | ||||||
|  |                         height: 24, | ||||||
|  |                       ), | ||||||
|  |                       articles(), | ||||||
|  |                     ], | ||||||
|  |                   ), | ||||||
|  |                 ), | ||||||
|  |               ], | ||||||
|  |             ) | ||||||
|  |           ], | ||||||
|  |         ), | ||||||
|  |       ), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Widget portofolioValue() { | ||||||
|  |     return Column( | ||||||
|  |       crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |       children: [ | ||||||
|  |         Row( | ||||||
|  |           children: [ | ||||||
|  |             const Text('Portofolio Value', style: TextStyle(color: Colors.white)), | ||||||
|  |             const SizedBox( | ||||||
|  |               width: 12, | ||||||
|  |             ), | ||||||
|  |             GestureDetector( | ||||||
|  |                 onTap: () { | ||||||
|  |                   setState(() { | ||||||
|  |                     seePortofolioValue = !seePortofolioValue; | ||||||
|  |                   }); | ||||||
|  |                 }, | ||||||
|  |                 child: const Icon(Icons.visibility_outlined, color: Color(0xff93C5FD)) | ||||||
|  |             ) | ||||||
|  |           ], | ||||||
|  |         ), | ||||||
|  |         const SizedBox( | ||||||
|  |           height: 4, | ||||||
|  |         ), | ||||||
|  |         Row( | ||||||
|  |           children: [ | ||||||
|  |             AnimatedCrossFade( | ||||||
|  |               duration: const Duration(milliseconds: 300), | ||||||
|  |               alignment: Alignment.center, | ||||||
|  |               crossFadeState: seePortofolioValue ? CrossFadeState.showSecond : CrossFadeState.showFirst, | ||||||
|  |               firstChild: RichText( | ||||||
|  |                   text: const TextSpan( | ||||||
|  |                       text: 'Rp ', | ||||||
|  |                       style: TextStyle(fontSize: 32, color: Color(0xff93C5FD), fontFamily: 'Manrope',), | ||||||
|  |                       children: [ | ||||||
|  |                         TextSpan( | ||||||
|  |                           text: '22.500.000', | ||||||
|  |                           style: TextStyle( | ||||||
|  |                               fontSize: 32, | ||||||
|  |                               fontWeight: FontWeight.bold, | ||||||
|  |                               color: Colors.white, | ||||||
|  |                               fontFamily: 'Manrope', | ||||||
|  |                           ), | ||||||
|  |                         ) | ||||||
|  |                       ] | ||||||
|  |                   ) | ||||||
|  |               ), | ||||||
|  |               secondChild: Padding( | ||||||
|  |                 padding: const EdgeInsets.symmetric(vertical: 16), | ||||||
|  |                 child: Wrap( | ||||||
|  |                   spacing: 7, | ||||||
|  |                   children: [ | ||||||
|  |                     for (int i = 0; i < 6; i++) | ||||||
|  |                       Container( | ||||||
|  |                         width: 12, | ||||||
|  |                         height: 12, | ||||||
|  |                         decoration: const BoxDecoration(color: Colors.white, shape: BoxShape.circle), | ||||||
|  |                       ), | ||||||
|  |                   ], | ||||||
|  |                 ), | ||||||
|  |               ), | ||||||
|  |             ), | ||||||
|  |           ], | ||||||
|  |         ) | ||||||
|  |       ], | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Widget cardInvestType() { | ||||||
|  |     return Container( | ||||||
|  |       padding: const EdgeInsets.all(16), | ||||||
|  |       decoration: BoxDecoration( | ||||||
|  |           color: Colors.white, | ||||||
|  |           borderRadius: BorderRadius.circular(12), | ||||||
|  |           boxShadow: [ | ||||||
|  |             BoxShadow( | ||||||
|  |                 spreadRadius: 2, | ||||||
|  |                 blurRadius: 4, | ||||||
|  |                 color: const Color(0xff1E293B).withOpacity(0.04) | ||||||
|  |             ) | ||||||
|  |           ] | ||||||
|  |       ), | ||||||
|  |       child: Wrap( | ||||||
|  |         spacing: 10, | ||||||
|  |         children: listPortofolioType.asMap().entries.map((e) { | ||||||
|  |           return  GestureDetector( | ||||||
|  |             onTap: () { | ||||||
|  |               routePush(context, page: InvestTypeView(e.value.name)); | ||||||
|  |             }, | ||||||
|  |             child: Container( | ||||||
|  |               color: Colors.white, | ||||||
|  |               width: SizeConfig.width * .18, | ||||||
|  |               child: Column( | ||||||
|  |                 children: [ | ||||||
|  |                   ImageView(image: e.value.iconImage, height: SizeConfig.width * .12, width: SizeConfig.width * .12,), | ||||||
|  |                   const SizedBox( | ||||||
|  |                     height: 8, | ||||||
|  |                   ), | ||||||
|  |                   Text( | ||||||
|  |                     e.value.name, | ||||||
|  |                     overflow: TextOverflow.ellipsis, | ||||||
|  |                     textAlign: TextAlign.center, | ||||||
|  |                     style: const TextStyle( | ||||||
|  |                       fontSize: 12, | ||||||
|  |                       fontWeight: FontWeight.w600 | ||||||
|  |                     ), | ||||||
|  |                   ) | ||||||
|  |                 ], | ||||||
|  |               ), | ||||||
|  |             ), | ||||||
|  |           ); | ||||||
|  |         }).toList(), | ||||||
|  |       ), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Widget cardVerification() { | ||||||
|  |     return Container( | ||||||
|  |       margin: const EdgeInsets.symmetric(horizontal: 24), | ||||||
|  |       padding: const EdgeInsets.all(16), | ||||||
|  |       decoration: BoxDecoration( | ||||||
|  |         color: Colors.white, | ||||||
|  |         borderRadius: BorderRadius.circular(12), | ||||||
|  |       ), | ||||||
|  |       child: Column( | ||||||
|  |         children: [ | ||||||
|  |           stepVerification(), | ||||||
|  |           const SizedBox( | ||||||
|  |             height: 24, | ||||||
|  |           ), | ||||||
|  |           Row( | ||||||
|  |             mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||||
|  |             children: [ | ||||||
|  |               const Row( | ||||||
|  |                 children: [ | ||||||
|  |                   Icon(Icons.verified, size: 18,), | ||||||
|  |                   SizedBox( | ||||||
|  |                     width: 12, | ||||||
|  |                   ), | ||||||
|  |                   Text( | ||||||
|  |                     'Verified by PT Gemilang', | ||||||
|  |                     style: TextStyle( | ||||||
|  |                       color: ColorPalette.slate500 | ||||||
|  |                     ), | ||||||
|  |                   ) | ||||||
|  |                 ], | ||||||
|  |               ), | ||||||
|  |               Container( | ||||||
|  |                 width: 16, | ||||||
|  |                 height: 16, | ||||||
|  |                 decoration: BoxDecoration( | ||||||
|  |                     color: Colors.white, | ||||||
|  |                     border: Border.all(color: const Color(0xffCBD5E1), width: 1.5), | ||||||
|  |                     shape: BoxShape.circle | ||||||
|  |                 ), | ||||||
|  |               ) | ||||||
|  |             ], | ||||||
|  |           ), | ||||||
|  |           const SizedBox( | ||||||
|  |             height: 16, | ||||||
|  |           ), | ||||||
|  |           Row( | ||||||
|  |             mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||||
|  |             children: [ | ||||||
|  |               const Row( | ||||||
|  |                 crossAxisAlignment: CrossAxisAlignment.end, | ||||||
|  |                 children: [ | ||||||
|  |                   Icon(Icons.verified, size: 18,), | ||||||
|  |                   SizedBox( | ||||||
|  |                     width: 12, | ||||||
|  |                   ), | ||||||
|  |                   Text( | ||||||
|  |                     'Verified by KSEI', | ||||||
|  |                     style: TextStyle( | ||||||
|  |                         color: ColorPalette.slate500 | ||||||
|  |                     ), | ||||||
|  |                   ) | ||||||
|  |                 ], | ||||||
|  |               ), | ||||||
|  |               Container( | ||||||
|  |                 width: 16, | ||||||
|  |                 height: 16, | ||||||
|  |                 decoration: BoxDecoration( | ||||||
|  |                     color: Colors.white, | ||||||
|  |                     border: Border.all(color: const Color(0xffCBD5E1), width: 1.5), | ||||||
|  |                     shape: BoxShape.circle | ||||||
|  |                 ), | ||||||
|  |               ) | ||||||
|  |             ], | ||||||
|  |           ), | ||||||
|  |           const SizedBox( | ||||||
|  |             height: 16, | ||||||
|  |           ), | ||||||
|  |           Container( | ||||||
|  |             padding: const EdgeInsets.all(12), | ||||||
|  |             decoration: BoxDecoration( | ||||||
|  |                 color: ColorPalette.blue50, | ||||||
|  |                 borderRadius: BorderRadius.circular(12) | ||||||
|  |             ), | ||||||
|  |             child: const Column( | ||||||
|  |               children: [ | ||||||
|  |                 Text( | ||||||
|  |                   'Your registration is currently being verified by PT Gemilang', | ||||||
|  |                   style: TextStyle( | ||||||
|  |                       color: ColorPalette.slate500 | ||||||
|  |                   ), | ||||||
|  |                 ), | ||||||
|  |                 SizedBox( | ||||||
|  |                   height: 16, | ||||||
|  |                 ), | ||||||
|  |                 Row( | ||||||
|  |                   mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||||
|  |                   children: [ | ||||||
|  |                     Text('Estimated:', | ||||||
|  |                       style: TextStyle( | ||||||
|  |                         color: ColorPalette.slate500 | ||||||
|  |                       ), | ||||||
|  |                     ), | ||||||
|  |                     Text( | ||||||
|  |                       'January 30 2024', | ||||||
|  |                       style: TextStyle( | ||||||
|  |                           fontWeight: FontWeight.w600, | ||||||
|  |                           color: Color(0xff1E293B) | ||||||
|  |                       ), | ||||||
|  |                     ) | ||||||
|  |                   ], | ||||||
|  |                 ) | ||||||
|  |               ], | ||||||
|  |             ), | ||||||
|  |           ) | ||||||
|  |         ], | ||||||
|  |       ), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Widget stepVerification() { | ||||||
|  |     return Row( | ||||||
|  |       mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||||
|  |       children: listStepVerification.nameStep.asMap().entries.map((e) { | ||||||
|  |         return Row( | ||||||
|  |           crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |           children: [ | ||||||
|  |             if(e.key != 0) | ||||||
|  |               SizedBox( | ||||||
|  |                 width: 30, | ||||||
|  |                 height: 30, | ||||||
|  |                 child: Divider(color: listStepVerification.currentStep >= e.key ? const Color(0xff2563EB) : const Color(0xffCBD5E1),), | ||||||
|  |               ), | ||||||
|  |             Column( | ||||||
|  |               children: [ | ||||||
|  |                 Container( | ||||||
|  |                   width: 30, | ||||||
|  |                   height: 30, | ||||||
|  |                   decoration: BoxDecoration( | ||||||
|  |                       shape: BoxShape.circle, | ||||||
|  |                       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 | ||||||
|  |                       ) | ||||||
|  |                   ), | ||||||
|  |                   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),) | ||||||
|  |               ], | ||||||
|  |             ), | ||||||
|  |           ], | ||||||
|  |         ); | ||||||
|  |       }).toList(), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Widget infoAndPromo() { | ||||||
|  |     return Padding( | ||||||
|  |       padding: const EdgeInsets.symmetric(horizontal: 24), | ||||||
|  |       child: Column( | ||||||
|  |         crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |         children: [ | ||||||
|  |           const TextTitle(title: 'Info and Special Promo', color: ColorPalette.slate800,), | ||||||
|  |           const SizedBox( | ||||||
|  |             height: 16, | ||||||
|  |           ), | ||||||
|  |           CarouselSlider( | ||||||
|  |             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,), | ||||||
|  |               ); | ||||||
|  |             }).toList(), | ||||||
|  |             options: CarouselOptions( | ||||||
|  |               height: 150, | ||||||
|  |               autoPlay: true, | ||||||
|  |               pageSnapping: true, | ||||||
|  |               viewportFraction: 0.9, | ||||||
|  |               autoPlayInterval: const Duration(seconds: 5), | ||||||
|  |               autoPlayCurve: Curves.fastOutSlowIn, | ||||||
|  |             ), | ||||||
|  |           ) | ||||||
|  |         ], | ||||||
|  |       ), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Widget articles() { | ||||||
|  |     return Container( | ||||||
|  |       color: Colors.white, | ||||||
|  |       padding: const EdgeInsets.symmetric(vertical: 24), | ||||||
|  |       child: Column( | ||||||
|  |         children: [ | ||||||
|  |           Padding( | ||||||
|  |             padding: const EdgeInsets.symmetric(horizontal: 24), | ||||||
|  |             child: Row( | ||||||
|  |               mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||||
|  |               children: [ | ||||||
|  |                 const TextTitle(title: 'Article', color: ColorPalette.slate800), | ||||||
|  |                 GestureDetector( | ||||||
|  |                   onTap: () { | ||||||
|  |  | ||||||
|  |                   }, | ||||||
|  |                   child: const Text('See More', | ||||||
|  |                     style: TextStyle( | ||||||
|  |                       color: ColorPalette.primary, | ||||||
|  |                       fontWeight: FontWeight.bold | ||||||
|  |                     ),), | ||||||
|  |                 ) | ||||||
|  |               ], | ||||||
|  |             ), | ||||||
|  |           ), | ||||||
|  |           const SizedBox( | ||||||
|  |             height: 16, | ||||||
|  |           ), | ||||||
|  |           ...listArticle.asMap().entries.map((e) { | ||||||
|  |             return Column( | ||||||
|  |               children: [ | ||||||
|  |                 if(e.key != 0)...[ | ||||||
|  |                   const Padding( | ||||||
|  |                     padding: EdgeInsets.symmetric(vertical: 12), | ||||||
|  |                     child: Divider(color: ColorPalette.slate200,), | ||||||
|  |                   ) | ||||||
|  |                 ], | ||||||
|  |                 cardArticle(e.value), | ||||||
|  |               ], | ||||||
|  |             ); | ||||||
|  |           }) | ||||||
|  |         ], | ||||||
|  |       ), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Widget cardArticle(Article article) { | ||||||
|  |     return Padding( | ||||||
|  |       padding: const EdgeInsets.symmetric(horizontal: 24), | ||||||
|  |       child: Row( | ||||||
|  |         children: [ | ||||||
|  |           ImageView(image: PathAssets.imgArticles, width: SizeConfig.width * .17, height: SizeConfig.height * .08, borderRadius: 8,), | ||||||
|  |           const SizedBox( | ||||||
|  |             width: 16, | ||||||
|  |           ), | ||||||
|  |           Expanded( | ||||||
|  |             child: Column( | ||||||
|  |               crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |               children: [ | ||||||
|  |                 Text(article.title, | ||||||
|  |                   style: const TextStyle( | ||||||
|  |                     fontWeight: FontWeight.bold, | ||||||
|  |                   ), | ||||||
|  |                 ), | ||||||
|  |                 const SizedBox( | ||||||
|  |                   height: 8, | ||||||
|  |                 ), | ||||||
|  |                 Container( | ||||||
|  |                   padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 12), | ||||||
|  |                   decoration: BoxDecoration( | ||||||
|  |                     borderRadius: BorderRadius.circular(30), | ||||||
|  |                     color: ColorPalette.colorSwitchButtonActive | ||||||
|  |                   ), | ||||||
|  |                   child: Text(article.type), | ||||||
|  |                 ), | ||||||
|  |               ], | ||||||
|  |             ) | ||||||
|  |           ) | ||||||
|  |         ], | ||||||
|  |       ), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -0,0 +1,236 @@ | |||||||
|  | import 'package:cims_apps/application/assets/path_assets.dart'; | ||||||
|  | import 'package:cims_apps/application/component/button/button_back.dart'; | ||||||
|  | import 'package:cims_apps/application/component/image/image_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/number_formatter.dart'; | ||||||
|  | import 'package:cims_apps/core/utils/size_config.dart'; | ||||||
|  | import 'package:cims_apps/features/dashboard/dashboard_account/view/product/product_view.dart'; | ||||||
|  | import 'package:flutter/material.dart'; | ||||||
|  |  | ||||||
|  | class Product { | ||||||
|  |   String name; | ||||||
|  |   double yield; | ||||||
|  |   double priceUnit; | ||||||
|  |   double funds; | ||||||
|  |    | ||||||
|  |   Product(this.name, this.yield, this.priceUnit, this.funds); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class InvestTypeView extends StatefulWidget { | ||||||
|  |   final String title; | ||||||
|  |   const InvestTypeView(this.title, {super.key}); | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   State<InvestTypeView> createState() => _InvestTypeViewState(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class _InvestTypeViewState extends State<InvestTypeView> { | ||||||
|  |    | ||||||
|  |   List<Product> listProduct = [ | ||||||
|  |     Product('Gemilang Dana Kas Maxima', 8.17, 2600.79, 6300000), | ||||||
|  |     Product('Gemilang Dana Likuid', 6.42, 1600.79, 2340000), | ||||||
|  |     Product('Gemilang Income Fund', 8.17, 2600.79, 6300000) | ||||||
|  |   ]; | ||||||
|  |    | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) { | ||||||
|  |     return Scaffold( | ||||||
|  |       body: SizedBox( | ||||||
|  |         width: SizeConfig.width, | ||||||
|  |         height: SizeConfig.height, | ||||||
|  |         child: Stack( | ||||||
|  |           children: [ | ||||||
|  |             const ImageView(image: PathAssets.imgDashboardAccount), | ||||||
|  |             Column( | ||||||
|  |               children: [ | ||||||
|  |                 const SizedBox( | ||||||
|  |                   height: 50, | ||||||
|  |                 ), | ||||||
|  |                 Padding( | ||||||
|  |                   padding: const EdgeInsets.symmetric(horizontal: 24), | ||||||
|  |                   child: Row( | ||||||
|  |                     mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||||
|  |                     children: [ | ||||||
|  |                       const ButtonBack(), | ||||||
|  |                       TextTitle(title: widget.title, color: Colors.white), | ||||||
|  |                       SizedBox( | ||||||
|  |                         width: SizeConfig.width * 0.1, | ||||||
|  |                       ) | ||||||
|  |                     ], | ||||||
|  |                   ), | ||||||
|  |                 ), | ||||||
|  |                 const SizedBox( | ||||||
|  |                   height: 24, | ||||||
|  |                 ), | ||||||
|  |                 Container( | ||||||
|  |                   padding: const EdgeInsets.all(24), | ||||||
|  |                   decoration: BoxDecoration( | ||||||
|  |                     borderRadius: BorderRadius.circular(16), | ||||||
|  |                     color: Colors.white | ||||||
|  |                   ), | ||||||
|  |                   child: Column( | ||||||
|  |                     children: [ | ||||||
|  |                       filters(), | ||||||
|  |                       ListView( | ||||||
|  |                         shrinkWrap: true, | ||||||
|  |                         children: listProduct.asMap().entries.map((e) { | ||||||
|  |                           return GestureDetector( | ||||||
|  |                             onTap: () { | ||||||
|  |                               routePush(context, page: ProductView(widget.title)); | ||||||
|  |                             }, | ||||||
|  |                             child: Padding( | ||||||
|  |                               padding: EdgeInsets.only(top: e.key != 0 ? 24 : 0), | ||||||
|  |                               child: cardProduct(e.value), | ||||||
|  |                             ), | ||||||
|  |                           ); | ||||||
|  |                         }).toList(), | ||||||
|  |                       ) | ||||||
|  |                     ], | ||||||
|  |                   ), | ||||||
|  |                 ), | ||||||
|  |               ], | ||||||
|  |             ) | ||||||
|  |           ], | ||||||
|  |         ), | ||||||
|  |       ), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Widget filters() { | ||||||
|  |     return Padding( | ||||||
|  |       padding: const EdgeInsets.symmetric(horizontal: 8), | ||||||
|  |       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', () { }), | ||||||
|  |         ], | ||||||
|  |       ), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Widget segmentFilter(Widget leading, String text, void Function()? onTap) { | ||||||
|  |     return GestureDetector( | ||||||
|  |       onTap: onTap, | ||||||
|  |       child:  Container( | ||||||
|  |         padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), | ||||||
|  |         decoration: BoxDecoration( | ||||||
|  |             border: Border.all(color: ColorPalette.slate200), | ||||||
|  |             borderRadius: BorderRadius.circular(56) | ||||||
|  |         ), | ||||||
|  |         child: Row( | ||||||
|  |           children: [ | ||||||
|  |             leading, | ||||||
|  |             const SizedBox( | ||||||
|  |               width: 4, | ||||||
|  |             ), | ||||||
|  |             Text( | ||||||
|  |               text, | ||||||
|  |               overflow: TextOverflow.ellipsis, | ||||||
|  |               style: const TextStyle( | ||||||
|  |                 color: ColorPalette.slate500, | ||||||
|  |                 fontWeight: FontWeight.w700 | ||||||
|  |               ), | ||||||
|  |             ) | ||||||
|  |           ], | ||||||
|  |         ), | ||||||
|  |       ), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Widget cardProduct(Product product) { | ||||||
|  |     return Container( | ||||||
|  |       padding: const EdgeInsets.all(16), | ||||||
|  |       decoration: BoxDecoration( | ||||||
|  |         borderRadius: BorderRadius.circular(12), | ||||||
|  |         border: Border.all(color: ColorPalette.slate200), | ||||||
|  |       ), | ||||||
|  |       child: Column( | ||||||
|  |         children: [ | ||||||
|  |           Row( | ||||||
|  |             children: [ | ||||||
|  |               ImageView(image: PathAssets.imgProduct, width: SizeConfig.width * .12,), | ||||||
|  |               const SizedBox( | ||||||
|  |                 width: 8, | ||||||
|  |               ), | ||||||
|  |               Expanded( | ||||||
|  |                 child: Text( | ||||||
|  |                   product.name, | ||||||
|  |                   style: const TextStyle( | ||||||
|  |                     fontWeight: FontWeight.bold, | ||||||
|  |                     fontSize: 18 | ||||||
|  |                   ), | ||||||
|  |                 ), | ||||||
|  |               ) | ||||||
|  |             ], | ||||||
|  |           ), | ||||||
|  |           const Padding( | ||||||
|  |             padding: EdgeInsets.symmetric(vertical: 12), | ||||||
|  |             child: Divider(color: ColorPalette.slate200), | ||||||
|  |           ), | ||||||
|  |           Row( | ||||||
|  |             mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||||
|  |             children: [ | ||||||
|  |               Column( | ||||||
|  |                 children: [ | ||||||
|  |                   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 | ||||||
|  |                         ), | ||||||
|  |                       ), | ||||||
|  |                       const Text('/'), | ||||||
|  |                       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),), | ||||||
|  |                   Row( | ||||||
|  |                     children: [ | ||||||
|  |                       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 | ||||||
|  |                         ), | ||||||
|  |                       ), | ||||||
|  |                     ], | ||||||
|  |                   ) | ||||||
|  |                 ], | ||||||
|  |               ), | ||||||
|  |               Column( | ||||||
|  |                 children: [ | ||||||
|  |                   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 | ||||||
|  |                         ), | ||||||
|  |                       ), | ||||||
|  |                     ], | ||||||
|  |                   ) | ||||||
|  |                 ], | ||||||
|  |               ) | ||||||
|  |             ], | ||||||
|  |           ) | ||||||
|  |         ], | ||||||
|  |       ), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,347 @@ | |||||||
|  | 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'; | ||||||
|  | import 'package:cims_apps/core/utils/size_config.dart'; | ||||||
|  | import 'package:fl_chart/fl_chart.dart'; | ||||||
|  | import 'package:flutter/material.dart'; | ||||||
|  |  | ||||||
|  | class CategoryPortofolio { | ||||||
|  |   String name; | ||||||
|  |   int value; | ||||||
|  |  | ||||||
|  |   CategoryPortofolio(this.value, this.name); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class PortofolioView extends StatefulWidget { | ||||||
|  |   const PortofolioView({super.key}); | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   State<PortofolioView> createState() => _PortofolioViewState(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class _PortofolioViewState extends State<PortofolioView> { | ||||||
|  |   List<Color> contentColor = [ | ||||||
|  |     ColorPalette.purple500, | ||||||
|  |     ColorPalette.orange500, | ||||||
|  |     ColorPalette.cyan500, | ||||||
|  |     ColorPalette.green500, | ||||||
|  |   ]; | ||||||
|  |   List<Color> bgContentColor = [ | ||||||
|  |     ColorPalette.purple100, | ||||||
|  |     ColorPalette.orange100, | ||||||
|  |     ColorPalette.cyan100, | ||||||
|  |     ColorPalette.green100, | ||||||
|  |   ]; | ||||||
|  |  | ||||||
|  |   bool seePortofolioValue = false; | ||||||
|  |   int touchedIndex = -1; | ||||||
|  |  | ||||||
|  |   List<CategoryPortofolio> listCategoryPortofolio = [ | ||||||
|  |     CategoryPortofolio(20, 'Money Market'), | ||||||
|  |     CategoryPortofolio(15, 'Shares'), | ||||||
|  |     CategoryPortofolio(8, 'Bonds'), | ||||||
|  |     CategoryPortofolio(50, 'Sharia'), | ||||||
|  |   ]; | ||||||
|  |  | ||||||
|  |   List<String> assetsImage = [ | ||||||
|  |     PathAssets.iconPortofolioMoneyMarket, | ||||||
|  |     PathAssets.iconPortofolioShares, | ||||||
|  |     PathAssets.iconPortofolioBonds, | ||||||
|  |     PathAssets.iconPortofolioSharia, | ||||||
|  |   ]; | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) { | ||||||
|  |     return Scaffold( | ||||||
|  |       backgroundColor: Colors.white, | ||||||
|  |       body: SizedBox( | ||||||
|  |         width: SizeConfig.width, | ||||||
|  |         height: SizeConfig.height, | ||||||
|  |         child: Stack( | ||||||
|  |           children: [ | ||||||
|  |             const ImageView(image: PathAssets.imgDashboardAccount), | ||||||
|  |             Column( | ||||||
|  |               children: [ | ||||||
|  |                 const SizedBox( | ||||||
|  |                   height: 50, | ||||||
|  |                 ), | ||||||
|  |                 const Center( | ||||||
|  |                   child: Text( | ||||||
|  |                     'Portofolio', | ||||||
|  |                     style: TextStyle( | ||||||
|  |                         fontSize: 20, | ||||||
|  |                         fontWeight: FontWeight.w700, | ||||||
|  |                         color: Colors.white), | ||||||
|  |                   ), | ||||||
|  |                 ), | ||||||
|  |                 const SizedBox( | ||||||
|  |                   height: 40, | ||||||
|  |                 ), | ||||||
|  |                 Padding( | ||||||
|  |                   padding: const EdgeInsets.symmetric(horizontal: 24), | ||||||
|  |                   child: portofolioValue(), | ||||||
|  |                 ), | ||||||
|  |                 Expanded( | ||||||
|  |                   child: Container( | ||||||
|  |                     margin: const EdgeInsets.only(top: 24), | ||||||
|  |                     decoration: const BoxDecoration( | ||||||
|  |                       color: Colors.white, | ||||||
|  |                       borderRadius: BorderRadius.only( | ||||||
|  |                           topLeft: Radius.circular(24), | ||||||
|  |                           topRight: Radius.circular(24)), | ||||||
|  |                     ), | ||||||
|  |                     child: ListView( | ||||||
|  |                       padding: const EdgeInsets.symmetric(vertical: 0), | ||||||
|  |                       children: [ | ||||||
|  |                         Stack(alignment: Alignment.center, children: [ | ||||||
|  |                           AspectRatio( | ||||||
|  |                             aspectRatio: 1.3, | ||||||
|  |                             child: PieChart(PieChartData( | ||||||
|  |                                 pieTouchData: PieTouchData( | ||||||
|  |                                   touchCallback: | ||||||
|  |                                       (FlTouchEvent event, pieTouchResponse) { | ||||||
|  |                                     setState(() { | ||||||
|  |                                       if (!event.isInterestedForInteractions || | ||||||
|  |                                           pieTouchResponse == null || | ||||||
|  |                                           pieTouchResponse.touchedSection == | ||||||
|  |                                               null) { | ||||||
|  |                                         touchedIndex = -1; | ||||||
|  |                                         return; | ||||||
|  |                                       } | ||||||
|  |                                       touchedIndex = pieTouchResponse | ||||||
|  |                                           .touchedSection!.touchedSectionIndex; | ||||||
|  |                                     }); | ||||||
|  |                                   }, | ||||||
|  |                                 ), | ||||||
|  |                                 borderData: FlBorderData( | ||||||
|  |                                   show: true, | ||||||
|  |                                 ), | ||||||
|  |                                 sectionsSpace: 20, | ||||||
|  |                                 centerSpaceRadius: 100, | ||||||
|  |                                 sections: sectionsDataPortofolio())), | ||||||
|  |                           ), | ||||||
|  |                           const Column( | ||||||
|  |                             children: [ | ||||||
|  |                               Text('Total Mutual Fund'), | ||||||
|  |                               Text('10', | ||||||
|  |                                   style: TextStyle( | ||||||
|  |                                       fontSize: 44, | ||||||
|  |                                       fontWeight: FontWeight.w700)), | ||||||
|  |                             ], | ||||||
|  |                           ) | ||||||
|  |                         ]), | ||||||
|  |                         const SizedBox( | ||||||
|  |                           height: 12, | ||||||
|  |                         ), | ||||||
|  |                         menuPortofolio(), | ||||||
|  |                         const SizedBox( | ||||||
|  |                           height: 24, | ||||||
|  |                         ), | ||||||
|  |                         ...listColumnPortofolio(), | ||||||
|  |                         const SizedBox( | ||||||
|  |                           height: 24, | ||||||
|  |                         ) | ||||||
|  |                       ], | ||||||
|  |                     ), | ||||||
|  |                   ), | ||||||
|  |                 ) | ||||||
|  |               ], | ||||||
|  |             ) | ||||||
|  |           ], | ||||||
|  |         ), | ||||||
|  |       ), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Widget portofolioValue() { | ||||||
|  |     return Column( | ||||||
|  |       crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |       children: [ | ||||||
|  |         Row( | ||||||
|  |           children: [ | ||||||
|  |             const Text('Portofolio Value', | ||||||
|  |                 style: TextStyle(color: Colors.white)), | ||||||
|  |             const SizedBox( | ||||||
|  |               width: 8, | ||||||
|  |             ), | ||||||
|  |             GestureDetector( | ||||||
|  |                 onTap: () { | ||||||
|  |                   setState(() { | ||||||
|  |                     seePortofolioValue = !seePortofolioValue; | ||||||
|  |                   }); | ||||||
|  |                 }, | ||||||
|  |                 child: const Icon(Icons.visibility_outlined, | ||||||
|  |                     color: Color(0xff93C5FD))) | ||||||
|  |           ], | ||||||
|  |         ), | ||||||
|  |         const SizedBox( | ||||||
|  |           height: 4, | ||||||
|  |         ), | ||||||
|  |         Row( | ||||||
|  |           children: [ | ||||||
|  |             AnimatedCrossFade( | ||||||
|  |               duration: const Duration(milliseconds: 300), | ||||||
|  |               alignment: Alignment.center, | ||||||
|  |               crossFadeState: seePortofolioValue | ||||||
|  |                   ? CrossFadeState.showSecond | ||||||
|  |                   : CrossFadeState.showFirst, | ||||||
|  |               firstChild: RichText( | ||||||
|  |                   text: const TextSpan( | ||||||
|  |                       text: 'Rp ', | ||||||
|  |                       style: TextStyle(fontSize: 32, color: Color(0xff93C5FD), fontFamily: 'Manrope'), | ||||||
|  |                       children: [ | ||||||
|  |                     TextSpan( | ||||||
|  |                       text: '22.500.000', | ||||||
|  |                       style: TextStyle( | ||||||
|  |                           fontSize: 32, | ||||||
|  |                           fontFamily: 'Manrope', | ||||||
|  |                           fontWeight: FontWeight.bold, | ||||||
|  |                           color: Colors.white | ||||||
|  |                       ), | ||||||
|  |                     ) | ||||||
|  |                   ])), | ||||||
|  |               secondChild: Padding( | ||||||
|  |                 padding: const EdgeInsets.symmetric(vertical: 16), | ||||||
|  |                 child: Wrap( | ||||||
|  |                   spacing: 7, | ||||||
|  |                   children: [ | ||||||
|  |                     for (int i = 0; i < 6; i++) | ||||||
|  |                       Container( | ||||||
|  |                         width: 12, | ||||||
|  |                         height: 12, | ||||||
|  |                         decoration: const BoxDecoration( | ||||||
|  |                             color: Colors.white, shape: BoxShape.circle), | ||||||
|  |                       ), | ||||||
|  |                   ], | ||||||
|  |                 ), | ||||||
|  |               ), | ||||||
|  |             ), | ||||||
|  |           ], | ||||||
|  |         ) | ||||||
|  |       ], | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   List<PieChartSectionData> sectionsDataPortofolio() { | ||||||
|  |     return listCategoryPortofolio.asMap().entries.map((e) { | ||||||
|  |       final isTouched = e.key == touchedIndex; | ||||||
|  |       final radius = isTouched ? 40.0 : 30.0; | ||||||
|  |       return PieChartSectionData( | ||||||
|  |         color: contentColor[e.key], | ||||||
|  |         value: e.value.value.toDouble(), | ||||||
|  |         title: e.value.name, | ||||||
|  |         showTitle: isTouched, | ||||||
|  |         radius: radius, | ||||||
|  |         titleStyle: const TextStyle( | ||||||
|  |           fontSize: 20, | ||||||
|  |           fontWeight: FontWeight.bold, | ||||||
|  |         ), | ||||||
|  |       ); | ||||||
|  |     }).toList(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Widget menuPortofolio() { | ||||||
|  |     return Container( | ||||||
|  |       margin: const EdgeInsets.symmetric(horizontal: 24), | ||||||
|  |       padding: const EdgeInsets.all(12), | ||||||
|  |       decoration: BoxDecoration( | ||||||
|  |           color: Colors.white, | ||||||
|  |           borderRadius: const BorderRadius.all(Radius.circular(12)), | ||||||
|  |           boxShadow: [ | ||||||
|  |             BoxShadow( | ||||||
|  |                 spreadRadius: 2, | ||||||
|  |                 blurRadius: 8, | ||||||
|  |                 color: const Color(0xff1E293B).withOpacity(0.04)) | ||||||
|  |           ]), | ||||||
|  |       child: Wrap( | ||||||
|  |         alignment: WrapAlignment.center, | ||||||
|  |         spacing: 12, | ||||||
|  |         children: listCategoryPortofolio.asMap().entries.map((e) { | ||||||
|  |           return Container( | ||||||
|  |             color: Colors.white, | ||||||
|  |             width: SizeConfig.width * 0.18, | ||||||
|  |             child: Column( | ||||||
|  |               children: [ | ||||||
|  |                 Container( | ||||||
|  |                   height: 58, | ||||||
|  |                   width: 58, | ||||||
|  |                   alignment: Alignment.center, | ||||||
|  |                   decoration: BoxDecoration( | ||||||
|  |                       shape: BoxShape.circle, | ||||||
|  |                       color: bgContentColor[e.key], | ||||||
|  |                   ), | ||||||
|  |                   child: Text( | ||||||
|  |                     '${e.value.value}%', | ||||||
|  |                     style: TextStyle( | ||||||
|  |                         fontWeight: FontWeight.bold, | ||||||
|  |                         color: contentColor[e.key]), | ||||||
|  |                   ), | ||||||
|  |                 ), | ||||||
|  |                 const SizedBox( | ||||||
|  |                   height: 8, | ||||||
|  |                 ), | ||||||
|  |                 Text( | ||||||
|  |                   e.value.name, | ||||||
|  |                   overflow: TextOverflow.ellipsis, | ||||||
|  |                   textAlign: TextAlign.center, | ||||||
|  |                 ) | ||||||
|  |               ], | ||||||
|  |             ), | ||||||
|  |           ); | ||||||
|  |         }).toList(), | ||||||
|  |       ), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   List<Widget> listColumnPortofolio() { | ||||||
|  |     return listCategoryPortofolio.asMap().entries.map((e) { | ||||||
|  |       return Column( | ||||||
|  |         children: [ | ||||||
|  |           if (e.key > 0) ...[ | ||||||
|  |             const Divider( | ||||||
|  |               color: ColorPalette.slate200, | ||||||
|  |             ) | ||||||
|  |           ], | ||||||
|  |           ListTile( | ||||||
|  |             contentPadding: | ||||||
|  |                 const EdgeInsets.symmetric(vertical: 0, horizontal: 24), | ||||||
|  |             leading: ImageView( | ||||||
|  |               image: assetsImage[e.key], | ||||||
|  |               width: SizeConfig.width * .15, | ||||||
|  |               height: SizeConfig.height * .08, | ||||||
|  |               borderRadius: 8, | ||||||
|  |             ), | ||||||
|  |             title: Text( | ||||||
|  |               e.value.name, | ||||||
|  |               style: const TextStyle(fontWeight: FontWeight.w600), | ||||||
|  |             ), | ||||||
|  |             subtitle: Text( | ||||||
|  |               e.value.name, | ||||||
|  |               style: const TextStyle( | ||||||
|  |                   fontWeight: FontWeight.w600, color: Color(0xff94A3B8)), | ||||||
|  |             ), | ||||||
|  |             trailing: const Column( | ||||||
|  |               crossAxisAlignment: CrossAxisAlignment.end, | ||||||
|  |               children: [ | ||||||
|  |                 Text( | ||||||
|  |                   'Rp 2.000.000', | ||||||
|  |                   style: TextStyle( | ||||||
|  |                       color: Colors.black, | ||||||
|  |                       fontSize: 16, | ||||||
|  |                       fontWeight: FontWeight.w700), | ||||||
|  |                 ), | ||||||
|  |                 Text( | ||||||
|  |                   '+ Rp 200.000', | ||||||
|  |                   style: TextStyle( | ||||||
|  |                       fontSize: 14, | ||||||
|  |                       color: Color(0xff4ADE80), | ||||||
|  |                       fontWeight: FontWeight.w600), | ||||||
|  |                 ) | ||||||
|  |               ], | ||||||
|  |             ), | ||||||
|  |           ), | ||||||
|  |         ], | ||||||
|  |       ); | ||||||
|  |     }).toList(); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -0,0 +1,325 @@ | |||||||
|  | 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/utils/number_formatter.dart'; | ||||||
|  | import 'package:fl_chart/fl_chart.dart'; | ||||||
|  | import 'package:flutter/material.dart'; | ||||||
|  | import 'dart:math'; | ||||||
|  | import 'package:intl/intl.dart'; | ||||||
|  |  | ||||||
|  | class ProductChartView extends StatefulWidget { | ||||||
|  |   final String tabType; | ||||||
|  |   final String lastTime; | ||||||
|  |   final List<double> dataChart; | ||||||
|  |  | ||||||
|  |   const ProductChartView({ | ||||||
|  |     super.key, | ||||||
|  |     required this.tabType, | ||||||
|  |     required this.lastTime, | ||||||
|  |     required this.dataChart, | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   State<ProductChartView> createState() => _ProductChartViewState(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class _ProductChartViewState extends State<ProductChartView> { | ||||||
|  |   bool isShowLabel = true; | ||||||
|  |   DateTime dateTime = DateTime.now(); | ||||||
|  |   double currentPrice = 0; | ||||||
|  |   int spotIndicator = 0; | ||||||
|  |   List<int> showingTooltipOnSpots = [1, 3, 5]; | ||||||
|  |   List<FlSpot> spots = []; | ||||||
|  |  | ||||||
|  |   double dataHighest = 0; | ||||||
|  |   double dataLowest = 0; | ||||||
|  |  | ||||||
|  |   int indexHighestValue = 0; | ||||||
|  |   int indexLowestValue = 0; | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   void initState() { | ||||||
|  |     spots = widget.dataChart.asMap().entries.map((e) { | ||||||
|  |       return FlSpot(double.parse(e.key.toString()), e.value); | ||||||
|  |     }).toList(); | ||||||
|  |     dataHighest = widget.dataChart.reduce(max); | ||||||
|  |     dataLowest = widget.dataChart.reduce(min); | ||||||
|  |     currentPrice = dataHighest; | ||||||
|  |     indexHighestValue = widget.dataChart.indexWhere((element) => element == dataHighest); | ||||||
|  |     indexLowestValue = widget.dataChart.indexWhere((element) => element == dataLowest); | ||||||
|  |     // TODO: implement initState | ||||||
|  |     super.initState(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   void didUpdateWidget(covariant ProductChartView oldWidget) { | ||||||
|  |     // TODO: implement didUpdateWidget | ||||||
|  |     spots = widget.dataChart.asMap().entries.map((e) { | ||||||
|  |       return FlSpot(double.parse(e.key.toString()), e.value); | ||||||
|  |     }).toList(); | ||||||
|  |     dataHighest = widget.dataChart.reduce(max); | ||||||
|  |     dataLowest = widget.dataChart.reduce(min); | ||||||
|  |     currentPrice = dataHighest; | ||||||
|  |     indexHighestValue = widget.dataChart.indexWhere((element) => element == dataHighest); | ||||||
|  |     indexLowestValue = widget.dataChart.indexWhere((element) => element == dataLowest); | ||||||
|  |     super.didUpdateWidget(oldWidget); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) { | ||||||
|  |  | ||||||
|  |     return Column( | ||||||
|  |       crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |       children: [ | ||||||
|  |         Padding( | ||||||
|  |           padding: const EdgeInsets.symmetric(horizontal: 24), | ||||||
|  |           child: Wrap( | ||||||
|  |             spacing: 8, | ||||||
|  |             children: [ | ||||||
|  |               Text( | ||||||
|  |                 widget.tabType, | ||||||
|  |                 style: TextStyle( | ||||||
|  |                     color: ColorPalette.slate400, | ||||||
|  |                     fontWeight: FontWeight.w700 | ||||||
|  |                 ), | ||||||
|  |               ), | ||||||
|  |               Text( | ||||||
|  |                 DateFormat('dd MMM yyyy').format(dateTime), | ||||||
|  |                 style: TextStyle( | ||||||
|  |                     color: ColorPalette.slate300 | ||||||
|  |                 ), | ||||||
|  |               ), | ||||||
|  |             ], | ||||||
|  |           ), | ||||||
|  |         ), | ||||||
|  |         Padding( | ||||||
|  |           padding: const EdgeInsets.symmetric(horizontal: 24), | ||||||
|  |           child: TextTitle(title: NumberFormatter.numberCurrency(currentPrice, 'Rp ', 'id_ID')), | ||||||
|  |         ), | ||||||
|  |         Padding( | ||||||
|  |           padding: const EdgeInsets.symmetric(horizontal: 24), | ||||||
|  |           child: Wrap( | ||||||
|  |             crossAxisAlignment: WrapCrossAlignment.center, | ||||||
|  |             spacing: 8, | ||||||
|  |             children: [ | ||||||
|  |               Icon( | ||||||
|  |                 Icons.trending_up_outlined, | ||||||
|  |                 size: 18, | ||||||
|  |                 color: ColorPalette.green500, | ||||||
|  |               ), | ||||||
|  |               Text( | ||||||
|  |                 'Rp20,30 (+3,88%)', | ||||||
|  |                 style: TextStyle( | ||||||
|  |                   color: ColorPalette.green500, | ||||||
|  |                   fontWeight: FontWeight.w600 | ||||||
|  |                 ), | ||||||
|  |               ), | ||||||
|  |               Text( | ||||||
|  |                 'Last ${widget.lastTime}', | ||||||
|  |                 style: TextStyle( | ||||||
|  |                   color: ColorPalette.slate300, | ||||||
|  |                   fontWeight: FontWeight.w600 | ||||||
|  |                 ), | ||||||
|  |               ) | ||||||
|  |             ], | ||||||
|  |           ), | ||||||
|  |         ), | ||||||
|  |         Padding( | ||||||
|  |           padding: const EdgeInsets.symmetric(vertical: 48), | ||||||
|  |           child: AspectRatio( | ||||||
|  |             aspectRatio: 2.5, | ||||||
|  |             child: LayoutBuilder( | ||||||
|  |               builder: (context, constraints) { | ||||||
|  |                 return LineChart( | ||||||
|  |                   LineChartData( | ||||||
|  |                     // showingTooltipIndicators: showingTooltipOnSpots.map((index) { | ||||||
|  |                     //   return ShowingTooltipIndicators([ | ||||||
|  |                     //     LineBarSpot( | ||||||
|  |                     //       tooltipsOnBar, | ||||||
|  |                     //       lineBarsData.indexOf(tooltipsOnBar), | ||||||
|  |                     //       tooltipsOnBar.spots[index], | ||||||
|  |                     //     ), | ||||||
|  |                     //   ]); | ||||||
|  |                     // }).toList(), | ||||||
|  |                     extraLinesData: ExtraLinesData( | ||||||
|  |                         verticalLines: [ | ||||||
|  |                           VerticalLine( | ||||||
|  |                               color: Colors.transparent, | ||||||
|  |                               x: indexHighestValue.toDouble(), | ||||||
|  |                               label: VerticalLineLabel( | ||||||
|  |                                 show: spots.length < 7 ? false : isShowLabel, | ||||||
|  |                                 padding: EdgeInsets.only(bottom: 20, top: -25), | ||||||
|  |                                 alignment: (indexHighestValue / widget.dataChart.length) < 0.25 ? Alignment.topRight : (indexHighestValue / widget.dataChart.length) > 0.75 ? Alignment.topLeft : Alignment.topCenter, | ||||||
|  |                                 style: const TextStyle( | ||||||
|  |                                   color: ColorPalette.slate400, | ||||||
|  |                                   fontSize: 12, | ||||||
|  |                                   fontWeight: FontWeight.bold, | ||||||
|  |                                 ), | ||||||
|  |                                 labelResolver: (p0) => NumberFormatter.numberCurrency(dataHighest, 'Rp ', 'id_ID'), | ||||||
|  |                               ) | ||||||
|  |                           ), | ||||||
|  |                           VerticalLine( | ||||||
|  |                               color: Colors.transparent, | ||||||
|  |                               x: indexLowestValue.toDouble(), | ||||||
|  |                               label: VerticalLineLabel( | ||||||
|  |                                 show: spots.length < 7 ? false : isShowLabel, | ||||||
|  |                                 padding: EdgeInsets.only(bottom: -5, top: 20), | ||||||
|  |                                 alignment: (indexLowestValue / widget.dataChart.length ) < 0.25 ? Alignment.bottomRight : (indexLowestValue / widget.dataChart.length ) > 0.75 ? Alignment.bottomLeft : Alignment.bottomCenter, | ||||||
|  |                                 style: const TextStyle( | ||||||
|  |                                   color: ColorPalette.slate400, | ||||||
|  |                                   fontSize: 12, | ||||||
|  |                                   fontWeight: FontWeight.bold, | ||||||
|  |                                 ), | ||||||
|  |                                 labelResolver: (p0) => NumberFormatter.numberCurrency(dataLowest, 'Rp ', 'id_ID'), | ||||||
|  |                               ) | ||||||
|  |                           ) | ||||||
|  |                         ] | ||||||
|  |                     ), | ||||||
|  |                     lineTouchData: LineTouchData( | ||||||
|  |                       getTouchLineEnd: (barData, spotIndex) => double.infinity, | ||||||
|  |                       getTouchedSpotIndicator: (barData, spotIndexes) { | ||||||
|  |                         return spotIndexes.map((spotIndex) { | ||||||
|  |                           return TouchedSpotIndicatorData( | ||||||
|  |                             const FlLine(strokeWidth: 1, color: ColorPalette.primary), | ||||||
|  |                             FlDotData( | ||||||
|  |                               getDotPainter: (spot, percent, barData, index) => | ||||||
|  |                                   FlDotCirclePainter( | ||||||
|  |                                     radius: 1, | ||||||
|  |                                     color: ColorPalette.white, | ||||||
|  |                                     strokeColor: ColorPalette.primary, | ||||||
|  |                                     strokeWidth: 2, | ||||||
|  |                                   ), | ||||||
|  |                             ), | ||||||
|  |                           ); | ||||||
|  |                         }).toList(); | ||||||
|  |                       }, | ||||||
|  |                       touchCallback: (FlTouchEvent event, LineTouchResponse? response) { | ||||||
|  |                         if (response == null || response.lineBarSpots == null) { | ||||||
|  |                           setState(() { | ||||||
|  |                             isShowLabel = true; | ||||||
|  |                             currentPrice = widget.dataChart.last; | ||||||
|  |                             dateTime = DateTime.now(); | ||||||
|  |                           }); | ||||||
|  |                           return; | ||||||
|  |                         } | ||||||
|  |                         double? spotIndex = response.lineBarSpots?[0].x; | ||||||
|  |                         if(spotIndex != null){ | ||||||
|  |                           int absIndex = (spotIndex.toInt() - (spots.length - 1)).abs(); | ||||||
|  |                           setState(() { | ||||||
|  |                             isShowLabel = false; | ||||||
|  |                             spotIndicator = spotIndex.toInt(); | ||||||
|  |                             currentPrice = widget.dataChart[spotIndex.toInt()]; | ||||||
|  |                             dateTime = DateTime.now().subtract(Duration(days: absIndex)); | ||||||
|  |                           }); | ||||||
|  |                         } | ||||||
|  |                       }, | ||||||
|  |                       touchTooltipData: LineTouchTooltipData( | ||||||
|  |                         tooltipBgColor: Colors.transparent, | ||||||
|  |                         tooltipPadding: EdgeInsets.all(0), | ||||||
|  |                         fitInsideHorizontally: true, | ||||||
|  |                         showOnTopOfTheChartBoxArea: true, | ||||||
|  |                         getTooltipItems: (touchedSpots) { | ||||||
|  |                           return touchedSpots.map((LineBarSpot touchedSpot) { | ||||||
|  |                             final textStyle = TextStyle( | ||||||
|  |                               color: ColorPalette.slate500, | ||||||
|  |                               fontWeight: FontWeight.bold, | ||||||
|  |                               fontSize: 12, | ||||||
|  |                             ); | ||||||
|  |                             return LineTooltipItem( | ||||||
|  |                               DateFormat('dd MMM yyyy').format(dateTime), | ||||||
|  |                               textStyle, | ||||||
|  |                             ); | ||||||
|  |                           }).toList(); | ||||||
|  |                         }, | ||||||
|  |                       ), | ||||||
|  |                       handleBuiltInTouches: true, | ||||||
|  |                     ), | ||||||
|  |                     lineBarsData: [ | ||||||
|  |                       LineChartBarData( | ||||||
|  |                         color: ColorPalette.primary, | ||||||
|  |                         spots: spots, | ||||||
|  |                         isCurved: true, | ||||||
|  |                         preventCurveOverShooting: true, | ||||||
|  |                         isStrokeCapRound: true, | ||||||
|  |                         isStrokeJoinRound: true, | ||||||
|  |                         barWidth: 1.2, | ||||||
|  |                         belowBarData: BarAreaData( | ||||||
|  |                           show: true, | ||||||
|  |                           gradient: LinearGradient( | ||||||
|  |                               begin: Alignment.topCenter, | ||||||
|  |                               end: Alignment.bottomCenter, | ||||||
|  |                               colors: [ | ||||||
|  |                                 Color(0xFF5B8FF9), | ||||||
|  |                                 Colors.white | ||||||
|  |                               ] | ||||||
|  |                           ), | ||||||
|  |                           spotsLine: BarAreaSpotsLine( | ||||||
|  |                             show: true, | ||||||
|  |                             applyCutOffY: true, | ||||||
|  |                             flLineStyle: FlLine( | ||||||
|  |                               color: ColorPalette.primary, | ||||||
|  |                               strokeWidth: 1, | ||||||
|  |                             ), | ||||||
|  |                             checkToShowSpotLine: (spot) { | ||||||
|  |                               if(spot.x == spotIndicator && !isShowLabel){ | ||||||
|  |                                 return true; | ||||||
|  |                               } | ||||||
|  |                               return false; | ||||||
|  |                             }, | ||||||
|  |                           ) | ||||||
|  |                         ), | ||||||
|  |                         dotData: FlDotData( | ||||||
|  |                           show: true, | ||||||
|  |                           getDotPainter: (p0, p1, p2, p3) { | ||||||
|  |                             return  FlDotCirclePainter( | ||||||
|  |                               radius: 1, | ||||||
|  |                               color: ColorPalette.white, | ||||||
|  |                               strokeColor: ColorPalette.primary, | ||||||
|  |                               strokeWidth: 2, | ||||||
|  |                             ); | ||||||
|  |                           }, | ||||||
|  |                           checkToShowDot: (spot, barData) { | ||||||
|  |                             if(spot.x == spotIndicator && !isShowLabel){ | ||||||
|  |                               return true; | ||||||
|  |                             } | ||||||
|  |                             return false; | ||||||
|  |                           }, | ||||||
|  |                         ), | ||||||
|  |                       ), | ||||||
|  |                     ], | ||||||
|  |                     titlesData: FlTitlesData( | ||||||
|  |                       leftTitles: AxisTitles( | ||||||
|  |                         sideTitles: SideTitles( | ||||||
|  |                           showTitles: false, | ||||||
|  |                           reservedSize: 56, | ||||||
|  |                         ), | ||||||
|  |                         drawBelowEverything: true, | ||||||
|  |                       ), | ||||||
|  |                       rightTitles: const AxisTitles( | ||||||
|  |                         sideTitles: SideTitles(showTitles: false), | ||||||
|  |                       ), | ||||||
|  |                       bottomTitles: AxisTitles( | ||||||
|  |                         sideTitles: SideTitles( | ||||||
|  |                           showTitles: false, | ||||||
|  |                           reservedSize: 36, | ||||||
|  |                           interval: 1, | ||||||
|  |                         ), | ||||||
|  |                         drawBelowEverything: true, | ||||||
|  |                       ), | ||||||
|  |                       topTitles: const AxisTitles( | ||||||
|  |                         sideTitles: SideTitles(showTitles: false), | ||||||
|  |                       ), | ||||||
|  |                     ), | ||||||
|  |                     gridData: FlGridData( | ||||||
|  |                         show: false | ||||||
|  |                     ), | ||||||
|  |                     borderData: FlBorderData(show: false), | ||||||
|  |                   ), | ||||||
|  |                 ); | ||||||
|  |               }, | ||||||
|  |             ), | ||||||
|  |           ), | ||||||
|  |         ), | ||||||
|  |       ], | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -0,0 +1,789 @@ | |||||||
|  | import 'dart:math'; | ||||||
|  |  | ||||||
|  | import 'package:cims_apps/application/assets/path_assets.dart'; | ||||||
|  | import 'package:cims_apps/application/component/button/button_back.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/utils/number_formatter.dart'; | ||||||
|  | import 'package:cims_apps/core/utils/size_config.dart'; | ||||||
|  | import 'package:cims_apps/features/dashboard/dashboard_account/view/product/product_chart_view.dart'; | ||||||
|  | import 'package:flutter/material.dart'; | ||||||
|  | import 'package:group_button/group_button.dart'; | ||||||
|  |  | ||||||
|  | class Time { | ||||||
|  |   int value; | ||||||
|  |   String simpleName, completeName; | ||||||
|  |  | ||||||
|  |   Time(this.value, this.simpleName, this.completeName); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class ProductView extends StatefulWidget { | ||||||
|  |   final String investType; | ||||||
|  |   const ProductView(this.investType, {super.key}); | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   State<ProductView> createState() => _ProductViewState(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class _ProductViewState extends State<ProductView> { | ||||||
|  |   int selectedTab = 0; | ||||||
|  |   Time selectedTime = Time(2, '1D', '1 day'); | ||||||
|  |   int selectedMachineType = 0; | ||||||
|  |   int selectedMachineTime = 0; | ||||||
|  |  | ||||||
|  |   List<Time> listTime = [ | ||||||
|  |     Time(2, '1D', '1 day'), | ||||||
|  |     Time(30, '1M', '1 month'), | ||||||
|  |     Time(90, '3M', '3 months'), | ||||||
|  |     Time(365, '1Y', '1 year'), | ||||||
|  |   ]; | ||||||
|  |  | ||||||
|  |   List<String> listTab = ['NAV', 'AUM']; | ||||||
|  |  | ||||||
|  |   List<String> listMachine = ['Monthly Routine', 'Connect Once']; | ||||||
|  |  | ||||||
|  |   List<Time> listMachineTime = [ | ||||||
|  |     Time(1, '1D', '1 year'), | ||||||
|  |     Time(3, '1M', '3 year'), | ||||||
|  |     Time(5, '3M', '5 year'), | ||||||
|  |     Time(10, '1Y', '10 year'), | ||||||
|  |   ]; | ||||||
|  |  | ||||||
|  |   TextEditingController machineController = TextEditingController(); | ||||||
|  |  | ||||||
|  |   GroupButtonController machineGroupButtonController = GroupButtonController(selectedIndex: 0); | ||||||
|  |  | ||||||
|  |   List<String> listTopHoldings = [ | ||||||
|  |     'Bank Pembangunan Daerah Sulawesi Selatan dan Sulawesi Barat', | ||||||
|  |     'PT. Bank Jabar Banten, TBK', | ||||||
|  |     'PT. Bank Mega', | ||||||
|  |     'PT. Bank Nagaria', | ||||||
|  |     'PT. BPD Sulawesi Tengah' | ||||||
|  |   ]; | ||||||
|  |  | ||||||
|  |   List<double> data = []; | ||||||
|  |   double estimatedValue = 0; | ||||||
|  |  | ||||||
|  |   void setEstimatedValue() { | ||||||
|  |     double parseValue = double.parse(machineController.text.replaceAll('Rp ', '').replaceAll('.', '')); | ||||||
|  |     int machineType = selectedMachineType == 0 ? 12 : 1; | ||||||
|  |     setState(() { | ||||||
|  |       estimatedValue = (machineType * (listMachineTime[selectedMachineTime].value) * ((parseValue * machineType) * 10/100)) + parseValue; | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   void initState() { | ||||||
|  |     machineController.text = NumberFormatter.numberCurrency(100000, 'Rp ', 'id_ID', decimalDigits: 0); | ||||||
|  |     selectedTime = listTime[0]; | ||||||
|  |     setEstimatedValue(); | ||||||
|  |     List.generate(2, (index) => { | ||||||
|  |       data.add((2500 + index - Random().nextInt(100)).toDouble()) | ||||||
|  |     }); | ||||||
|  |     // TODO: implement initState | ||||||
|  |     super.initState(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   void dispose() { | ||||||
|  |     machineController.dispose(); | ||||||
|  |     machineGroupButtonController.dispose(); | ||||||
|  |     // TODO: implement dispose | ||||||
|  |     super.dispose(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) { | ||||||
|  |     return Scaffold( | ||||||
|  |       body: SizedBox( | ||||||
|  |         width: SizeConfig.width, | ||||||
|  |         height: SizeConfig.height, | ||||||
|  |         child: Stack( | ||||||
|  |           children: [ | ||||||
|  |             const ImageView(image: PathAssets.imgDashboardAccount), | ||||||
|  |             Column( | ||||||
|  |               children: [ | ||||||
|  |                 const SizedBox( | ||||||
|  |                   height: 50, | ||||||
|  |                 ), | ||||||
|  |                 const Padding( | ||||||
|  |                   padding: EdgeInsets.symmetric(horizontal: 24), | ||||||
|  |                   child: Row( | ||||||
|  |                     mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||||
|  |                     children: [ | ||||||
|  |                       ButtonBack(), | ||||||
|  |                       Wrap( | ||||||
|  |                         spacing: 12, | ||||||
|  |                         children: [ | ||||||
|  |                           Icon(Icons.search_rounded, color: ColorPalette.blue200, size: 32), | ||||||
|  |                           Icon(Icons.file_download_outlined, color: ColorPalette.blue200, size: 32), | ||||||
|  |                           Icon(Icons.star_outline_rounded, color: ColorPalette.blue200, size: 32) | ||||||
|  |                         ], | ||||||
|  |                       ) | ||||||
|  |                     ], | ||||||
|  |                   ), | ||||||
|  |                 ), | ||||||
|  |                 const SizedBox( | ||||||
|  |                   height: 24, | ||||||
|  |                 ), | ||||||
|  |                 headContainer(), | ||||||
|  |                 const SizedBox( | ||||||
|  |                   height: 24, | ||||||
|  |                 ), | ||||||
|  |                 Expanded( | ||||||
|  |                   child: contentContainer() | ||||||
|  |                 ) | ||||||
|  |               ], | ||||||
|  |             ) | ||||||
|  |           ], | ||||||
|  |         ), | ||||||
|  |       ), | ||||||
|  |       bottomNavigationBar: Padding( | ||||||
|  |         padding: const EdgeInsets.symmetric(horizontal: 24), | ||||||
|  |         child: ButtonView( | ||||||
|  |           name: 'Buy', | ||||||
|  |           onPressed: () { | ||||||
|  |  | ||||||
|  |           }, | ||||||
|  |           height: SizeConfig.height * 0.06, | ||||||
|  |           marginVertical: 16, | ||||||
|  |         ), | ||||||
|  |       ), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Widget headContainer() { | ||||||
|  |     return Padding( | ||||||
|  |         padding: const EdgeInsets.symmetric(horizontal: 24), | ||||||
|  |         child: Row( | ||||||
|  |           mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||||
|  |           children: [ | ||||||
|  |             Expanded( | ||||||
|  |               child: Row( | ||||||
|  |                 children: [ | ||||||
|  |                   ImageView(image: PathAssets.imgProduct, width: SizeConfig.width * .12), | ||||||
|  |                   SizedBox(width: 8), | ||||||
|  |                   Expanded( | ||||||
|  |                     child: Text( | ||||||
|  |                       'Gemilang Dana Kas Maxima', | ||||||
|  |                       maxLines: 2, | ||||||
|  |                       overflow: TextOverflow.ellipsis, | ||||||
|  |                       style: TextStyle( | ||||||
|  |                           color: Colors.white, | ||||||
|  |                           fontWeight: FontWeight.w700, | ||||||
|  |                           fontSize: 18 | ||||||
|  |                       ), | ||||||
|  |                     ), | ||||||
|  |                   ) | ||||||
|  |                 ], | ||||||
|  |               ), | ||||||
|  |             ), | ||||||
|  |             Container( | ||||||
|  |               padding: const EdgeInsets.all(6), | ||||||
|  |               decoration: BoxDecoration( | ||||||
|  |                   borderRadius: BorderRadius.circular(40), | ||||||
|  |                   color: ColorPalette.investTypeBgColor[widget.investType] ?? Colors.white, | ||||||
|  |                   border: Border.all(width: 2, color: ColorPalette.investTypeColor[widget.investType] ?? Colors.white) | ||||||
|  |               ), | ||||||
|  |               child: Text( | ||||||
|  |                 widget.investType, | ||||||
|  |                 style: TextStyle( | ||||||
|  |                     color: ColorPalette.investTypeColor[widget.investType], | ||||||
|  |                     fontWeight: FontWeight.w600 | ||||||
|  |                 ), | ||||||
|  |               ), | ||||||
|  |             ) | ||||||
|  |           ], | ||||||
|  |         ), | ||||||
|  |       ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Widget contentContainer() { | ||||||
|  |     return ClipRRect( | ||||||
|  |       borderRadius: BorderRadius.circular(12), | ||||||
|  |       child: Container( | ||||||
|  |         decoration: BoxDecoration( | ||||||
|  |           color: Colors.white, | ||||||
|  |         ), | ||||||
|  |         child: ListView( | ||||||
|  |           children: [ | ||||||
|  |             ProductChartView( | ||||||
|  |               tabType: listTab[selectedTab], | ||||||
|  |               lastTime: selectedTime.completeName, | ||||||
|  |               dataChart: data, | ||||||
|  |             ), | ||||||
|  |             Center( | ||||||
|  |               child: Padding( | ||||||
|  |                 padding: const EdgeInsets.all(24), | ||||||
|  |                 child: switchTab(listTab, (value) { | ||||||
|  |                   setState(() { | ||||||
|  |                     selectedTab = value; | ||||||
|  |                     data.clear(); | ||||||
|  |                     List.generate(selectedTime.value, (index) => { | ||||||
|  |                       data.add((2500 + index - Random().nextInt(100)).toDouble()) | ||||||
|  |                     }); | ||||||
|  |                   }); | ||||||
|  |                 }, selectedTab), | ||||||
|  |               ), | ||||||
|  |             ), | ||||||
|  |             swithTime(), | ||||||
|  |             const SizedBox( | ||||||
|  |             height: 24, | ||||||
|  |             ), | ||||||
|  |             Padding( | ||||||
|  |               padding: const EdgeInsets.symmetric(horizontal: 24), | ||||||
|  |               child: Row( | ||||||
|  |                 mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||||
|  |                 children: [ | ||||||
|  |                   columnInformation('CAGR 1Y', '3,88%'), | ||||||
|  |                   columnInformation('Drawdown 1Y', '0%'), | ||||||
|  |                   columnInformation('Expense Ratio', '1,99%') | ||||||
|  |                 ], | ||||||
|  |               ), | ||||||
|  |             ), | ||||||
|  |             const SizedBox( | ||||||
|  |               height: 16, | ||||||
|  |             ), | ||||||
|  |             Padding( | ||||||
|  |               padding: const EdgeInsets.symmetric(horizontal: 24), | ||||||
|  |               child: Row( | ||||||
|  |                 mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||||
|  |                 children: [ | ||||||
|  |                   columnInformation('Total AUM', '3,88%'), | ||||||
|  |                   columnInformation('Avg.Yield Dec 23', '6,44%'), | ||||||
|  |                   columnInformation('Risk Level', 'Conservative') | ||||||
|  |                 ], | ||||||
|  |               ), | ||||||
|  |             ), | ||||||
|  |             const SizedBox( | ||||||
|  |               height: 24, | ||||||
|  |             ), | ||||||
|  |             cardInformation('Investment Information', informationInvest()), | ||||||
|  |             const SizedBox( | ||||||
|  |               height: 24, | ||||||
|  |             ), | ||||||
|  |             cardInformation('Investment Costs', investCost()), | ||||||
|  |             const SizedBox( | ||||||
|  |               height: 24, | ||||||
|  |             ), | ||||||
|  |             moreAction(), | ||||||
|  |             const SizedBox( | ||||||
|  |               height: 24, | ||||||
|  |             ), | ||||||
|  |             cardInformation('Time Machine', timeMachine()), | ||||||
|  |             const SizedBox( | ||||||
|  |               height: 24, | ||||||
|  |             ), | ||||||
|  |             topFiveHoldings(), | ||||||
|  |             const SizedBox( | ||||||
|  |               height: 24, | ||||||
|  |             ), | ||||||
|  |             cardInformation('Document', documentProduct()), | ||||||
|  |           ], | ||||||
|  |         ), | ||||||
|  |       ), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Widget switchTab(List<String> dataTab, void Function(int value) onTap, int current) { | ||||||
|  |     return Container( | ||||||
|  |       width: SizeConfig.width, | ||||||
|  |       decoration: BoxDecoration( | ||||||
|  |         border: Border.all( | ||||||
|  |           color: ColorPalette.slate200, | ||||||
|  |         ), | ||||||
|  |         borderRadius: BorderRadius.circular(80) | ||||||
|  |       ), | ||||||
|  |       child: Stack( | ||||||
|  |         children: [ | ||||||
|  |           // AnimatedPositioned( | ||||||
|  |           //   duration: const Duration(milliseconds: 200), | ||||||
|  |           //   curve: Curves.fastOutSlowIn, | ||||||
|  |           //   right: current == dataTab.length - 1 ? 0 : SizeConfig.width * current / dataTab.length - (12 * dataTab.length), | ||||||
|  |           //   left:  current == 0 ? 0 : SizeConfig.width * current / dataTab.length - (12 * dataTab.length), | ||||||
|  |           //   child: Container( | ||||||
|  |           //     height: 35, | ||||||
|  |           //     decoration: BoxDecoration( | ||||||
|  |           //       color: ColorPalette.blue200, | ||||||
|  |           //       borderRadius: BorderRadius.circular(80) | ||||||
|  |           //     ), | ||||||
|  |           //   ), | ||||||
|  |           // ), | ||||||
|  |           Container( | ||||||
|  |             height: 35, | ||||||
|  |             decoration: BoxDecoration( | ||||||
|  |               borderRadius: BorderRadius.circular(80) | ||||||
|  |             ), | ||||||
|  |             child: Row( | ||||||
|  |               children: dataTab.asMap().entries.map((e) => Expanded( | ||||||
|  |                   child: GestureDetector( | ||||||
|  |                       onTap: () { | ||||||
|  |                         onTap(e.key); | ||||||
|  |                       }, | ||||||
|  |                       child: AnimatedContainer( | ||||||
|  |                         duration: const Duration(milliseconds: 300), | ||||||
|  |                         height: 35, | ||||||
|  |                         alignment: Alignment.center, | ||||||
|  |                         decoration: BoxDecoration( | ||||||
|  |                           borderRadius: BorderRadius.circular(80), | ||||||
|  |                           color: e.key == current ? ColorPalette.blue200 : ColorPalette.white | ||||||
|  |                         ), | ||||||
|  |                         child: Text( | ||||||
|  |                           e.value, | ||||||
|  |                           textAlign: TextAlign.center, | ||||||
|  |                           style: TextStyle( | ||||||
|  |                             fontWeight: e.key == current ? FontWeight.w700 : FontWeight.w500, | ||||||
|  |                             color: e.key == current ? ColorPalette.primary : ColorPalette.slate500 | ||||||
|  |                           ), | ||||||
|  |                         ), | ||||||
|  |                       ) | ||||||
|  |                   ) | ||||||
|  |               )).toList(), | ||||||
|  |             ), | ||||||
|  |           ) | ||||||
|  |         ], | ||||||
|  |       ), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Widget swithTime() { | ||||||
|  |     return Container( | ||||||
|  |         color: ColorPalette.slate50, | ||||||
|  |         alignment: Alignment.center, | ||||||
|  |         child: SingleChildScrollView( | ||||||
|  |           scrollDirection: Axis.horizontal, | ||||||
|  |           padding: const EdgeInsets.symmetric(horizontal: 24), | ||||||
|  |           child: Row( | ||||||
|  |             mainAxisAlignment: MainAxisAlignment.center, | ||||||
|  |             children: listTime.map((e) { | ||||||
|  |               return GestureDetector( | ||||||
|  |                 onTap: () { | ||||||
|  |                   setState(() { | ||||||
|  |                     selectedTime = e; | ||||||
|  |                     data.clear(); | ||||||
|  |                     List.generate(e.value, (index) => { | ||||||
|  |                       data.add((2500 + index - Random().nextInt(100)).toDouble()) | ||||||
|  |                     }); | ||||||
|  |                   }); | ||||||
|  |                 }, | ||||||
|  |                 child: AnimatedContainer( | ||||||
|  |                   duration: const Duration(milliseconds: 200), | ||||||
|  |                   width: SizeConfig.width * .12, | ||||||
|  |                   alignment: Alignment.center, | ||||||
|  |                   padding: const EdgeInsets.symmetric(vertical: 4), | ||||||
|  |                   decoration: BoxDecoration( | ||||||
|  |                       borderRadius: BorderRadius.circular(4), | ||||||
|  |                       color: selectedTime == e ? ColorPalette.primary : ColorPalette.slate50 | ||||||
|  |                   ), | ||||||
|  |                   child: Text(e.simpleName, style: TextStyle( | ||||||
|  |                       color: selectedTime == e ? ColorPalette.white : ColorPalette.slate400, | ||||||
|  |                       fontWeight: FontWeight.w700 | ||||||
|  |                   )), | ||||||
|  |                 ), | ||||||
|  |               ); | ||||||
|  |             }).toList(), | ||||||
|  |           ), | ||||||
|  |         ) | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Widget columnInformation(String title, String value) { | ||||||
|  |     return Column( | ||||||
|  |       crossAxisAlignment: CrossAxisAlignment.center, | ||||||
|  |       children: [ | ||||||
|  |         rowInformation(title), | ||||||
|  |         Row( | ||||||
|  |           mainAxisAlignment: MainAxisAlignment.center, | ||||||
|  |           children: [ | ||||||
|  |             Text(value) | ||||||
|  |           ], | ||||||
|  |         ) | ||||||
|  |       ], | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Widget rowInformation(String title) { | ||||||
|  |     return Row( | ||||||
|  |       mainAxisAlignment: MainAxisAlignment.center, | ||||||
|  |       children: [ | ||||||
|  |         Text( | ||||||
|  |           title, | ||||||
|  |           maxLines: 1, | ||||||
|  |           style: const TextStyle( | ||||||
|  |             color: ColorPalette.slate400, | ||||||
|  |             fontWeight: FontWeight.w600 | ||||||
|  |           ), | ||||||
|  |         ), | ||||||
|  |         const SizedBox(width: 2), | ||||||
|  |         const Icon(Icons.info_outline_rounded, size: 16, color: ColorPalette.slate400) | ||||||
|  |       ], | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   Widget cardInformation(String title, Widget child) { | ||||||
|  |     return Container( | ||||||
|  |       margin: const EdgeInsets.symmetric(horizontal: 24), | ||||||
|  |       padding: const EdgeInsets.all(16), | ||||||
|  |       decoration: BoxDecoration( | ||||||
|  |         border: Border.all(color: ColorPalette.slate200), | ||||||
|  |         borderRadius: BorderRadius.circular(12) | ||||||
|  |       ), | ||||||
|  |       child: Column( | ||||||
|  |         crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |         children: [ | ||||||
|  |           TextTitle(title: title, fontSize: 16), | ||||||
|  |           const SizedBox( | ||||||
|  |             height: 16, | ||||||
|  |           ), | ||||||
|  |           child | ||||||
|  |         ], | ||||||
|  |       ), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Widget informationInvest() { | ||||||
|  |     return Column( | ||||||
|  |       children: [ | ||||||
|  |         const Row( | ||||||
|  |           mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||||
|  |           children: [ | ||||||
|  |             Text( | ||||||
|  |               'Minimum Purchase', | ||||||
|  |               style: TextStyle( | ||||||
|  |                 color: ColorPalette.slate400, | ||||||
|  |                 fontWeight: FontWeight.w600 | ||||||
|  |               ), | ||||||
|  |             ), | ||||||
|  |             Text('Rp10.000') | ||||||
|  |           ], | ||||||
|  |         ), | ||||||
|  |         Row( | ||||||
|  |           mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||||
|  |           children: [ | ||||||
|  |             rowInformation('Custodian Bank'), | ||||||
|  |             const Text('HSBC INDONESIA') | ||||||
|  |           ], | ||||||
|  |         ), | ||||||
|  |         Row( | ||||||
|  |           mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||||
|  |           children: [ | ||||||
|  |             rowInformation('Depository Bank'), | ||||||
|  |             const Text('BCA') | ||||||
|  |           ], | ||||||
|  |         ) | ||||||
|  |       ], | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Widget investCost(){ | ||||||
|  |     return Column( | ||||||
|  |       children: [ | ||||||
|  |         const Row( | ||||||
|  |           mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||||
|  |           children: [ | ||||||
|  |             Text( | ||||||
|  |               'Purchase Commission', | ||||||
|  |               style: TextStyle( | ||||||
|  |                   color: ColorPalette.slate400, | ||||||
|  |                   fontWeight: FontWeight.w600 | ||||||
|  |               ), | ||||||
|  |             ), | ||||||
|  |             Text('Free', | ||||||
|  |               style: TextStyle( | ||||||
|  |                 fontWeight: FontWeight.bold | ||||||
|  |               ), | ||||||
|  |             ) | ||||||
|  |           ], | ||||||
|  |         ), | ||||||
|  |         Row( | ||||||
|  |           mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||||
|  |           children: [ | ||||||
|  |             rowInformation('Sales Commission'), | ||||||
|  |             const Text('Free', | ||||||
|  |               style: TextStyle( | ||||||
|  |                 fontWeight: FontWeight.bold | ||||||
|  |               ), | ||||||
|  |             ) | ||||||
|  |           ], | ||||||
|  |         ), | ||||||
|  |       ], | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Widget moreAction() { | ||||||
|  |     return Padding( | ||||||
|  |       padding: const EdgeInsets.symmetric(horizontal: 24), | ||||||
|  |       child: Row( | ||||||
|  |         children: [ | ||||||
|  |           Expanded( | ||||||
|  |             child: ButtonView( | ||||||
|  |               onPressed: () { | ||||||
|  |  | ||||||
|  |               }, | ||||||
|  |               prefixIcon: Icon(Icons.space_dashboard_sharp), | ||||||
|  |               backgroundColor: ColorPalette.blue50, | ||||||
|  |               sizeBorderRadius: 8, | ||||||
|  |               isSecondaryColor: false, | ||||||
|  |               width: SizeConfig.width * .5, | ||||||
|  |               heightWrapContent: true, | ||||||
|  |               isOutlined: true, | ||||||
|  |               widthPrefix: 10, | ||||||
|  |               name: 'Routine Savings', | ||||||
|  |               textSize: 14, | ||||||
|  |               textAlign: TextAlign.start, | ||||||
|  |               contentPadding: EdgeInsets.all(12), | ||||||
|  |             ) | ||||||
|  |           ), | ||||||
|  |           SizedBox( | ||||||
|  |             width: 16, | ||||||
|  |           ), | ||||||
|  |           Expanded( | ||||||
|  |               child: ButtonView( | ||||||
|  |                 onPressed: () { | ||||||
|  |  | ||||||
|  |                 }, | ||||||
|  |                 prefixIcon: Icon(Icons.space_dashboard_sharp, color: ColorPalette.orange500), | ||||||
|  |                 widthPrefix: 10, | ||||||
|  |                 name: 'Compare Mutual Funds', | ||||||
|  |                 width: SizeConfig.width * .5, | ||||||
|  |                 heightWrapContent: true, | ||||||
|  |                 backgroundColor: ColorPalette.orange50, | ||||||
|  |                 sizeBorderRadius: 8, | ||||||
|  |                 isOutlined: true, | ||||||
|  |                 borderColor: ColorPalette.orange500, | ||||||
|  |                 textSize: 14, | ||||||
|  |                 textAlign: TextAlign.start, | ||||||
|  |                 textColor: ColorPalette.orange500, | ||||||
|  |                 contentPadding: EdgeInsets.all(12), | ||||||
|  |               ) | ||||||
|  |           ), | ||||||
|  |         ], | ||||||
|  |       ), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Widget timeMachine() { | ||||||
|  |     return Column( | ||||||
|  |       crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |       children: [ | ||||||
|  |         switchTab(listMachine, (value) { | ||||||
|  |             setState(() { | ||||||
|  |               selectedMachineType = value; | ||||||
|  |             }); | ||||||
|  |             setEstimatedValue(); | ||||||
|  |           }, | ||||||
|  |           selectedMachineType | ||||||
|  |         ), | ||||||
|  |         const Padding( | ||||||
|  |           padding: EdgeInsets.only(top: 16, bottom: 8), | ||||||
|  |           child: Text( | ||||||
|  |             "Today's Investment Estimated Value", | ||||||
|  |             style: TextStyle( | ||||||
|  |               fontWeight: FontWeight.w600, | ||||||
|  |               color: ColorPalette.slate800 | ||||||
|  |             ), | ||||||
|  |           ), | ||||||
|  |         ), | ||||||
|  |         TextFormView( | ||||||
|  |           name: '', | ||||||
|  |           ctrl: machineController, | ||||||
|  |           onChanged: (value) { | ||||||
|  |             value = value.replaceAll('Rp ', '').replaceAll('.', ''); | ||||||
|  |             double parseValue = double.parse(value); | ||||||
|  |             if(value.isNotEmpty){ | ||||||
|  |               machineController.text = NumberFormatter.numberCurrency(parseValue, 'Rp ', 'id_ID', decimalDigits: 0); | ||||||
|  |             }else{ | ||||||
|  |               machineController.text = NumberFormatter.numberCurrency(0, 'Rp ', 'id_ID', decimalDigits: 0); | ||||||
|  |             } | ||||||
|  |             setEstimatedValue(); | ||||||
|  |           }, | ||||||
|  |           keyboardType: TextInputType.number, | ||||||
|  |         ), | ||||||
|  |         const Padding( | ||||||
|  |           padding: EdgeInsets.only(top: 16, bottom: 8), | ||||||
|  |           child: Text( | ||||||
|  |             "How many years ago did you start investing?", | ||||||
|  |             style: TextStyle( | ||||||
|  |                 fontWeight: FontWeight.w600, | ||||||
|  |                 color: ColorPalette.slate800 | ||||||
|  |             ), | ||||||
|  |           ), | ||||||
|  |         ), | ||||||
|  |         Center( | ||||||
|  |           child: GroupButton( | ||||||
|  |             buttons: listMachineTime.map((e) => e.completeName).toList(), | ||||||
|  |             controller: machineGroupButtonController, | ||||||
|  |             onSelected: (value, index, isSelected) { | ||||||
|  |               setState(() { | ||||||
|  |                 selectedMachineTime = index; | ||||||
|  |               }); | ||||||
|  |               setEstimatedValue(); | ||||||
|  |             }, | ||||||
|  |             options: GroupButtonOptions( | ||||||
|  |               buttonWidth: SizeConfig.width * .375, | ||||||
|  |               mainGroupAlignment: MainGroupAlignment.spaceBetween, | ||||||
|  |               groupRunAlignment: GroupRunAlignment.spaceBetween, | ||||||
|  |               spacing: 16, | ||||||
|  |               elevation: 0, | ||||||
|  |               borderRadius: BorderRadius.circular(80), | ||||||
|  |               selectedShadow: const [], | ||||||
|  |               selectedColor: Colors.white, | ||||||
|  |               selectedBorderColor: ColorPalette.primary, | ||||||
|  |               selectedTextStyle: const TextStyle( | ||||||
|  |                 fontWeight: FontWeight.w700, | ||||||
|  |                 color: ColorPalette.primary | ||||||
|  |               ), | ||||||
|  |               unselectedShadow: const [], | ||||||
|  |               unselectedBorderColor: ColorPalette.slate200, | ||||||
|  |               unselectedTextStyle: const TextStyle( | ||||||
|  |                 fontWeight: FontWeight.w500, | ||||||
|  |                 color: ColorPalette.slate500 | ||||||
|  |               ), | ||||||
|  |             ), | ||||||
|  |           ), | ||||||
|  |         ), | ||||||
|  |         const Padding( | ||||||
|  |           padding: EdgeInsets.only(top: 16, bottom: 8), | ||||||
|  |           child: Text( | ||||||
|  |             "Today's Investment Estimated Value", | ||||||
|  |             style: TextStyle( | ||||||
|  |                 fontWeight: FontWeight.w600, | ||||||
|  |                 color: ColorPalette.slate500 | ||||||
|  |             ), | ||||||
|  |           ), | ||||||
|  |         ), | ||||||
|  |         TextTitle( | ||||||
|  |           title: NumberFormatter.numberCurrency(estimatedValue, 'Rp ', 'id_ID'), | ||||||
|  |           fontSize: 24, | ||||||
|  |           color: ColorPalette.primary, | ||||||
|  |         ) | ||||||
|  |       ], | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Widget topFiveHoldings() { | ||||||
|  |     return Column( | ||||||
|  |       children: [ | ||||||
|  |         const Padding( | ||||||
|  |           padding: EdgeInsets.symmetric(horizontal: 24), | ||||||
|  |           child: Row( | ||||||
|  |             mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||||
|  |             children: [ | ||||||
|  |               TextTitle(title: 'Top 5 Holdings'), | ||||||
|  |               Text( | ||||||
|  |                 'As of 31 Dec 2023', | ||||||
|  |                 style: TextStyle( | ||||||
|  |                   fontSize: 12, | ||||||
|  |                   color: ColorPalette.slate400 | ||||||
|  |                 ), | ||||||
|  |               ) | ||||||
|  |             ], | ||||||
|  |           ), | ||||||
|  |         ), | ||||||
|  |         const SizedBox( | ||||||
|  |           height: 16, | ||||||
|  |         ), | ||||||
|  |         ...listTopHoldings.asMap().entries.map((e) { | ||||||
|  |           return topProduct(e.key, e.value); | ||||||
|  |         }) | ||||||
|  |       ], | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Widget topProduct(int index, String name) { | ||||||
|  |     return Column( | ||||||
|  |       children: [ | ||||||
|  |         if(index != 0)...[ | ||||||
|  |           const Padding( | ||||||
|  |             padding: EdgeInsets.symmetric(vertical: 16), | ||||||
|  |             child: Divider(color: ColorPalette.slate200,), | ||||||
|  |           ) | ||||||
|  |         ], | ||||||
|  |         Padding( | ||||||
|  |           padding: const EdgeInsets.symmetric(horizontal: 24), | ||||||
|  |           child: Row( | ||||||
|  |             children: [ | ||||||
|  |               Container( | ||||||
|  |                 alignment: Alignment.center, | ||||||
|  |                 padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 11), | ||||||
|  |                 decoration: BoxDecoration( | ||||||
|  |                   shape: BoxShape.circle, | ||||||
|  |                   color: ColorPalette.blue50, | ||||||
|  |                   border: Border.all(color: ColorPalette.blue200) | ||||||
|  |                 ), | ||||||
|  |                 child: Text(index.toString(), style: const TextStyle(color: ColorPalette.primary)), | ||||||
|  |               ), | ||||||
|  |               const SizedBox( | ||||||
|  |                 width: 16, | ||||||
|  |               ), | ||||||
|  |               Expanded( | ||||||
|  |                 child: Text( | ||||||
|  |                   name, | ||||||
|  |                   style: const TextStyle( | ||||||
|  |                     color: ColorPalette.slate800, | ||||||
|  |                     fontSize: 16 | ||||||
|  |                   ), | ||||||
|  |                 ) | ||||||
|  |               ) | ||||||
|  |             ], | ||||||
|  |           ), | ||||||
|  |         ) | ||||||
|  |       ], | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Widget documentProduct() { | ||||||
|  |     return Column( | ||||||
|  |       children: [ | ||||||
|  |         Wrap( | ||||||
|  |           runAlignment: WrapAlignment.spaceBetween, | ||||||
|  |           alignment: WrapAlignment.spaceBetween, | ||||||
|  |           children: [ | ||||||
|  |             SizedBox( | ||||||
|  |               width: SizeConfig.width * .4, | ||||||
|  |               child: const Row( | ||||||
|  |                 children: [ | ||||||
|  |                   Icon(Icons.file_copy_outlined, color: ColorPalette.primary), | ||||||
|  |                   SizedBox( | ||||||
|  |                     width: 16, | ||||||
|  |                   ), | ||||||
|  |                   Text( | ||||||
|  |                     'Prospektus', | ||||||
|  |                     style: TextStyle( | ||||||
|  |                       color: ColorPalette.primary, | ||||||
|  |                       fontWeight: FontWeight.w600 | ||||||
|  |                     ), | ||||||
|  |                   ) | ||||||
|  |                 ], | ||||||
|  |               ), | ||||||
|  |             ), | ||||||
|  |             SizedBox( | ||||||
|  |               width: SizeConfig.width * .4, | ||||||
|  |               child: const Row( | ||||||
|  |                 children: [ | ||||||
|  |                   Icon(Icons.file_copy_outlined, color: ColorPalette.primary), | ||||||
|  |                   SizedBox( | ||||||
|  |                     width: 16, | ||||||
|  |                   ), | ||||||
|  |                   Expanded( | ||||||
|  |                     child: Text( | ||||||
|  |                       'Fun Fact Sheet', | ||||||
|  |                       overflow: TextOverflow.ellipsis, | ||||||
|  |                       style: TextStyle( | ||||||
|  |                           color: ColorPalette.primary, | ||||||
|  |                           fontWeight: FontWeight.w600 | ||||||
|  |                       ), | ||||||
|  |                     ), | ||||||
|  |                   ) | ||||||
|  |                 ], | ||||||
|  |               ), | ||||||
|  |             ) | ||||||
|  |           ], | ||||||
|  |         ) | ||||||
|  |       ], | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -5,6 +5,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/registration_view.dart'; | import 'package:cims_apps/features/auth/registration/view/registration_view.dart'; | ||||||
|  | import 'package:cims_apps/features/bottom_navigation_view.dart'; | ||||||
| import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||||
|  |  | ||||||
| class DashboardPublicView extends StatelessWidget { | class DashboardPublicView extends StatelessWidget { | ||||||
| @@ -68,7 +69,9 @@ class DashboardPublicView extends StatelessWidget { | |||||||
|                   isOutlined: true, |                   isOutlined: true, | ||||||
|                   width: SizeConfig.width * .43, |                   width: SizeConfig.width * .43, | ||||||
|                   height: SizeConfig.height * .06, |                   height: SizeConfig.height * .06, | ||||||
|                   onPressed: () {}, |                   onPressed: () { | ||||||
|  |                     routePush(context, page: const BottomNavigationView()); | ||||||
|  |                   }, | ||||||
|                 ), |                 ), | ||||||
|                 ButtonView( |                 ButtonView( | ||||||
|                   name: 'Sign Up', |                   name: 'Sign Up', | ||||||
|   | |||||||
							
								
								
									
										40
									
								
								pubspec.lock
									
									
									
									
									
								
							
							
						
						| @@ -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" | ||||||
|  |   carousel_slider: | ||||||
|  |     dependency: "direct main" | ||||||
|  |     description: | ||||||
|  |       name: carousel_slider | ||||||
|  |       sha256: "9c695cc963bf1d04a47bd6021f68befce8970bcd61d24938e1fb0918cf5d9c42" | ||||||
|  |       url: "https://pub.dev" | ||||||
|  |     source: hosted | ||||||
|  |     version: "4.2.1" | ||||||
|   characters: |   characters: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
| @@ -97,6 +105,14 @@ packages: | |||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "1.0.6" |     version: "1.0.6" | ||||||
|  |   equatable: | ||||||
|  |     dependency: transitive | ||||||
|  |     description: | ||||||
|  |       name: equatable | ||||||
|  |       sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2 | ||||||
|  |       url: "https://pub.dev" | ||||||
|  |     source: hosted | ||||||
|  |     version: "2.0.5" | ||||||
|   fake_async: |   fake_async: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
| @@ -129,6 +145,14 @@ packages: | |||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "1.1.0" |     version: "1.1.0" | ||||||
|  |   fl_chart: | ||||||
|  |     dependency: "direct main" | ||||||
|  |     description: | ||||||
|  |       name: fl_chart | ||||||
|  |       sha256: "5a74434cc83bf64346efb562f1a06eefaf1bcb530dc3d96a104f631a1eff8d79" | ||||||
|  |       url: "https://pub.dev" | ||||||
|  |     source: hosted | ||||||
|  |     version: "0.65.0" | ||||||
|   flutter: |   flutter: | ||||||
|     dependency: "direct main" |     dependency: "direct main" | ||||||
|     description: flutter |     description: flutter | ||||||
| @@ -168,6 +192,14 @@ packages: | |||||||
|     description: flutter |     description: flutter | ||||||
|     source: sdk |     source: sdk | ||||||
|     version: "0.0.0" |     version: "0.0.0" | ||||||
|  |   group_button: | ||||||
|  |     dependency: "direct main" | ||||||
|  |     description: | ||||||
|  |       name: group_button | ||||||
|  |       sha256: "0610fcf28ed122bfb4b410fce161a390f7f2531d55d1d65c5375982001415940" | ||||||
|  |       url: "https://pub.dev" | ||||||
|  |     source: hosted | ||||||
|  |     version: "5.3.4" | ||||||
|   http: |   http: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
| @@ -184,6 +216,14 @@ packages: | |||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "4.0.2" |     version: "4.0.2" | ||||||
|  |   intl: | ||||||
|  |     dependency: "direct main" | ||||||
|  |     description: | ||||||
|  |       name: intl | ||||||
|  |       sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf | ||||||
|  |       url: "https://pub.dev" | ||||||
|  |     source: hosted | ||||||
|  |     version: "0.19.0" | ||||||
|   js: |   js: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|   | |||||||
| @@ -39,7 +39,11 @@ dependencies: | |||||||
|   flutter_svg: ^1.1.6 |   flutter_svg: ^1.1.6 | ||||||
|   cached_network_image: ^3.2.3 |   cached_network_image: ^3.2.3 | ||||||
|   remove_emoji_input_formatter: ^0.0.1+1 |   remove_emoji_input_formatter: ^0.0.1+1 | ||||||
|  |   fl_chart: ^0.65.0 | ||||||
|  |   intl: ^0.19.0 | ||||||
|  |   carousel_slider: ^4.2.1 | ||||||
|   provider: ^6.1.1 |   provider: ^6.1.1 | ||||||
|  |   group_button: ^5.3.4 | ||||||
|   pinput: ^2.2.21 |   pinput: ^2.2.21 | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||