diff --git a/app/installation/page.tsx b/app/installation/page.tsx index cc49a37..08ce391 100644 --- a/app/installation/page.tsx +++ b/app/installation/page.tsx @@ -7,6 +7,7 @@ import { } from '@heroicons/react/24/outline'; import Image from 'next/image'; import { useState } from 'react'; +import CircularButton from '../ui/components/circular-button'; import Data4HealthCoder from './components/Data4HealthCoder'; import Data4HealthNonCoder from './components/Data4HealthNonCoder'; @@ -41,54 +42,7 @@ interface SubButtonConfig { } -function CircularButton({ icon, label, onClick, isImage = false, isActive = false }: CircularButtonProps) { - const Icon = icon as React.ElementType; // For when icon is a component - return ( -
-
{ - if (e.key === 'Enter' || e.key === ' ') { - e.preventDefault(); - onClick(); - } - }} - className={`cursor-pointer transform transition-all duration-300 ease-in-out hover:scale-110 hover:shadow-lg rounded-full p-4 w-24 h-24 flex items-center justify-center - ${isActive - ? 'bg-purple-100 shadow-lg scale-105 rotate-3' - : 'hover:bg-purple-50 hover:rotate-3'}`} - > - {isImage ? ( - {label} - ) : ( - // allow passing a simple string (emoji) as icon - typeof icon === 'string' ? ( - - {icon} - - ) : ( - - ) - )} -
- - {label} - -
- ); -} +// CircularButton is now a shared component in app/ui/components/circular-button.tsx interface SubButtonsProps { section: Section; @@ -184,6 +138,14 @@ function InstallationContent({ section, type }: InstallationContentProps) { export default function Page() { const [activeSection, setActiveSection] = useState
(null); const [activeInstallType, setActiveInstallType] = useState<'coder' | 'noncoder' | null>(null); + // Toggle buttons by editing this map in code. Set true to disable, false to enable. + const disabledMap: Record = { + data4health: false, + clim4health: false, + land4health: false, + socio4health: false, + cube4health: false, + }; const handleToolkitClick = (section: Section) => { if (section === activeSection) { @@ -207,41 +169,27 @@ export default function Page() {

- handleToolkitClick('data4health')} - isImage={true} - isActive={activeSection === 'data4health'} - /> - handleToolkitClick('clim4health')} - isImage={true} - isActive={activeSection === 'clim4health'} - /> - handleToolkitClick('land4health')} - isImage={true} - isActive={activeSection === 'land4health'} - /> - handleToolkitClick('socio4health')} - isImage={true} - isActive={activeSection === 'socio4health'} - /> - handleToolkitClick('cube4health')} - isImage={true} - isActive={false} - /> + {[ + { key: 'data4health', logo: D4H_LOGO, label: 'data4Health' }, + { key: 'clim4health', logo: C4H_LOGO, label: 'clim4health' }, + { key: 'land4health', logo: L4H_LOGO, label: 'land4health' }, + { key: 'socio4health', logo: S4H_LOGO, label: 'socio4health' }, + { key: 'cube4health', logo: CU4H_LOGO, label: 'cube4health' }, + ].map((tk) => { + const section = tk.key as Section; + return ( +
+ handleToolkitClick(section)} + isImage={true} + isActive={activeSection === section} + disabled={disabledMap[section]} + /> +
+ ); + })}
{activeSection && ( diff --git a/app/trainings/page.tsx b/app/trainings/page.tsx new file mode 100644 index 0000000..a4dffbe --- /dev/null +++ b/app/trainings/page.tsx @@ -0,0 +1,170 @@ +'use client'; + +import React from 'react'; +import Image from 'next/image'; +import { useState } from 'react'; +import CircularButton from '../ui/components/circular-button'; +import DownloadButton from '../ui/components/download-button'; + +const D4H_LOGO = '/cards/toolkits/data4health.svg'; +const C4H_LOGO = '/cards/toolkits/clim4health.svg'; +const L4H_LOGO = '/cards/toolkits/land4health.svg'; +const S4H_LOGO = '/cards/toolkits/socio4health.svg'; +const CU4H_LOGO = '/cards/toolkits/cube4health.svg'; + + +type Section = 'data4health' | 'clim4health' | 'land4health' | 'socio4health' | 'cube4health'; + +interface CircularButtonProps { + icon: React.ElementType | string; + label: string; + onClick: () => void; + isImage?: boolean; + isActive?: boolean; + size?: 'sm' | 'md'; +} + + +function SubButtons({ section }: { section: Section }) { + const resources: Record }> = { + data4health: { + pdf: '/training/data4health-training.pdf', + related: [ + //{ label: 'Quickstart (download)', href: '/cards/toolkits/data4health-quickstart.zip', isFile: true }, + //{ label: 'Online docs', href: 'https://example.org/data4health' }, + ], + }, + clim4health: { + pdf: '/training/clim4health-training.pdf', + related: [ + { label: 'Clim4Health training files', href: '/training/clim4health_for_website.zip', isFile: true, useButton: true }, + ], + }, + land4health: { + pdf: '/cards/toolkits/land4health-installation.pdf', + related: [ + { label: 'Land4Health dataset', href: '/cards/toolkits/land4health-dataset.zip', isFile: true }, + { label: 'Documentation', href: 'https://example.org/land4health' }, + ], + }, + socio4health: { + pdf: '/cards/toolkits/socio4health-installation.pdf', + related: [ + { label: 'Socio4Health notes (download)', href: '/cards/toolkits/socio4health-notes.pdf', isFile: true }, + { label: 'Website', href: 'https://example.org/socio4health' }, + ], + }, + cube4health: { + pdf: '/training/cube4health-training.pdf', + related: [ + //{ label: 'Cube4Health examples', href: '/cards/toolkits/cube4health-examples.zip', isFile: true }, + //{ label: 'Repo', href: 'https://example.org/cube4health' }, + ], + }, + }; + + const entry = resources[section]; + + return ( +
+ + {entry?.pdf ? ( +
+ {/* The iframe/embed will show the PDF. If the PDF isn't present, users + can use the link below to open/download it. */} +