visuddhinanda 2 лет назад
Родитель
Сommit
3ae9dbe706

+ 20 - 0
dashboard/src/components/term/TermItem.tsx

@@ -0,0 +1,20 @@
+import { Typography } from "antd";
+import { ITermDataResponse } from "../api/Term";
+import MdView from "../template/MdView";
+
+const { Title, Text, Paragraph } = Typography;
+
+interface IWidget {
+  data?: ITermDataResponse;
+}
+const Widget = ({ data }: IWidget) => {
+  return (
+    <Paragraph>
+      <Title level={4}>{data?.meaning}</Title>
+      <Text>{data?.other_meaning}</Text>
+      <MdView html={data?.html} />
+    </Paragraph>
+  );
+};
+
+export default Widget;

+ 66 - 0
dashboard/src/components/term/TermSearch.tsx

@@ -0,0 +1,66 @@
+import { useState, useEffect } from "react";
+import { Col, List, Row } from "antd";
+
+import { get } from "../../request";
+import {
+  ITermDataResponse,
+  ITermListResponse,
+  ITermResponse,
+} from "../api/Term";
+import TermItem from "./TermItem";
+
+interface IWidget {
+  word?: string;
+  wordId?: string;
+  compact?: boolean;
+}
+const TermSearchWidget = ({ word, wordId, compact = false }: IWidget) => {
+  const [tableData, setTableData] = useState<ITermDataResponse[]>();
+
+  useEffect(() => {
+    if (typeof word === "undefined" && typeof wordId === "undefined") {
+      return;
+    }
+    if (word) {
+      const url = `/v2/terms?view=word&word=${word}`;
+      get<ITermListResponse>(url)
+        .then((json) => {
+          setTableData(json.data.rows);
+        })
+        .catch((error) => {
+          console.error(error);
+        });
+    } else if (wordId) {
+      const url = `/v2/terms/${wordId}`;
+      get<ITermResponse>(url)
+        .then((json) => {
+          setTableData([json.data]);
+        })
+        .catch((error) => {
+          console.error(error);
+        });
+    }
+  }, [word, wordId]);
+
+  return (
+    <Row>
+      <Col flex="200px">{compact ? <></> : <></>}</Col>
+      <Col flex="760px">
+        <List
+          itemLayout="vertical"
+          size="large"
+          dataSource={tableData}
+          header={word}
+          renderItem={(item) => (
+            <List.Item>
+              <TermItem data={item} />
+            </List.Item>
+          )}
+        />
+      </Col>
+      <Col flex="200px"></Col>
+    </Row>
+  );
+};
+
+export default TermSearchWidget;

+ 74 - 0
dashboard/src/components/term/TermShow.tsx

@@ -0,0 +1,74 @@
+import { useEffect, useState } from "react";
+import { Layout, Affix, Col, Row } from "antd";
+
+import SearchVocabulary from "../dict/SearchVocabulary";
+import TermSearch from "./TermSearch";
+
+const { Content } = Layout;
+
+interface IWidget {
+  word?: string;
+  wordId?: string;
+  compact?: boolean;
+  onSearch?: Function;
+}
+const TermShowWidget = ({
+  word,
+  wordId,
+  compact = false,
+  onSearch,
+}: IWidget) => {
+  const [split, setSplit] = useState<string>();
+  const [wordSearch, setWordSearch] = useState<string>();
+  const [container, setContainer] = useState<HTMLDivElement | null>(null);
+
+  useEffect(() => {
+    setWordSearch(word?.toLowerCase());
+  }, [word]);
+  const dictSearch = (value: string, isFactor?: boolean) => {
+    console.log("onSearch", value);
+    const word = value.toLowerCase();
+    setWordSearch(word);
+    if (typeof onSearch !== "undefined") {
+      onSearch(value, isFactor);
+    }
+  };
+  return (
+    <div ref={setContainer}>
+      <Affix offsetTop={0} target={compact ? () => container : undefined}>
+        <div
+          style={{
+            backgroundColor: "rgba(100,100,100,0.3)",
+            backdropFilter: "blur(5px)",
+          }}
+        >
+          <Row style={{ paddingTop: "0.5em", paddingBottom: "0.5em" }}>
+            {compact ? <></> : <Col flex="auto"></Col>}
+            <Col flex="560px">
+              <SearchVocabulary
+                value={word}
+                onSearch={dictSearch}
+                onSplit={(word: string | undefined) => {
+                  console.log("onSplit", word);
+                  setSplit(word);
+                }}
+              />
+            </Col>
+            {compact ? <></> : <Col flex="auto"></Col>}
+          </Row>
+        </div>
+      </Affix>
+      <Content style={{ minHeight: 700 }}>
+        <Row>
+          {compact ? <></> : <Col flex="auto"></Col>}
+          <Col flex="1260px">
+            <TermSearch word={wordSearch} wordId={wordId} compact={compact} />
+          </Col>
+          {compact ? <></> : <Col flex="auto"></Col>}
+        </Row>
+      </Content>
+    </div>
+  );
+};
+
+export default TermShowWidget;

+ 18 - 0
dashboard/src/pages/library/term/index.tsx

@@ -0,0 +1,18 @@
+import { Outlet } from "react-router-dom";
+import { Layout } from "antd";
+
+import HeadBar from "../../../components/library/HeadBar";
+import FooterBar from "../../../components/library/FooterBar";
+
+const Widget = () => {
+  // TODO
+  return (
+    <Layout>
+      <HeadBar selectedKeys="term" />
+      <Outlet />
+      <FooterBar />
+    </Layout>
+  );
+};
+
+export default Widget;

+ 10 - 0
dashboard/src/pages/library/term/list.tsx

@@ -0,0 +1,10 @@
+import { useParams } from "react-router-dom";
+
+import TermShow from "../../../components/term/TermShow";
+
+const Widget = () => {
+  const { word } = useParams(); //url 参数
+  return <TermShow word={word} />;
+};
+
+export default Widget;