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

Upgrade magazine room to all sanity and looks #2547 #2576

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions sanityv3/schemas/HeroTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export enum HeroTypes {
FIFTY_FIFTY = 'fiftyFifty',
FULL_WIDTH_IMAGE = 'fullWidthImage',
LOOPING_VIDEO = 'loopingVideo',
BACKGROUND_IMAGE = 'backgroundImage',
}
62 changes: 60 additions & 2 deletions sanityv3/schemas/documents/magazineIndexPage.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import blocksToText from '../../helpers/blocksToText'
import { configureBlockContent } from '../editors/blockContentType'
import CompactBlockEditor from '../components/CompactBlockEditor'
import MagazineFooterComponent from '../objects/magazineFooterComponent'
import sharedHeroFields from './header/sharedHeaderFields'
import { EdsIcon } from '../../icons'
import { bookmarks } from '@equinor/eds-icons'

import type { PortableTextBlock, Rule } from 'sanity'
import { lang } from './langField'
import { HeroTypes } from '../HeroTypes'
import { configureTitleBlockContent } from '../editors'
import { ValidationContext } from '../../types/schemaTypes'

const titleContentType = configureTitleBlockContent()

const textContentType = configureBlockContent({
h2: true,
Expand Down Expand Up @@ -53,7 +58,60 @@ export default {
description: 'You can override the hero image as the SoMe image by uploading another image here.',
fieldset: 'metadata',
},
...sharedHeroFields,
{
name: 'title',
type: 'array',
title: 'Title',
components: {
input: CompactBlockEditor,
},
of: [titleContentType],
fieldset: 'header',
validation: (Rule: Rule) => Rule.required(),
},
{
title: 'Type',
name: 'heroType',
type: 'string',
options: {
list: [
{ title: 'Default', value: HeroTypes.DEFAULT },
{ title: 'Full Image', value: HeroTypes.FULL_WIDTH_IMAGE },
{ title: 'Background image', value: HeroTypes.BACKGROUND_IMAGE },
].filter((e) => e),
},
initialValue: 'default',
fieldset: 'header',
},
{
title: 'Hero image',
name: 'heroFigure',
type: 'imageWithAltAndCaption',
fieldset: 'header',
},
{
title: 'Hero image ratio',
name: 'heroRatio',
type: 'string',
options: {
list: [
{ title: 'Tall', value: 'tall' },
{ title: '2:1(deprecated)', value: '0.5' },
{ title: 'Narrow', value: 'narrow' },
],
},
hidden: ({ parent }: DocumentType) => {
return parent?.heroType !== HeroTypes.FULL_WIDTH_IMAGE
},
validation: (Rule: Rule) =>
Rule.custom((value: string, context: ValidationContext) => {
const { parent } = context as unknown as DocumentType
if (parent?.heroType === HeroTypes.FULL_WIDTH_IMAGE && !value) return 'Field is required'
return true
}),
initialValue: '0.5',
fieldset: 'header',
},
{
title: 'Text',
name: 'ingress',
Expand Down
5 changes: 5 additions & 0 deletions sanityv3/schemas/textSnippets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,11 @@ const snippets: textSnippet = {
defaultValue: 'Switch to',
group: groups.others,
},
filter: {
title: 'Filter',
defaultValue: 'Filter',
group: groups.others,
},
}

type textSnippetGroup = { title: string; hidden?: boolean }
Expand Down
20 changes: 20 additions & 0 deletions web/common/contexts/PaginationContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { createContext, RefObject, useState } from 'react'

type Props = {
resultsRef: RefObject<HTMLDivElement> | undefined
}

type ProviderProps = {
defaultRef?: RefObject<HTMLDivElement> | undefined
children: React.ReactNode
}

export const PaginationContext = createContext<Props>({
resultsRef: undefined,
})

export const PaginationContextProvider = ({ defaultRef, children }: ProviderProps) => {
const [resultsRef] = useState<RefObject<HTMLDivElement> | undefined>(defaultRef)

return <PaginationContext.Provider value={{ resultsRef }}>{children}</PaginationContext.Provider>
}
3 changes: 3 additions & 0 deletions web/common/helpers/scrollToTop.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const scrollToTop = () => {
window.scrollTo({ top: 0, behavior: 'smooth' })
}
24 changes: 16 additions & 8 deletions web/components/src/Backgrounds/ImageBackgroundContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ type ImageBackgroundContainerProps = {
scrimClassName?: string
/* On mobile dont split background image and content */
dontSplit?: boolean
/* Provide gradient in scrimClassname and disable default */
overrideGradient?: boolean
aspectRatio?: number
} & ImageBackground &
HTMLAttributes<HTMLDivElement>
const DEFAULT_MAX_WIDTH = 1920
Expand All @@ -22,12 +25,14 @@ export const ImageBackgroundContainer = forwardRef<HTMLDivElement, ImageBackgrou
children,
className = '',
scrimClassName = '',
overrideGradient = false,
dontSplit = false,
aspectRatio,
...rest
},
ref,
) {
const props = useSanityLoader(image, DEFAULT_MAX_WIDTH, undefined)
const props = useSanityLoader(image, DEFAULT_MAX_WIDTH, aspectRatio)
const src = props?.src
const isMobile = useMediaQuery(`(max-width: 800px)`)

Expand Down Expand Up @@ -66,9 +71,12 @@ export const ImageBackgroundContainer = forwardRef<HTMLDivElement, ImageBackgrou
'bottom-center': 'black-to-top-gradient',
}

const animatedScrimGradient = useLight
? `${lightGradientForContentAlignment[contentAlignment]}`
: `black-center-gradient ${darkGradientForContentAlignment[contentAlignment]}`
let animatedScrimGradient = ''
if (!overrideGradient) {
animatedScrimGradient = useLight
? `${lightGradientForContentAlignment[contentAlignment]}`
: `black-center-gradient ${darkGradientForContentAlignment[contentAlignment]}`
}

return useAnimation && !isMobile ? (
<div
Expand Down Expand Up @@ -119,10 +127,10 @@ export const ImageBackgroundContainer = forwardRef<HTMLDivElement, ImageBackgrou
<div
className={twMerge(
`h-full
py-40
lg:py-52
relative
${animatedScrimGradient}`,
py-40
lg:py-52
relative
${animatedScrimGradient}`,
scrimClassName,
)}
>
Expand Down
67 changes: 67 additions & 0 deletions web/core/SimplePagination/SimplePagination.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import envisTwMerge from '../../twMerge'
import { useIntl } from 'react-intl'
import { MediaButton } from '@core/MediaButton/MediaButton'
import { useContext } from 'react'
import { usePrefersReducedMotion } from '../../common/hooks/usePrefersReducedMotion'
import { PaginationContext } from '../../common/contexts/PaginationContext'

export type SimplePaginationProps = {
className?: string
onNextPage: () => void
onPreviousPage: () => void
isFirstPage: boolean
isLastPage: boolean
}

export const SimplePagination = ({
className = '',
onNextPage,
onPreviousPage,
isFirstPage = false,
isLastPage = false,
...rest
}: SimplePaginationProps) => {
const intl = useIntl()
const { resultsRef } = useContext(PaginationContext)
const prefersReducedMotion = usePrefersReducedMotion()

const handleNextPagination = () => {
if (!prefersReducedMotion && resultsRef?.current) {
resultsRef.current.scrollIntoView({ behavior: 'smooth' })
}
onNextPage()
}
const handlePrevPagination = () => {
if (!prefersReducedMotion && resultsRef?.current) {
resultsRef.current.scrollIntoView({ behavior: 'smooth' })
}
onPreviousPage()
}

return (
<ul className={envisTwMerge(`max-w-viewport flex flex-wrap gap-2 my-2`, className)} {...rest}>
<div className="flex gap-3 items-center">
<MediaButton
title={intl.formatMessage({
id: 'previous',
defaultMessage: 'Previous',
})}
mode="previous"
disabled={isFirstPage}
onClick={handlePrevPagination}
className=""
/>
<MediaButton
title={intl.formatMessage({
id: 'next',
defaultMessage: 'Next',
})}
mode="next"
disabled={isLastPage}
onClick={handleNextPagination}
className=""
/>
</div>
</ul>
)
}
24 changes: 24 additions & 0 deletions web/lib/fetchData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,27 @@ export const getComponentsData = async (page: { query: string; queryParams: Quer

return { menuData, pageData, footerData }
}

export type MagazineQueryParams = {
lang?: string
tag?: string | undefined
lastId?: string
lastPublishedAt?: string
}

export const getData = async (fetchQuery: { query: string; queryParams: MagazineQueryParams }, preview = false) => {
const client = getClient(preview)
try {
const results = await client.fetch(fetchQuery.query, fetchQuery.queryParams)
return {
isSuccess: true,
data: results,
}
} catch (error) {
console.log('Error when fetching from Sanity', error)
return {
isError: true,
data: [],
}
}
}
69 changes: 65 additions & 4 deletions web/lib/queries/magazine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import downloadableImageFields from './common/actions/downloadableImageFields'
import markDefs from './common/blockEditorMarks'
import { seoAndSomeFields } from './common/seoAndSomeFields'
import { sameLang, fixPreviewForDrafts, noDrafts } from './common/langAndDrafts'
import { publishDateTimeQuery } from './common/publishDateTime'
import background from './common/background'

const footerComponentFields = /* groq */ `
title,
Expand All @@ -15,7 +17,7 @@ const footerComponentFields = /* groq */ `
${markDefs},
},
"designOptions": {
"background": coalesce(background.title, 'White'),
${background},
"imagePosition": coalesce(imagePosition, 'left'),
},
"image": image{
Expand All @@ -29,7 +31,11 @@ const footerComponentFields = /* groq */ `
},
`

const promotedmagazineTags = /* groq */ `"": *[_type == "magazineIndex" && ${sameLang} && ${noDrafts}][0] {"magazineTags":promotedMagazineTags[]->title[$lang]}`
const promotedmagazineTags = /* groq */ `"": *[_type == "magazineIndex" && ${sameLang} && ${noDrafts}][0] {"magazineTags":promotedMagazineTags[]->{
"id": _id,
"key": key.current,
"title":title[$lang],
}}`

export const magazineQuery = /* groq */ `
*[_type == "magazine" && slug.current == $slug && ${fixPreviewForDrafts}] {
Expand All @@ -40,6 +46,7 @@ export const magazineQuery = /* groq */ `
"hero": ${heroFields},
"template": _type,
${promotedmagazineTags},
"tags": magazineTags[]->title[$lang],
"content": content[] {
${pageContentFields}
},
Expand All @@ -65,8 +72,62 @@ export const magazineIndexQuery = /* groq */ `
},
"background": coalesce(ingressBackground.title, 'White'),
},
"magazineTags": promotedMagazineTags[]->title[$lang],
"magazineTags": promotedMagazineTags[]->{
"id": _id,
"key": key.current,
"title":title[$lang],
},
"footerComponent": footerComponent{
${footerComponentFields}
}
}`
}`

export const allMagazineDocuments = /* groq */ `
*[_type == "magazine" && ${sameLang} && ${noDrafts} ] | order(${publishDateTimeQuery} desc){
"id": _id,
"slug": slug.current,
title[]{
...,
${markDefs},
},
"hero": ${heroFields}
}`

//&& (${publishDateTimeQuery} < $lastPublishedAt || (${publishDateTimeQuery} == $lastPublishedAt && _id < $lastId))
const prevDirectionFilter = /* groq */ `
&& (${publishDateTimeQuery} < $lastPublishedAt || (${publishDateTimeQuery} == $lastPublishedAt && _id < $lastId))
`
//&& (${publishDateTimeQuery} > $lastPublishedAt || (${publishDateTimeQuery} == $lastPublishedAt && _id > $lastId))
const nextDirectionFilter = /* groq */ `
&& (${publishDateTimeQuery} > $lastPublishedAt || (${publishDateTimeQuery} == $lastPublishedAt && _id > $lastId))
`

export const getMagazineArticlesByTag = (hasFirstId = false, hasLastId = false) => /* groq */ `
{
"tagsParam": *[_type == 'magazineTag'
&& !(_id in path('drafts.**'))
&& key.current == $tag]
{ _id, "key": key.current },
}{
"articles": *[_type == 'magazine' && ${sameLang} && ${noDrafts}
&& references(^.tagsParam[]._id)
${hasLastId ? nextDirectionFilter : ''}
${hasFirstId ? prevDirectionFilter : ''}
] | order(${publishDateTimeQuery} desc){
"id": _id,
"slug": slug.current,
title[]{
...,
${markDefs},
},
"hero": ${heroFields}
}
}.articles
`

export const allMagazineTags = /* groq */ `
*[_type == "magazineTag" && ${noDrafts}]{
"id": _id,
"key": key.current,
"title":title[$lang],
}`
Loading
Loading