mirror of
https://github.com/penxio/penx.git
synced 2026-04-19 03:03:06 -04:00
90 lines
2.9 KiB
TypeScript
90 lines
2.9 KiB
TypeScript
'use client'
|
|
|
|
import { useEffect, useState } from 'react'
|
|
import TextareaAutosize from 'react-textarea-autosize'
|
|
import { updatePost } from '@/lib/hooks/usePost'
|
|
import { usePostSaving } from '@/lib/hooks/usePostSaving'
|
|
import { editorDefaultValue } from '@/lib/constants'
|
|
import { trpc } from '@/lib/trpc'
|
|
import { Post as PostType } from '@/server/db/schema'
|
|
import { useDebouncedCallback } from 'use-debounce'
|
|
import { PlateEditor } from '../editor/plate-editor'
|
|
import { ProfileAvatar } from '../Profile/ProfileAvatar'
|
|
import { CoverUpload } from './CoverUpload'
|
|
import { Tags } from './Tags'
|
|
|
|
export function Post({ post }: { post: PostType }) {
|
|
const [data, setData] = useState<PostType>(post)
|
|
const { mutateAsync } = trpc.post.update.useMutation()
|
|
const { setPostSaving } = usePostSaving()
|
|
|
|
const debounced = useDebouncedCallback(
|
|
async (value: PostType) => {
|
|
if (data.content !== post.content || data.title !== post.title) {
|
|
setPostSaving(true)
|
|
|
|
try {
|
|
await mutateAsync({
|
|
id: data.id,
|
|
title: value.title || '',
|
|
content: value.content,
|
|
description: value.description || '',
|
|
})
|
|
|
|
updatePost({
|
|
id: data.id,
|
|
title: value.title,
|
|
content: value.content,
|
|
description: value.description,
|
|
})
|
|
} catch (error) {}
|
|
setPostSaving(false)
|
|
}
|
|
},
|
|
// delay in ms
|
|
400,
|
|
)
|
|
|
|
useEffect(() => {
|
|
debounced(data)
|
|
}, [data, debounced])
|
|
|
|
return (
|
|
<div className="w-full h-full">
|
|
<div className="relative min-h-[500px] max-w-screen-lg p-12 px-8 mx-auto z-0">
|
|
<div className="mb-5 flex flex-col space-y-3 ">
|
|
{/* <CoverUpload post={data} /> */}
|
|
<TextareaAutosize
|
|
placeholder="Title"
|
|
defaultValue={data?.title || ''}
|
|
autoFocus
|
|
onChange={(e) => {
|
|
setData({ ...data, title: e.target.value })
|
|
}}
|
|
className="dark:placeholder-text-600 w-full resize-none border-none px-0 placeholder:text-foreground/40 focus:outline-none focus:ring-0 bg-transparent text-4xl font-bold"
|
|
/>
|
|
<TextareaAutosize
|
|
placeholder="Description"
|
|
defaultValue={post?.description || ''}
|
|
onChange={(e) => setData({ ...data, description: e.target.value })}
|
|
className="dark:placeholder-text-600 w-full resize-none border-none px-0 placeholder:text-stone-400 focus:outline-none focus:ring-0 bg-transparent"
|
|
/>
|
|
</div>
|
|
<div className="mb-4 space-y-2">
|
|
<ProfileAvatar showName />
|
|
{/* <Tags /> */}
|
|
</div>
|
|
|
|
<PlateEditor
|
|
className="w-full -mx-6"
|
|
showAddButton
|
|
value={post.content ? JSON.parse(post.content) : editorDefaultValue}
|
|
onChange={(v) => {
|
|
setData({ ...data, content: JSON.stringify(v) })
|
|
}}
|
|
/>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|