import ExternalLink from 'lucide-solid/icons/external-link';
import type { JSX } from 'solid-js';
import { createMemo, createSignal, createUniqueId, For, Show } from 'solid-js';
import { statusLabel } from '@/lib/filterOpportunities';
import { formatDate, formatDateTime, formatValue } from '@/lib/format';
import type { ReleaseValue } from '@/lib/ocdsRelease';
import { parseReleaseData, summariseRelease } from '@/lib/ocdsRelease';
import type { NoticeSite } from '@/lib/opportunities';
import type { OpportunityRelease } from '@/types/Opportunities';
import { JsonView } from './JsonView';
interface Props {
releases: OpportunityRelease[];
/** The site the releases are notices on, so each can link to its notice; undefined if none. */
site: NoticeSite | undefined;
}
const tabClass =
'shrink-0 border-b-2 border-transparent px-3 py-2 text-sm whitespace-nowrap text-muted hover:text-ink aria-selected:border-accent aria-selected:font-semibold aria-selected:text-ink';
const sectionHeading = 'mb-1.5 text-sm font-semibold';
const summaryList = 'grid grid-cols-[max-content_1fr] gap-x-4 gap-y-1 text-sm';
const value = (money: ReleaseValue | undefined): string =>
money ? formatValue(money.amount, money.currency) : '—';
const tagsOf = (release: OpportunityRelease): string =>
(release.release_tags ?? []).map((tag) => tag.tag).join(', ');
interface FieldProps {
term: string;
children: JSX.Element;
}
/** A term and its description in a summary list. */
function Field(props: FieldProps): JSX.Element {
return (
<>
{props.term}
{props.children}
>
);
}
interface ReleasePanelProps {
release: OpportunityRelease;
site: NoticeSite | undefined;
}
/** One release: its notice, a summary of its tender, awards and contracts, and its JSON. */
function ReleasePanel(props: ReleasePanelProps): JSX.Element {
const parsed = createMemo(() => parseReleaseData(props.release.data));
const summary = createMemo(() => summariseRelease(parsed()));
// The JSON is only laid out once it's opened: a release can be 100KB or more.
const [isJsonOpen, setIsJsonOpen] = createSignal(false);
const notice = () => {
const site = props.site;
const url = site?.urlFor(props.release);
return site && url ? { name: site.name, url } : undefined;
};
const json = () => {
const data = parsed();
return data === undefined ? props.release.data : JSON.stringify(data, null, 2);
};
return (