bottom navigation bar fix, portfolio ui update, academy ui update
This commit is contained in:
BIN
assets/images/academy_screen/play_arrow.png
Normal file
BIN
assets/images/academy_screen/play_arrow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
BIN
assets/images/portfolio_screen/card_bg.png
Normal file
BIN
assets/images/portfolio_screen/card_bg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
@@ -2,8 +2,7 @@
|
||||
|
||||
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/detailsScreen.dart';
|
||||
import 'package:tanami_app/features/MainScreens/MainScreen.dart';
|
||||
import 'package:tanami_app/features/MainScreens/Academy/presentation/pages/academy_details_screen.dart';
|
||||
|
||||
import 'package:tanami_app/features/MainScreens/Portfolio/presentation/pages/portfolio_details_screen.dart';
|
||||
|
||||
@@ -17,6 +16,7 @@ import 'package:tanami_app/features/register/presentation/pages/register_step_sc
|
||||
import 'package:tanami_app/features/securePin/presentation/pages/pin_screen.dart';
|
||||
import 'package:tanami_app/features/welcome/presentation/pages/weclome_screen.dart';
|
||||
|
||||
import '../../features/MainScreens/main_screen.dart';
|
||||
import '../../features/forgotPassword/presentation/pages/restore_password_phone_verification_screen.dart';
|
||||
import '../../features/login/presentation/pages/login_screen.dart';
|
||||
import '../../features/register/presentation/pages/register_user_details_screen.dart';
|
||||
|
||||
@@ -58,4 +58,15 @@ class AppColor {
|
||||
static const Color negativePercentageColor = Color(0xFFde9595);
|
||||
static const Color statusTextColor = Color(0xFF0FA4A4);
|
||||
static const Color portoflioCardTextColor = Color(0xFF535353);
|
||||
static const Color documentCardBgColor = Color(0xFFF4F4F4);
|
||||
static const Color stausBgColor = Color(0xFF59B7B7);
|
||||
|
||||
//bottom navigation bar
|
||||
static const Color selectedItemColor = Color(0xFF0B8933);
|
||||
static const Color unselectedItemColor = Color(0xFF676767);
|
||||
|
||||
//Academy Color
|
||||
|
||||
static const Color academyCardBgColor = Color(0xFFF8F8F8);
|
||||
static const Color academyCardTextColor = Color(0xFFD8D8D8);
|
||||
}
|
||||
|
||||
@@ -63,4 +63,17 @@ class AppImages {
|
||||
'assets/images/portfolio_screen/clock.png';
|
||||
static const String portfolioClockOff =
|
||||
'assets/images/portfolio_screen/clock_off.png';
|
||||
static const String documentIcon =
|
||||
'assets/images/portfolio_screen/document.png';
|
||||
static const String donwloadIcon =
|
||||
'assets/images/portfolio_screen/download.png';
|
||||
static const String portfolioCardBg =
|
||||
'assets/images/portfolio_screen/card_bg.png';
|
||||
|
||||
//Academy
|
||||
static const String academyCardOverlay =
|
||||
'assets/images/academy_screen/dark_overlay.png';
|
||||
static const String videoIcon = 'assets/images/academy_screen/video.png';
|
||||
static const String videoPlayIcon =
|
||||
'assets/images/academy_screen/play_arrow.png';
|
||||
}
|
||||
|
||||
@@ -87,6 +87,7 @@ class AppText {
|
||||
|
||||
//Academy
|
||||
static const String videosTitle = "Videos";
|
||||
static const String academyText = "Academy";
|
||||
|
||||
//Dialog
|
||||
static const String exitText = "Exit";
|
||||
|
||||
@@ -1,239 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.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';
|
||||
|
||||
class AcademyScreen extends StatefulWidget {
|
||||
const AcademyScreen({super.key});
|
||||
|
||||
@override
|
||||
State<AcademyScreen> createState() => _AcademyScreenState();
|
||||
}
|
||||
|
||||
class _AcademyScreenState extends State<AcademyScreen> {
|
||||
List data = [
|
||||
{
|
||||
'img_path': 'assets/images/academy_screen/bg1.jpg',
|
||||
'date': 'July / 10 / 2025',
|
||||
'title': 'Article ',
|
||||
'videos': '3',
|
||||
'desc':
|
||||
'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.'
|
||||
},
|
||||
{
|
||||
'img_path': 'assets/images/academy_screen/bg2.jpg',
|
||||
'date': 'July / 10 / 2025',
|
||||
'title': 'Article ',
|
||||
'videos': '3',
|
||||
'desc':
|
||||
'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.'
|
||||
},
|
||||
{
|
||||
'img_path': 'assets/images/academy_screen/bg3.jpg',
|
||||
'date': 'July / 10 / 2025',
|
||||
'videos': '3',
|
||||
'title': 'Article ',
|
||||
'desc':
|
||||
'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.'
|
||||
},
|
||||
{
|
||||
'img_path': 'assets/images/academy_screen/bg4.jpg',
|
||||
'date': 'July / 10 / 2025',
|
||||
'videos': '3',
|
||||
'title': 'Article ',
|
||||
'desc':
|
||||
'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.',
|
||||
},
|
||||
{
|
||||
'img_path': 'assets/images/academy_screen/bg5.jpg',
|
||||
'date': 'July / 10 / 2025',
|
||||
'videos': '3',
|
||||
'title': 'Article ',
|
||||
'desc':
|
||||
'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.',
|
||||
},
|
||||
{
|
||||
'img_path': 'assets/images/academy_screen/bg4.jpg',
|
||||
'date': 'July / 10 / 2025',
|
||||
'videos': '3',
|
||||
'title': 'Article ',
|
||||
'desc':
|
||||
'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.',
|
||||
},
|
||||
{
|
||||
'img_path': 'assets/images/academy_screen/bg4.jpg',
|
||||
'date': 'July / 10 / 2025',
|
||||
'videos': '3',
|
||||
'title': 'Article ',
|
||||
'desc':
|
||||
'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.',
|
||||
},
|
||||
{
|
||||
'img_path': 'assets/images/academy_screen/bg4.jpg',
|
||||
'date': 'July / 10 / 2025',
|
||||
'videos': '3',
|
||||
'title': 'Article ',
|
||||
'desc':
|
||||
'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.',
|
||||
},
|
||||
];
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.white,
|
||||
elevation: 0,
|
||||
scrolledUnderElevation: 0,
|
||||
automaticallyImplyLeading: false,
|
||||
title: Text(
|
||||
'Academy',
|
||||
style: GoogleFonts.dmSans(
|
||||
color: const Color(0xFF272727),
|
||||
fontSize: 22.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
titleSpacing: 16,
|
||||
),
|
||||
body: ListView.builder(
|
||||
itemCount: data.length,
|
||||
itemBuilder: (context, index) {
|
||||
return Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(vertical: 10.0, horizontal: 16.0),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
goRouter.goNamed(RouteName.academyDetails);
|
||||
},
|
||||
child: Container(
|
||||
height: 140.h,
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.all(Radius.circular(20.0)),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.15),
|
||||
spreadRadius: 2,
|
||||
blurRadius: 10,
|
||||
offset: Offset(0, 3), // changes position of shadow
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
height: 140.h,
|
||||
width: 164.w,
|
||||
decoration: const BoxDecoration(
|
||||
color: Color(0xFFF8F8F8),
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(20.0),
|
||||
),
|
||||
),
|
||||
child: Stack(
|
||||
children: [
|
||||
ClipRRect(
|
||||
borderRadius: const BorderRadius.only(
|
||||
topLeft: Radius.circular(20.0),
|
||||
bottomLeft: Radius.circular(20.0),
|
||||
),
|
||||
child: Image.asset(
|
||||
data[index]['img_path'],
|
||||
fit: BoxFit.cover,
|
||||
height: double.infinity,
|
||||
alignment: Alignment.topCenter,
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 0.0,
|
||||
child: ClipRRect(
|
||||
borderRadius: const BorderRadius.only(
|
||||
bottomLeft: Radius.circular(20.0),
|
||||
),
|
||||
child: Image.asset(
|
||||
'assets/images/academy_screen/dark_overlay.png',
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 8.0, left: 12.0,
|
||||
// alignment: Alignment.bottomLeft,
|
||||
child: Row(
|
||||
children: [
|
||||
Image.asset(
|
||||
'assets/images/academy_screen/video.png',
|
||||
height: 15.sp,
|
||||
),
|
||||
SizedBox(
|
||||
width: 5.w,
|
||||
),
|
||||
Text(
|
||||
'${data[index]['videos']} videos',
|
||||
style: GoogleFonts.dmSans(
|
||||
color: const Color(0xFFD8D8D8),
|
||||
fontSize: 12.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 20.0, horizontal: 16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
data[index]['date'],
|
||||
style: GoogleFonts.dmSans(
|
||||
color: const Color(0xFF8D8D8D),
|
||||
fontSize: 11.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 4.h,
|
||||
),
|
||||
Text(
|
||||
data[index]['title'],
|
||||
style: GoogleFonts.dmSans(
|
||||
color: Colors.black,
|
||||
fontSize: 17.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 12.h,
|
||||
),
|
||||
SizedBox(
|
||||
width: 158.w,
|
||||
child: Text(
|
||||
data[index]['desc'],
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: GoogleFonts.dmSans(
|
||||
color: const Color(0xFF8D8D8D),
|
||||
fontSize: 11.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import '../widgets/academy_detail_section.dart';
|
||||
import '../widgets/academy_video_section.dart';
|
||||
|
||||
class AcademyDetailsLayout extends StatelessWidget {
|
||||
const AcademyDetailsLayout({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 20.0),
|
||||
child: Column(
|
||||
children: [
|
||||
const AcademyDetailSection(),
|
||||
Gap(12.h),
|
||||
const AcademyVideoSection(),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:tanami_app/features/MainScreens/Academy/presentation/pages/academy_details_layout.dart';
|
||||
|
||||
import '../../../../../shared/components/appbar_widget.dart';
|
||||
|
||||
class AcademyDetailsScreen extends StatefulWidget {
|
||||
const AcademyDetailsScreen({super.key});
|
||||
|
||||
@override
|
||||
State<AcademyDetailsScreen> createState() => _AcademyDetailsScreenState();
|
||||
}
|
||||
|
||||
class _AcademyDetailsScreenState extends State<AcademyDetailsScreen> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Scaffold(
|
||||
appBar: AppBarWidget(
|
||||
height: 50,
|
||||
titleTxt: "Article Name",
|
||||
),
|
||||
body: AcademyDetailsLayout(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:tanami_app/features/MainScreens/Academy/presentation/widgets/academy_card.dart';
|
||||
|
||||
class AcademyLayout extends StatelessWidget {
|
||||
const AcademyLayout({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: ListView.builder(
|
||||
itemCount: data.length,
|
||||
itemBuilder: (context, index) {
|
||||
return academyCard(data[index]);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
List data = [
|
||||
{
|
||||
'img_path': 'assets/images/academy_screen/bg1.jpg',
|
||||
'date': 'July / 10 / 2025',
|
||||
'title': 'Article ',
|
||||
'videos': '3',
|
||||
'desc':
|
||||
'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.'
|
||||
},
|
||||
{
|
||||
'img_path': 'assets/images/academy_screen/bg2.jpg',
|
||||
'date': 'July / 10 / 2025',
|
||||
'title': 'Article ',
|
||||
'videos': '3',
|
||||
'desc':
|
||||
'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.'
|
||||
},
|
||||
{
|
||||
'img_path': 'assets/images/academy_screen/bg3.jpg',
|
||||
'date': 'July / 10 / 2025',
|
||||
'videos': '3',
|
||||
'title': 'Article ',
|
||||
'desc':
|
||||
'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.'
|
||||
},
|
||||
{
|
||||
'img_path': 'assets/images/academy_screen/bg4.jpg',
|
||||
'date': 'July / 10 / 2025',
|
||||
'videos': '3',
|
||||
'title': 'Article ',
|
||||
'desc':
|
||||
'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.',
|
||||
},
|
||||
{
|
||||
'img_path': 'assets/images/academy_screen/bg5.jpg',
|
||||
'date': 'July / 10 / 2025',
|
||||
'videos': '3',
|
||||
'title': 'Article ',
|
||||
'desc':
|
||||
'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.',
|
||||
},
|
||||
{
|
||||
'img_path': 'assets/images/academy_screen/bg4.jpg',
|
||||
'date': 'July / 10 / 2025',
|
||||
'videos': '3',
|
||||
'title': 'Article ',
|
||||
'desc':
|
||||
'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.',
|
||||
},
|
||||
{
|
||||
'img_path': 'assets/images/academy_screen/bg4.jpg',
|
||||
'date': 'July / 10 / 2025',
|
||||
'videos': '3',
|
||||
'title': 'Article ',
|
||||
'desc':
|
||||
'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.',
|
||||
},
|
||||
{
|
||||
'img_path': 'assets/images/academy_screen/bg4.jpg',
|
||||
'date': 'July / 10 / 2025',
|
||||
'videos': '3',
|
||||
'title': 'Article ',
|
||||
'desc':
|
||||
'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.',
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,32 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:tanami_app/core/styles/app_color.dart';
|
||||
import 'package:tanami_app/features/MainScreens/Academy/presentation/pages/academy_layout.dart';
|
||||
import 'package:tanami_app/shared/components/text_widget.dart';
|
||||
|
||||
import '../../../../../core/styles/app_text.dart';
|
||||
|
||||
class AcademyScreen extends StatefulWidget {
|
||||
const AcademyScreen({super.key});
|
||||
|
||||
@override
|
||||
State<AcademyScreen> createState() => _AcademyScreenState();
|
||||
}
|
||||
|
||||
class _AcademyScreenState extends State<AcademyScreen> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.white,
|
||||
elevation: 0,
|
||||
scrolledUnderElevation: 0,
|
||||
automaticallyImplyLeading: false,
|
||||
title: TextWidget().text22W700(
|
||||
AppText.academyText,
|
||||
clr: AppColor.charcoalColor,
|
||||
),
|
||||
titleSpacing: 16,
|
||||
),
|
||||
body: const AcademyLayout());
|
||||
}
|
||||
}
|
||||
@@ -1,199 +0,0 @@
|
||||
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_text.dart';
|
||||
|
||||
class AcademyDetailsScreen extends StatefulWidget {
|
||||
const AcademyDetailsScreen({super.key});
|
||||
|
||||
@override
|
||||
State<AcademyDetailsScreen> createState() => _AcademyDetailsScreenState();
|
||||
}
|
||||
|
||||
class _AcademyDetailsScreenState extends State<AcademyDetailsScreen> {
|
||||
List videos = [
|
||||
'assets/images/academy_screen/vd_bg.jpg',
|
||||
'assets/images/academy_screen/vd_bg.jpg',
|
||||
'assets/images/academy_screen/vd_bg.jpg'
|
||||
];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
appBar: AppBar(
|
||||
elevation: 0,
|
||||
scrolledUnderElevation: 0.0,
|
||||
backgroundColor: Colors.white,
|
||||
centerTitle: true,
|
||||
title: Text(
|
||||
'Article name',
|
||||
style: GoogleFonts.dmSans(
|
||||
color: const Color(0xFF272727), // Text color similar to your image
|
||||
fontSize: 20.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 20.0),
|
||||
child: Column(
|
||||
children: [
|
||||
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: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Stack(
|
||||
children: [
|
||||
ClipRRect(
|
||||
borderRadius: const BorderRadius.only(
|
||||
topLeft: Radius.circular(20.0),
|
||||
topRight: Radius.circular(20.0),
|
||||
),
|
||||
child: Image.asset(
|
||||
'assets/images/academy_screen/bg2.jpg',
|
||||
fit: BoxFit.cover,
|
||||
width: double.infinity,
|
||||
height: 190.h,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 0.0,
|
||||
child: Image.asset(
|
||||
'assets/images/academy_screen/dark_overlay.png',
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 8.0,
|
||||
left: 12.0,
|
||||
child: Row(
|
||||
children: [
|
||||
Image.asset(
|
||||
'assets/images/academy_screen/video.png',
|
||||
height: 15.sp,
|
||||
),
|
||||
SizedBox(
|
||||
width: 5.w,
|
||||
),
|
||||
Text(
|
||||
'3 videos',
|
||||
style: GoogleFonts.dmSans(
|
||||
color: const Color(0xFFD8D8D8),
|
||||
fontSize: 12.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16.0, vertical: 20.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Jul / 10 / 2025',
|
||||
style: GoogleFonts.dmSans(
|
||||
color: const Color(0xFF8D8D8D),
|
||||
fontSize: 11.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 12.h,
|
||||
),
|
||||
Text(
|
||||
'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.',
|
||||
style: GoogleFonts.dmSans(
|
||||
color: Colors.grey,
|
||||
fontSize: 14.sp,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 12.h,
|
||||
),
|
||||
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: Image.asset(
|
||||
videos[index],
|
||||
fit: BoxFit.cover,
|
||||
height: 160.h,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
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/routes/route_name.dart';
|
||||
import '../../../../../core/routes/routes.dart';
|
||||
|
||||
Widget academyCard(dynamic data) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 16.0),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
goRouter.pushNamed(RouteName.academyDetails);
|
||||
},
|
||||
child: Container(
|
||||
height: 140.h,
|
||||
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: Row(
|
||||
children: [
|
||||
Container(
|
||||
height: 140.h,
|
||||
width: 164.w,
|
||||
decoration: const BoxDecoration(
|
||||
color: AppColor.academyCardBgColor,
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(20.0),
|
||||
),
|
||||
),
|
||||
child: Stack(
|
||||
children: [
|
||||
ClipRRect(
|
||||
borderRadius: const BorderRadius.only(
|
||||
topLeft: Radius.circular(20.0),
|
||||
bottomLeft: Radius.circular(20.0),
|
||||
),
|
||||
child: Image.asset(
|
||||
data['img_path'],
|
||||
fit: BoxFit.cover,
|
||||
height: double.infinity,
|
||||
alignment: Alignment.topCenter,
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 0.0,
|
||||
child: ClipRRect(
|
||||
borderRadius: const BorderRadius.only(
|
||||
bottomLeft: Radius.circular(20.0),
|
||||
),
|
||||
child: Image.asset(
|
||||
AppImages.academyCardOverlay,
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 8.0, left: 12.0,
|
||||
// alignment: Alignment.bottomLeft,
|
||||
child: Row(
|
||||
children: [
|
||||
Image.asset(
|
||||
AppImages.videoIcon,
|
||||
height: 15.sp,
|
||||
),
|
||||
Gap(
|
||||
5.w,
|
||||
),
|
||||
TextWidget().text12W700(
|
||||
'${data['videos']} videos',
|
||||
clr: AppColor.academyCardTextColor,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(vertical: 20.0, horizontal: 16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
TextWidget().text13W500(
|
||||
data['date'],
|
||||
clr: AppColor.academyCardTextColor,
|
||||
),
|
||||
Gap(
|
||||
4.h,
|
||||
),
|
||||
TextWidget().text17W600(
|
||||
data['title'],
|
||||
clr: AppColor.plainBlack,
|
||||
),
|
||||
Gap(
|
||||
12.h,
|
||||
),
|
||||
SizedBox(
|
||||
width: 158.w,
|
||||
child: TextWidget().text14W400(
|
||||
data['desc'],
|
||||
maxLine: 2,
|
||||
txtAlign: TextAlign.start,
|
||||
clr: AppColor.academyCardTextColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:google_fonts/google_fonts.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';
|
||||
|
||||
class AcademyDetailSection extends StatelessWidget {
|
||||
const AcademyDetailSection({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.plainWhite,
|
||||
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: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Stack(
|
||||
children: [
|
||||
ClipRRect(
|
||||
borderRadius: const BorderRadius.only(
|
||||
topLeft: Radius.circular(20.0),
|
||||
topRight: Radius.circular(20.0),
|
||||
),
|
||||
child: Image.asset(
|
||||
'assets/images/academy_screen/bg2.jpg',
|
||||
fit: BoxFit.cover,
|
||||
width: double.infinity,
|
||||
height: 190.h,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 0.0,
|
||||
child: Image.asset(
|
||||
AppImages.academyCardOverlay,
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 8.0,
|
||||
left: 12.0,
|
||||
child: Row(
|
||||
children: [
|
||||
Image.asset(
|
||||
AppImages.videoIcon,
|
||||
height: 15.sp,
|
||||
),
|
||||
Gap(5.w),
|
||||
TextWidget().text12W700(
|
||||
'3 ${AppText.videosTitle}',
|
||||
clr: AppColor.academyCardTextColor,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 16.0, vertical: 20.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
TextWidget()
|
||||
.text11W500('Jul / 10 / 2025', clr: AppColor.hintTextColor),
|
||||
Gap(12.h),
|
||||
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,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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 AcademyVideoSection extends StatelessWidget {
|
||||
const AcademyVideoSection({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,12 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import 'carousel_event.dart';
|
||||
import 'carousel_state.dart';
|
||||
|
||||
class CarouselBloc extends Bloc<CarouselEvent, CarouselState> {
|
||||
CarouselBloc() : super(CarouselInitial()) {
|
||||
on<PageChanged>((event, emit) {
|
||||
emit(CarouselPageState(event.index));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
abstract class CarouselEvent {}
|
||||
|
||||
class PageChanged extends CarouselEvent {
|
||||
final int index;
|
||||
|
||||
PageChanged(this.index);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
abstract class CarouselState {}
|
||||
|
||||
class CarouselInitial extends CarouselState {}
|
||||
|
||||
class CarouselPageState extends CarouselState {
|
||||
final int currentIndex;
|
||||
|
||||
CarouselPageState(this.currentIndex);
|
||||
}
|
||||
@@ -1,342 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.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_text.dart';
|
||||
|
||||
class PortfolioScreen extends StatefulWidget {
|
||||
const PortfolioScreen({super.key});
|
||||
|
||||
@override
|
||||
State<PortfolioScreen> createState() => _PortfolioScreenState();
|
||||
}
|
||||
|
||||
class _PortfolioScreenState extends State<PortfolioScreen> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
body: CustomScrollView(
|
||||
slivers: [
|
||||
SliverAppBar(
|
||||
elevation: 0,
|
||||
scrolledUnderElevation: 0,
|
||||
expandedHeight: 230.0,
|
||||
automaticallyImplyLeading: false,
|
||||
snap: false,
|
||||
pinned: true,
|
||||
floating: false,
|
||||
flexibleSpace: LayoutBuilder(
|
||||
builder: (BuildContext context, BoxConstraints constraints) {
|
||||
var top = constraints.biggest.height;
|
||||
var percentage =
|
||||
((top - kToolbarHeight) / (200.0 - kToolbarHeight))
|
||||
.clamp(0.0, 1.0);
|
||||
var opacity = (1 - percentage).clamp(0.0, 1.0);
|
||||
return FlexibleSpaceBar(
|
||||
// centerTitle: true,
|
||||
titlePadding:
|
||||
const EdgeInsets.only(left: 30, top: 0, bottom: 15),
|
||||
title: Opacity(
|
||||
opacity: opacity,
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
AppText.portfolio,
|
||||
style: GoogleFonts.dmSans(
|
||||
color: const Color(0xFF888888),
|
||||
fontSize: 12.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'SAR 178,000',
|
||||
style: GoogleFonts.dmSans(
|
||||
color: Colors.black,
|
||||
fontSize: 14.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
background: Stack(
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
Image.asset(
|
||||
'assets/images/portfolio_screen/bg.png', // Replace with your image asset
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 40.0),
|
||||
child: Opacity(
|
||||
opacity: percentage,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
AppText.portfolio,
|
||||
style: GoogleFonts.dmSans(
|
||||
color: const Color(0xFFC9D9CB),
|
||||
fontSize: 14.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 8.h,
|
||||
),
|
||||
Text(
|
||||
'SAR 178,000',
|
||||
style: GoogleFonts.dmSans(
|
||||
color: Colors.white,
|
||||
fontSize: 28.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}),
|
||||
backgroundColor: Colors.white,
|
||||
),
|
||||
SliverList(
|
||||
delegate: SliverChildBuilderDelegate(
|
||||
(context, index) => Padding(
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
goRouter.pushNamed(RouteName.porfolioDetails);
|
||||
},
|
||||
child: 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: Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 20.0, vertical: 16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Image.asset(
|
||||
(index == 2)
|
||||
? 'assets/images/portfolio_screen/clock_off.png'
|
||||
: 'assets/images/portfolio_screen/clock.png',
|
||||
height: 25.sp,
|
||||
),
|
||||
SizedBox(
|
||||
width: 5.w,
|
||||
),
|
||||
Text(
|
||||
'Mar 01 2024',
|
||||
style: GoogleFonts.dmSans(
|
||||
color: const Color(0xFF004717),
|
||||
fontSize: 12.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Text(
|
||||
(index == 2) ? 'Exited' : 'Pending',
|
||||
style: GoogleFonts.dmSans(
|
||||
color: (index == 2)
|
||||
? const Color(0xFF8D8D8D)
|
||||
: const Color(0xFF0FA4A4),
|
||||
fontSize: 14.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 8.h,
|
||||
),
|
||||
Text(
|
||||
(index == 2)
|
||||
? 'Real Estate III'
|
||||
: 'Private equity portfolio I',
|
||||
style: GoogleFonts.dmSans(
|
||||
color: Colors.black,
|
||||
fontSize: 17.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
decoration: const BoxDecoration(
|
||||
color: Color(0xFFF8F8F8),
|
||||
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: [
|
||||
Text(
|
||||
AppText.investmentamount,
|
||||
style: GoogleFonts.dmSans(
|
||||
color: (index == 2)
|
||||
? const Color(0xFF8D8D8D)
|
||||
: const Color(0xFF535353),
|
||||
fontSize: 14.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.end,
|
||||
children: [
|
||||
Text(
|
||||
'SAR 100,000',
|
||||
style: GoogleFonts.dmSans(
|
||||
color: (index == 2)
|
||||
? const Color(0xFF8D8D8D)
|
||||
: Colors.black,
|
||||
fontSize: 14.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
' \$ 26,700',
|
||||
style: GoogleFonts.dmSans(
|
||||
color: (index == 2)
|
||||
? const Color(0xFF8D8D8D)
|
||||
: Colors.black,
|
||||
fontSize: 11.sp,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 8.h,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
AppText.currentval,
|
||||
style: GoogleFonts.dmSans(
|
||||
color: (index == 2)
|
||||
? const Color(0xFF8D8D8D)
|
||||
: const Color(0xFF535353),
|
||||
fontSize: 14.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.end,
|
||||
children: [
|
||||
Text(
|
||||
'SAR 100,000',
|
||||
style: GoogleFonts.dmSans(
|
||||
color: (index == 2)
|
||||
? const Color(0xFF8D8D8D)
|
||||
: Colors.black,
|
||||
fontSize: 14.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
' \$ 26,700',
|
||||
style: GoogleFonts.dmSans(
|
||||
color: (index == 2)
|
||||
? const Color(0xFF8D8D8D)
|
||||
: Colors.black,
|
||||
fontSize: 11.sp,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 8.h,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
AppText.totalreturn,
|
||||
style: GoogleFonts.dmSans(
|
||||
color: (index == 2)
|
||||
? const Color(0xFF8D8D8D)
|
||||
: const Color(0xFF535353),
|
||||
fontSize: 14.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
(index == 2) ? '- 20.0%' : '+ 20.0%',
|
||||
style: GoogleFonts.dmSans(
|
||||
color: (index == 2)
|
||||
? const Color(0xFFde9595)
|
||||
: const Color(0xFF066123),
|
||||
fontSize: 14.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
childCount: 3,
|
||||
), //SliverChildBuildDelegate
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
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 '../widgets/details_section.dart';
|
||||
import '../widgets/included_documents_section.dart';
|
||||
import '../widgets/portfolio_image_carousel.dart';
|
||||
|
||||
class PortfolioDetailsLayout extends StatelessWidget {
|
||||
const PortfolioDetailsLayout({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: [
|
||||
CarouselView(),
|
||||
const DetailsSection(),
|
||||
],
|
||||
),
|
||||
),
|
||||
Gap(
|
||||
20.h,
|
||||
),
|
||||
const IncludedDocumentsSection(),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,477 +1,28 @@
|
||||
import 'package:carousel_slider/carousel_slider.dart';
|
||||
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_text.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:tanami_app/features/MainScreens/Portfolio/presentation/pages/portfolio_details_layout.dart';
|
||||
|
||||
class DetailsScreen extends StatefulWidget {
|
||||
import '../../../../../shared/components/appbar_widget.dart';
|
||||
import '../bloc/carousel/carousel_bloc.dart';
|
||||
|
||||
class DetailsScreen extends StatelessWidget {
|
||||
const DetailsScreen({super.key});
|
||||
|
||||
@override
|
||||
State<DetailsScreen> createState() => _DetailsScreenState();
|
||||
}
|
||||
|
||||
class _DetailsScreenState extends State<DetailsScreen> {
|
||||
int _current = 0;
|
||||
final CarouselController _controller = CarouselController();
|
||||
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'},
|
||||
];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.white,
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 20.0),
|
||||
child: Column(
|
||||
children: [
|
||||
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: Column(
|
||||
children: [
|
||||
Container(
|
||||
height: 190.h,
|
||||
decoration: const BoxDecoration(
|
||||
color: Color(0xFFF8F8F8),
|
||||
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) {
|
||||
setState(() {
|
||||
_current = index;
|
||||
});
|
||||
}),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(bottom: 17.0),
|
||||
child: 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: (_current == entry.key)
|
||||
? Colors.white
|
||||
: Colors.grey,
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
)),
|
||||
Positioned(
|
||||
top: 20,
|
||||
left: 20,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 15.0, vertical: 10.0),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(
|
||||
0xFFE4F5E9), // Background color similar to your image
|
||||
borderRadius: BorderRadius.circular(
|
||||
30.0), // Large border radius for rounded corners
|
||||
),
|
||||
child: Text(
|
||||
'Asset Class',
|
||||
style: GoogleFonts.dmSans(
|
||||
color: const Color(
|
||||
0xFF0B8933), // Text color similar to your image
|
||||
fontSize: 12.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
top: 20,
|
||||
right: 20,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 15.0, vertical: 10.0),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors
|
||||
.white, // Background color similar to your image
|
||||
borderRadius: BorderRadius.circular(
|
||||
30.0), // Large border radius for rounded corners
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Image.asset(
|
||||
'assets/images/portfolio_screen/clock.png',
|
||||
height: 15.h,
|
||||
),
|
||||
SizedBox(
|
||||
width: 5.w,
|
||||
),
|
||||
Text(
|
||||
'Jul 10 2025',
|
||||
style: GoogleFonts.dmSans(
|
||||
color: Colors
|
||||
.black, // Text color similar to your image
|
||||
fontSize: 12.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
color: Colors.white,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(20.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Multi Family Residental',
|
||||
style: GoogleFonts.dmSans(
|
||||
color: Colors.black,
|
||||
fontSize: 17.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 10.h,
|
||||
),
|
||||
Text(
|
||||
'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.',
|
||||
style: GoogleFonts.dmSans(
|
||||
color: Colors.grey,
|
||||
fontSize: 14.sp,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
decoration: const BoxDecoration(
|
||||
color: Color(0xFFF8F8F8),
|
||||
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: Text(
|
||||
AppText.investmentamount,
|
||||
style: GoogleFonts.dmSans(
|
||||
color: const Color(0xFF535353),
|
||||
fontSize: 14.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Text(
|
||||
'SAR 100,000',
|
||||
style: GoogleFonts.dmSans(
|
||||
color: Colors.black,
|
||||
fontSize: 14.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
' \$ 26,700',
|
||||
style: GoogleFonts.dmSans(
|
||||
color: Colors.black,
|
||||
fontSize: 11.sp,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 8.h,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 150.w,
|
||||
child: Text(
|
||||
AppText.currentval,
|
||||
style: GoogleFonts.dmSans(
|
||||
color: const Color(0xFF535353),
|
||||
fontSize: 14.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Text(
|
||||
'SAR 100,000',
|
||||
style: GoogleFonts.dmSans(
|
||||
color: Colors.black,
|
||||
fontSize: 14.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
' \$ 26,700',
|
||||
style: GoogleFonts.dmSans(
|
||||
color: Colors.black,
|
||||
fontSize: 11.sp,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 8.h,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 150.w,
|
||||
child: Text(
|
||||
AppText.disttodate,
|
||||
style: GoogleFonts.dmSans(
|
||||
color: const Color(0xFF535353),
|
||||
fontSize: 14.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'20.0%',
|
||||
style: GoogleFonts.dmSans(
|
||||
color: Colors.black,
|
||||
fontSize: 14.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 8.h,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
AppText.totalreturn,
|
||||
style: GoogleFonts.dmSans(
|
||||
color: const Color(0xFF535353),
|
||||
fontSize: 14.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'+ 20.0%',
|
||||
style: GoogleFonts.dmSans(
|
||||
color: const Color(0xFF066123),
|
||||
fontSize: 14.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 20.h,
|
||||
),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
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.all(20.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
AppText.includeddocs,
|
||||
style: GoogleFonts.dmSans(
|
||||
color: Colors.black,
|
||||
fontSize: 15.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 16.h,
|
||||
),
|
||||
GridView.count(
|
||||
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: Color(0xFFF4F4F4),
|
||||
borderRadius:
|
||||
BorderRadius.all(Radius.circular(10.0)),
|
||||
),
|
||||
padding: const EdgeInsets.all(20.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Image.asset(
|
||||
'assets/images/portfolio_screen/document.png',
|
||||
height: 16.sp,
|
||||
),
|
||||
SizedBox(
|
||||
width: 7.w,
|
||||
),
|
||||
Text(
|
||||
"Filename.pdf",
|
||||
style: GoogleFonts.dmSans(
|
||||
color: Colors.black,
|
||||
fontSize: 12.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 14.h,
|
||||
),
|
||||
Row(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.end,
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
"512 Mb",
|
||||
style: GoogleFonts.dmSans(
|
||||
color: const Color(0xFF535353),
|
||||
fontSize: 12.sp,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 7.w,
|
||||
),
|
||||
Image.asset(
|
||||
'assets/images/portfolio_screen/download.png',
|
||||
height: 20.sp,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
appBar: const AppBarWidget(
|
||||
height: 45,
|
||||
titleTxt: "",
|
||||
),
|
||||
),
|
||||
);
|
||||
body: MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider(
|
||||
// Create an instance of the OnboardingBloc
|
||||
create: (context) => CarouselBloc(),
|
||||
),
|
||||
],
|
||||
child: const PortfolioDetailsLayout(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import '../../../../../core/styles/app_text.dart';
|
||||
|
||||
class PortfolioLayout extends StatelessWidget {
|
||||
const PortfolioLayout({super.key});
|
||||
//2339.712 - 2326.866
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:tanami_app/features/MainScreens/Portfolio/presentation/pages/portfolio_layout.dart';
|
||||
|
||||
class PortfolioScreen extends StatefulWidget {
|
||||
import 'portfolio_layout.dart';
|
||||
|
||||
class PortfolioScreen extends StatelessWidget {
|
||||
const PortfolioScreen({super.key});
|
||||
|
||||
@override
|
||||
State<PortfolioScreen> createState() => _PortfolioScreenState();
|
||||
}
|
||||
|
||||
class _PortfolioScreenState extends State<PortfolioScreen> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Scaffold(body: PortfolioLayout());
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
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 DetailsSection extends StatelessWidget {
|
||||
const DetailsSection({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().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.investmentamount,
|
||||
clr: AppColor.portoflioCardTextColor,
|
||||
txtAlign: TextAlign.start,
|
||||
),
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
TextWidget().text14W700(
|
||||
'SAR 100,000',
|
||||
clr: AppColor.plainBlack,
|
||||
txtAlign: TextAlign.end,
|
||||
),
|
||||
TextWidget().text11W400(
|
||||
' \$ 26,700',
|
||||
clr: AppColor.plainBlack,
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 8.h,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 150.w,
|
||||
child: TextWidget().text14W500(
|
||||
AppText.currentval,
|
||||
clr: AppColor.portoflioCardTextColor,
|
||||
txtAlign: TextAlign.start,
|
||||
),
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
TextWidget().text14W700(
|
||||
'SAR 100,000',
|
||||
clr: AppColor.plainBlack,
|
||||
txtAlign: TextAlign.end,
|
||||
),
|
||||
TextWidget().text11W400(
|
||||
' \$ 26,700',
|
||||
clr: AppColor.plainBlack,
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 8.h,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 150.w,
|
||||
child: TextWidget().text14W500(
|
||||
AppText.disttodate,
|
||||
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: [
|
||||
TextWidget().text14W500(
|
||||
AppText.totalreturn,
|
||||
clr: AppColor.portoflioCardTextColor,
|
||||
txtAlign: TextAlign.start,
|
||||
),
|
||||
TextWidget().text14W700(
|
||||
'+ 20.0%',
|
||||
clr: AppColor.selectedItemColor,
|
||||
txtAlign: TextAlign.end,
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -65,9 +65,19 @@ class ExitedCard extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
),
|
||||
TextWidget().text14W700(
|
||||
portfolioModel.status,
|
||||
clr: AppColor.hintTextColor,
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 15,
|
||||
vertical: 3,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.appBarIconColor,
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
),
|
||||
child: TextWidget().text14W700(
|
||||
portfolioModel.status,
|
||||
clr: AppColor.plainWhite,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -82,8 +92,11 @@ class ExitedCard extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: 1.sw,
|
||||
decoration: const BoxDecoration(
|
||||
color: AppColor.portfolioCardBgColor,
|
||||
image: DecorationImage(
|
||||
image: AssetImage(AppImages.portfolioCardBg),
|
||||
fit: BoxFit.cover),
|
||||
borderRadius: BorderRadius.only(
|
||||
bottomLeft: Radius.circular(20.0),
|
||||
bottomRight: Radius.circular(20.0),
|
||||
@@ -100,18 +113,18 @@ class ExitedCard extends StatelessWidget {
|
||||
children: [
|
||||
TextWidget().text14W500(
|
||||
AppText.investmentamount,
|
||||
clr: AppColor.hintTextColor,
|
||||
clr: AppColor.portoflioCardTextColor,
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
TextWidget().text14W700(
|
||||
portfolioModel.investmentAmountSAR,
|
||||
clr: AppColor.hintTextColor,
|
||||
clr: AppColor.plainBlack,
|
||||
),
|
||||
TextWidget().text11W400(
|
||||
'\$ ${portfolioModel.investmentAmountUSD}',
|
||||
clr: AppColor.hintTextColor,
|
||||
clr: AppColor.plainBlack,
|
||||
),
|
||||
],
|
||||
)
|
||||
@@ -126,18 +139,18 @@ class ExitedCard extends StatelessWidget {
|
||||
children: [
|
||||
TextWidget().text14W500(
|
||||
AppText.currentval,
|
||||
clr: AppColor.hintTextColor,
|
||||
clr: AppColor.portoflioCardTextColor,
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
TextWidget().text14W700(
|
||||
portfolioModel.currentValuationSAR,
|
||||
clr: AppColor.hintTextColor,
|
||||
clr: AppColor.plainBlack,
|
||||
),
|
||||
TextWidget().text11W400(
|
||||
'\$ ${portfolioModel.currentValuationUSD}',
|
||||
clr: AppColor.hintTextColor,
|
||||
clr: AppColor.plainBlack,
|
||||
),
|
||||
],
|
||||
)
|
||||
@@ -152,11 +165,11 @@ class ExitedCard extends StatelessWidget {
|
||||
children: [
|
||||
TextWidget().text14W500(
|
||||
AppText.totalreturn,
|
||||
clr: AppColor.hintTextColor,
|
||||
clr: AppColor.portoflioCardTextColor,
|
||||
),
|
||||
TextWidget().text14W700(
|
||||
'- ${portfolioModel.totalReturnPercentage}',
|
||||
clr: AppColor.negativePercentageColor,
|
||||
clr: AppColor.txtErrorColor,
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
@@ -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 IncludedDocumentsSection extends StatelessWidget {
|
||||
const IncludedDocumentsSection({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,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -65,9 +65,19 @@ class PendingCard extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
),
|
||||
TextWidget().text14W700(
|
||||
portfolioModel.status,
|
||||
clr: AppColor.statusTextColor,
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 15,
|
||||
vertical: 3,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.stausBgColor,
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
),
|
||||
child: TextWidget().text14W700(
|
||||
portfolioModel.status,
|
||||
clr: AppColor.plainWhite,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -82,8 +92,11 @@ class PendingCard extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: 1.sw,
|
||||
decoration: const BoxDecoration(
|
||||
color: AppColor.portfolioCardBgColor,
|
||||
image: DecorationImage(
|
||||
image: AssetImage(AppImages.portfolioCardBg),
|
||||
fit: BoxFit.cover),
|
||||
borderRadius: BorderRadius.only(
|
||||
bottomLeft: Radius.circular(20.0),
|
||||
bottomRight: Radius.circular(20.0),
|
||||
@@ -111,7 +124,7 @@ class PendingCard extends StatelessWidget {
|
||||
),
|
||||
TextWidget().text11W400(
|
||||
' \$ ${portfolioModel.investmentAmountUSD}',
|
||||
clr: Colors.black,
|
||||
clr: AppColor.plainBlack,
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
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/shared/components/text_widget.dart';
|
||||
|
||||
import '../bloc/carousel/carousel_bloc.dart';
|
||||
import '../bloc/carousel/carousel_event.dart';
|
||||
import '../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 CarouselView extends StatelessWidget {
|
||||
final CarouselController _controller = CarouselController();
|
||||
|
||||
CarouselView({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(
|
||||
'Jul 10 2025',
|
||||
clr: AppColor.plainBlack,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:tanami_app/features/MainScreens/Academy/presentation/pages/academyScreen.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/Portfolio/presentation/pages/portfolio_screen.dart';
|
||||
import 'package:tanami_app/features/MainScreens/Settings/presentation/pages/settingsScreen.dart';
|
||||
import 'package:tanami_app/features/MainScreens/Wallet/presentation/pages/walletScreen.dart';
|
||||
import 'package:tanami_app/shared/components/common_bottom_navigation.dart';
|
||||
|
||||
import '../../shared/components/bloc/bottom_nav_bar/bottom_navigation_bloc.dart';
|
||||
import '../../shared/components/bloc/bottom_nav_bar/bottom_navigation_state.dart';
|
||||
import '../../shared/components/exit_app_dialog.dart';
|
||||
|
||||
var currentTab = [
|
||||
@@ -18,24 +21,25 @@ var currentTab = [
|
||||
|
||||
var selectedIndex = 1;
|
||||
|
||||
void updateTab(int index) {
|
||||
selectedIndex = index;
|
||||
}
|
||||
|
||||
class MainScreen extends StatelessWidget {
|
||||
const MainScreen({super.key});
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WillPopScope(
|
||||
onWillPop: () async {
|
||||
exitAppDialog(context);
|
||||
return false;
|
||||
return BlocBuilder<BottomNavigationBloc, BottomNavigationState>(
|
||||
builder: (context, state) {
|
||||
int selectedIndex = (state as TabState).selectedIndex;
|
||||
return WillPopScope(
|
||||
onWillPop: () async {
|
||||
exitAppDialog(context);
|
||||
return false;
|
||||
},
|
||||
child: Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
body: currentTab[selectedIndex],
|
||||
bottomNavigationBar: bottomnavigationbar(context, selectedIndex),
|
||||
),
|
||||
);
|
||||
},
|
||||
child: Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
body: currentTab[selectedIndex],
|
||||
bottomNavigationBar: bottomnavigationbar(selectedIndex),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'core/routes/routes.dart';
|
||||
import 'core/utils/connectivity/network_connectivity.dart';
|
||||
import 'features/countrySelection/presentation/bloc/choose_country_bloc.dart';
|
||||
import 'shared/components/bloc/bottom_nav_bar/bottom_navigation_bloc.dart';
|
||||
|
||||
/* CREATED BY - JAYESH JAIN
|
||||
DATE - 24-05-2024
|
||||
@@ -54,9 +55,9 @@ class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
|
||||
BlocProvider(
|
||||
create: (context) => RadioBloc(),
|
||||
),
|
||||
// BlocProvider(
|
||||
// create: (context) => PasswordVisibilityBloc(),
|
||||
// ),
|
||||
BlocProvider(
|
||||
create: (_) => BottomNavigationBloc(),
|
||||
)
|
||||
],
|
||||
child: ScreenUtilInit(
|
||||
builder: (BuildContext context, Widget? child) => MaterialApp.router(
|
||||
|
||||
@@ -9,16 +9,18 @@ import 'package:tanami_app/shared/components/text_widget.dart';
|
||||
class AppBarWidget extends StatelessWidget implements PreferredSizeWidget {
|
||||
@override
|
||||
Size get preferredSize => Size.fromHeight(height!);
|
||||
const AppBarWidget(
|
||||
{super.key,
|
||||
required this.titleTxt,
|
||||
this.suffixIcon,
|
||||
this.showLeading = true,
|
||||
this.customBack,
|
||||
this.backPageName = '',
|
||||
this.customActionWidget,
|
||||
this.onCustomActionPressed,
|
||||
this.height = 105});
|
||||
const AppBarWidget({
|
||||
super.key,
|
||||
required this.titleTxt,
|
||||
this.suffixIcon,
|
||||
this.showLeading = true,
|
||||
this.customBack,
|
||||
this.backPageName = '',
|
||||
this.customActionWidget,
|
||||
this.onCustomActionPressed,
|
||||
this.height = 10,
|
||||
this.centerTitle,
|
||||
});
|
||||
|
||||
final String titleTxt;
|
||||
final String? suffixIcon;
|
||||
@@ -28,6 +30,7 @@ class AppBarWidget extends StatelessWidget implements PreferredSizeWidget {
|
||||
final Widget? customActionWidget;
|
||||
final VoidCallback? onCustomActionPressed;
|
||||
final double? height;
|
||||
final bool? centerTitle;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return PreferredSize(
|
||||
@@ -35,11 +38,11 @@ class AppBarWidget extends StatelessWidget implements PreferredSizeWidget {
|
||||
child: AppBar(
|
||||
scrolledUnderElevation: 0.0,
|
||||
elevation: 0,
|
||||
centerTitle: true,
|
||||
centerTitle: centerTitle ?? true,
|
||||
title: TextWidget().text20W700(titleTxt, clr: AppColor.charcoalColor),
|
||||
leading: Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: 16.w,
|
||||
left: !showLeading! ? 0 : 16.w,
|
||||
),
|
||||
child: !showLeading!
|
||||
? null
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import 'package:bloc/bloc.dart';
|
||||
|
||||
import 'bottom_navigation_event.dart';
|
||||
import 'bottom_navigation_state.dart';
|
||||
|
||||
// Bloc
|
||||
class BottomNavigationBloc
|
||||
extends Bloc<BottomNavigationEvent, BottomNavigationState> {
|
||||
BottomNavigationBloc() : super(TabState(0)) {
|
||||
// Register the event handler
|
||||
on<TabChanged>((event, emit) {
|
||||
emit(TabState(event.index));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
abstract class BottomNavigationEvent {}
|
||||
|
||||
class TabChanged extends BottomNavigationEvent {
|
||||
final int index;
|
||||
|
||||
TabChanged(this.index);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
abstract class BottomNavigationState {}
|
||||
|
||||
class TabState extends BottomNavigationState {
|
||||
final int selectedIndex;
|
||||
|
||||
TabState(this.selectedIndex);
|
||||
}
|
||||
@@ -1,28 +1,31 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:tanami_app/features/MainScreens/MainScreen.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:tanami_app/core/styles/app_color.dart';
|
||||
|
||||
Widget bottomnavigationbar(selectedIndex) {
|
||||
import 'bloc/bottom_nav_bar/bottom_navigation_bloc.dart';
|
||||
import 'bloc/bottom_nav_bar/bottom_navigation_event.dart';
|
||||
|
||||
Widget bottomnavigationbar(BuildContext context, selectedIndex) {
|
||||
return BottomNavigationBar(
|
||||
type: BottomNavigationBarType.fixed,
|
||||
showUnselectedLabels: true,
|
||||
selectedItemColor: Color(0xFF0B8933),
|
||||
unselectedItemColor: const Color(0xFF676767),
|
||||
unselectedLabelStyle: TextStyle(
|
||||
selectedItemColor: AppColor.selectedItemColor,
|
||||
unselectedItemColor: AppColor.unselectedItemColor,
|
||||
unselectedLabelStyle: GoogleFonts.dmSans(
|
||||
fontSize: 10.sp,
|
||||
color: const Color(0xFF676767),
|
||||
color: AppColor.unselectedItemColor,
|
||||
fontWeight: FontWeight.w400,
|
||||
fontFamily: 'hiragino',
|
||||
),
|
||||
selectedLabelStyle: TextStyle(
|
||||
selectedLabelStyle: GoogleFonts.dmSans(
|
||||
fontSize: 10.sp,
|
||||
color: const Color(0xFF0B8933),
|
||||
color: AppColor.selectedItemColor,
|
||||
fontWeight: FontWeight.w400,
|
||||
fontFamily: 'hiragino',
|
||||
),
|
||||
currentIndex: selectedIndex,
|
||||
onTap: (index) {
|
||||
updateTab(index);
|
||||
context.read<BottomNavigationBloc>().add(TabChanged(index));
|
||||
},
|
||||
items: [
|
||||
BottomNavigationBarItem(
|
||||
@@ -62,8 +65,6 @@ Widget bottomnavigationbar(selectedIndex) {
|
||||
height: 28.h,
|
||||
width: 28.w,
|
||||
),
|
||||
|
||||
// SvgPicture.asset('assets/image/svg/active_shortTrade.svg'),
|
||||
label: 'Invest',
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
|
||||
@@ -12,6 +12,14 @@ class TextWidget {
|
||||
color: clr ?? AppColor.plainWhite));
|
||||
}
|
||||
|
||||
Widget text11W500(String text, {Color? clr}) {
|
||||
return Text(text,
|
||||
style: GoogleFonts.dmSans(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: clr ?? AppColor.plainWhite));
|
||||
}
|
||||
|
||||
//Text Size 12
|
||||
Widget text12W400(String text, {Color? clr}) {
|
||||
return Text(text,
|
||||
@@ -36,16 +44,29 @@ class TextWidget {
|
||||
fontWeight: FontWeight.w700,
|
||||
color: clr ?? AppColor.plainWhite));
|
||||
}
|
||||
//Text Size 14
|
||||
|
||||
//Text Size 13
|
||||
Widget text13W500(String text, {Color? clr}) {
|
||||
return Text(text,
|
||||
style: GoogleFonts.dmSans(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: clr ?? AppColor.plainWhite));
|
||||
}
|
||||
|
||||
//Text Size 14
|
||||
Widget text14W400(
|
||||
String text, {
|
||||
Color? clr,
|
||||
TextDecoration? textDecoration,
|
||||
TextAlign? txtAlign,
|
||||
int? maxLine,
|
||||
TextOverflow? txtOverflow,
|
||||
}) {
|
||||
return Text(text,
|
||||
textAlign: txtAlign ?? TextAlign.center,
|
||||
maxLines: maxLine ?? 20,
|
||||
overflow: txtOverflow ?? TextOverflow.ellipsis,
|
||||
style: GoogleFonts.dmSans(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w400,
|
||||
@@ -80,20 +101,6 @@ class TextWidget {
|
||||
}
|
||||
|
||||
//Text Size 15
|
||||
Widget text15W500(
|
||||
String text, {
|
||||
Color? clr,
|
||||
TextDecoration? textDecoration,
|
||||
}) {
|
||||
return Text(text,
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.dmSans(
|
||||
fontSize: 15,
|
||||
decorationColor: AppColor.hintTextColor,
|
||||
decoration: textDecoration ?? TextDecoration.none,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: clr ?? AppColor.plainWhite));
|
||||
}
|
||||
|
||||
Widget text15W400(
|
||||
String text, {
|
||||
@@ -111,7 +118,53 @@ class TextWidget {
|
||||
color: clr ?? AppColor.plainWhite));
|
||||
}
|
||||
|
||||
Widget text15W500(
|
||||
String text, {
|
||||
Color? clr,
|
||||
TextDecoration? textDecoration,
|
||||
}) {
|
||||
return Text(text,
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.dmSans(
|
||||
fontSize: 15,
|
||||
decorationColor: AppColor.hintTextColor,
|
||||
decoration: textDecoration ?? TextDecoration.none,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: clr ?? AppColor.plainWhite));
|
||||
}
|
||||
|
||||
Widget text15W700(
|
||||
String text, {
|
||||
Color? clr,
|
||||
TextDecoration? textDecoration,
|
||||
}) {
|
||||
return Text(text,
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.dmSans(
|
||||
fontSize: 15,
|
||||
decorationColor: AppColor.hintTextColor,
|
||||
decoration: textDecoration ?? TextDecoration.none,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: clr ?? AppColor.plainWhite));
|
||||
}
|
||||
|
||||
//Text Size 17
|
||||
|
||||
Widget text17W600(
|
||||
String text, {
|
||||
Color? clr,
|
||||
TextDecoration? textDecoration,
|
||||
}) {
|
||||
return Text(text,
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.dmSans(
|
||||
fontSize: 17,
|
||||
decorationColor: AppColor.hintTextColor,
|
||||
decoration: textDecoration ?? TextDecoration.none,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: clr ?? AppColor.plainWhite));
|
||||
}
|
||||
|
||||
Widget text17W700(
|
||||
String text, {
|
||||
Color? clr,
|
||||
|
||||
Reference in New Issue
Block a user