diff --git a/assets/images/portfolio_screen/bg.png b/assets/images/portfolio_screen/bg.png new file mode 100644 index 0000000..7fa1a98 Binary files /dev/null and b/assets/images/portfolio_screen/bg.png differ diff --git a/assets/images/portfolio_screen/clock.png b/assets/images/portfolio_screen/clock.png new file mode 100644 index 0000000..6bb8342 Binary files /dev/null and b/assets/images/portfolio_screen/clock.png differ diff --git a/assets/images/portfolio_screen/clock_off.png b/assets/images/portfolio_screen/clock_off.png new file mode 100644 index 0000000..3cbab85 Binary files /dev/null and b/assets/images/portfolio_screen/clock_off.png differ diff --git a/assets/images/portfolio_screen/detailsbg.png b/assets/images/portfolio_screen/detailsbg.png new file mode 100644 index 0000000..9ff1bcd Binary files /dev/null and b/assets/images/portfolio_screen/detailsbg.png differ diff --git a/lib/core/routes/route_name.dart b/lib/core/routes/route_name.dart index e1f07a5..5a286bd 100644 --- a/lib/core/routes/route_name.dart +++ b/lib/core/routes/route_name.dart @@ -20,4 +20,7 @@ class RouteName { // static const String mainScreen = 'mainScreen'; + + //Portfolio details + static const String porfolioDetails = 'porfolioDetails'; } diff --git a/lib/core/routes/routes.dart b/lib/core/routes/routes.dart index 8b19b23..4bb1c0a 100644 --- a/lib/core/routes/routes.dart +++ b/lib/core/routes/routes.dart @@ -3,6 +3,7 @@ import 'package:go_router/go_router.dart'; import 'package:tanami_app/core/routes/route_name.dart'; import 'package:tanami_app/features/MainScreens/MainScreen.dart'; +import 'package:tanami_app/features/MainScreens/Portfolio/presentation/pages/detailsScreen.dart'; import 'package:tanami_app/features/countrySelection/presentation/pages/choose_country_screen.dart'; import 'package:tanami_app/features/welcome/presentation/pages/weclome_screen.dart'; @@ -19,47 +20,55 @@ final goRouter = GoRouter( //errorBuilder: (context, state) => ErrorScreen(state.error), routes: [ GoRoute( - name: "splash", - path: RouteName.splashScreen, - builder: (context, state) { - return const SplashScreen(); - }, - // redirect: (context, state) { - // if (true) { - // return "/login"; - // } - // return "/"; - // }, - routes: [ - GoRoute( - name: RouteName.loginScreen, - path: RouteName.loginScreen, - builder: (context, state) { - return const LoginScreen(); - }, - ), - GoRoute( - name: RouteName.welcomeScreen, - path: RouteName.welcomeScreen, - builder: (context, state) { - return const WelcomeScreen(); - }, - ), - GoRoute( - name: RouteName.chooseCountryScreen, - path: RouteName.chooseCountryScreen, - builder: (context, state) { - return const ChooseCountryScreen(); - }, - ), - GoRoute( - name: RouteName.mainScreen, - path: RouteName.mainScreen, - builder: (context, state) { - return const MainScreen(); - }, - ), - ]), + name: "splash", + path: RouteName.splashScreen, + builder: (context, state) { + return const SplashScreen(); + }, + // redirect: (context, state) { + // if (true) { + // return "/login"; + // } + // return "/"; + // }, + routes: [ + GoRoute( + name: RouteName.loginScreen, + path: RouteName.loginScreen, + builder: (context, state) { + return const LoginScreen(); + }, + ), + GoRoute( + name: RouteName.welcomeScreen, + path: RouteName.welcomeScreen, + builder: (context, state) { + return const WelcomeScreen(); + }, + ), + GoRoute( + name: RouteName.chooseCountryScreen, + path: RouteName.chooseCountryScreen, + builder: (context, state) { + return const ChooseCountryScreen(); + }, + ), + GoRoute( + name: RouteName.mainScreen, + path: RouteName.mainScreen, + builder: (context, state) { + return const MainScreen(); + }, + ), + GoRoute( + name: RouteName.porfolioDetails, + path: RouteName.porfolioDetails, + builder: (context, state) { + return const DetailsScreen(); + }, + ), + ], + ), // GoRoute( // path: '/profile/:userId', diff --git a/lib/core/styles/app_text.dart b/lib/core/styles/app_text.dart index d13575e..3088294 100644 --- a/lib/core/styles/app_text.dart +++ b/lib/core/styles/app_text.dart @@ -36,6 +36,12 @@ class AppText { static const String qatarCountryText = "Qatar"; static const String saudiArabiaCountryText = "Saudi Arabia"; static const String uaeCountryText = "United Arab Emirates"; - static const String confirmSelectionText = "Confirm selection"; + + //Portfolio + static const String portfolio = "Portfolio Value: "; + static const String investmentamount = "Investment Amount"; + static const String currentval = "Current valuation"; + static const String totalreturn = "Total return"; + static const String disttodate = "Distributions to date"; } diff --git a/lib/features/MainScreens/MainScreen.dart b/lib/features/MainScreens/MainScreen.dart index a1d6e05..8e8a26e 100644 --- a/lib/features/MainScreens/MainScreen.dart +++ b/lib/features/MainScreens/MainScreen.dart @@ -25,6 +25,7 @@ class MainScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( + backgroundColor: Colors.white, body: currentTab[selectedIndex], bottomNavigationBar: bottomnavigationbar(selectedIndex), ); diff --git a/lib/features/MainScreens/Portfolio/presentation/pages/detailsScreen.dart b/lib/features/MainScreens/Portfolio/presentation/pages/detailsScreen.dart new file mode 100644 index 0000000..879a4eb --- /dev/null +++ b/lib/features/MainScreens/Portfolio/presentation/pages/detailsScreen.dart @@ -0,0 +1,313 @@ +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 DetailsScreen extends StatefulWidget { + const DetailsScreen({super.key}); + + @override + State createState() => _DetailsScreenState(); +} + +class _DetailsScreenState extends State { + @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: 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: 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: Image.asset( + 'assets/images/portfolio_screen/detailsbg.png', + fit: BoxFit.cover, + width: double.infinity, + alignment: Alignment.topCenter, + ), + ), + 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: 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: 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: 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: Color(0xFF535353), + fontSize: 14.sp, + fontWeight: FontWeight.w500, + ), + ), + Text( + '+ 20.0%', + style: GoogleFonts.dmSans( + color: Color(0xFF066123), + fontSize: 14.sp, + fontWeight: FontWeight.w700, + ), + ) + ], + ) + ], + ), + ), + ) + ], + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/features/MainScreens/Portfolio/presentation/pages/portfolioScreen.dart b/lib/features/MainScreens/Portfolio/presentation/pages/portfolioScreen.dart index c46f5dc..ef12c34 100644 --- a/lib/features/MainScreens/Portfolio/presentation/pages/portfolioScreen.dart +++ b/lib/features/MainScreens/Portfolio/presentation/pages/portfolioScreen.dart @@ -1,4 +1,9 @@ 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}); @@ -10,6 +15,324 @@ class PortfolioScreen extends StatefulWidget { class _PortfolioScreenState extends State { @override Widget build(BuildContext context) { - return Scaffold(body: Text('Portfolio'),); + 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: EdgeInsets.only(left: 30, top: 0, bottom: 15), + title: Opacity( + opacity: opacity, + child: Row( + children: [ + Text( + AppText.portfolio, + style: GoogleFonts.dmSans( + color: 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: 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: 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: 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: Color(0xFF004717), + fontSize: 12.sp, + fontWeight: FontWeight.w500, + ), + ) + ], + ), + Text( + (index == 2) ? 'Exited' : 'Pending', + style: GoogleFonts.dmSans( + color: (index == 2) + ? Color(0xFF8D8D8D) + : 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) + ? Color(0xFF8D8D8D) + : Color(0xFF535353), + fontSize: 14.sp, + fontWeight: FontWeight.w500, + ), + ), + Column( + crossAxisAlignment: + CrossAxisAlignment.end, + children: [ + Text( + 'SAR 100,000', + style: GoogleFonts.dmSans( + color: (index == 2) + ? Color(0xFF8D8D8D) + : Colors.black, + fontSize: 14.sp, + fontWeight: FontWeight.w700, + ), + ), + Text( + ' \$ 26,700', + style: GoogleFonts.dmSans( + color: (index == 2) + ? 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) + ? Color(0xFF8D8D8D) + : Color(0xFF535353), + fontSize: 14.sp, + fontWeight: FontWeight.w500, + ), + ), + Column( + crossAxisAlignment: + CrossAxisAlignment.end, + children: [ + Text( + 'SAR 100,000', + style: GoogleFonts.dmSans( + color: (index == 2) + ? Color(0xFF8D8D8D) + : Colors.black, + fontSize: 14.sp, + fontWeight: FontWeight.w700, + ), + ), + Text( + ' \$ 26,700', + style: GoogleFonts.dmSans( + color: (index == 2) + ? 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) + ? Color(0xFF8D8D8D) + : Color(0xFF535353), + fontSize: 14.sp, + fontWeight: FontWeight.w500, + ), + ), + Text( + (index == 2) ? '- 20.0%' : '+ 20.0%', + style: GoogleFonts.dmSans( + color: (index == 2) + ? Color(0xFFde9595) + : Color(0xFF066123), + fontSize: 14.sp, + fontWeight: FontWeight.w700, + ), + ) + ], + ) + ], + ), + ), + ) + ], + ), + ), + ), + ), + childCount: 3, + ), //SliverChildBuildDelegate + ), + ], + ), + ); } -} \ No newline at end of file +} diff --git a/pubspec.yaml b/pubspec.yaml index 699f049..fb8f726 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -95,3 +95,4 @@ flutter: - assets/images/country_flag/png/ - assets/images/bottom_bar/active/ - assets/images/bottom_bar/inactive/ + - assets/images/portfolio_screen/