diff --git a/src/components/site/SiteLayout.tsx b/src/components/site/SiteLayout.tsx index 29509d71..0683c743 100644 --- a/src/components/site/SiteLayout.tsx +++ b/src/components/site/SiteLayout.tsx @@ -1,38 +1,90 @@ -import clsx from "clsx" import React, { useEffect } from "react" import { getUserContentsUrl } from "~/lib/user-contents" import { SEOHead } from "../common/SEOHead" -import { SiteNavigationItem, Viewer, Profile, Note } from "~/lib/types" import { SiteFooter } from "./SiteFooter" import { SiteHeader } from "./SiteHeader" import { useRouter } from "next/router" import { useStore } from "~/lib/store" import { BlockchainInfo } from "~/components/common/BlockchainInfo" -import type { Links } from "unidata.js" +import { GetServerSideProps } from "next" +import { + prefetchGetSite, + prefetchGetSiteSubscriptions, +} from "~/queries/site.server" +import { prefetchGetPagesBySite } from "~/queries/page.server" +import { PageVisibilityEnum } from "~/lib/types" +import { useGetSiteSubscriptions } from "~/queries/site" +import { dehydrate } from "@tanstack/react-query" +import { queryClientServer } from "~/lib/query-client.server" +import { useGetSite } from "~/queries/site" +import { fetchGetPage } from "~/queries/page.server" +import { notFound } from "~/lib/server-side-props" +import { useGetPage } from "~/queries/page" -export type SiteLayoutProps = { - site?: Profile - viewer?: Profile | null - children: React.ReactNode - title?: string | null - ogDescription?: string | null - page?: Note - subscriptions?: Links | null +export const getServerSideProps: GetServerSideProps = async (ctx) => { + const domainOrSubdomain = ctx.params!.site as string + const pageSlug = ctx.params!.page as string + const tag = ctx.params!.tag as string + + await prefetchGetSite(domainOrSubdomain) + await prefetchGetSiteSubscriptions({ + siteId: domainOrSubdomain, + }) + + if (pageSlug) { + const page = await fetchGetPage({ + site: domainOrSubdomain, + page: pageSlug, + render: true, + includeAuthors: true, + }) + + if (new Date(page!.date_published) > new Date()) { + throw notFound() + } + } else { + await prefetchGetPagesBySite({ + site: domainOrSubdomain, + take: 1000, + type: "post", + visibility: PageVisibilityEnum.Published, + render: true, + ...(tag && { tags: [tag] }), + }) + } + + return { + props: { + dehydratedState: dehydrate(queryClientServer), + }, + } } -export const SiteLayout: React.FC = ({ - site, - viewer, - children, - title, - ogDescription, - page, - subscriptions, -}) => { +export type SiteLayoutProps = { + children: React.ReactNode + title?: string | null +} + +export const SiteLayout: React.FC = ({ children, title }) => { const router = useRouter() + const domainOrSubdomain = router.query.site as string + const pageSlug = router.query.page as string + const tag = router.query.tag as string + + const page = useGetPage({ + site: domainOrSubdomain, + page: pageSlug, + render: true, + includeAuthors: true, + }) + const setSubscribeModalOpened = useStore( (store) => store.setSubscribeModalOpened, ) + const site = useGetSite(domainOrSubdomain) + const subscriptions = useGetSiteSubscriptions({ + siteId: domainOrSubdomain, + }) useEffect(() => { if ("subscription" in router.query) { @@ -43,25 +95,26 @@ export const SiteLayout: React.FC = ({ return ( <> ]*>/g, "") + (page.data?.summary?.content || page.data?.body?.content) ?? + site.data?.description?.replace(/<[^>]*>/g, "") } - image={page?.cover || getUserContentsUrl(site?.avatars?.[0])} - icon={getUserContentsUrl(site?.avatars?.[0])} + image={page.data?.cover || getUserContentsUrl(site.data?.avatars?.[0])} + icon={getUserContentsUrl(site.data?.avatars?.[0])} /> - - + +
{children}
- +
- + ) } diff --git a/src/components/site/SitePage.tsx b/src/components/site/SitePage.tsx index ab6a92ad..e6d9d80e 100644 --- a/src/components/site/SitePage.tsx +++ b/src/components/site/SitePage.tsx @@ -1,14 +1,11 @@ -import type { PageType } from "~/lib/db.server" -import { Rendered } from "~/markdown" import { PageContent } from "../common/PageContent" import { PostMeta } from "./PostMeta" import { PostFooter } from "./PostFooter" -import { Profile, Note } from "~/lib/types" +import { Note } from "~/lib/types" export const SitePage: React.FC<{ - site?: Profile page?: Note -}> = ({ site, page }) => { +}> = ({ page }) => { return ( <>
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index cc7be118..764d6b27 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -71,6 +71,8 @@ const queryClient = new QueryClient({ const persister = createIDBPersister() function MyApp({ Component, pageProps }: any) { + const getLayout = Component.getLayout ?? ((page: any) => page) + return ( @@ -82,7 +84,7 @@ function MyApp({ Component, pageProps }: any) { - + {getLayout()} diff --git a/src/pages/_site/[site]/[page].tsx b/src/pages/_site/[site]/[page].tsx index c404a074..cfb36ea1 100644 --- a/src/pages/_site/[site]/[page].tsx +++ b/src/pages/_site/[site]/[page].tsx @@ -1,31 +1,21 @@ import { GetServerSideProps } from "next" -import { SiteLayout } from "~/components/site/SiteLayout" +import { + SiteLayout, + getServerSideProps as getLayoutServerSideProps, +} from "~/components/site/SiteLayout" import { SitePage } from "~/components/site/SitePage" import { serverSidePropsHandler } from "~/lib/server-side-props" import { queryClientServer } from "~/lib/query-client.server" -import { prefetchGetSite } from "~/queries/site.server" -import { useGetSite } from "~/queries/site" -import { dehydrate, QueryClient } from "@tanstack/react-query" -import { fetchGetPage } from "~/queries/page.server" +import { dehydrate } from "@tanstack/react-query" import { useGetPage } from "~/queries/page" -import { notFound } from "~/lib/server-side-props" +import type { ReactElement } from "react" export const getServerSideProps: GetServerSideProps = serverSidePropsHandler( async (ctx) => { const domainOrSubdomain = ctx.params!.site as string const pageSlug = ctx.params!.page as string - await prefetchGetSite(domainOrSubdomain) - const page = await fetchGetPage({ - site: domainOrSubdomain, - page: pageSlug, - render: true, - includeAuthors: true, - }) - - if (new Date(page!.date_published) > new Date()) { - throw notFound() - } + await getLayoutServerSideProps(ctx) return { props: { @@ -50,15 +40,12 @@ function SitePagePage({ render: true, includeAuthors: true, }) - const ogDescription = page.data?.summary?.content || page.data?.body?.content - const site = useGetSite(domainOrSubdomain) + return +} - return ( - - - - ) +SitePagePage.getLayout = (page: ReactElement) => { + return {page} } export default SitePagePage diff --git a/src/pages/_site/[site]/archives.tsx b/src/pages/_site/[site]/archives.tsx index c06beebd..4749fcca 100644 --- a/src/pages/_site/[site]/archives.tsx +++ b/src/pages/_site/[site]/archives.tsx @@ -1,27 +1,21 @@ import { GetServerSideProps } from "next" -import { SiteLayout } from "~/components/site/SiteLayout" +import { + SiteLayout, + getServerSideProps as getLayoutServerSideProps, +} from "~/components/site/SiteLayout" import { serverSidePropsHandler } from "~/lib/server-side-props" import { SiteArchives } from "~/components/site/SiteArchives" -import { Viewer, Profile, Notes } from "~/lib/types" +import { Profile, Notes } from "~/lib/types" import { queryClientServer } from "~/lib/query-client.server" -import { prefetchGetSite } from "~/queries/site.server" -import { useGetSite } from "~/queries/site" -import { dehydrate, QueryClient } from "@tanstack/react-query" +import { dehydrate } from "@tanstack/react-query" import { useGetPagesBySite } from "~/queries/page" -import { prefetchGetPagesBySite } from "~/queries/page.server" import { PageVisibilityEnum } from "~/lib/types" +import type { ReactElement } from "react" export const getServerSideProps: GetServerSideProps = serverSidePropsHandler( async (ctx) => { const domainOrSubdomain = ctx.params!.site as string - - await prefetchGetSite(domainOrSubdomain) - await prefetchGetPagesBySite({ - site: domainOrSubdomain, - take: 1000, - type: "post", - visibility: PageVisibilityEnum.Published, - }) + await getLayoutServerSideProps(ctx) return { props: { @@ -39,19 +33,19 @@ function SiteArchivesPage({ posts: Notes domainOrSubdomain: string }) { - const site = useGetSite(domainOrSubdomain) const posts = useGetPagesBySite({ site: domainOrSubdomain, take: 1000, type: "post", visibility: PageVisibilityEnum.Published, + render: true, }) - return ( - - - - ) + return +} + +SiteArchivesPage.getLayout = (page: ReactElement) => { + return {page} } export default SiteArchivesPage diff --git a/src/pages/_site/[site]/index.tsx b/src/pages/_site/[site]/index.tsx index 425362d2..6e6ef34c 100644 --- a/src/pages/_site/[site]/index.tsx +++ b/src/pages/_site/[site]/index.tsx @@ -1,32 +1,18 @@ import { GetServerSideProps } from "next" import { SiteHome } from "~/components/site/SiteHome" -import { SiteLayout } from "~/components/site/SiteLayout" -import { queryClientServer } from "~/lib/query-client.server" import { - prefetchGetSite, - prefetchGetSiteSubscriptions, -} from "~/queries/site.server" -import { useGetSite } from "~/queries/site" -import { dehydrate, QueryClient } from "@tanstack/react-query" + SiteLayout, + getServerSideProps as getLayoutServerSideProps, +} from "~/components/site/SiteLayout" +import { queryClientServer } from "~/lib/query-client.server" +import { dehydrate } from "@tanstack/react-query" import { useGetPagesBySite } from "~/queries/page" -import { prefetchGetPagesBySite } from "~/queries/page.server" import { PageVisibilityEnum } from "~/lib/types" -import { useGetSiteSubscriptions } from "~/queries/site" +import type { ReactElement } from "react" export const getServerSideProps: GetServerSideProps = async (ctx) => { const domainOrSubdomain = ctx.params!.site as string - - await prefetchGetSite(domainOrSubdomain) - await prefetchGetPagesBySite({ - site: domainOrSubdomain, - take: 1000, - type: "post", - visibility: PageVisibilityEnum.Published, - render: true, - }) - await prefetchGetSiteSubscriptions({ - siteId: domainOrSubdomain, - }) + await getLayoutServerSideProps(ctx) return { props: { @@ -37,7 +23,6 @@ export const getServerSideProps: GetServerSideProps = async (ctx) => { } function SiteIndexPage({ domainOrSubdomain }: { domainOrSubdomain: string }) { - const site = useGetSite(domainOrSubdomain) const posts = useGetPagesBySite({ site: domainOrSubdomain, take: 1000, @@ -45,15 +30,12 @@ function SiteIndexPage({ domainOrSubdomain }: { domainOrSubdomain: string }) { visibility: PageVisibilityEnum.Published, render: true, }) - const subscriptions = useGetSiteSubscriptions({ - siteId: domainOrSubdomain, - }) - return ( - - - - ) + return +} + +SiteIndexPage.getLayout = (page: ReactElement) => { + return {page} } export default SiteIndexPage diff --git a/src/pages/_site/[site]/tag/[tag].tsx b/src/pages/_site/[site]/tag/[tag].tsx index 40623af2..01a055da 100644 --- a/src/pages/_site/[site]/tag/[tag].tsx +++ b/src/pages/_site/[site]/tag/[tag].tsx @@ -1,29 +1,23 @@ import { GetServerSideProps } from "next" -import { SiteLayout } from "~/components/site/SiteLayout" +import { + SiteLayout, + getServerSideProps as getLayoutServerSideProps, +} from "~/components/site/SiteLayout" import { serverSidePropsHandler } from "~/lib/server-side-props" import { SiteArchives } from "~/components/site/SiteArchives" -import { Viewer, Profile, Notes } from "~/lib/types" +import { Profile, Notes } from "~/lib/types" import { queryClientServer } from "~/lib/query-client.server" -import { prefetchGetSite } from "~/queries/site.server" -import { useGetSite } from "~/queries/site" -import { dehydrate, QueryClient } from "@tanstack/react-query" +import { dehydrate } from "@tanstack/react-query" import { useGetPagesBySite } from "~/queries/page" -import { prefetchGetPagesBySite } from "~/queries/page.server" import { PageVisibilityEnum } from "~/lib/types" +import type { ReactElement } from "react" export const getServerSideProps: GetServerSideProps = serverSidePropsHandler( async (ctx) => { const domainOrSubdomain = ctx.params!.site as string const tag = ctx.params!.tag as string - await prefetchGetSite(domainOrSubdomain) - await prefetchGetPagesBySite({ - site: domainOrSubdomain, - take: 1000, - type: "post", - visibility: PageVisibilityEnum.Published, - tags: [tag], - }) + await getLayoutServerSideProps(ctx) return { props: { @@ -35,7 +29,7 @@ export const getServerSideProps: GetServerSideProps = serverSidePropsHandler( }, ) -function SiteArchivesPage({ +function SiteTagPage({ domainOrSubdomain, tag, }: { @@ -44,20 +38,20 @@ function SiteArchivesPage({ domainOrSubdomain: string tag: string }) { - const site = useGetSite(domainOrSubdomain) const posts = useGetPagesBySite({ site: domainOrSubdomain, take: 1000, type: "post", visibility: PageVisibilityEnum.Published, + render: true, tags: [tag], }) - return ( - - - - ) + return } -export default SiteArchivesPage +SiteTagPage.getLayout = (page: ReactElement) => { + return {page} +} + +export default SiteTagPage