invest screen ui

This commit is contained in:
jayesh
2024-06-11 16:53:29 +05:30
parent 6e6e2efcc2
commit fce7910f8e
16 changed files with 606 additions and 5 deletions

View File

@@ -64,4 +64,5 @@ class RouteName {
//invest
static const String investDetailScreen = "investDetailScreen";
static const String investPaymentScreen = "investPaymentScreen";
}

View File

@@ -4,14 +4,12 @@ import 'package:go_router/go_router.dart';
import 'package:tanami_app/core/routes/route_name.dart';
import 'package:tanami_app/features/MainScreens/Academy/presentation/pages/academy_details_screen.dart';
import 'package:tanami_app/features/MainScreens/Invest/presentation/pages/invest_details_screen.dart';
import 'package:tanami_app/features/MainScreens/Invest/presentation/pages/payment/invest_payment_screen.dart';
import 'package:tanami_app/features/MainScreens/Portfolio/presentation/pages/portfolio_details_screen.dart';
import 'package:tanami_app/features/MainScreens/Wallet/presentation/pages/walletDetails.dart';
import 'package:tanami_app/features/biometric/presentation/pages/biometric_screen.dart';
import 'package:tanami_app/features/changePassword/presentation/pages/change_password_screen.dart';
import 'package:tanami_app/features/contactAdmin/presentation/pages/contact_admin_screen.dart';
import 'package:tanami_app/features/countrySelection/presentation/pages/choose_country_screen.dart';
import 'package:tanami_app/features/deleteAccount/presentation/pages/delete_account_screen.dart';
import 'package:tanami_app/features/forgotPassword/presentation/pages/restore_password_screen.dart';
@@ -201,6 +199,13 @@ final goRouter = GoRouter(
return const InvestDetailsScreen();
},
),
GoRoute(
name: RouteName.investPaymentScreen,
path: RouteName.investPaymentScreen,
builder: (context, state) {
return const InvestPaymentScreen();
},
),
],
),
],

View File

@@ -80,6 +80,7 @@ class AppColor {
//Language Color
static const Color languageTextColor = Color(0xFF015698);
static const Color infoTextColor = Color(0xFFDF7B00);
//Delete Account Color
static const Color descriptionText = Color(0xFFC6C6C6);
@@ -90,4 +91,5 @@ class AppColor {
static const Color investKycBoxShadow1Color = Color(0xFF90D4FF);
static const Color investKycBoxShadow2Color = Color(0xA0DAF0FF);
static const Color investTextColor = Color(0xFF066123);
static const Color investPaymentTextColor = Color(0xFF535353);
}

View File

@@ -102,6 +102,8 @@ class AppImages {
//Language
static const String infoIcon =
'assets/images/language_screen/png/info_icon.png';
static const String orangenInfoIcon =
'assets/images/language_screen/png/orange_info.png';
//Invest
static const String investIcon =
@@ -112,4 +114,6 @@ class AppImages {
static const String walletIcon = 'assets/images/invest_screen/svg/wallet.svg';
static const String timeSquareIcon =
'assets/images/invest_screen/svg/time_square.svg';
static const String applePayIcon =
'assets/images/invest_screen/svg/apple_pay.svg';
}

View File

@@ -129,6 +129,7 @@ class AppText {
//Wallet
static const String walletTitle = "Wallet balance";
static const String walletText = "Wallet";
static const String day = "Today";
static const String onHold = "On hold";
@@ -204,4 +205,38 @@ class AppText {
static const String holdingPeriodText = "Holding period";
static const String minimumInvestmentText = "Minimum investment";
static const String keyMeritsIOfnvestmentText = "Key Merits of Investment";
static const String investmentDetailsText = "Investment details";
static const String enterInvestmentAmountText = "Enter investment amount";
static const String thisIsUsdInvestmentOpportunityText =
"This is a USD investment opportunity. Funds will be converted into USD upon confirmation.";
static const String choosePaymentMethodText = "Choose payment method";
static const String balanceText = "Balance";
static const String applePayText = "Apple Pay";
static const String gPayText = "Gpay Pay";
static const String instantTransferFundsApplePayText =
"Instant transfer of funds using Apple Pay!";
static const String instantTransferFundsGpayPayText =
"Instant transfer of funds using Gpay Pay!";
static const String retailInvestirCanInvestMaxText =
"Retail investors can invest a maximum of SAR 200,000 in this opportunity.";
static const String upgradeYourInvestorStatusToIncreaseText =
"Upgrade your investor status to increase your investment limit.";
static const String currentExchangeText = "Current Exchange";
static const String feeText = "Fee";
static const String debitedAmountText = "Debited amount";
static const String totalInvestmentAmountText = "Total Investment amount";
static const String confirmInvestmentText = "Confirm investment";
static const String paymentMethodText = "Payment method";
static const String totalDebitedAmountText = "Total debited amount";
static const String unableToProcessTransactionText =
"Unable to process transaction";
static const String investmentOpportunityHasReachedMaxcapText =
"Investment opportunity has reached maximum capacity";
static const String backToInvestmentText = "Back to Investment";
static const String otpCheckIsFailedText = "OTP Check is failed...";
static const String pleaseTryAgainText = "Please try again";
static const String tryAgainText = "Try again";
static const String investmentConfirmationText = "Investment confirmation";
static const String enterAmountText = "Enter Amount";
static const String pleaseEnterAmountText = "Please Enter Amount";
}

View File

@@ -1,9 +1,12 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:tanami_app/core/routes/route_name.dart';
import 'package:tanami_app/core/routes/routes.dart';
import 'package:tanami_app/core/styles/app_color.dart';
import 'package:tanami_app/core/styles/app_text.dart';
import 'package:tanami_app/shared/components/button_widget.dart';
import '../../../../../shared/components/appbar_widget.dart';
import '../../../Portfolio/presentation/bloc/carousel/carousel_bloc.dart';
import 'invest_details_layout.dart';
@@ -21,7 +24,9 @@ class InvestDetailsScreen extends StatelessWidget {
child: ButtonWidget().elevatedBtn(
text: AppText.investText,
clr: AppColor.primaryColor2,
function: () {}),
function: () {
goRouter.pushNamed(RouteName.investPaymentScreen);
}),
),
appBar: const AppBarWidget(
height: 45,

View File

@@ -0,0 +1,24 @@
import 'package:flutter/material.dart';
import 'package:tanami_app/features/MainScreens/Invest/presentation/widgets/payment/invest_pay_bottom_section.dart';
import 'package:tanami_app/features/MainScreens/Invest/presentation/widgets/payment/invest_pay_method_section.dart';
import 'package:tanami_app/features/MainScreens/Invest/presentation/widgets/payment/invest_pay_top_section.dart';
class InvestPaymentLayout extends StatelessWidget {
const InvestPaymentLayout({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(16.0),
child: ListView(
children: const [
InvestPayTopSection(),
InvestPayMethodSection(),
InvestPayBottomSection(),
],
),
),
);
}
}

View File

@@ -0,0 +1,20 @@
import 'package:flutter/material.dart';
import '../../../../../../core/styles/app_text.dart';
import '../../../../../../shared/components/appbar_widget.dart';
import 'invest_payment_layout.dart';
class InvestPaymentScreen extends StatelessWidget {
const InvestPaymentScreen({super.key});
@override
Widget build(BuildContext context) {
return const Scaffold(
appBar: AppBarWidget(
height: 75,
titleTxt: AppText.investmentDetailsText,
),
body: InvestPaymentLayout(),
);
}
}

View File

@@ -0,0 +1,67 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:gap/gap.dart';
import '../../../../../../core/routes/routes.dart';
import '../../../../../../core/styles/app_color.dart';
import '../../../../../../core/styles/app_text.dart';
import '../../../../../../shared/components/button_widget.dart';
import '../../../../../../shared/components/text_widget.dart';
class InvestPayBottomSection extends StatelessWidget {
const InvestPayBottomSection({super.key});
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
margin: const EdgeInsets.symmetric(
horizontal: 16,
),
width: 1.sw,
height: 56.h,
child: ButtonWidget().elevatedBtn(
txtClr: // isButtonEnabled ?
AppColor.plainWhite,
// : AppColor.inactiveBtnTxtColor,
function: () {
// isButtonEnabled
// ? context.read<ChangePasswordBloc>().add(
// ChangePasswordSubmitted(
// context
// .read<ChangePasswordBloc>()
// .currentPasswordTextField
// .text,
// context
// .read<ChangePasswordBloc>()
// .passwordTextField
// .text,
// context
// .read<ChangePasswordBloc>()
// .repeatPasswordTextField
// .text,
// ),
// )
// : null;
},
text: AppText.nextText,
clr:
// isButtonEnabled ?
AppColor.primaryColor2
// : AppColor.inactiveBtnColor,
),
),
const Gap(5),
ButtonWidget().textBtn(
function: () {
goRouter.pop();
},
text: TextWidget().text14W700(AppText.backText,
clr: AppColor.textLabelColor,
textDecoration: TextDecoration.underline)),
],
);
}
}

View File

@@ -0,0 +1,199 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:gap/gap.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:tanami_app/core/styles/app_images.dart';
import 'package:tanami_app/core/styles/app_text.dart';
import 'package:tanami_app/shared/components/text_widget.dart';
import '../../../../../../core/styles/app_color.dart';
import '../../../../../countrySelection/presentation/bloc/choose_country_bloc.dart';
import '../../../../../countrySelection/presentation/bloc/choose_country_event.dart';
import '../../../../../countrySelection/presentation/bloc/choose_country_state.dart';
class InvestPayMethodSection extends StatelessWidget {
const InvestPayMethodSection({super.key});
@override
Widget build(BuildContext context) {
final radioBloc = context.read<RadioBloc>();
return BlocBuilder<RadioBloc, RadioState>(
builder: (context, state) {
int selectedIndex = 0;
if (state is RadioSelectionChanged) {
selectedIndex = state.selectedIndex;
}
return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
TextWidget().text15W700(AppText.choosePaymentMethodText,
clr: AppColor.plainBlack),
const Gap(16),
InkWell(
onTap: () {
radioBloc.add(const RadioSelected(0));
},
child: Container(
clipBehavior: Clip.antiAlias,
padding: const EdgeInsets.all(12),
decoration: ShapeDecoration(
color: Colors.white,
shape: RoundedRectangleBorder(
side: const BorderSide(color: Color(0xFFD8D8D8)),
borderRadius: BorderRadius.circular(22),
),
shadows: const [
BoxShadow(
color: Color(0x14000000),
blurRadius: 8,
offset: Offset(-2, -2),
spreadRadius: 0.50,
),
BoxShadow(
color: Color(0x3391978E),
blurRadius: 8,
offset: Offset(2, 2),
spreadRadius: 1,
)
],
),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Radio<int>(
activeColor: AppColor.radioActiveColor,
value: 0,
groupValue: selectedIndex,
onChanged: (int? value) {
if (value != null) {
radioBloc.add(RadioSelected(value));
}
},
),
const Gap(5),
SvgPicture.asset(AppImages.walletIcon),
const Gap(5),
TextWidget().text14W700(AppText.walletText,
clr: AppColor.textLabelColor),
],
),
Container(
decoration: const BoxDecoration(
border: Border(
bottom:
BorderSide(width: 1, color: Colors.grey))),
child: Row(
children: [
RichText(
text: TextSpan(
children: [
TextSpan(
text: '${AppText.balanceText}: ',
style: GoogleFonts.dmSans(
color: Colors.grey,
fontSize: 12.0,
fontWeight: FontWeight.bold,
),
),
TextSpan(
text: 'SAR 178,000',
style: GoogleFonts.dmSans(
color: Colors.black,
fontSize: 14.0,
fontWeight: FontWeight.bold,
),
),
],
),
),
const Icon(
Icons.arrow_forward,
color: Colors.grey,
size: 15,
)
],
),
),
],
),
TextWidget().text14W500(
"condimentum ac, vestibulum eu nisl.torquent per conubia nostra, per inceptos himenaeos.",
clr: AppColor.textLabelColor),
const Gap(12),
],
),
),
),
const Gap(12),
InkWell(
onTap: () {
radioBloc.add(const RadioSelected(1));
},
child: Container(
clipBehavior: Clip.antiAlias,
padding: const EdgeInsets.all(12),
decoration: ShapeDecoration(
color: Colors.white,
shape: RoundedRectangleBorder(
side: const BorderSide(color: Color(0xFFD8D8D8)),
borderRadius: BorderRadius.circular(22),
),
shadows: const [
BoxShadow(
color: Color(0x14000000),
blurRadius: 8,
offset: Offset(-2, -2),
spreadRadius: 0.2,
),
BoxShadow(
color: Color(0x3391978E),
blurRadius: 8,
offset: Offset(2, 2),
spreadRadius: 1,
)
],
),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Radio<int>(
activeColor: AppColor.radioActiveColor,
value: 1,
groupValue: selectedIndex,
onChanged: (int? value) {
if (value != null) {
radioBloc.add(RadioSelected(value));
}
},
),
const Gap(5),
SvgPicture.asset(AppImages.applePayIcon),
const Gap(5),
TextWidget().text14W700(AppText.applePayText,
clr: AppColor.textLabelColor),
],
),
],
),
TextWidget().text14W500(
AppText.instantTransferFundsApplePayText,
clr: AppColor.textLabelColor),
const Gap(12),
],
),
),
),
const Gap(16),
]);
},
);
}
}

View File

@@ -0,0 +1,227 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:gap/gap.dart';
import 'package:tanami_app/core/styles/app_color.dart';
import 'package:tanami_app/core/styles/app_images.dart';
import 'package:tanami_app/core/styles/app_text.dart';
import 'package:tanami_app/shared/components/text_widget.dart';
import '../../../../../../shared/components/text_from_field_widget.dart';
class InvestPayTopSection extends StatelessWidget {
const InvestPayTopSection({super.key});
@override
Widget build(BuildContext context) {
TextEditingController amountController = TextEditingController();
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextWidget().text15W700(AppText.enterInvestmentAmountText,
clr: AppColor.plainBlack),
const Gap(16.0),
Container(
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
color: AppColor.plainWhite,
borderRadius: BorderRadius.circular(22.0),
boxShadow: const [
BoxShadow(
color: Color(0x14000000),
blurRadius: 8,
offset: Offset(-2, -2),
spreadRadius: 0.50,
),
BoxShadow(
color: Color(0x3391978E),
blurRadius: 8,
offset: Offset(2, 2),
spreadRadius: 4,
)
],
),
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(16.0),
child: Row(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(4),
child: Image.asset(
'assets/images/portfolio_screen/detailsbg.png',
width: 0.2.sw,
height: 0.2.sw,
fit: BoxFit.cover,
),
),
const Gap(16.0),
Expanded(
child: TextWidget().text17W700(
'Multi Family Residential',
clr: AppColor.plainBlack,
)),
],
),
),
Container(
decoration: const ShapeDecoration(
color: AppColor.portfolioCardBgColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(22),
bottomRight: Radius.circular(22),
),
),
),
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(12.0),
child: Stack(
alignment: Alignment.centerLeft,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
TextWidget().text15W700(
"SAR",
clr: AppColor.textLabelColor,
),
const Gap(12),
Expanded(
child: Column(
children: [
textFormField(
txtAlign: TextAlign.center,
readonly: false,
validator: (value) {
if (amountController.text.isEmpty) {
return AppText.pleaseEnterAmountText;
}
return null;
},
texttype: TextInputType.number,
textEditingController: amountController,
hintText: AppText.enterAmountText,
suffixIcon: const SizedBox(),
),
],
),
),
],
),
],
),
),
const Padding(
padding: EdgeInsets.all(12.0),
child: Column(
children: [
InvestmentDetailRow(
label: AppText.currentExchangeText,
value: 'SAR 1 = USD 0.267',
),
SizedBox(height: 8.0),
InvestmentDetailRow(
label: AppText.feeText,
value: '3%',
),
SizedBox(height: 8.0),
InvestmentDetailRow(
label: '${AppText.totalInvestmentAmountText}:',
value: 'SAR 1000',
),
],
),
)
],
),
)
],
),
),
const Gap(24),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Image.asset(
width: 24,
height: 24,
AppImages.orangenInfoIcon,
),
const Gap(8),
Column(
children: [
SizedBox(
width: 0.8.sw,
child: TextWidget().text12W500(
AppText.retailInvestirCanInvestMaxText,
clr: AppColor.infoTextColor,
),
),
SizedBox(
width: 0.8.sw,
child: TextWidget().text12W700(
AppText.upgradeYourInvestorStatusToIncreaseText,
clr: AppColor.infoTextColor,
txtDec: TextDecoration.underline,
decClr: AppColor.infoTextColor,
),
),
],
),
],
),
const Gap(15),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Image.asset(
width: 24,
height: 24,
AppImages.infoIcon,
),
const Gap(8),
SizedBox(
width: 0.8.sw,
child: TextWidget().text12W500(
AppText.upgradeYourInvestorStatusToIncreaseText,
clr: AppColor.languageTextColor,
),
),
],
),
const Gap(24),
],
);
}
}
class InvestmentDetailRow extends StatelessWidget {
final String label;
final String value;
const InvestmentDetailRow({
super.key,
required this.label,
required this.value,
});
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
TextWidget().text14W500(
label,
clr: AppColor.investPaymentTextColor,
),
TextWidget().text14W700(
value,
clr: AppColor.plainBlack,
),
],
);
}
}

View File

@@ -20,8 +20,10 @@ Widget textFormField({
final VoidCallback? onTap,
final TextCapitalization? textCapV,
final Widget? suffixIcon,
final TextAlign? txtAlign,
}) {
return TextFormField(
textAlign: txtAlign ?? TextAlign.start,
validator: validator,
textAlignVertical: TextAlignVertical.center,
cursorColor: AppColor.primaryColor2,

View File

@@ -45,10 +45,13 @@ class TextWidget {
color: clr ?? AppColor.plainWhite));
}
Widget text12W700(String text, {Color? clr}) {
Widget text12W700(String text,
{Color? clr, TextDecoration? txtDec, Color? decClr}) {
return Text(text,
style: GoogleFonts.dmSans(
fontSize: 12,
decorationColor: decClr ?? AppColor.plainWhite,
decoration: txtDec ?? TextDecoration.none,
fontWeight: FontWeight.w700,
color: clr ?? AppColor.plainWhite));
}