Files
Traders_Circuit/lib/view/MainScreen/Portfolio/PortfolioEmpty.dart

1024 lines
42 KiB
Dart

import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import 'package:async/async.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:glassmorphism/glassmorphism.dart';
import 'package:lottie/lottie.dart';
import 'package:scgateway_flutter_plugin/scgateway_flutter_plugin.dart';
import 'package:traderscircuit/Utils/Common/CommonBottomNavigation.dart';
import 'package:traderscircuit/Utils/Common/commonBotton.dart';
import 'package:traderscircuit/Utils/Common/sized_box.dart';
import 'package:traderscircuit/Utils/text.dart';
import 'package:traderscircuit/view/MainScreen/MainScreen.dart';
import 'package:traderscircuit/view/Sidemenu/Sidemenu.dart';
import 'package:traderscircuit/view/onBoarding/splashScreen1.dart';
import '../../../Utils/Common/comonGlassmorphicContainer.dart';
import '../../../model/SmallCaseModel/broker_account_model.dart';
import '../../../view_model/SmallCaseApi/smallcase_api_methods.dart';
class Portfolio extends StatefulWidget {
const Portfolio({super.key});
@override
State<Portfolio> createState() => _PortfolioState();
}
class _PortfolioState extends State<Portfolio> {
final GlobalKey<ScaffoldState> _scaffoldKey1 = GlobalKey<ScaffoldState>();
List<String> containerTexts = ["Swing Trade", "Multibagger", "Options"];
final selectedIndex = 0.obs;
RxBool noBrokerAvailable = true.obs;
FutureGroup fetchUserIdAndBrokerAccounts = FutureGroup();
List<Data> myBrokerAccounts = [];
@override
void initState() {
fetchUserIdAndBrokerAccounts.add(fetchBrokerAccounts());
fetchUserIdAndBrokerAccounts.close();
fetchUserIdAndBrokerAccounts.future.then((value) {
log(value.toString());
try {
myBrokerAccounts = value[0] as List<Data>;
} catch (e) {}
debugPrint("myBrokerAccounts.length ${myBrokerAccounts.length}");
if (myBrokerAccounts.isEmpty) {
noBrokerAvailable.value = true;
} else {
noBrokerAvailable.value = false;
}
});
super.initState();
}
Widget holdings() {
return Obx(() {
WidgetsBinding.instance.addPostFrameCallback((_) {
if (selectedIndex.value == 1) _unlockbottomsheet();
});
return selectedIndex.value == 0
? Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
sizedBoxHeight(25.h),
GestureDetector(
onTap: () {
log(myBrokerAccounts[selectedIndex.value].brokerName!);
ScgatewayFlutterPlugin.setConfigEnvironment(
GatewayEnvironment.PRODUCTION,
'traderscircuit',
false,
["upstox"],
);
fetchHoldingsImportTxnId(myBrokerAccounts
.elementAt(selectedIndex.value)
.authToken!)
.then((txnIdResponse) {
if (txnIdResponse != "Failed") {
fetchHoldingsImportTxnId(myBrokerAccounts
.elementAt(selectedIndex.value)
.authToken!)
.then((txnIdResponse) {
debugPrint('SESSION STARTED');
debugPrint(
'AUTH TOKEN: ${myBrokerAccounts.elementAt(selectedIndex.value).authToken!}');
String txnId = txnIdResponse;
debugPrint('TXN ID $txnId');
ScgatewayFlutterPlugin.triggerGatewayTransaction(
txnId)
.then(
(txnRes) {
debugPrint('TXN RES $txnRes');
if (txnRes != null) {
fetchHoldings(
//holdingsAuthToken
myBrokerAccounts
.elementAt(selectedIndex.value)
.authToken!)
.then(
(holdings) {
setState(() {});
},
);
}
},
);
});
} else {
debugPrint('SESSION EXPIRED');
onTxnTimeout();
}
});
},
child: Align(
alignment: Alignment.centerRight,
child: Container(
width: 180,
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
color: const Color(0xff6C0000),
),
child: Center(child: text15W600("Update Stock's")),
),
),
),
sizedBoxHeight(25.h),
Table(
children: [
TableRow(
children: [
TableCell(
child: Text(
"Stock Name",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16.sp,
color: Colors.white,
fontWeight: FontWeight.w500,
fontFamily: 'hiragino'),
),
),
TableCell(
child: Text(
"AVG Price",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16.sp,
color: Colors.white,
fontWeight: FontWeight.w500,
fontFamily: 'hiragino'),
),
),
TableCell(
child: Text(
"Quantity",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16.sp,
color: Colors.white,
fontWeight: FontWeight.w500,
fontFamily: 'hiragino'),
),
),
],
),
],
),
const Divider(
color: Color(0xFF3A3A3A),
),
Expanded(
child: ListView.separated(
physics: const BouncingScrollPhysics(),
shrinkWrap: true,
itemCount: 16,
itemBuilder: ((context, index) {
return Table(
children: [
TableRow(
children: [
TableCell(
child: Text(
"TATA MOTORS",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16.sp,
color: Colors.white,
fontWeight: FontWeight.w500,
fontFamily: 'hiragino'),
),
),
TableCell(
child: Text(
"416.66",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16.sp,
color: Colors.white,
fontWeight: FontWeight.w500,
fontFamily: 'hiragino'),
),
),
TableCell(
child: Text(
"3",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16.sp,
color: Colors.white,
fontWeight: FontWeight.w500,
fontFamily: 'hiragino'),
),
),
],
),
],
);
}),
separatorBuilder: (BuildContext context, int index) {
return const Divider();
},
),
),
SizedBox(
height: 30.h,
)
],
)
: selectedIndex == 1
? const Column(
children: [],
)
: const Column(
children: [],
);
});
}
void onTxnTimeout() {
bool showDialogContent = true;
bool replaceDialogContentWithLoader = false;
showDialog(
barrierDismissible: false,
context: context,
builder: (context) => AlertDialog(content: StatefulBuilder(
builder: (context, setDialogState) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Visibility(
visible: showDialogContent,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text("Transaction Timeout",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
)),
const SizedBox(height: 18),
const Text("You need to login again to continue"),
const SizedBox(height: 18),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
OutlinedButton(
onPressed: () {
Get.back();
},
child: const Text("Cancel"),
),
const SizedBox(width: 12),
ElevatedButton(
onPressed: () {
setDialogState(() {
showDialogContent = false;
replaceDialogContentWithLoader = true;
});
//login again
fetchAuthToken().then((fetchedAuthToken) {
debugPrint(
"fetchedAuthToken $fetchedAuthToken");
fetchBrokerConnectTxnId(
authToken: fetchedAuthToken)
.then(
(txnId) =>
ScgatewayFlutterPlugin.initGateway(
fetchedAuthToken,
).then(
(value) => ScgatewayFlutterPlugin
.triggerGatewayTransaction(
txnId,
).then(
(loginRes) {
if (loginRes != null) {
var data =
jsonDecode(loginRes)['data'];
if (data != null) {
String authToken = jsonDecode(
data)['smallcaseAuthToken'];
String brokerName =
jsonDecode(data)['broker'];
String txnId = jsonDecode(
data)['transactionId'];
postBrokerAccount(
brokerName: brokerName,
authToken: authToken,
txnId: txnId)
.then((isPosted) {
if (isPosted) {
Get.back();
}
});
}
}
},
),
),
);
});
},
child: const Text("Login Again"),
),
],
)
],
),
),
Visibility(
visible: replaceDialogContentWithLoader,
child: const Padding(
padding: EdgeInsets.symmetric(vertical: 28.0),
child: Center(
child: CircularProgressIndicator(),
),
),
)
],
);
},
)));
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
_onBackButtonPressed(context);
return true; // Return true to allow the pop action
},
child: Scaffold(
key: _scaffoldKey1,
backgroundColor: Colors.black,
drawerEnableOpenDragGesture: false,
drawer: const SideMenu(),
extendBody: true,
appBar: AppBar(
scrolledUnderElevation: 0.0,
backgroundColor: Colors.black,
elevation: 0,
automaticallyImplyLeading: false,
titleSpacing: 0,
leading: InkWell(
onTap: () {
_scaffoldKey1.currentState?.openDrawer();
},
child: Center(
child: Image.asset(
'assets/images/png/menu.png',
height: 15.h,
width: 20.w,
),
),
),
),
body: Obx(
() => Stack(
children: [
const CommonBlurLeft(),
const CommonBlurRight(),
!noBrokerAvailable.value
? Stack(
children: [
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 16, vertical: 16),
child: ListView(
physics: const NeverScrollableScrollPhysics(),
children: [
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
text25W600("My Portfolio"),
GestureDetector(
onTap: () {
ScgatewayFlutterPlugin
.setConfigEnvironment(
GatewayEnvironment.PRODUCTION,
'traderscircuit',
false,
[],
);
fetchAuthToken().then((fetchedAuthToken) {
debugPrint(
"fetchedAuthToken $fetchedAuthToken");
fetchBrokerConnectTxnId(
authToken: fetchedAuthToken)
.then(
(txnId) => ScgatewayFlutterPlugin
.initGateway(fetchedAuthToken)
.then(
(value) => ScgatewayFlutterPlugin
.triggerGatewayTransaction(
txnId,
).then(
(loginRes) {
log(loginRes.toString());
if (loginRes != null) {
var data = jsonDecode(
loginRes)['data'];
if (data != null) {
String authToken =
jsonDecode(data)[
'smallcaseAuthToken'];
String brokerName =
jsonDecode(
data)['broker'];
String txnId = jsonDecode(
data)['transactionId'];
postBrokerAccount(
brokerName:
brokerName,
authToken:
authToken,
txnId: txnId)
.then((isPosted) {
ScaffoldMessenger.of(
context)
.clearSnackBars();
ScaffoldMessenger.of(
context)
.showSnackBar(
const SnackBar(
content: Text(
'New broker account is added')));
});
}
}
},
),
),
);
});
setState(() {});
},
child: Container(
width: 80,
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
color: const Color(0xff6C0000),
),
child: Center(child: text15W600("ADD")),
),
),
],
),
const SizedBox(
height: 10,
),
DefaultTabController(
length: myBrokerAccounts.length,
// initialIndex: selectedIndex.value,
child: Column(
children: [
PortfolioTabBar(
portfolioLength: myBrokerAccounts.length,
portoflioName: myBrokerAccounts,
),
SizedBox(
height: 30.h,
),
SizedBox(
height: 570.h,
child: TabBarView(
children: List.generate(
myBrokerAccounts.length, (count) {
return DefaultTabController(
length: 2,
child: Column(
children: [
const HoldingsTabBar(),
Expanded(
child: TabBarView(
children: [
holdings(),
PortfolioReview(),
],
),
),
],
),
);
}),
),
),
],
),
),
sizedBoxHeight(40.h),
],
),
),
],
)
: Stack(
children: [
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 16, vertical: 16),
child: Column(
children: [
Row(
children: [
text25W600("My Portfolio"),
],
),
SizedBox(
height: 30.h,
),
Text(
'Please click the "Add" button below to add a portfolio.',
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: 'hiragino',
color: Colors.white,
fontSize: 16.sp,
fontWeight: FontWeight.w400,
),
),
const Spacer(),
LottieBuilder.asset(
"assets/images/png/TAdlX7YnR7 (1).json",
width: 200.w,
height: 200.h,
),
const Spacer(),
CommonBtn(
text: "Add",
onTap: () {
fetchAuthToken().then((fetchedAuthToken) {
debugPrint(
"fetchedAuthToken $fetchedAuthToken");
fetchBrokerConnectTxnId(
authToken: fetchedAuthToken)
.then(
(txnId) =>
ScgatewayFlutterPlugin.initGateway(
fetchedAuthToken)
.then(
(value) => ScgatewayFlutterPlugin
.triggerGatewayTransaction(
txnId,
).then(
(loginRes) {
log(loginRes.toString());
if (loginRes != null) {
var data = jsonDecode(
loginRes)['data'];
if (data != null) {
String authToken =
jsonDecode(data)[
'smallcaseAuthToken'];
String brokerName =
jsonDecode(
data)['broker'];
String txnId = jsonDecode(
data)['transactionId'];
postBrokerAccount(
brokerName:
brokerName,
authToken: authToken,
txnId: txnId)
.then((isPosted) {
ScaffoldMessenger.of(
context)
.clearSnackBars();
ScaffoldMessenger.of(
context)
.showSnackBar(
const SnackBar(
content: Text(
'New broker account is added')));
fetchUserIdAndBrokerAccounts
.add(
fetchBrokerAccounts());
fetchUserIdAndBrokerAccounts
.close();
fetchUserIdAndBrokerAccounts
.future
.then((value) {
log(value.toString());
try {
myBrokerAccounts =
value[0]
as List<Data>;
} catch (e) {}
debugPrint(
"myBrokerAccounts.length ${myBrokerAccounts.length}");
if (myBrokerAccounts
.isEmpty) {
noBrokerAvailable
.value = true;
} else {
noBrokerAvailable
.value = false;
}
});
setState(() {});
});
}
}
},
),
),
);
});
}),
const Spacer(),
],
),
),
],
)
],
),
),
bottomNavigationBar: bottomnavigationbar(mainController),
),
);
}
Widget topContainer(String text, int index) {
return Obx(() {
return selectedIndex.value == index
? Container(
height: 40.h,
width: 126.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: const Color(0Xff6C0000),
),
child: Center(child: text16W500(text)),
)
: commonGlassContainer(
width: 126.w,
height: 40.h,
borderradius: 5,
customWidget: Center(child: text16W400(text)),
);
});
}
void _unlockbottomsheet() {
Get.bottomSheet(
SizedBox(
height: 200,
child: commonGlassContainer(
width: double.infinity,
height: 200,
borderradius: 2,
customWidget: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Image.asset(
// 'assets/images/png/Group 1000003722.png',
// height: 100.h,
// ),
// sizedBoxHeight(25.h),
text20W400('Please subscribed to unlock'),
sizedBoxHeight(30.h),
CommonBtn(text: 'Subscribe Now'),
],
),
),
),
backgroundColor: Colors.black.withOpacity(0.3),
);
}
Widget PortfolioReview() {
List<Map<String, String>> cardSwing = [
{
'text': 'Performance Overview:',
'content':
'Your portfolio has generated a total return of 15% over the past six months, outperforming the S&P 500 index by 5%.',
},
{
'text': 'Asset Allocation:',
'content':
'Your portfolio is well-diversified, with 60% allocated to equities, 30% to bonds, and 10% to cash equivalents.',
},
{
'text': 'Individual Holdings Analysis:',
'content':
'Your investment in Company XYZ has performed exceptionally well, with a 25% increase in share price since purchase, driven by strong quarterly earnings.',
},
];
return SingleChildScrollView(
child: Column(
children: [
sizedBoxHeight(20.h),
Obx(() {
return selectedIndex.value == 0
? Column(
children: List.generate(cardSwing.length, (index) {
return Column(
children: [
PortfolioCard(
text: cardSwing[index]['text']!,
content: cardSwing[index]['content']!,
),
sizedBoxHeight(20.h)
],
);
}),
)
: selectedIndex.value == 1
? Column(
children: List.generate(cardSwing.length, (index) {
return Column(
children: [
PortfolioCard(
text: cardSwing[index]['text']!,
content: cardSwing[index]['content']!,
),
sizedBoxHeight(20.h)
],
);
}),
)
: Column(
children: List.generate(cardSwing.length, (index) {
return Column(
children: [
PortfolioCard(
text: cardSwing[index]['text']!,
content: cardSwing[index]['content']!,
),
sizedBoxHeight(20.h)
],
);
}),
);
}),
sizedBoxHeight(200.h)
],
),
);
}
Widget PortfolioCard({
required String text,
required String content,
}) {
return commonGlassContainer(
width: double.infinity,
height: 166.h,
borderradius: 8,
customWidget: Column(
children: [
Padding(
padding: EdgeInsets.symmetric(vertical: 16.h, horizontal: 16.w),
child: Row(
children: [
Container(
decoration: BoxDecoration(
color: const Color(0xFF6C0000),
borderRadius: BorderRadius.circular(2),
),
height: 25.h,
width: 4.w,
),
sizedBoxWidth(15.w),
text18W600(text),
const Spacer(),
],
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 18),
child: text16W400(content),
)
],
),
);
}
Widget HoldingCard({
required String text,
required String content,
}) {
return commonGlassContainer(
width: double.infinity,
height: 166.h,
borderradius: 8,
customWidget: Column(
children: [
Padding(
padding: EdgeInsets.symmetric(vertical: 16.h, horizontal: 16.w),
child: Row(
children: [
GlassmorphicContainer(
width: 47.w,
height: 47.h,
borderRadius: 100,
blur: 10,
alignment: Alignment.center,
border: 0.9,
linearGradient: const LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color(0xff3A3A3A),
Color(0xFF3A3A3A),
],
),
borderGradient: const LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color.fromRGBO(70, 5, 1, 0.8),
Color.fromRGBO(102, 102, 102, 0.8),
],
),
child: Center(
child: Image.asset(
'assets/images/png/TATAMOTORS.NS_BIG 1.png',
width: 26.w,
height: 23.h,
),
),
),
sizedBoxWidth(15.w),
text18W600(text),
const Spacer(),
],
),
),
Container(
width: double.infinity,
height: 1.h,
color: const Color(0xFF3A3A3A),
),
Padding(
padding: const EdgeInsets.all(18),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
text14W400_979797('Portfolio Value'),
sizedBoxHeight(5.h),
SizedBox(width: 150.w, child: text15W600("₹ 40,000"))
],
),
sizedBoxWidth(30.w),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
text14W400_979797('%P/L'),
sizedBoxHeight(5.h),
text14W400_00FF19("-36.006%")
],
)
],
),
],
),
)
],
),
);
}
Future<bool> _onBackButtonPressed(BuildContext context) async {
bool? exitApp = await showDialog(
context: context,
builder: (context) {
return AlertDialog(
backgroundColor: const Color(0xFFFFF3E4),
title: const Text('Exit App'),
content: const Text('Do you really want to close the app?'),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop(false);
},
child: const Text(
'No',
style: TextStyle(
color: Color(0xff1B243D),
),
),
),
TextButton(
onPressed: () {
SystemNavigator.pop();
Navigator.pop(context);
},
child: const Text(
'Yes',
style: TextStyle(
color: Color(0xff1B243D),
),
),
)
],
);
});
return exitApp ?? false;
}
}
class HoldingsTabBar extends StatelessWidget {
const HoldingsTabBar({super.key});
// Set the desired height
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
border: Border.all(color: const Color(0Xff3A3A3A)),
borderRadius: BorderRadius.circular(8.r),
),
padding: const EdgeInsets.all(8.0), // Set the desired padding
child: TabBar(
indicator: BoxDecoration(
color: const Color(0xff6C0000),
borderRadius: BorderRadius.circular(5),
),
dividerColor: Colors.transparent,
labelStyle: TextStyle(
fontSize: 16.sp,
color: Colors.white,
fontWeight: FontWeight.w500,
fontFamily: 'hiragino'),
indicatorSize: TabBarIndicatorSize.tab,
indicatorColor: const Color(0xFFFFFFFF),
labelColor: Colors.white,
unselectedLabelColor: const Color(0xffFFFFFF),
overlayColor: MaterialStateProperty.all(const Color(0xFFFFFFFF)),
tabs: const [
Tab(
text: 'Holdings',
),
Tab(
text: 'Portfolio Reviews',
),
]),
);
}
}
class PortfolioTabBar extends StatelessWidget {
final int portfolioLength;
final List<Data> portoflioName;
const PortfolioTabBar({
super.key,
required this.portfolioLength,
required this.portoflioName,
});
// Set the desired height
@override
Widget build(BuildContext context) {
return TabBar(
tabAlignment: TabAlignment.start,
isScrollable: true,
dividerColor: Colors.transparent,
labelStyle: TextStyle(
fontSize: 18.sp,
color: Colors.white,
fontWeight: FontWeight.w500,
fontFamily: 'hiragino'),
indicatorSize: TabBarIndicatorSize.tab,
indicatorWeight: 2,
indicatorColor: const Color(0xff6C0000),
labelColor: Colors.white,
unselectedLabelColor: const Color(0xFF464646),
overlayColor: MaterialStateProperty.all(const Color(0xFFFFFFFF)),
tabs: List.generate(portfolioLength, (counter) {
return Tab(
text: portoflioName[counter].brokerName,
);
}));
}
}