Files
penx/components/Post/Post.tsx
2024-12-17 11:50:29 +08:00

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>
)
}