visuddhinanda 3 лет назад
Родитель
Сommit
26a909bd56

+ 134 - 113
dashboard/src/Router.tsx

@@ -85,141 +85,162 @@ import StudioAnthologyEdit from "./pages/studio/anthology/edit";
 
 import StudioAnalysis from "./pages/studio/analysis";
 import StudioAnalysisList from "./pages/studio/analysis/list";
+import { ConfigProvider } from "antd";
+import { useAppSelector } from "./hooks";
+import { currTheme } from "./reducers/theme";
 
 const Widget = () => {
+  const theme = useAppSelector(currTheme);
   return (
-    <Routes>
-      <Route path="anonymous" element={<Anonymous />}>
-        <Route path="users">
-          <Route path="sign-in" element={<NutUsersSignIn />} />
-          <Route path="sign-up" element={<NutUsersSignUp />} />
-
-          <Route path="unlock">
-            <Route path="new" element={<NutUsersUnlockNew />} />
-            <Route path="verify/:token" element={<NutUsersUnlockVerify />} />
+    <ConfigProvider prefixCls={theme}>
+      <Routes>
+        <Route path="anonymous" element={<Anonymous />}>
+          <Route path="users">
+            <Route path="sign-in" element={<NutUsersSignIn />} />
+            <Route path="sign-up" element={<NutUsersSignUp />} />
+
+            <Route path="unlock">
+              <Route path="new" element={<NutUsersUnlockNew />} />
+              <Route path="verify/:token" element={<NutUsersUnlockVerify />} />
+            </Route>
+            <Route
+              path="reset-password/:token"
+              element={<NutUsersResetPassword />}
+            />
+            <Route
+              path="forgot-password"
+              element={<NutUsersForgotPassword />}
+            />
           </Route>
-          <Route
-            path="reset-password/:token"
-            element={<NutUsersResetPassword />}
-          />
-          <Route path="forgot-password" element={<NutUsersForgotPassword />} />
         </Route>
-      </Route>
 
-      <Route path="dashboard" element={<Dashboard />}>
-        <Route path="users">
-          <Route path="change-password" element={<NutUsersChangePassword />} />
-          <Route path="logs" element={<NutUsersLogs />} />
-          <Route path="account-info" element={<NutUsersAccountInfo />} />
+        <Route path="dashboard" element={<Dashboard />}>
+          <Route path="users">
+            <Route
+              path="change-password"
+              element={<NutUsersChangePassword />}
+            />
+            <Route path="logs" element={<NutUsersLogs />} />
+            <Route path="account-info" element={<NutUsersAccountInfo />} />
+          </Route>
+        </Route>
+        <Route path="switch-language" element={<NutSwitchLanguage />} />
+        <Route path="forbidden" element={<NutForbidden />} />
+        <Route path="nut" element={<NutHome />} />
+        <Route path="" element={<LibraryHome />} />
+        <Route path="*" element={<NutNotFound />} />
+
+        <Route path="community" element={<LibraryCommunity />}>
+          <Route path="list" element={<LibraryCommunityList />} />
+          <Route path="recent" element={<LibraryCommunityRecent />} />
         </Route>
-      </Route>
-      <Route path="switch-language" element={<NutSwitchLanguage />} />
-      <Route path="forbidden" element={<NutForbidden />} />
-      <Route path="nut" element={<NutHome />} />
-      <Route path="" element={<LibraryHome />} />
-      <Route path="*" element={<NutNotFound />} />
-
-      <Route path="community" element={<LibraryCommunity />}>
-        <Route path="list" element={<LibraryCommunityList />} />
-        <Route path="recent" element={<LibraryCommunityRecent />} />
-      </Route>
-
-      <Route path="palicanon" element={<LibraryPalicanon />}>
-        <Route path="list" element={<LibraryPalicanonByPath />} />
-        <Route path="list/:root" element={<LibraryPalicanonByPath />} />
-        <Route path="list/:root/:path" element={<LibraryPalicanonByPath />} />
-        <Route
-          path="list/:root/:path/:tag"
-          element={<LibraryPalicanonByPath />}
-        />
-        <Route path="chapter/:id" element={<LibraryPalicanonChapter />} />
-      </Route>
-
-      <Route path="course" element={<LibraryCourse />}>
-        <Route path="list" element={<LibraryCourseList />}></Route>
-        <Route path="show/:id" element={<LibraryCourseShow />}></Route>
-        <Route path="lesson" element={<LibraryLessonShow />}></Route>
-      </Route>
-
-      <Route path="term/:word" element={<LibraryTerm />} />
-
-      <Route path="dict" element={<LibraryDict />}>
-        <Route path=":word" element={<LibraryDictShow />} />
-        <Route path="recent" element={<LibraryDictShow />} />
-      </Route>
-
-      <Route path="anthology" element={<LibraryAnthology />}>
-        <Route path="list" element={<LibraryAnthologyList />} />
-        <Route path=":id" element={<LibraryAnthologyShow />} />
-        <Route path=":id/by_channel/:tags" element={<LibraryAnthologyShow />} />
-      </Route>
-
-      <Route path="article" element={<LibraryArticle />}>
-        <Route path=":type/:id" element={<LibraryArticleShow />} />
-        <Route path=":type/:id/:mode" element={<LibraryArticleShow />} />
-        <Route path=":type/:id/:mode/:param" element={<LibraryArticleShow />} />
-      </Route>
-
-      <Route path="discussion" element={<LibraryDiscussion />}>
-        <Route path="list" element={<LibraryDiscussionList />} />
-        <Route path="topic/:id" element={<LibraryDiscussionTopic />} />
-        <Route path="discussion/:id" element={<LibraryDiscussion />} />
-      </Route>
-
-      <Route path="blog/:studio" element={<LibraryBlog />}>
-        <Route path="overview" element={<LibraryBlogOverview />} />
-        <Route path="palicanon" element={<LibraryBlogTranslation />} />
-        <Route path="course" element={<LibraryBlogCourse />} />
-        <Route path="anthology" element={<LibraryBlogAnthology />} />
-        <Route path="term" element={<LibraryBlogTerm />} />
-      </Route>
-
-      <Route path="studio/:studioname" element={<Studio />}>
-        <Route path="home" element={<StudioHome />} />
-        <Route path="palicanon" element={<StudioPalicanon />}></Route>
-        <Route path="recent" element={<StudioRecent />}></Route>
-
-        <Route path="channel" element={<StudioChannel />}>
-          <Route path="list" element={<StudioChannelList />} />
-          <Route path=":channelid/edit" element={<StudioChannelEdit />} />
-          <Route path=":channelId" element={<StudioChannelShow />} />
+
+        <Route path="palicanon" element={<LibraryPalicanon />}>
+          <Route path="list" element={<LibraryPalicanonByPath />} />
+          <Route path="list/:root" element={<LibraryPalicanonByPath />} />
+          <Route path="list/:root/:path" element={<LibraryPalicanonByPath />} />
+          <Route
+            path="list/:root/:path/:tag"
+            element={<LibraryPalicanonByPath />}
+          />
+          <Route path="chapter/:id" element={<LibraryPalicanonChapter />} />
         </Route>
 
-        <Route path="group" element={<StudioGroup />}>
-          <Route path="list" element={<StudioGroupList />} />
-          <Route path=":groupId" element={<StudioGroupShow />} />
-          <Route path=":groupId/edit" element={<StudioGroupEdit />} />
-          <Route path=":groupId/show" element={<StudioGroupShow />} />
+        <Route path="course" element={<LibraryCourse />}>
+          <Route path="list" element={<LibraryCourseList />}></Route>
+          <Route path="show/:id" element={<LibraryCourseShow />}></Route>
+          <Route path="lesson" element={<LibraryLessonShow />}></Route>
         </Route>
 
-        <Route path="course" element={<StudioCourse />}>
-          <Route path="list" element={<StudioCourseList />} />
-          <Route path=":courseId/edit" element={<StudioCourseEdit />} />
+        <Route path="term/:word" element={<LibraryTerm />} />
+
+        <Route path="dict" element={<LibraryDict />}>
+          <Route path=":word" element={<LibraryDictShow />} />
+          <Route path="recent" element={<LibraryDictShow />} />
         </Route>
 
-        <Route path="dict" element={<StudioDict />}>
-          <Route path="list" element={<StudioDictList />} />
+        <Route path="anthology" element={<LibraryAnthology />}>
+          <Route path="list" element={<LibraryAnthologyList />} />
+          <Route path=":id" element={<LibraryAnthologyShow />} />
+          <Route
+            path=":id/by_channel/:tags"
+            element={<LibraryAnthologyShow />}
+          />
         </Route>
 
-        <Route path="term" element={<StudioTerm />}>
-          <Route path="list" element={<StudioTermList />} />
+        <Route path="article" element={<LibraryArticle />}>
+          <Route path=":type/:id" element={<LibraryArticleShow />} />
+          <Route path=":type/:id/:mode" element={<LibraryArticleShow />} />
+          <Route
+            path=":type/:id/:mode/:param"
+            element={<LibraryArticleShow />}
+          />
         </Route>
 
-        <Route path="article" element={<StudioArticle />}>
-          <Route path="list" element={<StudioArticleList />} />
-          <Route path=":articleid/edit" element={<StudioArticleEdit />} />
+        <Route path="discussion" element={<LibraryDiscussion />}>
+          <Route path="list" element={<LibraryDiscussionList />} />
+          <Route path="topic/:id" element={<LibraryDiscussionTopic />} />
+          <Route path="discussion/:id" element={<LibraryDiscussion />} />
         </Route>
 
-        <Route path="anthology" element={<StudioAnthology />}>
-          <Route path="list" element={<StudioAnthologyList />}></Route>
-          <Route path=":anthology_id/edit" element={<StudioAnthologyEdit />} />
+        <Route path="blog/:studio" element={<LibraryBlog />}>
+          <Route path="overview" element={<LibraryBlogOverview />} />
+          <Route path="palicanon" element={<LibraryBlogTranslation />} />
+          <Route path="course" element={<LibraryBlogCourse />} />
+          <Route path="anthology" element={<LibraryBlogAnthology />} />
+          <Route path="term" element={<LibraryBlogTerm />} />
         </Route>
 
-        <Route path="analysis" element={<StudioAnalysis />}>
-          <Route path="list" element={<StudioAnalysisList />} />
+        <Route path="studio/:studioname" element={<Studio />}>
+          <Route path="home" element={<StudioHome />} />
+          <Route path="palicanon" element={<StudioPalicanon />}></Route>
+          <Route path="recent" element={<StudioRecent />}></Route>
+
+          <Route path="channel" element={<StudioChannel />}>
+            <Route path="list" element={<StudioChannelList />} />
+            <Route path=":channelid/edit" element={<StudioChannelEdit />} />
+            <Route path=":channelId" element={<StudioChannelShow />} />
+          </Route>
+
+          <Route path="group" element={<StudioGroup />}>
+            <Route path="list" element={<StudioGroupList />} />
+            <Route path=":groupId" element={<StudioGroupShow />} />
+            <Route path=":groupId/edit" element={<StudioGroupEdit />} />
+            <Route path=":groupId/show" element={<StudioGroupShow />} />
+          </Route>
+
+          <Route path="course" element={<StudioCourse />}>
+            <Route path="list" element={<StudioCourseList />} />
+            <Route path=":courseId/edit" element={<StudioCourseEdit />} />
+          </Route>
+
+          <Route path="dict" element={<StudioDict />}>
+            <Route path="list" element={<StudioDictList />} />
+          </Route>
+
+          <Route path="term" element={<StudioTerm />}>
+            <Route path="list" element={<StudioTermList />} />
+          </Route>
+
+          <Route path="article" element={<StudioArticle />}>
+            <Route path="list" element={<StudioArticleList />} />
+            <Route path=":articleid/edit" element={<StudioArticleEdit />} />
+          </Route>
+
+          <Route path="anthology" element={<StudioAnthology />}>
+            <Route path="list" element={<StudioAnthologyList />}></Route>
+            <Route
+              path=":anthology_id/edit"
+              element={<StudioAnthologyEdit />}
+            />
+          </Route>
+
+          <Route path="analysis" element={<StudioAnalysis />}>
+            <Route path="list" element={<StudioAnalysisList />} />
+          </Route>
         </Route>
-      </Route>
-    </Routes>
+      </Routes>
+    </ConfigProvider>
   );
 };
 

+ 16 - 8
dashboard/src/components/library/HeadBar.tsx

@@ -8,6 +8,7 @@ import img_banner from "../../assets/library/images/wikipali_logo_library.svg";
 import UiLangSelect from "../general/UiLangSelect";
 import SignInAvatar from "../auth/SignInAvatar";
 import ToStudio from "../auth/ToStudio";
+import ThemeSelect from "../general/ThemeSelect";
 
 const { Header } = Layout;
 
@@ -126,13 +127,19 @@ const Widget = ({ selectedKeys = "" }: IWidgetHeadBar) => {
         paddingRight: 10,
       }}
     >
-      <Row justify="space-between">
-        <Col flex="100px">
+      <div
+        style={{
+          display: "flex",
+          width: "100%",
+          justifyContent: "space-between",
+        }}
+      >
+        <div style={{ width: 100 }}>
           <Link to="/">
             <img alt="code" style={{ height: "3em" }} src={img_banner} />
           </Link>
-        </Col>
-        <Col span={8}>
+        </div>
+        <div style={{ width: 500 }}>
           <Menu
             onClick={onClick}
             selectedKeys={[selectedKeys]}
@@ -140,15 +147,16 @@ const Widget = ({ selectedKeys = "" }: IWidgetHeadBar) => {
             theme="dark"
             items={mainMenuItems}
           />
-        </Col>
-        <Col span={4}>
+        </div>
+        <div>
           <Space>
             <ToStudio />
             <SignInAvatar />
             <UiLangSelect />
+            <ThemeSelect />
           </Space>
-        </Col>
-      </Row>
+        </div>
+      </div>
     </Header>
   );
 };

+ 26 - 9
dashboard/src/components/studio/HeadBar.tsx

@@ -5,6 +5,7 @@ import img_banner from "../../assets/studio/images/wikipali_banner.svg";
 import UiLangSelect from "../general/UiLangSelect";
 import SignInAvatar from "../auth/SignInAvatar";
 import ToLibaray from "../auth/ToLibaray";
+import ThemeSelect from "../general/ThemeSelect";
 
 const { Search } = Input;
 const { Header } = Layout;
@@ -13,28 +14,44 @@ const onSearch = (value: string) => console.log(value);
 
 const Widget = () => {
   return (
-    <Header className="header" style={{ lineHeight: "44px", height: 44 }}>
-      <Row justify="space-between">
-        <Col flex="80px">
+    <Header
+      className="header"
+      style={{
+        lineHeight: "44px",
+        height: 44,
+        paddingLeft: 10,
+        paddingRight: 10,
+      }}
+    >
+      <div
+        style={{
+          display: "flex",
+          width: "100%",
+          justifyContent: "space-between",
+        }}
+      >
+        <div style={{ width: 80 }}>
           <Link to="/">
             <img alt="code" style={{ height: 36 }} src={img_banner} />
           </Link>
-        </Col>
-        <Col span={8}>
+        </div>
+        <div style={{ width: 500, lineHeight: 44 }}>
           <Search
+            disabled
             placeholder="input search text"
             onSearch={onSearch}
             style={{ width: "100%" }}
           />
-        </Col>
-        <Col span={4}>
+        </div>
+        <div>
           <Space>
             <ToLibaray />
             <SignInAvatar />
             <UiLangSelect />
+            <ThemeSelect />
           </Space>
-        </Col>
-      </Row>
+        </div>
+      </div>
     </Header>
   );
 };

+ 9 - 0
dashboard/src/load.ts

@@ -5,6 +5,7 @@ import { get as getToken, IUser, signIn } from "./reducers/current-user";
 //import { DURATION } from "./reducers/current-user";
 import { ISite, refresh as refreshLayout } from "./reducers/layout";
 import { ISettingItem, refresh as refreshSetting } from "./reducers/setting";
+import { refresh as refreshTheme } from "./reducers/theme";
 import { get, IErrorResponse } from "./request";
 //import { GRPC_HOST,  grpc_metadata } from "./request";
 import store from "./store";
@@ -70,6 +71,14 @@ const init = () => {
     const json: ISettingItem[] = JSON.parse(setting);
     store.dispatch(refreshSetting(json));
   }
+
+  //获取用户选择的主题
+  const theme = localStorage.getItem("theme");
+  if (theme === "dark") {
+    store.dispatch(refreshTheme("dark"));
+  } else {
+    store.dispatch(refreshTheme("ant"));
+  }
 };
 
 export default init;

+ 2 - 0
dashboard/src/store.ts

@@ -11,6 +11,7 @@ import articleModeReducer from "./reducers/article-mode";
 import inlineDictReducer from "./reducers/inline-dict";
 import currentCourseReducer from "./reducers/current-course";
 import sentenceReducer from "./reducers/sentence";
+import themeReducer from "./reducers/theme";
 
 const store = configureStore({
   reducer: {
@@ -25,6 +26,7 @@ const store = configureStore({
     inlineDict: inlineDictReducer,
     currentCourse: currentCourseReducer,
     sentence: sentenceReducer,
+    theme: themeReducer,
   },
 });