feat: crossbell renovation - settings general page
This commit is contained in:
parent
877cf5be96
commit
ff53629b8e
|
|
@ -71,7 +71,7 @@ export async function createOrUpdatePage(
|
|||
source: 'Crossbell Note',
|
||||
identity: input.siteId,
|
||||
platform: 'Crossbell',
|
||||
action: input.pageId ? 'add' : 'update',
|
||||
action: input.pageId ? 'update' : 'add',
|
||||
}, {
|
||||
...(input.pageId && { id: input.pageId }),
|
||||
...(input.title && { title: input.title }),
|
||||
|
|
@ -155,7 +155,6 @@ export async function getPagesBySite(
|
|||
platform: 'Crossbell',
|
||||
limit: input.take || 100,
|
||||
});
|
||||
console.log(pages?.list.length, visibility)
|
||||
|
||||
if (pages?.list) {
|
||||
switch (visibility) {
|
||||
|
|
@ -169,6 +168,7 @@ export async function getPagesBySite(
|
|||
pages.list = pages.list.filter(page => +new Date(page.date_published) > +new Date() && page.date_published !== new Date('9999-01-01').toISOString())
|
||||
break
|
||||
}
|
||||
pages.list = pages.list.filter(page => page.tags?.includes(input.type))
|
||||
pages.total = pages.list.length
|
||||
|
||||
pages.list = await Promise.all(pages?.list.map(async (page) => {
|
||||
|
|
|
|||
|
|
@ -58,24 +58,20 @@ export const getUserSites = async (address: string) => {
|
|||
}
|
||||
|
||||
export const getSite = async (input: string) => {
|
||||
const site = isUUID(input)
|
||||
? await prismaRead.site.findUnique({
|
||||
where: {
|
||||
id: input,
|
||||
},
|
||||
})
|
||||
: await prismaRead.site.findUnique({
|
||||
where: {
|
||||
subdomain: input,
|
||||
},
|
||||
})
|
||||
if (unidata) {
|
||||
const profiles = await unidata.profiles.get({
|
||||
source: 'Crossbell Profile',
|
||||
identity: input,
|
||||
platform: 'Crossbell',
|
||||
});
|
||||
|
||||
if (!site || site.deletedAt) {
|
||||
throw new Error(`Site not found`)
|
||||
}
|
||||
const site = profiles.list?.sort((a, b) => +new Date(b.date_updated || 0) - +new Date(a.date_updated || 0))?.[0]
|
||||
|
||||
return site as Omit<Site, "navigation"> & {
|
||||
navigation: SiteNavigationItem[] | null
|
||||
if (!site) return null
|
||||
|
||||
return site
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -98,45 +94,31 @@ export const getSubscription = async (data: {
|
|||
}
|
||||
|
||||
export async function updateSite(
|
||||
gate: Gate,
|
||||
payload: {
|
||||
site: string
|
||||
name?: string
|
||||
description?: string
|
||||
icon?: string | null
|
||||
subdomain?: string
|
||||
navigation?: SiteNavigationItem[]
|
||||
navigation?: SiteNavigationItem[] // TODO
|
||||
},
|
||||
) {
|
||||
const site = await getSite(payload.site)
|
||||
|
||||
if (!gate.allows({ type: "can-update-site", site })) {
|
||||
throw gate.permissionError()
|
||||
}
|
||||
|
||||
if (payload.subdomain) {
|
||||
await checkSubdomain({
|
||||
subdomain: payload.subdomain,
|
||||
updatingSiteId: site.id,
|
||||
if (unidata) {
|
||||
return await unidata.profiles.set({
|
||||
source: 'Crossbell Profile',
|
||||
identity: payload.site,
|
||||
platform: 'Crossbell',
|
||||
}, {
|
||||
...(payload.name && { name: payload.name }),
|
||||
...(payload.description && { bio: payload.description }),
|
||||
...(payload.icon && { avatars: [payload.icon] }),
|
||||
...(payload.subdomain && { username: payload.subdomain }),
|
||||
})
|
||||
}
|
||||
|
||||
const updated = await prismaPrimary.site.update({
|
||||
where: {
|
||||
id: site.id,
|
||||
},
|
||||
data: {
|
||||
name: payload.name,
|
||||
subdomain: payload.subdomain,
|
||||
description: payload.description,
|
||||
icon: payload.icon,
|
||||
navigation: payload.navigation,
|
||||
},
|
||||
})
|
||||
|
||||
return {
|
||||
site: updated,
|
||||
subdomainUpdated: updated.subdomain !== site.subdomain,
|
||||
} else {
|
||||
return {
|
||||
code: 1,
|
||||
message: 'Unidata is not found',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -202,55 +184,55 @@ export async function subscribeToSite(
|
|||
}
|
||||
},
|
||||
) {
|
||||
const { newUser } = input
|
||||
if (newUser) {
|
||||
// Create the login token instead
|
||||
sendLoginEmail({
|
||||
email: newUser.email,
|
||||
url: newUser.url,
|
||||
toSubscribeSiteId: input.siteId,
|
||||
})
|
||||
return
|
||||
}
|
||||
// const { newUser } = input
|
||||
// if (newUser) {
|
||||
// // Create the login token instead
|
||||
// sendLoginEmail({
|
||||
// email: newUser.email,
|
||||
// url: newUser.url,
|
||||
// toSubscribeSiteId: input.siteId,
|
||||
// })
|
||||
// return
|
||||
// }
|
||||
|
||||
const user = gate.getUser(true)
|
||||
// const user = gate.getUser(true)
|
||||
|
||||
const site = await getSite(input.siteId)
|
||||
const subscription = await getSubscription({
|
||||
userId: user.id,
|
||||
siteId: site.id,
|
||||
})
|
||||
if (!subscription) {
|
||||
await prismaPrimary.membership.create({
|
||||
data: {
|
||||
role: MembershipRole.SUBSCRIBER,
|
||||
user: {
|
||||
connect: {
|
||||
id: user.id,
|
||||
},
|
||||
},
|
||||
site: {
|
||||
connect: {
|
||||
id: site.id,
|
||||
},
|
||||
},
|
||||
config: {
|
||||
email: input.email,
|
||||
},
|
||||
},
|
||||
})
|
||||
} else {
|
||||
await prismaPrimary.membership.update({
|
||||
where: {
|
||||
id: subscription.id,
|
||||
},
|
||||
data: {
|
||||
config: {
|
||||
email: input.email,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
// const site = await getSite(input.siteId)
|
||||
// const subscription = await getSubscription({
|
||||
// userId: user.id,
|
||||
// siteId: site.id,
|
||||
// })
|
||||
// if (!subscription) {
|
||||
// await prismaPrimary.membership.create({
|
||||
// data: {
|
||||
// role: MembershipRole.SUBSCRIBER,
|
||||
// user: {
|
||||
// connect: {
|
||||
// id: user.id,
|
||||
// },
|
||||
// },
|
||||
// site: {
|
||||
// connect: {
|
||||
// id: site.id,
|
||||
// },
|
||||
// },
|
||||
// config: {
|
||||
// email: input.email,
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
// } else {
|
||||
// await prismaPrimary.membership.update({
|
||||
// where: {
|
||||
// id: subscription.id,
|
||||
// },
|
||||
// data: {
|
||||
// config: {
|
||||
// email: input.email,
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
// }
|
||||
}
|
||||
|
||||
export async function unsubscribeFromSite(
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ export default function SubdomainEditor() {
|
|||
|
||||
setValues({
|
||||
title: page.title || '',
|
||||
publishedAt: page.date_published,
|
||||
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 || "",
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,26 +1,30 @@
|
|||
import { Button } from "~/components/ui/Button"
|
||||
import { Input } from "~/components/ui/Input"
|
||||
import { AvatarForm } from "~/components/dashboard/AvatarForm"
|
||||
import { useEffect } from "react"
|
||||
import { useEffect, useState } from "react"
|
||||
import toast from "react-hot-toast"
|
||||
import { SettingsLayout } from "~/components/dashboard/SettingsLayout"
|
||||
import { useRouter } from "next/router"
|
||||
import { DashboardLayout } from "~/components/dashboard/DashboardLayout"
|
||||
import { trpc } from "~/lib/trpc"
|
||||
import { useForm } from "react-hook-form"
|
||||
import { getSite, updateSite } from "~/models/site.model"
|
||||
import { Profile } from "unidata.js"
|
||||
|
||||
export default function SiteSettingsGeneralPage() {
|
||||
const router = useRouter()
|
||||
|
||||
const subdomain = router.query.subdomain as string
|
||||
|
||||
const siteResult = trpc.useQuery(["site", { site: subdomain }], {
|
||||
enabled: !!subdomain,
|
||||
refetchOnWindowFocus: false,
|
||||
refetchOnReconnect: false,
|
||||
})
|
||||
const site = siteResult.data
|
||||
const updateSite = trpc.useMutation("site.updateSite")
|
||||
let [site, setSite] = useState<Profile | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
if (subdomain) {
|
||||
getSite(subdomain).then((site) => {
|
||||
setSite(site)
|
||||
})
|
||||
}
|
||||
}, [subdomain])
|
||||
|
||||
const form = useForm({
|
||||
defaultValues: {
|
||||
|
|
@ -29,28 +33,30 @@ export default function SiteSettingsGeneralPage() {
|
|||
},
|
||||
})
|
||||
|
||||
let [loading, setLoading] = useState<boolean>(false)
|
||||
const handleSubmit = form.handleSubmit((values) => {
|
||||
updateSite.mutate({
|
||||
setLoading(true)
|
||||
updateSite({
|
||||
site: subdomain,
|
||||
name: values.name,
|
||||
description: values.description,
|
||||
}).then((result) => {
|
||||
if (result.code === 0) {
|
||||
toast.success("Site updated")
|
||||
} else {
|
||||
toast.error("Failed to update site" + ": " + result.message)
|
||||
}
|
||||
setLoading(false)
|
||||
})
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
if (site) {
|
||||
form.setValue("name", site.name)
|
||||
form.setValue("description", site.description || "")
|
||||
form.setValue("name", site.name || "")
|
||||
form.setValue("description", site.bio || "")
|
||||
}
|
||||
}, [site, form])
|
||||
|
||||
useEffect(() => {
|
||||
if (updateSite.isSuccess && updateSite.data) {
|
||||
toast.success("Site updated")
|
||||
updateSite.reset()
|
||||
}
|
||||
}, [updateSite])
|
||||
|
||||
return (
|
||||
<DashboardLayout title="Site Settings">
|
||||
<SettingsLayout title="Site Settings" type="site">
|
||||
|
|
@ -58,9 +64,9 @@ export default function SiteSettingsGeneralPage() {
|
|||
<div>
|
||||
<label className="form-label">Icon</label>
|
||||
<AvatarForm
|
||||
site={site.id}
|
||||
name={site.name}
|
||||
filename={site.icon || undefined}
|
||||
site={site.username}
|
||||
name={site.name || site.username || ""}
|
||||
filename={site.avatars?.[0] || undefined}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
|
@ -80,7 +86,7 @@ export default function SiteSettingsGeneralPage() {
|
|||
/>
|
||||
</div>
|
||||
<div className="mt-5">
|
||||
<Button type="submit" isLoading={updateSite.isLoading}>
|
||||
<Button type="submit" isLoading={loading}>
|
||||
Save
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in New Issue