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

v3 - announcement banner #843

Merged
merged 2 commits into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/components/link/CustomLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ interface ICustomLink {
link: ILink;
isSelected?: boolean;
size?: "normal" | "small";
color?: "dark" | "light";
}

const CustomLink = ({
type = "link",
link,
isSelected,
size = "normal",
color = "dark",
}: ICustomLink) => {
const href = getHref(link);
const newTab = link.newTab;
Expand All @@ -35,7 +37,9 @@ const CustomLink = ({
(type === "link" ? (
<div
className={
styles.wrapper + (size === "small" ? ` ${styles.sizeSmall}` : "")
styles.wrapper +
(size === "small" ? ` ${styles.sizeSmall}` : "") +
(color === "light" ? ` ${styles.colorLight}` : "")
}
>
<Link
Expand Down
20 changes: 20 additions & 0 deletions src/components/link/link.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,24 @@
border-radius: 1.5625rem;
}

.sizeSmall.wrapper {
gap: 0;
}

.underline {
width: 100%;
height: 0.0625rem;
background-color: var(--primary-black);
}

.colorLight .underline {
background-color: var(--primary-white);
}

.sizeSmall .underline {
margin-top: -0.125rem;
}

.link {
color: var(--primary-black);

Expand Down Expand Up @@ -48,6 +60,14 @@
}
}

.colorLight .link {
color: var(--primary-white);

&::after {
background-color: var(--primary-white);
}
}

.sizeSmall .link {
font-size: 0.95rem;
gap: 0.25rem;
Expand Down
2 changes: 2 additions & 0 deletions src/components/navigation/header/Header.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Meta, StoryObj } from "@storybook/react";

import { defaultLanguage } from "i18n/supportedLanguages";
import {
mockAnnouncement,
mockLogo,
mockNavigation,
mockPathTranslations,
Expand Down Expand Up @@ -30,6 +31,7 @@ export const Default: Story = {
args: {
navigation: mockNavigation,
assets: mockLogo,
announcement: mockAnnouncement,
currentLanguage: defaultLanguage?.id ?? "en",
pathTranslations: mockPathTranslations,
},
Expand Down
25 changes: 25 additions & 0 deletions src/components/navigation/header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import LanguageSwitcher from "src/components/languageSwitcher/LanguageSwitcher";
import CustomLink from "src/components/link/CustomLink";
import LinkButton from "src/components/linkButton/LinkButton";
import { BreadCrumbMenu } from "src/components/navigation/breadCrumbMenu/BreadCrumbMenu";
import Text from "src/components/text/Text";
import { getHref } from "src/utils/link";
import { Announcement } from "studio/lib/interfaces/announcement";
import { BrandAssets } from "studio/lib/interfaces/brandAssets";
import { InternationalizedString } from "studio/lib/interfaces/global";
import { ILink, Navigation } from "studio/lib/interfaces/navigation";
Expand All @@ -23,6 +25,7 @@ import styles from "./header.module.css";
export interface IHeader {
navigation: Navigation;
assets: BrandAssets;
announcement: Announcement | null;
currentLanguage: string;
pathTitles: string[];
pathTranslations: InternationalizedString;
Expand All @@ -35,6 +38,7 @@ const filterLinks = (data: ILink[], type: string) =>
export const Header = ({
navigation,
assets,
announcement,
currentLanguage,
pathTitles,
pathTranslations,
Expand Down Expand Up @@ -72,6 +76,11 @@ export const Header = ({
};
}, []);

const showAnnouncement =
announcement !== null &&
announcement.text.length > 0 &&
(!announcement.hideAfter || new Date(announcement.hideAfter) > new Date());

return (
<>
<FocusOn
Expand Down Expand Up @@ -126,6 +135,22 @@ export const Header = ({
</div>
)}
</nav>
{showAnnouncement && (
<div className={styles.announcementWrapper}>
<div className={styles.announcementContent}>
<Text type={"bodySmall"}>{announcement.text}</Text>
{announcement.link && announcement.link.linkTitle && (
<div>
<CustomLink
link={announcement.link}
size={"small"}
color={"light"}
/>
</div>
)}
</div>
</div>
)}
</header>
</FocusOn>
{showBreadcrumbs && (
Expand Down
17 changes: 15 additions & 2 deletions src/components/navigation/header/HeaderPreview.tsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,58 @@
"use client";
import { QueryResponseInitial, useQuery } from "@sanity/react-loader";

import { Announcement } from "studio/lib/interfaces/announcement";
import { BrandAssets } from "studio/lib/interfaces/brandAssets";
import { InternationalizedString } from "studio/lib/interfaces/global";
import { Navigation } from "studio/lib/interfaces/navigation";
import { BRAND_ASSETS_QUERY, NAV_QUERY } from "studio/lib/queries/siteSettings";
import {
ANNOUNCEMENT_QUERY,
BRAND_ASSETS_QUERY,
NAV_QUERY,
} from "studio/lib/queries/siteSettings";

import { Header } from "./Header";

export default function HeaderPreview({
initialNav,
initialBrandAssets,
initialAnnouncement,
currentLanguage,
pathTitles,
pathTranslations,
showBreadcrumbs,
}: {
initialNav: QueryResponseInitial<Navigation>;
initialBrandAssets: QueryResponseInitial<BrandAssets>;
initialAnnouncement: QueryResponseInitial<Announcement | null>;
currentLanguage: string;
pathTitles: string[];
pathTranslations: InternationalizedString;
showBreadcrumbs: boolean;
}) {
const { data: newNav } = useQuery<Navigation | null>(
NAV_QUERY,
{ language: initialNav.data.language },
{ language: currentLanguage },
{ initial: initialNav },
);
const { data: newBrandAssets } = useQuery<BrandAssets | null>(
BRAND_ASSETS_QUERY,
{},
{ initial: initialBrandAssets },
);
const { data: newAnnouncement } = useQuery<Announcement | null>(
ANNOUNCEMENT_QUERY,
{ language: currentLanguage },
{ initial: initialAnnouncement },
);

return (
newNav &&
newBrandAssets && (
<Header
navigation={newNav}
assets={newBrandAssets}
announcement={newAnnouncement}
currentLanguage={currentLanguage}
pathTitles={pathTitles}
pathTranslations={pathTranslations}
Expand Down
30 changes: 19 additions & 11 deletions src/components/navigation/header/PageHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import { getDraftModeInfo } from "src/utils/draftmode";
import { isNonNullQueryResponse } from "src/utils/queryResponse";
import { Announcement } from "studio/lib/interfaces/announcement";
import { BrandAssets } from "studio/lib/interfaces/brandAssets";
import { InternationalizedString } from "studio/lib/interfaces/global";
import { Navigation } from "studio/lib/interfaces/navigation";
import { BRAND_ASSETS_QUERY, NAV_QUERY } from "studio/lib/queries/siteSettings";
import {
ANNOUNCEMENT_QUERY,
BRAND_ASSETS_QUERY,
NAV_QUERY,
} from "studio/lib/queries/siteSettings";
import { loadStudioQuery } from "studio/lib/store";

import { Header } from "./Header";
Expand Down Expand Up @@ -35,19 +41,20 @@ export default async function PageHeader({
{ perspective },
);

const initialAnnouncement = await loadStudioQuery<Announcement | null>(
ANNOUNCEMENT_QUERY,
{ language },
{ perspective },
);

return (
initialBrandAssets.data !== null &&
initialNav.data !== null &&
isNonNullQueryResponse(initialBrandAssets) &&
isNonNullQueryResponse(initialNav) &&
(isDraftMode ? (
<HeaderPreview
initialNav={{
...initialNav,
data: initialNav.data,
}}
initialBrandAssets={{
...initialBrandAssets,
data: initialBrandAssets.data,
}}
initialNav={initialNav}
initialBrandAssets={initialBrandAssets}
initialAnnouncement={initialAnnouncement}
currentLanguage={language}
pathTitles={pathTitles}
pathTranslations={pathTranslations}
Expand All @@ -57,6 +64,7 @@ export default async function PageHeader({
<Header
navigation={initialNav.data}
assets={initialBrandAssets.data}
announcement={initialAnnouncement.data}
currentLanguage={language}
pathTitles={pathTitles}
pathTranslations={pathTranslations}
Expand Down
24 changes: 24 additions & 0 deletions src/components/navigation/header/header.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -145,3 +145,27 @@
composes: button;
background: url("/_assets/menu-close.svg") no-repeat 50% 50%;
}

.announcementWrapper {
display: flex;
flex-direction: column;
padding: 0.75rem;
background-color: var(--primary-bg-blue);
align-items: center;
}

.announcementContent {
display: flex;
gap: 2rem;

@media (max-width: 1024px) {
align-items: center;
flex-direction: column;
gap: 0.5rem;
}
}

.announcementContent p {
font-weight: 600;
color: var(--primary-white);
}
9 changes: 9 additions & 0 deletions src/components/navigation/mockData.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import primaryLogoFile from "src/stories/assets/energiai-primary-logo.svg";
import secondaryLogoFile from "src/stories/assets/energiai-secondary-logo.svg";
import { Announcement } from "studio/lib/interfaces/announcement";
import { InternationalizedString } from "studio/lib/interfaces/global";
import {
LinkType,
Expand Down Expand Up @@ -131,6 +132,14 @@ export const mockLogo = {
favicon: {},
};

export const mockAnnouncement: Announcement = {
language: "no",
text: "Mandag 21.10. er det TDC! Møt oss der!",
hideAfter: new Date(
new Date().setMonth(new Date().getMonth() + 1),
).toISOString(),
};

// Mock Social Media Profiles
export const mockSocialMediaProfiles: SocialMediaProfiles = {
_id: "profile123",
Expand Down
1 change: 1 addition & 0 deletions src/styles/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ html {
--primary-light: #f5a4c4;
--primary-bg: #f2f2f2;
--primary-bg-dark: #d9d9d9;
--primary-bg-blue: #0014cd;

--primary-white-bright: #ffffff;
--primary-white: #faf8f5;
Expand Down
11 changes: 11 additions & 0 deletions studio/deskStructure.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
CaseIcon,
CogIcon,
ConfettiIcon,
EarthGlobeIcon,
HeartIcon,
ImagesIcon,
Expand All @@ -22,6 +23,7 @@ import { legalDocumentID } from "./schemas/documents/admin/legalDocuments";
import { compensationsId } from "./schemas/documents/compensations";
import { languageSettingsID } from "./schemas/documents/languageSettings";
import { pageBuilderID } from "./schemas/documents/pageBuilder";
import { announcementID } from "./schemas/documents/siteSettings/announcement";
import { brandAssetsID } from "./schemas/documents/siteSettings/brandAssets";
import { localeID } from "./schemas/documents/siteSettings/locale";
import { soMeLinksID } from "./schemas/documents/siteSettings/socialMediaProfiles";
Expand Down Expand Up @@ -120,6 +122,15 @@ const siteSettingSection = (S: StructureBuilder) =>
.documentId(defaultSeoID)
.title("Default SEO"),
),
S.listItem()
.title("Announcement")
.icon(ConfettiIcon)
.child(
S.document()
.schemaType(announcementID)
.documentId(announcementID)
.title("Announcement"),
),
]),
);

Expand Down
8 changes: 8 additions & 0 deletions studio/lib/interfaces/announcement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { ILink } from "./navigation";

export interface Announcement {
language: string;
text: string;
link?: ILink;
hideAfter?: string;
}
13 changes: 13 additions & 0 deletions studio/lib/queries/siteSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,16 @@ export const DEFAULT_SEO_QUERY = groq`
${SEO_FRAGMENT}
}
`;

// Announcement
export const ANNOUNCEMENT_QUERY = groq`
*[_type == "announcement"][0]{
${LANGUAGE_FIELD_FRAGMENT},
"text": ${translatedFieldFragment("text")},
"link": link {
...,
${TRANSLATED_LINK_FRAGMENT}
},
hideAfter
}
`;
2 changes: 2 additions & 0 deletions studio/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import legalDocument from "./schemas/documents/admin/legalDocuments";
import compensations from "./schemas/documents/compensations";
import languageSettings from "./schemas/documents/languageSettings";
import pageBuilder from "./schemas/documents/pageBuilder";
import announcement from "./schemas/documents/siteSettings/announcement";
import brandAssets from "./schemas/documents/siteSettings/brandAssets";
import locale from "./schemas/documents/siteSettings/locale";
import navigationManager from "./schemas/documents/siteSettings/navigationManager";
Expand Down Expand Up @@ -41,5 +42,6 @@ export const schema: { types: SchemaTypeDefinition[] } = {
locale,
richText,
seo,
announcement,
],
};
Loading