feat: site stat
This commit is contained in:
parent
e9a0c3f555
commit
5d2d68671d
|
|
@ -7,18 +7,10 @@ import type { Profiles as UniProfiles } from "unidata.js"
|
|||
import { createClient } from "@urql/core"
|
||||
import axios from "axios"
|
||||
import { indexer } from "@crossbell/indexer"
|
||||
import type { LinkEntity, NoteEntity, Contract } from "crossbell.js"
|
||||
import type { Contract } from "crossbell.js"
|
||||
import { CharacterOperatorPermission } from "crossbell.js"
|
||||
import { GeneralAccount } from "@crossbell/connect-kit"
|
||||
|
||||
export const checkSubdomain = async ({
|
||||
subdomain,
|
||||
updatingSiteId,
|
||||
}: {
|
||||
subdomain: string
|
||||
updatingSiteId?: string
|
||||
}) => {}
|
||||
|
||||
const expandSite = (site: Profile) => {
|
||||
site.navigation = JSON.parse(
|
||||
site.metadata?.raw?.attributes?.find(
|
||||
|
|
@ -247,6 +239,7 @@ export const getSiteSubscriptions = async (
|
|||
data: {
|
||||
siteId: string
|
||||
cursor?: string
|
||||
limit?: number
|
||||
},
|
||||
customUnidata?: Unidata,
|
||||
) => {
|
||||
|
|
@ -256,6 +249,7 @@ export const getSiteSubscriptions = async (
|
|||
platform: "Crossbell",
|
||||
reversed: true,
|
||||
cursor: data.cursor,
|
||||
limit: data.limit,
|
||||
})
|
||||
|
||||
links?.list.map(async (item: any) => {
|
||||
|
|
@ -540,3 +534,35 @@ export async function getNFTs(address: string, customUnidata?: Unidata) {
|
|||
})
|
||||
return assets
|
||||
}
|
||||
|
||||
export async function getStat({ characterId }: { characterId: string }) {
|
||||
if (characterId) {
|
||||
const [stat, site, subscriptions, comments, notes] = await Promise.all([
|
||||
(
|
||||
await fetch(
|
||||
`https://indexer.crossbell.io/v1/stat/characters/${characterId}`,
|
||||
)
|
||||
).json(),
|
||||
indexer.getCharacter(characterId),
|
||||
indexer.getBacklinksOfCharacter(characterId, {
|
||||
limit: 0,
|
||||
}),
|
||||
indexer.getNotes({
|
||||
limit: 0,
|
||||
toCharacterId: characterId,
|
||||
}),
|
||||
indexer.getNotes({
|
||||
characterId,
|
||||
sources: "xlog",
|
||||
limit: 0,
|
||||
}),
|
||||
])
|
||||
return {
|
||||
viewsCount: stat.viewNoteCount,
|
||||
createdAt: site?.createdAt,
|
||||
subscriptionCount: subscriptions?.count,
|
||||
commentsCount: comments?.count,
|
||||
notesCount: notes?.count,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,21 +6,62 @@ import Image from "next/image"
|
|||
import { DISCORD_LINK, TWITTER_LINK, GITHUB_LINK, APP_NAME } from "~/lib/env"
|
||||
import { getSiteLink } from "~/lib/helpers"
|
||||
import type { ReactElement } from "react"
|
||||
import { useGetSite, useGetStat } from "~/queries/site"
|
||||
import dayjs from "~/lib/date"
|
||||
|
||||
export default function SubdomainIndex() {
|
||||
const router = useRouter()
|
||||
const subdomain = router.query.subdomain as string
|
||||
const site = useGetSite(subdomain)
|
||||
const characterId = site.data?.metadata?.proof
|
||||
const stat = useGetStat({
|
||||
characterId,
|
||||
})
|
||||
const statMap = [
|
||||
{
|
||||
name: "Total Posts",
|
||||
value: stat.data?.notesCount,
|
||||
},
|
||||
{
|
||||
name: "Total Comments",
|
||||
value: stat.data?.commentsCount,
|
||||
},
|
||||
{
|
||||
name: "Total Subscribers",
|
||||
value: stat.data?.subscriptionCount,
|
||||
},
|
||||
{
|
||||
name: "Total Views",
|
||||
value: stat.data?.viewsCount,
|
||||
},
|
||||
{
|
||||
name: "Site Duration",
|
||||
value: dayjs().diff(dayjs(stat.data?.createdAt), "day") + " days",
|
||||
},
|
||||
]
|
||||
|
||||
return (
|
||||
<DashboardMain>
|
||||
<div className="prose max-w-screen-md">
|
||||
<div className="prose min-w-[270px] max-w-screen-md">
|
||||
<div className="w-14 h-14 mb-8">
|
||||
<Image alt="logo" src="/logo.svg" width={100} height={100} />
|
||||
</div>
|
||||
<p className="text-2xl font-bold">Site Stat</p>
|
||||
<div className="grid gap-4 sm:grid-cols-3 grid-cols-2 mb-8">
|
||||
{statMap.map((item) => (
|
||||
<div
|
||||
key={item.name}
|
||||
className="bg-slate-100 rounded-lg flex justify-center flex-col py-4 px-6"
|
||||
>
|
||||
<span>{item.name}</span>
|
||||
<span className="font-bold text-2xl text-accent">
|
||||
{item.value}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<p>Hello there,</p>
|
||||
<p>
|
||||
This page is quite empty for now, but we will polish it very soon!
|
||||
Maybe some useful analytics!
|
||||
</p>
|
||||
<p>Welcome to use {APP_NAME}!</p>
|
||||
<p>Here{`'`}re some useful links to get started:</p>
|
||||
<ul>
|
||||
<li>
|
||||
|
|
@ -53,10 +94,7 @@ export default function SubdomainIndex() {
|
|||
via RSS Reader
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
You are not alone, join the community to meet friends or give xLog
|
||||
some advice:
|
||||
</p>
|
||||
<p>Join the community to meet friends or build {APP_NAME} together:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<UniLink href={DISCORD_LINK}>
|
||||
|
|
|
|||
|
|
@ -285,3 +285,16 @@ export const useGetNFTs = (address: string) => {
|
|||
).json()
|
||||
})
|
||||
}
|
||||
|
||||
export const useGetStat = (
|
||||
data: Partial<Parameters<typeof siteModel.getStat>[0]>,
|
||||
) => {
|
||||
return useQuery(["getStat", data.characterId], async () => {
|
||||
if (!data.characterId) {
|
||||
return null
|
||||
}
|
||||
return siteModel.getStat({
|
||||
characterId: data.characterId,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue