import { Menu,MenuButton,MenuList,MenuItem, Text, Box, Heading, Image, HStack, Center, Button, Flex, Modal, ModalOverlay, ModalContent, ModalHeader, ModalBody, ModalFooter, FormControl, FormLabel, FormHelperText, Input, FormErrorMessage, VStack, Textarea, Divider, useColorModeValue, useToast } from "@chakra-ui/react" import Card from "components/card" import Sidebar from "layouts/sidebar/sidebar" import React, { useEffect, useState } from "react" import {editorLinks} from "src/data/links" import { requestApi } from "utils/axios/request" import { useDisclosure } from "@chakra-ui/react" import { Field, Form, Formik } from "formik" import { config } from "configs/config" import TextStoryCard from "components/story/text-story-card" import { Story } from "src/types/story" import { FaExternalLinkAlt, FaRegEdit } from "react-icons/fa" import { useRouter } from "next/router" import { ReserveUrls } from "src/data/reserve-urls" import Link from "next/link" import PageContainer1 from "layouts/page-container1" import Empty from "components/empty" import { IDType } from "src/types/id" var validator = require('validator'); const newPost: Story = {type: IDType.Post,title: '', url: '', cover: '' } const PostsPage = () => { const [currentPost, setCurrentPost] = useState(newPost) const [posts, setPosts] = useState([]) const { isOpen, onOpen, onClose } = useDisclosure() const router = useRouter() const toast = useToast() const getPosts = () => { requestApi.get(`/story/posts/editor?type=${IDType.Post}`).then((res) => setPosts(res.data)).catch(_ => setPosts([])) } useEffect(() => { getPosts() }, []) function validateTitle(value) { let error if (!value?.trim()) { error = "标题不能为空" } if (value?.length > config.posts.titleMaxLen) { error = "标题长度不能超过128" } return error } function validateUrl(value) { let error if (!validator.isURL(value)) { error = "URL格式不合法" } return error } function validateBrief(value) { let error if (value && value.length > config.posts.briefMaxLen) { error = `文本长度不能超过${config.posts.briefMaxLen}` } return error } const submitPost = async (values, _) => { await requestApi.post(`/story`, values) onClose() toast({ description: "提交成功", status: "success", duration: 2000, isClosable: true, }) setCurrentPost(newPost) getPosts() } const editPost = (post: Story) => { if (post.url.trim() === "") { router.push(`/editor/post/${post.id}`) } else { setCurrentPost(post) onOpen() } } const onDeletePost= async (id) => { await requestApi.delete(`/story/post/${id}`) getPosts() toast({ description: "删除成功", status: "success", duration: 2000, isClosable: true, }) } return ( <> 文章列表({posts.length}) {config.posts.writingEnabled ? 新建文章 } onClick={onOpen}>外部链接 } >原创博客 : } { posts.length === 0 ? : <> {posts.map(post => editPost(post)} onDelete={() => onDeletePost(post.id)} /> )}
没有更多文章了
}
{currentPost.id ? "编辑文章" : "新建文章"} {(props) => (
{({ field, form }) => ( 标题 {form.errors.title} )} {({ field, form }) => ( URL {form.errors.url} )} {({ field, form }) => ( 封面图片 {form.errors.cover} )} {({ field, form }) => ( 文章简介 {form.errors.brief} )}
)}
) } export default PostsPage