Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add styling for new footer component #916

Merged
merged 14 commits into from
Dec 12, 2024
7 changes: 7 additions & 0 deletions messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,12 @@
"job_posting": {
"office": "Office",
"all": "All"
},
"footer": {
"text": "We have multiple offices in Norway and Sweden. Feel free to drop by for a cup of coffee or just a friendly chat.",
"mainMenu": "Main menu",
"other": "Other",
"socialMedia": "Follow us",
"contact": "General contact"
}
}
7 changes: 7 additions & 0 deletions messages/no.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,12 @@
"job_posting": {
"office": "Kontor",
"all": "Alle"
},
"footer": {
"text": "Vi har flere kontorer i Norge og Sverige. Kom gjerne innom for en kopp kaffe eller bare en hyggelig prat.",
"mainMenu": "Hovedmeny",
"other": "Annet",
"socialMedia": "Følg oss",
"contact": "Generell kontakt"
}
}
7 changes: 7 additions & 0 deletions messages/se.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,12 @@
"job_posting": {
"office": "Kontor",
"all": "Alla"
},
"footer": {
"text": "Vi har flera kontor i Sverige och Norge. Du är välkommen att komma förbi för en kopp kaffe eller bara en trevlig pratstund.",
"mainMenu": "Huvudmeny",
"other": "Övrigt",
"socialMedia": "Följ oss",
"contact": "Kontakt"
}
}
16 changes: 14 additions & 2 deletions src/app/(main)/[locale]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,17 @@ import SkipToMain from "src/components/skipToMain/SkipToMain";
import { Locale, routing } from "src/i18n/routing";
import { getDraftModeInfo } from "src/utils/draftmode";
import { BrandAssets } from "studio/lib/interfaces/brandAssets";
import { CompanyInfo } from "studio/lib/interfaces/companyDetails";
import {
CompanyInfo,
CompanyLocation,
} from "studio/lib/interfaces/companyDetails";
import { LegalDocument } from "studio/lib/interfaces/legalDocuments";
import { Navigation } from "studio/lib/interfaces/navigation";
import { SocialMediaProfiles } from "studio/lib/interfaces/socialMedia";
import LiveVisualEditing from "studio/lib/loaders/AutomaticVisualEditing";
import {
COMPANY_INFO_QUERY,
COMPANY_LOCATIONS_QUERY,
LEGAL_DOCUMENTS_BY_LANG_QUERY,
} from "studio/lib/queries/admin";
import {
Expand Down Expand Up @@ -57,6 +61,7 @@ export default async function Layout({
initialSoMe,
initialLegal,
initialBrandAssets,
initialCompanyLocations,
] = await Promise.all([
loadStudioQuery<Navigation>(
NAV_QUERY,
Expand All @@ -75,6 +80,11 @@ export default async function Layout({
{ perspective },
),
loadStudioQuery<BrandAssets>(BRAND_ASSETS_QUERY, {}, { perspective }),
loadStudioQuery<CompanyLocation[]>(
COMPANY_LOCATIONS_QUERY,
{},
{ perspective },
),
]);

const hasNavData = hasValidData(initialNav.data);
Expand All @@ -95,13 +105,15 @@ export default async function Layout({
initialSoMe={initialSoMe}
initialLegal={initialLegal}
language={params.locale}
initialCompanyLocations={initialCompanyLocations}
/>
) : (
<Footer
navigationData={initialNav.data}
legalData={initialLegal.data}
companyInfo={initialCompanyInfo.data}
brandAssets={initialBrandAssets.data}
companyLocations={initialCompanyLocations.data}
/* brandAssets={initialBrandAssets.data} */
soMeData={initialSoMe.data}
/>
)}
Expand Down
22 changes: 20 additions & 2 deletions src/components/link/CustomLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ import { ILink } from "studio/lib/interfaces/navigation";

import styles from "./link.module.css";

type ComponentLinkType = "link" | "headerLink" | "footerLink";
type ComponentLinkType =
| "link"
| "headerLink"
| "footerLink"
| "footerLinkNew"
| "footerLinkGrey";

interface ICustomLink {
type?: ComponentLinkType;
Expand Down Expand Up @@ -80,7 +85,20 @@ const CustomLink = ({
rel={rel}
aria-label={link.ariaLabel}
>
<span className={styles.dot}></span>
{link.linkTitle}
</Link>
)
);
case "footerLinkGrey":
return (
link.linkTitle && (
<Link
className={styles.footerLinkGrey}
href={href}
target={target}
rel={rel}
aria-label={link.ariaLabel}
>
{link.linkTitle}
</Link>
)
Expand Down
25 changes: 18 additions & 7 deletions src/components/link/link.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -175,19 +175,30 @@
}

.footerLink {
color: var(--text-primary-light);
color: var(--stroke-primary);
cursor: pointer;
text-decoration: none;
font-family: var(--font-britti-sans);
font-size: 2rem;
font-weight: 400;
font-size: 1.125rem;
font-style: normal;
font-weight: 500;
line-height: 120%;

&:hover {
font-weight: 500;
text-decoration: underline;
}
}

&:active {
color: var(--background-bg-light-secondary);
.footerLinkGrey {
color: var(--text-tertiary);
cursor: pointer;
font-family: var(--font-britti-sans);
font-size: 0.875rem;
font-weight: 400;
text-decoration-line: underline;
text-decoration-style: solid;

&:hover {
color: var(--text-primary);
}
}

Expand Down
172 changes: 119 additions & 53 deletions src/components/navigation/footer/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,90 +1,156 @@
"use client";

import Image from "next/image";
import Link from "next/link";
import { useTranslations } from "next-intl";
import { ReactNode } from "react";

import { SanityImage } from "src/components/image/SanityImage";
import CustomLink from "src/components/link/CustomLink";
import SoMeLink from "src/components/link/SoMeLink";
import Text from "src/components/text/Text";
import { BrandAssets } from "studio/lib/interfaces/brandAssets";
import { CompanyInfo } from "studio/lib/interfaces/companyDetails";
import {
CompanyInfo,
CompanyLocation,
} from "studio/lib/interfaces/companyDetails";
import { LegalDocument } from "studio/lib/interfaces/legalDocuments";
import { ILink, LinkType, Navigation } from "studio/lib/interfaces/navigation";
import { ILink, Navigation } from "studio/lib/interfaces/navigation";
import {
SocialMediaLink,
SocialMediaProfiles,
} from "studio/lib/interfaces/socialMedia";

import styles from "./footer.module.css";
import { FooterIllustration } from "./footerIllustration/FooterIllustration";
import { FooterSection } from "./footerSection/FooterSection";
import { TextTertiary } from "./textTertiary/TextTertiary";

export interface IFooter {
navigationData: Navigation;
companyInfo: CompanyInfo;
brandAssets: BrandAssets;
soMeData: SocialMediaProfiles | null;
legalData: LegalDocument[];
companyInfo: CompanyInfo;
companyLocations: CompanyLocation[];
}

const Footer = ({
navigationData,
companyInfo,
brandAssets,
soMeData,
legalData,
/* legalData, */
companyInfo,
companyLocations,
}: IFooter) => {
const currentYear = new Date().getFullYear();
const t = useTranslations("footer");

return (
<footer className={styles.footer}>
{brandAssets?.secondaryLogo && (
<div className={styles.logo}>
<SanityImage image={brandAssets.secondaryLogo} />
</div>
)}
<nav className={styles.nav}>
{renderLinks(navigationData)}
{soMeData && renderSoMe(navigationData, soMeData)}
</nav>
<ul className={styles.credits}>
<li key="credit-legal-key-1">
<Text className={styles.whiteColor}>
{`© ${currentYear} ${companyInfo.companyName}`}
</Text>
</li>
{legalData?.map((legal) => {
const link: ILink = {
_key: legal._id,
_type: legal._type,
linkTitle: legal.basicTitle,
linkType: LinkType.Internal,
internalLink: {
_ref: legal.slug.current,
},
language: legal.language,
};
return (
<li key={legal._id}>
<CustomLink link={link} type="footerLink" />
<FooterIllustration color={"#FFD02F"} />
<div className={styles.footerContent}>
<nav className={styles.nav}>
<div className={styles.flex_container_left}>
<div>
<TextTertiary>{t("text")}</TextTertiary>
{/* TODO:: Get offices and map through. Should these link to something? */}
<ul className={styles.offices}>
{companyLocations.map((location) => (
<li
key={location.companyLocationName}
className={styles.dotSeparator}
>
{location.companyLocationName}
</li>
))}
</ul>
</div>
<div>
<FooterSection title={t("contact")}>
<Link
href={`mailto:${companyInfo.companyEmail}`}
className={styles.contactInfo}
>
{companyInfo.companyEmail}
</Link>
</FooterSection>
</div>
</div>
<div className={styles.flex_container_right}>
{navigationData.main && (
<FooterSection title={t("mainMenu")}>
{renderPageLinks(navigationData)}
</FooterSection>
)}
{navigationData.footer && (
<FooterSection title={t("other")}>
{renderOtherLinks(navigationData)}
</FooterSection>
)}

{soMeData && (
<FooterSection title={t("socialMedia")}>
{renderSoMe(navigationData, soMeData)}
</FooterSection>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typically this should be a component to utilise react properly, but can be fixed later

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, there are also a few things that can be done to make this more dynamic and utilize the connection to Sanity better, but I would rather get a version of this out now, and then we can make it even better later 👌

Regarding max-width I wasn't quite sure if it should have it or not, as some footers span the width of the page, but it won't be a problem to add it if we see that it's too big in relation to other content

)}
</div>
</nav>
<Image
className={styles.logo}
src={"/_assets/variant-logo.svg"}
alt={"variant logo"}
width={310}
height={74}
/>

<div className={styles.grey_links}>
{/* <ul className={styles.grey_links__language}>
<li>
<CustomLink link={dummyLink("English")} type="footerLink" />
</li>
);
})}
</ul>
</ul> */}
{/* THERE ARE NO LEGAL DOCUMENTS FOR LAUNCH, REINSTATE WHEN WE HAVE LEGAL DOCUMENTS TO SHOW */}
{/* <ul className={styles.credits}>
{legalData?.map((legal) => {
const link: ILink = {
_key: legal._id,
_type: legal._type,
linkTitle: legal.basicTitle,
linkType: LinkType.Internal,
internalLink: {
_ref: legal.slug.current,
},
language: legal.language,
};
return (
<li key={legal._id}>
<CustomLink link={link} type="footerLink" />
</li>
);
})}
</ul> */}

<span className={styles.organisationNumber}>
Org. nr. {companyInfo.organizationNumber}
</span>
</div>
</div>
</footer>
);
};

const renderLinks = (data: Navigation) => {
const contentSections = filterSectionsByType(data, "content");
const links = contentSections?.[0]?.linksAndContent;
return (
links &&
renderList(
links.map((link: ILink) => (
const renderOtherLinks = (data: Navigation) => {
return renderList(
data.footer?.map((footer) =>
footer.linksAndContent?.map((link: ILink) => (
<li key={link._key}>
<CustomLink link={link} type="footerLink" />
</li>
)),
)
),
);
};

const renderPageLinks = (data: Navigation) => {
return renderList(
data.main.map((p: ILink) => (
<li key={p._key}>
<CustomLink link={p} type="footerLink" />
</li>
)),
);
};

Expand Down
Loading
Loading