Merge pull request 'refactor codes' (#34) from code_refactor into main
Reviewed-on: https://repo.ravanertebat.com/TM/tm_app/pulls/34
This commit is contained in:
@@ -37,6 +37,10 @@ class AppStrings {
|
|||||||
//Tenders
|
//Tenders
|
||||||
static const String tendersTitle = 'Tenders';
|
static const String tendersTitle = 'Tenders';
|
||||||
static const String tenderSeeMore = 'See More';
|
static const String tenderSeeMore = 'See More';
|
||||||
|
static const String reject = 'Reject';
|
||||||
|
static const String submit = 'Submit';
|
||||||
|
static const String dislike = 'Dislike';
|
||||||
|
static const String like = 'Like';
|
||||||
|
|
||||||
//profile
|
//profile
|
||||||
static const String profile = 'Profile';
|
static const String profile = 'Profile';
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ class MobileShellPage extends StatelessWidget {
|
|||||||
height: 72.0.h(),
|
height: 72.0.h(),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: AppColors.grey10,
|
color: AppColors.grey10,
|
||||||
border: Border.fromBorderSide(BorderSide(color: AppColors.grey30)),
|
border: Border(top: BorderSide(color: AppColors.grey30)),
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ const String mockYourTendersData = '''
|
|||||||
"location": "Sweden",
|
"location": "Sweden",
|
||||||
"countryFlag": "assets/icons/SE.png",
|
"countryFlag": "assets/icons/SE.png",
|
||||||
"status": "Completed",
|
"status": "Completed",
|
||||||
"projectStatus": "Self Control"
|
"projectStatus": "Self Apply"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date": "2025-05-21",
|
"date": "2025-05-21",
|
||||||
@@ -26,7 +26,7 @@ const String mockYourTendersData = '''
|
|||||||
"location": "Italy",
|
"location": "Italy",
|
||||||
"countryFlag": "assets/icons/SE.png",
|
"countryFlag": "assets/icons/SE.png",
|
||||||
"status": "Completed",
|
"status": "Completed",
|
||||||
"projectStatus": "Self Control"
|
"projectStatus": "Self Apply"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"tendersSubmitted": [
|
"tendersSubmitted": [
|
||||||
@@ -37,7 +37,7 @@ const String mockYourTendersData = '''
|
|||||||
"location": "Sweden",
|
"location": "Sweden",
|
||||||
"countryFlag": "assets/icons/SE.png",
|
"countryFlag": "assets/icons/SE.png",
|
||||||
"status": "Won",
|
"status": "Won",
|
||||||
"projectStatus": "Self Control"
|
"projectStatus": "Self Apply"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date": "2025-05-21",
|
"date": "2025-05-21",
|
||||||
@@ -55,7 +55,7 @@ const String mockYourTendersData = '''
|
|||||||
"location": "Italy",
|
"location": "Italy",
|
||||||
"countryFlag": "assets/icons/SE.png",
|
"countryFlag": "assets/icons/SE.png",
|
||||||
"status": "Won",
|
"status": "Won",
|
||||||
"projectStatus": "Self Control"
|
"projectStatus": "Self Apply"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ final String tendersMockData = '''
|
|||||||
"deadline": "2025-06-15",
|
"deadline": "2025-06-15",
|
||||||
"location": "Sweden",
|
"location": "Sweden",
|
||||||
"type": "Self Apply",
|
"type": "Self Apply",
|
||||||
"profile_match": 0.75,
|
"profile_match": 75,
|
||||||
"liked": false,
|
"liked": false,
|
||||||
"disliked": false,
|
"disliked": false,
|
||||||
"rejected": false,
|
"rejected": false,
|
||||||
@@ -23,7 +23,7 @@ final String tendersMockData = '''
|
|||||||
"deadline": "2025-07-20",
|
"deadline": "2025-07-20",
|
||||||
"location": "Norway",
|
"location": "Norway",
|
||||||
"type": "Invitation",
|
"type": "Invitation",
|
||||||
"profile_match": 0.85,
|
"profile_match": 85,
|
||||||
"liked": false,
|
"liked": false,
|
||||||
"disliked": false,
|
"disliked": false,
|
||||||
"rejected": false,
|
"rejected": false,
|
||||||
@@ -37,7 +37,7 @@ final String tendersMockData = '''
|
|||||||
"deadline": "2025-08-10",
|
"deadline": "2025-08-10",
|
||||||
"location": "Finland",
|
"location": "Finland",
|
||||||
"type": "Self Apply",
|
"type": "Self Apply",
|
||||||
"profile_match": 0.65,
|
"profile_match": 65,
|
||||||
"liked": false,
|
"liked": false,
|
||||||
"disliked": false,
|
"disliked": false,
|
||||||
"rejected": false,
|
"rejected": false,
|
||||||
@@ -51,7 +51,7 @@ final String tendersMockData = '''
|
|||||||
"deadline": "2025-09-05",
|
"deadline": "2025-09-05",
|
||||||
"location": "Denmark",
|
"location": "Denmark",
|
||||||
"type": "Invitation",
|
"type": "Invitation",
|
||||||
"profile_match": 0.90,
|
"profile_match": 90,
|
||||||
"liked": false,
|
"liked": false,
|
||||||
"disliked": false,
|
"disliked": false,
|
||||||
"rejected": false,
|
"rejected": false,
|
||||||
@@ -65,7 +65,7 @@ final String tendersMockData = '''
|
|||||||
"deadline": "2025-10-12",
|
"deadline": "2025-10-12",
|
||||||
"location": "Iceland",
|
"location": "Iceland",
|
||||||
"type": "Self Apply",
|
"type": "Self Apply",
|
||||||
"profile_match": 0.70,
|
"profile_match": 70,
|
||||||
"liked": false,
|
"liked": false,
|
||||||
"disliked": false,
|
"disliked": false,
|
||||||
"rejected": false,
|
"rejected": false,
|
||||||
|
|||||||
@@ -28,35 +28,7 @@ class MobileHomePage extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (homeViewModel.errorMessage != null) {
|
if (homeViewModel.errorMessage != null) {
|
||||||
return Center(
|
return Center(child: Text(homeViewModel.errorMessage!));
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(24.0),
|
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
const Icon(
|
|
||||||
Icons.error_outline,
|
|
||||||
size: 64,
|
|
||||||
color: Colors.red,
|
|
||||||
),
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
Text(
|
|
||||||
homeViewModel.errorMessage!,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
color: Colors.grey.shade700,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 24),
|
|
||||||
ElevatedButton(
|
|
||||||
onPressed: () => homeViewModel.getHome(),
|
|
||||||
child: const Text('Try Again'),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return SingleChildScrollView(
|
return SingleChildScrollView(
|
||||||
|
|||||||
@@ -30,8 +30,9 @@ class _LoginDesktopPageState extends State<LoginDesktopPage> {
|
|||||||
if (viewModel.loggedInUser != null) {
|
if (viewModel.loggedInUser != null) {
|
||||||
HomeRouteData().go(context);
|
HomeRouteData().go(context);
|
||||||
} else if (viewModel.errorMessage != null) {
|
} else if (viewModel.errorMessage != null) {
|
||||||
ScaffoldMessenger.of(context)
|
ScaffoldMessenger.of(
|
||||||
.showSnackBar(SnackBar(content: Text(viewModel.errorMessage!)));
|
context,
|
||||||
|
).showSnackBar(SnackBar(content: Text(viewModel.errorMessage!)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,51 +12,43 @@ class MobileProfilePage extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SafeArea(
|
return Scaffold(
|
||||||
child: Scaffold(
|
backgroundColor: AppColors.backgroundColor,
|
||||||
backgroundColor: AppColors.backgroundColor,
|
appBar: tenderMobileAppBar(title: AppStrings.profile),
|
||||||
appBar: tenderMobileAppBar(title: AppStrings.profile),
|
body: Padding(
|
||||||
body: Padding(
|
padding: EdgeInsets.symmetric(horizontal: 24.0.w(), vertical: 16.0.h()),
|
||||||
padding: EdgeInsets.symmetric(
|
child: Column(
|
||||||
horizontal: 24.0.w(),
|
children: [
|
||||||
vertical: 16.0.h(),
|
SizedBox(height: 36.0.h()),
|
||||||
),
|
TitleDescription(
|
||||||
child: Column(
|
title: 'Company Name',
|
||||||
children: [
|
description: 'Telecom Solutions GmbH',
|
||||||
SizedBox(height: 36.0.h()),
|
),
|
||||||
TitleDescription(
|
TitleDescription(title: 'National ID', description: '12345678901'),
|
||||||
title: 'Company Name',
|
TitleDescription(
|
||||||
description: 'Telecom Solutions GmbH',
|
title: 'Registration No.',
|
||||||
|
description: 'DE-55667788',
|
||||||
|
),
|
||||||
|
TitleDescription(
|
||||||
|
title: 'Business Type',
|
||||||
|
description: 'Telecommunications',
|
||||||
|
),
|
||||||
|
TitleDescription(title: 'Founded', description: '2010'),
|
||||||
|
SizedBox(height: 24.0.h()),
|
||||||
|
// Theme Toggle
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 16.0.w(),
|
||||||
|
vertical: 12.0.h(),
|
||||||
),
|
),
|
||||||
TitleDescription(
|
decoration: BoxDecoration(
|
||||||
title: 'National ID',
|
color: AppColors.surfaceColor,
|
||||||
description: '12345678901',
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
border: Border.all(color: AppColors.borderColor),
|
||||||
),
|
),
|
||||||
TitleDescription(
|
child: const ThemeToggle(),
|
||||||
title: 'Registration No.',
|
),
|
||||||
description: 'DE-55667788',
|
],
|
||||||
),
|
|
||||||
TitleDescription(
|
|
||||||
title: 'Business Type',
|
|
||||||
description: 'Telecommunications',
|
|
||||||
),
|
|
||||||
TitleDescription(title: 'Founded', description: '2010'),
|
|
||||||
SizedBox(height: 24.0.h()),
|
|
||||||
// Theme Toggle
|
|
||||||
Container(
|
|
||||||
padding: EdgeInsets.symmetric(
|
|
||||||
horizontal: 16.0.w(),
|
|
||||||
vertical: 12.0.h(),
|
|
||||||
),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColors.surfaceColor,
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
border: Border.all(color: AppColors.borderColor),
|
|
||||||
),
|
|
||||||
child: const ThemeToggle(),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,37 +3,6 @@ import 'package:tm_app/core/constants/assets.dart';
|
|||||||
import 'package:tm_app/core/theme/colors.dart';
|
import 'package:tm_app/core/theme/colors.dart';
|
||||||
import 'package:tm_app/core/utils/size_config.dart';
|
import 'package:tm_app/core/utils/size_config.dart';
|
||||||
|
|
||||||
// PreferredSize tenderMobileAppBar({required String title}) {
|
|
||||||
// return PreferredSize(
|
|
||||||
// preferredSize: Size.fromHeight(kToolbarHeight.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(
|
|
||||||
// title,
|
|
||||||
// style: TextStyle(
|
|
||||||
// fontSize: 20,
|
|
||||||
// fontWeight: FontWeight.bold,
|
|
||||||
// color: AppColors.grey70,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// Image.asset(
|
|
||||||
// 'assets/icons/tenderLogo.png',
|
|
||||||
// width: 59.0.w(),
|
|
||||||
// height: 28.0.h(),
|
|
||||||
// fit: BoxFit.cover,
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
PreferredSizeWidget tenderMobileAppBar({required String title}) {
|
PreferredSizeWidget tenderMobileAppBar({required String title}) {
|
||||||
return PreferredSize(
|
return PreferredSize(
|
||||||
preferredSize: const Size.fromHeight(56),
|
preferredSize: const Size.fromHeight(56),
|
||||||
@@ -65,39 +34,3 @@ PreferredSizeWidget tenderMobileAppBar({required String title}) {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// PreferredSize appBar({required String title, required BuildContext context}) {
|
|
||||||
// return PreferredSize(
|
|
||||||
// preferredSize: Size.fromHeight(kToolbarHeight.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: [
|
|
||||||
// GestureDetector(
|
|
||||||
// onTap: () {
|
|
||||||
// Navigator.pop(context);
|
|
||||||
// },
|
|
||||||
// child: SvgPicture.asset(
|
|
||||||
// AssetsManager.arrowLeft,
|
|
||||||
// width: 24.0.w(),
|
|
||||||
// height: 24.0.h(),
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// SizedBox(width: 2.0.w()),
|
|
||||||
// Text(
|
|
||||||
// title,
|
|
||||||
// style: TextStyle(
|
|
||||||
// fontSize: 20,
|
|
||||||
// fontWeight: FontWeight.bold,
|
|
||||||
// color: AppColors.grey70,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|||||||
@@ -13,29 +13,27 @@ class MobileTendersPage extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SafeArea(
|
return Scaffold(
|
||||||
child: Scaffold(
|
backgroundColor: AppColors.backgroundColor,
|
||||||
backgroundColor: AppColors.backgroundColor,
|
appBar: tenderMobileAppBar(title: AppStrings.tendersTitle),
|
||||||
appBar: tenderMobileAppBar(title: AppStrings.tendersTitle),
|
body: Consumer<TendersViewModel>(
|
||||||
body: Consumer<TendersViewModel>(
|
builder: (context, viewModel, child) {
|
||||||
builder: (context, viewModel, child) {
|
if (viewModel.isLoading) {
|
||||||
if (viewModel.isLoading) {
|
return Center(
|
||||||
return Center(
|
child: CircularProgressIndicator(color: AppColors.jellyBean),
|
||||||
child: CircularProgressIndicator(color: AppColors.jellyBean),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (viewModel.errorMessage != null) {
|
|
||||||
return Center(child: Text(viewModel.errorMessage!));
|
|
||||||
}
|
|
||||||
|
|
||||||
return Padding(
|
|
||||||
padding: EdgeInsets.symmetric(vertical: 24.0.h()),
|
|
||||||
child: MainTendersSlider(
|
|
||||||
tenders: viewModel.tendersResponse?.tenders ?? [],
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
},
|
}
|
||||||
),
|
if (viewModel.errorMessage != null) {
|
||||||
|
return Center(child: Text(viewModel.errorMessage!));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Padding(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 24.0.h()),
|
||||||
|
child: MainTendersSlider(
|
||||||
|
tenders: viewModel.tendersResponse?.tenders ?? [],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,84 +59,93 @@ class _MainTendersSliderState extends State<MainTendersSlider> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Stack(
|
return SingleChildScrollView(
|
||||||
children: [
|
child: Stack(children: [_tendersPageView(), _nextPreviousArrows()]),
|
||||||
SizedBox(
|
);
|
||||||
width: double.infinity,
|
}
|
||||||
height: 717.0.h(),
|
|
||||||
child: PageView.builder(
|
Widget _tendersPageView() {
|
||||||
controller: pageController,
|
return SizedBox(
|
||||||
scrollDirection: Axis.horizontal,
|
width: double.infinity,
|
||||||
itemCount: widget.tenders.length,
|
height: 719.0.h(),
|
||||||
onPageChanged: (index) {
|
child: PageView.builder(
|
||||||
setState(() {
|
controller: pageController,
|
||||||
currentPage = index + 1;
|
scrollDirection: Axis.horizontal,
|
||||||
});
|
itemCount: widget.tenders.length,
|
||||||
},
|
onPageChanged: (index) {
|
||||||
itemBuilder: (context, index) {
|
setState(() {
|
||||||
final tender = widget.tenders[index];
|
currentPage = index + 1;
|
||||||
return TenderCard(tender: tender, isDesktop: widget.isDesktop);
|
});
|
||||||
},
|
},
|
||||||
),
|
itemBuilder: (context, index) {
|
||||||
|
final tender = widget.tenders[index];
|
||||||
|
return TenderCard(tender: tender, isDesktop: widget.isDesktop);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _nextPreviousArrows() {
|
||||||
|
return Positioned(
|
||||||
|
top: 607.0.h(),
|
||||||
|
bottom: 52.0.h(),
|
||||||
|
left: 9.0.w(),
|
||||||
|
right: 9.0.w(),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [_leftArrowButton(), _pageNumberText(), _rightArrowButton()],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _leftArrowButton() {
|
||||||
|
return InkWell(
|
||||||
|
borderRadius: BorderRadius.circular(100),
|
||||||
|
onTap: _goToPreviousPage,
|
||||||
|
child: Container(
|
||||||
|
width: 32.0.w(),
|
||||||
|
height: 32.0.w(),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
border: Border.all(color: AppColors.iconColor, width: 1.5),
|
||||||
),
|
),
|
||||||
Positioned(
|
alignment: Alignment.center,
|
||||||
top: 607.0.h(),
|
child: SvgPicture.asset(
|
||||||
bottom: 52.0.h(),
|
AssetsManager.arrowLeftSmall,
|
||||||
left: 9.0.w(),
|
colorFilter: ColorFilter.mode(AppColors.iconColor, BlendMode.srcATop),
|
||||||
right: 9.0.w(),
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
GestureDetector(
|
|
||||||
onTap: _goToPreviousPage,
|
|
||||||
child: Container(
|
|
||||||
width: 32.0.w(),
|
|
||||||
height: 32.0.w(),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
border: Border.all(color: AppColors.iconColor, width: 1.5),
|
|
||||||
),
|
|
||||||
alignment: Alignment.center,
|
|
||||||
child: SvgPicture.asset(
|
|
||||||
AssetsManager.arrowLeftSmall,
|
|
||||||
colorFilter: ColorFilter.mode(
|
|
||||||
AppColors.iconColor,
|
|
||||||
BlendMode.srcATop,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
'$currentPage/${widget.tenders.length}',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14.0.sp(),
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: AppColors.grey,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
GestureDetector(
|
|
||||||
onTap: _goToNextPage,
|
|
||||||
child: Container(
|
|
||||||
width: 32.0.w(),
|
|
||||||
height: 32.0.w(),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
border: Border.all(color: AppColors.iconColor, width: 1.5),
|
|
||||||
),
|
|
||||||
alignment: Alignment.center,
|
|
||||||
child: SvgPicture.asset(
|
|
||||||
AssetsManager.arrowRightSmall,
|
|
||||||
colorFilter: ColorFilter.mode(
|
|
||||||
AppColors.iconColor,
|
|
||||||
BlendMode.srcATop,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _pageNumberText() {
|
||||||
|
return Text(
|
||||||
|
'$currentPage/${widget.tenders.length}',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.0.sp(),
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: AppColors.grey,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _rightArrowButton() {
|
||||||
|
return InkWell(
|
||||||
|
borderRadius: BorderRadius.circular(100),
|
||||||
|
onTap: _goToNextPage,
|
||||||
|
child: Container(
|
||||||
|
width: 32.0.w(),
|
||||||
|
height: 32.0.w(),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
border: Border.all(color: AppColors.iconColor, width: 1.5),
|
||||||
|
),
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
AssetsManager.arrowRightSmall,
|
||||||
|
colorFilter: ColorFilter.mode(AppColors.iconColor, BlendMode.srcATop),
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,214 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_svg/svg.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:tm_app/data/services/model/home/tender/tender_model.dart';
|
|
||||||
import 'package:tm_app/view_models/tenders_view_model.dart';
|
|
||||||
|
|
||||||
import '../../../core/constants/assets.dart';
|
|
||||||
import '../../../core/theme/colors.dart';
|
|
||||||
import '../../../core/utils/size_config.dart';
|
|
||||||
|
|
||||||
class TenderActionButtons extends StatelessWidget {
|
|
||||||
final TenderModel tender;
|
|
||||||
final bool isDesktop;
|
|
||||||
|
|
||||||
const TenderActionButtons({
|
|
||||||
required this.tender,
|
|
||||||
this.isDesktop = false,
|
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final viewModel = context.watch<TendersViewModel>();
|
|
||||||
return Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
SizedBox(width: 16.0.w()),
|
|
||||||
|
|
||||||
// Dislike button
|
|
||||||
Tooltip(
|
|
||||||
message: 'Dislike',
|
|
||||||
child: InkWell(
|
|
||||||
splashColor: Colors.transparent,
|
|
||||||
onTap: () {
|
|
||||||
viewModel.toggleDislike(tender);
|
|
||||||
},
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
SvgPicture.asset(
|
|
||||||
width: 32.0.w(),
|
|
||||||
height: 32.0.w(),
|
|
||||||
fit: BoxFit.cover,
|
|
||||||
AssetsManager.dislike,
|
|
||||||
colorFilter: ColorFilter.mode(
|
|
||||||
tender.disliked ?? false
|
|
||||||
? AppColors.errorColor
|
|
||||||
: AppColors.grey50,
|
|
||||||
BlendMode.srcATop,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 8.0.h()),
|
|
||||||
if (!isDesktop)
|
|
||||||
Text(
|
|
||||||
'Dislike',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 12.0.sp(),
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
color:
|
|
||||||
tender.disliked ?? false
|
|
||||||
? AppColors.errorColor
|
|
||||||
: AppColors.grey50,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(width: 32.0.w()),
|
|
||||||
//reject button
|
|
||||||
Tooltip(
|
|
||||||
message: 'Reject',
|
|
||||||
child: InkWell(
|
|
||||||
splashColor: Colors.transparent,
|
|
||||||
onTap: () {
|
|
||||||
viewModel.toggleReject(tender);
|
|
||||||
},
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
width: 32.0.w(),
|
|
||||||
height: 32.0.w(),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
border: Border.all(
|
|
||||||
color:
|
|
||||||
tender.rejected ?? false
|
|
||||||
? AppColors.errorColor
|
|
||||||
: AppColors.grey60,
|
|
||||||
width: 1.5.w(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
alignment: Alignment.center,
|
|
||||||
child: Icon(
|
|
||||||
Icons.close,
|
|
||||||
color:
|
|
||||||
tender.rejected ?? false
|
|
||||||
? AppColors.errorColor
|
|
||||||
: AppColors.grey60,
|
|
||||||
size: 16,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 8.0.h()),
|
|
||||||
if (!isDesktop)
|
|
||||||
Text(
|
|
||||||
'Reject',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 12.0.sp(),
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
color:
|
|
||||||
tender.rejected ?? false
|
|
||||||
? AppColors.errorColor
|
|
||||||
: AppColors.grey60,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(width: 32.0.w()),
|
|
||||||
//submit button
|
|
||||||
Tooltip(
|
|
||||||
message: 'Submit',
|
|
||||||
child: InkWell(
|
|
||||||
splashColor: Colors.transparent,
|
|
||||||
onTap: () {
|
|
||||||
viewModel.toggleSubmit(tender);
|
|
||||||
},
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
width: 32.0.w(),
|
|
||||||
height: 32.0.w(),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
border: Border.all(
|
|
||||||
color:
|
|
||||||
tender.submitted ?? false
|
|
||||||
? AppColors.successColor
|
|
||||||
: AppColors.grey60,
|
|
||||||
width: 1.5.w(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
alignment: Alignment.center,
|
|
||||||
child: SvgPicture.asset(
|
|
||||||
AssetsManager.tick,
|
|
||||||
colorFilter: ColorFilter.mode(
|
|
||||||
tender.submitted ?? false
|
|
||||||
? AppColors.successColor
|
|
||||||
: AppColors.grey60,
|
|
||||||
BlendMode.srcATop,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 8.0.h()),
|
|
||||||
if (!isDesktop)
|
|
||||||
Text(
|
|
||||||
'Submit',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 12.0.sp(),
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
color:
|
|
||||||
tender.submitted ?? false
|
|
||||||
? AppColors.successColor
|
|
||||||
: AppColors.grey60,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(width: 32.0.w()),
|
|
||||||
// Like button
|
|
||||||
Tooltip(
|
|
||||||
message: 'Like',
|
|
||||||
child: InkWell(
|
|
||||||
splashColor: Colors.transparent,
|
|
||||||
onTap: () {
|
|
||||||
viewModel.toggleLike(tender);
|
|
||||||
},
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
SvgPicture.asset(
|
|
||||||
width: 32.0.w(),
|
|
||||||
height: 32.0.w(),
|
|
||||||
fit: BoxFit.cover,
|
|
||||||
AssetsManager.like,
|
|
||||||
colorFilter: ColorFilter.mode(
|
|
||||||
tender.liked ?? false
|
|
||||||
? AppColors.successColor
|
|
||||||
: AppColors.grey50,
|
|
||||||
BlendMode.srcATop,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 8.0.h()),
|
|
||||||
if (!isDesktop)
|
|
||||||
Text(
|
|
||||||
'Like',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 12.0.sp(),
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
color:
|
|
||||||
tender.liked ?? false
|
|
||||||
? AppColors.successColor
|
|
||||||
: AppColors.grey50,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,231 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:tm_app/core/constants/strings.dart';
|
||||||
|
import 'package:tm_app/data/services/model/home/tender/tender_model.dart';
|
||||||
|
import 'package:tm_app/view_models/tenders_view_model.dart';
|
||||||
|
|
||||||
|
import '../../../core/constants/assets.dart';
|
||||||
|
import '../../../core/theme/colors.dart';
|
||||||
|
import '../../../core/utils/size_config.dart';
|
||||||
|
|
||||||
|
class TenderActionButtonsRow extends StatelessWidget {
|
||||||
|
final TenderModel tender;
|
||||||
|
final bool isDesktop;
|
||||||
|
|
||||||
|
const TenderActionButtonsRow({
|
||||||
|
required this.tender,
|
||||||
|
this.isDesktop = false,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final viewModel = context.watch<TendersViewModel>();
|
||||||
|
return Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
SizedBox(width: 16.0.w()),
|
||||||
|
|
||||||
|
// Dislike button
|
||||||
|
_dislikeButton(viewModel),
|
||||||
|
SizedBox(width: 32.0.w()),
|
||||||
|
//reject button
|
||||||
|
_rejectButton(viewModel),
|
||||||
|
SizedBox(width: 32.0.w()),
|
||||||
|
//submit button
|
||||||
|
_submitButton(viewModel),
|
||||||
|
SizedBox(width: 32.0.w()),
|
||||||
|
// Like button
|
||||||
|
_likeButton(viewModel),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _rejectButton(TendersViewModel viewModel) {
|
||||||
|
return Tooltip(
|
||||||
|
message: AppStrings.reject,
|
||||||
|
child: InkWell(
|
||||||
|
splashColor: Colors.transparent,
|
||||||
|
onTap: () {
|
||||||
|
viewModel.toggleReject(tender);
|
||||||
|
},
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 32.0.w(),
|
||||||
|
height: 32.0.w(),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
border: Border.all(
|
||||||
|
color:
|
||||||
|
tender.rejected ?? false
|
||||||
|
? AppColors.errorColor
|
||||||
|
: AppColors.grey60,
|
||||||
|
width: 1.5.w(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: Icon(
|
||||||
|
Icons.close,
|
||||||
|
color:
|
||||||
|
tender.rejected ?? false
|
||||||
|
? AppColors.errorColor
|
||||||
|
: AppColors.grey60,
|
||||||
|
size: 16,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 8.0.h()),
|
||||||
|
if (!isDesktop)
|
||||||
|
Text(
|
||||||
|
AppStrings.reject,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.0.sp(),
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color:
|
||||||
|
tender.rejected ?? false
|
||||||
|
? AppColors.errorColor
|
||||||
|
: AppColors.grey60,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _submitButton(TendersViewModel viewModel) {
|
||||||
|
return Tooltip(
|
||||||
|
message: AppStrings.submit,
|
||||||
|
child: InkWell(
|
||||||
|
splashColor: Colors.transparent,
|
||||||
|
onTap: () {
|
||||||
|
viewModel.toggleSubmit(tender);
|
||||||
|
},
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 32.0.w(),
|
||||||
|
height: 32.0.w(),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
border: Border.all(
|
||||||
|
color:
|
||||||
|
tender.submitted ?? false
|
||||||
|
? AppColors.successColor
|
||||||
|
: AppColors.grey60,
|
||||||
|
width: 1.5.w(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
AssetsManager.tick,
|
||||||
|
colorFilter: ColorFilter.mode(
|
||||||
|
tender.submitted ?? false
|
||||||
|
? AppColors.successColor
|
||||||
|
: AppColors.grey60,
|
||||||
|
BlendMode.srcATop,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 8.0.h()),
|
||||||
|
if (!isDesktop)
|
||||||
|
Text(
|
||||||
|
AppStrings.submit,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.0.sp(),
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color:
|
||||||
|
tender.submitted ?? false
|
||||||
|
? AppColors.successColor
|
||||||
|
: AppColors.grey60,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _dislikeButton(TendersViewModel viewModel) {
|
||||||
|
return Tooltip(
|
||||||
|
message: AppStrings.dislike,
|
||||||
|
child: InkWell(
|
||||||
|
splashColor: Colors.transparent,
|
||||||
|
onTap: () {
|
||||||
|
viewModel.toggleDislike(tender);
|
||||||
|
},
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
SvgPicture.asset(
|
||||||
|
width: 32.0.w(),
|
||||||
|
height: 32.0.w(),
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
AssetsManager.dislike,
|
||||||
|
colorFilter: ColorFilter.mode(
|
||||||
|
tender.disliked ?? false
|
||||||
|
? AppColors.errorColor
|
||||||
|
: AppColors.grey50,
|
||||||
|
BlendMode.srcATop,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 8.0.h()),
|
||||||
|
if (!isDesktop)
|
||||||
|
Text(
|
||||||
|
AppStrings.dislike,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.0.sp(),
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color:
|
||||||
|
tender.disliked ?? false
|
||||||
|
? AppColors.errorColor
|
||||||
|
: AppColors.grey50,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _likeButton(TendersViewModel viewModel) {
|
||||||
|
return Tooltip(
|
||||||
|
message: AppStrings.like,
|
||||||
|
child: InkWell(
|
||||||
|
splashColor: Colors.transparent,
|
||||||
|
onTap: () {
|
||||||
|
viewModel.toggleLike(tender);
|
||||||
|
},
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
SvgPicture.asset(
|
||||||
|
width: 32.0.w(),
|
||||||
|
height: 32.0.w(),
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
AssetsManager.like,
|
||||||
|
colorFilter: ColorFilter.mode(
|
||||||
|
tender.liked ?? false
|
||||||
|
? AppColors.successColor
|
||||||
|
: AppColors.grey50,
|
||||||
|
BlendMode.srcATop,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 8.0.h()),
|
||||||
|
if (!isDesktop)
|
||||||
|
Text(
|
||||||
|
AppStrings.like,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.0.sp(),
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color:
|
||||||
|
tender.liked ?? false
|
||||||
|
? AppColors.successColor
|
||||||
|
: AppColors.grey50,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import '../../../core/constants/assets.dart';
|
|
||||||
import '../../../core/constants/strings.dart';
|
|
||||||
import '../../../core/theme/colors.dart';
|
|
||||||
import '../../../core/utils/size_config.dart';
|
|
||||||
|
|
||||||
class TenderAppBar extends StatelessWidget {
|
|
||||||
const TenderAppBar({super.key});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Padding(
|
|
||||||
padding: EdgeInsets.symmetric(horizontal: 24.0.w()),
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
AppStrings.tendersTitle,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20.0.sp(),
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
color: AppColors.grey70,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Image.asset(
|
|
||||||
AssetsManager.tenderLogo,
|
|
||||||
width: 59.0.w(),
|
|
||||||
height: 28.0.h(),
|
|
||||||
fit: BoxFit.cover,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -7,7 +7,7 @@ import 'package:tm_app/data/services/model/home/tender/tender_model.dart';
|
|||||||
import '../../../core/constants/assets.dart';
|
import '../../../core/constants/assets.dart';
|
||||||
import '../../../core/theme/colors.dart';
|
import '../../../core/theme/colors.dart';
|
||||||
import '../../../core/utils/size_config.dart';
|
import '../../../core/utils/size_config.dart';
|
||||||
import 'tender_action_buttons.dart';
|
import 'tender_action_buttons_row.dart';
|
||||||
|
|
||||||
class TenderCard extends StatelessWidget {
|
class TenderCard extends StatelessWidget {
|
||||||
final TenderModel tender;
|
final TenderModel tender;
|
||||||
@@ -19,7 +19,6 @@ class TenderCard extends StatelessWidget {
|
|||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
// width: 364.0.w(),
|
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
margin: EdgeInsets.symmetric(horizontal: 16.0.w()),
|
margin: EdgeInsets.symmetric(horizontal: 16.0.w()),
|
||||||
height: 587.0.h(),
|
height: 587.0.h(),
|
||||||
@@ -40,16 +39,9 @@ class TenderCard extends StatelessWidget {
|
|||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
_dateText(),
|
||||||
tender.createdTime ?? '',
|
|
||||||
style: TextStyle(
|
|
||||||
color: AppColors.grey60,
|
|
||||||
fontSize: 12.0.sp(),
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (isDesktop)
|
if (isDesktop)
|
||||||
TenderActionButtons(
|
TenderActionButtonsRow(
|
||||||
tender: tender,
|
tender: tender,
|
||||||
isDesktop: isDesktop,
|
isDesktop: isDesktop,
|
||||||
),
|
),
|
||||||
@@ -58,70 +50,19 @@ class TenderCard extends StatelessWidget {
|
|||||||
SizedBox(height: 12.0.h()),
|
SizedBox(height: 12.0.h()),
|
||||||
|
|
||||||
// Deadline badge
|
// Deadline badge
|
||||||
Container(
|
_deadlineBadge(),
|
||||||
width: double.infinity,
|
|
||||||
height: 24.0.h(),
|
|
||||||
padding: EdgeInsets.symmetric(horizontal: 8.0.w()),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColors.primary20,
|
|
||||||
borderRadius: BorderRadius.circular(4),
|
|
||||||
),
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
AppStrings.tenderDeadlineLabel,
|
|
||||||
style: TextStyle(
|
|
||||||
color: AppColors.textBlue,
|
|
||||||
fontSize: 14.0.sp(),
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
tender.deadline ?? '',
|
|
||||||
style: TextStyle(
|
|
||||||
color: AppColors.grey80,
|
|
||||||
fontSize: 14.0.sp(),
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 12.0.h()),
|
SizedBox(height: 12.0.h()),
|
||||||
|
|
||||||
// Title
|
// Title
|
||||||
Text(
|
_tenderTitle(),
|
||||||
tender.title ?? '',
|
|
||||||
style: TextStyle(
|
|
||||||
color: AppColors.grey80,
|
|
||||||
fontSize: 16.0.sp(),
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 8.0.h()),
|
SizedBox(height: 8.0.h()),
|
||||||
|
|
||||||
// Description
|
// Description
|
||||||
Text(
|
_tenderDescription(),
|
||||||
tender.description ?? '',
|
|
||||||
style: TextStyle(
|
|
||||||
color: AppColors.grey70,
|
|
||||||
fontSize: 16.0.sp(),
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
height: 1.5,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 12.0.h()),
|
SizedBox(height: 12.0.h()),
|
||||||
|
|
||||||
// Tender ID
|
// Tender ID
|
||||||
Text(
|
_idText(),
|
||||||
tender.tenderId ?? '',
|
|
||||||
style: TextStyle(
|
|
||||||
color: AppColors.grey,
|
|
||||||
fontSize: 14.0.sp(),
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -132,101 +73,21 @@ class TenderCard extends StatelessWidget {
|
|||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
// Match percentage
|
// Match percentage
|
||||||
Row(
|
_matchPercentage(),
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
AppStrings.tenderMatchProfile,
|
|
||||||
style: TextStyle(
|
|
||||||
color: AppColors.grey80,
|
|
||||||
fontSize: 14.0.sp(),
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
'${tender.profileMatch?.toInt() ?? 0}%',
|
|
||||||
style: TextStyle(
|
|
||||||
color: AppColors.secondaryTextColor,
|
|
||||||
fontSize: 16.0.sp(),
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
SizedBox(height: 8.0.h()),
|
SizedBox(height: 8.0.h()),
|
||||||
|
|
||||||
// Progress bar
|
// Progress bar
|
||||||
Container(
|
_progressBar(),
|
||||||
width: double.infinity,
|
|
||||||
height: 4.0.h(),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColors.grey20,
|
|
||||||
borderRadius: BorderRadius.circular(2),
|
|
||||||
),
|
|
||||||
child: FractionallySizedBox(
|
|
||||||
alignment: Alignment.centerLeft,
|
|
||||||
widthFactor: tender.profileMatch ?? 0 / 100,
|
|
||||||
child: Container(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColors.secondary50,
|
|
||||||
borderRadius: BorderRadius.circular(2),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 16.0.h()),
|
SizedBox(height: 16.0.h()),
|
||||||
|
|
||||||
// Location and apply button
|
// Location and apply button
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
// Location info
|
// Location info
|
||||||
Expanded(
|
_locationInfo(),
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
SvgPicture.asset(AssetsManager.location),
|
|
||||||
SizedBox(width: 4.0.w()),
|
|
||||||
Text(
|
|
||||||
tender.location ?? '',
|
|
||||||
style: TextStyle(
|
|
||||||
color: AppColors.grey80,
|
|
||||||
fontSize: 14.0.sp(),
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(width: 8.0.w()),
|
|
||||||
// Country flag placeholder
|
|
||||||
Image.asset(
|
|
||||||
AssetsManager.seFlag,
|
|
||||||
width: 32.0.w(),
|
|
||||||
height: 21.0.h(),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
// See More button
|
// See More button
|
||||||
GestureDetector(
|
_seeMoreButton(context),
|
||||||
onTap: () {
|
|
||||||
TenderDetailRouteData().push(context);
|
|
||||||
},
|
|
||||||
child: Container(
|
|
||||||
width: 108.0.w(),
|
|
||||||
height: 40.0.h(),
|
|
||||||
alignment: Alignment.center,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColors.primary20,
|
|
||||||
borderRadius: BorderRadius.circular(100),
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
AppStrings.tenderSeeMore,
|
|
||||||
style: TextStyle(
|
|
||||||
color: AppColors.mainBlue,
|
|
||||||
fontSize: 14.0.sp(),
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -236,8 +97,178 @@ class TenderCard extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(height: 72.0.h()),
|
SizedBox(height: 72.0.h()),
|
||||||
if (!isDesktop) TenderActionButtons(tender: tender),
|
if (!isDesktop) TenderActionButtonsRow(tender: tender),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _dateText() {
|
||||||
|
return Text(
|
||||||
|
tender.createdTime ?? '',
|
||||||
|
style: TextStyle(
|
||||||
|
color: AppColors.grey60,
|
||||||
|
fontSize: 12.0.sp(),
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _deadlineBadge() {
|
||||||
|
return Container(
|
||||||
|
width: double.infinity,
|
||||||
|
height: 24.0.h(),
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 8.0.w()),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColors.primary20,
|
||||||
|
borderRadius: BorderRadius.circular(4),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
AppStrings.tenderDeadlineLabel,
|
||||||
|
style: TextStyle(
|
||||||
|
color: AppColors.textBlue,
|
||||||
|
fontSize: 14.0.sp(),
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
tender.deadline ?? '',
|
||||||
|
style: TextStyle(
|
||||||
|
color: AppColors.grey80,
|
||||||
|
fontSize: 14.0.sp(),
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _tenderTitle() {
|
||||||
|
return Text(
|
||||||
|
tender.title ?? '',
|
||||||
|
style: TextStyle(
|
||||||
|
color: AppColors.grey80,
|
||||||
|
fontSize: 16.0.sp(),
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _tenderDescription() {
|
||||||
|
return Text(
|
||||||
|
tender.description ?? '',
|
||||||
|
style: TextStyle(
|
||||||
|
color: AppColors.grey70,
|
||||||
|
fontSize: 16.0.sp(),
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
height: 1.5,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _idText() {
|
||||||
|
return Text(
|
||||||
|
tender.tenderId ?? '',
|
||||||
|
style: TextStyle(
|
||||||
|
color: AppColors.grey,
|
||||||
|
fontSize: 14.0.sp(),
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _matchPercentage() {
|
||||||
|
return Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
AppStrings.tenderMatchProfile,
|
||||||
|
style: TextStyle(
|
||||||
|
color: AppColors.grey80,
|
||||||
|
fontSize: 14.0.sp(),
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'${tender.profileMatch ?? 0}%',
|
||||||
|
style: TextStyle(
|
||||||
|
color: AppColors.secondaryTextColor,
|
||||||
|
fontSize: 16.0.sp(),
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _progressBar() {
|
||||||
|
return Container(
|
||||||
|
width: double.infinity,
|
||||||
|
height: 4.0.h(),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColors.grey20,
|
||||||
|
borderRadius: BorderRadius.circular(2),
|
||||||
|
),
|
||||||
|
child: FractionallySizedBox(
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
widthFactor: (tender.profileMatch ?? 0) / 100,
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColors.secondary50,
|
||||||
|
borderRadius: BorderRadius.circular(2),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _locationInfo() {
|
||||||
|
return Expanded(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
SvgPicture.asset(AssetsManager.location),
|
||||||
|
SizedBox(width: 4.0.w()),
|
||||||
|
Text(
|
||||||
|
tender.location ?? '',
|
||||||
|
style: TextStyle(
|
||||||
|
color: AppColors.grey80,
|
||||||
|
fontSize: 14.0.sp(),
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 8.0.w()),
|
||||||
|
// Country flag placeholder
|
||||||
|
Image.asset(AssetsManager.seFlag, width: 32.0.w(), height: 21.0.h()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _seeMoreButton(BuildContext context) {
|
||||||
|
return InkWell(
|
||||||
|
onTap: () {
|
||||||
|
TenderDetailRouteData().push(context);
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
width: 108.0.w(),
|
||||||
|
height: 40.0.h(),
|
||||||
|
alignment: Alignment.center,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColors.primary20,
|
||||||
|
borderRadius: BorderRadius.circular(100),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
AppStrings.tenderSeeMore,
|
||||||
|
style: TextStyle(
|
||||||
|
color: AppColors.mainBlue,
|
||||||
|
fontSize: 14.0.sp(),
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,2 @@
|
|||||||
export '../../shared/main_tab_bar.dart';
|
export '../../shared/main_tab_bar.dart';
|
||||||
export 'tender_app_bar.dart';
|
|
||||||
export 'tender_card.dart';
|
export 'tender_card.dart';
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:tm_app/core/constants/strings.dart';
|
import 'package:tm_app/core/constants/strings.dart';
|
||||||
import 'package:tm_app/core/theme/colors.dart';
|
import 'package:tm_app/core/theme/colors.dart';
|
||||||
|
import 'package:tm_app/core/utils/size_config.dart';
|
||||||
|
import 'package:tm_app/view_models/your_tenders_view_model.dart';
|
||||||
import 'package:tm_app/views/shared/main_tab_bar.dart';
|
import 'package:tm_app/views/shared/main_tab_bar.dart';
|
||||||
import 'package:tm_app/views/shared/tender_app_bar.dart';
|
|
||||||
import 'package:tm_app/views/your_tenders/widgets/approved_tenders.dart';
|
import 'package:tm_app/views/your_tenders/widgets/approved_tenders.dart';
|
||||||
import 'package:tm_app/views/your_tenders/widgets/tenders_submitted.dart';
|
import 'package:tm_app/views/your_tenders/widgets/tenders_submitted.dart';
|
||||||
import 'package:tm_app/view_models/your_tenders_view_model.dart';
|
|
||||||
|
import '../../../core/constants/assets.dart';
|
||||||
|
|
||||||
class YourTendersMobilePage extends StatefulWidget {
|
class YourTendersMobilePage extends StatefulWidget {
|
||||||
const YourTendersMobilePage({super.key});
|
const YourTendersMobilePage({super.key});
|
||||||
@@ -37,25 +40,50 @@ class _YourTendersMobilePageState extends State<YourTendersMobilePage>
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SafeArea(
|
return Scaffold(
|
||||||
child: Scaffold(
|
backgroundColor: AppColors.backgroundColor,
|
||||||
backgroundColor: AppColors.backgroundColor,
|
appBar: _buildAppBar(context),
|
||||||
appBar: tenderMobileAppBar(title: AppStrings.yourTenders),
|
body: Column(
|
||||||
body: Column(
|
children: [
|
||||||
children: [
|
MainTabBar(
|
||||||
MainTabBar(
|
controller: controller,
|
||||||
|
titles: [AppStrings.approvedTenders, AppStrings.tenderSubmitted],
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: TabBarView(
|
||||||
controller: controller,
|
controller: controller,
|
||||||
titles: [AppStrings.approvedTenders, AppStrings.tenderSubmitted],
|
children: const [ApprovedTenders(), TendersSubmitted()],
|
||||||
),
|
),
|
||||||
Expanded(
|
),
|
||||||
child: TabBarView(
|
],
|
||||||
controller: controller,
|
|
||||||
children: const [ApprovedTenders(), TendersSubmitted()],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PreferredSizeWidget _buildAppBar(BuildContext context) {
|
||||||
|
return PreferredSize(
|
||||||
|
preferredSize: const Size.fromHeight(60),
|
||||||
|
child: AppBar(
|
||||||
|
backgroundColor: AppColors.backgroundColor,
|
||||||
|
elevation: 0,
|
||||||
|
titleSpacing: 0,
|
||||||
|
leading: IconButton(
|
||||||
|
icon: SvgPicture.asset(
|
||||||
|
AssetsManager.arrowLeft,
|
||||||
|
height: 24.0.w(),
|
||||||
|
width: 24.0.w(),
|
||||||
|
),
|
||||||
|
onPressed: () => Navigator.pop(context),
|
||||||
|
),
|
||||||
|
title: Text(
|
||||||
|
AppStrings.yourTenders,
|
||||||
|
style: TextStyle(
|
||||||
|
color: AppColors.grey70,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
fontSize: 20.0.sp(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -39,13 +39,13 @@ class ApprovedTenders extends StatelessWidget {
|
|||||||
t.status == 'Won'
|
t.status == 'Won'
|
||||||
? AppColors.gren0
|
? AppColors.gren0
|
||||||
: t.status == 'Completed'
|
: t.status == 'Completed'
|
||||||
? AppColors.white
|
? AppColors.grey0
|
||||||
: AppColors.red0.withValues(alpha: 0.2),
|
: AppColors.red0.withValues(alpha: 0.2),
|
||||||
borderColor:
|
borderColor:
|
||||||
t.status == 'Won'
|
t.status == 'Won'
|
||||||
? AppColors.green10
|
? AppColors.green10
|
||||||
: t.status == 'Completed'
|
: t.status == 'Completed'
|
||||||
? AppColors.cyanAqua
|
? AppColors.grey30
|
||||||
: AppColors.red0,
|
: AppColors.red0,
|
||||||
statusIcon:
|
statusIcon:
|
||||||
t.status == 'Won'
|
t.status == 'Won'
|
||||||
|
|||||||
Reference in New Issue
Block a user