feat: add news and new friends block on dashboard index
This commit is contained in:
parent
68be592967
commit
d2c01af1bc
|
|
@ -35,8 +35,9 @@
|
|||
"Import markdown file with front matter supported": "导入 Markdown 文件(支持 Front Matter)",
|
||||
"View Site": "查看站点",
|
||||
"hello" : {
|
||||
"welcome" : "<p>你好,</p><p>欢迎使用xLog!</p><p>以下是一些有用的链接,帮助你开始使用 xLog:</p>",
|
||||
"community": "<p>加入我们的社区,认识新朋友或共同建设xLog:</p>"
|
||||
"welcome" : "<p>👋 你好哇,</p><p>欢迎使用 xLog!</p><p>以下是一些有用的链接,帮助你开始使用 xLog:</p>",
|
||||
"hidden": "👋 你好哇",
|
||||
"community": "<p>加入我们的社区,认识新朋友或共同建设 xLog:</p>"
|
||||
},
|
||||
"Edit": "编辑",
|
||||
"Convert to Page": "转换为页面",
|
||||
|
|
@ -117,5 +118,8 @@
|
|||
"Warning": "警告",
|
||||
"Operators have permissions to enter your dashboard, change your settings(excluding xLog subdomain) and post, modify, delete contents on your site.":
|
||||
"影子授权可以进入你的仪表盘,更改你的设置(不包括 xLog 子域名)并在你的站点上发布、修改、删除内容。",
|
||||
"Add": "添加"
|
||||
"Add": "添加",
|
||||
"xLog News": "xLog 新鲜事",
|
||||
"More": "更多",
|
||||
"Meet New Friends": "认识新朋友"
|
||||
}
|
||||
|
|
@ -14,9 +14,9 @@
|
|||
},
|
||||
"Own": {
|
||||
"subtitle": "在区块链上拥有自己的内容",
|
||||
"description": "通过在 Crossbell 区块链上发布来拥有自己的内容。 xLog 不会存储任何数据,xLog 也无法剥夺或修改您的权利和内容,即使 xLog 想这样做。 <aown>了解 Crossbell 是如何工作的。</aown>",
|
||||
"description": "通过在 Crossbell 区块链上发布来拥有自己的内容。 xLog 不会存储任何数据,也无法剥夺或修改你的权利和内容,即使 xLog 想这样做。 <aown>了解 Crossbell 是如何工作的。</aown>",
|
||||
"extra": {
|
||||
"title": "不要相信,要验证",
|
||||
"title": "不要相信,去验证",
|
||||
"description": "在互联网上不轻信任何人是一个好习惯,包括 xLog。因此,我们强烈建议你浏览 xLog 上的任何站点,检查页面底部的交易历史,阅读区块链合约代码,看看实情是否与 xLog 所声称的一致。",
|
||||
"button": "去验证"
|
||||
}
|
||||
|
|
@ -32,7 +32,7 @@
|
|||
"Source Code": "源码",
|
||||
"Visit": "访问",
|
||||
"Easy to get started": "简单上手",
|
||||
"Easy to get started text": "xLog 支持 <strong>web3 钱包</strong>和<strong>电子邮件</strong>连接,使您能够快速创建一个定制的博客,具有自定义域名、订阅、评论、NFT 铸造、RSS 订阅和 AI 增强等功能,仅需 5 分钟即可完成,无需申请或费用。",
|
||||
"Easy to get started text": "xLog 支持 <strong>web3 钱包</strong>和<strong>电子邮件</strong>连接,使你能够快速创建一个定制的博客,具有自定义域名、订阅、评论、NFT 铸造、RSS 订阅和 AI 增强等功能,仅需 5 分钟即可完成,无需申请或费用。",
|
||||
"Safe": "安全",
|
||||
"Safe text": "所有博客数据,包括配置、文章、订阅、评论等,都由你自己签名并安全地存储在<strong>区块链</strong>上,只有你持有的<strong>私钥</strong>才能进行控制和访问。包括 xLog 在内的任何人都无法进行更改。",
|
||||
"Fast": "快速",
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import {
|
|||
import { useUserRole } from "~/hooks/useUserRole"
|
||||
import { useAccountState, useConnectModal } from "@crossbell/connect-kit"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { Logo } from "~/components/common/Logo"
|
||||
|
||||
export function DashboardLayout({
|
||||
children,
|
||||
|
|
@ -105,7 +106,7 @@ export function DashboardLayout({
|
|||
return ready ? (
|
||||
hasPermission ? (
|
||||
<>
|
||||
<SEOHead title={title} siteName={APP_NAME} />
|
||||
<SEOHead title={t(title) || ""} siteName={APP_NAME} />
|
||||
{site?.data?.css && (
|
||||
<link
|
||||
type="text/css"
|
||||
|
|
@ -120,22 +121,37 @@ export function DashboardLayout({
|
|||
<DashboardSidebar>
|
||||
{(isOpen) => (
|
||||
<>
|
||||
<div className="mb-2 px-5 pt-3 pb-2 text-2xl font-extrabold flex items-center">
|
||||
<div className="inline-block w-9 h-9 mr-3">
|
||||
<Logo
|
||||
type="lottie"
|
||||
width={36}
|
||||
height={36}
|
||||
autoplay={false}
|
||||
/>
|
||||
</div>
|
||||
{isOpen && "xLog"}
|
||||
</div>
|
||||
{userSite.data?.[0]?.username &&
|
||||
subdomain &&
|
||||
userSite.data[0].username !== subdomain && (
|
||||
<div className="mb-2 px-5 pt-3 pb-2 bg-orange-50 text-center">
|
||||
<div className="mb-2">You are operating</div>
|
||||
<div className="mb-2">
|
||||
{isOpen && "You are operating"}
|
||||
</div>
|
||||
<Avatar
|
||||
images={site.data?.avatars || []}
|
||||
size={60}
|
||||
size={isOpen ? 60 : 40}
|
||||
name={site.data?.name}
|
||||
/>
|
||||
<span className="flex flex-col justify-center">
|
||||
<span className="block">{site.data?.name}</span>
|
||||
<span className="block text-sm text-zinc-400">
|
||||
@{site.data?.username}
|
||||
{isOpen && (
|
||||
<span className="flex flex-col justify-center">
|
||||
<span className="block">{site.data?.name}</span>
|
||||
<span className="block text-sm text-zinc-400">
|
||||
@{site.data?.username}
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<div className="mb-2 px-2 pt-3 pb-2">
|
||||
|
|
@ -162,7 +178,7 @@ export function DashboardLayout({
|
|||
className={cn(
|
||||
`flex px-4 h-12 items-center rounded-md space-x-2 w-full transition-colors`,
|
||||
active
|
||||
? `bg-slate-200 font-medium text-slate-800`
|
||||
? `bg-slate-200 font-medium text-accent`
|
||||
: `hover:bg-slate-200 hover:bg-opacity-50`,
|
||||
!isOpen && "justify-center",
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
import { cn } from "~/lib/utils"
|
||||
import { useTranslation } from "next-i18next"
|
||||
|
||||
export const DashboardMain: React.FC<{
|
||||
children: React.ReactNode
|
||||
fullWidth?: boolean
|
||||
}> = ({ children, fullWidth }) => {
|
||||
title?: string
|
||||
}> = ({ children, fullWidth, title }) => {
|
||||
const { t } = useTranslation("dashboard")
|
||||
|
||||
return (
|
||||
<div className="flex-1 overflow-scroll">
|
||||
<div
|
||||
|
|
@ -13,6 +17,7 @@ export const DashboardMain: React.FC<{
|
|||
: "max-w-screen-2xl relative px-5 py-5 md:px-10",
|
||||
)}
|
||||
>
|
||||
{title && <p className="text-2xl font-bold mb-8">{t(title)}</p>}
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { useRouter } from "next/router"
|
|||
import { DashboardLayout } from "~/components/dashboard/DashboardLayout"
|
||||
import { DashboardMain } from "~/components/dashboard/DashboardMain"
|
||||
import { UniLink } from "~/components/ui/UniLink"
|
||||
import Image from "next/image"
|
||||
import { Image } from "~/components/ui/Image"
|
||||
import { DISCORD_LINK, TWITTER_LINK, GITHUB_LINK, APP_NAME } from "~/lib/env"
|
||||
import { getSiteLink } from "~/lib/helpers"
|
||||
import type { ReactElement } from "react"
|
||||
|
|
@ -12,7 +12,14 @@ import { useTranslation, Trans } from "next-i18next"
|
|||
import { getServerSideProps as getLayoutServerSideProps } from "~/components/dashboard/DashboardLayout.server"
|
||||
import { GetServerSideProps } from "next"
|
||||
import { serverSidePropsHandler } from "~/lib/server-side-props"
|
||||
import { Logo } from "~/components/common/Logo"
|
||||
import { getStorage, setStorage } from "~/lib/storage"
|
||||
import { useState } from "react"
|
||||
import { ChevronDownIcon } from "@heroicons/react/20/solid"
|
||||
import { cn } from "~/lib/utils"
|
||||
import { useGetPagesBySite } from "~/queries/page"
|
||||
import showcase from "../../../../showcase.json"
|
||||
import { useGetSites } from "~/queries/site"
|
||||
import { CharacterFloatCard } from "~/components/common/CharacterFloatCard"
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = serverSidePropsHandler(
|
||||
async (ctx) => {
|
||||
|
|
@ -62,103 +69,172 @@ export default function SubdomainIndex() {
|
|||
},
|
||||
]
|
||||
|
||||
const pages = useGetPagesBySite({
|
||||
type: "post",
|
||||
site: "xlog",
|
||||
take: 4,
|
||||
})
|
||||
|
||||
const showcaseSites = useGetSites(showcase)
|
||||
|
||||
return (
|
||||
<DashboardMain>
|
||||
<div className="prose min-w-[270px] max-w-screen-md">
|
||||
<div className="w-14 h-14 mb-8">
|
||||
<Logo type="lottie" width={56} height={56} />
|
||||
<DashboardMain title="Dashboard">
|
||||
<div className="min-w-[270px] flex flex-col xl:flex-row space-y-8 xl:space-y-0">
|
||||
<div className="flex-1 space-y-8">
|
||||
<div className="grid gap-4 sm:grid-cols-3 grid-cols-2">
|
||||
{statMap.map((item) => (
|
||||
<div
|
||||
key={item.name}
|
||||
className="bg-slate-100 rounded-lg flex justify-center flex-col py-4 px-6"
|
||||
>
|
||||
<span>{t(item.name)}</span>
|
||||
<span className="font-bold text-2xl text-accent">
|
||||
{item.value}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="prose p-6 bg-slate-50 rounded-lg relative">
|
||||
<Trans
|
||||
i18nKey="hello.welcome"
|
||||
defaults="<p>👋 Hello there,</p><p>Welcome to use xLog!</p><p>Here're some useful links to get started:</p>"
|
||||
components={{
|
||||
p: <p />,
|
||||
}}
|
||||
ns="dashboard"
|
||||
/>
|
||||
<ul>
|
||||
<li>
|
||||
<UniLink href={`/dashboard/${subdomain}/editor?type=post`}>
|
||||
Create a Post
|
||||
</UniLink>
|
||||
</li>
|
||||
<li>
|
||||
<UniLink href={`/dashboard/${subdomain}/settings/general`}>
|
||||
Change Site Name or Icon
|
||||
</UniLink>
|
||||
</li>
|
||||
</ul>
|
||||
<Trans
|
||||
i18nKey="hello.community"
|
||||
defaults="<p>Join the community to meet friends or build xLog together:</p>"
|
||||
components={{
|
||||
p: <p />,
|
||||
}}
|
||||
ns="dashboard"
|
||||
/>
|
||||
<ul>
|
||||
<li>
|
||||
<UniLink href={DISCORD_LINK}>
|
||||
Join {APP_NAME}
|
||||
{`'`}s Discord channel
|
||||
</UniLink>
|
||||
</li>
|
||||
<li>
|
||||
<UniLink
|
||||
href={getSiteLink({
|
||||
subdomain: "xlog",
|
||||
})}
|
||||
>
|
||||
Follow {APP_NAME}
|
||||
{`'`}s xLog
|
||||
</UniLink>
|
||||
</li>
|
||||
<li>
|
||||
<UniLink href={GITHUB_LINK}>
|
||||
Participate in the development of xLog
|
||||
</UniLink>
|
||||
</li>
|
||||
<li>
|
||||
<UniLink href={TWITTER_LINK}>
|
||||
Follow {APP_NAME}
|
||||
{`'`}s Twitter
|
||||
</UniLink>
|
||||
</li>
|
||||
</ul>
|
||||
<div></div>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-2xl font-bold">{t("Site Stats")}</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"
|
||||
<div className="w-full xl:w-[500px] xl:ml-10 space-y-7">
|
||||
<div className="p-6 bg-slate-50 rounded-lg relative">
|
||||
<UniLink
|
||||
href={getSiteLink({ subdomain: "xlog" })}
|
||||
className="absolute right-0 left-0 top-0 h-16 cursor-pointer"
|
||||
>
|
||||
<span>{t(item.name)}</span>
|
||||
<span className="font-bold text-2xl text-accent">
|
||||
{item.value}
|
||||
</span>
|
||||
<div className="absolute right-5 top-5 text-sm font-bold">
|
||||
{t("More")}
|
||||
</div>
|
||||
</UniLink>
|
||||
<h4 className="text-xl font-bold mb-4 leading-none">
|
||||
{t("xLog News")}
|
||||
</h4>
|
||||
<div className="grid gap-4 grid-cols-1 sm:grid-cols-2">
|
||||
{pages.data?.pages[0]?.list.map((item) => (
|
||||
<UniLink
|
||||
href={`${getSiteLink({ subdomain: "xlog" })}/${item.slug}`}
|
||||
key={item.id}
|
||||
className="bg-slate-100 rounded-lg flex flex-col py-4 px-6"
|
||||
>
|
||||
{item.cover && (
|
||||
<div className="w-full h-24">
|
||||
<Image
|
||||
className="object-cover rounded"
|
||||
alt="cover"
|
||||
fill={true}
|
||||
src={item.cover}
|
||||
></Image>
|
||||
</div>
|
||||
)}
|
||||
<span className="font-bold text-sm text-zinc-800 leading-tight mt-4">
|
||||
{item.title}
|
||||
</span>
|
||||
</UniLink>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="p-6 bg-slate-50 rounded-lg relative">
|
||||
<h4 className="text-xl font-bold mb-4 leading-none">
|
||||
{t("Meet New Friends")}
|
||||
</h4>
|
||||
<ul className="pt-2 grid grid-cols-3 gap-6 relative">
|
||||
{showcaseSites.data.slice(0, 6)?.map((site: any) => (
|
||||
<li className="inline-flex align-middle" key={site.handle}>
|
||||
<UniLink
|
||||
href={getSiteLink({
|
||||
subdomain: site.handle,
|
||||
})}
|
||||
className="inline-flex align-middle w-full"
|
||||
>
|
||||
<CharacterFloatCard siteId={site.handle}>
|
||||
<span className="w-14 h-14 inline-block">
|
||||
<Image
|
||||
className="rounded-full"
|
||||
src={
|
||||
site.metadata.content?.avatars?.[0] ||
|
||||
"ipfs://bafkreiabgixxp63pg64moxnsydz7hewmpdkxxi3kdsa4oqv4pb6qvwnmxa"
|
||||
}
|
||||
alt={site.handle}
|
||||
width="56"
|
||||
height="56"
|
||||
></Image>
|
||||
</span>
|
||||
</CharacterFloatCard>
|
||||
<span className="ml-3 min-w-0 flex-1 justify-center inline-flex flex-col">
|
||||
<span className="truncate w-full inline-block font-medium">
|
||||
{site.metadata.content?.name}
|
||||
</span>
|
||||
{site.metadata.content?.bio && (
|
||||
<span className="text-gray-500 text-xs truncate w-full inline-block mt-1">
|
||||
{site.metadata.content?.bio}
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
</UniLink>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<Trans
|
||||
i18nKey="hello.welcome"
|
||||
defaults="<p>Hello there,</p><p>Welcome to use xLog!</p><p>Here're some useful links to get started:</p>"
|
||||
components={{
|
||||
p: <p />,
|
||||
}}
|
||||
ns="dashboard"
|
||||
/>
|
||||
<ul>
|
||||
<li>
|
||||
<UniLink href={`/dashboard/${subdomain}/editor?type=post`}>
|
||||
Create a Post
|
||||
</UniLink>
|
||||
</li>
|
||||
<li>
|
||||
<UniLink href={`/dashboard/${subdomain}/settings/general`}>
|
||||
Change Site Name or Icon
|
||||
</UniLink>
|
||||
</li>
|
||||
<li>
|
||||
Subscribe the{" "}
|
||||
<UniLink
|
||||
href={`${getSiteLink({
|
||||
subdomain: subdomain,
|
||||
})}/feed`}
|
||||
>
|
||||
posts feed
|
||||
</UniLink>{" "}
|
||||
and{" "}
|
||||
<UniLink
|
||||
href={`${getSiteLink({
|
||||
subdomain: subdomain,
|
||||
})}/feed/notifications`}
|
||||
>
|
||||
notifications feed
|
||||
</UniLink>{" "}
|
||||
via RSS Reader
|
||||
</li>
|
||||
</ul>
|
||||
<Trans
|
||||
i18nKey="hello.community"
|
||||
defaults="<p>Join the community to meet friends or build xLog together:</p>"
|
||||
components={{
|
||||
p: <p />,
|
||||
}}
|
||||
ns="dashboard"
|
||||
/>
|
||||
<ul>
|
||||
<li>
|
||||
<UniLink href={DISCORD_LINK}>
|
||||
Join {APP_NAME}
|
||||
{`'`}s Discord channel
|
||||
</UniLink>
|
||||
</li>
|
||||
<li>
|
||||
<UniLink
|
||||
href={getSiteLink({
|
||||
subdomain: "xlog",
|
||||
})}
|
||||
>
|
||||
Follow {APP_NAME}
|
||||
{`'`}s xLog
|
||||
</UniLink>
|
||||
</li>
|
||||
<li>
|
||||
<UniLink href={GITHUB_LINK}>
|
||||
View {APP_NAME}
|
||||
{`'`}s source code or participate in its development
|
||||
</UniLink>
|
||||
</li>
|
||||
<li>
|
||||
<UniLink href={TWITTER_LINK}>
|
||||
Follow {APP_NAME}
|
||||
{`'`}s Twitter
|
||||
</UniLink>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</DashboardMain>
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in New Issue