feat(tender-procurement): enhance tender procurement section with additional details
- Added functionality to trim and filter related TED notice publication IDs for better display. - Introduced new fields for notice type code and main classification in the tender details. - Updated the procurement section to conditionally render additional information, improving user experience and data visibility.
This commit is contained in:
@@ -13,7 +13,27 @@ type TenderProcurementSectionProps = {
|
|||||||
tender: TTenderDetails;
|
tender: TTenderDetails;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const TED_NOTICE_DETAIL = "https://ted.europa.eu/en/notice/-/detail";
|
||||||
|
|
||||||
|
function uniqueTrimmedNoticeIds(ids: string[] | undefined): string[] {
|
||||||
|
if (!ids?.length) return [];
|
||||||
|
const seen = new Set<string>();
|
||||||
|
const out: string[] = [];
|
||||||
|
for (const id of ids) {
|
||||||
|
const trimmed = id?.trim();
|
||||||
|
if (!trimmed || seen.has(trimmed)) continue;
|
||||||
|
seen.add(trimmed);
|
||||||
|
out.push(trimmed);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
export function TenderProcurementSection({ tender }: TenderProcurementSectionProps) {
|
export function TenderProcurementSection({ tender }: TenderProcurementSectionProps) {
|
||||||
|
const relatedNoticeIds = uniqueTrimmedNoticeIds(tender.related_notice_publication_ids);
|
||||||
|
|
||||||
|
const noticeTypeCode = tender.notice_type_code?.trim();
|
||||||
|
const mainClassification = tender.main_classification?.trim();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
id={TENDER_SECTION_IDS.procurement}
|
id={TENDER_SECTION_IDS.procurement}
|
||||||
@@ -41,7 +61,7 @@ export function TenderProcurementSection({ tender }: TenderProcurementSectionPro
|
|||||||
<ShowcaseSection title="Notice publication ID" {...SHOWCASE_CENTERED_BODY}>
|
<ShowcaseSection title="Notice publication ID" {...SHOWCASE_CENTERED_BODY}>
|
||||||
<span className="font-medium text-primary underline-offset-4 hover:underline">
|
<span className="font-medium text-primary underline-offset-4 hover:underline">
|
||||||
<Link
|
<Link
|
||||||
href={`https://ted.europa.eu/en/notice/-/detail/${tender.notice_publication_id}`}
|
href={`${TED_NOTICE_DETAIL}/${tender.notice_publication_id}`}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
>
|
>
|
||||||
@@ -59,6 +79,48 @@ export function TenderProcurementSection({ tender }: TenderProcurementSectionPro
|
|||||||
{tender.procurement_type_code}
|
{tender.procurement_type_code}
|
||||||
</span>
|
</span>
|
||||||
</ShowcaseSection>
|
</ShowcaseSection>
|
||||||
|
{noticeTypeCode ? (
|
||||||
|
<ShowcaseSection title="Notice type code" {...SHOWCASE_CENTERED_BODY}>
|
||||||
|
<span className="font-medium text-dark dark:text-white">
|
||||||
|
{noticeTypeCode}
|
||||||
|
</span>
|
||||||
|
</ShowcaseSection>
|
||||||
|
) : null}
|
||||||
|
{mainClassification ? (
|
||||||
|
<ShowcaseSection
|
||||||
|
title="Main classification (CPV)"
|
||||||
|
{...SHOWCASE_CENTERED_BODY}
|
||||||
|
>
|
||||||
|
<span className="font-medium text-dark dark:text-white">
|
||||||
|
{mainClassification}
|
||||||
|
</span>
|
||||||
|
</ShowcaseSection>
|
||||||
|
) : null}
|
||||||
|
{relatedNoticeIds.length > 0 ? (
|
||||||
|
<ShowcaseSection
|
||||||
|
title="Related notice publications"
|
||||||
|
rootClassName={cn(
|
||||||
|
SHOWCASE_CENTERED_BODY.rootClassName,
|
||||||
|
"sm:col-span-2 xl:col-span-3 2xl:col-span-5",
|
||||||
|
)}
|
||||||
|
className="flex min-h-0 flex-1 flex-col items-stretch justify-center"
|
||||||
|
>
|
||||||
|
<ul className="flex flex-wrap justify-center gap-x-3 gap-y-2">
|
||||||
|
{relatedNoticeIds.map((noticeId) => (
|
||||||
|
<li key={noticeId}>
|
||||||
|
<Link
|
||||||
|
href={`${TED_NOTICE_DETAIL}/${noticeId}`}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="font-medium text-primary underline-offset-4 hover:underline"
|
||||||
|
>
|
||||||
|
{noticeId}
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</ShowcaseSection>
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -13,6 +13,12 @@ export const TenderSchema = z.object({
|
|||||||
duration_unit: z.string(),
|
duration_unit: z.string(),
|
||||||
estimated_value: z.number(),
|
estimated_value: z.number(),
|
||||||
notice_publication_id: z.string(),
|
notice_publication_id: z.string(),
|
||||||
|
/** Related TED notice publication IDs (e.g. modifications, same procedure). */
|
||||||
|
related_notice_publication_ids: z.array(z.string()).optional(),
|
||||||
|
/** TED form / notice type code (e.g. can-modif). */
|
||||||
|
notice_type_code: z.string().optional(),
|
||||||
|
/** Primary CPV classification code. */
|
||||||
|
main_classification: z.string().optional(),
|
||||||
procedure_code: z.string(),
|
procedure_code: z.string(),
|
||||||
procurement_type_code: z.string(),
|
procurement_type_code: z.string(),
|
||||||
publication_date: z.number(),
|
publication_date: z.number(),
|
||||||
|
|||||||
Reference in New Issue
Block a user