feat: site stat

This commit is contained in:
DIYgod 2023-01-19 20:44:26 +00:00
parent e9a0c3f555
commit 5d2d68671d
No known key found for this signature in database
3 changed files with 95 additions and 18 deletions

View File

@ -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,
}
}
}

View File

@ -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}>

View File

@ -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,
})
})
}