import 'package:flutter/material.dart' hide DateUtils; import 'package:flutter_svg/svg.dart'; import 'package:tm_app/core/routes/app_routes.dart'; import 'package:tm_app/core/utils/price_extension.dart'; import 'package:tm_app/data/services/model/tender_data/tender_data.dart'; import '../../../core/constants/assets.dart'; import '../../../core/theme/colors.dart'; import '../../../core/utils/date_utils.dart'; import '../../../core/utils/size_config.dart'; import '../../detail/strings/tender_details_strings.dart'; import '../../shared/flag.dart'; import '../strings/tenders_strings.dart'; import 'tender_action_buttons_row.dart'; class TenderCard extends StatelessWidget { final TenderData tender; final bool isDesktop; const TenderCard({required this.tender, super.key, this.isDesktop = false}); @override Widget build(BuildContext context) { return Column( children: [ Container( width: double.infinity, margin: EdgeInsets.symmetric(horizontal: 16.0.w()), height: isDesktop ? 350.0.h() : 587.0.h(), decoration: BoxDecoration( color: AppColors.grey0, borderRadius: BorderRadius.circular(12), border: Border.all(color: AppColors.grey30), ), child: Column( children: [ // Main content Padding( padding: EdgeInsets.all(16.0.w()), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Date Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ _dateText(), if (isDesktop) TenderActionButtonsRow( tender: tender, isDesktop: isDesktop, ), ], ), SizedBox(height: 12.0.h()), // Deadline badge _deadlineBadge(), isDesktop ? Container() : SizedBox(height: 12.0.h()), // Approval status badge // _approvalStatusBadge(), SizedBox(height: isDesktop ? 6.0.h() : 12.0.h()), // Title _tenderTitle(), SizedBox(height: isDesktop ? 4.0.h() : 8.0.h()), // Description _tenderDescription(), isDesktop ? Container() : SizedBox(height: 12.0.h()), // Tender ID isDesktop ? Container() : _idText(), ], ), ), const Spacer(), // Bottom section with progress and actions Padding( padding: EdgeInsets.symmetric( vertical: isDesktop ? 8.0.w() : 16.0.w(), horizontal: 16.0.w(), ), child: Column( children: [ // Match percentage _matchPercentage(), SizedBox(height: isDesktop ? 4.0.h() : 8.0.h()), // Progress bar _progressBar(), SizedBox(height: isDesktop ? 8.0.h() : 16.0.h()), // Location and apply button Row( children: [ // Location info _locationInfo(), // See More button _seeMoreButton(context), ], ), ], ), ), ], ), ), SizedBox(height: isDesktop ? 20.0.h() : 52.0.h()), if (!isDesktop) TenderActionButtonsRow(tender: tender), ], ); } Widget _dateText() { return Text( timeConvertor(tender.publicationDate), style: TextStyle( color: AppColors.grey60, fontSize: 12.0.sp(), fontWeight: FontWeight.w400, ), ); } Widget _deadlineBadge() { return Container( width: double.infinity, // height: 24.0.h(), // height: 65.0.h(), padding: EdgeInsets.symmetric(horizontal: 8.0.w(), vertical: 6.0.h()), decoration: BoxDecoration( color: AppColors.primary20, borderRadius: BorderRadius.circular(4), ), child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Text( TendersStrings.tenderDeadlineLabel, style: TextStyle( color: AppColors.textBlue, fontSize: 14.0.sp(), fontWeight: FontWeight.w500, ), ), SizedBox(width: 4.0.w()), Text( timeConvertor(tender.submissionDeadline), style: TextStyle( color: AppColors.grey80, fontSize: 14.0.sp(), fontWeight: FontWeight.w500, ), ), ], ), // SizedBox(height: 4.0.h()), Visibility( visible: tender.estimatedValue != null && tender.estimatedValue != 0, child: const Divider(color: AppColors.primary40), ), // SizedBox(height: 4.0.h()), Visibility( visible: tender.estimatedValue != null && tender.estimatedValue != 0, child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Text( TendersStrings.tenderBudgetLabel, style: TextStyle( color: AppColors.textBlue, fontSize: 14.0.sp(), fontWeight: FontWeight.w500, ), ), SizedBox(width: 4.0.w()), Text( tender.estimatedValue?.formattedPrice ?? '', style: TextStyle( color: AppColors.grey80, fontSize: 14.0.sp(), fontWeight: FontWeight.w500, ), ), SizedBox(width: 4.0.w()), Text( tender.currency ?? '', style: TextStyle( color: AppColors.grey80, fontSize: 14.0.sp(), fontWeight: FontWeight.w500, ), ), ], ), ), ], ), ); } Widget _tenderTitle() { return Text( tender.title ?? '', maxLines: isDesktop ? 2 : 4, style: TextStyle( color: AppColors.grey80, fontSize: 16.0.sp(), fontWeight: isDesktop ? FontWeight.w500 : FontWeight.w600, ), ); } Widget _tenderDescription() { return Text( tender.description ?? '', maxLines: isDesktop ? 2 : 4, overflow: TextOverflow.ellipsis, style: TextStyle( color: AppColors.grey70, fontSize: isDesktop ? 14.0.sp() : 16.0.sp(), fontWeight: FontWeight.w400, height: 1.5, ), ); } Widget _idText() { return Text( tender.id ?? '', style: TextStyle( color: AppColors.grey, fontSize: 14.0.sp(), fontWeight: FontWeight.w400, ), ); } Widget _matchPercentage() { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( TenderDetailsStrings.tenderMatchProfile, style: TextStyle( color: AppColors.grey80, fontSize: isDesktop ? 12.0.sp() : 14.0.sp(), fontWeight: isDesktop ? FontWeight.w400 : FontWeight.w500, ), ), Text( '${45}%', style: TextStyle( color: AppColors.secondaryTextColor, fontSize: isDesktop ? 12.0.sp() : 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: (45) / 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.countryCode ?? '', style: TextStyle( color: AppColors.grey80, fontSize: 14.0.sp(), fontWeight: FontWeight.w500, ), ), SizedBox(width: 8.0.w()), // Country flag placeholder tender.countryCode != null ? Flag(countryCode: tender.countryCode!) : const Flag(countryCode: ''), ], ), ); } Widget _seeMoreButton(BuildContext context) { return InkWell( onTap: () { if (tender.id != null) { TenderDetailRouteData(tenderId: tender.id!).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( TendersStrings.tenderSeeMore, style: TextStyle( color: AppColors.mainBlue, fontSize: 14.0.sp(), fontWeight: FontWeight.w500, ), ), ), ); } }