Added, beneficiaries, site visits and change management

This commit is contained in:
2026-09-27 11:40:28 +02:00
parent fb27cc8c92
commit 36e5d3d7c8
16 changed files with 3132 additions and 212 deletions
@@ -42,6 +42,7 @@ import { useToast } from '../ui/Toast';
import { ProblemDetailsAlert } from '../ui/ProblemDetailsAlert';
import { ExportButton } from '../ui/ExportButton';
import { ExportColumn } from '../../utils/exportUtils';
import { useTableSort, SortableTh } from '../../utils/tableSort';
import {
Contract,
Award,
@@ -406,6 +407,30 @@ export const ContractsManagement: React.FC<ContractsManagementProps> = ({
{ header: 'Document URI', key: 'fileUri', format: (val) => val || '—' },
];
// Table sorting hook
const {
sortedData: sortedContracts,
sortColumn: contractSortCol,
sortDirection: contractSortDir,
handleSort: handleContractSort,
} = useTableSort<Contract>(filteredContracts, null, null, {
id: (c: any) => c.id,
awardId: (c: any) => c.totalValue || c.awardId,
programmeId: (c: any) => {
const a = getAwardForContract(c);
const pr = getProgrammeForAward(a);
return pr?.name || '';
},
organisationId: (c: any) => {
const a = getAwardForContract(c);
const o = getOrganisationForAward(a);
return o?.name || '';
},
signedDate: (c: any) => c.signedDate,
status: (c: any) => getContractStatusBadge(c.status).label,
fileUri: (c: any) => c.fileUri || '',
});
return (
<div className="space-y-6">
{/* Summary Cards */}
@@ -612,18 +637,32 @@ export const ContractsManagement: React.FC<ContractsManagementProps> = ({
<table className="w-full text-left text-xs text-slate-300">
<thead className="bg-[#151b2c]/80 text-slate-400 border-b border-slate-800/80 uppercase font-semibold text-[11px] tracking-wider">
<tr>
<th className="py-3.5 px-4">Contract / Ref</th>
<th className="py-3.5 px-4">Award & Amount</th>
<th className="py-3.5 px-4">Programme & Project</th>
<th className="py-3.5 px-4">Organisation</th>
<th className="py-3.5 px-4">Validity Period</th>
<th className="py-3.5 px-4">Status</th>
<th className="py-3.5 px-4">Document / S3</th>
<th className="py-3.5 px-4 text-right">Actions</th>
<SortableTh column="id" currentColumn={contractSortCol} direction={contractSortDir} onSort={handleContractSort} className="py-3.5 px-4">
Contract / Ref
</SortableTh>
<SortableTh column="awardId" currentColumn={contractSortCol} direction={contractSortDir} onSort={handleContractSort} className="py-3.5 px-4">
Award & Amount
</SortableTh>
<SortableTh column="programmeId" currentColumn={contractSortCol} direction={contractSortDir} onSort={handleContractSort} className="py-3.5 px-4">
Programme & Project
</SortableTh>
<SortableTh column="organisationId" currentColumn={contractSortCol} direction={contractSortDir} onSort={handleContractSort} className="py-3.5 px-4">
Organisation
</SortableTh>
<SortableTh column="signedDate" currentColumn={contractSortCol} direction={contractSortDir} onSort={handleContractSort} className="py-3.5 px-4">
Validity Period
</SortableTh>
<SortableTh column="status" currentColumn={contractSortCol} direction={contractSortDir} onSort={handleContractSort} className="py-3.5 px-4">
Status
</SortableTh>
<SortableTh column="fileUri" currentColumn={contractSortCol} direction={contractSortDir} onSort={handleContractSort} className="py-3.5 px-4">
Document / S3
</SortableTh>
<th className="py-3.5 px-4 text-right font-medium">Actions</th>
</tr>
</thead>
<tbody className="divide-y divide-slate-800/50">
{filteredContracts.map((contract) => {
{sortedContracts.map((contract) => {
const award = getAwardForContract(contract);
const org = getOrganisationForAward(award);
const prog = getProgrammeForAward(award);