2024-09-28 14:58:45 +08:00
|
|
|
'use client';
|
|
|
|
|
|
|
|
import { getRandomInt } from '@3rapp/utils';
|
2024-10-14 11:38:41 +08:00
|
|
|
import { zodResolver } from '@hookform/resolvers/zod';
|
2024-09-28 14:58:45 +08:00
|
|
|
import { Post } from '@prisma/client';
|
|
|
|
import { isNil } from 'lodash';
|
|
|
|
import { useRouter } from 'next/navigation';
|
|
|
|
import { useMemo } from 'react';
|
|
|
|
|
|
|
|
import { useForm } from 'react-hook-form';
|
2024-10-14 11:38:41 +08:00
|
|
|
import { DeepNonNullable } from 'utility-types';
|
2024-09-28 14:58:45 +08:00
|
|
|
|
|
|
|
import { createPostItem, updatePostItem } from '@/app/actions/post';
|
|
|
|
|
2024-10-14 11:38:41 +08:00
|
|
|
import { useToast } from '@/hooks/use-toast';
|
|
|
|
|
2024-09-28 14:58:45 +08:00
|
|
|
import { MarkdownEditorProps } from '../markdown/type';
|
|
|
|
import { useEditorModalContext } from '../modal/hooks';
|
|
|
|
|
2024-10-14 11:38:41 +08:00
|
|
|
import { generatePostFormValidator } from './form-validator';
|
2024-09-28 14:58:45 +08:00
|
|
|
import { PostActionFormProps, PostCreateData, PostFormData, PostUpdateData } from './types';
|
|
|
|
|
|
|
|
export function usePostActionForm(params: PostActionFormProps) {
|
|
|
|
const defaultValues = useMemo(() => {
|
|
|
|
if (params.type === 'create') {
|
|
|
|
return {
|
2024-10-14 11:38:41 +08:00
|
|
|
title: '',
|
|
|
|
body: '',
|
|
|
|
summary: '',
|
|
|
|
slug: '',
|
|
|
|
keywords: '',
|
|
|
|
description: '',
|
|
|
|
} as DeepNonNullable<PostCreateData>;
|
2024-09-28 14:58:45 +08:00
|
|
|
}
|
|
|
|
return {
|
|
|
|
title: params.post.title,
|
|
|
|
body: params.post.body,
|
|
|
|
summary: isNil(params.post.summary) ? '' : params.post.summary,
|
2024-10-14 11:38:41 +08:00
|
|
|
slug: isNil(params.post.slug) ? null : params.post.slug,
|
|
|
|
keywords: isNil(params.post.keywords) ? '' : params.post.keywords,
|
|
|
|
description: isNil(params.post.description) ? '' : params.post.description,
|
|
|
|
} as DeepNonNullable<PostUpdateData>;
|
2024-09-28 14:58:45 +08:00
|
|
|
}, [params.type]);
|
|
|
|
|
2024-10-14 11:38:41 +08:00
|
|
|
return useForm<DeepNonNullable<PostFormData>>({
|
|
|
|
defaultValues,
|
|
|
|
mode: 'all',
|
|
|
|
resolver: zodResolver(
|
|
|
|
generatePostFormValidator(params.type === 'update' ? params.post.id : undefined),
|
|
|
|
),
|
|
|
|
});
|
2024-09-28 14:58:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
export function usePostFormSubmitHandler(params: PostActionFormProps) {
|
|
|
|
const router = useRouter();
|
2024-10-14 11:38:41 +08:00
|
|
|
const { toast } = useToast();
|
2024-09-28 14:58:45 +08:00
|
|
|
const submitHandle = async (data: PostFormData) => {
|
|
|
|
let post: Post | null;
|
|
|
|
for (const key of Object.keys(data) as Array<keyof PostFormData>) {
|
|
|
|
if (typeof data[key] === 'string' && data[key].trim() === '') {
|
|
|
|
delete data[key];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
if (params.type === 'update') {
|
|
|
|
post = await updatePostItem(params.post.id, data);
|
|
|
|
} else {
|
|
|
|
post = await createPostItem({
|
|
|
|
thumb: `/uploads/thumb/post-${getRandomInt(1, 8)}.png`,
|
|
|
|
...data,
|
|
|
|
} as PostCreateData);
|
|
|
|
}
|
|
|
|
// 创建或更新文章后跳转到文章详情页
|
|
|
|
// 注意,这里不要用push,防止在详情页后退后返回到创建或编辑页面的弹出框
|
|
|
|
if (!isNil(post)) router.replace(`/post/${post.id}`);
|
|
|
|
} catch (error) {
|
2024-10-14 11:38:41 +08:00
|
|
|
toast({
|
|
|
|
variant: 'destructive',
|
|
|
|
title: '遇到服务器错误,请联系管理员处理',
|
|
|
|
description: (error as Error).message,
|
|
|
|
});
|
2024-09-28 14:58:45 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
return submitHandle;
|
|
|
|
}
|
|
|
|
|
|
|
|
export const usePostEditorScreenHandler = () => {
|
|
|
|
const { editorFullScreen } = useEditorModalContext();
|
|
|
|
|
|
|
|
return useMemo<MarkdownEditorProps['handlers']>(
|
|
|
|
() => ({
|
|
|
|
onBroswerScreen: editorFullScreen,
|
|
|
|
onPageScreen: editorFullScreen,
|
|
|
|
}),
|
|
|
|
[editorFullScreen],
|
|
|
|
);
|
|
|
|
};
|