added your tenders screen

This commit is contained in:
amirrezaghabeli
2025-08-05 19:18:47 +03:30
parent 9f6c458e15
commit 21d13ac072
24 changed files with 682 additions and 63 deletions
+7 -3
View File
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:tm_app/core/routes/app_routes.dart';
import '../../../core/constants/strings.dart';
import '../../core/constants/colors.dart';
@@ -10,6 +11,7 @@ class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
SizeConfig.init(context);
return SafeArea(
child: Scaffold(
backgroundColor: Colors.white,
@@ -36,7 +38,7 @@ class HomeScreen extends StatelessWidget {
// SizedBox(height: 32.0.h()),
_progressBarsRow(),
SizedBox(height: 32.0.h()),
_firstStatisticsRow(),
_firstStatisticsRow(context),
SizedBox(height: 8.0.h()),
_secondStatisticsRow(),
SizedBox(height: 32.0.h()),
@@ -104,7 +106,7 @@ class HomeScreen extends StatelessWidget {
);
}
Widget _firstStatisticsRow() {
Widget _firstStatisticsRow(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
@@ -124,7 +126,9 @@ class HomeScreen extends StatelessWidget {
amount: '03',
textColor: Color(0xFF24848E),
enableTap: true,
onTap: () {},
onTap: () {
YourTendersRouteData().push(context);
},
),
],
);
+114 -11
View File
@@ -1,4 +1,6 @@
import 'package:flutter/material.dart';
import 'package:tm_app/core/constants/strings.dart';
import 'package:tm_app/core/utils/size_config.dart';
import '../../core/constants/colors.dart';
@@ -7,17 +9,118 @@ class ProfileScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColors.backgroundColor,
appBar: AppBar(
title: const Text('Profile'),
backgroundColor: AppColors.grey10,
elevation: 0,
),
body: const Center(
child: Text(
'Profile Screen',
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
return SafeArea(
child: Scaffold(
backgroundColor: AppColors.backgroundColor,
appBar: PreferredSize(
preferredSize: Size.fromHeight(56.0.h()),
child: Container(
color: AppColors.backgroundColor,
padding: EdgeInsets.symmetric(horizontal: 24.0.w()),
height: 56.0.h(),
width: double.infinity,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
AppStrings.profile,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Color(0xFF222222),
),
),
Image.asset(
'assets/icons/tenderLogo.png',
width: 59.0.w(),
height: 28.0.h(),
fit: BoxFit.cover,
),
],
),
),
),
body: Padding(
padding: EdgeInsets.symmetric(
horizontal: 24.0.w(),
vertical: 16.0.h(),
),
child: Column(
children: [
SizedBox(height: 36.0.h()),
TitleDescription(
title: 'Company Name',
description: 'Telecom Solutions GmbH',
),
TitleDescription(
title: 'National ID',
description: '12345678901',
),
TitleDescription(
title: 'Registration No.',
description: 'DE-55667788',
),
TitleDescription(
title: 'Business Type',
description: 'Telecommunications',
),
TitleDescription(title: 'Founded', description: '2010'),
],
),
),
),
);
}
}
class TitleDescription extends StatelessWidget {
const TitleDescription({
required this.title,
required this.description,
super.key,
});
final String title;
final String description;
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.only(bottom: 24.0.h()),
child: SizedBox(
width: double.infinity,
height: 43.0.h(),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
title,
style: TextStyle(
fontSize: 16.0.sp(),
fontWeight: FontWeight.w400,
color: AppColors.grey60,
),
),
Text(
description,
style: TextStyle(
fontSize: 16.0.sp(),
fontWeight: FontWeight.w400,
color: AppColors.grey80,
),
),
],
),
Container(
width: double.infinity,
height: 1.0.h(),
color: AppColors.dividerColor,
),
],
),
),
);
+2 -1
View File
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:tm_app/core/constants/assets.dart';
import '../../core/utils/size_config.dart';
@@ -33,7 +34,7 @@ class _TenderBottomNavigationState extends State<TenderBottomNavigation> {
});
},
iconPath: 'assets/icons/home.svg',
activeIconPath: 'assets/icons/homeActive.svg',
activeIconPath: AssetsManager.homeActive,
),
_bottomNavigationItem(
text: 'Tenders',
@@ -1,13 +1,13 @@
import 'package:flutter/material.dart';
import '../../../core/constants/colors.dart';
import '../../../core/utils/size_config.dart';
import 'tab_item.dart';
import '../../core/constants/colors.dart';
import '../../core/utils/size_config.dart';
class MainTabBar extends StatefulWidget {
const MainTabBar({super.key, required this.controller});
const MainTabBar({required this.controller, required this.titles, super.key});
final TabController controller;
final List<String> titles;
@override
State<MainTabBar> createState() => _MainTabBarState();
@@ -41,22 +41,14 @@ class _MainTabBarState extends State<MainTabBar> {
],
),
controller: widget.controller,
tabs: [
TabItem(
title: 'New',
isActive: widget.controller.index == 0,
onTap: () {
widget.controller.animateTo(0);
},
),
TabItem(
title: 'Last',
isActive: widget.controller.index == 1,
onTap: () {
widget.controller.animateTo(1);
},
),
],
labelColor: AppColors.mainBlue,
unselectedLabelColor: AppColors.grey60,
labelStyle: TextStyle(fontSize: 16.0.sp(), fontWeight: FontWeight.w600),
unselectedLabelStyle: TextStyle(
fontSize: 16.0.sp(),
fontWeight: FontWeight.w600,
),
tabs: [Tab(text: widget.titles[0]), Tab(text: widget.titles[1])],
),
);
}
@@ -1,14 +1,14 @@
import 'package:flutter/material.dart';
import '../../../core/constants/colors.dart';
import '../../../core/utils/size_config.dart';
import '../../core/constants/colors.dart';
import '../../core/utils/size_config.dart';
class TabItem extends StatelessWidget {
const TabItem({
super.key,
required this.title,
required this.isActive,
required this.onTap,
super.key,
});
final String title;
+1 -1
View File
@@ -1,4 +1,4 @@
export 'last_tenders_tab.dart';
export 'main_tab_bar.dart';
export '../../shared/main_tab_bar.dart';
export 'tender_app_bar.dart';
export 'tender_card.dart';
@@ -0,0 +1,101 @@
import 'package:flutter/material.dart';
class TenderModel {
final String date;
final String title;
final String description;
final String location;
final String countryFlag;
final String status;
final String projectStatus;
final Color? backgroundColor;
final Color? borderColor;
final String? statusIcon;
final Color? statusCardColor;
TenderModel({
required this.date,
required this.title,
required this.description,
required this.location,
required this.countryFlag,
required this.status,
required this.projectStatus,
this.backgroundColor,
this.borderColor,
this.statusIcon,
this.statusCardColor,
});
}
List<TenderModel> approvedTenders = [
TenderModel(
date: '2025-01-01',
title:
'Lorem ipsum dolor sit amet consectetur. Sed mi tortor eu purus senectus.',
description:
'Lorem ipsum dolor sit amet consectetur. Volutpat velit tincidunt amet diam. Placerat congue ut Sed facilisis faucibus porttitor. Proin suspendisse eu euismod sit lorem quis. ',
location: 'Stockholm, Sweden',
countryFlag: 'assets/icons/SE.png',
status: 'Completed',
projectStatus: 'Self Control',
),
TenderModel(
date: '2025-01-01',
title:
'Lorem ipsum dolor sit amet consectetur. Sed mi tortor eu purus senectus.',
description:
'Lorem ipsum dolor sit amet consectetur. Volutpat velit tincidunt amet diam. Placerat congue ut Sed facilisis faucibus porttitor. Proin suspendisse eu euismod sit lorem quis. ',
location: 'Stockholm, Sweden',
countryFlag: 'assets/icons/SE.png',
status: 'Completed',
projectStatus: 'Patner Ship',
),
TenderModel(
date: '2025-01-01',
title:
'Lorem ipsum dolor sit amet consectetur. Sed mi tortor eu purus senectus.',
description:
'Lorem ipsum dolor sit amet consectetur. Volutpat velit tincidunt amet diam. Placerat congue ut Sed facilisis faucibus porttitor. Proin suspendisse eu euismod sit lorem quis. ',
location: 'Stockholm, Sweden',
countryFlag: 'assets/icons/SE.png',
status: 'Completed',
projectStatus: 'Self Control',
),
];
List<TenderModel> tendersSubmitted = [
TenderModel(
date: '2025-01-01',
title:
'Lorem ipsum dolor sit amet consectetur. Sed mi tortor eu purus senectus.',
description:
'Lorem ipsum dolor sit amet consectetur. Volutpat velit tincidunt amet diam. Placerat congue ut Sed facilisis faucibus porttitor. Proin suspendisse eu euismod sit lorem quis. ',
location: 'Stockholm, Sweden',
countryFlag: 'assets/icons/SE.png',
status: 'Won',
projectStatus: 'Self Control',
),
TenderModel(
date: '2025-01-01',
title:
'Lorem ipsum dolor sit amet consectetur. Sed mi tortor eu purus senectus.',
description:
'Lorem ipsum dolor sit amet consectetur. Volutpat velit tincidunt amet diam. Placerat congue ut Sed facilisis faucibus porttitor. Proin suspendisse eu euismod sit lorem quis. ',
location: 'Stockholm, Sweden',
countryFlag: 'assets/icons/SE.png',
status: 'Reject',
projectStatus: 'Patner Ship',
),
TenderModel(
date: '2025-01-01',
title:
'Lorem ipsum dolor sit amet consectetur. Sed mi tortor eu purus senectus.',
description:
'Lorem ipsum dolor sit amet consectetur. Volutpat velit tincidunt amet diam. Placerat congue ut Sed facilisis faucibus porttitor. Proin suspendisse eu euismod sit lorem quis. ',
location: 'Stockholm, Sweden',
countryFlag: 'assets/icons/SE.png',
status: 'Won',
projectStatus: 'Self Control',
),
];
@@ -0,0 +1,31 @@
import 'package:flutter/material.dart';
import 'package:tm_app/core/utils/size_config.dart';
import 'package:tm_app/views/your_tenders/model/tender_model.dart';
import 'package:tm_app/views/your_tenders/widgets/tender_card.dart';
class ApprovedTenders extends StatelessWidget {
const ApprovedTenders({super.key});
@override
Widget build(BuildContext context) {
return ListView.builder(
padding: EdgeInsets.only(top: 20.0.h()),
itemCount: approvedTenders.length,
itemBuilder: (context, index) {
final tender = approvedTenders[index];
return TenderCard(
date: tender.date,
title: tender.title,
description: tender.description,
location: tender.location,
countryFlag: tender.countryFlag,
status: tender.status,
projectStatus: tender.projectStatus,
backgroundColor: tender.backgroundColor,
borderColor: tender.borderColor,
statusIcon: tender.statusIcon,
);
},
);
}
}
@@ -0,0 +1,190 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import '../../../core/constants/assets.dart';
import '../../../core/constants/colors.dart';
import '../../../core/utils/size_config.dart';
class TenderCard extends StatelessWidget {
final String date;
final String title;
final String description;
final String location;
final String countryFlag;
final String status;
final String projectStatus;
final Color? backgroundColor;
final Color? borderColor;
final String? statusIcon;
final Color? statusCardColor;
final Color? statusTextColor;
const TenderCard({
required this.date,
required this.title,
required this.description,
required this.location,
this.countryFlag = 'assets/icons/SE.png',
this.status = 'Completed',
this.projectStatus = 'Self Control',
this.backgroundColor,
this.borderColor,
this.statusIcon,
this.statusCardColor,
this.statusTextColor,
super.key,
});
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
margin: EdgeInsets.only(
left: 24.0.w(),
right: 24.0.w(),
bottom: 24.0.h(),
),
decoration: BoxDecoration(
color: backgroundColor ?? AppColors.grey0,
borderRadius: BorderRadius.circular(12),
border: Border.all(color: borderColor ?? AppColors.borderColor),
),
child: Padding(
padding: EdgeInsets.all(16.0.w()),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Top section with date and status
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// Date
Text(
date,
style: TextStyle(
color: AppColors.grey60,
fontSize: 12.0.sp(),
fontWeight: FontWeight.w400,
),
),
// Completed status badge
Container(
padding: EdgeInsets.symmetric(
horizontal: 16.0.w(),
vertical: 4.0.h(),
),
decoration: BoxDecoration(
color: statusCardColor ?? AppColors.gren20,
borderRadius: BorderRadius.circular(8),
),
child: Row(
children: [
if (statusIcon != null)
SvgPicture.asset(
statusIcon!,
width: 16.0.w(),
height: 16.0.h(),
),
SizedBox(width: 4.0.w()),
Text(
status,
style: TextStyle(
color: statusTextColor ?? AppColors.gren30,
fontSize: 12.0.sp(),
fontWeight: FontWeight.w500,
),
),
],
),
),
],
),
SizedBox(height: 12.0.h()),
// Title
Text(
title,
style: TextStyle(
color: AppColors.grey80,
fontSize: 16.0.sp(),
fontWeight: FontWeight.w600,
height: 1.3,
),
),
SizedBox(height: 8.0.h()),
// Description
Text(
description,
style: TextStyle(
color: AppColors.grey70,
fontSize: 14.0.sp(),
fontWeight: FontWeight.w400,
height: 1.4,
),
maxLines: 3,
overflow: TextOverflow.ellipsis,
),
SizedBox(height: 24.0.h()),
// Bottom section with location and action button
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// Location with flag
Expanded(
child: Row(
children: [
SvgPicture.asset(
AssetsManager.location,
width: 16.0.w(),
height: 16.0.h(),
),
SizedBox(width: 4.0.w()),
Text(
location,
style: TextStyle(
color: AppColors.grey80,
fontSize: 12.0.sp(),
fontWeight: FontWeight.w400,
),
),
SizedBox(width: 8.0.w()),
// Country flag
Image.asset(
countryFlag,
width: 32.0.w(),
height: 21.0.h(),
),
],
),
),
// Self Control button
Container(
padding: EdgeInsets.symmetric(
horizontal: 16.0.w(),
vertical: 4.0.h(),
),
decoration: BoxDecoration(
color: AppColors.grey20,
borderRadius: BorderRadius.circular(88),
border: Border.all(color: AppColors.grey40),
),
child: Text(
projectStatus,
style: TextStyle(
color: AppColors.grey60,
fontSize: 12.0.sp(),
fontWeight: FontWeight.w500,
),
),
),
],
),
],
),
),
);
}
}
@@ -0,0 +1,45 @@
import 'package:flutter/material.dart';
import 'package:tm_app/core/constants/assets.dart';
import 'package:tm_app/core/constants/colors.dart';
import 'package:tm_app/core/utils/size_config.dart';
import 'package:tm_app/views/your_tenders/model/tender_model.dart';
import 'package:tm_app/views/your_tenders/widgets/tender_card.dart';
class TendersSubmitted extends StatelessWidget {
const TendersSubmitted({super.key});
@override
Widget build(BuildContext context) {
return ListView.builder(
padding: EdgeInsets.only(top: 20.0.h()),
itemCount: tendersSubmitted.length,
itemBuilder: (context, index) {
final tender = tendersSubmitted[index];
return TenderCard(
date: tender.date,
title: tender.title,
description: tender.description,
location: tender.location,
countryFlag: tender.countryFlag,
status: tender.status,
projectStatus: tender.projectStatus,
backgroundColor:
tender.status == 'Won'
? AppColors.gren0
: AppColors.red0.withValues(alpha: 0.2),
borderColor:
tender.status == 'Won' ? AppColors.green10 : AppColors.red0,
statusIcon:
tender.status == 'Won'
? AssetsManager.tickCircle
: AssetsManager.closeCircle,
statusCardColor:
tender.status == 'Won' ? AppColors.gren20 : AppColors.red0,
statusTextColor:
tender.status == 'Won' ? AppColors.gren30 : AppColors.red10,
);
},
);
}
}
@@ -0,0 +1,83 @@
import 'package:flutter/material.dart';
import 'package:tm_app/core/constants/colors.dart';
import 'package:tm_app/core/constants/strings.dart';
import 'package:tm_app/core/utils/size_config.dart';
import 'package:tm_app/views/your_tenders/widgets/approved_tenders.dart';
import 'package:tm_app/views/your_tenders/widgets/tenders_submitted.dart';
import '../shared/main_tab_bar.dart';
class YourTendersScreen extends StatefulWidget {
const YourTendersScreen({super.key});
@override
State<YourTendersScreen> createState() => _YourTendersScreenState();
}
class _YourTendersScreenState extends State<YourTendersScreen>
with SingleTickerProviderStateMixin {
late TabController controller;
@override
void initState() {
super.initState();
controller = TabController(length: 2, vsync: this);
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
backgroundColor: AppColors.backgroundColor,
appBar: PreferredSize(
preferredSize: Size.fromHeight(56.0.h()),
child: Container(
color: AppColors.backgroundColor,
padding: EdgeInsets.symmetric(horizontal: 24.0.w()),
height: 56.0.h(),
width: double.infinity,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
AppStrings.yourTenders,
style: TextStyle(
fontSize: 20.0.sp(),
fontWeight: FontWeight.bold,
color: Color(0xFF222222),
),
),
Image.asset(
'assets/icons/tenderLogo.png',
width: 59.0.w(),
height: 28.0.h(),
fit: BoxFit.cover,
),
],
),
),
),
body: Column(
children: [
MainTabBar(
controller: controller,
titles: ['Approved tenders', 'Tenders submitted'],
),
Expanded(
child: TabBarView(
controller: controller,
children: [ApprovedTenders(), TendersSubmitted()],
),
),
],
),
),
);
}
}