import 'package:flutter/material.dart'; import 'package:tm_app/core/theme/colors.dart'; import 'package:tm_app/core/utils/date_utils.dart'; import 'package:tm_app/core/utils/price_extension.dart'; import 'package:tm_app/core/utils/size_config.dart'; import 'package:tm_app/data/services/model/tender_data/tender_data.dart'; import 'package:tm_app/views/detail/strings/tender_details_strings.dart'; import 'package:tm_app/views/detail/widgets/deadline_item.dart'; import 'package:tm_app/views/detail/widgets/info_item.dart'; // AI-NOTE (for PR reviewer): This widget was rewritten to render ONLY the // backend-driven fields requested for the tender-details page (notice type, // form type, languages, issue/publication dates, procedure, value, duration, // deadlines, buyer org/address, lots, status, ids). Design is unchanged — it // still uses InfoItem/DeadlineItem. The _infoItem() helper returns an empty // list when a value is null/blank so empty fields don't render as blank rows // (this is why each entry is spread with `...`). The old hard-coded // "Reference Number" row was dropped because it isn't in the requested set. class TenderDetailInfoSection extends StatelessWidget { final bool isScreenBig; final TenderData detail; const TenderDetailInfoSection({ required this.isScreenBig, required this.detail, super.key, }); @override Widget build(BuildContext context) { final buyer = detail.buyerOrganization; final address = buyer?.address; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ DeadlineItem(detail: detail, isScreenBig: isScreenBig), ..._infoItem(TenderDetailsStrings.noticeTypeCode, detail.noticeTypeCode), ..._infoItem(TenderDetailsStrings.formType, detail.formType), ..._infoItem( TenderDetailsStrings.noticeLanguageCode, detail.noticeLanguageCode, ), ..._infoItem( TenderDetailsStrings.issueDate, _date(detail.issueDate), ), ..._infoItem( TenderDetailsStrings.issueTime, _dateTime(detail.issueTime), ), ..._infoItem(TenderDetailsStrings.procedureCode, detail.procedureCode), ..._infoItem( TenderDetailsStrings.estimatedValue, detail.estimatedValue == null ? null : '${detail.estimatedValue?.formattedPrice} ${detail.currency ?? ''}', ), ..._infoItem(TenderDetailsStrings.durationLabel, _duration()), ..._infoItem( TenderDetailsStrings.publicationDate, _date(detail.publicationDate), ), ..._infoItem( TenderDetailsStrings.tenderDeadlineDate, _date(detail.tenderDeadline), ), ..._infoItem(TenderDetailsStrings.countryCode, detail.countryCode), ..._infoItem(TenderDetailsStrings.buyerName, buyer?.name), ..._infoItem(TenderDetailsStrings.companyId, buyer?.companyId), ..._infoItem(TenderDetailsStrings.buyerCity, address?.cityName), ..._infoItem(TenderDetailsStrings.buyerCountry, address?.countryCode), ..._infoItem( TenderDetailsStrings.officialLanguages, (detail.officialLanguages == null || detail.officialLanguages!.isEmpty) ? null : detail.officialLanguages!.join(', '), ), ..._infoItem(TenderDetailsStrings.status, detail.status), ..._infoItem(TenderDetailsStrings.tenderId, detail.tenderId), ..._lotsSection(), ], ); } /// Returns an [InfoItem] only when [value] has content, so empty fields are /// not rendered as blank rows. List _infoItem(String title, String? value) { if (value == null || value.trim().isEmpty) { return const []; } return [InfoItem(title: title, value: value)]; } List _lotsSection() { final lots = detail.lots; if (lots == null || lots.isEmpty) { return const []; } return [ SizedBox(height: 8.0.h()), Text( TenderDetailsStrings.lots, style: TextStyle( color: AppColors.grey80, fontWeight: FontWeight.w600, fontSize: 16.0.sp(), ), ), SizedBox(height: 8.0.h()), for (final lot in lots) ...[ ..._infoItem(TenderDetailsStrings.lotId, lot.lotId), ..._infoItem('Title', lot.title), ..._infoItem('Description', lot.description), ], ]; } String? _duration() { final duration = detail.duration?.trim() ?? ''; final unit = detail.durationUnit?.trim() ?? ''; final combined = '$duration $unit'.trim(); return combined.isEmpty ? null : combined; } String? _date(int? unix) { if (unix == null) { return null; } return timeConvertor(unix); } String? _dateTime(int? unix) { if (unix == null) { return null; } return timeConvertor(unix, hasTime: true); } }