visuddhinanda 3 лет назад
Родитель
Сommit
03d2f94f5a

+ 49 - 20
dashboard/src/components/corpus/ChapterFilter.tsx

@@ -1,29 +1,58 @@
-import { Layout, Row, Col } from "antd";
-import { Button } from "antd";
+import { Space, Input } from "antd";
 
 import ChapterFilterType from "./ChapterFilterType";
 import ChapterFilterLang from "./ChapterFilterLang";
 import ChapterFilterProgress from "./ChapterFilterProgress";
 
-const Widget = () => {
+const { Search } = Input;
+
+interface IWidget {
+  onTypeChange?: Function;
+  onLangChange?: Function;
+  onProgressChange?: Function;
+  onSearchChange?: Function;
+}
+const Widget = ({
+  onTypeChange,
+  onLangChange,
+  onProgressChange,
+  onSearchChange,
+}: IWidget) => {
   return (
-    <Layout>
-      <Row>
-        <Col>
-          <ChapterFilterType />
-        </Col>
-        <Col>
-          <ChapterFilterLang />
-        </Col>
-        <Col>
-          <ChapterFilterProgress />
-        </Col>
-        <Col>
-          <Button>Search</Button>
-          <Button>Reset</Button>
-        </Col>
-      </Row>
-    </Layout>
+    <Space style={{ margin: 8 }}>
+      <Search
+        placeholder="标题搜索"
+        onSearch={(value: string) => {
+          if (typeof onSearchChange !== "undefined") {
+            onSearchChange(value);
+          }
+        }}
+        style={{ width: 200 }}
+      />
+      <ChapterFilterProgress
+        onSelect={(value: string) => {
+          if (typeof onProgressChange !== "undefined") {
+            onProgressChange(value);
+          }
+        }}
+      />
+
+      <ChapterFilterType
+        onSelect={(value: string) => {
+          if (typeof onTypeChange !== "undefined") {
+            onTypeChange(value);
+          }
+        }}
+      />
+
+      <ChapterFilterLang
+        onSelect={(value: string) => {
+          if (typeof onLangChange !== "undefined") {
+            onLangChange(value);
+          }
+        }}
+      />
+    </Space>
   );
 };
 

+ 35 - 22
dashboard/src/components/corpus/ChapterFilterLang.tsx

@@ -1,29 +1,42 @@
 import { Select } from "antd";
-import React from "react";
+import { DefaultOptionType } from "antd/lib/select";
+import { useEffect, useState } from "react";
 
-const { Option } = Select;
+import { get } from "../../request";
+import { IChapterLangListResponse } from "../api/Corpus";
 
-const children: React.ReactNode[] = [];
-for (let i = 10; i < 36; i++) {
-	children.push(<Option key={i.toString(36) + i}>{i.toString(36) + i}</Option>);
+interface IWidget {
+  onSelect?: Function;
 }
-
-const handleChange = (value: string[]) => {
-	console.log(`selected ${value}`);
-};
-const Widget = () => {
-	return (
-		<Select
-			mode="multiple"
-			allowClear
-			style={{ minWidth: 100 }}
-			placeholder="Language"
-			defaultValue={[]}
-			onChange={handleChange}
-		>
-			{children}
-		</Select>
-	);
+const Widget = ({ onSelect }: IWidget) => {
+  const [lang, setLang] = useState<DefaultOptionType[]>([]);
+  useEffect(() => {
+    get<IChapterLangListResponse>(`/v2/progress?view=lang`).then((json) => {
+      if (json.ok) {
+        const langs = json.data.rows.map((item) => {
+          return {
+            value: item.lang,
+            label: `${item.lang}-${item.count}`,
+          };
+        });
+        setLang(langs);
+      }
+    });
+  }, []);
+  return (
+    <Select
+      style={{ minWidth: 100 }}
+      placeholder="Language"
+      defaultValue={["zh"]}
+      onChange={(value: string[]) => {
+        console.log(`selected ${value}`);
+        if (typeof onSelect !== "undefined") {
+          onSelect(value);
+        }
+      }}
+      options={lang}
+    />
+  );
 };
 
 export default Widget;

+ 23 - 19
dashboard/src/components/corpus/ChapterFilterProgress.tsx

@@ -1,27 +1,31 @@
 import { Select } from "antd";
-import React from "react";
 
 const { Option } = Select;
 
-const children: React.ReactNode[] = [];
-for (let i = 10; i < 36; i++) {
-	children.push(<Option key={i.toString(36) + i}>{i.toString(36) + i}</Option>);
+interface IWidget {
+  onSelect?: Function;
 }
-
-const handleChange = (value: string[]) => {
-	console.log(`selected ${value}`);
-};
-const Widget = () => {
-	return (
-		<Select style={{ width: 100 }} placeholder="完成度" defaultValue={["90"]} onChange={handleChange}>
-			<Option key="0.9">90%</Option>
-			<Option key="0.8">80%</Option>
-			<Option key="0.7">70%</Option>
-			<Option key="0.6">60%</Option>
-			<Option key="0.5">50%</Option>
-			<Option key="0.01">1%</Option>
-		</Select>
-	);
+const Widget = ({ onSelect }: IWidget) => {
+  return (
+    <Select
+      style={{ width: 100 }}
+      placeholder="完成度"
+      defaultValue={["90"]}
+      onChange={(value: string[]) => {
+        console.log(`selected`, value);
+        if (typeof onSelect !== "undefined") {
+          onSelect(value);
+        }
+      }}
+    >
+      <Option key="0.9">90%</Option>
+      <Option key="0.8">80%</Option>
+      <Option key="0.7">70%</Option>
+      <Option key="0.6">60%</Option>
+      <Option key="0.5">50%</Option>
+      <Option key="0.01">1%</Option>
+    </Select>
+  );
 };
 
 export default Widget;

+ 36 - 15
dashboard/src/components/corpus/ChapterFilterType.tsx

@@ -1,22 +1,43 @@
 import { Select } from "antd";
-import React from "react";
+import { useIntl } from "react-intl";
 
-const { Option } = Select;
-
-const children: React.ReactNode[] = [];
-for (let i = 1; i < 5; i++) {
-	children.push(<Option key={i.toString(5) + i}>{i.toString(5) + i}</Option>);
+interface IWidget {
+  onSelect?: Function;
 }
+const Widget = ({ onSelect }: IWidget) => {
+  const intl = useIntl();
 
-const handleChange = (value: string[]) => {
-	console.log(`selected ${value}`);
-};
-const Widget = () => {
-	return (
-		<Select style={{ width: 100 }} allowClear placeholder="Type" defaultValue={[]} onChange={handleChange}>
-			{children}
-		</Select>
-	);
+  return (
+    <Select
+      style={{ minWidth: 100 }}
+      placeholder="Type"
+      defaultValue={["translation"]}
+      onChange={(value: string[]) => {
+        console.log(`selected ${value}`);
+        if (typeof onSelect !== "undefined") {
+          onSelect(value);
+        }
+      }}
+      options={[
+        {
+          value: "translation",
+          label: intl.formatMessage({ id: "channel.type.translation.label" }),
+        },
+        {
+          value: "nissaya",
+          label: intl.formatMessage({ id: "channel.type.nissaya.label" }),
+        },
+        {
+          value: "commentary",
+          label: intl.formatMessage({ id: "channel.type.commentary.label" }),
+        },
+        {
+          value: "original",
+          label: intl.formatMessage({ id: "channel.type.original.label" }),
+        },
+      ]}
+    />
+  );
 };
 
 export default Widget;

+ 62 - 23
dashboard/src/components/corpus/ChapterList.tsx

@@ -7,34 +7,47 @@ import ChapterCard from "./ChapterCard";
 import type { ChapterData } from "./ChapterCard";
 import type { ChannelFilterProps } from "../channel/ChannelList";
 
-const defaultChannelFilterProps: ChannelFilterProps = {
+const defaultFilterProps: ChannelFilterProps = {
   chapterProgress: 0.9,
   lang: "en",
   channelType: "translation",
 };
 
-interface IWidgetChannelList {
+interface IWidget {
   filter?: ChannelFilterProps;
+  progress?: number;
+  lang?: string;
+  type?: string;
   tags?: string[];
+  onTagClick?: Function;
 }
 
 const Widget = ({
-  filter = defaultChannelFilterProps,
+  progress = 0.9,
+  lang = "zh",
+  type = "translation",
   tags = [],
-}: IWidgetChannelList) => {
+  onTagClick,
+}: IWidget) => {
   const [tableData, setTableData] = useState<ChapterData[]>([]);
-
+  const [total, setTotal] = useState<number>();
+  const [currPage, setCurrPage] = useState<number>(1);
   useEffect(() => {
-    console.log("useEffect");
-
-    fetchData(filter, tags);
-  }, [tags, filter]);
+    fetchData(
+      { chapterProgress: progress, lang: lang, channelType: type },
+      tags,
+      currPage
+    );
+  }, [progress, lang, type, tags, currPage]);
 
-  function fetchData(filter: ChannelFilterProps, tags: string[]) {
+  function fetchData(filter: ChannelFilterProps, tags: string[], page = 1) {
     const strTags = tags.length > 0 ? "&tags=" + tags.join() : "";
-    get<IChapterListResponse>(`/v2/progress?view=chapter${strTags}`).then(
-      (json) => {
-        console.log("chapter list ajax", json);
+    const offset = (page - 1) * 20;
+    get<IChapterListResponse>(
+      `/v2/progress?view=chapter${strTags}&offset=${offset}&progress=${filter.chapterProgress}&lang=${filter.lang}&channel_type=${filter.channelType}`
+    ).then((json) => {
+      console.log("chapter list ajax", json);
+      if (json.ok) {
         let newTree: ChapterData[] = json.data.rows.map(
           (item: IChapterData) => {
             return {
@@ -44,15 +57,16 @@ const Widget = ({
               book: item.book,
               paragraph: item.para,
               summary: item.summary,
-              tag: item.tags,
+              tag: item.tags.map((item) => {
+                return { title: item.name, key: item.name };
+              }),
               channel: {
-                channelName: item.channel.name,
-                channelId: item.channel_id,
-                channelType: "translation",
-                studioName: item.channel.name,
-                studioId: item.channel.owner_uid,
-                studioType: "",
+                name: item.channel.name,
+                id: item.channel_id,
+                type: "translation",
               },
+              studio: item.studio,
+              progress: Math.round(item.progress * 100),
               createdAt: item.created_at,
               updatedAt: item.updated_at,
               hit: item.view,
@@ -61,19 +75,44 @@ const Widget = ({
             };
           }
         );
+        setTotal(json.data.count);
         setTableData(newTree);
+      } else {
+        setTotal(0);
+        setTableData([]);
       }
-    );
+    });
   }
 
   return (
     <List
       itemLayout="vertical"
-      size="large"
+      size="small"
       dataSource={tableData}
+      pagination={{
+        onChange: (page) => {
+          console.log(page);
+          setCurrPage(page);
+        },
+        showQuickJumper: true,
+        showSizeChanger: false,
+        pageSize: 20,
+        total: total,
+        position: "both",
+        showTotal: (total) => {
+          return `结果: ${total}`;
+        },
+      }}
       renderItem={(item) => (
         <List.Item>
-          <ChapterCard data={item} />
+          <ChapterCard
+            data={item}
+            onTagClick={(tag: string) => {
+              if (typeof onTagClick !== "undefined") {
+                onTagClick(tag);
+              }
+            }}
+          />
         </List.Item>
       )}
     />

+ 56 - 10
dashboard/src/pages/library/community/list.tsx

@@ -1,34 +1,80 @@
+import { useNavigate } from "react-router-dom";
 import { useState } from "react";
-import { Layout, Affix, Row, Col } from "antd";
+import { Layout, Affix, Row, Col, Divider, Space } from "antd";
 import { Typography } from "antd";
-
+import { TagOutlined } from "@ant-design/icons";
 import ChannelList from "../../../components/channel/ChannelList";
 import BookTree from "../../../components/corpus/BookTree";
-import ChapterFileter from "../../../components/corpus/ChapterFilter";
+import ChapterFilter from "../../../components/corpus/ChapterFilter";
 import ChapterList from "../../../components/corpus/ChapterList";
 import ChapterTagList from "../../../components/corpus/ChapterTagList";
 
 const { Title } = Typography;
 const Widget = () => {
   // TODO
+  const navigate = useNavigate();
+
   const defaultTags: string[] = [];
   const [tags, setTags] = useState(defaultTags);
+  const [progress, setProgress] = useState(0.9);
+  const [lang, setLang] = useState("zh");
+  const [type, setType] = useState("translation");
 
   return (
     <Row>
-      <Col xs={0} xl={6}>
+      <Col xs={0} sm={6} md={5}>
         <Affix offsetTop={0}>
           <Layout style={{ height: "100vh", overflowY: "scroll" }}>
-            <BookTree />
+            <BookTree
+              onChange={(key: string, path: string[]) => {
+                /*
+                navigate(
+                  `/community/list/${key.split(",").join("-").toLowerCase()}`
+                );
+                */
+                setTags(key.split(","));
+
+                console.log(key);
+              }}
+            />
           </Layout>
         </Affix>
       </Col>
-      <Col xs={24} xl={14}>
-        <ChapterFileter />
-        <Title level={1}>{tags}</Title>
-        <ChapterList tags={tags} />
+      <Col xs={24} sm={18} md={14}>
+        <ChapterFilter
+          onProgressChange={(value: string) => {
+            console.log("progress change", value);
+            setProgress(parseFloat(value));
+          }}
+          onLangChange={(value: string) => {
+            console.log("lang change", value);
+            setLang(value);
+          }}
+          onTypeChange={(value: string) => {
+            console.log("type change", value);
+            setType(value);
+          }}
+        />
+        <Divider />
+
+        <Title level={3}>
+          <Space>
+            <TagOutlined />
+            {tags}
+          </Space>
+        </Title>
+
+        <ChapterList
+          tags={tags}
+          progress={progress}
+          lang={lang}
+          type={type}
+          onTagClick={(tag: string) => {
+            setTags([tag]);
+          }}
+        />
       </Col>
-      <Col xs={0} xl={4}>
+      <Col xs={0} sm={0} md={5}>
         <ChapterTagList
           onTagClick={(key: string) => {
             setTags([key]);