From b7c06f7b5dac198f648d669414bb1050d4623068 Mon Sep 17 00:00:00 2001 From: hegeaal Date: Thu, 7 Nov 2024 14:59:59 +0100 Subject: [PATCH] feat: add organization carousel to front page --- .../frontpage/organization-carousel/index.tsx | 71 +++++++++++++++++++ .../organization-carousel.module.scss | 14 ++++ .../organization-carousel/organizations.json | 35 +++++++++ .../frontpage/share-data-banner/index.tsx | 3 +- apps/data-norge/tsconfig.json | 66 +++++++++-------- .../src/lib/dictionaries/en/frontpage.json | 8 ++- .../src/lib/dictionaries/nb/frontpage.json | 8 ++- .../src/lib/dictionaries/nn/frontpage.json | 8 ++- 8 files changed, 178 insertions(+), 35 deletions(-) create mode 100644 apps/data-norge/src/app/components/frontpage/organization-carousel/index.tsx create mode 100644 apps/data-norge/src/app/components/frontpage/organization-carousel/organization-carousel.module.scss create mode 100644 apps/data-norge/src/app/components/frontpage/organization-carousel/organizations.json diff --git a/apps/data-norge/src/app/components/frontpage/organization-carousel/index.tsx b/apps/data-norge/src/app/components/frontpage/organization-carousel/index.tsx new file mode 100644 index 00000000..89cf3eeb --- /dev/null +++ b/apps/data-norge/src/app/components/frontpage/organization-carousel/index.tsx @@ -0,0 +1,71 @@ +'use client'; + +import organizations from './organizations.json'; +import styles from './organization-carousel.module.scss'; +import React, { useEffect, useState } from 'react'; +import { Popover } from '@digdir/designsystemet-react'; +import { Dictionary } from '@fdk-frontend/dictionaries'; + +type Props = { + dictionary: Dictionary; +}; + +const OrganizationCarousel = ({ dictionary }: Props) => { + const INITIAL_INDEX = 0; + const FADE_DURATION = 500; + const INTERVAL = 6000; + + const [currentIndex, setCurrentIndex] = useState(INITIAL_INDEX); + const [fade, setFade] = useState(true); + const [isPaused, setIsPaused] = useState(false); + const [open, setOpen] = useState(false); + const [shuffledOrganizations, setShuffledOrganizations] = useState([]); + + useEffect(() => { + const shuffled = [...organizations].sort(() => Math.random() - 0.5); + setShuffledOrganizations(shuffled); + }, []); + + const handleRotation = () => { + setFade(false); + setTimeout(() => { + setCurrentIndex((prevIndex) => (prevIndex + 1) % shuffledOrganizations.length); + setFade(true); + }, FADE_DURATION); + }; + + useEffect(() => { + if (isPaused) return; + const intervalId = setInterval(handleRotation, INTERVAL); + return () => clearInterval(intervalId); + }, [isPaused, currentIndex, shuffledOrganizations]); + + return ( +
+ + + setOpen(true)} + onMouseLeave={() => setOpen(false)} + onClick={() => setIsPaused((prevState) => !prevState)} + onKeyDown={(e) => e.key === 'Enter' && setIsPaused((prevState) => !prevState)} + className={`${fade ? styles['fade-in'] : styles['fade-out']}`} + > + {`${dictionary.shareDataBanner.doLike} ${shuffledOrganizations[currentIndex]}`} + + + + {isPaused ? dictionary.shareDataBanner.popover.start : dictionary.shareDataBanner.popover.pause} + + +
+ ); +}; + +export default OrganizationCarousel; diff --git a/apps/data-norge/src/app/components/frontpage/organization-carousel/organization-carousel.module.scss b/apps/data-norge/src/app/components/frontpage/organization-carousel/organization-carousel.module.scss new file mode 100644 index 00000000..0211ae2e --- /dev/null +++ b/apps/data-norge/src/app/components/frontpage/organization-carousel/organization-carousel.module.scss @@ -0,0 +1,14 @@ +.fade-in { + opacity: 1; + transition: + opacity 0.5s, + transform 1s; + transition-delay: 0.5s; +} + +.fade-out { + opacity: 0; + transition: + opacity 0.5s, + transform 1s; +} diff --git a/apps/data-norge/src/app/components/frontpage/organization-carousel/organizations.json b/apps/data-norge/src/app/components/frontpage/organization-carousel/organizations.json new file mode 100644 index 00000000..990bb8b3 --- /dev/null +++ b/apps/data-norge/src/app/components/frontpage/organization-carousel/organizations.json @@ -0,0 +1,35 @@ +[ + "Arbeids- og velferdsetaten", + "Arbeidstilsynet", + "Artsdatabanken", + "Bergen kommune", + "Digitaliseringsdirektoratet", + "Direktoratet for internasjonalisering og kvalitetsutvikling i høyere utdanning (DIKU)", + "Direktoratet for samfunnssikkerhet og beredskap (DSB)", + "Fiskeridirektoratet", + "Folkehelseinstituttet", + "Fredrikstad kommune", + "Havforskningsinstituttet", + "Høgskulen på Vestlandet", + "Kystverket", + "Landbruksdirektoratet", + "Mattilsynet", + "Meteorologisk institutt", + "Miljødirektoratet", + "Nasjonalbiblioteket", + "Nibio - Norsk Institutt for Bioøkonomi", + "Norges geologiske undersøkelse", + "Norges vassdrags- og energidirektorat (NVE)", + "Norsk polarinstitutt", + "Oslo kommune", + "Registerenheten i Brønnøysund", + "Riksantikvaren", + "Sokkeldirektoratet", + "Statens kartverk", + "Statens lånekasse for utdanning", + "Statens vegvesen", + "Statistisk sentralbyrå", + "Stavanger kommune", + "Tolletaten", + "Utdanningsdirektoratet" +] diff --git a/apps/data-norge/src/app/components/frontpage/share-data-banner/index.tsx b/apps/data-norge/src/app/components/frontpage/share-data-banner/index.tsx index 6e6ff232..afcb651f 100644 --- a/apps/data-norge/src/app/components/frontpage/share-data-banner/index.tsx +++ b/apps/data-norge/src/app/components/frontpage/share-data-banner/index.tsx @@ -4,6 +4,7 @@ import { Dictionary, interpolate, type LocaleCodes } from '@fdk-frontend/diction import { HeadingWithDivider } from '@fdk-frontend/ui/typography'; import styles from './share-data-banner.module.scss'; +import OrganizationCarousel from '../organization-carousel'; type ShareDataBannerProps = { dictionary: Dictionary; @@ -17,7 +18,7 @@ const ShareDataBanner = ({ dictionary, baseUri, locale }: ShareDataBannerProps) level={2} className={styles.headline} > - {dictionary.shareDataBanner.title} + {interpolate(dictionary.shareDataBanner.content, { diff --git a/apps/data-norge/tsconfig.json b/apps/data-norge/tsconfig.json index 04dae76a..162611ba 100644 --- a/apps/data-norge/tsconfig.json +++ b/apps/data-norge/tsconfig.json @@ -1,31 +1,41 @@ { - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "jsx": "preserve", - "allowJs": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "strict": true, - "forceConsistentCasingInFileNames": true, - "noEmit": true, - "resolveJsonModule": true, - "isolatedModules": true, - "incremental": true, - "plugins": [ - { - "name": "next" - } - ], - "types": ["jest", "node"] - }, - "include": [ - "**/*.ts", - "**/*.tsx", - "**/*.js", - "**/*.jsx", - "next-env.d.ts", - ".next/types/**/*.ts", - "../../dist/apps/data.norge.no/.next/types/**/*.ts" + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "jsx": "preserve", + "allowJs": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "resolveJsonModule": true, + "isolatedModules": true, + "incremental": true, + "plugins": [ + { + "name": "next" + } ], - "exclude": ["node_modules", "jest.config.ts", "**/*.spec.ts", "**/*.test.ts", "**/*.stories.tsx"] + "types": [ + "jest", + "node" + ] + }, + "include": [ + "**/*.ts", + "**/*.tsx", + "**/*.js", + "**/*.jsx", + "next-env.d.ts", + ".next/types/**/*.ts", + "../../dist/apps/data.norge.no/.next/types/**/*.ts", + "../../dist/apps/data-norge/.next/types/**/*.ts" + ], + "exclude": [ + "node_modules", + "jest.config.ts", + "**/*.spec.ts", + "**/*.test.ts", + "**/*.stories.tsx" + ] } diff --git a/libs/dictionaries/src/lib/dictionaries/en/frontpage.json b/libs/dictionaries/src/lib/dictionaries/en/frontpage.json index 07ccdfc9..3899cbd5 100644 --- a/libs/dictionaries/src/lib/dictionaries/en/frontpage.json +++ b/libs/dictionaries/src/lib/dictionaries/en/frontpage.json @@ -48,10 +48,14 @@ "title": "Our data catalogs" }, "shareDataBanner": { - "content": "Follow {{link}} and share your data with the rest of the country.", + "content": "...and {{link}} and share your data with the rest of the country.", "shareDataLinkText": "Share data", "documentationLinkText": "Help and guidance", "organizationsLinkText": "125 other organizations", - "title": "Share your data" + "doLike": "Do like", + "popover": { + "start": "Click to start the animation", + "pause": "Click to pause the animation" + } } } diff --git a/libs/dictionaries/src/lib/dictionaries/nb/frontpage.json b/libs/dictionaries/src/lib/dictionaries/nb/frontpage.json index 66476689..46e504a4 100644 --- a/libs/dictionaries/src/lib/dictionaries/nb/frontpage.json +++ b/libs/dictionaries/src/lib/dictionaries/nb/frontpage.json @@ -48,10 +48,14 @@ "title": "Våre datakataloger" }, "shareDataBanner": { - "content": "Gjør som over {{link}} og del dine data med resten av landet.", + "content": "...og over {{link}}, og del dine data med resten av landet.", "shareDataLinkText": "Del data", "documentationLinkText": "Hjelp og veiledning", "organizationsLinkText": "125 andre virksomheter", - "title": "Har du data å dele?" + "doLike": "Gjør som", + "popover": { + "start": "Klikk for å starte animasjonen", + "pause": "Klikk for å pause animasjonen" + } } } diff --git a/libs/dictionaries/src/lib/dictionaries/nn/frontpage.json b/libs/dictionaries/src/lib/dictionaries/nn/frontpage.json index e4738cfa..6b09139d 100644 --- a/libs/dictionaries/src/lib/dictionaries/nn/frontpage.json +++ b/libs/dictionaries/src/lib/dictionaries/nn/frontpage.json @@ -48,10 +48,14 @@ "title": "Våre datakatalogar" }, "shareDataBanner": { - "content": "Gjer som over {{link}} og del dine data med resten av landet.", + "content": "...og over {{link}}, og del dine data med resten av landet.", "shareDataLinkText": "Del data", "documentationLinkText": "Hjelp og rettleiing", "organizationsLinkText": "125 andre verksemder", - "title": "Har du data å dele?" + "doLike": "Gjer som", + "popover": { + "start": "Klikk for å starte animasjonen", + "pause": "Klikk for å pause animasjonen" + } } }