Skip to content

Commit

Permalink
Project page #439
Browse files Browse the repository at this point in the history
  • Loading branch information
danielvdm2000 committed Feb 28, 2024
1 parent cf8abc8 commit df71624
Show file tree
Hide file tree
Showing 26 changed files with 731 additions and 203 deletions.
5 changes: 3 additions & 2 deletions packages/gbif-org/src/components/Tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ import { MdMoreHoriz } from 'react-icons/md';
import { useI18n } from '@/contexts/i18n';

export type Props = {
className?: string;
links: Array<{ to: string; children: React.ReactNode }>;
};

export function Tabs({ links }: Props) {
export function Tabs({ links, className }: Props) {
const containerRef = useRef<HTMLDivElement>(null);
const dropdownMenuTriggerRef = useRef<HTMLButtonElement>(null);
const [visibleTabCount, setVisibleTabCount] = useState(0);
Expand Down Expand Up @@ -58,7 +59,7 @@ export function Tabs({ links }: Props) {
}, [links, setVisibleTabCount]);

return (
<div ref={containerRef} className="relative ">
<div ref={containerRef} className={cn('relative', className)}>
<ul className="border-b border-slate-200 flex whitespace-nowrap dark:border-slate-200/5 overflow-hidden -mb-px">
{links.map(({ to, children }, idx) => {
const visible = idx < visibleTabCount;
Expand Down
12 changes: 6 additions & 6 deletions packages/gbif-org/src/gbif/routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@ import {
import {
ProjectAboutTab,
ProjectDatasetsTab,
ProjectNewsTab,
ProjectNewsTabSkeleton,
ProjectNewsAndEventsTab,
ProjectNewsAndEventsTabSkeleton,
ProjectPage,
ProjectPageSkeleton,
projectNewsLoader,
projectNewsAndEventsLoader,
projectPageLoader,
} from '@/routes/resource/key/project';
import { RouteId } from '@/hooks/useParentRouteLoaderData';
Expand Down Expand Up @@ -205,9 +205,9 @@ const baseRoutes: SourceRouteObject[] = [
},
{
path: 'news',
element: <ProjectNewsTab />,
loadingElement: <ProjectNewsTabSkeleton />,
loader: projectNewsLoader,
element: <ProjectNewsAndEventsTab />,
loadingElement: <ProjectNewsAndEventsTabSkeleton />,
loader: projectNewsAndEventsLoader,
},
{
path: 'datasets',
Expand Down
56 changes: 38 additions & 18 deletions packages/gbif-org/src/gql/gql.ts

Large diffs are not rendered by default.

42 changes: 27 additions & 15 deletions packages/gbif-org/src/gql/graphql.ts

Large diffs are not rendered by default.

82 changes: 82 additions & 0 deletions packages/gbif-org/src/routes/dataset/DatasetResult.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { DynamicLink } from '@/components/DynamicLink';
import { DatasetCountsFragment, DatasetResultFragment } from '@/gql/graphql';
import { fragmentManager } from '@/services/FragmentManager';
import { isPositiveNumber } from '@/utils/isPositiveNumber';
import { FormattedMessage, FormattedNumber } from 'react-intl';
import { MapThumbnail } from '../resource/key/components/MapThumbnail';

fragmentManager.register(/* GraphQL */ `
fragment DatasetResult on DatasetSearchStub {
key
title
excerpt
type
publishingOrganizationTitle
recordCount
license
}
`);

fragmentManager.register(/* GraphQL */ `
fragment DatasetCounts on DatasetSearchStub {
key
occurrenceCount
literatureCount
}
`);

export function DatasetResult({
dataset,
counts,
}: {
dataset: DatasetResultFragment;
counts?: DatasetCountsFragment;
}) {
return (
<article className="bg-slate-50 p-4 rounded border mb-4 flex flex-row gap-4">
<div>
<h3 className="text-base font-semibold mb-2">
<DynamicLink to={`/dataset/${dataset.key}`}>{dataset.title}</DynamicLink>
</h3>
<p className="font-normal text-slate-500 text-sm">{dataset.excerpt}</p>
<div className="mt-2 flex items-center">
<Tag>
<FormattedMessage id={`enums.datasetType.${dataset.type}`} />
</Tag>
{isPositiveNumber(counts?.literatureCount) && (
<Tag>
<FormattedMessage id="tableHeaders.citations" />:{' '}
<FormattedNumber value={counts.literatureCount} />
</Tag>
)}
{isPositiveNumber(counts?.occurrenceCount) && (
<Tag>
<FormattedMessage id="tableHeaders.occurrences" />:{' '}
<FormattedNumber value={counts.occurrenceCount} />
</Tag>
)}
</div>
</div>
<MapThumbnail
datasetKey={dataset.key}
x={0}
y={0}
z={0}
tileStyle="gbif-middle"
mapStyle="classic-noborder.poly"
format="@1x.png"
srs="EPSG:3857"
bin="square"
squareSize={100}
/>
</article>
);
}

function Tag({ children }: { children: React.ReactNode }) {
return (
<span className="align-middle bg-slate-300/50 text-slate-800 text-xs font-medium me-2 px-2.5 py-0.5 rounded dark:bg-red-900 dark:text-red-300">
{children}
</span>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { ProgrammeFundingBannerFragment, ProjectFundingBannerFragment } from '@/gql/graphql';
import { fragmentManager } from '@/services/FragmentManager';
import { notNull } from '@/utils/notNull';
import { FormattedMessage } from 'react-intl';

fragmentManager.register(/* GraphQL */ `
fragment FundingOrganisationDetails on FundingOrganisation {
id
title
url
logo {
title
file {
url
}
}
}
`);

fragmentManager.register(/* GraphQL */ `
fragment ProgrammeFundingBanner on Programme {
__typename
fundingOrganisations {
...FundingOrganisationDetails
}
}
`);

fragmentManager.register(/* GraphQL */ `
fragment ProjectFundingBanner on GbifProject {
__typename
fundsAllocated
programme {
...ProgrammeFundingBanner
}
overrideProgrammeFunding {
...FundingOrganisationDetails
}
}
`);

type Props = {
resource: ProgrammeFundingBannerFragment | ProjectFundingBannerFragment;
};

export function FundingBanner({ resource }: Props) {
const fundingOrganisations =
resource.__typename === 'GbifProject'
? resource.overrideProgrammeFunding ?? resource.programme?.fundingOrganisations
: resource.fundingOrganisations;

const fundsAllocated =
resource.__typename === 'GbifProject' ? resource.fundsAllocated : undefined;

return (
<div className="bg-slate-100 mt-6 p-6 flex flex-col items-center">
<span className="text-gray-500 text-xs">
{fundsAllocated && `€ ${fundsAllocated} `}
<FormattedMessage id="cms.project.fundedBy" />
</span>

<div className="pt-6 flex gap-8 flex-wrap justify-center">
{fundingOrganisations?.filter(notNull).map((fundingOrganisation) => (
<div key={fundingOrganisation.id}>
<a href={fundingOrganisation.url!} className="flex flex-col items-center group">
<img
className="max-w-28"
src={fundingOrganisation.logo?.file.url}
/>
<span className="text-gray-500 text-sm pt-2 group-hover:underline">
{fundingOrganisation.title}
</span>
</a>
</div>
))}
</div>
</div>
);
}
32 changes: 32 additions & 0 deletions packages/gbif-org/src/routes/resource/key/components/HelpLine.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { MdInfoOutline } from 'react-icons/md';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import { fragmentManager } from '@/services/FragmentManager';
import { HelpLineDetailsFragment } from '@/gql/graphql';

fragmentManager.register(/* GraphQL */ `
fragment HelpLineDetails on Help {
__typename
title
body
}
`);

type Props = {
help: HelpLineDetailsFragment;
};

export function HelpLine({ help }: Props) {
return (
<p className="pb-4 text-gray-600 text-sm text-right">
<Popover>
<PopoverTrigger>
{help.title} <MdInfoOutline />
</PopoverTrigger>
<PopoverContent
className="prose max-w-lg w-auto"
dangerouslySetInnerHTML={{ __html: help.body ?? '' }}
/>
</Popover>
</p>
);
}

0 comments on commit df71624

Please sign in to comment.