invest screen ui
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
import 'package:bloc/bloc.dart';
|
||||
|
||||
import 'tab_event.dart';
|
||||
import 'tab_state.dart';
|
||||
|
||||
class TabBloc extends Bloc<TabEvent, TabState> {
|
||||
TabBloc() : super(const TabState()) {
|
||||
on<LoadAvailableItems>(_onLoadAvailableItems);
|
||||
on<LoadClosedItems>(_onLoadClosedItems);
|
||||
}
|
||||
|
||||
void _onLoadAvailableItems(LoadAvailableItems event, Emitter<TabState> emit) {
|
||||
// Simulate fetching available items
|
||||
final availableItems =
|
||||
List<String>.generate(10, (index) => 'Available Item $index');
|
||||
emit(state.copyWith(availableItems: availableItems));
|
||||
}
|
||||
|
||||
void _onLoadClosedItems(LoadClosedItems event, Emitter<TabState> emit) {
|
||||
// Simulate fetching closed items
|
||||
final closedItems =
|
||||
List<String>.generate(10, (index) => 'Closed Item $index');
|
||||
emit(state.copyWith(closedItems: closedItems));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
abstract class TabEvent extends Equatable {
|
||||
const TabEvent();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class LoadAvailableItems extends TabEvent {}
|
||||
|
||||
class LoadClosedItems extends TabEvent {}
|
||||
@@ -0,0 +1,24 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
class TabState extends Equatable {
|
||||
final List<String> availableItems;
|
||||
final List<String> closedItems;
|
||||
|
||||
const TabState({
|
||||
this.availableItems = const [],
|
||||
this.closedItems = const [],
|
||||
});
|
||||
|
||||
TabState copyWith({
|
||||
List<String>? availableItems,
|
||||
List<String>? closedItems,
|
||||
}) {
|
||||
return TabState(
|
||||
availableItems: availableItems ?? this.availableItems,
|
||||
closedItems: closedItems ?? this.closedItems,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object> get props => [availableItems, closedItems];
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class InvestScreen extends StatefulWidget {
|
||||
const InvestScreen({super.key});
|
||||
|
||||
@override
|
||||
State<InvestScreen> createState() => _InvestScreenState();
|
||||
}
|
||||
|
||||
class _InvestScreenState extends State<InvestScreen> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Scaffold(
|
||||
body: Text('Invest'),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
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/features/MainScreens/Invest/presentation/pages/invest_video_section.dart';
|
||||
import 'package:tanami_app/features/MainScreens/Invest/presentation/widgets/invest_details_section.dart';
|
||||
|
||||
import '../widgets/invest_image_carousel.dart';
|
||||
import '../widgets/invest_included_documents_section.dart';
|
||||
import '../widgets/key_investment_section.dart';
|
||||
|
||||
class InvestDetailsLayout extends StatelessWidget {
|
||||
const InvestDetailsLayout({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 20.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.plainWhite,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(20.0)),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppColor.plainBlack.withOpacity(0.15),
|
||||
spreadRadius: 2,
|
||||
blurRadius: 10,
|
||||
offset: const Offset(0, 3),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
InvestCarouselView(),
|
||||
const InvestDetailsSection(),
|
||||
],
|
||||
),
|
||||
),
|
||||
Gap(
|
||||
20.h,
|
||||
),
|
||||
const KeyInvestmentSection(),
|
||||
Gap(
|
||||
20.h,
|
||||
),
|
||||
const InvestIncludedDocumentsSection(),
|
||||
Gap(
|
||||
20.h,
|
||||
),
|
||||
const InvestVideoSection(),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.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';
|
||||
|
||||
class InvestDetailsScreen extends StatelessWidget {
|
||||
const InvestDetailsScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
bottomNavigationBar: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 18, vertical: 26),
|
||||
width: 1.sw,
|
||||
height: 105.h,
|
||||
child: ButtonWidget().elevatedBtn(
|
||||
text: AppText.investText,
|
||||
clr: AppColor.primaryColor2,
|
||||
function: () {}),
|
||||
),
|
||||
appBar: const AppBarWidget(
|
||||
height: 45,
|
||||
titleTxt: "",
|
||||
),
|
||||
body: MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider(
|
||||
// Create an instance of the OnboardingBloc
|
||||
create: (context) => CarouselBloc(),
|
||||
),
|
||||
],
|
||||
child: const InvestDetailsLayout(),
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:google_fonts/google_fonts.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/features/MainScreens/Invest/presentation/widgets/kyc_card.dart';
|
||||
|
||||
import '../bloc/tab_bloc.dart';
|
||||
import '../bloc/tab_event.dart';
|
||||
import '../bloc/tab_state.dart';
|
||||
import '../widgets/invest_details_section.dart';
|
||||
import '../widgets/invest_image_carousel.dart';
|
||||
|
||||
class InvestLayout extends StatelessWidget {
|
||||
const InvestLayout({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DefaultTabController(
|
||||
length: 2,
|
||||
child: Scaffold(
|
||||
body: Column(
|
||||
children: [
|
||||
TabBar(
|
||||
tabs: const [
|
||||
Tab(text: AppText.availableText),
|
||||
Tab(text: AppText.closedText),
|
||||
],
|
||||
labelStyle: GoogleFonts.dmSans(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 14.0,
|
||||
),
|
||||
unselectedLabelStyle: GoogleFonts.dmSans(
|
||||
fontWeight: FontWeight.normal,
|
||||
fontSize: 14.0,
|
||||
),
|
||||
labelColor: AppColor.plainBlack,
|
||||
unselectedLabelColor: AppColor.charcoalColor,
|
||||
indicatorColor: AppColor.plainBlack,
|
||||
indicatorSize: TabBarIndicatorSize.tab,
|
||||
indicatorWeight: 1.0,
|
||||
indicatorPadding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
),
|
||||
const Expanded(
|
||||
child: TabBarView(
|
||||
children: [
|
||||
AvailableItemsScreen(),
|
||||
ClosedItemsScreen(),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class AvailableItemsScreen extends StatelessWidget {
|
||||
const AvailableItemsScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
context.read<TabBloc>().add(LoadAvailableItems());
|
||||
|
||||
return BlocBuilder<TabBloc, TabState>(
|
||||
builder: (context, state) {
|
||||
if (state.availableItems.isEmpty) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
return ListView.builder(
|
||||
itemCount: state.availableItems.length,
|
||||
itemBuilder: (context, index) {
|
||||
return index == 0
|
||||
? Container(
|
||||
margin: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 18,
|
||||
),
|
||||
child: kycCard())
|
||||
: InkWell(
|
||||
onTap: () {
|
||||
goRouter.pushNamed(RouteName.investDetailScreen);
|
||||
},
|
||||
child: Container(
|
||||
margin: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 18,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.plainWhite,
|
||||
borderRadius:
|
||||
const BorderRadius.all(Radius.circular(20.0)),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppColor.plainBlack.withOpacity(0.15),
|
||||
spreadRadius: 2,
|
||||
blurRadius: 10,
|
||||
offset: const Offset(0, 3),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
InvestCarouselView(),
|
||||
const InvestDetailsSection(),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ClosedItemsScreen extends StatelessWidget {
|
||||
const ClosedItemsScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
context.read<TabBloc>().add(LoadClosedItems());
|
||||
|
||||
return BlocBuilder<TabBloc, TabState>(
|
||||
builder: (context, state) {
|
||||
if (state.closedItems.isEmpty) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
return ListView.builder(
|
||||
itemCount: state.closedItems.length,
|
||||
itemBuilder: (context, index) {
|
||||
return index == 0
|
||||
? Container(
|
||||
margin: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 18,
|
||||
),
|
||||
child: kycCard())
|
||||
: InkWell(
|
||||
onTap: () {
|
||||
goRouter.pushNamed(RouteName.investDetailScreen);
|
||||
},
|
||||
child: Container(
|
||||
margin: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 18,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.plainWhite,
|
||||
borderRadius:
|
||||
const BorderRadius.all(Radius.circular(20.0)),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppColor.plainBlack.withOpacity(0.15),
|
||||
spreadRadius: 2,
|
||||
blurRadius: 10,
|
||||
offset: const Offset(0, 3),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
InvestCarouselView(),
|
||||
const InvestDetailsSection(),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:tanami_app/features/MainScreens/Invest/presentation/bloc/tab_bloc.dart';
|
||||
import 'package:tanami_app/features/MainScreens/Portfolio/presentation/bloc/carousel/carousel_bloc.dart';
|
||||
|
||||
import '../../../../../core/styles/app_color.dart';
|
||||
import '../../../../../core/styles/app_text.dart';
|
||||
import '../../../../../shared/components/text_widget.dart';
|
||||
import 'invest_layout.dart';
|
||||
|
||||
class InvestScreen extends StatefulWidget {
|
||||
const InvestScreen({super.key});
|
||||
|
||||
@override
|
||||
State<InvestScreen> createState() => _InvestScreenState();
|
||||
}
|
||||
|
||||
class _InvestScreenState extends State<InvestScreen> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
// backgroundColor: Colors.white,
|
||||
elevation: 0,
|
||||
scrolledUnderElevation: 0,
|
||||
automaticallyImplyLeading: false,
|
||||
title: TextWidget().text22W700(
|
||||
AppText.investText,
|
||||
clr: AppColor.charcoalColor,
|
||||
),
|
||||
titleSpacing: 16,
|
||||
),
|
||||
body: MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider(
|
||||
// Create an instance of the OnboardingBloc
|
||||
create: (context) => TabBloc(),
|
||||
),
|
||||
BlocProvider(
|
||||
// Create an instance of the OnboardingBloc
|
||||
create: (context) => CarouselBloc(),
|
||||
),
|
||||
],
|
||||
child: const InvestLayout(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:tanami_app/core/styles/app_images.dart';
|
||||
|
||||
import '../../../../../core/styles/app_text.dart';
|
||||
|
||||
class InvestVideoSection extends StatelessWidget {
|
||||
const InvestVideoSection({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(20.0)),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.15),
|
||||
spreadRadius: 2,
|
||||
blurRadius: 10,
|
||||
offset: const Offset(0, 3), // changes position of shadow
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 20.0, horizontal: 16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
AppText.videosTitle,
|
||||
style: GoogleFonts.dmSans(
|
||||
color: Colors.black,
|
||||
fontSize: 15.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 12.h,
|
||||
),
|
||||
ListView.builder(
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
shrinkWrap: true,
|
||||
itemCount: videos.length,
|
||||
itemBuilder: (context, index) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 18.0),
|
||||
child: ClipRRect(
|
||||
borderRadius: const BorderRadius.all(
|
||||
Radius.circular(18.0),
|
||||
),
|
||||
child: Stack(
|
||||
children: [
|
||||
Image.asset(
|
||||
videos[index],
|
||||
fit: BoxFit.cover,
|
||||
height: 160.h,
|
||||
width: 1.sw,
|
||||
),
|
||||
Positioned(
|
||||
bottom: 0.0,
|
||||
child: Image.asset(
|
||||
AppImages.academyCardOverlay,
|
||||
),
|
||||
),
|
||||
Positioned.fill(
|
||||
child: Image.asset(
|
||||
AppImages.videoPlayIcon,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
List videos = [
|
||||
'assets/images/academy_screen/vd_bg.jpg',
|
||||
'assets/images/academy_screen/vd_bg.jpg',
|
||||
'assets/images/academy_screen/vd_bg.jpg'
|
||||
];
|
||||
@@ -0,0 +1,155 @@
|
||||
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 '../../../../../core/styles/app_text.dart';
|
||||
import '../../../../../shared/components/text_widget.dart';
|
||||
|
||||
class InvestDetailsSection extends StatelessWidget {
|
||||
const InvestDetailsSection({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
Container(
|
||||
color: AppColor.plainWhite,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(20.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
TextWidget().text17W700(
|
||||
'Multi Family Residental',
|
||||
clr: AppColor.plainBlack,
|
||||
),
|
||||
Gap(
|
||||
10.h,
|
||||
),
|
||||
TextWidget()
|
||||
.text22W400("SAR 1,478,000", clr: AppColor.investTextColor),
|
||||
const Gap(8.0),
|
||||
LinearProgressIndicator(
|
||||
value: 0.6,
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
minHeight: 8.0,
|
||||
backgroundColor: AppColor.txtBorderColor,
|
||||
valueColor: const AlwaysStoppedAnimation<Color>(
|
||||
AppColor.investTextColor),
|
||||
),
|
||||
const Gap(8.0),
|
||||
TextWidget().text11W700("60% ${AppText.fundedText}",
|
||||
clr: AppColor.portoflioCardTextColor),
|
||||
const Gap(8.0),
|
||||
TextWidget().text14W400(
|
||||
'Forem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vulputate libero et velit interdum, ac aliquet odio mattis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur tempus urna at turpis condimentum lobortis.',
|
||||
clr: Colors.grey,
|
||||
txtAlign: TextAlign.start,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
decoration: const BoxDecoration(
|
||||
color: AppColor.portfolioCardBgColor,
|
||||
borderRadius: BorderRadius.only(
|
||||
bottomLeft: Radius.circular(20.0),
|
||||
bottomRight: Radius.circular(20.0),
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 20.0, vertical: 16.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 150.w,
|
||||
child: TextWidget().text14W500(
|
||||
"${AppText.sponsorNameText}:",
|
||||
clr: AppColor.portoflioCardTextColor,
|
||||
txtAlign: TextAlign.start,
|
||||
),
|
||||
),
|
||||
TextWidget().text14W700(
|
||||
'Silverlake',
|
||||
clr: AppColor.plainBlack,
|
||||
txtAlign: TextAlign.end,
|
||||
)
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 8.h,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 150.w,
|
||||
child: TextWidget().text14W500(
|
||||
"${AppText.estimatedReturnText}:",
|
||||
clr: AppColor.portoflioCardTextColor,
|
||||
txtAlign: TextAlign.start,
|
||||
),
|
||||
),
|
||||
TextWidget().text14W700(
|
||||
'20.0%',
|
||||
clr: AppColor.plainBlack,
|
||||
txtAlign: TextAlign.end,
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 8.h,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 150.w,
|
||||
child: TextWidget().text14W500(
|
||||
"${AppText.holdingPeriodText}:",
|
||||
clr: AppColor.portoflioCardTextColor,
|
||||
txtAlign: TextAlign.start,
|
||||
),
|
||||
),
|
||||
TextWidget().text14W700(
|
||||
'24 Months',
|
||||
clr: AppColor.plainBlack,
|
||||
txtAlign: TextAlign.end,
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 8.h,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
TextWidget().text14W500(
|
||||
"${AppText.minimumInvestmentText}:",
|
||||
clr: AppColor.portoflioCardTextColor,
|
||||
txtAlign: TextAlign.start,
|
||||
),
|
||||
TextWidget().text14W700(
|
||||
'SAR 1,000',
|
||||
clr: AppColor.plainBlack,
|
||||
txtAlign: TextAlign.end,
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:carousel_slider/carousel_slider.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 '../../../Portfolio/presentation/bloc/carousel/carousel_bloc.dart';
|
||||
import '../../../Portfolio/presentation/bloc/carousel/carousel_event.dart';
|
||||
import '../../../Portfolio/presentation/bloc/carousel/carousel_state.dart';
|
||||
|
||||
final List imgList = [
|
||||
{'id': 1, 'img_path': 'assets/images/portfolio_screen/detailsbg.png'},
|
||||
{'id': 2, 'img_path': 'assets/images/portfolio_screen/detailsbg.png'},
|
||||
{'id': 3, 'img_path': 'assets/images/portfolio_screen/detailsbg.png'},
|
||||
{'id': 4, 'img_path': 'assets/images/portfolio_screen/detailsbg.png'},
|
||||
{'id': 5, 'img_path': 'assets/images/portfolio_screen/detailsbg.png'},
|
||||
];
|
||||
|
||||
class InvestCarouselView extends StatelessWidget {
|
||||
final CarouselController _controller = CarouselController();
|
||||
|
||||
InvestCarouselView({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
height: 190.h,
|
||||
decoration: const BoxDecoration(
|
||||
color: AppColor.portfolioCardBgColor,
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(20.0),
|
||||
topRight: Radius.circular(20.0),
|
||||
),
|
||||
),
|
||||
child: Stack(
|
||||
children: [
|
||||
ClipRRect(
|
||||
borderRadius: const BorderRadius.only(
|
||||
topLeft: Radius.circular(20.0),
|
||||
topRight: Radius.circular(20.0),
|
||||
),
|
||||
child: CarouselSlider(
|
||||
items: imgList
|
||||
.map(
|
||||
(item) => Image.asset(
|
||||
item['img_path'],
|
||||
fit: BoxFit.cover,
|
||||
width: double.infinity,
|
||||
alignment: Alignment.topCenter,
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
carouselController: _controller,
|
||||
options: CarouselOptions(
|
||||
scrollPhysics: const BouncingScrollPhysics(),
|
||||
autoPlay: true,
|
||||
aspectRatio: 2,
|
||||
viewportFraction: 1,
|
||||
onPageChanged: (index, reason) {
|
||||
context.read<CarouselBloc>().add(PageChanged(index));
|
||||
}),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(bottom: 17.0),
|
||||
child: BlocBuilder<CarouselBloc, CarouselState>(
|
||||
builder: (context, state) {
|
||||
int currentIndex = 0;
|
||||
if (state is CarouselPageState) {
|
||||
currentIndex = state.currentIndex;
|
||||
}
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: imgList.asMap().entries.map((entry) {
|
||||
return GestureDetector(
|
||||
onTap: () => _controller.animateToPage(entry.key),
|
||||
child: Container(
|
||||
width: 20.w,
|
||||
height: 7.h,
|
||||
margin: const EdgeInsets.symmetric(horizontal: 3.0),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: (currentIndex == entry.key)
|
||||
? AppColor.plainWhite
|
||||
: AppColor.smokeGrayColor,
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
top: 20,
|
||||
left: 20,
|
||||
child: Container(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 15.0, vertical: 10.0),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFE4F5E9),
|
||||
borderRadius: BorderRadius.circular(30.0),
|
||||
),
|
||||
child: TextWidget().text12W700(
|
||||
'Asset Class',
|
||||
clr: AppColor.selectedItemColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
top: 20,
|
||||
right: 20,
|
||||
child: Container(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 15.0, vertical: 10.0),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(30.0),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Image.asset(
|
||||
AppImages.portfolioClock,
|
||||
height: 15.h,
|
||||
),
|
||||
Gap(
|
||||
5.w,
|
||||
),
|
||||
TextWidget().text12W500(
|
||||
'${AppText.closingDateText} Jul 10 2025',
|
||||
clr: AppColor.plainBlack,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
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/shared/components/text_widget.dart';
|
||||
|
||||
import '../../../../../core/styles/app_text.dart';
|
||||
|
||||
class InvestIncludedDocumentsSection extends StatelessWidget {
|
||||
const InvestIncludedDocumentsSection({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.plainWhite,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(20.0)),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppColor.plainBlack.withOpacity(0.15),
|
||||
spreadRadius: 2,
|
||||
blurRadius: 10,
|
||||
offset: const Offset(0, 3), // changes position of shadow
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(20.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
TextWidget().text15W700(
|
||||
AppText.includeddocs,
|
||||
clr: AppColor.plainBlack,
|
||||
),
|
||||
Gap(
|
||||
16.h,
|
||||
),
|
||||
GridView.count(
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
shrinkWrap: true,
|
||||
childAspectRatio: 1.7,
|
||||
mainAxisSpacing: 10.h,
|
||||
crossAxisSpacing: 10.w,
|
||||
crossAxisCount: 2, // Number of columns
|
||||
children: List.generate(
|
||||
6,
|
||||
(index) {
|
||||
return Center(
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
color: AppColor.documentCardBgColor,
|
||||
borderRadius: BorderRadius.all(Radius.circular(10.0)),
|
||||
),
|
||||
padding: const EdgeInsets.all(20.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Image.asset(
|
||||
AppImages.documentIcon,
|
||||
height: 16.sp,
|
||||
),
|
||||
Gap(
|
||||
7.w,
|
||||
),
|
||||
TextWidget().text12W700("Filename.pdf",
|
||||
clr: AppColor.plainBlack),
|
||||
],
|
||||
),
|
||||
Gap(
|
||||
14.h,
|
||||
),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
TextWidget().text12W700("512 Mb",
|
||||
clr: AppColor.portoflioCardTextColor),
|
||||
Gap(
|
||||
7.w,
|
||||
),
|
||||
Image.asset(
|
||||
AppImages.donwloadIcon,
|
||||
height: 20.sp,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:flutter_svg/flutter_svg.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/shared/components/text_widget.dart';
|
||||
|
||||
import '../../../../../core/styles/app_text.dart';
|
||||
|
||||
class KeyInvestmentSection extends StatelessWidget {
|
||||
const KeyInvestmentSection({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.plainWhite,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(20.0)),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppColor.plainBlack.withOpacity(0.15),
|
||||
spreadRadius: 2,
|
||||
blurRadius: 10,
|
||||
offset: const Offset(0, 3), // changes position of shadow
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(20.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
TextWidget().text15W700(
|
||||
AppText.keyMeritsIOfnvestmentText,
|
||||
clr: AppColor.plainBlack,
|
||||
),
|
||||
Gap(
|
||||
16.h,
|
||||
),
|
||||
ListView.builder(
|
||||
itemCount: 4,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
shrinkWrap: true,
|
||||
itemBuilder: (ctx, index) {
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(
|
||||
bottom: 12,
|
||||
),
|
||||
child: investmentSectionCardText(
|
||||
AppImages.timeSquareIcon,
|
||||
"Nunc vulputate libero et velit interdum",
|
||||
"ac aliquet odio mattis.",
|
||||
),
|
||||
);
|
||||
})
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Widget investmentSectionCardText(
|
||||
String icon,
|
||||
String title,
|
||||
String subtitle,
|
||||
) {
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SvgPicture.asset(icon),
|
||||
const Gap(8),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
TextWidget().text14W700(
|
||||
title,
|
||||
clr: AppColor.textLabelColor,
|
||||
txtAlign: TextAlign.start,
|
||||
),
|
||||
TextWidget().text14W400(
|
||||
subtitle,
|
||||
clr: AppColor.textLabelColor,
|
||||
txtAlign: TextAlign.start,
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.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';
|
||||
|
||||
Widget kycCard() {
|
||||
return Container(
|
||||
clipBehavior: Clip.antiAlias,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
decoration: ShapeDecoration(
|
||||
color: AppColor.investKycCardColor,
|
||||
shape: RoundedRectangleBorder(
|
||||
side: const BorderSide(width: 1, color: AppColor.investKycBorderColor),
|
||||
borderRadius: BorderRadius.circular(22),
|
||||
),
|
||||
shadows: const [
|
||||
BoxShadow(
|
||||
color: AppColor.investKycBoxShadow1Color,
|
||||
blurRadius: 4,
|
||||
offset: Offset(0, 1),
|
||||
spreadRadius: 0,
|
||||
),
|
||||
BoxShadow(
|
||||
color: AppColor.investKycBoxShadow2Color,
|
||||
blurRadius: 4,
|
||||
offset: Offset(0, 8),
|
||||
spreadRadius: 0,
|
||||
)
|
||||
],
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
AppImages.investIcon,
|
||||
),
|
||||
const Gap(8),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
TextWidget().text14W600(
|
||||
AppText.completeYourVerification,
|
||||
clr: AppColor.languageTextColor,
|
||||
),
|
||||
TextWidget().text11W500(
|
||||
AppText.verifyYourAccountInUnderMinutesToStartInvestingToday,
|
||||
clr: AppColor.languageTextColor,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:tanami_app/features/MainScreens/Academy/presentation/pages/academy_screen.dart';
|
||||
import 'package:tanami_app/features/MainScreens/Invest/presentation/pages/investScreen.dart';
|
||||
import 'package:tanami_app/features/MainScreens/Invest/presentation/pages/invest_screen.dart';
|
||||
import 'package:tanami_app/features/MainScreens/Portfolio/presentation/pages/portfolio_screen.dart';
|
||||
import 'package:tanami_app/features/MainScreens/Settings/presentation/pages/settings_Screen.dart';
|
||||
import 'package:tanami_app/features/MainScreens/Wallet/presentation/pages/walletScreen.dart';
|
||||
|
||||
Reference in New Issue
Block a user