feat(SW-187): Added social media data and copyright label

This commit is contained in:
Pontus Dreij
2024-09-05 09:34:02 +02:00
parent 2c37bbad55
commit c033f776b6
17 changed files with 144 additions and 91 deletions

View File

@@ -3,12 +3,14 @@ import Image from "@/components/Image"
import LanguageSwitcher from "@/components/LanguageSwitcher" import LanguageSwitcher from "@/components/LanguageSwitcher"
import Link from "@/components/TempDesignSystem/Link" import Link from "@/components/TempDesignSystem/Link"
import Footnote from "@/components/TempDesignSystem/Text/Footnote" import Footnote from "@/components/TempDesignSystem/Text/Footnote"
import { getIntl } from "@/i18n"
import { getLang } from "@/i18n/serverContext" import { getLang } from "@/i18n/serverContext"
import { footer } from "../mockedData" import { footer } from "../mockedData"
import styles from "./details.module.css" import styles from "./details.module.css"
import type { FooterDetailsProps } from "@/types/components/footer/navigation"
import type { SocialIconsProps } from "@/types/components/footer/socialIcons" import type { SocialIconsProps } from "@/types/components/footer/socialIcons"
import { IconName } from "@/types/components/icon" import { IconName } from "@/types/components/icon"
@@ -17,16 +19,13 @@ function SocialIcon({ iconName }: SocialIconsProps) {
return SocialIcon ? <SocialIcon color="white" /> : <span>{iconName}</span> return SocialIcon ? <SocialIcon color="white" /> : <span>{iconName}</span>
} }
export default function FooterDetails() { export default async function FooterDetails({
socialMedia,
}: FooterDetailsProps) {
const lang = getLang() const lang = getLang()
const { formatMessage } = await getIntl()
const currentYear = new Date().getFullYear() const currentYear = new Date().getFullYear()
const { const { tertiaryLinks, languageSwitcher } = footer
socialMedia,
copyrightCompany,
copyrightInfo,
tertiaryLinks,
languageSwitcher,
} = footer
return ( return (
<section className={styles.details}> <section className={styles.details}>
<div className={styles.topContainer}> <div className={styles.topContainer}>
@@ -43,27 +42,28 @@ export default function FooterDetails() {
/> />
</Link> </Link>
<nav className={styles.socialNav}> <nav className={styles.socialNav}>
{socialMedia.links.map((link) => ( {socialMedia?.links.map(
<a (link) =>
className={styles.socialLink} link.href && (
color="white" <a
href={link.href} className={styles.socialLink}
key={link.id} color="white"
target="_blank" href={link.href.href}
aria-label={link.title} key={link.href.title}
> target="_blank"
<SocialIcon iconName={link.title} /> aria-label={link.href.title}
</a> >
))} <SocialIcon iconName={link.href.title} />
</a>
)
)}
</nav> </nav>
</div> </div>
<div className={styles.bottomContainer}> <div className={styles.bottomContainer}>
<div className={styles.copyrightContainer}> <div className={styles.copyrightContainer}>
<Footnote textTransform="uppercase"> <Footnote textTransform="uppercase">
© {currentYear} {copyrightCompany} © {currentYear}{" "}
</Footnote> {formatMessage({ id: "Copyright all rights reserved" })}
<Footnote textTransform="uppercase" color="peach50">
{copyrightInfo}
</Footnote> </Footnote>
</div> </div>
<div className={styles.navigationContainer}> <div className={styles.navigationContainer}>
@@ -81,9 +81,6 @@ export default function FooterDetails() {
</Footnote> </Footnote>
))} ))}
</nav> </nav>
{
// This will be changed to the new LangueSwitcher that is done in the header branch, when implementing contentstack
}
<LanguageSwitcher type="desktopFooter" urls={languageSwitcher.urls} /> <LanguageSwitcher type="desktopFooter" urls={languageSwitcher.urls} />
</div> </div>
</div> </div>

View File

@@ -5,46 +5,49 @@ import { getLang } from "@/i18n/serverContext"
import styles from "./secondarynav.module.css" import styles from "./secondarynav.module.css"
import { import { AppDownLoadLinks } from "@/types/components/footer/appDownloadIcons"
AppDownLoadLinks, import { type FooterSecondaryNavProps } from "@/types/components/footer/navigation"
type FooterSecondaryNavProps,
} from "@/types/components/footer/navigation"
export default function FooterSecondaryNav({ export default function FooterSecondaryNav({
secondaryLinks, secondaryLinks,
appDownloads, appDownloads,
}: FooterSecondaryNavProps) { }: FooterSecondaryNavProps) {
const lang = getLang() const lang = getLang()
console.log("hej", JSON.stringify(secondaryLinks, null, 4))
return ( return (
<div className={styles.secondaryNavigation}> <div className={styles.secondaryNavigation}>
<nav className={styles.secondaryNavigationGroup}> {appDownloads && (
<Body color="peach80" textTransform="uppercase"> <nav className={styles.secondaryNavigationGroup}>
{appDownloads.title} <Body color="peach80" textTransform="uppercase">
</Body> {appDownloads.title}
<ul className={styles.secondaryNavigationList}> </Body>
{appDownloads.links.map((link) => ( <ul className={styles.secondaryNavigationList}>
<li key={link.type} className={styles.appDownloadItem}> {appDownloads.links.map(
<a (link) =>
href={link.href.href} link.href && (
target="_blank" <li key={link.type} className={styles.appDownloadItem}>
aria-label={link.href.title} <a
> href={link.href.href}
<Image target="_blank"
src={ aria-label={link.href.title}
AppDownLoadLinks[ >
`${link.type}_${lang}` as keyof typeof AppDownLoadLinks <Image
] src={
} AppDownLoadLinks[
alt={link.href.title} `${link.type}_${lang}` as keyof typeof AppDownLoadLinks
width={125} ]
height={40} }
/> alt={link.href.title}
</a> width={125}
</li> height={40}
))} />
</ul> </a>
</nav> </li>
)
)}
</ul>
</nav>
)}
{secondaryLinks.map((link) => ( {secondaryLinks.map((link) => (
<nav className={styles.secondaryNavigationGroup} key={link.title}> <nav className={styles.secondaryNavigationGroup} key={link.title}>
<Body color="peach80" textTransform="uppercase"> <Body color="peach80" textTransform="uppercase">
@@ -52,7 +55,7 @@ export default function FooterSecondaryNav({
</Body> </Body>
<ul className={styles.secondaryNavigationList}> <ul className={styles.secondaryNavigationList}>
{link?.links?.map((link) => ( {link?.links?.map((link) => (
<li key={link.id} className={styles.secondaryNavigationItem}> <li key={link.title} className={styles.secondaryNavigationItem}>
{link.isExternal ? ( {link.isExternal ? (
<a <a
href={link.url} href={link.url}

View File

@@ -3,9 +3,13 @@ import FooterSecondaryNav from "./SecondaryNav"
import styles from "./navigation.module.css" import styles from "./navigation.module.css"
export default function FooterNavigation({ ...props }) { import type { FooterNavigationProps } from "@/types/components/footer/navigation"
const { mainLinks, secondaryLinks, appDownloads } = props
export default function FooterNavigation({
mainLinks,
secondaryLinks,
appDownloads,
}: FooterNavigationProps) {
return ( return (
<section className={styles.section}> <section className={styles.section}>
<div className={styles.maxWidth}> <div className={styles.maxWidth}>

View File

@@ -10,12 +10,16 @@ export default async function Footer() {
lang: getLang(), lang: getLang(),
}) })
if (!footerData) { if (!footerData) {
return null return <FooterDetails />
} }
return ( return (
<footer> <footer>
<FooterNavigation {...footerData} /> <FooterNavigation
<FooterDetails /> mainLinks={footerData.mainLinks}
secondaryLinks={footerData.secondaryLinks}
appDownloads={footerData.appDownloads}
/>
<FooterDetails socialMedia={footerData.socialMedia} />
</footer> </footer>
) )
} }

View File

@@ -42,6 +42,7 @@
"Compare all levels": "Sammenlign alle niveauer", "Compare all levels": "Sammenlign alle niveauer",
"Contact us": "Kontakt os", "Contact us": "Kontakt os",
"Continue": "Blive ved", "Continue": "Blive ved",
"Copyright all rights reserved": "Scandic AB Alle rettigheder forbeholdes",
"Could not find requested resource": "Kunne ikke finde den anmodede ressource", "Could not find requested resource": "Kunne ikke finde den anmodede ressource",
"Country": "Land", "Country": "Land",
"Country code": "Landekode", "Country code": "Landekode",

View File

@@ -41,6 +41,7 @@
"Compare all levels": "Vergleichen Sie alle Levels", "Compare all levels": "Vergleichen Sie alle Levels",
"Contact us": "Kontaktieren Sie uns", "Contact us": "Kontaktieren Sie uns",
"Continue": "Weitermachen", "Continue": "Weitermachen",
"Copyright all rights reserved": "Scandic AB Alle Rechte vorbehalten",
"Could not find requested resource": "Die angeforderte Ressource konnte nicht gefunden werden.", "Could not find requested resource": "Die angeforderte Ressource konnte nicht gefunden werden.",
"Country": "Land", "Country": "Land",
"Country code": "Landesvorwahl", "Country code": "Landesvorwahl",

View File

@@ -42,6 +42,7 @@
"Compare all levels": "Compare all levels", "Compare all levels": "Compare all levels",
"Contact us": "Contact us", "Contact us": "Contact us",
"Continue": "Continue", "Continue": "Continue",
"Copyright all rights reserved": "Scandic AB All rights reserved",
"Could not find requested resource": "Could not find requested resource", "Could not find requested resource": "Could not find requested resource",
"Country": "Country", "Country": "Country",
"Country code": "Country code", "Country code": "Country code",

View File

@@ -42,6 +42,7 @@
"Compare all levels": "Vertaa kaikkia tasoja", "Compare all levels": "Vertaa kaikkia tasoja",
"Contact us": "Ota meihin yhteyttä", "Contact us": "Ota meihin yhteyttä",
"Continue": "Jatkaa", "Continue": "Jatkaa",
"Copyright all rights reserved": "Scandic AB Kaikki oikeudet pidätetään",
"Could not find requested resource": "Pyydettyä resurssia ei löytynyt", "Could not find requested resource": "Pyydettyä resurssia ei löytynyt",
"Country": "Maa", "Country": "Maa",
"Country code": "Maatunnus", "Country code": "Maatunnus",

View File

@@ -42,6 +42,7 @@
"Compare all levels": "Sammenlign alle nivåer", "Compare all levels": "Sammenlign alle nivåer",
"Contact us": "Kontakt oss", "Contact us": "Kontakt oss",
"Continue": "Fortsette", "Continue": "Fortsette",
"Copyright all rights reserved": "Scandic AB Alle rettigheter forbeholdt",
"Could not find requested resource": "Kunne ikke finne den forespurte ressursen", "Could not find requested resource": "Kunne ikke finne den forespurte ressursen",
"Country": "Land", "Country": "Land",
"Country code": "Landskode", "Country code": "Landskode",

View File

@@ -42,6 +42,7 @@
"Compare all levels": "Jämför alla nivåer", "Compare all levels": "Jämför alla nivåer",
"Contact us": "Kontakta oss", "Contact us": "Kontakta oss",
"Continue": "Fortsätt", "Continue": "Fortsätt",
"Copyright all rights reserved": "Scandic AB Alla rättigheter förbehålls",
"Could not find requested resource": "Det gick inte att hitta den begärda resursen", "Could not find requested resource": "Det gick inte att hitta den begärda resursen",
"Country": "Land", "Country": "Land",
"Country code": "Landskod", "Country code": "Landskod",

View File

@@ -0,0 +1,11 @@
fragment SocialMedia on Footer {
social_media {
links {
href {
href
title
}
type
}
}
}

View File

@@ -1,6 +1,7 @@
#import "../Fragments/Footer/AppDownloads.graphql" #import "../Fragments/Footer/AppDownloads.graphql"
#import "../Fragments/Footer/MainLinks.graphql" #import "../Fragments/Footer/MainLinks.graphql"
#import "../Fragments/Footer/SecondaryLinks.graphql" #import "../Fragments/Footer/SecondaryLinks.graphql"
#import "../Fragments/Footer/SocialMedia.graphql"
#import "../Fragments/Footer/Refs/MainLinks.graphql" #import "../Fragments/Footer/Refs/MainLinks.graphql"
#import "../Fragments/Footer/Refs/SecondaryLinks.graphql" #import "../Fragments/Footer/Refs/SecondaryLinks.graphql"
#import "../Fragments/Refs/System.graphql" #import "../Fragments/Refs/System.graphql"
@@ -11,6 +12,7 @@ query GetFooter($locale: String!) {
...MainLinks ...MainLinks
...SecondaryLinks ...SecondaryLinks
...AppDownloads ...AppDownloads
...SocialMedia
} }
} }
} }

View File

@@ -309,6 +309,14 @@ export const validateFooterConfigSchema = z.object({
links: z.array(validateLinkItem), links: z.array(validateLinkItem),
}) })
), ),
social_media: z.object({
links: z.array(
z.object({
type: z.string(),
href: validateExternalLink,
})
),
}),
}) })
), ),
}), }),

View File

@@ -440,6 +440,7 @@ export const baseQueryRouter = router({
mainLinks: mainLinks, mainLinks: mainLinks,
appDownloads: validatedFooterData.app_downloads, appDownloads: validatedFooterData.app_downloads,
secondaryLinks: secondaryLinks, secondaryLinks: secondaryLinks,
socialMedia: validatedFooterData.social_media,
} }
}), }),
}) })

View File

@@ -9,6 +9,7 @@ export function transformPageConnectionLinks(links: FooterLinkItem[]) {
title: edge.node.title || "", title: edge.node.title || "",
url: edge.node.url || "", url: edge.node.url || "",
openInNewTab: link.open_in_new_tab, openInNewTab: link.open_in_new_tab,
isExternal: false,
})) }))
} else if (link.link) { } else if (link.link) {
return [ return [
@@ -16,6 +17,7 @@ export function transformPageConnectionLinks(links: FooterLinkItem[]) {
title: link.link.title, title: link.link.title,
url: link.link.href, url: link.link.href,
openInNewTab: link.open_in_new_tab, openInNewTab: link.open_in_new_tab,
isExternal: true,
}, },
] ]
} }

View File

@@ -0,0 +1,14 @@
export enum AppDownLoadLinks {
apple_da = "/_static/img/app-store-badge-da.svg",
apple_de = "/_static/img/app-store-badge-de.svg",
apple_en = "/_static/img/app-store-badge-en.svg",
apple_fi = "/_static/img/app-store-badge-fi.svg",
apple_no = "/_static/img/app-store-badge-no.svg",
apple_sv = "/_static/img/app-store-badge-sv.svg",
google_da = "/_static/img/google-play-badge-da.svg",
google_de = "/_static/img/google-play-badge-de.svg",
google_en = "/_static/img/google-play-badge-en.svg",
google_fi = "/_static/img/google-play-badge-fi.svg",
google_no = "/_static/img/google-play-badge-no.svg",
google_sv = "/_static/img/google-play-badge-sv.svg",
}

View File

@@ -7,40 +7,41 @@ export type FooterMainNavProps = {
} }
export type FooterSecondaryNav = { export type FooterSecondaryNav = {
id: string
isExternal: boolean isExternal: boolean
openInNewTab: boolean openInNewTab: boolean
title: string title: string
url: string url: string
} }
export type FooterSecondaryNavProps = { type FooterSecondaryNavGroup = {
secondaryLinks: { title: string
title: string links: FooterSecondaryNav[]
links: FooterSecondaryNav[] }
}[] type FooterLinkWithType = {
appDownloads: { href?:
title: string | {
links: {
href: {
href: string href: string
title: string title: string
} }
type: string | undefined
}[] type: string
}
} }
export enum AppDownLoadLinks { type FooterAppDownloads = {
apple_da = "/_static/img/app-store-badge-da.svg", title: string
apple_de = "/_static/img/app-store-badge-de.svg", links: FooterLinkWithType[]
apple_en = "/_static/img/app-store-badge-en.svg",
apple_fi = "/_static/img/app-store-badge-fi.svg",
apple_no = "/_static/img/app-store-badge-no.svg",
apple_sv = "/_static/img/app-store-badge-sv.svg",
google_da = "/_static/img/google-play-badge-da.svg",
google_de = "/_static/img/google-play-badge-de.svg",
google_en = "/_static/img/google-play-badge-en.svg",
google_fi = "/_static/img/google-play-badge-fi.svg",
google_no = "/_static/img/google-play-badge-no.svg",
google_sv = "/_static/img/google-play-badge-sv.svg",
} }
type FooterSocialMedia = {
links: FooterLinkWithType[]
}
export type FooterSecondaryNavProps = {
secondaryLinks: FooterSecondaryNavGroup[]
appDownloads: FooterAppDownloads
}
export type FooterDetailsProps = {
socialMedia?: FooterSocialMedia
}
export type FooterNavigationProps = FooterMainNavProps & FooterSecondaryNavProps