{post.title}
diff --git a/src/lib/types.ts b/src/lib/types.ts
index a1624086..1714c958 100644
--- a/src/lib/types.ts
+++ b/src/lib/types.ts
@@ -1,3 +1,5 @@
+import type { Note as UniNote } from "unidata.js"
+
export type Site = {
id: string
name: string
@@ -68,3 +70,12 @@ export type SiteNavigationItem = {
label: string
url: string
}
+
+export type Note = UniNote & {
+ slug?: string
+}
+
+export type Notes = {
+ total: number,
+ list: Note[],
+}
\ No newline at end of file
diff --git a/src/models/page.model.ts b/src/models/page.model.ts
index a8a69f68..2eee6380 100644
--- a/src/models/page.model.ts
+++ b/src/models/page.model.ts
@@ -9,13 +9,12 @@ import {
import { type Gate } from "~/lib/gate.server"
import { Rendered, renderPageContent } from "~/markdown"
import { notFound } from "~/lib/server-side-props"
-import { PageVisibilityEnum } from "~/lib/types"
+import { PageVisibilityEnum, Notes } from "~/lib/types"
import { isUUID } from "~/lib/uuid"
import { getSite } from "./site.model"
import { stripHTML } from "~/lib/utils"
import { sendEmailForNewPost } from "~/lib/mailgun.server"
import unidata from "~/lib/unidata"
-import { Notes } from "unidata.js"
const checkPageSlug = async ({
slug,
@@ -57,6 +56,7 @@ export async function createOrUpdatePage(
input: {
pageId?: string
siteId: string
+ slug?: string
title?: string
content?: string
published?: boolean
@@ -86,7 +86,7 @@ export async function createOrUpdatePage(
mime_type: 'text/markdown',
}
}),
- tags: [input.isPost ? "post" : "page"],
+ tags: [input.isPost ? "post" : "page", ...(input.slug ? ["slug:" + input.slug] : [])],
})
}
@@ -140,7 +140,7 @@ export async function getPagesBySite(
const visibility = input.visibility || PageVisibilityEnum.All
- let pages = await unidata.notes.get({
+ let pages: Notes | null = await unidata.notes.get({
source: 'Crossbell Note',
identity: input.site,
platform: 'Crossbell',
@@ -176,6 +176,7 @@ export async function getPagesBySite(
}
}
}
+ page.slug = page.tags?.find((tag) => tag.startsWith("slug:"))?.replace(/^slug:/, "") || page.id
return page
}))
}
@@ -197,7 +198,8 @@ export async function deletePage({ site, id }: { site: string, id: string }) {
export async function getPage(
input: {
/** page slug or id, `site` is needed when `page` is a slug */
- page: string
+ page?: string
+ pageId?: string
site?: string
render?: TRender
includeAuthors?: boolean
@@ -207,30 +209,32 @@ export async function getPage(
throw notFound(`site not found`)
}
- const isPageUUID = isUUID(input.page)
- if (!isPageUUID && !input.site) {
- throw new Error("input.site is required because input.page is a slug")
- }
-
- const pages = await unidata.notes.get({
+ const pages: Notes | null = await unidata.notes.get({
source: 'Crossbell Note',
identity: input.site,
platform: 'Crossbell',
- filter: {
- id: input.page,
- }
+ limit: 1000,
+ ...(input.pageId && {
+ filter: {
+ id: input.pageId,
+ }
+ })
})
- const page = pages?.list[0]
+ let page;
+ if (input.page) {
+ page = pages?.list.find((item) => {
+ item.slug = item.tags?.find((tag) => tag.startsWith("slug:"))?.replace(/^slug:/, "") || item.id
+ return item.slug === input.page
+ })
+ } else {
+ page = pages?.list[0]
+ }
if (!page) {
throw notFound(`page ${input.page} not found`)
}
- if (new Date(page.date_published) > new Date()) {
- throw notFound()
- }
-
if (pages?.list) {
pages.list = await Promise.all(pages?.list.map(async (page) => {
if (page.body?.content && page.body?.mime_type === 'text/markdown' && input.render) {
@@ -246,6 +250,7 @@ export async function getPage(
}
}
}
+ page.slug = page.tags?.find((tag) => tag.startsWith("slug:"))?.replace(/^slug:/, "") || page.id
return page
}))
}
diff --git a/src/pages/_site/[site]/[page].tsx b/src/pages/_site/[site]/[page].tsx
index 68cd67b1..d308be83 100644
--- a/src/pages/_site/[site]/[page].tsx
+++ b/src/pages/_site/[site]/[page].tsx
@@ -13,6 +13,7 @@ import { getUserSites, getSite } from "~/models/site.model"
import { getPage } from "~/models/page.model"
import { Profile, Note } from "unidata.js"
import { PageVisibilityEnum } from "~/lib/types"
+import { notFound } from "~/lib/server-side-props"
export const getServerSideProps: GetServerSideProps = serverSidePropsHandler(
async (ctx) => {
@@ -28,7 +29,11 @@ export const getServerSideProps: GetServerSideProps = serverSidePropsHandler(
includeAuthors: true,
}),
])
-
+
+ if (new Date(page.date_published) > new Date()) {
+ throw notFound()
+ }
+
return {
props: {
site,
diff --git a/src/pages/dashboard/[subdomain]/editor.tsx b/src/pages/dashboard/[subdomain]/editor.tsx
index c342f6aa..fb49555f 100644
--- a/src/pages/dashboard/[subdomain]/editor.tsx
+++ b/src/pages/dashboard/[subdomain]/editor.tsx
@@ -17,13 +17,12 @@ import { useUploadFile } from "~/hooks/useUploadFile"
import { inLocalTimezone } from "~/lib/date"
import { getSiteLink } from "~/lib/helpers"
import { getPageVisibility } from "~/lib/page-helpers"
-import { PageVisibilityEnum } from "~/lib/types"
+import { PageVisibilityEnum, Note } from "~/lib/types"
import { FieldLabel } from "~/components/ui/FieldLabel"
import { Button } from "~/components/ui/Button"
import { EmailPostModal } from "~/components/common/EmailPostModal"
import { useStore } from "~/lib/store"
-import type { Note } from "unidata.js"
-import { getPagesBySite, createOrUpdatePage } from "~/models/page.model"
+import { getPage, createOrUpdatePage } from "~/models/page.model"
const getInputDatetimeValue = (date: Date | string) => {
const str = dayjs(date).format()
@@ -40,15 +39,12 @@ export default function SubdomainEditor() {
let [page, setPage] = useState(undefined)
useEffect(() => {
- if (subdomain) {
- getPagesBySite({
- type: isPost ? "post" : "page",
+ if (subdomain && pageId) {
+ getPage({
site: subdomain!,
- take: 1000,
+ pageId: pageId,
render: false
- }).then((pages) => {
- console.log(pages, pageId)
- const page = (pages?.list || []).find((p) => p.id === pageId)
+ }).then((page) => {
setPage(page)
})
}
@@ -70,6 +66,7 @@ export default function SubdomainEditor() {
publishedAt: new Date().toISOString(),
published: false,
excerpt: "",
+ slug: "",
})
const [content, setContent] = useState("")
@@ -152,6 +149,7 @@ export default function SubdomainEditor() {
publishedAt: page.date_published === new Date('9999-01-01').toISOString() ? new Date().toISOString() : page.date_published,
published: page.date_published !== new Date('9999-01-01').toISOString(),
excerpt: page.summary?.content || "",
+ slug: page.slug!,
})
}, [page])
@@ -238,6 +236,37 @@ export default function SubdomainEditor() {
} will be accesisble from this time`}
/>
+
+ ) =>
+ updateValue("slug", e.target.value)
+ }
+ help={
+ <>
+ {values.slug && (
+ <>
+ This {isPost ? "post" : "page"} will be accessible at{" "}
+
+ {getSiteLink({ subdomain, noProtocol: true })}/
+ {values.slug}
+
+ >
+ )}
+ >
+ }
+ />
+