visuddhinanda 3 лет назад
Родитель
Сommit
9ad4cf54d5

+ 20 - 0
dashboard/src/components/api/Comment.ts

@@ -0,0 +1,20 @@
+import { IUserRequest } from "./Auth";
+
+export interface ICommentRequest {
+  id?: string;
+  content?: string;
+  editor?: IUserRequest;
+  updated_at?: string;
+}
+
+export interface ICommentResponse {
+  ok: boolean;
+  message: string;
+  data: ICommentRequest;
+}
+
+export interface ICommentListResponse {
+  ok: boolean;
+  message: string;
+  data: { rows: ICommentRequest[]; count: number };
+}

+ 78 - 0
dashboard/src/components/comment/CommentEdit.tsx

@@ -0,0 +1,78 @@
+import { useState } from "react";
+import { useIntl } from "react-intl";
+import { Button, Card } from "antd";
+import { Input, message } from "antd";
+import { SaveOutlined } from "@ant-design/icons";
+
+import { IComment } from "./CommentItem";
+import { put } from "../../request";
+import { ICommentRequest, ICommentResponse } from "../api/Comment";
+
+const { TextArea } = Input;
+
+interface IWidget {
+  data: IComment;
+}
+const Widget = ({ data }: IWidget) => {
+  const intl = useIntl();
+  const [value, setValue] = useState(data.content);
+
+  const [saving, setSaving] = useState<boolean>(false);
+
+  const save = () => {
+    setSaving(true);
+    put<ICommentRequest, ICommentResponse>(`/v2/comment/${data.id}`, {
+      content: value,
+    })
+      .then((json) => {
+        console.log(json);
+        setSaving(false);
+
+        if (json.ok) {
+          message.success(intl.formatMessage({ id: "flashes.success" }));
+        } else {
+          message.error(json.message);
+        }
+      })
+      .catch((e) => {
+        setSaving(false);
+        console.error("catch", e);
+        message.error(e.message);
+      });
+  };
+
+  return (
+    <div>
+      <Card
+        title={<span>{data.user.nickName}</span>}
+        extra={
+          <Button shape="circle" size="small">
+            xxx
+          </Button>
+        }
+        style={{ width: "auto" }}
+      >
+        <TextArea
+          rows={4}
+          showCount
+          maxLength={2048}
+          value={value}
+          onChange={(e) => setValue(e.target.value)}
+        />
+
+        <div>
+          <Button
+            type="primary"
+            icon={<SaveOutlined />}
+            loading={saving}
+            onClick={() => save()}
+          >
+            Save
+          </Button>
+        </div>
+      </Card>
+    </div>
+  );
+};
+
+export default Widget;

+ 44 - 0
dashboard/src/components/comment/CommentItem.tsx

@@ -0,0 +1,44 @@
+import { Avatar } from "antd";
+import { useState } from "react";
+import { IUser } from "../auth/User";
+import CommentShow from "./CommentShow";
+import CommentEdit from "./CommentEdit";
+
+export interface IComment {
+  id?: string; //id未提供为新建
+  user: IUser;
+  title?: string;
+  content?: string;
+  children?: IComment[];
+  createdAt?: string;
+  updatedAt?: string;
+}
+interface IWidget {
+  data: IComment;
+  create?: boolean;
+}
+const Widget = ({ data, create = false }: IWidget) => {
+  const [edit, setEdit] = useState(false);
+
+  return (
+    <div style={{ display: "flex" }}>
+      <div style={{ width: "auto", padding: 8 }}>
+        <Avatar>{data.user.nickName.slice(0, 1)}</Avatar>
+      </div>
+      <div style={{ flex: "auto" }}>
+        {edit || create ? (
+          <CommentEdit data={data} />
+        ) : (
+          <CommentShow
+            data={data}
+            onEdit={() => {
+              setEdit(true);
+            }}
+          />
+        )}
+      </div>
+    </div>
+  );
+};
+
+export default Widget;

+ 46 - 0
dashboard/src/components/comment/CommentList.tsx

@@ -0,0 +1,46 @@
+import { Card, List, Avatar, Space } from "antd";
+import { MessageOutlined } from "@ant-design/icons";
+
+import { IComment } from "./CommentItem";
+import { Link } from "react-router-dom";
+
+interface IWidget {
+  data: IComment[];
+}
+const Widget = ({ data }: IWidget) => {
+  return (
+    <div>
+      <List
+        pagination={{
+          onChange: (page) => {
+            console.log(page);
+          },
+          pageSize: 10,
+        }}
+        itemLayout="horizontal"
+        dataSource={data}
+        renderItem={(item) => (
+          <List.Item
+            actions={[
+              <Space>
+                <MessageOutlined /> {"5"}
+              </Space>,
+            ]}
+          >
+            <List.Item.Meta
+              avatar={<Avatar src="https://joeschmoe.io/api/v1/random" />}
+              title={
+                <Link to={`/comment/${item.id}`}>
+                  {item.title ? item.title : item.content?.slice(0, 20)}
+                </Link>
+              }
+              description={item.content?.slice(0, 40)}
+            />
+          </List.Item>
+        )}
+      />
+    </div>
+  );
+};
+
+export default Widget;

+ 22 - 0
dashboard/src/components/comment/CommentListCard.tsx

@@ -0,0 +1,22 @@
+import { Card } from "antd";
+import { useState } from "react";
+
+import { IComment } from "./CommentItem";
+import CommentList from "./CommentList";
+
+interface IWidget {
+  resId: string;
+}
+const Widget = ({ resId }: IWidget) => {
+  const [data, setData] = useState<IComment[]>([]);
+
+  return (
+    <div>
+      <Card title="问题列表" extra={<a href="#">More</a>}>
+        <CommentList data={data} />
+      </Card>
+    </div>
+  );
+};
+
+export default Widget;

+ 5 - 0
dashboard/src/components/comment/CommentListItem.tsx

@@ -0,0 +1,5 @@
+const Widget = () => {
+  return <div>change password</div>;
+};
+
+export default Widget;

+ 80 - 0
dashboard/src/components/comment/CommentShow.tsx

@@ -0,0 +1,80 @@
+import { Button, Card, Dropdown, Space } from "antd";
+import { MoreOutlined } from "@ant-design/icons";
+import type { MenuProps } from "antd";
+
+import { IComment } from "./CommentItem";
+import TimeShow from "../general/TimeShow";
+
+interface IWidget {
+  data: IComment;
+  onEdit?: Function;
+}
+const Widget = ({ data, onEdit }: IWidget) => {
+  const onClick: MenuProps["onClick"] = (e) => {
+    console.log("click ", e);
+    switch (e.key) {
+      case "edit":
+        if (typeof onEdit !== "undefined") {
+          onEdit();
+        }
+        break;
+      default:
+        break;
+    }
+  };
+
+  const items: MenuProps["items"] = [
+    {
+      key: "copy-link",
+      label: "复制链接",
+    },
+    {
+      key: "reply",
+      label: "回复",
+    },
+    {
+      type: "divider",
+    },
+    {
+      key: "edit",
+      label: "编辑",
+    },
+    {
+      key: "delete",
+      label: "删除",
+    },
+    {
+      type: "divider",
+    },
+    {
+      key: "report-content",
+      label: "举报",
+    },
+  ];
+  return (
+    <div>
+      <Card
+        title={
+          <Space>
+            {data.user.nickName}
+            <TimeShow time={data.updatedAt} title="UpdatedAt" />
+          </Space>
+        }
+        extra={
+          <Dropdown menu={{ items, onClick }} placement="bottomRight">
+            <Button
+              shape="circle"
+              size="small"
+              icon={<MoreOutlined />}
+            ></Button>
+          </Dropdown>
+        }
+        style={{ width: "auto" }}
+      >
+        {data.content}
+      </Card>
+    </div>
+  );
+};
+
+export default Widget;

+ 25 - 0
dashboard/src/components/comment/CommentTopic.tsx

@@ -0,0 +1,25 @@
+import { useState } from "react";
+import { Divider } from "antd";
+
+import CommentItem, { IComment } from "./CommentItem";
+import CommentTopicList from "./CommentTopicList";
+import CommentTopicHead from "./CommentTopicHead";
+
+interface IWidget {
+  resId: string;
+}
+const Widget = ({ resId }: IWidget) => {
+  const [childrenData, setChildrenData] = useState<IComment[]>([]);
+  const [data, setData] = useState<IComment>();
+
+  return (
+    <div>
+      <CommentTopicHead data={data} />
+      <Divider />
+      <CommentTopicList data={childrenData} />
+      {data ? <CommentItem data={data} create={true} /> : undefined}
+    </div>
+  );
+};
+
+export default Widget;

+ 30 - 0
dashboard/src/components/comment/CommentTopicHead.tsx

@@ -0,0 +1,30 @@
+import { Typography, Space } from "antd";
+import TimeShow from "../general/TimeShow";
+
+import { IComment } from "./CommentItem";
+
+const { Title, Text } = Typography;
+
+interface IWidget {
+  data?: IComment;
+}
+const Widget = ({ data }: IWidget) => {
+  return (
+    <div>
+      <Title editable level={1} style={{ margin: 0 }}>
+        {data?.title}
+      </Title>
+      <div>
+        <Text type="secondary">
+          <Space>
+            {" "}
+            {data?.user.nickName}{" "}
+            <TimeShow time={data?.createdAt} title="创建" />
+          </Space>
+        </Text>
+      </div>
+    </div>
+  );
+};
+
+export default Widget;

+ 32 - 0
dashboard/src/components/comment/CommentTopicList.tsx

@@ -0,0 +1,32 @@
+import { Card, List, Avatar, Space } from "antd";
+import { MessageOutlined } from "@ant-design/icons";
+
+import CommentItem, { IComment } from "./CommentItem";
+import { Link } from "react-router-dom";
+
+interface IWidget {
+  data: IComment[];
+}
+const Widget = ({ data }: IWidget) => {
+  return (
+    <div>
+      <List
+        pagination={{
+          onChange: (page) => {
+            console.log(page);
+          },
+          pageSize: 10,
+        }}
+        itemLayout="horizontal"
+        dataSource={data}
+        renderItem={(item) => (
+          <List.Item>
+            <CommentItem data={item} />
+          </List.Item>
+        )}
+      />
+    </div>
+  );
+};
+
+export default Widget;