diff --git a/client/src/pages/organizations/[id]/index.tsx b/client/src/pages/organizations/[id]/index.tsx index 65ba126a..85d3490c 100644 --- a/client/src/pages/organizations/[id]/index.tsx +++ b/client/src/pages/organizations/[id]/index.tsx @@ -1,62 +1,75 @@ -import { useParams } from "react-router-dom"; -import { useQuery } from "@tanstack/react-query"; import { - Breadcrumb, - Container, - Link, - Notice, - useDSFRConfig, + Breadcrumb, + Container, + Link, + Notice, + useDSFRConfig, } from "@dataesr/dsfr-plus"; -import PageSkeleton from "../../../components/skeleton/page-skeleton"; -import OrganizationPresentation from "./components/organization"; +import { useQuery } from "@tanstack/react-query"; +import { RawIntlProvider, createIntl } from "react-intl"; +import { useParams } from "react-router-dom"; import { getOrganizationById } from "../../../api/organizations/[id]"; +import PageSkeleton from "../../../components/skeleton/page-skeleton"; import getLangFieldValue from "../../../utils/lang"; -import { RawIntlProvider, createIntl } from "react-intl"; +import OrganizationPresentation from "./components/organization"; const modules = import.meta.glob("./locales/*.json", { - eager: true, - import: "default", + eager: true, + import: "default", }); const messages = Object.keys(modules).reduce((acc, key) => { - const locale = key.match(/\.\/locales\/(.+)\.json$/)?.[1]; - if (locale) { - return { ...acc, [locale]: modules[key] }; - } - return acc; + const locale = key.match(/\.\/locales\/(.+)\.json$/)?.[1]; + if (locale) { + return { ...acc, [locale]: modules[key] }; + } + return acc; }, {}); export default function Organization() { - const { locale } = useDSFRConfig(); - const intl = createIntl({ locale, messages: messages[locale] }); - const { id } = useParams(); - const { data, isLoading } = useQuery({ - queryKey: ["organizations", id], - queryFn: () => getOrganizationById(id), - throwOnError: true, - }); + const { locale } = useDSFRConfig(); + const intl = createIntl({ locale, messages: messages[locale] }); + const { id } = useParams(); + const { data, isLoading } = useQuery({ + queryKey: ["organizations", id], + queryFn: () => getOrganizationById(id), + throwOnError: true, + }); + + // if Date.parse fails, it returns NaN and NaN compares false to everything + // it then defaults to false if data?.endDate is undefined, null or invalid + // it returns true only if data?.endDate is a valid date in the past + const isClosed = Date.parse(data?.endDate) < Date.now(); + + const isForeign = data?.isFrench === false; + const breadcrumbLabel = getLangFieldValue(locale)(data?.label); - return ( - - {data && !data?.isFrench && ( - - {intl.formatMessage({ id: "organizations.notice.not-french" })} - - )} - {data?.endDate && ( - - {intl.formatMessage({ id: "organizations.notice.closed" })} {data.endDate.slice(0, 4)}. - - )} - - - {intl.formatMessage({ id: "organizations.breadcrumb.home" })} - {intl.formatMessage({ id: "organizations.breadcrumb.search" })} - {getLangFieldValue(locale)(data?.label)} - - {(isLoading || !data?.id) && } - {data?.id && } - - - ) + return ( + + {isForeign && ( + + {intl.formatMessage({ id: "organizations.notice.not-french" })} + + )} + {isClosed && ( + + {intl.formatMessage({ id: "organizations.notice.closed" })}{" "} + {new Date(data.endDate).toLocaleDateString()}. + + )} + + + + {intl.formatMessage({ id: "organizations.breadcrumb.home" })} + + + {intl.formatMessage({ id: "organizations.breadcrumb.search" })} + + {breadcrumbLabel} + + {(isLoading || !data?.id) && } + {data?.id && } + + + ); } diff --git a/client/src/types/organization.ts b/client/src/types/organization.ts index 4f15c6a3..607f93e2 100644 --- a/client/src/types/organization.ts +++ b/client/src/types/organization.ts @@ -1,157 +1,161 @@ -import { Aggregation, Address, LangField, ExternalIdsData } from "./commons"; -import { Network } from "./network"; +import type { + Aggregation, + Address, + LangField, + ExternalIdsData, +} from "./commons"; +import type { Network } from "./network"; export type OrganizationPublicationsData = { - byYear: Aggregation[]; - byPublicationType: Aggregation[]; - byAuthors: Aggregation[]; - byWiki: Aggregation[]; - bySource: Aggregation[]; - publicationsCount: number; + byYear: Aggregation[]; + byPublicationType: Aggregation[]; + byAuthors: Aggregation[]; + byWiki: Aggregation[]; + bySource: Aggregation[]; + publicationsCount: number; }; export type OrganizationProjectsData = { - byYear: Aggregation[]; - byType: Aggregation[]; - byKeywords: Aggregation[]; - projectsCount: number; + byYear: Aggregation[]; + byType: Aggregation[]; + byKeywords: Aggregation[]; + projectsCount: number; }; export type OrganizationPatentsData = { - nature: any; - level: any; - kind: any; - byYear: Aggregation[]; - patentsCount: number; + nature: any; + level: any; + kind: any; + byYear: Aggregation[]; + patentsCount: number; }; type BaseLink = { - type?: string; - url?: string; - language?: string; + type?: string; + url?: string; + language?: string; }; type BaseSocialMedia = BaseLink & { account?: string }; export type OrganizationLinksData = BaseLink[]; export type OrganizationSocialMediasData = BaseSocialMedia[]; export type RelatedOrganizationData = { - structure: string; - relationType?: string; - type?: string; - fromDate: string; - label: string; - denormalized: { - id: string; - label: LangField; - address?: Address[]; - }; + structure: string; + relationType?: string; + type?: string; + fromDate: string; + label: string; + denormalized: { + id: string; + label: LangField; + address?: Address[]; + }; }; export type OrganizationLeaderData = { - person?: string; - role?: string; - fromDate?: string; - firstName?: string; - lastName?: string; + person?: string; + role?: string; + fromDate?: string; + firstName?: string; + lastName?: string; }; export type OrganizationBadgesData = { - code: string; - label: LangField; + code: string; + label: LangField; }; export type OrganizationAwardsData = { - label: string, - year: number, - domain?: { - id: string, - label: string - } -} + label: string; + year: number; + domain?: { + id: string; + label: string; + }; +}; export type OrganizationAgreementsData = { - type: string, - start: number, - end: number, - years: number[], - label: string, -} + type: string; + start: number; + end: number; + years: number[]; + label: string; +}; export type OrganizationIaDescription = { - creation_date: string, - model: string, - description: LangField -} + creation_date: string; + model: string; + description: LangField; +}; export type Organization = { - _id: string; - acronym: LangField; - address?: Address[]; - agreements: OrganizationAgreementsData[]; - ai_description?: OrganizationIaDescription; - awards: OrganizationAwardsData[]; - badges?: OrganizationBadgesData[]; - creationYear?: number; - description: LangField; - endDate: string; - externalIds: ExternalIdsData[]; - id: string; - institutionOf?: RelatedOrganizationData[]; - institutions?: RelatedOrganizationData[]; - isFrench: boolean; - kind: string[]; - label: LangField; - leaders?: OrganizationLeaderData[]; - level?: string; - links: OrganizationLinksData; - nature?: string; - parentOf?: RelatedOrganizationData[]; - parents?: RelatedOrganizationData[]; - patents: OrganizationPatentsData; - projects: OrganizationProjectsData; - publications: OrganizationPublicationsData; - relationOf?: RelatedOrganizationData[]; - relations?: RelatedOrganizationData[]; - socialMedias: OrganizationSocialMediasData; - network?: Network + _id: string; + acronym: LangField; + address?: Address[]; + agreements: OrganizationAgreementsData[]; + ai_description?: OrganizationIaDescription; + awards: OrganizationAwardsData[]; + badges?: OrganizationBadgesData[]; + creationYear?: number; + description: LangField; + endDate?: string; + externalIds: ExternalIdsData[]; + id: string; + institutionOf?: RelatedOrganizationData[]; + institutions?: RelatedOrganizationData[]; + isFrench: boolean; + kind: string[]; + label: LangField; + leaders?: OrganizationLeaderData[]; + level?: string; + links: OrganizationLinksData; + nature?: string; + parentOf?: RelatedOrganizationData[]; + parents?: RelatedOrganizationData[]; + patents: OrganizationPatentsData; + projects: OrganizationProjectsData; + publications: OrganizationPublicationsData; + relationOf?: RelatedOrganizationData[]; + relations?: RelatedOrganizationData[]; + socialMedias: OrganizationSocialMediasData; + network?: Network; }; export type OrganizationAggregations = { - byNature: Aggregation[]; - byKind: Aggregation[]; - byLocalization: Aggregation[]; - byLevel: Aggregation[]; - byFundings: Aggregation[]; - byTags: Aggregation[]; - byAwards: Aggregation[]; - byAgreements: Aggregation[]; + byNature: Aggregation[]; + byKind: Aggregation[]; + byLocalization: Aggregation[]; + byLevel: Aggregation[]; + byFundings: Aggregation[]; + byTags: Aggregation[]; + byAwards: Aggregation[]; + byAgreements: Aggregation[]; }; export type LightOrganization = { - label: LangField; - acronym: LangField; - address: { - main: boolean; - city?: string; - }[]; - kind: string[]; - level: string; - nature: string; - id: string; - creationYear: string; - isFrench: string; - active: string; - publicationsCount: number; - projectsCount: number; + label: LangField; + acronym: LangField; + address: { + main: boolean; + city?: string; + }[]; + kind: string[]; + level: string; + nature: string; + id: string; + creationYear: string; + isFrench: string; + active: string; + publicationsCount: number; + projectsCount: number; }; - export type ExportOrganization = { - label: LangField; - acronym: LangField; - address: { - postcode: string; - main: boolean; - city?: string; - }[]; - links: OrganizationLinksData; - kind: string[]; - nature: string; - id: string; + label: LangField; + acronym: LangField; + address: { + postcode: string; + main: boolean; + city?: string; + }[]; + links: OrganizationLinksData; + kind: string[]; + nature: string; + id: string; };