refactor(tender-details): integrate unixToDate for date formatting and enhance layout consistency
- Replaced msToDate with unixToDate for application, publication, submission, and tender deadlines to ensure accurate date representation. - Improved ShowcaseSection layout by adjusting class names for better visual consistency across various sections. - Enhanced error message formatting for improved readability.
This commit is contained in:
@@ -7,7 +7,11 @@ import Status from "@/components/ui/Status";
|
|||||||
import { useTenderDetailQuery } from "@/hooks/queries";
|
import { useTenderDetailQuery } from "@/hooks/queries";
|
||||||
import { useGetFlagQuery } from "@/hooks/queries/useFlagsQueries";
|
import { useGetFlagQuery } from "@/hooks/queries/useFlagsQueries";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { isValidAlpha2CountryCode, msToDate, truncateString } from "@/utils/shared";
|
import {
|
||||||
|
isValidAlpha2CountryCode,
|
||||||
|
truncateString,
|
||||||
|
unixToDate,
|
||||||
|
} from "@/utils/shared";
|
||||||
import getSymbolFromCurrency from "currency-symbol-map";
|
import getSymbolFromCurrency from "currency-symbol-map";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { use } from "react";
|
import { use } from "react";
|
||||||
@@ -82,11 +86,12 @@ const TenderDetails = ({ params }: IProps) => {
|
|||||||
We couldn't load this tender
|
We couldn't load this tender
|
||||||
</p>
|
</p>
|
||||||
<p className="max-w-sm text-sm text-dark-5 dark:text-dark-6">
|
<p className="max-w-sm text-sm text-dark-5 dark:text-dark-6">
|
||||||
Check your connection or try again. You can go back to the tender list anytime.
|
Check your connection or try again. You can go back to the tender
|
||||||
|
list anytime.
|
||||||
</p>
|
</p>
|
||||||
<Link
|
<Link
|
||||||
href="/tenders"
|
href="/tenders"
|
||||||
className="mt-2 inline-flex items-center justify-center rounded-xl bg-primary px-5 py-2.5 text-sm font-medium text-white shadow-theme-xs transition hover:bg-primary/90"
|
className="shadow-theme-xs mt-2 inline-flex items-center justify-center rounded-xl bg-primary px-5 py-2.5 text-sm font-medium text-white transition hover:bg-primary/90"
|
||||||
>
|
>
|
||||||
Back to tenders
|
Back to tenders
|
||||||
</Link>
|
</Link>
|
||||||
@@ -114,13 +119,15 @@ const TenderDetails = ({ params }: IProps) => {
|
|||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex shrink-0 flex-col gap-3 sm:flex-row sm:items-center sm:justify-end">
|
<div className="flex shrink-0 flex-col gap-3 sm:flex-row sm:items-center sm:justify-end">
|
||||||
<Status status={tender.status ?? "Unknown"}>{tender.status}</Status>
|
<Status status={tender.status ?? "Unknown"}>
|
||||||
|
{tender.status}
|
||||||
|
</Status>
|
||||||
{submissionUrl && (
|
{submissionUrl && (
|
||||||
<Link
|
<Link
|
||||||
href={submissionUrl}
|
href={submissionUrl}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
className="inline-flex items-center justify-center gap-2 rounded-xl bg-primary px-4 py-2.5 text-sm font-medium text-white shadow-theme-xs transition hover:bg-primary/90 hover:shadow-md"
|
className="shadow-theme-xs inline-flex items-center justify-center gap-2 rounded-xl bg-primary px-4 py-2.5 text-sm font-medium text-white transition hover:bg-primary/90 hover:shadow-md"
|
||||||
>
|
>
|
||||||
<span>Open submission</span>
|
<span>Open submission</span>
|
||||||
<ExternalLinkIcon className="opacity-90" />
|
<ExternalLinkIcon className="opacity-90" />
|
||||||
@@ -136,7 +143,9 @@ const TenderDetails = ({ params }: IProps) => {
|
|||||||
<SectionHeading>Procurement</SectionHeading>
|
<SectionHeading>Procurement</SectionHeading>
|
||||||
<div className="grid gap-4 sm:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-5">
|
<div className="grid gap-4 sm:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-5">
|
||||||
<ShowcaseSection title="Tender ID" {...SHOWCASE_CENTERED_BODY}>
|
<ShowcaseSection title="Tender ID" {...SHOWCASE_CENTERED_BODY}>
|
||||||
<span className="font-medium text-dark dark:text-white">{tender.tender_id}</span>
|
<span className="font-medium text-dark dark:text-white">
|
||||||
|
{tender.tender_id}
|
||||||
|
</span>
|
||||||
</ShowcaseSection>
|
</ShowcaseSection>
|
||||||
<ShowcaseSection
|
<ShowcaseSection
|
||||||
title="Buyer organization"
|
title="Buyer organization"
|
||||||
@@ -150,15 +159,26 @@ const TenderDetails = ({ params }: IProps) => {
|
|||||||
{tender.buyer_organization.name}
|
{tender.buyer_organization.name}
|
||||||
</span>
|
</span>
|
||||||
</ShowcaseSection>
|
</ShowcaseSection>
|
||||||
<ShowcaseSection title="Notice publication ID" {...SHOWCASE_CENTERED_BODY}>
|
<ShowcaseSection
|
||||||
|
title="Notice publication ID"
|
||||||
|
{...SHOWCASE_CENTERED_BODY}
|
||||||
|
>
|
||||||
<span className="font-medium text-dark dark:text-white">
|
<span className="font-medium text-dark dark:text-white">
|
||||||
{tender.notice_publication_id}
|
{tender.notice_publication_id}
|
||||||
</span>
|
</span>
|
||||||
</ShowcaseSection>
|
</ShowcaseSection>
|
||||||
<ShowcaseSection title="Procedure code" {...SHOWCASE_CENTERED_BODY}>
|
<ShowcaseSection
|
||||||
<span className="font-medium text-dark dark:text-white">{tender.procedure_code}</span>
|
title="Procedure code"
|
||||||
|
{...SHOWCASE_CENTERED_BODY}
|
||||||
|
>
|
||||||
|
<span className="font-medium text-dark dark:text-white">
|
||||||
|
{tender.procedure_code}
|
||||||
|
</span>
|
||||||
</ShowcaseSection>
|
</ShowcaseSection>
|
||||||
<ShowcaseSection title="Procurement type" {...SHOWCASE_CENTERED_BODY}>
|
<ShowcaseSection
|
||||||
|
title="Procurement type"
|
||||||
|
{...SHOWCASE_CENTERED_BODY}
|
||||||
|
>
|
||||||
<span className="font-medium text-dark dark:text-white">
|
<span className="font-medium text-dark dark:text-white">
|
||||||
{tender.procurement_type_code}
|
{tender.procurement_type_code}
|
||||||
</span>
|
</span>
|
||||||
@@ -169,28 +189,55 @@ const TenderDetails = ({ params }: IProps) => {
|
|||||||
<div>
|
<div>
|
||||||
<SectionHeading>Timeline</SectionHeading>
|
<SectionHeading>Timeline</SectionHeading>
|
||||||
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5">
|
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5">
|
||||||
<ShowcaseSection title="Application deadline" {...SHOWCASE_CENTERED_BODY}>
|
<ShowcaseSection
|
||||||
|
title="Application deadline"
|
||||||
|
{...SHOWCASE_CENTERED_BODY}
|
||||||
|
>
|
||||||
<time className="font-medium tabular-nums text-dark dark:text-white">
|
<time className="font-medium tabular-nums text-dark dark:text-white">
|
||||||
{msToDate(tender.application_deadline ?? 0)}
|
{unixToDate({
|
||||||
|
unix: tender.application_deadline ?? 0,
|
||||||
|
hasTime: true,
|
||||||
|
})}
|
||||||
</time>
|
</time>
|
||||||
</ShowcaseSection>
|
</ShowcaseSection>
|
||||||
<ShowcaseSection title="Publication date" {...SHOWCASE_CENTERED_BODY}>
|
<ShowcaseSection
|
||||||
|
title="Publication date"
|
||||||
|
{...SHOWCASE_CENTERED_BODY}
|
||||||
|
>
|
||||||
<time className="font-medium tabular-nums text-dark dark:text-white">
|
<time className="font-medium tabular-nums text-dark dark:text-white">
|
||||||
{msToDate(tender.publication_date ?? 0)}
|
{unixToDate({
|
||||||
|
unix: tender.publication_date ?? 0,
|
||||||
|
hasTime: true,
|
||||||
|
})}
|
||||||
</time>
|
</time>
|
||||||
</ShowcaseSection>
|
</ShowcaseSection>
|
||||||
<ShowcaseSection title="Submission deadline" {...SHOWCASE_CENTERED_BODY}>
|
<ShowcaseSection
|
||||||
|
title="Submission deadline"
|
||||||
|
{...SHOWCASE_CENTERED_BODY}
|
||||||
|
>
|
||||||
<time className="font-medium tabular-nums text-dark dark:text-white">
|
<time className="font-medium tabular-nums text-dark dark:text-white">
|
||||||
{msToDate(tender.submission_deadline ?? 0)}
|
{unixToDate({
|
||||||
|
unix: tender.submission_deadline ?? 0,
|
||||||
|
hasTime: true,
|
||||||
|
})}
|
||||||
</time>
|
</time>
|
||||||
</ShowcaseSection>
|
</ShowcaseSection>
|
||||||
<ShowcaseSection title="Tender deadline" {...SHOWCASE_CENTERED_BODY}>
|
<ShowcaseSection
|
||||||
|
title="Tender deadline"
|
||||||
|
{...SHOWCASE_CENTERED_BODY}
|
||||||
|
>
|
||||||
<time className="font-medium tabular-nums text-dark dark:text-white">
|
<time className="font-medium tabular-nums text-dark dark:text-white">
|
||||||
{msToDate(tender.tender_deadline ?? 0)}
|
{unixToDate({
|
||||||
|
unix: tender.tender_deadline ?? 0,
|
||||||
|
hasTime: true,
|
||||||
|
})}
|
||||||
</time>
|
</time>
|
||||||
</ShowcaseSection>
|
</ShowcaseSection>
|
||||||
{submissionUrl && (
|
{submissionUrl && (
|
||||||
<ShowcaseSection title="Submission URL" {...SHOWCASE_CENTERED_BODY}>
|
<ShowcaseSection
|
||||||
|
title="Submission URL"
|
||||||
|
{...SHOWCASE_CENTERED_BODY}
|
||||||
|
>
|
||||||
<Link
|
<Link
|
||||||
href={submissionUrl}
|
href={submissionUrl}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
@@ -208,7 +255,7 @@ const TenderDetails = ({ params }: IProps) => {
|
|||||||
<div>
|
<div>
|
||||||
<SectionHeading>Location & currency</SectionHeading>
|
<SectionHeading>Location & currency</SectionHeading>
|
||||||
<div className="grid gap-4 sm:grid-cols-2 lg:max-w-3xl">
|
<div className="grid gap-4 sm:grid-cols-2 lg:max-w-3xl">
|
||||||
<div className="relative overflow-hidden rounded-2xl border border-stroke/70 bg-gradient-to-br from-white via-gray-2/30 to-primary/[0.06] p-5 shadow-theme-xs dark:border-dark-3 dark:from-gray-dark dark:via-gray-dark dark:to-primary/[0.12]">
|
<div className="shadow-theme-xs relative overflow-hidden rounded-2xl border border-stroke/70 bg-gradient-to-br from-white via-gray-2/30 to-primary/[0.06] p-5 dark:border-dark-3 dark:from-gray-dark dark:via-gray-dark dark:to-primary/[0.12]">
|
||||||
<div className="pointer-events-none absolute -right-8 top-0 h-24 w-24 rounded-full bg-primary/15 blur-2xl dark:bg-primary/25" />
|
<div className="pointer-events-none absolute -right-8 top-0 h-24 w-24 rounded-full bg-primary/15 blur-2xl dark:bg-primary/25" />
|
||||||
<h3 className="mb-4 text-xs font-semibold uppercase tracking-wide text-dark-5 dark:text-dark-6">
|
<h3 className="mb-4 text-xs font-semibold uppercase tracking-wide text-dark-5 dark:text-dark-6">
|
||||||
Country
|
Country
|
||||||
@@ -232,7 +279,7 @@ const TenderDetails = ({ params }: IProps) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{tender.currency && (
|
{tender.currency && (
|
||||||
<div className="relative overflow-hidden rounded-2xl border border-stroke/70 bg-gradient-to-br from-white via-gray-2/30 to-purple-500/[0.06] p-5 shadow-theme-xs dark:border-dark-3 dark:from-gray-dark dark:via-gray-dark dark:to-purple-500/[0.12]">
|
<div className="shadow-theme-xs relative overflow-hidden rounded-2xl border border-stroke/70 bg-gradient-to-br from-white via-gray-2/30 to-purple-500/[0.06] p-5 dark:border-dark-3 dark:from-gray-dark dark:via-gray-dark dark:to-purple-500/[0.12]">
|
||||||
<div className="pointer-events-none absolute -left-6 bottom-0 h-20 w-20 rounded-full bg-purple-500/15 blur-2xl dark:bg-purple-500/25" />
|
<div className="pointer-events-none absolute -left-6 bottom-0 h-20 w-20 rounded-full bg-purple-500/15 blur-2xl dark:bg-purple-500/25" />
|
||||||
<h3 className="mb-4 text-xs font-semibold uppercase tracking-wide text-dark-5 dark:text-dark-6">
|
<h3 className="mb-4 text-xs font-semibold uppercase tracking-wide text-dark-5 dark:text-dark-6">
|
||||||
Currency
|
Currency
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@ export const unixToDate = ({
|
|||||||
unix: number;
|
unix: number;
|
||||||
hasTime?: boolean;
|
hasTime?: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
return moment.unix(unix).format(`YYYY/MM/DD - ${hasTime ? "HH:MM" : ""}`);
|
return unix === 0 ? "-" : moment.unix(unix).format(`YYYY/MM/DD - ${hasTime ? "HH:MM" : ""}`);
|
||||||
};
|
};
|
||||||
export const msToDate = (ms: number) => {
|
export const msToDate = (ms: number) => {
|
||||||
return moment.default(ms).format("YYYY/MM/DD");
|
return moment.default(ms).format("YYYY/MM/DD");
|
||||||
|
|||||||
Reference in New Issue
Block a user