last detailing

This commit is contained in:
amirhouieh 2023-05-16 22:56:44 +02:00
parent 4d27bc6a96
commit 3eea66a23b
25 changed files with 195 additions and 135 deletions

View File

@ -12,19 +12,19 @@ import { useScrollDirection } from '@/utils/ui.utils'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import { useSearchBarContext } from '@/context/searchbar.context' import { useSearchBarContext } from '@/context/searchbar.context'
interface NavbarProps { interface AppBarProps {
isDark: boolean isDark: boolean
toggle: () => void toggle: () => void
onSearch?: (query: string, tags: string[]) => void onSearch?: (query: string, tags: string[]) => void
onReset?: () => void onReset?: () => void
} }
export default function Navbar({ export default function AppBar({
isDark, isDark,
toggle, toggle,
onReset, onReset,
onSearch, onSearch,
}: NavbarProps) { }: AppBarProps) {
const { resultsNumber } = useSearchBarContext() const { resultsNumber } = useSearchBarContext()
const { pathname } = useRouter() const { pathname } = useRouter()
const isSearchPage = pathname === '/search' const isSearchPage = pathname === '/search'
@ -52,7 +52,7 @@ export default function Navbar({
return ( return (
<Container className={`${hide ? 'hide' : ''} ${className}`}> <Container className={`${hide ? 'hide' : ''} ${className}`}>
<AppBar> <NavBar>
<LogosIconContainer href={'/'}> <LogosIconContainer href={'/'}>
<LogosIcon color="primary" /> <LogosIcon color="primary" />
</LogosIconContainer> </LogosIconContainer>
@ -69,10 +69,10 @@ export default function Navbar({
size="small" size="small"
onClick={() => onSearchIconClick()} onClick={() => onSearchIconClick()}
> >
<SearchIcon /> <SearchIcon color="primary" />
</IconButton> </IconButton>
</Icons> </Icons>
</AppBar> </NavBar>
<MobileSearchContainer <MobileSearchContainer
className={`searchBar ${hideSearch ? 'hide' : ''}`} className={`searchBar ${hideSearch ? 'hide' : ''}`}
> >
@ -92,8 +92,8 @@ const Container = styled.div`
transition: top 0.2s; transition: top 0.2s;
position: fixed; position: fixed;
top: 0; top: 0;
left: 0;
z-index: 101; z-index: 101;
left: calc(calc(100% - ${uiConfigs.maxContainerWidth}px) / 2);
&._page { &._page {
@media (min-width: 768px) { @media (min-width: 768px) {
@ -110,7 +110,14 @@ const Container = styled.div`
&.search_page { &.search_page {
} }
@media (max-width: ${uiConfigs.maxContainerWidth}px) {
left: 16px;
width: calc(100% - 32px);
}
@media (max-width: 768px) { @media (max-width: 768px) {
left: 0;
width: 100%;
&.hide { &.hide {
top: -44px; top: -44px;
} }
@ -137,7 +144,7 @@ const MobileSearchContainer = styled.div`
} }
` `
const AppBar = styled.nav` const NavBar = styled.nav`
display: flex; display: flex;
padding: 8px 0; padding: 8px 0;
align-items: center; align-items: center;
@ -204,7 +211,3 @@ const Icons = styled.div`
} }
} }
` `
const Selector = styled(IconButton)`
border-left: none;
`

View File

@ -0,0 +1 @@
export { default as AppBar } from './AppBar'

View File

@ -43,13 +43,7 @@ const ArticleContainer = styled.article`
flex-direction: column; flex-direction: column;
gap: 16px; gap: 16px;
max-width: 700px; max-width: 700px;
margin-inline: 5%;
padding-bottom: 80px; padding-bottom: 80px;
// temporary breakpoint
@media (max-width: 1024px) {
margin-inline: 16px;
}
` `
const TextContainer = styled.div` const TextContainer = styled.div`

View File

@ -18,6 +18,7 @@ export const ArticleHeading = ({
block, block,
headingElementsRef, headingElementsRef,
typographyProps, typographyProps,
...props
}: Props) => { }: Props) => {
const id = const id =
extractIdFromFirstTag(block.html) || `${block.tagName}-${block.order}` extractIdFromFirstTag(block.html) || `${block.tagName}-${block.order}`
@ -37,6 +38,7 @@ export const ArticleHeading = ({
className={extractClassFromFirstTag(block.html) || ''} className={extractClassFromFirstTag(block.html) || ''}
dangerouslySetInnerHTML={{ __html: `${extractInnerHtml(block.html)}` }} dangerouslySetInnerHTML={{ __html: `${extractInnerHtml(block.html)}` }}
{...(typographyProps || {})} {...(typographyProps || {})}
{...props}
/> />
</> </>
) )
@ -48,7 +50,7 @@ const Headline = styled(Typography)`
@media (max-width: 768px) { @media (max-width: 768px) {
&.title { &.title {
font-size: var(--lsd-h3-fontSize); font-size: var(--lsd-h4-fontSize);
line-height: var(--lsd-h4-lineHeight); line-height: var(--lsd-h4-lineHeight);
} }

View File

@ -6,7 +6,7 @@ import { PostImageRatio } from '../../Post/Post'
import ArticleStats from '../Article.Stats' import ArticleStats from '../Article.Stats'
import { Typography } from '@acid-info/lsd-react' import { Typography } from '@acid-info/lsd-react'
import styled from '@emotion/styled' import styled from '@emotion/styled'
import ArticleSummary, { MobileSummary } from './Article.Summary' import ArticleSummary from './Article.Summary'
import { calcReadingTime } from '@/utils/string.utils' import { calcReadingTime } from '@/utils/string.utils'
import { Authors } from '@/components/Authors' import { Authors } from '@/components/Authors'
import { Tags } from '@/components/Tags' import { Tags } from '@/components/Tags'
@ -14,12 +14,8 @@ import { UnbodyGraphQl } from '@/lib/unbody/unbody-content.types'
import { ArticleHeading } from '@/components/Article/Article.Heading' import { ArticleHeading } from '@/components/Article/Article.Heading'
import { useArticleContainerContext } from '@/containers/ArticleContainer.Context' import { useArticleContainerContext } from '@/containers/ArticleContainer.Context'
import { useIntersectionObserver } from '@/utils/ui.utils' import { useIntersectionObserver } from '@/utils/ui.utils'
import { MobileToc } from '@/components/Article/Article.MobileToc'
import { useSearchBarContext } from '@/context/searchbar.context'
const ArticleHeader = ({ const ArticleHeader = ({
title,
toc,
summary, summary,
subtitle, subtitle,
mentions, mentions,
@ -27,9 +23,8 @@ const ArticleHeader = ({
modifiedAt, modifiedAt,
blocks, blocks,
}: GoogleDocEnhanced) => { }: GoogleDocEnhanced) => {
const { setTocId, tocId } = useArticleContainerContext() const { setTocId } = useArticleContainerContext()
const headingElementsRef = useIntersectionObserver(setTocId) const headingElementsRef = useIntersectionObserver(setTocId)
const { resultsNumber } = useSearchBarContext()
const _thumbnail = useMemo(() => { const _thumbnail = useMemo(() => {
const coverImage = getArticleCover(blocks) const coverImage = getArticleCover(blocks)
@ -58,15 +53,14 @@ const ArticleHeader = ({
}, [blocks]) }, [blocks])
return ( return (
<header> <ArticleHeaderContainer>
<ArticleStats dateStr={modifiedAt} readingLength={readingTime} /> <ArticleStats dateStr={modifiedAt} readingLength={readingTime} />
<ArticleHeading <ArticleTitle
block={blocks[0] as any} block={blocks[0] as any}
typographyProps={{ typographyProps={{
variant: 'h1', variant: 'h1',
genericFontFamily: 'serif', genericFontFamily: 'serif',
component: 'h1', component: 'h1',
style: { marginBottom: '16px' },
}} }}
headingElementsRef={headingElementsRef} headingElementsRef={headingElementsRef}
/> />
@ -79,22 +73,60 @@ const ArticleHeader = ({
{subtitle} {subtitle}
</ArticleSubtitle> </ArticleSubtitle>
)} )}
<Tags tags={tags} /> <Tags tags={tags} className={'articleTags'} />
<AuthorsContainer> <AuthorsContainer>
<Authors mentions={mentions} email={true} gap={12} /> <Authors mentions={mentions} email={true} gap={12} />
</AuthorsContainer> </AuthorsContainer>
<MobileCollapseContainer> {/*<MobileCollapseContainer>*/}
{resultsNumber === null && <MobileToc toc={toc} />} {/* {resultsNumber === null && <MobileToc toc={toc} />}*/}
{resultsNumber === null && <MobileSummary summary={summary} />} {/* {resultsNumber === null && <MobileSummary summary={summary} />}*/}
</MobileCollapseContainer> {/*</MobileCollapseContainer>*/}
<ArticleSummary
summary={summary}
className={'mobileSummary'}
showLabel={false}
/>
{_thumbnail} {_thumbnail}
<ArticleSummary summary={summary} /> <ArticleSummary
</header> summary={summary}
className={'desktopSummary'}
showLabel={true}
/>
</ArticleHeaderContainer>
) )
} }
const MobileCollapseContainer = styled.div` const ArticleHeaderContainer = styled.header`
margin-bottom: 32px; .mobileSummary {
display: none;
}
.desktopSummary {
display: block;
}
@media (max-width: 768px) {
.mobileSummary {
color: red;
display: block;
p {
font-size: var(--lsd-body3-fontSize);
line-height: var(--lsd-body3-lineHeight);
margin-bottom: 24px;
}
hr {
display: none;
}
}
.desktopSummary {
display: none;
}
.articleTags {
display: none;
}
}
` `
const CustomTypography = styled(Typography)` const CustomTypography = styled(Typography)`
@ -103,18 +135,34 @@ const CustomTypography = styled(Typography)`
white-space: pre-wrap; white-space: pre-wrap;
` `
const ArticleTitle = styled(CustomTypography)` const ArticleTitle = styled(ArticleHeading)`
margin-bottom: 24px; margin-bottom: 16px;
@media (max-width: 768px) {
margin-bottom: 8px;
}
` `
const ArticleSubtitle = styled(CustomTypography)` const ArticleSubtitle = styled(CustomTypography)`
margin-bottom: 16px; margin-bottom: 16px;
@media (max-width: 768px) {
font-size: var(--lsd-subtitle1-fontSize);
}
` `
const AuthorsContainer = styled.div` const AuthorsContainer = styled.div`
//margin-block: 24px; //margin-block: 24px;
margin-top: 24px; margin-top: 24px;
margin-bottom: 32px; margin-bottom: 32px;
@media (max-width: 768px) {
margin-top: 16px;
margin-bottom: 24px;
a[href^='mailto:'] {
display: none;
}
}
` `
export default ArticleHeader export default ArticleHeader

View File

@ -4,24 +4,14 @@ import React from 'react'
import { Collapse } from '@/components/Collapse' import { Collapse } from '@/components/Collapse'
import useIsDarkState from '@/states/isDarkState/isDarkState' import useIsDarkState from '@/states/isDarkState/isDarkState'
export const MobileSummary = ({ summary }: { summary: string }) => { type Props = {
const isDark = useIsDarkState().get() summary: string
return ( className?: string
<SummaryContainerMobile showLabel?: boolean
label={'Summary'}
initOpen={false}
style={{ background: isDark ? 'black' : 'white' }}
>
<SummaryParagraph variant="h6" component={'p'}>
{summary}
</SummaryParagraph>
</SummaryContainerMobile>
)
} }
const ArticleSummary = ({ summary, className, showLabel }: Props) => (
const ArticleSummary = ({ summary }: { summary: string }) => ( <ArticleSummaryContainer className={className}>
<ArticleSummaryContainer> {showLabel && <Typography variant="body3">summary</Typography>}
<Typography variant="body3">summary</Typography>
<SummaryParagraph variant="h6" component={'p'}> <SummaryParagraph variant="h6" component={'p'}>
{summary} {summary}
</SummaryParagraph> </SummaryParagraph>
@ -35,6 +25,7 @@ const ArticleSummaryContainer = styled('div')`
@media (max-width: 770px) { @media (max-width: 770px) {
display: none; display: none;
} }
> span { > span {
margin-bottom: 16px; margin-bottom: 16px;
display: block; display: block;
@ -46,17 +37,4 @@ const SummaryParagraph = styled(Typography)`
display: block; display: block;
` `
const SummaryContainerMobile = styled(Collapse)`
display: none;
@media (max-width: 770px) {
display: block;
p {
padding: 12px 14px;
margin-bottom: 0;
font-size: var(--lsd-font-size-body2);
line-height: var(--lsd-line-height-body2);
}
}
`
export default ArticleSummary export default ArticleSummary

View File

@ -1,7 +1,7 @@
import { Typography } from '@acid-info/lsd-react' import { Typography } from '@acid-info/lsd-react'
import styled from '@emotion/styled' import styled from '@emotion/styled'
import { uiConfigs } from '@/configs/ui.configs' import { uiConfigs } from '@/configs/ui.configs'
import { NavbarFiller } from '@/components/Navbar/NavbarFiller' import { NavbarFiller } from '@/components/AppBar/NavbarFiller'
import { Searchbar } from '@/components/Searchbar' import { Searchbar } from '@/components/Searchbar'
export default function Hero() { export default function Hero() {
@ -18,7 +18,6 @@ export default function Hero() {
</Description> </Description>
</HeroText> </HeroText>
<NavbarFiller /> <NavbarFiller />
<Searchbar className={'desktop'} />
</Container> </Container>
) )
} }

View File

@ -2,8 +2,8 @@ import styled from '@emotion/styled'
import { uiConfigs } from '@/configs/ui.configs' import { uiConfigs } from '@/configs/ui.configs'
import { PropsWithChildren } from 'react' import { PropsWithChildren } from 'react'
const Main = ({ children }: PropsWithChildren) => { const Main = ({ children, ...props }: PropsWithChildren<any>) => {
return <Container>{children}</Container> return <Container {...props}>{children}</Container>
} }
const Container = styled.main` const Container = styled.main`
@ -11,6 +11,10 @@ const Container = styled.main`
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
@media (max-width: ${uiConfigs.maxContainerWidth}px) {
padding: 0 16px;
}
@media (max-width: 768px) { @media (max-width: 768px) {
margin-top: ${uiConfigs.postSectionMobileMargin}px; margin-top: ${uiConfigs.postSectionMobileMargin}px;
} }

View File

@ -1 +0,0 @@
export { default as Navbar } from './Navbar';

View File

@ -137,13 +137,20 @@ export default function Post({
const _thumbnail = useMemo(() => { const _thumbnail = useMemo(() => {
if (!showImage || !coverImage) return null if (!showImage || !coverImage) return null
let allImageProps = [
...imagePropsArray,
...(imageProps ? [imageProps] : []),
]
if (postType === PostType.BODY) { if (postType === PostType.BODY) {
return ( return (
<Link href={`/article/${slug}`}> <Link href={`/article/${slug}`}>
{[...imagePropsArray, ...(imageProps ? [imageProps] : [])].map( {allImageProps.length > 0 ? (
(imageProps, index) => ( allImageProps.map((_imageProps, index) => (
<ResponsiveImage key={index} {...imageProps} data={coverImage} /> <ResponsiveImage key={index} {..._imageProps} data={coverImage} />
), ))
) : (
<ResponsiveImage {...imageProps} data={coverImage} />
)} )}
</Link> </Link>
) )
@ -151,14 +158,16 @@ export default function Post({
return ( return (
<> <>
<Link href={`/article/${slug}`}> <Link href={`/article/${slug}`}>
{[...imagePropsArray, ...(imageProps ? [imageProps] : [])].map( {allImageProps.length > 0 ? (
(imageProps, index) => ( allImageProps.map((_imageProps, index) => (
<ResponsiveImage <ResponsiveImage
key={index} key={index}
{...imageProps} {..._imageProps}
data={coverImage} data={coverImage}
/> />
), ))
) : (
<ResponsiveImage {...imageProps} data={coverImage} />
)} )}
</Link> </Link>
{_title} {_title}

View File

@ -79,6 +79,7 @@ const CustomGrid = styled(Grid)`
min-height: 500px; min-height: 500px;
@media (max-width: 768px) { @media (max-width: 768px) {
gap: 8px; gap: 8px;
min-height: auto;
} }
` `

View File

@ -29,7 +29,9 @@ export default function RelatedArticles({ data }: Props) {
tags: article.doc.tags, tags: article.doc.tags,
coverImage: getArticleCover(article.doc.blocks), coverImage: getArticleCover(article.doc.blocks),
}))} }))}
pageSize={4} pageSize={
typeof window !== 'undefined' && window.innerWidth < 768 ? 2 : 4
}
loading={data.loading} loading={data.loading}
/> />
} }

View File

@ -103,7 +103,6 @@ export default function Searchbar(props: SearchbarProps) {
performSearch('', []) performSearch('', [])
return return
} }
setQuery('') setQuery('')
setFilterTags([]) setFilterTags([])
setActive(false) setActive(false)
@ -126,7 +125,8 @@ export default function Searchbar(props: SearchbarProps) {
} }
} }
const isCollapsed = isValidSearchInput(filterTags) && !active const withValue = isValidSearchInput(filterTags) || resultsNumber !== null
const isCollapsed = withValue && !active
useEffect(() => { useEffect(() => {
if (active && query.length > 0) { if (active && query.length > 0) {
@ -203,11 +203,13 @@ export default function Searchbar(props: SearchbarProps) {
<div> <div>
<IconButton <IconButton
className={styles.searchButton} className={styles.searchButton}
onClick={() => onClick={() => (withValue ? performClear() : performSearch())}
isValidSearchInput() ? performClear() : performSearch()
}
> >
{isValidSearchInput() ? <CloseIcon /> : <SearchIcon />} {withValue ? (
<CloseIcon color="primary" />
) : (
<SearchIcon color="primary" />
)}
</IconButton> </IconButton>
</div> </div>
</SearchBox> </SearchBox>
@ -231,8 +233,10 @@ export default function Searchbar(props: SearchbarProps) {
variant={'subtitle2'} variant={'subtitle2'}
dangerouslySetInnerHTML={{ dangerouslySetInnerHTML={{
__html: [ __html: [
`${resultsNumber} matches`, ...(resultsNumber !== null ? [`${resultsNumber} matches`] : []),
`<span class="helper">${resultsHelperText}<span>`, ...(resultsHelperText !== null
? [`<span class="helper">${resultsHelperText}<span>`]
: []),
].join('<span class="dot">.</span>'), ].join('<span class="dot">.</span>'),
}} }}
/> />
@ -249,6 +253,7 @@ const TagsWrapper = styled.div`
margin-top: 19px; margin-top: 19px;
height: 24px; height: 24px;
} }
@media (max-width: 768px) { @media (max-width: 768px) {
&.active { &.active {
margin-top: 10px; margin-top: 10px;

View File

@ -20,10 +20,6 @@ export function SearchbarContainer({
className, className,
beSticky = false, beSticky = false,
}: Props) { }: Props) {
const { pathname } = useRouter()
const isSearchPage = pathname === '/search'
const isArticlePage = pathname === '/article/[slug]'
const { sticky, stickyRef, height } = useSticky<HTMLDivElement>( const { sticky, stickyRef, height } = useSticky<HTMLDivElement>(
uiConfigs.navbarRenderedHeight, uiConfigs.navbarRenderedHeight,
) )
@ -74,9 +70,25 @@ const SearchBarWrapper = styled.div<Props>`
&.sticky { &.sticky {
position: fixed; position: fixed;
top: ${uiConfigs.navbarRenderedHeight - 1}px; top: ${uiConfigs.navbarRenderedHeight - 1}px;
z-index: 100; z-index: 100;
max-width: ${uiConfigs.maxContainerWidth}px; max-width: ${uiConfigs.maxContainerWidth}px;
border-top: none; border-top: none;
} }
@media (max-width: ${uiConfigs.maxContainerWidth}px) {
&.sticky {
width: calc(100% - 32px);
left: 16px;
}
}
@media (max-width: 768px) {
&.sticky {
width: 100%;
left: 0;
top: 0;
}
}
` `

View File

@ -35,10 +35,6 @@ export const Section = ({ title, subtitle, children, ...props }: Props) => {
const SectionContainer = styled.section` const SectionContainer = styled.section`
width: 100%; width: 100%;
box-sizing: border-box; box-sizing: border-box;
@media (max-width: 1440px) {
padding-inline: 16px;
}
` `
const Container = styled.div` const Container = styled.div`

View File

@ -4,13 +4,13 @@ import styled from '@emotion/styled'
import Link from 'next/link' import Link from 'next/link'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
const Tags = ({ tags }: { tags: string[] }) => { const Tags = ({ tags, className }: { tags: string[]; className?: string }) => {
const router = useRouter() const router = useRouter()
const { query } = router const { query } = router
const { topics } = query const { topics } = query
return tags.length > 0 ? ( return tags.length > 0 ? (
<TagsContainer> <TagsContainer className={className}>
{tags.map((tag, idx) => ( {tags.map((tag, idx) => (
<Link key={`tag-${idx}`} href={`/search?topics=${tag}`}> <Link key={`tag-${idx}`} href={`/search?topics=${tag}`}>
<Tag <Tag

View File

@ -1,6 +1,6 @@
export const uiConfigs = { export const uiConfigs = {
navbarRenderedHeight: 45, navbarRenderedHeight: 45,
postSectionMargin: 108, postSectionMargin: 101,
postSectionMobileMargin: 48, postSectionMobileMargin: 48,
articleSectionMargin: 40, articleSectionMargin: 40,
maxContainerWidth: 1440, maxContainerWidth: 1440,

View File

@ -1,13 +1,10 @@
import { Navbar } from '@/components/Navbar'
import useIsDarkState from '@/states/isDarkState/isDarkState' import useIsDarkState from '@/states/isDarkState/isDarkState'
import { PropsWithChildren } from 'react' import { PropsWithChildren } from 'react'
import { NavbarFiller } from '@/components/Navbar/NavbarFiller'
import { Searchbar } from '@/components/Searchbar'
import { ESearchScope } from '@/types/ui.types'
import styles from './Article.layout.module.css' import styles from './Article.layout.module.css'
import { Footer } from '@/components/Footer' import { Footer } from '@/components/Footer'
import { Main } from '@/components/Main' import { Main } from '@/components/Main'
import { useArticleContext } from '@/context/article.context' import { useArticleContext } from '@/context/article.context'
import { AppBar } from '@/components/AppBar'
type Props = PropsWithChildren<{ type Props = PropsWithChildren<{
// onSearch: (query: string, filters: string[]) => void // onSearch: (query: string, filters: string[]) => void
@ -19,7 +16,7 @@ export default function ArticleLayout({ children }: Props) {
return ( return (
<> <>
<header className={styles.header}> <header className={styles.header}>
<Navbar <AppBar
isDark={isDarkState.get()} isDark={isDarkState.get()}
toggle={isDarkState.toggle} toggle={isDarkState.toggle}
onSearch={onSearch} onSearch={onSearch}

View File

@ -1,42 +1,41 @@
import { Navbar } from '@/components/Navbar' import { AppBar } from '../../components/AppBar'
import useIsDarkState from '@/states/isDarkState/isDarkState' import useIsDarkState from '@/states/isDarkState/isDarkState'
import { PropsWithChildren } from 'react' import { PropsWithChildren } from 'react'
import { Hero } from '@/components/Hero' import { Hero } from '@/components/Hero'
import { NavbarFiller } from '@/components/Navbar/NavbarFiller' import { NavbarFiller } from '@/components/AppBar/NavbarFiller'
import { Searchbar } from '@/components/Searchbar' import { Searchbar } from '@/components/Searchbar'
import { Footer } from '@/components/Footer' import { Footer } from '@/components/Footer'
import { Main } from '@/components/Main' import { Main } from '@/components/Main'
import { uiConfigs } from '@/configs/ui.configs' import { uiConfigs } from '@/configs/ui.configs'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import { defaultThemes } from '@acid-info/lsd-react' import { defaultThemes } from '@acid-info/lsd-react'
import styled from '@emotion/styled'
export default function DefaultLayout(props: PropsWithChildren<any>) { export default function DefaultLayout(props: PropsWithChildren<any>) {
const isDarkState = useIsDarkState() const isDarkState = useIsDarkState()
return ( return (
<> <>
<header <HeaderContainer
style={{ style={{
textAlign: 'center', textAlign: 'center',
marginBlock: `${uiConfigs.navbarRenderedHeight}px`, marginBlock: `${uiConfigs.navbarRenderedHeight}px`,
}} }}
> >
<div <div>
// style={{ <AppBar isDark={isDarkState.get()} toggle={isDarkState.toggle} />
// borderBottom: `1px solid rgb(${
// isDarkState.get()
// ? defaultThemes.dark.palette.border.primary
// : defaultThemes.light.palette.border.primary
// })`,
// }}
>
<Navbar isDark={isDarkState.get()} toggle={isDarkState.toggle} />
<Hero /> <Hero />
</div> </div>
<Searchbar withFilterTags={false} /> <Searchbar withFilterTags={false} beSticky={true} />
</header> </HeaderContainer>
<Main>{props.children}</Main> <Main>{props.children}</Main>
<Footer /> <Footer />
</> </>
) )
} }
const HeaderContainer = styled.header`
@media (min-width: 776px) and (max-width: ${uiConfigs.maxContainerWidth}px) {
padding: 0 16px;
}
`

View File

@ -1,12 +1,10 @@
import { Navbar } from '@/components/Navbar'
import useIsDarkState from '@/states/isDarkState/isDarkState' import useIsDarkState from '@/states/isDarkState/isDarkState'
import { PropsWithChildren } from 'react' import { PropsWithChildren } from 'react'
import { NavbarFiller } from '@/components/Navbar/NavbarFiller'
import { Searchbar } from '@/components/Searchbar'
import { ESearchScope } from '@/types/ui.types'
import styles from './Search.layout.module.css' import styles from './Search.layout.module.css'
import { Footer } from '@/components/Footer' import { Footer } from '@/components/Footer'
import { Main } from '@/components/Main' import { Main } from '@/components/Main'
import { AppBar } from '@/components/AppBar'
import styled from '@emotion/styled'
import { uiConfigs } from '@/configs/ui.configs' import { uiConfigs } from '@/configs/ui.configs'
export default function SearchLayout(props: PropsWithChildren<any>) { export default function SearchLayout(props: PropsWithChildren<any>) {
@ -14,10 +12,22 @@ export default function SearchLayout(props: PropsWithChildren<any>) {
return ( return (
<> <>
<header className={styles.header}> <header className={styles.header}>
<Navbar isDark={isDarkState.get()} toggle={isDarkState.toggle} /> <AppBar isDark={isDarkState.get()} toggle={isDarkState.toggle} />
</header> </header>
<Main>{props.children}</Main> <MainContainer className={'search_page'}>{props.children}</MainContainer>
<Footer /> <Footer />
</> </>
) )
} }
const MainContainer = styled(Main)`
&.search_page {
margin-top: ${uiConfigs.postSectionMargin * 1.7}px;
}
@media (max-width: 768px) {
&.search_page {
margin-top: ${uiConfigs.postSectionMobileMargin * 3}px;
}
}
`

View File

@ -42,7 +42,6 @@ export async function getStaticPaths() {
export const getStaticProps = async ({ params }: GetStaticPropsContext) => { export const getStaticProps = async ({ params }: GetStaticPropsContext) => {
const { slug } = params! const { slug } = params!
console.log('rendering', slug)
if (!slug) { if (!slug) {
return { return {

View File

@ -84,7 +84,12 @@ export default function SearchPage({
}, [mounted, router.query]) }, [mounted, router.query])
useEffect(() => { useEffect(() => {
setResultsNumber(articles.data.length + blocks.data.length) if (
articles.data.length + blocks.data.length <
initialArticles.length + initialBlocks.length
) {
setResultsNumber(articles.data.length + blocks.data.length)
}
const tags = extractTopicsFromQuery(router.query) const tags = extractTopicsFromQuery(router.query)
setResultsHelperText( setResultsHelperText(
[ [

View File

@ -5,10 +5,6 @@ class SearchService {
constructor() {} constructor() {}
search = (query: string, tags: string[], postType: PostTypes) => { search = (query: string, tags: string[], postType: PostTypes) => {
console.log(
`/api/search/general/${postType}?q=${query}&tags=${tags.join(',')}`,
)
return fetch( return fetch(
`/api/search/general/${postType}?q=${query}&tags=${tags.join(',')}`, `/api/search/general/${postType}?q=${query}&tags=${tags.join(',')}`,
) )

View File

@ -83,6 +83,7 @@ export function useIntersectionObserver(
headings.forEach((heading) => { headings.forEach((heading) => {
if (heading.isIntersecting && heading.target instanceof HTMLElement) { if (heading.isIntersecting && heading.target instanceof HTMLElement) {
const targetId = heading.target.getAttribute('id') const targetId = heading.target.getAttribute('id')
console.log(targetId)
if (targetId) setActiveId(targetId) if (targetId) setActiveId(targetId)
} }
}) })