feat: i18n for dashboard
This commit is contained in:
parent
4976f3b974
commit
90a7401cf0
|
|
@ -1,7 +1,5 @@
|
|||
{
|
||||
"intlRelativeTime": "{{val, relativetime}}",
|
||||
"intlDateTime": "{{val, datetime}}",
|
||||
"ago": "{{time}} ago",
|
||||
"joined ago": "Joined {{time}} ago",
|
||||
"like stored": "Your like has been stored on the blockchain, view it on <2>Crossbell Scan</2>",
|
||||
"mint stored": "This post has been minted to NFT by you, view it on <2>xChar</2> or <6>Crossbell Scan</6>"
|
||||
"joined ago": "Joined {{time}} ago"
|
||||
}
|
||||
|
|
@ -1 +1,3 @@
|
|||
{}
|
||||
{
|
||||
"link post-vs-page" : "https://wordpress.com/zh-cn/support/post-vs-page/"
|
||||
}
|
||||
|
|
@ -1,5 +1 @@
|
|||
{
|
||||
"description": "xLog, <1>on-chain</1> and <3>open-source</3> blogging platform for everyone.",
|
||||
"discover awesome": "Discover these awesome teams and geeks on xLog (sorted by update time)",
|
||||
"Integration description": "xLog's open design allows it to integrate with many other open protocols and applications without friction."
|
||||
}
|
||||
{}
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
"Followings": "正在关注",
|
||||
"Follow": "关注",
|
||||
"Unfollow": "取消关注",
|
||||
"intlRelativeTime": "{{val, relativetime}}",
|
||||
"intlDateTime": "{{val, datetime}}",
|
||||
"post": "文章",
|
||||
"posts": "文章",
|
||||
"page": "页面",
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
"Posts": "文章",
|
||||
"Pages": "页面",
|
||||
"Notifications": "通知",
|
||||
"Unread notifications": "未读通知",
|
||||
"Settings": "设置",
|
||||
"Site Stats": "站点统计",
|
||||
"Total Posts": "文章总数",
|
||||
|
|
@ -17,7 +18,104 @@
|
|||
"All Posts": "所有文章",
|
||||
"All Pages": "所有页面",
|
||||
"Published": "已发布",
|
||||
"published": "已发布",
|
||||
"Draft": "草稿",
|
||||
"draft": "草稿",
|
||||
"Scheduled": "定时发布",
|
||||
"Others on Crossbell": "Crossbell上的其他内容"
|
||||
"scheduled": "定时发布",
|
||||
"published and local modified": "已发布并本地修改",
|
||||
"Others on Crossbell": "Crossbell上的其他内容",
|
||||
"link post-vs-page" : "https://wordpress.com/zh-cn/support/post-vs-page/",
|
||||
"posts description": "文章是按时间倒序在你的网站上列出的条目。可以将它们看作是更新,以提供新内容给读者。<2>文章与页面</2>。",
|
||||
"pages description": "页面是静态的,不受日期影响。它们更像是你网站上的永久元素,比如“关于我们”、“联系我们”等。<2>文章与页面</2>。",
|
||||
"pages add": "创建页面后,你可以将其<2>添加到你网站的导航菜单中</2>,以便访问者可以找到它。",
|
||||
"New Post": "新建文章",
|
||||
"New Page": "新建页面",
|
||||
"Import": "导入",
|
||||
"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>"
|
||||
},
|
||||
"Edit": "编辑",
|
||||
"Convert to Page": "转换为页面",
|
||||
"Convert to Post": "转换为文章",
|
||||
"Delete": "删除",
|
||||
"Heading": "标题",
|
||||
"Bold": "粗体",
|
||||
"Italic": "斜体",
|
||||
"Strikethrough": "删除线",
|
||||
"Underline": "下划线",
|
||||
"Quote": "引用",
|
||||
"Inline Code": "行内代码",
|
||||
"Code Block": "代码块",
|
||||
"Unordered List": "无序列表",
|
||||
"Ordered List": "有序列表",
|
||||
"Link": "链接",
|
||||
"Image": "图片",
|
||||
"Upload Image": "上传图片",
|
||||
"Tip: xLog Flavored Markdown": "提示:xLog 风格的 Markdown",
|
||||
"Preview": "预览",
|
||||
"Publish": "发布",
|
||||
"Update": "更新",
|
||||
"Unpublish": "取消发布",
|
||||
"Publish at": "发布时间",
|
||||
"This post will be accessible from this time": "此文章将从此时间开始可访问",
|
||||
"This page will be accessible from this time": "此页面将从此时间开始可访问",
|
||||
"Post slug": "文章短链接",
|
||||
"Page slug": "页面短链接",
|
||||
"This post will be accessible at": "此文章将可通过以下链接访问",
|
||||
"This page will be accessible at": "此页面将可通过以下链接访问",
|
||||
"Tags": "标签",
|
||||
"Separate multiple tags with English commas": "多个标签请用英文逗号分隔",
|
||||
"Excerpt": "摘要",
|
||||
"Leave it blank to use auto-generated excerpt": "留空则使用自动生成的摘要",
|
||||
"General": "常规",
|
||||
"Social Platforms": "社交平台",
|
||||
"Navigation": "导航",
|
||||
"Domains": "域名",
|
||||
"Custom CSS": "自定义 CSS",
|
||||
"Operators": "影子授权",
|
||||
"Export data": "导出数据",
|
||||
"Site Settings": "站点设置",
|
||||
"Icon": "图标",
|
||||
"Banner": "横幅",
|
||||
"Supports both pictures and videos.": "支持图片和视频。",
|
||||
"Name": "名称",
|
||||
"Description": "描述",
|
||||
"Integrate Google Analytics": "将 Google Analytics 集成到你的站点中。你可以按照<2>这里</2>的说明查找你的 Measurement ID。",
|
||||
"Save": "保存",
|
||||
"Tips": "提示",
|
||||
"social tips": {
|
||||
"p1": "这些社交平台将显示在你的 xLog 的右下角。",
|
||||
"p2": "我们支持<2>这些平台</2>,自动显示其标志和链接。对于其他平台,将显示默认标志。如果你有其他需求,请随时向我们提交问题或PR,以支持更多的平台。",
|
||||
"p3": "你还可以在 <2>xSync</2> 上连接到 Twitter、Telegram 频道、Medium、Substack 等平台,并自动同步内容。当你在那里设置同步后,它也会显示在这里。"
|
||||
},
|
||||
"Platform": "平台",
|
||||
"Identity": "身份",
|
||||
"Remove": "移除",
|
||||
"New Item": "新建项目",
|
||||
"xLog provides some out-of-the-box built-in pages": "xLog 提供了一些开箱即用的内置页面",
|
||||
"Home page": "首页",
|
||||
"Archives page": "归档页面",
|
||||
"Tag page": "标签页面",
|
||||
"NFT Showcase page": "NFT 展示页面",
|
||||
"Label": "标签",
|
||||
"URL": "链接",
|
||||
"subdomain": "子域名",
|
||||
"Custom Domain": "自定义域名",
|
||||
"Set the following record on your DNS provider to active your custom domain": "在你的 DNS 提供商上设置以下记录以激活自定义域名",
|
||||
"Scope: These styles will be applied to your entire blog, including this dashboard.": "范围:这些样式将应用于你的整个博客,包括这个仪表盘。",
|
||||
"Support": "支持",
|
||||
"CSS variables: xLog provides some built-in CSS variables": "CSS 变量:xLog 提供了一些内置的 CSS 变量",
|
||||
"Address": "地址",
|
||||
"Character": "角色",
|
||||
"New operator": "新建授权",
|
||||
"Operator Address": "授权地址",
|
||||
"Operator Character Check": "授权角色检查",
|
||||
"Warning": "警告",
|
||||
"Operators have permissions to enter your dashboard, change your settings(excluding xLog subdomain) and post, modify, delete contents on your site.":
|
||||
"影子授权可以进入你的仪表盘,更改你的设置(不包括 xLog 子域名)并在你的站点上发布、修改、删除内容。",
|
||||
"Add": "添加"
|
||||
}
|
||||
|
|
@ -17,10 +17,10 @@
|
|||
"Customizable description": "使用自己的<strong>域名</strong>,自定义网站<strong>风格</strong>,完全自由地打造你的网站。这是你的网站,没有任何限制。",
|
||||
"Open": "开放",
|
||||
"Open description": "采用标准的 <strong>Markdown</strong> 语法,并提供了导入和导出工具以及丰富的API,让迁入和迁出变得轻而易举。所有的代码都<strong>开源</strong>在 GitHub 上,所有的<strong>数据都透明</strong>地存储在区块链上。",
|
||||
"discover awesome": "在 xLog 上发现这些超棒的团队和极客们(按更新时间排序)",
|
||||
"Discover these awesome teams and geeks on xLog (sorted by update time)": "在 xLog 上发现这些超棒的团队和极客们(按更新时间排序)",
|
||||
"Follow All!": "关注所有!",
|
||||
"Show more": "显示更多",
|
||||
"Submit yours": "提交你的",
|
||||
"Integration description": "xLog 的开放式设计使其能够与许多其他开放协议和应用程序无缝集成,没有任何限制。",
|
||||
"xLog's open design allows it to integrate with many other open protocols and applications without friction.": "xLog 的开放式设计使其能够与许多其他开放协议和应用程序无缝集成,没有任何限制。",
|
||||
"Dashboard": "仪表盘"
|
||||
}
|
||||
|
|
@ -40,7 +40,7 @@ export function DashboardLayout({
|
|||
const connectModal = useConnectModal()
|
||||
const [ready, setReady] = React.useState(false)
|
||||
const [hasPermission, setHasPermission] = React.useState(false)
|
||||
const { t } = useTranslation(["common", "dashboard"])
|
||||
const { t } = useTranslation("dashboard")
|
||||
|
||||
useEffect(() => {
|
||||
if (ssrReady) {
|
||||
|
|
@ -169,9 +169,7 @@ export function DashboardLayout({
|
|||
onClick={link.onClick}
|
||||
>
|
||||
<span className={clsx(link.icon, "text-lg")}></span>
|
||||
{isOpen && (
|
||||
<span>{t(link.text, { ns: "dashboard" })}</span>
|
||||
)}
|
||||
{isOpen && <span>{t(link.text)}</span>}
|
||||
</UniLink>
|
||||
)
|
||||
})}
|
||||
|
|
@ -185,7 +183,7 @@ export function DashboardLayout({
|
|||
className="space-x-2 border rounded-lg bg-slate-100 border-slate-200 text-slate-500 hover:text-accent flex w-full h-12 items-center justify-center transition-colors"
|
||||
>
|
||||
<span className="i-bi:box-arrow-up-right"></span>
|
||||
{isOpen && <span>View Site</span>}
|
||||
{isOpen && <span>{t("View Site")}</span>}
|
||||
</UniLink>
|
||||
</div>
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import { nanoid } from "nanoid"
|
|||
import { renderPageContent } from "~/markdown"
|
||||
import { Tooltip } from "../ui/Tooltip"
|
||||
import { APP_NAME } from "~/lib/env"
|
||||
import { useTranslation } from "next-i18next"
|
||||
import { Trans, useTranslation } from "next-i18next"
|
||||
|
||||
export const PagesManager: React.FC<{
|
||||
isPost: boolean
|
||||
|
|
@ -45,12 +45,12 @@ export const PagesManager: React.FC<{
|
|||
const createOrUpdatePage = useCreateOrUpdatePage()
|
||||
const [convertToastId, setConvertToastId] = useState("")
|
||||
const [deleteToastId, setDeleteToastId] = useState("")
|
||||
const { t } = useTranslation(["common", "site", "dashboard"])
|
||||
const { t } = useTranslation(["dashboard", "site"])
|
||||
const date = useDate()
|
||||
|
||||
useEffect(() => {
|
||||
if (deletePage.isSuccess) {
|
||||
toast.success(t("Deleted!", { ns: "dashboard" }), {
|
||||
toast.success(t("Deleted!"), {
|
||||
id: deleteToastId,
|
||||
})
|
||||
}
|
||||
|
|
@ -58,11 +58,11 @@ export const PagesManager: React.FC<{
|
|||
|
||||
useEffect(() => {
|
||||
if (createOrUpdatePage.isSuccess) {
|
||||
toast.success(t("Converted!", { ns: "dashboard" }), {
|
||||
toast.success(t("Converted!"), {
|
||||
id: convertToastId,
|
||||
})
|
||||
} else if (createOrUpdatePage.isError) {
|
||||
toast.error(t("Failed to convert.", { ns: "dashboard" }), {
|
||||
toast.error(t("Failed to convert."), {
|
||||
id: convertToastId,
|
||||
})
|
||||
}
|
||||
|
|
@ -290,39 +290,42 @@ export const PagesManager: React.FC<{
|
|||
const description = isPost ? (
|
||||
<>
|
||||
<p>
|
||||
<UniLink
|
||||
className="underline"
|
||||
href="https://wordpress.com/support/post-vs-page/"
|
||||
>
|
||||
Post vs. Page
|
||||
</UniLink>
|
||||
. Posts are entries listed in reverse chronological order on your site.
|
||||
Think of them as articles or updates that you share to offer up new
|
||||
content to your readers.
|
||||
<Trans i18nKey="posts description" ns="dashboard">
|
||||
Posts are entries listed in reverse chronological order on your site.
|
||||
Think of them as articles or updates that you share to offer up new
|
||||
content to your readers.{" "}
|
||||
<UniLink className="underline" href={t("link post-vs-page") || ""}>
|
||||
Post vs. Page
|
||||
</UniLink>
|
||||
</Trans>
|
||||
</p>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<p>
|
||||
<UniLink
|
||||
className="underline"
|
||||
href="https://wordpress.com/support/post-vs-page/"
|
||||
>
|
||||
Post vs. Page
|
||||
</UniLink>
|
||||
. Pages are static and are not affected by date. Think of them as more
|
||||
permanent fixtures of your site — an About page, and a Contact page are
|
||||
great examples of this.
|
||||
<Trans i18nKey="pages description" ns="dashboard">
|
||||
Pages are static and are not affected by date. Think of them as more
|
||||
permanent fixtures of your site — an About page, and a Contact page
|
||||
are great examples of this.{" "}
|
||||
<UniLink
|
||||
className="underline"
|
||||
href="https://wordpress.com/support/post-vs-page/"
|
||||
>
|
||||
Post vs. Page
|
||||
</UniLink>
|
||||
</Trans>
|
||||
</p>
|
||||
<p>
|
||||
After you create a page, you can{" "}
|
||||
<UniLink
|
||||
className="underline"
|
||||
href={`/dashboard/${subdomain}/settings/navigation`}
|
||||
>
|
||||
add it to your site's navigation menu
|
||||
</UniLink>{" "}
|
||||
so your visitors can find it.
|
||||
<Trans i18nKey="pages add" ns="dashboard">
|
||||
After you create a page, you can{" "}
|
||||
<UniLink
|
||||
className="underline"
|
||||
href={`/dashboard/${subdomain}/settings/navigation`}
|
||||
>
|
||||
add it to your site's navigation menu
|
||||
</UniLink>{" "}
|
||||
so your visitors can find it.
|
||||
</Trans>
|
||||
</p>
|
||||
</>
|
||||
)
|
||||
|
|
@ -333,9 +336,7 @@ export const PagesManager: React.FC<{
|
|||
<DashboardMain>
|
||||
<header className="mb-8">
|
||||
<div className="flex justify-between items-center mb-4">
|
||||
<h2 className="text-2xl font-bold">
|
||||
{t(title, { ns: "dashboard" })}
|
||||
</h2>
|
||||
<h2 className="text-2xl font-bold">{t(title)}</h2>
|
||||
<div className="flex justify-center items-center space-x-4">
|
||||
<Button
|
||||
className={clsx(`space-x-2 inline-flex`)}
|
||||
|
|
@ -359,16 +360,16 @@ export const PagesManager: React.FC<{
|
|||
<path d="M12 20h9"></path>
|
||||
<path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"></path>
|
||||
</svg>
|
||||
<span>New {isPost ? "Post" : "Page"}</span>
|
||||
<span>{t(`New ${isPost ? "Post" : "Page"}`)}</span>
|
||||
</Button>
|
||||
<span className="hidden sm:inline-flex">
|
||||
<Tooltip
|
||||
label="Import markdown file with front matter supported"
|
||||
label={t("Import markdown file with front matter supported")}
|
||||
placement="bottom"
|
||||
>
|
||||
<Button className={clsx(`space-x-2`)} onClick={importFile}>
|
||||
<span className="i-bxs:duplicate inline-block"></span>
|
||||
<span>Import</span>
|
||||
<span>{t("Import")}</span>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</span>
|
||||
|
|
@ -406,7 +407,7 @@ export const PagesManager: React.FC<{
|
|||
)}
|
||||
<div className="text-zinc-400 text-xs mt-1">
|
||||
<span className="capitalize">
|
||||
{getPageVisibility(page).toLowerCase()}
|
||||
{t(getPageVisibility(page))}
|
||||
</span>
|
||||
<span className="mx-2">·</span>
|
||||
<span>
|
||||
|
|
@ -448,7 +449,7 @@ export const PagesManager: React.FC<{
|
|||
<span className="inline-flex">
|
||||
{item.icon}
|
||||
</span>
|
||||
<span>{item.text}</span>
|
||||
<span>{t(item.text)}</span>
|
||||
</button>
|
||||
</Menu.Item>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { useEffect, useRef, useState } from "react"
|
|||
import useOnClickOutside from "use-onclickoutside"
|
||||
|
||||
import { Button, ButtonGroup } from "../ui/Button"
|
||||
import { useTranslation } from "next-i18next"
|
||||
|
||||
export const PublishButton: React.FC<{
|
||||
save: (published: boolean) => void
|
||||
|
|
@ -12,6 +13,7 @@ export const PublishButton: React.FC<{
|
|||
const [showDropdown, setShowDropdown] = useState(false)
|
||||
const dropdownRef = useRef<HTMLDivElement | null>(null)
|
||||
const triggerRef = useRef<HTMLButtonElement | null>(null)
|
||||
const { t } = useTranslation("dashboard")
|
||||
|
||||
useOnClickOutside(dropdownRef, (e) => {
|
||||
if (triggerRef.current?.contains(e.target as any)) return
|
||||
|
|
@ -34,7 +36,7 @@ export const PublishButton: React.FC<{
|
|||
isLoading={isSaving}
|
||||
isDisabled={isDisabled}
|
||||
>
|
||||
{published ? "Update" : "Publish"}
|
||||
{t(published ? "Update" : "Publish")}
|
||||
</Button>
|
||||
{published && (
|
||||
<Button
|
||||
|
|
@ -60,7 +62,7 @@ export const PublishButton: React.FC<{
|
|||
className="flex w-full h-8 hover:bg-zinc-100 items-center px-5"
|
||||
onClick={() => save(false)}
|
||||
>
|
||||
Unpublish
|
||||
{t("Unpublish")}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import React from "react"
|
|||
|
||||
import { type TabItem, Tabs } from "../ui/Tabs"
|
||||
import { DashboardMain } from "./DashboardMain"
|
||||
import { useTranslation } from "next-i18next"
|
||||
|
||||
export const SettingsLayout: React.FC<{
|
||||
title: string
|
||||
|
|
@ -10,6 +11,7 @@ export const SettingsLayout: React.FC<{
|
|||
type: "site" | "account"
|
||||
}> = ({ title, children, type }) => {
|
||||
const router = useRouter()
|
||||
const { t } = useTranslation("dashboard")
|
||||
|
||||
const subdomain = router.query.subdomain as string
|
||||
const tabItems: TabItem[] = (
|
||||
|
|
@ -42,7 +44,7 @@ export const SettingsLayout: React.FC<{
|
|||
<DashboardMain>
|
||||
<div className="">
|
||||
<header className="mb-8">
|
||||
<h2 className="text-2xl font-bold">{title}</h2>
|
||||
<h2 className="text-2xl font-bold">{t(title)}</h2>
|
||||
</header>
|
||||
<div>
|
||||
<Tabs items={tabItems} />
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import clsx from "clsx"
|
|||
import { Dispatch, FC, SetStateAction } from "react"
|
||||
import { ICommand } from "~/editor"
|
||||
import { Tooltip } from "./Tooltip"
|
||||
import { useTranslation } from "next-i18next"
|
||||
|
||||
export interface EditorToolbarProps {
|
||||
view?: EditorView
|
||||
|
|
@ -15,12 +16,13 @@ enum ToolbarMode {
|
|||
}
|
||||
|
||||
export const EditorToolbar: FC<EditorToolbarProps> = ({ view, toolbars }) => {
|
||||
const { t } = useTranslation("dashboard")
|
||||
const renderToolbar =
|
||||
(mode: ToolbarMode) =>
|
||||
// eslint-disable-next-line react/display-name
|
||||
({ name, icon, label, execute }: ICommand) => {
|
||||
return (
|
||||
<Tooltip key={name} label={label} placement="bottom">
|
||||
<Tooltip key={name} label={t(label)} placement="bottom">
|
||||
<button
|
||||
key={name}
|
||||
type="button"
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ export enum PageVisibilityEnum {
|
|||
Scheduled = "scheduled",
|
||||
Draft = "draft",
|
||||
Crossbell = "crossbell",
|
||||
Modified = "published and modified",
|
||||
Modified = "published and local modified",
|
||||
}
|
||||
|
||||
export type PostOnSiteHome = {
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
import { Html, Head, Main, NextScript, DocumentProps } from "next/document"
|
||||
|
||||
export default function Document(props: DocumentProps) {
|
||||
return (
|
||||
<Html lang="en">
|
||||
<Head></Head>
|
||||
<body>
|
||||
<Main />
|
||||
<NextScript />
|
||||
</body>
|
||||
</Html>
|
||||
)
|
||||
}
|
||||
|
|
@ -64,6 +64,7 @@ export default function SubdomainEditor() {
|
|||
const router = useRouter()
|
||||
const queryClient = useQueryClient()
|
||||
const date = useDate()
|
||||
const { t } = useTranslation("dashboard")
|
||||
|
||||
let pageId = router.query.id as string | undefined
|
||||
const subdomain = router.query.subdomain as string
|
||||
|
|
@ -394,7 +395,7 @@ export default function SubdomainEditor() {
|
|||
<DashboardMain fullWidth>
|
||||
{page.isLoading ? (
|
||||
<div className="flex justify-center items-center min-h-[300px]">
|
||||
Loading...
|
||||
{t("Loading")}...
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
|
|
@ -407,7 +408,7 @@ export default function SubdomainEditor() {
|
|||
subdomain: "xlog",
|
||||
})}/xfm`}
|
||||
>
|
||||
Tip: xLog Flavored Markdown
|
||||
{t("Tip: xLog Flavored Markdown")}
|
||||
</UniLink>
|
||||
</div>
|
||||
<div className="flex items-center space-x-3">
|
||||
|
|
@ -421,7 +422,7 @@ export default function SubdomainEditor() {
|
|||
: "text-green-600",
|
||||
)}
|
||||
>
|
||||
{visibility?.toLowerCase()}
|
||||
{t(visibility as string)}
|
||||
</span>
|
||||
<Button
|
||||
isAutoWidth
|
||||
|
|
@ -434,7 +435,7 @@ export default function SubdomainEditor() {
|
|||
)
|
||||
}}
|
||||
>
|
||||
Preview
|
||||
{t("Preview")}
|
||||
</Button>
|
||||
<PublishButton
|
||||
save={savePage}
|
||||
|
|
@ -493,7 +494,7 @@ export default function SubdomainEditor() {
|
|||
<div>
|
||||
<Input
|
||||
type="datetime-local"
|
||||
label="Publish at"
|
||||
label={t("Publish at") || ""}
|
||||
isBlock
|
||||
name="publishAt"
|
||||
id="publishAt"
|
||||
|
|
@ -507,9 +508,11 @@ export default function SubdomainEditor() {
|
|||
.toISOString()
|
||||
updateValue("publishedAt", value)
|
||||
}}
|
||||
help={`This ${
|
||||
isPost ? "post" : "page"
|
||||
} will be accessible from this time`}
|
||||
help={t(
|
||||
`This ${
|
||||
isPost ? "post" : "page"
|
||||
} will be accessible from this time`,
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
|
|
@ -517,7 +520,7 @@ export default function SubdomainEditor() {
|
|||
name="slug"
|
||||
value={values.slug}
|
||||
placeholder={defaultSlug}
|
||||
label={`${isPost ? "Post" : "Page"} slug`}
|
||||
label={t(`${isPost ? "Post" : "Page"} slug`) || ""}
|
||||
id="slug"
|
||||
isBlock
|
||||
onChange={(e: ChangeEvent<HTMLInputElement>) =>
|
||||
|
|
@ -527,8 +530,11 @@ export default function SubdomainEditor() {
|
|||
<>
|
||||
{(values.slug || defaultSlug) && (
|
||||
<>
|
||||
This {isPost ? "post" : "page"} will be accessible
|
||||
at{" "}
|
||||
{t(
|
||||
`This ${
|
||||
isPost ? "post" : "page"
|
||||
} will be accessible at`,
|
||||
)}{" "}
|
||||
<UniLink
|
||||
href={`${getSiteLink({
|
||||
subdomain,
|
||||
|
|
@ -553,18 +559,20 @@ export default function SubdomainEditor() {
|
|||
<Input
|
||||
name="tags"
|
||||
value={values.tags}
|
||||
label="Tags"
|
||||
label={t("Tags") || ""}
|
||||
id="tags"
|
||||
isBlock
|
||||
onChange={(e: ChangeEvent<HTMLInputElement>) =>
|
||||
updateValue("tags", e.target.value)
|
||||
}
|
||||
help='Separate multiple tags with English commas ","'
|
||||
help={
|
||||
t("Separate multiple tags with English commas") + ` ","`
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Input
|
||||
label="Excerpt"
|
||||
label={t("Excerpt") || ""}
|
||||
isBlock
|
||||
name="excerpt"
|
||||
id="excerpt"
|
||||
|
|
@ -574,7 +582,7 @@ export default function SubdomainEditor() {
|
|||
onChange={(e: ChangeEvent<HTMLTextAreaElement>) => {
|
||||
updateValue("excerpt", e.target.value)
|
||||
}}
|
||||
help="Leave it blank to use auto-generated excerpt"
|
||||
help={t("Leave it blank to use auto-generated excerpt")}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { getSiteLink } from "~/lib/helpers"
|
|||
import type { ReactElement } from "react"
|
||||
import { useGetSite, useGetStat } from "~/queries/site"
|
||||
import { useDate } from "~/hooks/useDate"
|
||||
import { useTranslation } from "next-i18next"
|
||||
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"
|
||||
|
|
@ -81,9 +81,14 @@ export default function SubdomainIndex() {
|
|||
</div>
|
||||
))}
|
||||
</div>
|
||||
<p>Hello there,</p>
|
||||
<p>Welcome to use {APP_NAME}!</p>
|
||||
<p>Here{`'`}re some useful links to get started:</p>
|
||||
<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`}>
|
||||
|
|
@ -115,7 +120,14 @@ export default function SubdomainIndex() {
|
|||
via RSS Reader
|
||||
</li>
|
||||
</ul>
|
||||
<p>Join the community to meet friends or build {APP_NAME} together:</p>
|
||||
<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}>
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ export default function SettingsCSSPage() {
|
|||
|
||||
const updateSite = useUpdateSite()
|
||||
const site = useGetSite(subdomain)
|
||||
const { t } = useTranslation("dashboard")
|
||||
|
||||
const [css, setCss] = useState("")
|
||||
const handleSubmit = (e: any) => {
|
||||
|
|
@ -66,38 +67,39 @@ export default function SettingsCSSPage() {
|
|||
<form onSubmit={handleSubmit}>
|
||||
<div className="">
|
||||
<div className="p-5 text-zinc-500 bg-zinc-50 mb-5 rounded-lg text-xs space-y-2">
|
||||
<p className="text-zinc-800 text-sm font-bold">Scope</p>
|
||||
<p className="text-zinc-800 text-sm font-bold">{t("Tips")}:</p>
|
||||
<p>
|
||||
These styles will be applied to your entire blog, including this
|
||||
dashboard.
|
||||
{t(
|
||||
"Scope: These styles will be applied to your entire blog, including this dashboard.",
|
||||
)}
|
||||
</p>
|
||||
<p>
|
||||
Support <code>ipfs://</code>
|
||||
</p>
|
||||
<p className="text-zinc-800 text-sm font-bold">
|
||||
Tips: you can override the built-in CSS variables
|
||||
{t("Support")} <code>ipfs://</code>
|
||||
</p>
|
||||
<p>
|
||||
{t("CSS variables: xLog provides some built-in CSS variables")}
|
||||
</p>
|
||||
<p className="pl-2">
|
||||
<span className="bg-zinc-200 rounded-lg px-2">
|
||||
--theme-color: #4f46e5;
|
||||
</span>
|
||||
</p>
|
||||
<p>
|
||||
<p className="pl-2">
|
||||
<span className="bg-zinc-200 rounded-lg px-2">
|
||||
--theme-color-emphasis: #4338ca;
|
||||
</span>
|
||||
</p>
|
||||
<p>
|
||||
<p className="pl-2">
|
||||
<span className="bg-zinc-200 rounded-lg px-2">
|
||||
--header-height: auto;
|
||||
</span>
|
||||
</p>
|
||||
<p>
|
||||
<p className="pl-2">
|
||||
<span className="bg-zinc-200 rounded-lg px-2">
|
||||
--banner-bg-color: #000;
|
||||
</span>
|
||||
</p>
|
||||
<p>
|
||||
<p className="pl-2">
|
||||
<span className="bg-zinc-200 rounded-lg px-2">
|
||||
--font-fans: ui-sans-serif, system-ui, -apple-system,
|
||||
BlinkMacSystemFont, "Segoe UI", Roboto,
|
||||
|
|
@ -108,7 +110,7 @@ export default function SettingsCSSPage() {
|
|||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<FieldLabel label="Custom CSS" />
|
||||
<FieldLabel label={t("Custom CSS")} />
|
||||
<Editor
|
||||
className="w-full h-96 border outline-none py-3 rounded-lg inline-flex items-center overflow-hidden"
|
||||
defaultLanguage="css"
|
||||
|
|
@ -121,7 +123,7 @@ export default function SettingsCSSPage() {
|
|||
</div>
|
||||
<div className="mt-5">
|
||||
<Button type="submit" isLoading={updateSite.isLoading}>
|
||||
Save
|
||||
{t("Save")}
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ export default function SettingsDomainsPage() {
|
|||
const updateSite = useUpdateSite()
|
||||
const site = useGetSite(subdomain)
|
||||
const userRole = useUserRole(subdomain)
|
||||
const { t } = useTranslation("dashboard")
|
||||
|
||||
const isEmailAccount = useAccountState(
|
||||
(s) => s.computed.account?.type === "email",
|
||||
|
|
@ -98,7 +99,7 @@ export default function SettingsDomainsPage() {
|
|||
<div>
|
||||
<Input
|
||||
id="subdomain"
|
||||
label={`${APP_NAME} subdomain`}
|
||||
label={`xLog ${t("subdomain")}`}
|
||||
addon={`.${OUR_DOMAIN}`}
|
||||
className="w-28"
|
||||
{...form.register("subdomain")}
|
||||
|
|
@ -137,15 +138,17 @@ export default function SettingsDomainsPage() {
|
|||
<div className="mt-5">
|
||||
<Input
|
||||
id="custom_domain"
|
||||
label="Custom Domain"
|
||||
label={t("Custom Domain") || ""}
|
||||
className="w-64"
|
||||
{...form.register("custom_domain")}
|
||||
/>
|
||||
{customDomain && (
|
||||
<div className="mt-2 text-xs">
|
||||
<p className="mb-2">
|
||||
Set the following record on your DNS provider to active your
|
||||
custom domain:
|
||||
{t(
|
||||
"Set the following record on your DNS provider to active your custom domain",
|
||||
)}
|
||||
:
|
||||
</p>
|
||||
<table className="">
|
||||
<tbody>
|
||||
|
|
@ -175,7 +178,7 @@ export default function SettingsDomainsPage() {
|
|||
</div>
|
||||
<div className="mt-5">
|
||||
<Button type="submit" isLoading={updateSite.isLoading}>
|
||||
Save
|
||||
{t("Save")}
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import { UniLink } from "~/components/ui/UniLink"
|
|||
import { ImageUploader } from "~/components/ui/ImageUploader"
|
||||
import { toIPFS } from "~/lib/ipfs-parser"
|
||||
import type { ReactElement } from "react"
|
||||
import { useTranslation } from "next-i18next"
|
||||
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"
|
||||
|
|
@ -35,6 +35,7 @@ export default function SiteSettingsGeneralPage() {
|
|||
|
||||
const updateSite = useUpdateSite()
|
||||
const site = useGetSite(subdomain)
|
||||
const { t } = useTranslation("dashboard")
|
||||
|
||||
const form = useForm({
|
||||
defaultValues: {
|
||||
|
|
@ -107,7 +108,7 @@ export default function SiteSettingsGeneralPage() {
|
|||
<form onSubmit={handleSubmit}>
|
||||
<div className="mt-5">
|
||||
<label htmlFor="icon" className="form-label">
|
||||
Icon
|
||||
{t("Icon")}
|
||||
</label>
|
||||
<Controller
|
||||
name="icon"
|
||||
|
|
@ -130,7 +131,7 @@ export default function SiteSettingsGeneralPage() {
|
|||
</div>
|
||||
<div className="mt-5">
|
||||
<label htmlFor="icon" className="form-label">
|
||||
Banner
|
||||
{t("Banner")}
|
||||
</label>
|
||||
<Controller
|
||||
name="banner"
|
||||
|
|
@ -156,15 +157,20 @@ export default function SiteSettingsGeneralPage() {
|
|||
)}
|
||||
/>
|
||||
<div className="text-xs text-gray-400 mt-1">
|
||||
Supports both pictures and videos.
|
||||
{t("Supports both pictures and videos.")}
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-5">
|
||||
<Input required label="Name" id="name" {...form.register("name")} />
|
||||
<Input
|
||||
required
|
||||
label={t("Name") || ""}
|
||||
id="name"
|
||||
{...form.register("name")}
|
||||
/>
|
||||
</div>
|
||||
<div className="mt-5">
|
||||
<label htmlFor="description" className="form-label">
|
||||
Description
|
||||
{t("Description")}
|
||||
</label>
|
||||
<Input
|
||||
multiline
|
||||
|
|
@ -182,15 +188,17 @@ export default function SiteSettingsGeneralPage() {
|
|||
label="Google Analytics"
|
||||
help={
|
||||
<p>
|
||||
Integrate Google Analytics into your site. You can follow the
|
||||
instructions{" "}
|
||||
<UniLink
|
||||
className="underline"
|
||||
href="https://support.google.com/analytics/answer/9539598"
|
||||
>
|
||||
here
|
||||
</UniLink>{" "}
|
||||
to find your Measurement ID.
|
||||
<Trans i18nKey="Integrate Google Analytics" ns="dashboard">
|
||||
Integrate Google Analytics into your site. You can follow the
|
||||
instructions{" "}
|
||||
<UniLink
|
||||
className="underline"
|
||||
href="https://support.google.com/analytics/answer/9539598"
|
||||
>
|
||||
here
|
||||
</UniLink>{" "}
|
||||
to find your Measurement ID.
|
||||
</Trans>
|
||||
</p>
|
||||
}
|
||||
/>
|
||||
|
|
@ -201,7 +209,7 @@ export default function SiteSettingsGeneralPage() {
|
|||
isLoading={updateSite.isLoading}
|
||||
isDisabled={iconUploading || bannerUploading}
|
||||
>
|
||||
Save
|
||||
{t("Save")}
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ const SortableNavigationItem: React.FC<{
|
|||
updateItem: UpdateItem
|
||||
removeItem: RemoveItem
|
||||
}> = ({ item, updateItem, removeItem }) => {
|
||||
const { t } = useTranslation("dashboard")
|
||||
return (
|
||||
<div className="flex space-x-5 border-b p-5 bg-zinc-50 last:border-0">
|
||||
<div>
|
||||
|
|
@ -53,7 +54,7 @@ const SortableNavigationItem: React.FC<{
|
|||
</button>
|
||||
</div>
|
||||
<Input
|
||||
label="Label"
|
||||
label={t("Label") || ""}
|
||||
required
|
||||
id={`${item.id}-label`}
|
||||
value={item.label}
|
||||
|
|
@ -62,7 +63,7 @@ const SortableNavigationItem: React.FC<{
|
|||
}
|
||||
/>
|
||||
<Input
|
||||
label="URL"
|
||||
label={t("URL") || ""}
|
||||
required
|
||||
id={`${item.id}-url`}
|
||||
type="text"
|
||||
|
|
@ -75,7 +76,7 @@ const SortableNavigationItem: React.FC<{
|
|||
/>
|
||||
<div className="flex items-end relative -top-[5px]">
|
||||
<Button onClick={() => removeItem(item.id)} variantColor="red">
|
||||
Remove
|
||||
{t("Remove")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -89,6 +90,7 @@ export default function SiteSettingsNavigationPage() {
|
|||
|
||||
const updateSite = useUpdateSite()
|
||||
const site = useGetSite(subdomain)
|
||||
const { t } = useTranslation("dashboard")
|
||||
|
||||
const [items, setItems] = useState<SiteNavigationItem[]>([])
|
||||
|
||||
|
|
@ -147,23 +149,26 @@ export default function SiteSettingsNavigationPage() {
|
|||
return (
|
||||
<SettingsLayout title="Site Settings" type="site">
|
||||
<div className="p-5 text-zinc-500 bg-zinc-50 mb-5 rounded-lg text-xs space-y-2">
|
||||
<p className="text-zinc-800 text-sm font-bold">Tips: built-in pages</p>
|
||||
<p className="text-zinc-800 text-sm font-bold">{t("Tips")}:</p>
|
||||
<p>
|
||||
<span className="text-zinc-800">
|
||||
Home page (use your own Label to replace the default Label):
|
||||
</span>{" "}
|
||||
<span className="text-zinc-800 font-medium">
|
||||
{t("xLog provides some out-of-the-box built-in pages")}:
|
||||
</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="text-zinc-800">- {t("Home page")}:</span>{" "}
|
||||
<span className="bg-zinc-200 rounded-lg px-2">/</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="text-zinc-800">Archives page:</span>{" "}
|
||||
<span className="text-zinc-800">- {t("Archives page")}:</span>{" "}
|
||||
<span className="bg-zinc-200 rounded-lg px-2">/archives</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="text-zinc-900">Tag page:</span>{" "}
|
||||
<span className="text-zinc-900">- {t("Tag page")}:</span>{" "}
|
||||
<span className="bg-zinc-200 rounded-lg px-2">/tag/[tag]</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="text-zinc-900">NFT Showcase page:</span>{" "}
|
||||
<span className="text-zinc-900">- {t("NFT Showcase page")}:</span>{" "}
|
||||
<span className="bg-zinc-200 rounded-lg px-2">/nft</span>
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -198,10 +203,10 @@ export default function SiteSettingsNavigationPage() {
|
|||
isLoading={updateSite.isLoading}
|
||||
isDisabled={!itemsModified}
|
||||
>
|
||||
Save
|
||||
{t("Save")}
|
||||
</Button>
|
||||
<Button variant="secondary" onClick={newEmptyItem}>
|
||||
New Item
|
||||
{t("New Item")}
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -43,11 +43,14 @@ const SortableNavigationItem: React.FC<{
|
|||
isLoading: boolean
|
||||
disabled?: boolean
|
||||
}> = ({ item, removeItem, isLoading, disabled }) => {
|
||||
const { t } = useTranslation("dashboard")
|
||||
return (
|
||||
<div className="flex space-x-5 border-b p-5 bg-zinc-50 last:border-0 items-center">
|
||||
<div className="text-sm space-y-4">
|
||||
<div>Address: {item}</div>
|
||||
<div>Character:</div>
|
||||
<div>
|
||||
{t("Address")}: {item}
|
||||
</div>
|
||||
<div>{t("Character")}:</div>
|
||||
<CharacterCard
|
||||
address={item}
|
||||
open={true}
|
||||
|
|
@ -62,7 +65,7 @@ const SortableNavigationItem: React.FC<{
|
|||
isLoading={isLoading}
|
||||
isDisabled={disabled}
|
||||
>
|
||||
Remove
|
||||
{t("Remove")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -85,6 +88,7 @@ export default function SettingsOperatorPage() {
|
|||
)
|
||||
const upgradeAccountModal = useUpgradeAccountModal()
|
||||
const userRole = useUserRole(subdomain)
|
||||
const { t } = useTranslation("dashboard")
|
||||
|
||||
const [items, setItems] = useState<string[]>([])
|
||||
|
||||
|
|
@ -144,19 +148,21 @@ export default function SettingsOperatorPage() {
|
|||
|
||||
<div className="relative bg-white rounded-lg max-w-md w-full mx-auto">
|
||||
<Dialog.Title className="px-5 h-12 flex items-center border-b">
|
||||
New operator
|
||||
{t("New operator")}
|
||||
</Dialog.Title>
|
||||
|
||||
<div className="p-5">
|
||||
<Input
|
||||
className="w-full"
|
||||
label="Operator Address"
|
||||
label={t("Operator Address") || ""}
|
||||
required
|
||||
onChange={(e) => {
|
||||
setAddress(e.target.value)
|
||||
}}
|
||||
/>
|
||||
<div className="form-label mt-5">Operator Character Check</div>
|
||||
<div className="form-label mt-5">
|
||||
{t("Operator Character Check")}
|
||||
</div>
|
||||
<div>
|
||||
<CharacterCard
|
||||
address={address}
|
||||
|
|
@ -173,14 +179,14 @@ export default function SettingsOperatorPage() {
|
|||
isDisabled={!address}
|
||||
onClick={addItem}
|
||||
>
|
||||
Save
|
||||
{t("Save")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
<div className="p-5 text-zinc-500 bg-orange-50 mb-5 rounded-lg text-sm space-y-2">
|
||||
<p className="text-zinc-800 text-sm font-bold">⚠️ Warning:</p>
|
||||
<p className="text-zinc-800 text-sm font-bold">⚠️ {t("Warning")}:</p>
|
||||
<p>
|
||||
<span className="text-zinc-800">
|
||||
{isEmailAccount && (
|
||||
|
|
@ -214,9 +220,9 @@ export default function SettingsOperatorPage() {
|
|||
)}
|
||||
{!isEmailAccount && userRole.data !== "operator" && (
|
||||
<span>
|
||||
Operators have permissions to enter your dashboard, change your
|
||||
settings(excluding xLog subdomain) and post contents on your
|
||||
site.
|
||||
{t(
|
||||
"Operators have permissions to enter your dashboard, change your settings(excluding xLog subdomain) and post, modify, delete contents on your site.",
|
||||
)}
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
|
|
@ -257,7 +263,7 @@ export default function SettingsOperatorPage() {
|
|||
onClick={newEmptyItem}
|
||||
isDisabled={isEmailAccount || userRole.data === "operator"}
|
||||
>
|
||||
Add
|
||||
{t("Add")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import { useGetSite, useUpdateSite } from "~/queries/site"
|
|||
import type { ReactElement } from "react"
|
||||
import { UniLink } from "~/components/ui/UniLink"
|
||||
import { Platform } from "~/components/site/Platform"
|
||||
import { useTranslation } from "next-i18next"
|
||||
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"
|
||||
|
|
@ -43,6 +43,7 @@ const SortableNavigationItem: React.FC<{
|
|||
updateItem: UpdateItem
|
||||
removeItem: RemoveItem
|
||||
}> = ({ item, updateItem, removeItem }) => {
|
||||
const { t } = useTranslation("dashboard")
|
||||
return (
|
||||
<div className="flex space-x-5 border-b p-5 bg-zinc-50 last:border-0">
|
||||
<div>
|
||||
|
|
@ -59,7 +60,7 @@ const SortableNavigationItem: React.FC<{
|
|||
</button>
|
||||
</div>
|
||||
<Input
|
||||
label="Platform"
|
||||
label={t("Platform") || ""}
|
||||
required
|
||||
id={`${item.id}-platform`}
|
||||
value={item.platform}
|
||||
|
|
@ -82,7 +83,7 @@ const SortableNavigationItem: React.FC<{
|
|||
</div>
|
||||
<div className="flex items-end relative -top-[5px]">
|
||||
<Button onClick={() => removeItem(item.id)} variantColor="red">
|
||||
Remove
|
||||
{t("Remove")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -96,6 +97,7 @@ export default function SiteSettingsNavigationPage() {
|
|||
|
||||
const updateSite = useUpdateSite()
|
||||
const site = useGetSite(subdomain)
|
||||
const { t } = useTranslation("dashboard")
|
||||
|
||||
const [items, setItems] = useState<Item[]>([])
|
||||
|
||||
|
|
@ -162,35 +164,36 @@ export default function SiteSettingsNavigationPage() {
|
|||
return (
|
||||
<SettingsLayout title="Site Settings" type="site">
|
||||
<div className="p-5 text-zinc-500 bg-zinc-50 mb-5 rounded-lg text-xs space-y-2">
|
||||
<p className="text-zinc-800 text-sm font-bold">Tips:</p>
|
||||
<p className="text-zinc-800 text-sm font-bold">{t("Tips")}:</p>
|
||||
<p>
|
||||
<span className="text-zinc-800">{t("social tips.p1")}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="text-zinc-800">
|
||||
These social platforms will be displayed in the bottom right hand
|
||||
corner of your xLog.
|
||||
<Trans ns="dashboard" i18nKey="social tips.p2">
|
||||
We support{" "}
|
||||
<UniLink
|
||||
href="https://github.com/Crossbell-Box/xLog/blob/dev/src/components/site/Platform.tsx#L7"
|
||||
className="underline"
|
||||
>
|
||||
these platforms
|
||||
</UniLink>{" "}
|
||||
with automatic display of logos and links, other platforms will
|
||||
display a default logo. Please feel free to submit an issue or pr
|
||||
to us to support more platforms.
|
||||
</Trans>
|
||||
</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="text-zinc-800">
|
||||
We support{" "}
|
||||
<UniLink
|
||||
href="https://github.com/Crossbell-Box/xLog/blob/dev/src/components/site/Platform.tsx#L7"
|
||||
className="underline"
|
||||
>
|
||||
these platforms
|
||||
</UniLink>{" "}
|
||||
with automatic display of logos and links, other platforms will
|
||||
display a default logo. Please feel free to submit an issue or pr to
|
||||
us to support more platforms.
|
||||
</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="text-zinc-800">
|
||||
You can also connect to Twitter, Telegram Channel, Medium, Substack
|
||||
and more and automatically sync content on{" "}
|
||||
<UniLink href="https://xsync.app/" className="underline">
|
||||
xSync
|
||||
</UniLink>
|
||||
. When you have set up the sync there, it will also show here.
|
||||
<Trans ns="dashboard" i18nKey="social tips.p3">
|
||||
You can also connect to Twitter, Telegram Channel, Medium,
|
||||
Substack and more and automatically sync content on{" "}
|
||||
<UniLink href="https://xsync.app/" className="underline">
|
||||
xSync
|
||||
</UniLink>
|
||||
. When you have set up the sync there, it will also show here.
|
||||
</Trans>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -225,10 +228,10 @@ export default function SiteSettingsNavigationPage() {
|
|||
isLoading={updateSite.isLoading}
|
||||
isDisabled={!itemsModified}
|
||||
>
|
||||
Save
|
||||
{t("Save")}
|
||||
</Button>
|
||||
<Button variant="secondary" onClick={newEmptyItem}>
|
||||
New Item
|
||||
{t("New Item")}
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -315,7 +315,11 @@ export default function Home() {
|
|||
<Element name="Showcase">
|
||||
<div className="pt-28 text-4xl font-bold">{t("Showcase")}</div>
|
||||
<div className="my-10 text-zinc-700">
|
||||
<p className="text-lg">{t("discover awesome")}</p>
|
||||
<p className="text-lg">
|
||||
{t(
|
||||
"Discover these awesome teams and geeks on xLog (sorted by update time)",
|
||||
)}
|
||||
</p>
|
||||
<Button
|
||||
size="xl"
|
||||
className="mt-5"
|
||||
|
|
@ -394,7 +398,11 @@ export default function Home() {
|
|||
<Element name="Integration">
|
||||
<div className="pt-28 text-4xl font-bold">{t("Integration")}</div>
|
||||
<div className="my-10 text-zinc-700">
|
||||
<p className="text-xl">{t("Integration description")}</p>
|
||||
<p className="text-xl">
|
||||
{t(
|
||||
"xLog's open design allows it to integrate with many other open protocols and applications without friction.",
|
||||
)}
|
||||
</p>
|
||||
<ul className="mt-14 grid grid-cols-3 sm:grid-cols-5 gap-y-14 gap-x-2">
|
||||
{integrations.map((item, index) => (
|
||||
<li
|
||||
|
|
|
|||
Loading…
Reference in New Issue