feat: operators in post meta
This commit is contained in:
parent
d127ff9dea
commit
f53decd736
|
|
@ -80,7 +80,7 @@
|
|||
"remark-stringify": "10.0.2",
|
||||
"sharp": "0.31.2",
|
||||
"sortablejs": "1.15.0",
|
||||
"unidata.js": "0.7.6",
|
||||
"unidata.js": "0.7.7",
|
||||
"unified": "10.1.2",
|
||||
"unist-builder": "3.0.0",
|
||||
"unist-util-visit": "4.1.1",
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ specifiers:
|
|||
sortablejs: 1.15.0
|
||||
tailwindcss: 3.2.4
|
||||
typescript: 4.9.3
|
||||
unidata.js: 0.7.6
|
||||
unidata.js: 0.7.7
|
||||
unified: 10.1.2
|
||||
unist-builder: 3.0.0
|
||||
unist-util-visit: 4.1.1
|
||||
|
|
@ -173,7 +173,7 @@ dependencies:
|
|||
remark-stringify: 10.0.2
|
||||
sharp: 0.31.2
|
||||
sortablejs: 1.15.0
|
||||
unidata.js: 0.7.6
|
||||
unidata.js: 0.7.7
|
||||
unified: 10.1.2
|
||||
unist-builder: 3.0.0
|
||||
unist-util-visit: 4.1.1
|
||||
|
|
@ -1734,8 +1734,8 @@ packages:
|
|||
resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
|
||||
dev: true
|
||||
|
||||
/@types/lodash/4.14.189:
|
||||
resolution: {integrity: sha512-kb9/98N6X8gyME9Cf7YaqIMvYGnBSWqEci6tiettE6iJWH1XdJz/PO8LB0GtLCG7x8dU3KWhZT+lA1a35127tA==}
|
||||
/@types/lodash/4.14.190:
|
||||
resolution: {integrity: sha512-5iJ3FBJBvQHQ8sFhEhJfjUP+G+LalhavTkYyrAYqz5MEJG+erSv0k9KJLb6q7++17Lafk1scaTIFXcMJlwK8Mw==}
|
||||
dev: false
|
||||
|
||||
/@types/mdast/3.0.10:
|
||||
|
|
@ -8284,10 +8284,10 @@ packages:
|
|||
dependencies:
|
||||
busboy: 1.6.0
|
||||
|
||||
/unidata.js/0.7.6:
|
||||
resolution: {integrity: sha512-m5RBr4BIjbhUV0V8OlLnh40z+zmj0fS8iZlEjmgLF5mz5Bz0c7sFVCLZSmwWWV5Xlnl1ToFRDzzh8HUR5hihZA==}
|
||||
/unidata.js/0.7.7:
|
||||
resolution: {integrity: sha512-RPUA4r6nf63TNeuFaY1CljfHOly1iIWFmjS+UC8h4ew/gWgTzBKxqOLRRk9+0tiorOzjyoysJsvQIoNn/BRc+A==}
|
||||
dependencies:
|
||||
'@types/lodash': 4.14.189
|
||||
'@types/lodash': 4.14.190
|
||||
'@urql/core': 3.0.5_graphql@16.6.0
|
||||
axios: 1.1.3
|
||||
axios-retry: 3.3.1
|
||||
|
|
|
|||
|
|
@ -53,7 +53,9 @@ export const CharacterCard: React.FC<{
|
|||
)}
|
||||
</span>
|
||||
<span className="block">
|
||||
<span className="font-bold text-base">{site?.name}</span>
|
||||
<span className="font-bold text-base text-zinc-800">
|
||||
{site?.name}
|
||||
</span>
|
||||
<span className="ml-1 text-gray-600">@{site.username}</span>
|
||||
</span>
|
||||
{site?.description && (
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import { DashboardSidebar } from "./DashboardSidebar"
|
|||
import { useGetUserSites } from "~/queries/site"
|
||||
import { useAccount } from "wagmi"
|
||||
import { ConnectButton } from "~/components/common/ConnectButton"
|
||||
import { useGetNotifications, useGetSite } from "~/queries/site"
|
||||
import { useGetNotifications, useGetSite, useIsOperators } from "~/queries/site"
|
||||
import { getStorage } from "~/lib/storage"
|
||||
import { toGateway } from "~/lib/ipfs-parser"
|
||||
|
||||
|
|
@ -33,6 +33,11 @@ export function DashboardLayout({
|
|||
siteCId: site.data?.metadata?.proof,
|
||||
})
|
||||
|
||||
const isOperator = useIsOperators({
|
||||
characterId: +(site.data?.metadata?.proof || 0),
|
||||
operator: address,
|
||||
})
|
||||
|
||||
const notificationCreatedAt =
|
||||
getStorage(`notification-${subdomain}`)?.createdAt || 0
|
||||
|
||||
|
|
@ -53,11 +58,21 @@ export function DashboardLayout({
|
|||
router.push("/")
|
||||
}
|
||||
if (userSite.isSuccess && subdomain) {
|
||||
if (!userSite.data?.find((site) => site.username === subdomain)) {
|
||||
if (
|
||||
!userSite.data?.find((site) => site.username === subdomain) &&
|
||||
!isOperator.data
|
||||
) {
|
||||
router.push("/dashboard")
|
||||
}
|
||||
}
|
||||
}, [address, router, userSite.isSuccess, userSite.data, subdomain])
|
||||
}, [
|
||||
address,
|
||||
router,
|
||||
userSite.isSuccess,
|
||||
userSite.data,
|
||||
subdomain,
|
||||
isOperator.data,
|
||||
])
|
||||
|
||||
const links: {
|
||||
href: string
|
||||
|
|
@ -147,7 +162,6 @@ export function DashboardLayout({
|
|||
<UniLink
|
||||
href={getSiteLink({
|
||||
subdomain,
|
||||
domain: userSite.data?.[0]?.custom_domain,
|
||||
})}
|
||||
className="space-x-2 border rounded-lg bg-gray-100 border-gray-200 text-gray-500 hover:text-accent flex w-full h-12 items-center justify-center transition-colors"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -1,24 +1,30 @@
|
|||
import { formatDate, formatToISO } from "~/lib/date"
|
||||
import { BlockchainIcon } from "~/components/icons/BlockchainIcon"
|
||||
import { UniLink } from "~/components/ui/UniLink"
|
||||
import { Note } from "~/lib/types"
|
||||
import { Note, Profile } from "~/lib/types"
|
||||
import { CSB_SCAN } from "~/lib/env"
|
||||
import { useEffect, useState } from "react"
|
||||
import { useGetUserSites } from "~/queries/site"
|
||||
import { CharacterFloatCard } from "~/components/common/CharacterFloatCard"
|
||||
import { getSiteLink } from "~/lib/helpers"
|
||||
import { Avatar } from "~/components/ui/Avatar"
|
||||
|
||||
export const PostMeta: React.FC<{
|
||||
page: Note
|
||||
}> = ({ page }) => {
|
||||
site?: Profile | null
|
||||
}> = ({ page, site }) => {
|
||||
const [isMounted, setIsMounted] = useState(false)
|
||||
const author = useGetUserSites(page.authors[0])
|
||||
|
||||
useEffect(() => {
|
||||
setIsMounted(true)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="text-zinc-400 mt-2 xlog-post-meta">
|
||||
<div className="text-zinc-400 mt-4 xlog-post-meta space-x-5 flex items-center">
|
||||
<time
|
||||
dateTime={formatToISO(page.date_published)}
|
||||
className="xlog-post-date align-middle"
|
||||
className="xlog-post-date"
|
||||
>
|
||||
{formatDate(
|
||||
page.date_published,
|
||||
|
|
@ -26,29 +32,55 @@ export const PostMeta: React.FC<{
|
|||
isMounted ? undefined : "America/Los_Angeles",
|
||||
)}
|
||||
</time>
|
||||
<span className="xlog-post-tags ml-4 space-x-1 align-middle">
|
||||
{page.tags
|
||||
?.filter((tag) => tag !== "post" && tag !== "page")
|
||||
.map((tag) => (
|
||||
<UniLink
|
||||
className="hover:text-zinc-600"
|
||||
key={tag}
|
||||
href={`/tag/${tag}`}
|
||||
>
|
||||
<>#{tag}</>
|
||||
</UniLink>
|
||||
))}
|
||||
</span>
|
||||
<span className="align-middle mx-1"> · </span>
|
||||
{page.tags?.filter((tag) => tag !== "post" && tag !== "page").length ? (
|
||||
<>
|
||||
<span className="xlog-post-tags space-x-1">
|
||||
{page.tags
|
||||
?.filter((tag) => tag !== "post" && tag !== "page")
|
||||
.map((tag) => (
|
||||
<UniLink
|
||||
className="hover:text-zinc-600"
|
||||
key={tag}
|
||||
href={`/tag/${tag}`}
|
||||
>
|
||||
<>#{tag}</>
|
||||
</UniLink>
|
||||
))}
|
||||
</span>
|
||||
</>
|
||||
) : null}
|
||||
{author.data?.[0].username &&
|
||||
site?.username !== author.data?.[0].username && (
|
||||
<>
|
||||
<span className="inline-flex items-center">
|
||||
<CharacterFloatCard siteId={author.data[0].username}>
|
||||
<UniLink
|
||||
href={getSiteLink({
|
||||
subdomain: author.data?.[0].username,
|
||||
})}
|
||||
className="cursor-pointer hover:text-zinc-600 inline-flex items-center"
|
||||
>
|
||||
<Avatar
|
||||
className="mr-1"
|
||||
images={author.data[0].avatars || []}
|
||||
size={19}
|
||||
name={author.data[0].name}
|
||||
/>
|
||||
<span>{author.data[0].name}</span>
|
||||
</UniLink>
|
||||
</CharacterFloatCard>
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
<UniLink
|
||||
className="xlog-post-blockchain align-middle inline-block"
|
||||
className="xlog-post-blockchain inline-block"
|
||||
href={
|
||||
page.related_urls?.filter((url) =>
|
||||
url.startsWith(CSB_SCAN + "/tx/"),
|
||||
)?.[0]
|
||||
}
|
||||
>
|
||||
<BlockchainIcon className="fill-zinc-500" />
|
||||
<BlockchainIcon className="fill-zinc-500 ml-1" />
|
||||
</UniLink>
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
import { PageContent } from "../common/PageContent"
|
||||
import { PostMeta } from "./PostMeta"
|
||||
import { PostFooter } from "./PostFooter"
|
||||
import { Note } from "~/lib/types"
|
||||
import { Note, Profile } from "~/lib/types"
|
||||
|
||||
export const SitePage: React.FC<{
|
||||
page?: Note | null
|
||||
}> = ({ page }) => {
|
||||
site?: Profile | null
|
||||
}> = ({ page, site }) => {
|
||||
return (
|
||||
<>
|
||||
{page?.preview && (
|
||||
|
|
@ -22,7 +23,7 @@ export const SitePage: React.FC<{
|
|||
{page?.title}
|
||||
</h2>
|
||||
)}
|
||||
{page?.tags?.includes("post") && <PostMeta page={page} />}
|
||||
{page?.tags?.includes("post") && <PostMeta page={page} site={site} />}
|
||||
</div>
|
||||
<PageContent
|
||||
className="mt-10"
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ export const Avatar: React.FC<
|
|||
<span
|
||||
{...props}
|
||||
className={clsx(
|
||||
`inline-flex text-zinc-500 bg-gray-400 flex-shrink-0 items-center justify-center text-xl font-medium uppercase overflow-hidden`,
|
||||
`inline-flex text-zinc-500 bg-gray-400 flex-shrink-0 items-center justify-center text-xl font-medium uppercase overflow-hidden text-[0px]`,
|
||||
borderRadius,
|
||||
className,
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import { SitePage } from "~/components/site/SitePage"
|
|||
import { serverSidePropsHandler } from "~/lib/server-side-props"
|
||||
import { dehydrate, QueryClient } from "@tanstack/react-query"
|
||||
import { useGetPage } from "~/queries/page"
|
||||
import { useGetSite } from "~/queries/site"
|
||||
import type { ReactElement } from "react"
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = serverSidePropsHandler(
|
||||
|
|
@ -36,8 +37,9 @@ function SitePagePage({
|
|||
site: domainOrSubdomain,
|
||||
page: pageSlug,
|
||||
})
|
||||
const site = useGetSite(domainOrSubdomain)
|
||||
|
||||
return <SitePage page={page.data} />
|
||||
return <SitePage page={page.data} site={site.data} />
|
||||
}
|
||||
|
||||
SitePagePage.getLayout = (page: ReactElement) => {
|
||||
|
|
|
|||
|
|
@ -3,18 +3,21 @@ import { SitePage } from "~/components/site/SitePage"
|
|||
import { useGetPage } from "~/queries/page"
|
||||
import type { ReactElement } from "react"
|
||||
import { useRouter } from "next/router"
|
||||
import { useGetSite } from "~/queries/site"
|
||||
|
||||
function SitePagePage() {
|
||||
const router = useRouter()
|
||||
const site = router.query.site as string
|
||||
const domainOrSubdomain = router.query.site as string
|
||||
const pageSlug = router.query.page as string
|
||||
|
||||
const page = useGetPage({
|
||||
site: site,
|
||||
site: domainOrSubdomain,
|
||||
pageId: pageSlug,
|
||||
})
|
||||
|
||||
return <SitePage page={page.data} />
|
||||
const site = useGetSite(domainOrSubdomain)
|
||||
|
||||
return <SitePage page={page.data} site={site.data} />
|
||||
}
|
||||
|
||||
SitePagePage.getLayout = (page: ReactElement) => {
|
||||
|
|
|
|||
|
|
@ -197,11 +197,20 @@ export const useGetOperators = (
|
|||
}
|
||||
|
||||
export const useIsOperators = (
|
||||
data: Parameters<typeof siteModel.isOperators>[0],
|
||||
data: Partial<Parameters<typeof siteModel.isOperators>[0]>,
|
||||
) => {
|
||||
const contract = useContract()
|
||||
return useQuery(["isOperators", data], async () => {
|
||||
return siteModel.isOperators(data, contract)
|
||||
if (!data.characterId || !data.operator) {
|
||||
return null
|
||||
}
|
||||
return siteModel.isOperators(
|
||||
{
|
||||
characterId: data.characterId,
|
||||
operator: data.operator,
|
||||
},
|
||||
contract,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue