From 00797230ad9eefa967675675c340e70b0d33e674 Mon Sep 17 00:00:00 2001 From: sunface Date: Fri, 19 Mar 2021 10:16:55 +0800 Subject: [PATCH] update --- pages/editor/drafts.tsx | 18 ++--- pages/editor/posts.tsx | 41 +++++----- pages/editor/series.tsx | 21 ++---- pages/settings/org/members/[org_id].tsx | 4 +- pages/settings/org/posts/[org_id].tsx | 74 +++++++++++++++++++ pages/settings/org/profile/[org_id].tsx | 2 +- server/internal/api/org.go | 49 ++++++++++++ server/internal/org/org.go | 10 +++ server/internal/server.go | 2 + server/internal/story/posts.go | 2 +- server/pkg/e/err_code.go | 1 + src/components/story/manage-stories.tsx | 46 ++++++++++++ ...t-story-card.tsx => manage-story-card.tsx} | 31 ++++---- src/data/links.tsx | 6 ++ 14 files changed, 237 insertions(+), 70 deletions(-) create mode 100644 pages/settings/org/posts/[org_id].tsx create mode 100644 src/components/story/manage-stories.tsx rename src/components/story/{text-story-card.tsx => manage-story-card.tsx} (73%) diff --git a/pages/editor/drafts.tsx b/pages/editor/drafts.tsx index 00d9e753..5d384d3b 100644 --- a/pages/editor/drafts.tsx +++ b/pages/editor/drafts.tsx @@ -8,7 +8,8 @@ import { Story } from "src/types/story" import { useRouter } from "next/router" import PageContainer1 from "layouts/page-container1" import Empty from "components/empty" -import TextStoryCard from "components/story/text-story-card" +import TextStoryCard from "components/story/manage-story-card" +import ManageStories from "components/story/manage-stories" const PostsPage = () => { const [posts, setPosts] = useState([]) @@ -50,17 +51,10 @@ const PostsPage = () => { posts.length === 0 ? : - <> - - {posts.map(post => - - editPost(post)} onDelete={() => onDeletePost(post.id)} showSource={false}/> - - - )} - -
没有更多文章了
- + + editPost(story)} onDelete={(id) => onDeletePost(id)} /> + + } diff --git a/pages/editor/posts.tsx b/pages/editor/posts.tsx index 8545179d..9397c6b5 100644 --- a/pages/editor/posts.tsx +++ b/pages/editor/posts.tsx @@ -1,13 +1,13 @@ -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 { 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 { 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 TextStoryCard from "components/story/manage-story-card" import { Story } from "src/types/story" import { FaExternalLinkAlt, FaRegEdit } from "react-icons/fa" import { useRouter } from "next/router" @@ -16,9 +16,10 @@ import Link from "next/link" import PageContainer1 from "layouts/page-container1" import Empty from "components/empty" import { IDType } from "src/types/id" +import ManageStories from "components/story/manage-stories" var validator = require('validator'); -const newPost: Story = {type: IDType.Post,title: '', url: '', cover: '' } +const newPost: Story = { type: IDType.Post, title: '', url: '', cover: '' } const PostsPage = () => { const [currentPost, setCurrentPost] = useState(newPost) const [posts, setPosts] = useState([]) @@ -85,7 +86,7 @@ const PostsPage = () => { } } - const onDeletePost= async (id) => { + const onDeletePost = async (id) => { await requestApi.delete(`/story/post/${id}`) getPosts() toast({ @@ -104,20 +105,20 @@ const PostsPage = () => { <> - + 文章列表({posts.length}) {config.posts.writingEnabled ? - - 新建文章 + + 新建文章 - - } onClick={onOpen}>外部链接 - } >原创博客 - - + + } onClick={onOpen}>外部链接 + } >原创博客 + + : } @@ -125,17 +126,9 @@ const PostsPage = () => { posts.length === 0 ? : - <> - - {posts.map(post => - - editPost(post)} onDelete={() => onDeletePost(post.id)} onPin={() => onPinPost(post.id)} /> - - - )} - -
没有更多文章了
- + + editPost(story)} onDelete={(id) => onDeletePost(id)} onPin={(id) => onPinPost(id)} /> + }
diff --git a/pages/editor/series.tsx b/pages/editor/series.tsx index ad6699a9..52bea20f 100644 --- a/pages/editor/series.tsx +++ b/pages/editor/series.tsx @@ -7,7 +7,7 @@ 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 TextStoryCard from "components/story/manage-story-card" import { Story } from "src/types/story" import { FaExternalLinkAlt, FaPlus, FaRegEdit } from "react-icons/fa" import { useRouter } from "next/router" @@ -20,10 +20,11 @@ import PostSelect from "components/story/post-select" import { cloneDeep, find, remove } from "lodash" import userCustomTheme from "theme/user-custom" import Tags from "components/tags/tags" +import ManageStories from "components/story/manage-stories" var validator = require('validator'); const newSeries: Story = { title: '', brief: '', cover: '', type: IDType.Series } -const PostsPage = () => { +const SeriesPage = () => { const [currentSeries, setCurrentSeries]: [Story, any] = useState(null) const [series, setSeries] = useState([]) const [posts, setPosts] = useState([]) @@ -286,17 +287,9 @@ const PostsPage = () => { { series.length === 0 ? : - <> - - {series.map(post => - - editSeries(post)} onDelete={() => onDeleteSeries(post.id)} showSource={false} onPin={() => onPinPost(post.id)} /> - - - )} - -
没有更多文章了
- + + editSeries(story)} onDelete={(id) => onDeleteSeries(id)} showSource={false} onPin={(id) => onPinPost(id)}/> + } } @@ -305,5 +298,5 @@ const PostsPage = () => { ) } -export default PostsPage +export default SeriesPage diff --git a/pages/settings/org/members/[org_id].tsx b/pages/settings/org/members/[org_id].tsx index 06086a91..f6499db9 100644 --- a/pages/settings/org/members/[org_id].tsx +++ b/pages/settings/org/members/[org_id].tsx @@ -82,7 +82,7 @@ const UserProfilePage = () => { <> - + Grow the org @@ -91,7 +91,7 @@ const UserProfilePage = () => { 1. Sign in 2. Navigate to {config.uiDomain}/settings/orgs 3. Paste the secret code below and click Join Organization - {secret} + {secret} diff --git a/pages/settings/org/posts/[org_id].tsx b/pages/settings/org/posts/[org_id].tsx new file mode 100644 index 00000000..41f6dd06 --- /dev/null +++ b/pages/settings/org/posts/[org_id].tsx @@ -0,0 +1,74 @@ +import { Text, Box, VStack, Divider, useToast, Heading, Alert, Tag, Button, HStack, Modal, ModalOverlay, ModalContent, ModalBody, Select, useDisclosure, Flex } from "@chakra-ui/react" +import Card from "components/card" +import Nav from "layouts/nav/nav" +import PageContainer from "layouts/page-container" +import Sidebar from "layouts/sidebar/sidebar" +import React, { useEffect, useState } from "react" +import { orgSettingLinks } from "src/data/links" +import { requestApi } from "utils/axios/request" +import { useRouter } from "next/router" +import { User } from "src/types/user" +import UserCard from "components/users/user-card" +import { config } from "configs/config" +import OrgMember from "components/users/org-member" +import { Role } from "src/types/role" +import { cloneDeep } from "lodash" +import { Story } from "src/types/story" +import Empty from "components/empty" +import ManageStories from "components/story/manage-stories" +import { IDType } from "src/types/id" + + +const OrgPostsPage = () => { + const [org, setOrg]:[User,any] = useState(null) + const [posts,setPosts]:[Story[],any] = useState([]) + const router = useRouter() + useEffect(() => { + if (router.query.org_id) { + getPosts() + requestApi.get(`/user/info/${router.query.org_id}`).then(res => setOrg(res.data)) + } + + }, [router.query.org_id]) + + const getPosts = async () => { + const res = await requestApi.get(`/story/posts/org/${router.query.org_id}?type=${IDType.Post}`) + setPosts(res.data) + } + const toast = useToast() + + const onDeletePost = async id => { + await requestApi.delete(`/org/post/${router.query.org_id}/${id}`) + getPosts() + } + + const onPinPost = async id => { + await requestApi.post(`/org/pin/story/${id}`) + } + + return ( + <> + + + + + + 文章列表({posts.length}) + + { + posts.length === 0 ? + + : + + onDeletePost(id)} onPin={(id) => onPinPost(id)} /> + + + } + + + + + ) +} +export default OrgPostsPage + diff --git a/pages/settings/org/profile/[org_id].tsx b/pages/settings/org/profile/[org_id].tsx index 08984494..668d38e8 100644 --- a/pages/settings/org/profile/[org_id].tsx +++ b/pages/settings/org/profile/[org_id].tsx @@ -116,7 +116,7 @@ const UserProfilePage = () => { <> - + {org && { + const { stories,showFooter=true,showSource=false, ...rest} = props + const borderColor = useColorModeValue(userCustomTheme.borderColor.light, userCustomTheme.borderColor.dark) + const showBorder = i => { + if (i < stories.length -1) { + return true + } + + if (showFooter) { + return true + } else { + return false + } + } + return ( + <> + + {stories.map((story,i) => + + + )} + + {showFooter &&
没有更多文章了
} + + ) +} + +export default ManageStories diff --git a/src/components/story/text-story-card.tsx b/src/components/story/manage-story-card.tsx similarity index 73% rename from src/components/story/text-story-card.tsx rename to src/components/story/manage-story-card.tsx index cb225dbf..471bab94 100644 --- a/src/components/story/text-story-card.tsx +++ b/src/components/story/manage-story-card.tsx @@ -9,21 +9,20 @@ import { getSvgIcon } from "components/svg-icon" type Props = PropsOf & { story: Story - showActions: boolean onEdit?: any onDelete?: any onPin?: any showSource?: boolean } - -export const TextStoryCard = (props: Props) => { - const { story, showActions, onEdit, onDelete, showSource = true,onPin, ...rest } = props +// 文章卡片,展示需要被管理的文章 +export const ManageStoryCard = (props: Props) => { + const { story, onEdit, onDelete, showSource = true,onPin, ...rest } = props const [isSmallScreen] = useMediaQuery("(max-width: 768px)") const Lay = isSmallScreen ? VStack : Flex const gap = moment(story.created).fromNow() - + const showActions = onEdit || onDelete || onPin return ( //@ts-ignore @@ -34,40 +33,40 @@ export const TextStoryCard = (props: Props) => { 发布于{gap}
- {props.showActions && - + {showActions && + {onPin && } - onClick={onPin} + onClick={() => onPin(story.id)} color={story.pinned? "teal" : null} /> - + } - + {onEdit&& onEdit(story)} /> - + } - + {onDelete&& } - onClick={props.onDelete} + onClick={() => props.onDelete(story.id)} /> - + } } ) } -export default TextStoryCard +export default ManageStoryCard diff --git a/src/data/links.tsx b/src/data/links.tsx index 0678d26c..2780d15a 100644 --- a/src/data/links.tsx +++ b/src/data/links.tsx @@ -113,6 +113,12 @@ export function orgSettingLinks(orgID) { icon: , disabled: false }, + { + title: '文章管理', + path: `${ReserveUrls.Settings}/org/posts/${orgID}`, + icon: getSvgIcon("post"), + disabled: false + }, ] }