2
0
Эх сурвалжийг харах

Merge remote-tracking branch 'origin/agile' into v3

Jeremy Zheng 1 жил өмнө
parent
commit
637444f669
100 өөрчлөгдсөн 2628 нэмэгдсэн , 0 устгасан
  1. 5 0
      .gitignore
  2. 25 0
      .vscode/extensions.json
  3. 15 0
      .vscode/launch.json
  4. 35 0
      .vscode/settings.json
  5. 16 0
      dashboard/.env.orig
  6. 12 0
      dashboard/.gitignore
  7. 12 0
      dashboard/README.md
  8. 101 0
      dashboard/package.json
  9. BIN
      dashboard/public/favicon.ico
  10. 106 0
      dashboard/public/index.html
  11. BIN
      dashboard/public/logo192.png
  12. BIN
      dashboard/public/logo512.png
  13. 25 0
      dashboard/public/manifest.json
  14. 3 0
      dashboard/public/robots.txt
  15. 13 0
      dashboard/src/App.css
  16. 9 0
      dashboard/src/App.test.tsx
  17. 46 0
      dashboard/src/App.tsx
  18. 380 0
      dashboard/src/Router.tsx
  19. BIN
      dashboard/src/assets/font/NotoSans/NotoSans-Black.ttf
  20. BIN
      dashboard/src/assets/font/NotoSans/NotoSans-BlackItalic.ttf
  21. BIN
      dashboard/src/assets/font/NotoSans/NotoSans-Bold.ttf
  22. BIN
      dashboard/src/assets/font/NotoSans/NotoSans-BoldItalic.ttf
  23. BIN
      dashboard/src/assets/font/NotoSans/NotoSans-ExtraBold.ttf
  24. BIN
      dashboard/src/assets/font/NotoSans/NotoSans-ExtraBoldItalic.ttf
  25. BIN
      dashboard/src/assets/font/NotoSans/NotoSans-ExtraLight.ttf
  26. BIN
      dashboard/src/assets/font/NotoSans/NotoSans-ExtraLightItalic.ttf
  27. BIN
      dashboard/src/assets/font/NotoSans/NotoSans-Italic.ttf
  28. BIN
      dashboard/src/assets/font/NotoSans/NotoSans-Light.ttf
  29. BIN
      dashboard/src/assets/font/NotoSans/NotoSans-LightItalic.ttf
  30. BIN
      dashboard/src/assets/font/NotoSans/NotoSans-Medium.ttf
  31. BIN
      dashboard/src/assets/font/NotoSans/NotoSans-MediumItalic.ttf
  32. BIN
      dashboard/src/assets/font/NotoSans/NotoSans-Regular.ttf
  33. BIN
      dashboard/src/assets/font/NotoSans/NotoSans-SemiBold.ttf
  34. BIN
      dashboard/src/assets/font/NotoSans/NotoSans-SemiBoldItalic.ttf
  35. BIN
      dashboard/src/assets/font/NotoSans/NotoSans-Thin.ttf
  36. BIN
      dashboard/src/assets/font/NotoSans/NotoSans-ThinItalic.ttf
  37. BIN
      dashboard/src/assets/font/NotoSans/NotoSansTaiTham-Regular.ttf
  38. BIN
      dashboard/src/assets/font/NotoSerif/NotoSerif-Black.ttf
  39. BIN
      dashboard/src/assets/font/NotoSerif/NotoSerif-BlackItalic.ttf
  40. BIN
      dashboard/src/assets/font/NotoSerif/NotoSerif-Bold.ttf
  41. BIN
      dashboard/src/assets/font/NotoSerif/NotoSerif-BoldItalic.ttf
  42. BIN
      dashboard/src/assets/font/NotoSerif/NotoSerif-ExtraBold.ttf
  43. BIN
      dashboard/src/assets/font/NotoSerif/NotoSerif-ExtraBoldItalic.ttf
  44. BIN
      dashboard/src/assets/font/NotoSerif/NotoSerif-ExtraLight.ttf
  45. BIN
      dashboard/src/assets/font/NotoSerif/NotoSerif-ExtraLightItalic.ttf
  46. BIN
      dashboard/src/assets/font/NotoSerif/NotoSerif-Italic.ttf
  47. BIN
      dashboard/src/assets/font/NotoSerif/NotoSerif-Light.ttf
  48. BIN
      dashboard/src/assets/font/NotoSerif/NotoSerif-LightItalic.ttf
  49. BIN
      dashboard/src/assets/font/NotoSerif/NotoSerif-Medium.ttf
  50. BIN
      dashboard/src/assets/font/NotoSerif/NotoSerif-MediumItalic.ttf
  51. BIN
      dashboard/src/assets/font/NotoSerif/NotoSerif-Regular.ttf
  52. BIN
      dashboard/src/assets/font/NotoSerif/NotoSerif-SemiBold.ttf
  53. BIN
      dashboard/src/assets/font/NotoSerif/NotoSerif-SemiBoldItalic.ttf
  54. BIN
      dashboard/src/assets/font/NotoSerif/NotoSerif-Thin.ttf
  55. BIN
      dashboard/src/assets/font/NotoSerif/NotoSerif-ThinItalic.ttf
  56. BIN
      dashboard/src/assets/font/Noto_Sans_Myanmar/NotoSansMyanmar-Black.ttf
  57. BIN
      dashboard/src/assets/font/Noto_Sans_Myanmar/NotoSansMyanmar-Bold.ttf
  58. BIN
      dashboard/src/assets/font/Noto_Sans_Myanmar/NotoSansMyanmar-ExtraBold.ttf
  59. BIN
      dashboard/src/assets/font/Noto_Sans_Myanmar/NotoSansMyanmar-ExtraLight.ttf
  60. BIN
      dashboard/src/assets/font/Noto_Sans_Myanmar/NotoSansMyanmar-Light.ttf
  61. BIN
      dashboard/src/assets/font/Noto_Sans_Myanmar/NotoSansMyanmar-Medium.ttf
  62. BIN
      dashboard/src/assets/font/Noto_Sans_Myanmar/NotoSansMyanmar-Regular.ttf
  63. BIN
      dashboard/src/assets/font/Noto_Sans_Myanmar/NotoSansMyanmar-SemiBold.ttf
  64. BIN
      dashboard/src/assets/font/Noto_Sans_Myanmar/NotoSansMyanmar-Thin.ttf
  65. 93 0
      dashboard/src/assets/font/Noto_Sans_Myanmar/OFL.txt
  66. BIN
      dashboard/src/assets/font/Noto_Sans_Tai_Tham/NotoSansTaiTham-Bold.ttf
  67. BIN
      dashboard/src/assets/font/Noto_Sans_Tai_Tham/NotoSansTaiTham-Medium.ttf
  68. BIN
      dashboard/src/assets/font/Noto_Sans_Tai_Tham/NotoSansTaiTham-Regular.ttf
  69. BIN
      dashboard/src/assets/font/Noto_Sans_Tai_Tham/NotoSansTaiTham-SemiBold.ttf
  70. BIN
      dashboard/src/assets/font/Noto_Sans_Tai_Tham/NotoSansTaiTham-VariableFont_wght.ttf
  71. 93 0
      dashboard/src/assets/font/Noto_Sans_Tai_Tham/OFL.txt
  72. 66 0
      dashboard/src/assets/font/Noto_Sans_Tai_Tham/README.txt
  73. BIN
      dashboard/src/assets/font/Noto_Serif_Myanmar/NotoSerifMyanmar-Black.ttf
  74. BIN
      dashboard/src/assets/font/Noto_Serif_Myanmar/NotoSerifMyanmar-Bold.ttf
  75. BIN
      dashboard/src/assets/font/Noto_Serif_Myanmar/NotoSerifMyanmar-ExtraBold.ttf
  76. BIN
      dashboard/src/assets/font/Noto_Serif_Myanmar/NotoSerifMyanmar-ExtraLight.ttf
  77. BIN
      dashboard/src/assets/font/Noto_Serif_Myanmar/NotoSerifMyanmar-Light.ttf
  78. BIN
      dashboard/src/assets/font/Noto_Serif_Myanmar/NotoSerifMyanmar-Medium.ttf
  79. BIN
      dashboard/src/assets/font/Noto_Serif_Myanmar/NotoSerifMyanmar-Regular.ttf
  80. BIN
      dashboard/src/assets/font/Noto_Serif_Myanmar/NotoSerifMyanmar-SemiBold.ttf
  81. BIN
      dashboard/src/assets/font/Noto_Serif_Myanmar/NotoSerifMyanmar-Thin.ttf
  82. 93 0
      dashboard/src/assets/font/Noto_Serif_Myanmar/OFL.txt
  83. 457 0
      dashboard/src/assets/font/main.css
  84. BIN
      dashboard/src/assets/font/taitham/tai-tham-kh-new-v3.ttf
  85. BIN
      dashboard/src/assets/general/images/logo_mps.png
  86. 22 0
      dashboard/src/assets/general/images/wikipali_login_page.svg
  87. 89 0
      dashboard/src/assets/general/images/wikipali_logo.svg
  88. 310 0
      dashboard/src/assets/icon/index.tsx
  89. 62 0
      dashboard/src/assets/library/images/books.svg
  90. BIN
      dashboard/src/assets/library/images/download_bg.png
  91. 127 0
      dashboard/src/assets/library/images/teachers.svg
  92. 51 0
      dashboard/src/assets/library/images/wikipali_logo_library.svg
  93. BIN
      dashboard/src/assets/nut/code.png
  94. 22 0
      dashboard/src/assets/studio/images/wikipali_banner.svg
  95. 12 0
      dashboard/src/components/README.md
  96. 59 0
      dashboard/src/components/admin/HeadBar.tsx
  97. 80 0
      dashboard/src/components/admin/LeftSider.tsx
  98. 64 0
      dashboard/src/components/admin/api/ApiDelayHour.tsx
  99. 83 0
      dashboard/src/components/admin/api/ApiGauge.tsx
  100. 42 0
      dashboard/src/components/admin/relation/CaseSelect.tsx

+ 5 - 0
.gitignore

@@ -0,0 +1,5 @@
+tmp
+*.log
+/.VSCodeCounter
+config.toml
+/.vscode/launch.json

+ 25 - 0
.vscode/extensions.json

@@ -0,0 +1,25 @@
+{
+  "recommendations": [
+    "ms-vscode.cpptools-extension-pack",
+    "ms-python.python",
+    "golang.go",
+    "rust-lang.rust-analyzer",
+    "bmewburn.vscode-intelephense-client",
+    "redhat.ansible",
+    "redhat.vscode-xml",
+    "redhat.vscode-yaml",
+    "tamasfe.even-better-toml",
+    "gaborv.flatbuffers",
+    "yzhang.markdown-all-in-one",
+    "zxh404.vscode-proto3",
+    "ms-vscode-remote.remote-ssh",
+    "ms-azuretools.vscode-docker",
+    "vscode-icons-team.vscode-icons",
+    "akamud.vscode-theme-onedark",
+    "dbaeumer.vscode-eslint",
+    "esbenp.prettier-vscode",
+    "editorconfig.editorconfig",
+    "gruntfuggly.todo-tree",
+    "streetsidesoftware.code-spell-checker"
+  ]
+}

+ 15 - 0
.vscode/launch.json

@@ -0,0 +1,15 @@
+{
+  // 使用 IntelliSense 了解相关属性。
+  // 悬停以查看现有属性的描述。
+  // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
+  "version": "0.2.0",
+  "configurations": [
+    {
+      "type": "chrome",
+      "request": "launch",
+      "name": "Launch Chrome against localhost",
+      "url": "http://127.0.0.1:3000/my",
+      "webRoot": "${workspaceFolder}"
+    }
+  ]
+}

+ 35 - 0
.vscode/settings.json

@@ -0,0 +1,35 @@
+{
+  "files.autoSave": "onFocusChange",
+  "files.insertFinalNewline": true,
+  "workbench.colorTheme": "Atom One Dark",
+  "editor.formatOnSave": true,
+  "editor.fontFamily": "source code pro",
+  "editor.mouseWheelZoom": true,
+  "editor.codeActionsOnSave": {
+    "source.fixAll.eslint": true
+  },
+  "editor.defaultFormatter": "esbenp.prettier-vscode",
+  // https://code.visualstudio.com/docs/setup/linux#_visual-studio-code-is-unable-to-watch-for-file-changes-in-this-large-workspace-error-enospc
+  "files.watcherExclude": {
+    "**/.git/**": true,
+    "**/node_modules/**": true
+  },
+  "[cpp]": {
+    "editor.defaultFormatter": "ms-vscode.cpptools"
+  },
+  "[rust]": {
+    "editor.defaultFormatter": "rust-lang.rust-analyzer"
+  },
+  "[proto3]": {
+    "editor.defaultFormatter": "zxh404.vscode-proto3"
+  },
+  "[xml]": {
+    "editor.defaultFormatter": "redhat.vscode-xml"
+  },
+  "[python]": {
+    "editor.defaultFormatter": "ms-python.python"
+  },
+  "[php]": {
+    "editor.defaultFormatter": "bmewburn.vscode-intelephense-client"
+  }
+}

+ 16 - 0
dashboard/.env.orig

@@ -0,0 +1,16 @@
+GENERATE_SOURCEMAP=false
+BROWSER=none
+PUBLIC_URL=/my
+HOST=0.0.0.0
+PORT=20139
+
+REACT_APP_DEFAULT_LOCALE=zh-Hans
+REACT_APP_LANGUAGES=en-US,zh-Hans,zh-Hant
+REACT_APP_ENABLE_LOCAL_TOKEN=true
+REACT_APP_TOKEN_KEY="token"
+REACT_APP_DOCUMENTS_SERVER=https://documents.wikipali.org
+REACT_APP_RPC_SERVER=https://rpc.wikipali.org
+REACT_APP_ASSETS_SERVER=https://assets.wikipali.org
+REACT_APP_API_SERVER=https://www.wikipali.org
+REACT_APP_ICP_CODE=
+REACT_APP_QUESTIONNAIRE_LINK=

+ 12 - 0
dashboard/.gitignore

@@ -0,0 +1,12 @@
+/node_modules/
+/yarn.lock
+
+# production
+/build/
+
+# misc
+.env
+.env.local
+.env.development.local
+.env.test.local
+.env.production.local

+ 12 - 0
dashboard/README.md

@@ -0,0 +1,12 @@
+# 前端框架
+
+## 目录
+
+- `public` 
+- `src`
+  - `components` 所有网页用的组件
+  - `locales` 所有国际化语言包
+  - `pages` 前端页面
+
+nut目录为练习用途。里面的内容可能会被删除。**线上不要使用**。
+

+ 101 - 0
dashboard/package.json

@@ -0,0 +1,101 @@
+{
+  "name": "dashboard",
+  "version": "0.1.0",
+  "private": true,
+  "dependencies": {
+    "@ant-design/charts": "^1.4.2",
+    "@ant-design/pro-components": "^2.3.32",
+    "@fortawesome/fontawesome-free": "^6.2.0",
+    "@reduxjs/toolkit": "^1.9.0",
+    "@testing-library/jest-dom": "^5.14.1",
+    "@testing-library/react": "^13.0.0",
+    "@testing-library/user-event": "^13.2.1",
+    "@types/diff": "^5.0.2",
+    "@types/google-protobuf": "^3.15.6",
+    "@types/jest": "^27.0.1",
+    "@types/js-cookie": "^3.0.2",
+    "@types/lodash": "^4.14.189",
+    "@types/marked": "^4.0.7",
+    "@types/node": "^16.7.13",
+    "@types/react": "^18.0.0",
+    "@types/react-big-calendar": "^0.38.2",
+    "@types/react-color": "^3.0.6",
+    "@types/react-copy-to-clipboard": "^5.0.4",
+    "@types/react-dom": "^18.0.0",
+    "@types/react-pdf": "^5.7.4",
+    "@types/video.js": "^7.3.50",
+    "@uiw/react-md-editor": "^3.19.7",
+    "antd": "^4.24.10",
+    "dayjs": "^1.11.6",
+    "diff": "^5.1.0",
+    "dinero.js": "^2.0.0-alpha.9",
+    "emoji-mart": "^5.3.2",
+    "famfamfam-flags": "^1.0.0",
+    "famfamfam-mini": "^1.0.0",
+    "famfamfam-silk": "^1.0.0",
+    "filesize": "^10.0.5",
+    "google-map-react": "^2.2.0",
+    "google-protobuf": "^3.21.2",
+    "grpc-web": "^1.4.2",
+    "js-cookie": "^3.0.1",
+    "jwt-decode": "^3.1.2",
+    "lodash": "^4.17.21",
+    "marked": "^4.2.2",
+    "mermaid": "^9.2.2",
+    "qrcode.react": "^3.1.0",
+    "react": "^18.2.0",
+    "react-big-calendar": "^1.5.2",
+    "react-color": "^2.19.3",
+    "react-copy-to-clipboard": "^5.1.0",
+    "react-dom": "^18.2.0",
+    "react-draggable": "^4.4.5",
+    "react-dropzone": "^14.2.3",
+    "react-highlight-words": "^0.18.0",
+    "react-hook-form": "^7.39.4",
+    "react-image-crop": "^10.0.8",
+    "react-intl": "^6.2.1",
+    "react-json-view": "^1.21.3",
+    "react-markdown": "^8.0.3",
+    "react-number-format": "^5.1.1",
+    "react-pdf": "^6.0.3",
+    "react-player": "^2.11.0",
+    "react-quill": "^2.0.0",
+    "react-redux": "^8.0.5",
+    "react-router-dom": "^6.4.3",
+    "react-scripts": "5.0.1",
+    "react-sparklines": "^1.7.0",
+    "react-syntax-highlighter": "^15.5.0",
+    "timezones-list": "^3.0.1",
+    "tslog": "^4.9.2",
+    "typescript": "^4.4.2",
+    "video.js": "^7.20.3",
+    "web-vitals": "^2.1.0"
+  },
+  "scripts": {
+    "start": "react-scripts start",
+    "build": "react-scripts build",
+    "test": "react-scripts test",
+    "eject": "react-scripts eject"
+  },
+  "eslintConfig": {
+    "extends": [
+      "react-app",
+      "react-app/jest"
+    ]
+  },
+  "browserslist": {
+    "production": [
+      ">0.2%",
+      "not dead",
+      "not op_mini all"
+    ],
+    "development": [
+      "last 1 chrome version",
+      "last 1 firefox version",
+      "last 1 safari version"
+    ]
+  },
+  "devDependencies": {
+    "@babel/plugin-proposal-private-property-in-object": "^7.21.11"
+  }
+}

BIN
dashboard/public/favicon.ico


+ 106 - 0
dashboard/public/index.html

@@ -0,0 +1,106 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8" />
+    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
+    <meta name="viewport" content="width=device-width, initial-scale=1" />
+    <meta name="theme-color" content="#000000" />
+    <meta name="description" content="IAPT Pali Canon Platform" />
+    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
+    <!--
+      manifest.json provides metadata used when your web app is installed on a
+      user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
+    -->
+    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
+    <!--
+      Notice the use of %PUBLIC_URL% in the tags above.
+      It will be replaced with the URL of the `public` folder during the build.
+      Only files inside the `public` folder can be referenced from the HTML.
+
+      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
+      work correctly both with client-side routing and a non-root public URL.
+      Learn how to configure a non-root public URL by running `npm run build`.
+    -->
+    <title>Wikipāḷi Library</title>
+  </head>
+  <body>
+    <noscript>You need to enable JavaScript to run this app.</noscript>
+    <style>
+      .lds-ellipsis {
+        display: inline-block;
+        position: relative;
+        width: 80px;
+        height: 80px;
+      }
+      .lds-ellipsis div {
+        position: absolute;
+        top: 33px;
+        width: 13px;
+        height: 13px;
+        border-radius: 50%;
+        background: burlywood;
+        animation-timing-function: cubic-bezier(0, 1, 1, 0);
+      }
+      .lds-ellipsis div:nth-child(1) {
+        left: 8px;
+        animation: lds-ellipsis1 0.6s infinite;
+      }
+      .lds-ellipsis div:nth-child(2) {
+        left: 8px;
+        animation: lds-ellipsis2 0.6s infinite;
+      }
+      .lds-ellipsis div:nth-child(3) {
+        left: 32px;
+        animation: lds-ellipsis2 0.6s infinite;
+      }
+      .lds-ellipsis div:nth-child(4) {
+        left: 56px;
+        animation: lds-ellipsis3 0.6s infinite;
+      }
+      @keyframes lds-ellipsis1 {
+        0% {
+          transform: scale(0);
+        }
+        100% {
+          transform: scale(1);
+        }
+      }
+      @keyframes lds-ellipsis3 {
+        0% {
+          transform: scale(1);
+        }
+        100% {
+          transform: scale(0);
+        }
+      }
+      @keyframes lds-ellipsis2 {
+        0% {
+          transform: translate(0, 0);
+        }
+        100% {
+          transform: translate(24px, 0);
+        }
+      }
+    </style>
+    <div id="root">
+      <div style="width: 100%; text-align: center; margin-top: 10em">
+        <div class="lds-ellipsis">
+          <div></div>
+          <div></div>
+          <div></div>
+          <div></div>
+        </div>
+      </div>
+    </div>
+    <!--
+      This HTML file is a template.
+      If you open it directly in the browser, you will see an empty page.
+
+      You can add webfonts, meta tags, or analytics to this file.
+      The build step will place the bundled scripts into the <body> tag.
+
+      To begin the development, run `npm start` or `yarn start`.
+      To create a production bundle, use `npm run build` or `yarn build`.
+    -->
+  </body>
+</html>

BIN
dashboard/public/logo192.png


BIN
dashboard/public/logo512.png


+ 25 - 0
dashboard/public/manifest.json

@@ -0,0 +1,25 @@
+{
+  "short_name": "React App",
+  "name": "Create React App Sample",
+  "icons": [
+    {
+      "src": "favicon.ico",
+      "sizes": "64x64 32x32 24x24 16x16",
+      "type": "image/x-icon"
+    },
+    {
+      "src": "logo192.png",
+      "type": "image/png",
+      "sizes": "192x192"
+    },
+    {
+      "src": "logo512.png",
+      "type": "image/png",
+      "sizes": "512x512"
+    }
+  ],
+  "start_url": ".",
+  "display": "standalone",
+  "theme_color": "#000000",
+  "background_color": "#ffffff"
+}

+ 3 - 0
dashboard/public/robots.txt

@@ -0,0 +1,3 @@
+# https://www.robotstxt.org/robotstxt.html
+User-agent: *
+Disallow:

+ 13 - 0
dashboard/src/App.css

@@ -0,0 +1,13 @@
+@import "~antd/dist/antd.min.css";
+@import "~react-quill/dist/quill.snow.css";
+@import "~video.js/dist/video-js.css";
+@import "./assets/font/main.css";
+@import "./theme/antd.dark.css";
+@import "./theme/antpro.dark.css";
+
+body {
+  margin: 0;
+  padding: 0;
+  font-family: "Noto Sans", "NotoSans-ExtraLight", "Noto Sans SC",
+    "Noto Sans TC", "Noto Sans Myanmar", "ATaiThamKHNewV3-Normal";
+}

+ 9 - 0
dashboard/src/App.test.tsx

@@ -0,0 +1,9 @@
+import React from 'react';
+import { render, screen } from '@testing-library/react';
+import App from './App';
+
+test('renders learn react link', () => {
+  render(<App />);
+  const linkElement = screen.getByText(/learn react/i);
+  expect(linkElement).toBeInTheDocument();
+});

+ 46 - 0
dashboard/src/App.tsx

@@ -0,0 +1,46 @@
+import { BrowserRouter } from "react-router-dom";
+import { ConfigProvider } from "antd";
+import { IntlProvider } from "react-intl";
+import { Provider } from "react-redux";
+import { pdfjs } from "react-pdf";
+import mermaid from "mermaid";
+import { enableMapSet } from "immer";
+
+import Router from "./Router";
+import store from "./store";
+import locales, {
+  get as getLocale,
+  DEFAULT as DEFAULT_LOCALE,
+} from "./locales";
+import { API_HOST } from "./request";
+import onLoad from "./load";
+
+import "./App.css";
+
+pdfjs.GlobalWorkerOptions.workerSrc = `${API_HOST}/assets/pdf.worker.min.js`;
+mermaid.initialize({ startOnLoad: true });
+enableMapSet();
+
+onLoad();
+const lang = getLocale();
+const i18n = locales(lang);
+
+function Widget() {
+  return (
+    <Provider store={store}>
+      <IntlProvider
+        messages={i18n.messages}
+        locale={lang}
+        defaultLocale={DEFAULT_LOCALE}
+      >
+        <ConfigProvider locale={i18n.antd}>
+          <BrowserRouter basename={process.env.PUBLIC_URL}>
+            <Router />
+          </BrowserRouter>
+        </ConfigProvider>
+      </IntlProvider>
+    </Provider>
+  );
+}
+
+export default Widget;

+ 380 - 0
dashboard/src/Router.tsx

@@ -0,0 +1,380 @@
+import { Route, Routes } from "react-router-dom";
+
+import Anonymous from "./layouts/anonymous";
+import Dashboard from "./layouts/dashboard";
+
+import Users from "./pages/users";
+import UsersSignUp from "./pages/users/sign-up";
+
+import NutUsersSignIn from "./pages/nut/users/sign-in";
+import NutUsersSignUp from "./pages/nut/users/sign-up";
+import NutUsersUnlockNew from "./pages/nut/users/unlock/new";
+import NutUsersUnlockVerify from "./pages/nut/users/unlock/verify";
+import NutUsersResetPassword from "./pages/nut/users/reset-password";
+import NutUsersForgotPassword from "./pages/nut/users/forgot-password";
+import NutUsersChangePassword from "./pages/nut/users/change-password";
+import NutUsersAccountInfo from "./pages/nut/users/account-info";
+import NutUsersLogs from "./pages/nut/users/logs";
+import NutForbidden from "./pages/nut/forbidden";
+import NutNotFound from "./pages/nut/not-found";
+import NutSwitchLanguage from "./pages/nut/switch-languages";
+import NutHome from "./pages/nut";
+
+import AdminHome from "./pages/admin";
+import AdminRelation from "./pages/admin/relation";
+import AdminRelationList from "./pages/admin/relation/list";
+import AdminNissayaEnding from "./pages/admin/nissaya-ending";
+import AdminNissayaEndingList from "./pages/admin/nissaya-ending/list";
+import AdminDictionary from "./pages/admin/dictionary";
+import AdminDictionaryList from "./pages/admin/dictionary/list";
+import AdminApi from "./pages/admin/api";
+import AdminApiDashboard from "./pages/admin/api/dashboard";
+
+import AdminUsers from "./pages/admin/users";
+import AdminUsersList from "./pages/admin/users/list";
+import AdminUsersShow from "./pages/admin/users/show";
+
+import AdminInvite from "./pages/admin/invite";
+import AdminInviteList from "./pages/admin/invite/list";
+
+import LibraryHome from "./pages/library";
+
+import LibraryCommunity from "./pages/library/community";
+import LibraryCommunityList from "./pages/library/community/list";
+
+import LibraryPalicanon from "./pages/library/palicanon";
+import LibraryPalicanonByPath from "./pages/library/palicanon/bypath";
+import LibraryPalicanonChapter from "./pages/library/palicanon/chapter";
+
+import LibraryCourse from "./pages/library/course";
+import LibraryCourseList from "./pages/library/course/list";
+import LibraryCourseShow from "./pages/library/course/course";
+
+import LibraryTerm from "./pages/library/term";
+import LibraryTermShow from "./pages/library/term/show";
+import LibraryTermList from "./pages/library/term/list";
+
+import LibraryDict from "./pages/library/dict";
+import LibraryDictShow from "./pages/library/dict/show";
+
+import LibraryAnthology from "./pages/library/anthology";
+import LibraryAnthologyShow from "./pages/library/anthology/show";
+import LibraryAnthologyList from "./pages/library/anthology/list";
+
+import LibraryArticle from "./pages/library/article";
+import LibraryArticleShow from "./pages/library/article/show";
+
+import LibraryNissaya from "./pages/library/nissaya";
+import LibraryNissayaShow from "./pages/library/nissaya/show";
+
+import LibraryBlog from "./pages/library/blog";
+import LibraryBlogOverview from "./pages/library/blog/overview";
+import LibraryBlogTranslation from "./pages/library/blog/translation";
+import LibraryBlogCourse from "./pages/library/blog/course";
+import LibraryBlogAnthology from "./pages/library/blog/anthology";
+import LibraryBlogTerm from "./pages/library/blog/term";
+
+import LibraryDiscussion from "./pages/library/discussion";
+import LibraryDiscussionList from "./pages/library/discussion/list";
+import LibraryDiscussionTopic from "./pages/library/discussion/topic";
+import LibraryDiscussionShow from "./pages/library/discussion/show";
+
+import LibrarySearch from "./pages/library/search";
+import LibrarySearchKey from "./pages/library/search/search";
+
+import LibraryDownload from "./pages/library/download";
+import LibraryDownloadPage from "./pages/library/download/Download";
+
+import LibraryNotifications from "./pages/library/notifications";
+import LibraryNotificationsList from "./pages/library/notifications/list";
+
+import Studio from "./pages/studio";
+import StudioHome from "./pages/studio/home";
+
+import StudioPalicanon from "./pages/studio/palicanon";
+
+import StudioRecent from "./pages/studio/recent";
+import StudioRecentList from "./pages/studio/recent/list";
+
+import StudioTransfer from "./pages/studio/transfer";
+import StudioTransferList from "./pages/studio/transfer/list";
+
+import StudioChannel from "./pages/studio/channel";
+import StudioChannelList from "./pages/studio/channel/list";
+import StudioChannelSetting from "./pages/studio/channel/setting";
+import StudioChannelShow from "./pages/studio/channel/show";
+
+import StudioGroup from "./pages/studio/group";
+import StudioGroupList from "./pages/studio/group/list";
+import StudioGroupEdit from "./pages/studio/group/edit";
+import StudioGroupShow from "./pages/studio/group/show";
+
+import StudioCourse from "./pages/studio/course";
+import StudioCourseList from "./pages/studio/course/list";
+import StudioCourseEdit from "./pages/studio/course/edit";
+
+import StudioDict from "./pages/studio/dict";
+import StudioDictList from "./pages/studio/dict/list";
+
+import StudioTerm from "./pages/studio/term";
+import StudioTermList from "./pages/studio/term/list";
+
+import StudioArticle from "./pages/studio/article";
+import StudioArticleList from "./pages/studio/article/list";
+import StudioArticleEdit from "./pages/studio/article/edit";
+import StudioArticleCreate from "./pages/studio/article/create";
+
+import StudioAnthology from "./pages/studio/anthology";
+import StudioAnthologyList from "./pages/studio/anthology/list";
+import StudioAnthologyEdit from "./pages/studio/anthology/edit";
+
+import StudioAttachment from "./pages/studio/attachment";
+import StudioAttachmentList from "./pages/studio/attachment/list";
+
+import StudioSetting from "./pages/studio/setting";
+
+import StudioAnalysis from "./pages/studio/analysis";
+import StudioAnalysisList from "./pages/studio/analysis/list";
+
+import StudioInvite from "./pages/studio/invite";
+import StudioInviteList from "./pages/studio/invite/list";
+
+import StudioTag from "./pages/studio/tags";
+import StudioTagList from "./pages/studio/tags/list";
+import StudioTagShow from "./pages/studio/tags/show";
+import StudioTagEdit from "./pages/studio/tags/edit";
+
+import { ConfigProvider } from "antd";
+import { useAppSelector } from "./hooks";
+import { currTheme } from "./reducers/theme";
+
+const Widget = () => {
+  const theme = useAppSelector(currTheme);
+  return (
+    <ConfigProvider prefixCls={theme}>
+      <Routes>
+        <Route path="admin" element={<AdminHome />}>
+          <Route path="api" element={<AdminApi />}>
+            <Route path="dashboard" element={<AdminApiDashboard />} />
+          </Route>
+          <Route path="relation" element={<AdminRelation />}>
+            <Route path="list" element={<AdminRelationList />} />
+          </Route>
+          <Route path="nissaya-ending" element={<AdminNissayaEnding />}>
+            <Route path="list" element={<AdminNissayaEndingList />} />
+            <Route path="list/:relation" element={<AdminNissayaEndingList />} />
+          </Route>
+          <Route path="dictionary" element={<AdminDictionary />}>
+            <Route path="list" element={<AdminDictionaryList />} />
+          </Route>
+          <Route path="users" element={<AdminUsers />}>
+            <Route path="list" element={<AdminUsersList />} />
+            <Route path="show/:id" element={<AdminUsersShow />} />
+          </Route>
+          <Route path="invite" element={<AdminInvite />}>
+            <Route path="list" element={<AdminInviteList />} />
+          </Route>
+        </Route>
+
+        <Route path="users" element={<Users />}>
+          <Route path="sign-up" element={<UsersSignUp />} />
+        </Route>
+        <Route path="anonymous" element={<Anonymous />}>
+          <Route path="users">
+            <Route path="sign-in" element={<NutUsersSignIn />} />
+            <Route path="sign-up/:token" 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>
+
+        <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>
+        <Route path="notifications" element={<LibraryNotifications />}>
+          <Route path="list" element={<LibraryNotificationsList />} />
+        </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>
+        <Route path="term" element={<LibraryTerm />}>
+          <Route path="list/:word" element={<LibraryTermList />}></Route>
+          <Route path="show/:id" element={<LibraryTermShow />}></Route>
+        </Route>
+
+        <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" element={<LibraryArticleShow />} />
+          <Route path=":type/:id" element={<LibraryArticleShow />} />
+          <Route path=":type/:id/:mode" element={<LibraryArticleShow />} />
+          <Route
+            path=":type/:id/:mode/:param"
+            element={<LibraryArticleShow />}
+          />
+        </Route>
+
+        <Route path="nissaya" element={<LibraryNissaya />}>
+          <Route path="ending/:ending" element={<LibraryNissayaShow />} />
+        </Route>
+
+        <Route path="discussion" element={<LibraryDiscussion />}>
+          <Route path="list" element={<LibraryDiscussionList />} />
+          <Route path="topic/:id" element={<LibraryDiscussionTopic />} />
+          <Route path="show/:type/:id" element={<LibraryDiscussionShow />} />
+        </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="search" element={<LibrarySearch />}>
+          <Route path="home" element={<LibrarySearchKey />} />
+          <Route path="key/:key" element={<LibrarySearchKey />} />
+        </Route>
+
+        <Route path="download" element={<LibraryDownload />}>
+          <Route path="download" element={<LibraryDownloadPage />} />
+        </Route>
+
+        <Route path="studio/:studioname" element={<Studio />}>
+          <Route path="home" element={<StudioHome />} />
+          <Route path="palicanon" element={<StudioPalicanon />}></Route>
+          <Route path="recent" element={<StudioRecent />}>
+            <Route path="list" element={<StudioRecentList />} />
+          </Route>
+
+          <Route path="channel" element={<StudioChannel />}>
+            <Route path="list" element={<StudioChannelList />} />
+            <Route
+              path=":channelId/setting"
+              element={<StudioChannelSetting />}
+            />
+            <Route
+              path=":channelId/setting/:type"
+              element={<StudioChannelSetting />}
+            />
+            <Route
+              path=":channelId/setting/:type/:id"
+              element={<StudioChannelSetting />}
+            />
+            <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="attachment" element={<StudioAttachment />}>
+            <Route path="list" element={<StudioAttachmentList />} />
+          </Route>
+
+          <Route path="article" element={<StudioArticle />}>
+            <Route path="list" element={<StudioArticleList />} />
+            <Route path="edit/:articleId" element={<StudioArticleEdit />} />
+            <Route path="create" element={<StudioArticleCreate />} />
+          </Route>
+
+          <Route path="anthology" element={<StudioAnthology />}>
+            <Route path="list" element={<StudioAnthologyList />}></Route>
+            <Route
+              path=":anthology_id/edit"
+              element={<StudioAnthologyEdit />}
+            />
+          </Route>
+          <Route path="setting" element={<StudioSetting />} />
+
+          <Route path="exp" element={<StudioAnalysis />}>
+            <Route path="list" element={<StudioAnalysisList />} />
+          </Route>
+          <Route path="invite" element={<StudioInvite />}>
+            <Route path="list" element={<StudioInviteList />} />
+          </Route>
+
+          <Route path="tags" element={<StudioTag />}>
+            <Route path="list" element={<StudioTagList />} />
+            <Route path=":id/list" element={<StudioTagShow />} />
+            <Route path=":tagId/edit" element={<StudioTagEdit />} />
+          </Route>
+
+          <Route path="transfer" element={<StudioTransfer />}>
+            <Route path="list" element={<StudioTransferList />} />
+          </Route>
+        </Route>
+      </Routes>
+    </ConfigProvider>
+  );
+};
+
+export default Widget;

BIN
dashboard/src/assets/font/NotoSans/NotoSans-Black.ttf


BIN
dashboard/src/assets/font/NotoSans/NotoSans-BlackItalic.ttf


BIN
dashboard/src/assets/font/NotoSans/NotoSans-Bold.ttf


BIN
dashboard/src/assets/font/NotoSans/NotoSans-BoldItalic.ttf


BIN
dashboard/src/assets/font/NotoSans/NotoSans-ExtraBold.ttf


BIN
dashboard/src/assets/font/NotoSans/NotoSans-ExtraBoldItalic.ttf


BIN
dashboard/src/assets/font/NotoSans/NotoSans-ExtraLight.ttf


BIN
dashboard/src/assets/font/NotoSans/NotoSans-ExtraLightItalic.ttf


BIN
dashboard/src/assets/font/NotoSans/NotoSans-Italic.ttf


BIN
dashboard/src/assets/font/NotoSans/NotoSans-Light.ttf


BIN
dashboard/src/assets/font/NotoSans/NotoSans-LightItalic.ttf


BIN
dashboard/src/assets/font/NotoSans/NotoSans-Medium.ttf


BIN
dashboard/src/assets/font/NotoSans/NotoSans-MediumItalic.ttf


BIN
dashboard/src/assets/font/NotoSans/NotoSans-Regular.ttf


BIN
dashboard/src/assets/font/NotoSans/NotoSans-SemiBold.ttf


BIN
dashboard/src/assets/font/NotoSans/NotoSans-SemiBoldItalic.ttf


BIN
dashboard/src/assets/font/NotoSans/NotoSans-Thin.ttf


BIN
dashboard/src/assets/font/NotoSans/NotoSans-ThinItalic.ttf


BIN
dashboard/src/assets/font/NotoSans/NotoSansTaiTham-Regular.ttf


BIN
dashboard/src/assets/font/NotoSerif/NotoSerif-Black.ttf


BIN
dashboard/src/assets/font/NotoSerif/NotoSerif-BlackItalic.ttf


BIN
dashboard/src/assets/font/NotoSerif/NotoSerif-Bold.ttf


BIN
dashboard/src/assets/font/NotoSerif/NotoSerif-BoldItalic.ttf


BIN
dashboard/src/assets/font/NotoSerif/NotoSerif-ExtraBold.ttf


BIN
dashboard/src/assets/font/NotoSerif/NotoSerif-ExtraBoldItalic.ttf


BIN
dashboard/src/assets/font/NotoSerif/NotoSerif-ExtraLight.ttf


BIN
dashboard/src/assets/font/NotoSerif/NotoSerif-ExtraLightItalic.ttf


BIN
dashboard/src/assets/font/NotoSerif/NotoSerif-Italic.ttf


BIN
dashboard/src/assets/font/NotoSerif/NotoSerif-Light.ttf


BIN
dashboard/src/assets/font/NotoSerif/NotoSerif-LightItalic.ttf


BIN
dashboard/src/assets/font/NotoSerif/NotoSerif-Medium.ttf


BIN
dashboard/src/assets/font/NotoSerif/NotoSerif-MediumItalic.ttf


BIN
dashboard/src/assets/font/NotoSerif/NotoSerif-Regular.ttf


BIN
dashboard/src/assets/font/NotoSerif/NotoSerif-SemiBold.ttf


BIN
dashboard/src/assets/font/NotoSerif/NotoSerif-SemiBoldItalic.ttf


BIN
dashboard/src/assets/font/NotoSerif/NotoSerif-Thin.ttf


BIN
dashboard/src/assets/font/NotoSerif/NotoSerif-ThinItalic.ttf


BIN
dashboard/src/assets/font/Noto_Sans_Myanmar/NotoSansMyanmar-Black.ttf


BIN
dashboard/src/assets/font/Noto_Sans_Myanmar/NotoSansMyanmar-Bold.ttf


BIN
dashboard/src/assets/font/Noto_Sans_Myanmar/NotoSansMyanmar-ExtraBold.ttf


BIN
dashboard/src/assets/font/Noto_Sans_Myanmar/NotoSansMyanmar-ExtraLight.ttf


BIN
dashboard/src/assets/font/Noto_Sans_Myanmar/NotoSansMyanmar-Light.ttf


BIN
dashboard/src/assets/font/Noto_Sans_Myanmar/NotoSansMyanmar-Medium.ttf


BIN
dashboard/src/assets/font/Noto_Sans_Myanmar/NotoSansMyanmar-Regular.ttf


BIN
dashboard/src/assets/font/Noto_Sans_Myanmar/NotoSansMyanmar-SemiBold.ttf


BIN
dashboard/src/assets/font/Noto_Sans_Myanmar/NotoSansMyanmar-Thin.ttf


+ 93 - 0
dashboard/src/assets/font/Noto_Sans_Myanmar/OFL.txt

@@ -0,0 +1,93 @@
+Copyright 2012 Google Inc. All Rights Reserved.
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded, 
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.

BIN
dashboard/src/assets/font/Noto_Sans_Tai_Tham/NotoSansTaiTham-Bold.ttf


BIN
dashboard/src/assets/font/Noto_Sans_Tai_Tham/NotoSansTaiTham-Medium.ttf


BIN
dashboard/src/assets/font/Noto_Sans_Tai_Tham/NotoSansTaiTham-Regular.ttf


BIN
dashboard/src/assets/font/Noto_Sans_Tai_Tham/NotoSansTaiTham-SemiBold.ttf


BIN
dashboard/src/assets/font/Noto_Sans_Tai_Tham/NotoSansTaiTham-VariableFont_wght.ttf


+ 93 - 0
dashboard/src/assets/font/Noto_Sans_Tai_Tham/OFL.txt

@@ -0,0 +1,93 @@
+Copyright 2012 Google Inc. All Rights Reserved.
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded, 
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.

+ 66 - 0
dashboard/src/assets/font/Noto_Sans_Tai_Tham/README.txt

@@ -0,0 +1,66 @@
+Noto Sans Tai Tham Variable Font
+================================
+
+This download contains Noto Sans Tai Tham as both a variable font and static fonts.
+
+Noto Sans Tai Tham is a variable font with this axis:
+  wght
+
+This means all the styles are contained in a single file:
+  NotoSansTaiTham-VariableFont_wght.ttf
+
+If your app fully supports variable fonts, you can now pick intermediate styles
+that aren’t available as static fonts. Not all apps support variable fonts, and
+in those cases you can use the static font files for Noto Sans Tai Tham:
+  static/NotoSansTaiTham-Regular.ttf
+  static/NotoSansTaiTham-Medium.ttf
+  static/NotoSansTaiTham-SemiBold.ttf
+  static/NotoSansTaiTham-Bold.ttf
+
+Get started
+-----------
+
+1. Install the font files you want to use
+
+2. Use your app's font picker to view the font family and all the
+available styles
+
+Learn more about variable fonts
+-------------------------------
+
+  https://developers.google.com/web/fundamentals/design-and-ux/typography/variable-fonts
+  https://variablefonts.typenetwork.com
+  https://medium.com/variable-fonts
+
+In desktop apps
+
+  https://theblog.adobe.com/can-variable-fonts-illustrator-cc
+  https://helpx.adobe.com/nz/photoshop/using/fonts.html#variable_fonts
+
+Online
+
+  https://developers.google.com/fonts/docs/getting_started
+  https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/Variable_Fonts_Guide
+  https://developer.microsoft.com/en-us/microsoft-edge/testdrive/demos/variable-fonts
+
+Installing fonts
+
+  MacOS: https://support.apple.com/en-us/HT201749
+  Linux: https://www.google.com/search?q=how+to+install+a+font+on+gnu%2Blinux
+  Windows: https://support.microsoft.com/en-us/help/314960/how-to-install-or-remove-a-font-in-windows
+
+Android Apps
+
+  https://developers.google.com/fonts/docs/android
+  https://developer.android.com/guide/topics/ui/look-and-feel/downloadable-fonts
+
+License
+-------
+Please read the full license text (OFL.txt) to understand the permissions,
+restrictions and requirements for usage, redistribution, and modification.
+
+You can use them freely in your products & projects - print or digital,
+commercial or otherwise.
+
+This isn't legal advice, please consider consulting a lawyer and see the full
+license for all details.

BIN
dashboard/src/assets/font/Noto_Serif_Myanmar/NotoSerifMyanmar-Black.ttf


BIN
dashboard/src/assets/font/Noto_Serif_Myanmar/NotoSerifMyanmar-Bold.ttf


BIN
dashboard/src/assets/font/Noto_Serif_Myanmar/NotoSerifMyanmar-ExtraBold.ttf


BIN
dashboard/src/assets/font/Noto_Serif_Myanmar/NotoSerifMyanmar-ExtraLight.ttf


BIN
dashboard/src/assets/font/Noto_Serif_Myanmar/NotoSerifMyanmar-Light.ttf


BIN
dashboard/src/assets/font/Noto_Serif_Myanmar/NotoSerifMyanmar-Medium.ttf


BIN
dashboard/src/assets/font/Noto_Serif_Myanmar/NotoSerifMyanmar-Regular.ttf


BIN
dashboard/src/assets/font/Noto_Serif_Myanmar/NotoSerifMyanmar-SemiBold.ttf


BIN
dashboard/src/assets/font/Noto_Serif_Myanmar/NotoSerifMyanmar-Thin.ttf


+ 93 - 0
dashboard/src/assets/font/Noto_Serif_Myanmar/OFL.txt

@@ -0,0 +1,93 @@
+Copyright 2012 Google Inc. All Rights Reserved.
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded, 
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.

+ 457 - 0
dashboard/src/assets/font/main.css

@@ -0,0 +1,457 @@
+/*@import url(//fonts.googleapis.com/earlyaccess/notosanstc.css);*/
+/*@import url(//fonts.googleapis.com/earlyaccess/notosanssc.css);*/
+
+/*Pāli Roma*/
+
+@font-face {
+  font-family: "Noto Sans";
+  font-style: normal;
+  font-weight: 100;
+  src: local("Noto Sans Thin"),
+    url(./NotoSans/NotoSans-Thin.ttf) format("truetype");
+  font-display: fallback;
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Sans";
+  font-style: normal;
+  font-weight: 300;
+  src: local("Noto Sans Light"),
+    url(./NotoSans/NotoSans-Light.ttf) format("truetype");
+  font-display: fallback;
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Sans";
+  font-style: normal;
+  font-weight: 400;
+  src: local("Noto Sans Regular"),
+    url(./NotoSans/NotoSans-Regular.ttf) format("truetype");
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Sans";
+  font-style: normal;
+  font-weight: 500;
+  src: local("Noto Sans Medium"),
+    url(./NotoSans/NotoSans-Medium.ttf) format("truetype");
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Sans";
+  font-style: normal;
+  font-weight: 700;
+  src: local("Noto Sans Bold"),
+    url(./NotoSans/NotoSans-Bold.ttf) format("truetype");
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Sans";
+  font-style: normal;
+  font-weight: 900;
+  src: local("Noto Sans Black"),
+    url(./NotoSans/NotoSans-Black.ttf) format("truetype");
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Sans";
+  font-style: italic;
+  font-weight: 100;
+  src: local("Noto Sans Thin Italic"),
+    url(./NotoSans/NotoSans-ThinItalic.ttf) format("truetype");
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Sans";
+  font-style: italic;
+  font-weight: 300;
+  src: local("Noto Sans Light Italic"),
+    url(./NotoSans/NotoSans-LightItalic.ttf) format("truetype");
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Sans";
+  font-style: italic;
+  font-weight: 400;
+  src: local("Noto Sans Italic"),
+    url(./NotoSans/NotoSans-Italic.ttf) format("truetype");
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Sans";
+  font-style: italic;
+  font-weight: 500;
+  src: local("Noto Sans Medium Italic"),
+    url(./NotoSans/NotoSans-MediumItalic.ttf) format("truetype");
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Sans";
+  font-style: italic;
+  font-weight: 700;
+  src: local("Noto Sans Bold Italic"),
+    url(./NotoSans/NotoSans-BoldItalic.ttf) format("truetype");
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Sans";
+  font-style: italic;
+  font-weight: 900;
+  src: local("Noto Sans Black Italic"),
+    url(./NotoSans/NotoSans-BlackItalic.ttf) format("truetype");
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Serif";
+  font-style: normal;
+  font-weight: 100;
+  src: local("Noto Serif Thin"),
+    url(./NotoSerif/NotoSerif-Thin.ttf) format("truetype");
+  font-display: fallback;
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Serif";
+  font-style: normal;
+  font-weight: 300;
+  src: local("Noto Serif Light"),
+    url(./NotoSerif/NotoSerif-Light.ttf) format("truetype");
+  font-display: fallback;
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Serif";
+  font-style: normal;
+  font-weight: 400;
+  src: local("Noto Serif Regular"),
+    url(./NotoSerif/NotoSerif-Regular.ttf) format("truetype");
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Serif";
+  font-style: normal;
+  font-weight: 500;
+  src: local("Noto Serif Medium"),
+    url(./NotoSerif/NotoSerif-Medium.ttf) format("truetype");
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Serif";
+  font-style: normal;
+  font-weight: 600;
+  src: local("Noto Serif SemiBold"),
+    url(./NotoSerif/NotoSerif-SemiBold.ttf) format("truetype");
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Serif";
+  font-style: normal;
+  font-weight: 700;
+  src: local("Noto Serif Bold"),
+    url(./NotoSerif/NotoSerif-Bold.ttf) format("truetype");
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Serif";
+  font-style: normal;
+  font-weight: 900;
+  src: local("Noto Serif Black"),
+    url(./NotoSerif/NotoSerif-Black.ttf) format("truetype");
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Serif";
+  font-style: italic;
+  font-weight: 100;
+  src: local("Noto Serif Thin Italic"),
+    url(./NotoSerif/NotoSerif-ThinItalic.ttf) format("truetype");
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Serif";
+  font-style: italic;
+  font-weight: 300;
+  src: local("Noto Serif Light Italic"),
+    url(./NotoSerif/NotoSerif-LightItalic.ttf) format("truetype");
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Serif";
+  font-style: italic;
+  font-weight: 400;
+  src: local("Noto Serif Italic"),
+    url(./NotoSerif/NotoSerif-Italic.ttf) format("truetype");
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Serif";
+  font-style: italic;
+  font-weight: 500;
+  src: local("Noto Serif Medium Italic"),
+    url(./NotoSerif/NotoSerif-MediumItalic.ttf) format("truetype");
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Serif";
+  font-style: italic;
+  font-weight: 600;
+  src: local("Noto Serif SemiBold Italic"),
+    url(./NotoSerif/NotoSerif-SemiBoldItalic.ttf) format("truetype");
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Serif";
+  font-style: italic;
+  font-weight: 700;
+  src: local("Noto Serif Bold Italic"),
+    url(./NotoSerif/NotoSerif-BoldItalic.ttf) format("truetype");
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Serif";
+  font-style: italic;
+  font-weight: 900;
+  src: local("Noto Serif Black Italic"),
+    url(./NotoSerif/NotoSerif-BlackItalic.ttf) format("truetype");
+  font-display: fallback;
+}
+
+/*Noto Sans Myanmar*/
+@font-face {
+  font-family: "Noto Sans Myanmar";
+  font-style: normal;
+  font-weight: 100;
+  src: local("Noto Sans Myanmar Thin"),
+    url(./Noto_Sans_Myanmar/NotoSansMyanmar-Thin.ttf) format("truetype");
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Sans Myanmar";
+  font-style: normal;
+  font-weight: 200;
+  src: local("Noto Sans Myanmar ExtraLight"),
+    url(./Noto_Sans_Myanmar/NotoSansMyanmar-ExtraLight.ttf) format("truetype");
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Sans Myanmar";
+  font-style: normal;
+  font-weight: 300;
+  src: local("Noto Sans Myanmar Light"),
+    url(./Noto_Sans_Myanmar/NotoSansMyanmar-Light.ttf) format("truetype");
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Sans Myanmar";
+  font-style: normal;
+  font-weight: 400;
+  src: local("Noto Sans Myanmar Regular"),
+    url(./Noto_Sans_Myanmar/NotoSansMyanmar-Regular.ttf) format("truetype");
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Sans Myanmar";
+  font-style: normal;
+  font-weight: 500;
+  src: local("Noto Sans Myanmar Medium"),
+    url(./Noto_Sans_Myanmar/NotoSansMyanmar-Medium.ttf) format("truetype");
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Sans Myanmar";
+  font-style: normal;
+  font-weight: 600;
+  src: local("Noto Sans Myanmar SemiBold"),
+    url(./Noto_Sans_Myanmar/NotoSansMyanmar-SemiBold.ttf) format("truetype");
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Sans Myanmar";
+  font-style: normal;
+  font-weight: 700;
+  src: local("Noto Sans Myanmar Bold"),
+    url(./Noto_Sans_Myanmar/NotoSansMyanmar-Bold.ttf) format("truetype");
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Sans Myanmar";
+  font-style: normal;
+  font-weight: 800;
+  src: local("Noto Sans Myanmar ExtraBold"),
+    url(./Noto_Sans_Myanmar/NotoSansMyanmar-ExtraBold.ttf) format("truetype");
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Sans Myanmar";
+  font-style: normal;
+  font-weight: 900;
+  src: local("Noto Sans Myanmar Black"),
+    url(./Noto_Sans_Myanmar/NotoSansMyanmar-Black.ttf) format("truetype");
+  font-display: fallback;
+}
+/*傣仂文*/
+@font-face {
+  font-family: "ATaiThamKHNewV3-Normal";
+  font-style: normal;
+  font-weight: 400;
+  src: local("A Tai Tham KH New V3"),
+    url(./taitham/tai-tham-kh-new-v3.ttf) format("truetype");
+  font-display: fallback;
+}
+
+/*中文繁體*/
+
+@font-face {
+  font-family: "Noto Sans TC";
+  font-style: normal;
+  font-weight: 300;
+  src: local("Noto Sans TC Light"), local("Noto Sans CJK TC Light"),
+    local("Source Han Sans TWHK Light");
+  /*url(../../font/NotoSansTC/NotoSansCJKtc-Light.otf) format('opentype'),*/
+  /*url(../../font/NotoSansTC/NotoSansTC-Light.woff) format('woff')*/
+}
+
+@font-face {
+  font-family: "Noto Sans TC";
+  font-style: normal;
+  font-weight: 400;
+  src: local("Noto Sans TC Regular"), local("Noto Sans CJK TC Regular"),
+    local("Source Han Sans TWHK Regular");
+  /*url(../../font/NotoSansTC/NotoSansCJKtc-Regular.otf) format('opentype'),*/
+  /*url(../../font/NotoSansTC/NotoSansTC-Regular.woff) format('woff');*/
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Sans TC";
+  font-style: normal;
+  font-weight: 500;
+  src: local("Noto Sans TC Medium"), local("Noto Sans CJK TC Medium"),
+    local("Source Han Sans TWHK Medium");
+  /*url(../../font/NotoSansTC/NotoSansCJKtc-Medium.otf) format('opentype'),*/
+  /*url(../../font/NotoSansTC/NotoSansTC-Medium.woff) format('woff');*/
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Sans TC";
+  font-style: normal;
+  font-weight: 700;
+  src: local("Noto Sans TC Bold"), local("Noto Sans CJK TC Bold"),
+    local("Source Han Sans TWHK Bold");
+  /*url(../../font/NotoSansTC/NotoSansCJKtc-Bold.otf) format('opentype'),*/
+  /*url(../../font/NotoSansTC/NotoSansTC-Bold.woff) format('woff');*/
+  font-display: fallback;
+}
+
+/*中文简体*/
+
+@font-face {
+  font-family: "Noto Sans SC";
+  font-style: normal;
+  font-weight: 300;
+  src: local("Noto Sans SC Light"), local("Noto Sans CJK SC Light"),
+    local("Source Han Sans CN Light");
+  /*url(../../font/NotoSansSC/NotoSansCJKsc-Light.otf) format('opentype'),
+    url(../../font/NotoSansSC/NotoSansSC-Light.woff) format('woff')*/
+}
+
+@font-face {
+  font-family: "Noto Sans SC";
+  font-style: normal;
+  font-weight: 400;
+  src: local("Noto Sans SC Regular"), local("Noto Sans CJK SC Regular"),
+    local("Source Han Sans CN Regular");
+  /*url(../../font/NotoSansSC/NotoSansCJKsc-Regular.otf) format('opentype'),
+    url(../../font/NotoSansSC/NotoSansSC-Regular.woff) format('woff');*/
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Sans SC";
+  font-style: normal;
+  font-weight: 500;
+  src: local("Noto Sans SC Medium"), local("Noto Sans CJK SC Medium"),
+    local("Source Han Sans CN Medium");
+  /*url(../../font/NotoSansSC/NotoSansCJKsc-Medium.otf) format('opentype'),
+    url(../../font/NotoSansSC/NotoSansSC-Medium.woff) format('woff');*/
+  font-display: fallback;
+}
+
+@font-face {
+  font-family: "Noto Sans SC";
+  font-style: normal;
+  font-weight: 700;
+  src: local("Noto Sans SC Bold"), local("Noto Sans CJK SC Bold"),
+    local("Source Han Sans CN Bold");
+  /*url(../../font/NotoSansSC/NotoSansCJKsc-Bold.otf) format('opentype'),
+    url(../../font/NotoSansSC/NotoSansSC-Bold.woff) format('woff');*/
+  font-display: fallback;
+}
+
+.font_ch {
+  font-family: "Noto Sans TC", "Noto Sans SC", Arial, Verdana;
+  font-style: normal;
+}
+
+.font_pali {
+  font-family: "Noto Sans", Arial, Verdana;
+  font-style: normal;
+}
+
+.font_m {
+  font-family: "Noto Sans", "Noto Sans TC", "Noto Sans SC", Arial, Verdana;
+  font-weight: 500;
+  font-style: normal;
+}
+
+.font_r {
+  font-family: "Noto Sans", "Noto Sans TC", "Noto Sans SC", Arial, Verdana;
+  font-weight: 400;
+  font-style: normal;
+}
+
+.font_l {
+  font-family: "Noto Sans", "Noto Sans TC", "Noto Sans SC", Arial, Verdana;
+  font-weight: 300;
+  font-style: normal;
+}
+
+.font_t {
+  font-family: "Noto Sans", "Noto Sans TC", "Noto Sans SC", Arial, Verdana;
+  font-weight: 100;
+  font-style: normal;
+}

BIN
dashboard/src/assets/font/taitham/tai-tham-kh-new-v3.ttf


BIN
dashboard/src/assets/general/images/logo_mps.png


+ 22 - 0
dashboard/src/assets/general/images/wikipali_login_page.svg

@@ -0,0 +1,22 @@
+<svg id="logo_login" xmlns="http://www.w3.org/2000/svg"  viewBox="0 0 336.454 152">
+  <g id="Group_12" data-name="Group 12" transform="translate(-396 -319)">
+    <g id="Group_2" data-name="Group 2" transform="translate(396 319)">
+      <g id="Group_1" data-name="Group 1" transform="translate(96.697 30.301)">
+        <path id="Path_1" data-name="Path 1" d="M258.951,153.873a2.9,2.9,0,0,1-1.8-.6,2.8,2.8,0,0,1-1.039-1.543l-8.443-31.183a2.022,2.022,0,0,1-.062-.5,1.673,1.673,0,0,1,.379-1.008,1.6,1.6,0,0,1,1.32-.629h3.023a2.765,2.765,0,0,1,1.765.6,2.869,2.869,0,0,1,1.008,1.543l4.159,17.074q.064.252,1.953,9.954a.113.113,0,0,0,.129.125.112.112,0,0,0,.125-.125q2.267-9.7,2.331-9.954l4.413-17.074a2.908,2.908,0,0,1,2.773-2.14h2.456a2.908,2.908,0,0,1,2.769,2.14l4.534,17.074q.375,1.576,1.164,4.882t1.23,5.073a.112.112,0,0,0,.125.125.206.206,0,0,0,.191-.125q.187-1.136.883-4.569t1.133-5.385l4.034-17.074a2.908,2.908,0,0,1,2.773-2.14H294.8a1.618,1.618,0,0,1,1.324.629,1.772,1.772,0,0,1,.379,1.07,1.99,1.99,0,0,1-.062.441l-8,31.183a2.8,2.8,0,0,1-1.039,1.543,2.876,2.876,0,0,1-1.8.6h-4.413a2.765,2.765,0,0,1-1.765-.6,2.855,2.855,0,0,1-1.008-1.543L274.447,136.3q-.633-2.519-2.2-10.079a.232.232,0,0,0-.223-.125.222.222,0,0,0-.219.125q-1.259,6.678-2.206,10.146l-3.78,15.371a2.855,2.855,0,0,1-1.008,1.543,2.743,2.743,0,0,1-1.765.6h-4.093Z" transform="translate(-247.61 -102.469)" fill="#fff"/>
+        <path id="Path_2" data-name="Path 2" d="M399.972,86.4a4.869,4.869,0,0,1-3.4,1.23,4.758,4.758,0,0,1-3.37-1.23,4.069,4.069,0,0,1-1.32-3.12A4.145,4.145,0,0,1,393.2,80.1a4.752,4.752,0,0,1,3.37-1.23,4.845,4.845,0,0,1,3.4,1.23,4.1,4.1,0,0,1,1.355,3.179A4.027,4.027,0,0,1,399.972,86.4Zm-4.819,43.375a2.254,2.254,0,0,1-2.269-2.269V96.514a2.117,2.117,0,0,1,.66-1.543,2.186,2.186,0,0,1,1.609-.66h2.835a2.193,2.193,0,0,1,1.609.66,2.119,2.119,0,0,1,.664,1.543v30.992a2.26,2.26,0,0,1-2.273,2.269Z" transform="translate(-335.539 -78.37)" fill="#fff"/>
+        <path id="Path_3" data-name="Path 3" d="M445.639,128.994a2.253,2.253,0,0,1-2.269-2.269V79.793a2.13,2.13,0,0,1,.66-1.543,2.186,2.186,0,0,1,1.609-.66h2.71a2.214,2.214,0,0,1,1.609.66,2.115,2.115,0,0,1,.66,1.543v30.871c0,.043.031.062.094.062a.224.224,0,0,0,.16-.062L463.345,95.23a4.484,4.484,0,0,1,3.655-1.7h3.718a.947.947,0,0,1,.914.6.935.935,0,0,1-.156,1.1L461.018,107.7a.409.409,0,0,0,0,.441l12.094,18.96a1.2,1.2,0,0,1,.191.629,1.179,1.179,0,0,1-.191.629,1.1,1.1,0,0,1-1.07.629h-3.589a3.8,3.8,0,0,1-3.4-1.89l-8.318-13.922c-.082-.168-.187-.187-.316-.062l-5.6,6.49a.823.823,0,0,0-.191.5v6.615a2.254,2.254,0,0,1-2.269,2.269h-2.714Z" transform="translate(-366.921 -77.59)" fill="#fff"/>
+        <path id="Path_4" data-name="Path 4" d="M545.4,86.4a4.869,4.869,0,0,1-3.4,1.23,4.752,4.752,0,0,1-3.37-1.23,4.069,4.069,0,0,1-1.32-3.12,4.145,4.145,0,0,1,1.32-3.179A4.758,4.758,0,0,1,542,78.87a4.845,4.845,0,0,1,3.4,1.23,4.1,4.1,0,0,1,1.355,3.179A4.04,4.04,0,0,1,545.4,86.4Zm-4.819,43.375a2.26,2.26,0,0,1-2.273-2.269V96.514a2.106,2.106,0,0,1,.664-1.543,2.186,2.186,0,0,1,1.609-.66h2.835a2.193,2.193,0,0,1,1.609.66,2.115,2.115,0,0,1,.66,1.543v30.992a2.254,2.254,0,0,1-2.269,2.269Z" transform="translate(-424.176 -78.37)" fill="#fff"/>
+        <path id="Path_5" data-name="Path 5" d="M591.075,167.236a2.253,2.253,0,0,1-2.265-2.265V119.612a2.253,2.253,0,0,1,2.265-2.269h1.574a2.488,2.488,0,0,1,1.671.629,2.784,2.784,0,0,1,.914,1.574l.187,1.574c.043.086.094.129.156.129a.234.234,0,0,0,.16-.062q5.67-4.727,10.837-4.725a12.237,12.237,0,0,1,10.364,4.882q3.685,4.885,3.687,13.2a24.893,24.893,0,0,1-1.261,8.1,17.127,17.127,0,0,1-3.4,6.049,15.857,15.857,0,0,1-4.881,3.687,13.081,13.081,0,0,1-5.764,1.324q-4.534,0-9.134-3.843a.077.077,0,0,0-.125,0,.182.182,0,0,0-.062.129l.187,5.8v9.2a2.253,2.253,0,0,1-2.269,2.265h-2.839Zm12.852-19.655a7.724,7.724,0,0,0,6.491-3.433q2.519-3.433,2.519-9.482,0-12.032-8.314-12.032-3.843,0-8.252,4.159a.6.6,0,0,0-.191.441v16.82a.6.6,0,0,0,.191.441A11.6,11.6,0,0,0,603.927,147.581Z" transform="translate(-455.564 -101.28)" fill="#fff"/>
+        <path id="Path_6" data-name="Path 6" d="M697.7,134.522a10.445,10.445,0,0,1-7.529-2.8,10.46,10.46,0,0,1,2.081-16.191q5.008-3.116,15.968-4.378c.168,0,.25-.1.25-.316q-.252-7.428-6.74-7.432a17.534,17.534,0,0,0-8.377,2.456,2.118,2.118,0,0,1-1.64.219,1.987,1.987,0,0,1-1.32-1.039l-.629-1.133a2.339,2.339,0,0,1-.219-1.73,2.015,2.015,0,0,1,1.039-1.355A25.533,25.533,0,0,1,702.994,97.3q6.491,0,9.7,3.905t3.214,11.149v19.089a2.26,2.26,0,0,1-2.273,2.269h-1.574a2.471,2.471,0,0,1-1.668-.629,2.74,2.74,0,0,1-.914-1.574l-.25-1.765c-.043-.082-.094-.129-.16-.129s-.113.043-.156.129Q703.244,134.522,697.7,134.522ZM695.3,90.362a2.253,2.253,0,0,1-2.269-2.269v-.5A2.253,2.253,0,0,1,695.3,85.32h15.433A2.253,2.253,0,0,1,713,87.589v.5a2.253,2.253,0,0,1-2.265,2.269Zm4.663,38.306q3.907,0,8.318-3.909a.681.681,0,0,0,.187-.5v-8.127c0-.211-.082-.293-.25-.25q-7.5.943-10.646,2.866a5.723,5.723,0,0,0-3.152,5.01,4.458,4.458,0,0,0,1.511,3.718A6.324,6.324,0,0,0,699.967,128.668Z" transform="translate(-515.555 -82.301)" fill="#fff"/>
+        <path id="Path_7" data-name="Path 7" d="M796.443,129.811q-3.907,0-5.639-2.331t-1.734-6.807V79.793a2.119,2.119,0,0,1,.664-1.543,2.186,2.186,0,0,1,1.609-.66h2.835a2.208,2.208,0,0,1,1.609.66,2.119,2.119,0,0,1,.664,1.543v41.263a2.744,2.744,0,0,0,1.008,2.519c.082.043.269.148.566.316s.5.293.629.379.293.2.5.344a1.693,1.693,0,0,1,.473.473,1.072,1.072,0,0,1,.156.566l.25,1.386a1.808,1.808,0,0,1,.062.441,2.351,2.351,0,0,1-.379,1.324,1.94,1.94,0,0,1-1.449.945C797.681,129.791,797.072,129.811,796.443,129.811Z" transform="translate(-577.618 -77.59)" fill="#fff"/>
+        <path id="Path_8" data-name="Path 8" d="M845.452,86.4a4.869,4.869,0,0,1-3.4,1.23,4.752,4.752,0,0,1-3.37-1.23,4.069,4.069,0,0,1-1.32-3.12,4.145,4.145,0,0,1,1.32-3.179,4.752,4.752,0,0,1,3.37-1.23,4.845,4.845,0,0,1,3.4,1.23,4.1,4.1,0,0,1,1.355,3.179A4.04,4.04,0,0,1,845.452,86.4Zm-4.819,43.375a2.254,2.254,0,0,1-2.269-2.269V96.514a2.117,2.117,0,0,1,.66-1.543,2.186,2.186,0,0,1,1.609-.66h2.835a2.193,2.193,0,0,1,1.609.66,2.119,2.119,0,0,1,.664,1.543v30.992a2.26,2.26,0,0,1-2.273,2.269Z" transform="translate(-607.05 -78.37)" fill="#fff"/>
+      </g>
+      <path id="Path_9" data-name="Path 9" d="M127.853,155.309a3.752,3.752,0,0,1-3.753-3.753V138c0-21.139,10.126-33.265,27.786-33.265a3.753,3.753,0,0,1,0,7.506c-13.457,0-20.284,8.666-20.284,25.763V151.56A3.745,3.745,0,0,1,127.853,155.309Z" transform="translate(-75.636 -63.837)" fill="#f1ca23"/>
+      <path id="Path_10" data-name="Path 10" d="M146.943,223.7a3.753,3.753,0,1,1,0-7.506c7.318,0,12.434-9.8,12.434-23.83v-40.3a3.753,3.753,0,0,1,7.506,0v40.3C166.879,214.011,156.866,223.7,146.943,223.7Z" transform="translate(-87.271 -90.392)" fill="#f1ca23"/>
+      <path id="Path_11" data-name="Path 11" d="M86.483,91.472a3.752,3.752,0,0,1-3.753-3.753V3.753a3.753,3.753,0,0,1,7.506,0v83.97A3.751,3.751,0,0,1,86.483,91.472Z" transform="translate(-50.422)" fill="#f1ca23"/>
+      <path id="Path_12" data-name="Path 12" d="M45.113,91.472a3.752,3.752,0,0,1-3.753-3.753V3.753a3.753,3.753,0,0,1,7.506,0v83.97A3.751,3.751,0,0,1,45.113,91.472Z" transform="translate(-25.208)" fill="#f1ca23"/>
+      <path id="Path_13" data-name="Path 13" d="M3.753,91.472A3.752,3.752,0,0,1,0,87.719V3.753a3.753,3.753,0,0,1,7.506,0v83.97A3.756,3.756,0,0,1,3.753,91.472Z" fill="#f1ca23"/>
+    </g>
+    <text id="studio" transform="translate(639 461)" fill="#fff" font-size="33" font-family="NotoSans-ExtraLight, Noto Sans" font-weight="200"><tspan x="0" y="0">studio</tspan></text>
+  </g>
+</svg>

+ 89 - 0
dashboard/src/assets/general/images/wikipali_logo.svg

@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 24.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.0" id="wikipali_logo" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
+	 y="0px" viewBox="0 0 100 50" style="enable-background:new 0 0 100 50;" xml:space="preserve">
+<g id="圖層_1">
+	<g id="Group_12" transform="translate(-396 -320)">
+		<g id="Group_2" transform="translate(396 320)">
+			<g id="Group_1" transform="translate(39.472 12.369)">
+				<g id="Path_1">
+					<path style="fill:#FFFFFF;" d="M-5.9,19.5c-0.2,0-0.3-0.1-0.5-0.2c-0.1-0.1-0.2-0.2-0.3-0.4l-2.2-8.2v-0.1c0-0.1,0-0.2,0.1-0.3
+						c0.1-0.1,0.2-0.2,0.3-0.2h0.8c0.2,0,0.3,0.1,0.5,0.2c0.1,0.1,0.2,0.2,0.3,0.4l1.1,4.5c0,0,0.2,0.9,0.5,2.6l0,0l0,0l0,0l0,0
+						c0.4-1.7,0.6-2.6,0.6-2.6l1.2-4.5c0.1-0.3,0.4-0.6,0.7-0.6h0.6c0.3,0,0.6,0.2,0.7,0.6l1.2,4.5c0.1,0.3,0.2,0.7,0.3,1.3
+						c0.1,0.6,0.2,1,0.3,1.3l0,0l0,0c0,0,0,0,0.1,0c0-0.2,0.1-0.6,0.2-1.2c0.3-0.6,0.4-1,0.5-1.4l1.1-4.5c0.1-0.3,0.4-0.6,0.7-0.6
+						h0.7c0.1,0,0.3,0.1,0.3,0.2c0,0.1,0.1,0.2,0.1,0.3v0.1l-2.1,8.2c0,0.2-0.1,0.3-0.3,0.4c-0.1,0.1-0.3,0.2-0.5,0.2H0
+						c-0.2,0-0.3-0.1-0.5-0.2c-0.1-0.1-0.2-0.2-0.3-0.4l-1-4.1c-0.1-0.4-0.3-1.3-0.6-2.7c0,0,0,0-0.1,0c0,0,0,0-0.1,0
+						c-0.2,1.2-0.4,2.1-0.6,2.7l-1,4.1c0,0.2-0.1,0.3-0.3,0.4c-0.1,0.1-0.3,0.2-0.5,0.2H-5.9L-5.9,19.5z"/>
+				</g>
+				<g id="Path_2">
+					<path style="fill:#FFFFFF;" d="M8.1,8.1C7.8,8.3,7.5,8.4,7.2,8.4S6.6,8.3,6.3,8.1C6.1,7.9,5.9,7.6,5.9,7.3S6,6.7,6.2,6.5
+						c0.2-0.2,0.6-0.3,0.9-0.3c0.3,0,0.7,0.1,0.9,0.3C8.2,6.7,8.4,7,8.4,7.3C8.4,7.6,8.3,7.9,8.1,8.1z M6.8,19.5
+						c-0.3,0-0.6-0.3-0.6-0.6l0,0v-8.2c0-0.2,0.1-0.3,0.2-0.4c0.1-0.1,0.3-0.2,0.4-0.2h0.7c0.2,0,0.3,0.1,0.4,0.2
+						c0.1,0.1,0.2,0.3,0.2,0.4v8.2c0,0.3-0.3,0.6-0.6,0.6l0,0H6.8z"/>
+				</g>
+				<g id="Path_3">
+					<path style="fill:#FFFFFF;" d="M11.8,19.5c-0.3,0-0.6-0.3-0.6-0.6l0,0V6.5c0-0.2,0.1-0.3,0.2-0.4c0.1-0.1,0.3-0.2,0.4-0.2h0.7
+						c0.2,0,0.3,0.1,0.4,0.2c0.1,0.1,0.2,0.3,0.2,0.4v8.1l0,0l0,0l3.3-4.1c0.2-0.3,0.6-0.5,1-0.4h1c0.1,0,0.2,0.1,0.2,0.2
+						c0.1,0.1,0,0.2,0,0.3l-2.8,3.3V14l3.2,5c0,0,0,0.1,0.1,0.2c0,0.1,0,0.1-0.1,0.2s-0.2,0.2-0.3,0.2h-0.9c-0.4,0-0.7-0.2-0.9-0.5
+						l-2.2-3.7c0,0,0,0-0.1,0l-1.5,1.7c0,0,0,0.1-0.1,0.1v1.7c0,0.3-0.3,0.6-0.6,0.6l0,0L11.8,19.5z"/>
+				</g>
+				<g id="Path_4">
+					<path style="fill:#FFFFFF;" d="M23,8.1c-0.2,0.2-0.6,0.3-0.9,0.3s-0.6-0.1-0.9-0.3c-0.2-0.2-0.3-0.5-0.3-0.8s0.1-0.6,0.3-0.8
+						c0.2-0.2,0.6-0.3,0.9-0.3s0.7,0.1,0.9,0.3c0.2,0.2,0.4,0.5,0.4,0.8C23.4,7.6,23.3,7.9,23,8.1z M21.8,19.5
+						c-0.3,0-0.6-0.3-0.6-0.6l0,0v-8.2c0-0.2,0.1-0.3,0.2-0.4c0.1-0.1,0.3-0.2,0.4-0.2h0.7c0.2,0,0.3,0.1,0.4,0.2
+						c0.1,0.1,0.2,0.3,0.2,0.4v8.2c0,0.3-0.3,0.6-0.6,0.6l0,0H21.8z"/>
+				</g>
+				<g id="Path_5">
+					<path style="fill:#FFFFFF;" d="M26.8,23.3c-0.3,0-0.6-0.3-0.6-0.6l0,0v-12c0-0.3,0.3-0.6,0.6-0.6l0,0h0.4
+						c0.2,0,0.3,0.1,0.4,0.2c0.1,0.1,0.2,0.3,0.2,0.4v0.4l0,0l0,0c0.8-0.7,1.8-1.2,2.9-1.2c1.1,0,2.1,0.4,2.7,1.3c0.7,1,1,2.2,1,3.5
+						c0,0.7-0.1,1.4-0.3,2.1c-0.2,0.6-0.5,1.1-0.9,1.6c-0.4,0.4-0.8,0.7-1.3,1c-0.5,0.2-1,0.3-1.5,0.3c-0.9,0-1.8-0.4-2.4-1l0,0l0,0
+						l0,0v1.5v2.4c0,0.3-0.3,0.6-0.6,0.6l0,0L26.8,23.3L26.8,23.3z M30.2,18.2c0.7,0,1.3-0.3,1.7-0.9c0.5-0.7,0.7-1.6,0.7-2.5
+						c0-2.1-0.7-3.2-2.2-3.2c-0.8,0.1-1.6,0.5-2.2,1.1l-0.1,0.1v4.4c0,0,0,0.1,0.1,0.1C28.8,17.8,29.5,18.1,30.2,18.2L30.2,18.2z"/>
+				</g>
+				<g id="Path_6">
+					<path style="fill:#FFFFFF;" d="M39.1,19.7c-0.7,0-1.4-0.2-2-0.7c-1.1-1.1-1-2.8,0.1-3.9c0.1-0.1,0.3-0.3,0.5-0.4
+						c1.3-0.7,2.7-1.1,4.2-1.2c0,0,0.1,0,0.1-0.1c0-1.3-0.6-2-1.8-2c-0.8,0-1.5,0.2-2.2,0.6c-0.1,0.1-0.3,0.1-0.4,0.1
+						c-0.2,0-0.3-0.1-0.3-0.3L37,11.6c-0.1-0.1-0.1-0.3-0.1-0.5s0.1-0.3,0.3-0.4c1-0.6,2.1-0.9,3.3-0.9c1-0.1,1.9,0.3,2.6,1
+						c0.6,0.9,0.9,1.9,0.8,2.9v5c0,0.3-0.3,0.6-0.6,0.6l0,0h-0.4c-0.2,0-0.3-0.1-0.4-0.2c-0.1-0.1-0.2-0.3-0.2-0.4l-0.1-0.5l0,0l0,0
+						C41.3,19.2,40.2,19.7,39.1,19.7z M38.5,8.1c-0.3,0-0.6-0.3-0.6-0.6l0,0V7.3c0-0.3,0.3-0.6,0.6-0.6l0,0h4.1
+						c0.3,0,0.6,0.3,0.6,0.6l0,0v0.1c0,0.3-0.3,0.6-0.6,0.6l0,0h-4.1V8.1z M39.7,18.2c0.8-0.1,1.6-0.4,2.2-1c0,0,0.1-0.1,0-0.1V15
+						c0-0.1,0-0.1-0.1-0.1c-1,0.1-1.9,0.3-2.8,0.8c-0.5,0.3-0.8,0.8-0.8,1.3c0,0.4,0.1,0.7,0.4,1C38.9,18.1,39.3,18.2,39.7,18.2
+						L39.7,18.2z"/>
+				</g>
+				<g id="Path_7">
+					<path style="fill:#FFFFFF;" d="M48.8,19.7c-0.6,0.1-1.1-0.2-1.5-0.6c-0.3-0.5-0.5-1.2-0.5-1.8V6.5c0-0.2,0.1-0.3,0.2-0.4
+						c0.1-0.1,0.3-0.2,0.4-0.2h0.7c0.2,0,0.3,0.1,0.4,0.2c0.1,0.1,0.2,0.3,0.2,0.4v10.9c0,0.3,0.1,0.5,0.3,0.7c0,0,0.1,0,0.1,0.1
+						c0.1,0,0.1,0.1,0.2,0.1l0.1,0.1l0.1,0.1v0.1l0.1,0.4v0.1c0,0.1,0,0.2-0.1,0.3c-0.1,0.1-0.2,0.2-0.4,0.2
+						C49.1,19.7,48.9,19.7,48.8,19.7z"/>
+				</g>
+				<g id="Path_8">
+					<path style="fill:#FFFFFF;" d="M53.9,8.1c-0.2,0.2-0.6,0.3-0.9,0.3c-0.3,0-0.6-0.1-0.9-0.3c-0.2-0.2-0.4-0.5-0.3-0.8
+						c0-0.3,0.1-0.6,0.3-0.8c0.2-0.2,0.6-0.3,0.9-0.3c0.3,0,0.7,0.1,0.9,0.3c0.2,0.2,0.4,0.5,0.4,0.8C54.3,7.6,54.2,7.9,53.9,8.1z
+						 M52.7,19.5c-0.3,0-0.6-0.3-0.6-0.6l0,0v-8.2c0-0.2,0.1-0.3,0.2-0.4c0.1-0.1,0.3-0.2,0.4-0.2h0.7c0.2,0,0.3,0.1,0.4,0.2
+						c0.1,0.1,0.2,0.3,0.2,0.4v8.2c0,0.3-0.3,0.6-0.6,0.6l0,0H52.7z"/>
+				</g>
+			</g>
+			<g id="Path_9">
+				<path style="fill:#F1CA23;" d="M18.9,34.4c-0.5,0-1-0.4-1-1l0,0v-3.6c0-5.6,2.7-8.8,7.3-8.8c0.5,0,1,0.4,1,1c0,0.5-0.4,1-1,1
+					l0,0c-3.5,0-5.3,2.3-5.3,6.8v3.6C19.8,34,19.4,34.4,18.9,34.4L18.9,34.4z"/>
+			</g>
+			<g id="Path_10">
+				<path style="fill:#F1CA23;" d="M20.8,45.5c-0.5,0-1-0.4-1-1c0-0.5,0.4-1,1-1l0,0c1.9,0,3.3-2.6,3.3-6.3V26.6c0-0.5,0.4-1,1-1
+					c0.5,0,1,0.4,1,1v10.6C26.1,42.9,23.4,45.5,20.8,45.5z"/>
+			</g>
+			<g id="Path_11">
+				<path style="fill:#F1CA23;" d="M14.6,34.4c-0.5,0-1-0.4-1-1l0,0V11.3c0-0.5,0.4-1,1-1c0.5,0,1,0.4,1,1v22.1
+					C15.6,34,15.1,34.4,14.6,34.4L14.6,34.4z"/>
+			</g>
+			<g id="Path_12">
+				<path style="fill:#F1CA23;" d="M10.3,34.4c-0.5,0-1-0.4-1-1l0,0V11.3c0-0.5,0.4-1,1-1c0.5,0,1,0.4,1,1v22.1
+					C11.3,34,10.9,34.4,10.3,34.4L10.3,34.4z"/>
+			</g>
+			<g id="Path_13">
+				<path style="fill:#F1CA23;" d="M6.1,34.4c-0.5,0-1-0.4-1-1l0,0V11.3c0-0.5,0.4-1,1-1s1,0.4,1,1v22.1C7.1,34,6.6,34.4,6.1,34.4z"
+					/>
+			</g>
+		</g>
+	</g>
+</g>
+</svg>

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 310 - 0
dashboard/src/assets/icon/index.tsx


+ 62 - 0
dashboard/src/assets/library/images/books.svg

@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 24.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.0" id="books_bg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 viewBox="0 0 610 947" style="enable-background:new 0 0 610 947;" xml:space="preserve">
+<g>
+	<defs>
+		<rect id="SVGID_3_" x="-135.3" y="-0.1" width="1141.1" height="947.4"/>
+	</defs>
+	<clipPath id="SVGID_2_">
+		<use xlink:href="#SVGID_3_"  style="overflow:visible;"/>
+	</clipPath>
+	<g id="Mask_Group_2_1_" style="clip-path:url(#SVGID_2_);">
+		<g id="Group_57_1_" transform="translate(-2443.92 512.47)">
+			<path id="Path_106_1_" style="fill:#EAEAEA;" d="M3010.1,259.9h-514.5l178.3-1001.2h157.9L3010.1,259.9z"/>
+			<path id="Path_128_1_" style="fill:#F0F0F0;" d="M2752.9,168c142.1,0,257.3,43,257.3,96.1s-115.2,96.1-257.3,96.1
+				s-257.3-43-257.3-96.1S2610.8,168,2752.9,168z"/>
+			<g id="Group_56_1_" transform="translate(2703.386 -23.966)">
+				<path id="Path_107_1_" style="fill:#B03C2C;" d="M28.4,261.7l-100.3,23.9c-11.4-0.1-22.1-3-23.3-7.8V114.4L5.2,90.4V99l23.3-0.7
+					L28.4,261.7z"/>
+				<path id="Path_108_1_" style="fill:#782E29;" d="M-71.9,285.6L-71.9,285.6l0-171.2h-23.3v163.4C-94,282.6-83.3,285.5-71.9,285.6
+					z"/>
+				<path id="Path_109_1_" style="fill:#FFFFFF;" d="M-94.8,115.4L4.7,91.6c1.1,4.9,12.3,6.5,23.8,6.6l-100.3,23.9
+					C-82.5,122.1-92.5,119.6-94.8,115.4z"/>
+				<path id="Path_110_1_" style="fill:#B03C2C;" d="M55.2,270.8l-100.3,23.9c-11.4-0.1-22.1-3-23.3-7.8V123.5L32,99.6v8.6l23.3-0.7
+					L55.2,270.8z"/>
+				<path id="Path_111_1_" style="fill:#782E29;" d="M-45.1,294.7L-45.1,294.7l0-171.2h-23.3v163.4
+					C-67.2,291.8-56.5,294.6-45.1,294.7z"/>
+				<path id="Path_112_1_" style="fill:#FFFFFF;" d="M-68,124.5l99.5-23.7c1.1,4.9,12.3,6.5,23.8,6.6l-100.3,23.9
+					C-55.7,131.2-65.7,128.8-68,124.5z"/>
+				<path id="Path_113_1_" style="fill:#B03C2C;" d="M82,279.9l-100.3,23.9c-11.4-0.1-22.1-3-23.3-7.8V132.6l100.3-23.9v8.6
+					l23.3-0.7L82,279.9z"/>
+				<path id="Path_114_1_" style="fill:#782E29;" d="M-18.3,303.8L-18.3,303.8l0-171.2h-23.3V296C-40.4,300.9-29.7,303.7-18.3,303.8
+					z"/>
+				<path id="Path_115_1_" style="fill:#FFFFFF;" d="M-41.2,133.6l99.5-23.7c1.1,4.9,12.3,6.5,23.8,6.6l-100.3,23.9
+					C-28.9,140.4-38.9,137.9-41.2,133.6z"/>
+				<path id="Path_116_1_" style="fill:#B03C2C;" d="M108.8,289L8.5,313c-11.4-0.1-22.1-3-23.3-7.8V141.7l100.3-23.9v8.6l23.3-0.7
+					V289z"/>
+				<path id="Path_117_1_" style="fill:#782E29;" d="M8.5,313L8.5,313l0-171.2h-23.3v163.4C-13.6,310-2.9,312.8,8.5,313z"/>
+				<path id="Path_118_1_" style="fill:#FFFFFF;" d="M-14.4,142.7L85.1,119c1.1,4.9,12.3,6.5,23.8,6.6L8.5,149.6
+					C-2.1,149.5-12.1,147-14.4,142.7z"/>
+				<path id="Path_119_1_" style="fill:#B03C2C;" d="M135.6,298.1L35.3,322.1c-11.4-0.1-22.1-3-23.3-7.8V150.9l100.3-23.9v8.6
+					l23.3-0.7V298.1z"/>
+				<path id="Path_120_1_" style="fill:#782E29;" d="M35.3,322.1L35.3,322.1l0-171.2H12v163.4C13.2,319.1,23.9,322,35.3,322.1z"/>
+				<path id="Path_121_1_" style="fill:#FFFFFF;" d="M12.4,151.9l99.5-23.7c1.1,4.9,12.3,6.5,23.8,6.6L35.3,158.7
+					C24.7,158.6,14.7,156.1,12.4,151.9z"/>
+				<path id="Path_122_1_" style="fill:#B03C2C;" d="M162.4,307.3L62.1,331.2c-11.4-0.1-22.1-3-23.3-7.8V160L139.1,136v8.6l23.3-0.7
+					V307.3z"/>
+				<path id="Path_123_1_" style="fill:#782E29;" d="M62.1,331.2L62.1,331.2l0-171.2H38.8v163.4C39.9,328.2,50.6,331.1,62.1,331.2z"
+					/>
+				<path id="Path_124_1_" style="fill:#FFFFFF;" d="M39.2,161l99.5-23.7c1.1,4.9,12.3,6.5,23.8,6.6L62.1,167.8
+					C51.5,167.7,41.5,165.2,39.2,161z"/>
+				<path id="Path_125_1_" style="fill:#B03C2C;" d="M189.2,316.4L88.9,340.3c-11.4-0.1-22.1-3-23.3-7.8V169.1l100.3-23.9v8.6
+					l23.3-0.7V316.4z"/>
+				<path id="Path_126_1_" style="fill:#782E29;" d="M88.9,340.3L88.9,340.3l0-171.2H65.6v163.4C66.7,337.4,77.4,340.2,88.9,340.3z"
+					/>
+				<path id="Path_127_1_" style="fill:#FFFFFF;" d="M66,170.1l99.5-23.7c1.1,4.9,12.3,6.5,23.8,6.6L88.9,176.9
+					C78.2,176.8,68.2,174.4,66,170.1z"/>
+			</g>
+		</g>
+	</g>
+</g>
+</svg>

BIN
dashboard/src/assets/library/images/download_bg.png


+ 127 - 0
dashboard/src/assets/library/images/teachers.svg

@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 24.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.0" id="teachers_bg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 viewBox="0 0 763 1491" style="enable-background:new 0 0 763 1491;" xml:space="preserve">
+<g id="Mask_Group_3_1_" transform="translate(0 -32)">
+	<g id="Group_62_1_" transform="translate(-1298.767 1264.372)">
+		<path id="Path_129_1_" style="fill:#545454;" d="M1507.6-1232.2L1361.5-17.1h630.3l-145.6-1215.1"/>
+		<ellipse id="Ellipse_4_1_" style="fill:#686868;" cx="1676.6" cy="-17.1" rx="315.1" ry="104"/>
+		<path id="Path_130_1_" style="fill:#343434;" d="M1724.5-230.8c-0.6-6.1-2.9-11.8-6.5-16.7c0,0,0.5-19.7-0.3-28
+			c-0.7-8.3-3.7-34-5.5-39.1c-1.3-3.9-4.1-38.9-8.3-51.1c-4.5-13.3-10.8-22.8-17.6-27.6c-0.9-0.6-1.8-1.2-2.7-1.8
+			c-0.8-0.8-1.7-1.5-2.6-2c-11.2-5.9-19.8-4.2-20.6-6.5c-0.4-2.7-0.5-5.5-0.3-8.2c5.9-2.3,11.4-5.5,16.3-9.5
+			c17.2-14.2,24.9-43.9,19.5-63.4c-6.3-23.1-28.6-33.7-51.9-32.4c-30.1,1.7-39.1,21.5-42.2,39.8c-2.7,16-1.1,41.2,13.4,59.5
+			c3.1,3.8,7.3,6.7,12,8.2c-0.2,0.8-0.5,1.5-0.9,2.2l0.1,0.1c-0.2,0.5-0.5,0.9-1,1.1c-0.2,0.1-0.6,0.2-1,0.4c-1.7-2.8-3-4.4-4.4-4.4
+			c-0.9,0.1-1.7,0.4-2.5,0.9c-0.3-0.2-0.6-0.4-0.9-0.5c-1.5-0.6-3.5,0.4-5.8,2.3c-14,3.8-27.5,19.8-31.5,28.8
+			c-5.3,11.8-6.3,19-9.7,30.3c-2.8,9.3-6.1,30.9-6.1,30.9s-19.9,50.2-20.9,55.3c-0.4,2.7-0.1,5.5,1.1,8c-3.6,4-6.2,8.8-7.7,14
+			c-2.4,9,6,18.4,9.7,19.8c3.7,1.4,13.7,2.6,17-8.7c0.1-0.3,0.2-0.6,0.2-0.8c0.2,0.2,0.3,0.3,0.5,0.5c-0.8,9.4-1.6,18.8-2.4,28.2
+			c0,0.3,0.2,0.6,0.6,0.8c-3.9,43.5-6.3,84.1-4.4,88.1c2.4,5.2,4.5,10.7,16.8,17.1c-3.4,5.7-7,10.2-15.7,16.8
+			c-9.3,7.1-13.4,13.5-7.1,19.1c6.2,5.6,22.1,8.9,31.2,3.9c9.1-5,13-16.2,15.9-20.6c1-1.6,1.3-5.2,1.3-9.4
+			c20.8,5.9,39.2,5.8,49.2,4.5c0.1,1.4,0.3,2.9,0.6,4.3c1.7,6.8,0.3,21.2,13.9,26.1c8.7,3.1,23.5-1.7,25.4-6.9s-0.5-13.4-7.2-22.4
+			c-2.5-3.6-4.1-7.7-4.7-12c9.7-2.2,13.4-4.7,16.9-9.2c5.1-6.7,3.6-16.3,5.3-41.4c1.5-22.2,0.5-42.4,0-77.2c2.9,6.9,8.4,10,15,9.3
+			C1723-211.7,1725.1-219.7,1724.5-230.8z M1698.8-242.5c-0.1-2.2-0.1-4.5-0.2-6.9c0.7,2.4,1.2,4,1.2,4S1699.3-244.3,1698.8-242.5
+			L1698.8-242.5z"/>
+		<path id="Path_131_1_" style="fill:#434343;" d="M1834.9-183.9c-1.5-5.3-4.1-10.2-7.7-14.3c1.2-2.5,1.5-5.4,1.1-8.1
+			c-1-5.3-20.9-56.5-20.9-56.5s-3.3-22-6.1-31.5c-3.4-11.5-4.4-19-9.7-31c-4-9.2-17.6-25.5-31.6-29.4c-2.3-1.9-4.4-2.9-5.9-2.4
+			c-0.3,0.1-0.7,0.3-0.9,0.5c-0.7-0.5-1.6-0.8-2.5-0.9c-1.4,0-2.8,1.6-4.5,4.4c-0.4-0.1-0.8-0.3-1-0.4c-0.4-0.3-0.8-0.7-1-1.1
+			l0.1-0.1c-0.4-0.7-0.7-1.5-0.9-2.2c4.7-1.5,8.9-4.4,12.1-8.3c14.6-18.7,16.2-44.5,13.5-60.8c-3.1-18.7-12.1-38.9-42.3-40.6
+			c-23.4-1.4-45.7,9.5-52.1,33c-5.4,19.9,2.3,50.2,19.6,64.7c4.9,4.1,10.5,7.4,16.4,9.7c0.2,2.8,0.1,5.6-0.3,8.4
+			c-0.8,2.3-9.5,0.6-20.7,6.6c-1,0.5-1.9,1.2-2.7,2.1c-1,0.6-1.9,1.2-2.8,1.9c-6.8,4.9-13.1,14.6-17.6,28.2
+			c-4.2,12.5-7,48.3-8.3,52.2c-1.8,5.3-4.7,31.4-5.5,39.9c-0.7,8.5-0.3,28.6-0.3,28.6c-3.7,5-5.9,10.9-6.5,17
+			c-0.7,11.4,1.5,19.6,10.4,20.5c6.6,0.7,12.1-2.5,15-9.5c-0.5,35.5-1.5,56.2,0,78.8c1.7,25.6,0.2,35.5,5.3,42.3
+			c3.5,4.6,7.2,7.2,17,9.4c-0.6,4.4-2.2,8.6-4.7,12.3c-6.8,9.2-9.1,17.6-7.2,22.9c1.9,5.3,16.7,10.2,25.4,7
+			c13.7-5,12.3-19.7,14-26.7c0.3-1.4,0.5-2.9,0.6-4.4c10.1,1.3,28.5,1.4,49.4-4.6c-0.1,4.3,0.2,8,1.3,9.6
+			c2.8,4.6,6.8,15.9,15.9,21.1s25,1.7,31.3-4s2.2-12.3-7.2-19.5c-8.7-6.7-12.3-11.3-15.7-17.1c12.3-6.5,14.4-12.1,16.8-17.4
+			c1.9-4.1-0.5-45.5-4.4-90c0.3-0.2,0.6-0.4,0.6-0.8c-0.8-9.6-1.6-19.2-2.4-28.8c0.2-0.2,0.3-0.3,0.5-0.5c0.1,0.3,0.2,0.6,0.2,0.9
+			c3.3,11.6,13.3,10.3,17.1,8.9C1828.9-165,1837.3-174.6,1834.9-183.9z M1671.9-193.2c-0.1,2.4-0.1,4.7-0.2,7c-0.6-1.9-1-3-1-3
+			S1671.1-190.7,1671.9-193.2z"/>
+		<g id="Group_61_1_" transform="translate(2271.497 -30.516)">
+			<path id="Path_132_1_" style="fill:#FFF0DE;" d="M-652.1-290.2c-6.9,3.6-18.3,26.9-20.1,37c-1.7,10.1-5.4,45.3-5.4,45.3
+				s-8,22.3-11,33.2c-2.4,8.7-6.2,31.4-6.2,31.4s-4.2,8.5-1.1,16.6c4.6,12.2,9,17.4,17.9,18.1c5.2,0.4,6.5-11.7,5-15.8
+				c-3.1-8.8-2.5-10.9-2.5-10.9s7.1-19.4,10.1-27.3c3.1-7.9,12-32.4,12.8-37.8c0.6-4.1,9.4-37.9,11.2-50.8c2-14,3.7-31.3,0.8-38.4
+				C-641.9-293.1-645.8-293.5-652.1-290.2z"/>
+			<path id="Path_133_1_" style="fill:#FFF0DE;" d="M-638.2-314.1c0,0,0.8,15,0,17.3s1.1-2.6-8.6,5.5c-10.1,8.4-19.2,34.8-21.1,49.1
+				c-1.4,10.6,1.9,38.3,1.9,38.3l103.8-4.9c0,0-0.8-61.3-12.4-74.1s-26.3-15.4-29-16.5c-2.6-1.1-4.5-17.7-4.5-17.7L-638.2-314.1z"/>
+			<g id="Group_58_1_" transform="translate(44.783 67.382)">
+				<path id="Path_134_1_" style="fill:#F9C8B0;" d="M-653-384.4c0,0,1.7,11.1,2.9,15.4c-2.7,2.5-9.5,5.8-14.6,6.9
+					c-7.3,1.5-13.1-0.6-18.5-2.2c1.3-4.3,0.1-17,0.1-17L-653-384.4z"/>
+			</g>
+			<path id="Path_135_1_" style="fill:#FFF0DE;" d="M-634.9-411.3c-29.8,2.8-38.1,23.2-40.5,41.8c-2.1,16.2,1.7,46.7,17.3,63.6
+				c10.5,11.4,54.2,11.3,66.8-7.1c12.6-18.5,15.1-47.8,9.1-67.3C-589.2-403.6-611.7-413.5-634.9-411.3z"/>
+			<path id="Path_136_1_" style="fill:#FFF0DE;" d="M-576.1,1.1c0,12.3-1.6,26,0,32.8c1.7,6.9,0.3,21.5,13.8,26.4
+				c8.7,3.2,23.3-1.7,25.2-7c1.9-5.3-0.5-13.6-7.2-22.7c-5.4-7.3-5.5-19.1-5.2-23.8c0.4-4.7,0-16.4,0-16.4L-576.1,1.1z"/>
+			<path id="Path_137_1_" style="fill:#FFF0DE;" d="M-626.9,5.2c0,4.5,2.8,24.8,0,29.3s-6.8,15.8-15.8,20.9c-9,5.1-24.8,1.7-31-3.9
+				s-2.2-12.2,7.1-19.3s12.7-11.9,16.3-18.3c3.6-6.4,2.5-16,2.5-16L-626.9,5.2z"/>
+			<path id="Path_138_1_" style="fill:#572A08;" d="M-620.4-349.9c-4.7,0-9.5-1.1-11.2-2.6c-0.4-0.4-0.5-1-0.1-1.4
+				c0.4-0.4,1-0.5,1.4-0.1c2.2,2,14.8,3.7,18.5-0.2c0.4-0.4,1-0.5,1.4-0.1c0.4,0.4,0.5,1,0.1,1.4c0,0-0.1,0.1-0.1,0.1
+				C-612.3-350.7-616.3-349.9-620.4-349.9z"/>
+			<path id="Path_139_1_" style="fill:#572A08;" d="M-660.2-348.4c-3-0.1-6-0.9-8.7-2.3c-0.5-0.2-0.7-0.8-0.5-1.4
+				c0.2-0.5,0.8-0.7,1.4-0.5c6.2,2.8,9.5,3.1,16.9-0.4c0.5-0.2,1.1,0,1.4,0.5c0.2,0.5,0,1.1-0.5,1.4
+				C-653.4-349.5-656.8-348.6-660.2-348.4z"/>
+			<path id="Path_140_1_" style="fill:#572A08;" d="M-638.6-320c-3.2,0.1-6.3-0.4-9.4-1.3c-0.5-0.2-0.8-0.8-0.6-1.3
+				c0.2-0.5,0.8-0.8,1.3-0.6c2.9,0.9,6,1.3,9.1,1.2c3.9-0.1,6.9-0.8,7.9-2.1c0.3-0.4,1-0.5,1.4-0.2c0.4,0.3,0.5,1,0.2,1.4l0,0
+				c-1.8,2.3-6.1,2.9-9.5,2.9C-638.3-320-638.4-320-638.6-320z"/>
+			<path id="Path_141_1_" style="fill:#572A08;" d="M-589.9-333.3c-0.6,0-1-0.4-1-1c0-0.5,0.4-1,0.9-1c3.1-0.4,8.2-3.9,7.7-14.5
+				c-0.1-1.9-1.2-3.6-3-4.5c-2-1.1-4.4-1-6.3,0.2c-0.5,0.3-1.1,0.1-1.4-0.4c-0.3-0.5-0.1-1.1,0.4-1.4l0,0c2.5-1.6,5.7-1.7,8.3-0.3
+				c2.4,1.2,3.9,3.6,4,6.2c0.5,10.5-4.4,15.9-9.5,16.6C-589.8-333.3-589.9-333.3-589.9-333.3z"/>
+			<path id="Path_142_1_" style="fill:#B03C2C;" d="M-626.2-267.4c-15,13.1-43.4,25.9-43.4,25.9s-6.7,71.8-7,115.8
+				c-0.4,44.6-1.9,67.5-0.2,92.9c1.7,25.4,0.2,35.2,5.2,41.9c5.1,6.8,10.7,9,35,12.4s70.5-6.8,76.1-11.3s3.2-150.4-5.5-208.9
+				c-10.7-71.9-23.7-104.6-32.3-104.8C-602.9-303.6-606.9-284.3-626.2-267.4z"/>
+			<path id="Path_143_1_" style="fill:#782E29;" d="M-600.3-288.5c-3.7,0.1-5.9,5.7-7.4,8.4c-4.4,8.3-9.9,16-16.2,23
+				c-11.5,12.1-26.6,22.1-40.5,30.8c-1.1,0.7-0.1,1.9,0.9,1.2c13-7.9,25.3-16.9,36.8-26.9c6.9-6.3,12.8-13.7,17.5-21.8
+				c1.7-2.9,3.3-5.9,5-8.7c0.7-1.1,2.2-4.3,3.8-4.4C-599.3-287-598.9-288.5-600.3-288.5L-600.3-288.5z"/>
+			<path id="Path_144_1_" style="fill:#B03C2C;" d="M-594.8-303.1c-6.5,2.5-17.5,30.7-29.9,107.5S-646.1-89-647.8-52.9
+				c-1.7,36.1-2.3,76.5,2.8,78.8c5.1,2.3,42.3,7.5,72.8-2.6c30.5-10.2,50.8-23.1,54.2-30.5c3.4-7.3,2.3-115.6-9-162.5
+				s-25.9-113.4-36.1-120.7C-573.4-297.7-589.2-305.2-594.8-303.1z"/>
+			<path id="Path_145_1_" style="fill:#782E29;" d="M-595.2-301.9c-2.7,1.1-4.3,4-5.6,6.4c-2.8,5.4-5,11.1-6.7,16.9
+				c-7.8,24.5-12.4,50.2-16.6,75.5c-5,29.8-10.2,59.5-15.9,89.2c-3.5,18.7-7.1,37.4-8.4,56.4c-1.2,16.6-1.6,33.4-1.2,50
+				c0,6.8,0.5,13.5,1.4,20.2c0.4,2.5,0.8,7.1,3.3,8.4c0.5,0.3,2.4-0.5,1.6-0.9c-2.3-1.2-2.6-6.1-3-8.3c-0.8-5.7-1.2-11.5-1.3-17.3
+				c-0.4-16,0-32,0.9-48c1-18,4-35.8,7.3-53.5c5-26.7,10.1-53.3,14.5-80.1c4.6-27.8,9.1-55.7,16.6-82.8c2-7.7,4.5-15.2,7.7-22.5
+				c1.2-2.7,3.1-7.6,6.2-8.8C-593.2-301.7-594.3-302.3-595.2-301.9L-595.2-301.9z"/>
+			<path id="Path_146_1_" style="fill:#FFF0DE;" d="M-588.8-130.7c-4.5,8.3,1.4,19.5,4.6,21.7c3.3,2.2,12.6,5.8,18.5-4.6
+				c5.9-10.4,11.2-29.2,2-32.5C-572.9-149.2-584.3-139.1-588.8-130.7z"/>
+			<path id="Path_147_1_" style="fill:#B03C2C;" d="M-560.7-291.9c15.1,10.6,24.9,30.9,34.1,50.5c9.4,19.9,22.4,79.7,22.1,96
+				c-0.3,16.5-5.2,66.6-11.9,68.3c-6.8,1.7-26.7-18.8-37.9-40.6c-11.4-22.1-20.6-28.6-18.7-32.3c2.4-4.7,15.7-46.6,15.7-46.6
+				s-8.8-22.1-13.6-30.7c-5.4-9.5-10.1-19.3-14-29.5c-4.1-10.6-9.9-38.2-4.7-40.2C-581.4-300.3-565.5-295.3-560.7-291.9z"/>
+			<path id="Path_148_1_" style="fill:#782E29;" d="M-516.6-80.5c-3.1,0.6-7.3-3.1-9.5-4.9c-4.2-3.5-8-7.5-11.5-11.7
+				c-4.1-4.9-7.8-10-11.1-15.4c-3.6-5.7-6.4-11.8-9.9-17.6c-2.7-4.5-5.6-8.8-8.7-13.1c-1.6-2.3-3.8-4.6-4.8-7.3
+				c-0.6-1.7,0-2.7,0.6-4.2c1-2.4,1.8-4.9,2.7-7.4c2.6-7.4,5-14.9,7.4-22.3c1.1-3.3,2.1-6.6,3.2-9.9c0.7-1.6,1.3-3.3,1.6-5.1
+				c-0.1-1.1-0.5-2.2-1-3.2c-1.5-3.8-3.1-7.5-4.7-11.2c-3.9-9-8.4-17.6-12.9-26.3c-5.5-10.2-9.7-21.1-12.6-32.3
+				c-1.3-5.3-2.2-10.6-2.8-16c-0.2-2.1-1.4-9.8,1.2-11c1.2-0.6,0.1-1.4-0.8-0.9c-2.1,1-2.4,3.5-2.6,5.7c-0.2,4.2,0.2,8.3,0.9,12.4
+				c1.6,10.2,4.5,20.1,8.5,29.6c4.4,10.4,10.3,20,15,30.3c2.1,4.6,4.1,9.3,6.1,14c1.1,2.7,3.2,6,3.6,8.9c-0.1,1-0.3,2-0.7,2.9
+				c-0.9,2.9-1.8,5.8-2.8,8.7c-2.5,7.9-5.1,15.8-7.8,23.7c-1,3-2.1,6.1-3.2,9.1c-0.6,1.4-1.5,2.8-1.2,4.4c0.5,2.3,2.4,4.5,3.7,6.3
+				c2.8,3.9,5.6,7.9,8.2,12c4.3,6.8,7.6,14,11.8,20.8c4,6.4,8.5,12.5,13.5,18.1c3.6,4.2,7.7,8,12.2,11.3c2.5,1.7,5.4,3.5,8.6,2.9
+				C-515-79.6-515.3-80.7-516.6-80.5L-516.6-80.5z"/>
+			<path id="Path_149_1_" style="fill:#572A08;" d="M-642.4-330.9L-642.4-330.9c-3.5-0.2-4.8-1.7-5.3-2.9c-0.9-2.1,0.2-5,2.9-8.1
+				c0.4-0.4,1-0.5,1.4-0.1c0.4,0.4,0.5,1,0.1,1.4c-2.2,2.5-3.1,4.7-2.6,6c0.5,1.2,2.1,1.5,3.4,1.6c0.6,0,1,0.5,0.9,1.1
+				C-641.4-331.3-641.9-330.9-642.4-330.9L-642.4-330.9z"/>
+			<path id="Path_150_1_" style="fill:#572A08;" d="M-627.7-363.9c0.2-0.6,0.6-1.2,1.1-1.6c0.5-0.4,1.1-0.7,1.8-0.9
+				c1.2-0.4,2.5-0.5,3.8-0.4c1.2,0.1,2.5,0.3,3.6,0.7c1.2,0.4,2.3,1,3.3,1.7c-1.2,0-2.4,0-3.6-0.1l-3.5-0.3
+				c-1.1-0.1-2.2-0.1-3.3-0.1C-625.6-364.8-626.8-364.5-627.7-363.9z"/>
+			<path id="Path_151_1_" style="fill:#572A08;" d="M-654-362.9c-1-0.6-2.1-0.9-3.2-0.9c-1.1-0.1-2.2,0-3.3,0.1l-3.5,0.3
+				c-1.2,0.1-2.4,0.2-3.6,0.1c1-0.7,2.1-1.3,3.3-1.7c1.2-0.4,2.4-0.7,3.6-0.7c1.3-0.1,2.6,0,3.8,0.4c0.6,0.2,1.2,0.5,1.8,0.9
+				C-654.7-364.1-654.3-363.5-654-362.9z"/>
+			<g id="Group_60_1_" transform="translate(0 95.202)">
+				<g id="Group_59_1_">
+					<path id="Path_152_1_" style="fill:#EDE8E6;" d="M-592.1-323.9c-5.1-35.8-25.6-55.9-56.5-47.4l0,0l0,0
+						c-23.7,6.5-39,27.3-47.2,51c-6.1,17.8-8.3,41.1,0.1,52c6.2,8,22.2,7.5,28.3,9.4c0.1,0,0.3,0.1,0.4,0.1s0.3,0.1,0.4,0.1
+						c6.7,2,26.9,14.8,41.6,11C-599-254.2-587.7-293.4-592.1-323.9z"/>
+					<path id="Path_153_1_" style="fill:#572A08;" d="M-649.4-367L-649.4-367l0.1,0c12.7-3.2,24.1-1.4,33.4,6.3
+						c9.3,7.7,15.7,21.1,18.1,38.6c1.9,14.8,0.2,29.8-5.1,43.7c-6.9,17.7-16.8,23.7-23.5,25.5c-4.2,1.2-9.8,0.7-16.5-1.2
+						c-5.3-1.6-10.5-3.6-15.5-5.9c-2.4-1.1-4.9-2.1-7.5-3c-0.1,0-0.2-0.1-0.4-0.1l-0.1,0l-0.1,0c-0.1,0-0.2-0.1-0.4-0.1
+						c-2.4-0.5-4.7-0.9-7.1-1.1c-4-0.4-7.9-1-11.8-2c-3.3-0.7-6.3-2.5-8.6-4.9c-4.5-5.6-5.1-14.6-4.9-21c0.4-9.2,2.2-18.3,5.2-27
+						c3.5-10.7,9-20.7,16.1-29.4C-670.5-357.7-660.5-364.1-649.4-367 M-648.5-371.3L-648.5-371.3L-648.5-371.3
+						c-23.8,6.5-39.1,27.4-47.3,51c-6.1,17.8-8.3,41.1,0.1,52c2.5,2.9,5.8,4.9,9.5,5.8c6.8,2.1,14.9,2.4,18.9,3.5
+						c0.1,0,0.3,0.1,0.4,0.1c0.1,0,0.3,0.1,0.4,0.1c4.1,1.2,13.1,6.4,22.9,9.4c6.3,2,13,3,18.6,1.6c26-6.6,37.3-45.7,32.9-76.3
+						C-597.2-359.8-617.7-379.8-648.5-371.3L-648.5-371.3z"/>
+				</g>
+				<path id="Path_154_1_" style="fill:#782E29;" d="M-664.5-274.3c-4.1-0.9-8.4,4.8-9.6,12.7c-0.1,0.5-0.1,0.9-0.2,1.4
+					c2.3,0.3,4.6,0.7,6.9,1.2c0.1,0,0.3,0.1,0.4,0.1s0.3,0.1,0.4,0.1c2.5,0.9,4.9,1.9,7.2,3.1c0.1-0.5,0.2-1,0.3-1.5
+					C-657.7-265.7-660.2-273.4-664.5-274.3z"/>
+				<path id="Path_155_1_" style="fill:#782E29;" d="M-670.6-214.3h-7.4l9.1-57.4l7.9,1.8L-670.6-214.3z"/>
+			</g>
+			<path id="Path_156_1_" style="fill:#FFF0DE;" d="M-694.6-142.1c0,0-6.2,7.2-5.2,16.4c1.4,13,11.3,23.3,20.3,20.3
+				c9.3-3.2,10.8-8.7,9.7-17c-1.3-9.6-6.7-13.1-6.7-13.1L-694.6-142.1z"/>
+		</g>
+	</g>
+</g>
+</svg>

+ 51 - 0
dashboard/src/assets/library/images/wikipali_logo_library.svg

@@ -0,0 +1,51 @@
+<svg id="wikipali_banner" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 221 54.417">
+  <g id="Group_12" data-name="Group 12" transform="translate(-396 -320)">
+    <g id="Group_2" data-name="Group 2" transform="translate(396 320)">
+      <g id="Group_1" data-name="Group 1" transform="translate(39.472 12.369)">
+        <path id="Path_1" data-name="Path 1"
+          d="M252.239,132.886a1.184,1.184,0,0,1-.733-.244,1.144,1.144,0,0,1-.424-.63l-3.447-12.729a.825.825,0,0,1-.026-.206.683.683,0,0,1,.155-.411.655.655,0,0,1,.539-.257h1.234a1.129,1.129,0,0,1,.721.244,1.171,1.171,0,0,1,.411.63l1.7,6.97q.026.1.8,4.063a.046.046,0,0,0,.053.051.046.046,0,0,0,.051-.051q.925-3.96.952-4.063l1.8-6.97a1.187,1.187,0,0,1,1.132-.874h1a1.187,1.187,0,0,1,1.13.874l1.851,6.97q.153.643.475,1.993t.5,2.071a.046.046,0,0,0,.051.051.084.084,0,0,0,.078-.051q.076-.464.36-1.865t.462-2.2l1.647-6.97a1.187,1.187,0,0,1,1.132-.874h1.028a.66.66,0,0,1,.54.257.723.723,0,0,1,.155.437.813.813,0,0,1-.026.18l-3.266,12.729a1.143,1.143,0,0,1-.424.63,1.174,1.174,0,0,1-.733.244h-1.8a1.129,1.129,0,0,1-.721-.244,1.165,1.165,0,0,1-.411-.63l-1.62-6.3q-.258-1.028-.9-4.114a.1.1,0,0,0-.091-.051.091.091,0,0,0-.089.051q-.514,2.726-.9,4.142l-1.543,6.275a1.166,1.166,0,0,1-.411.63,1.12,1.12,0,0,1-.721.244h-1.671Z"
+          transform="translate(-247.61 -111.903)" fill="#fff" />
+        <path id="Path_2" data-name="Path 2"
+          d="M395.183,81.944a1.988,1.988,0,0,1-1.389.5,1.942,1.942,0,0,1-1.376-.5,1.661,1.661,0,0,1-.539-1.274,1.692,1.692,0,0,1,.539-1.3,1.94,1.94,0,0,1,1.376-.5,1.978,1.978,0,0,1,1.389.5,1.673,1.673,0,0,1,.553,1.3A1.644,1.644,0,0,1,395.183,81.944ZM393.216,99.65a.92.92,0,0,1-.926-.926V86.072a.864.864,0,0,1,.269-.63.892.892,0,0,1,.657-.269h1.157a.9.9,0,0,1,.657.269.865.865,0,0,1,.271.63V98.723a.923.923,0,0,1-.928.926Z"
+          transform="translate(-368.881 -78.666)" fill="#fff" />
+        <path id="Path_3" data-name="Path 3"
+          d="M444.3,98.574a.92.92,0,0,1-.926-.926V78.489a.869.869,0,0,1,.269-.63.892.892,0,0,1,.657-.269H445.4a.9.9,0,0,1,.657.269.863.863,0,0,1,.269.63v12.6c0,.018.013.026.038.026a.091.091,0,0,0,.065-.026l5.092-6.3a1.831,1.831,0,0,1,1.492-.693h1.518a.387.387,0,0,1,.373.244.382.382,0,0,1-.064.45l-4.269,5.092a.167.167,0,0,0,0,.18l4.937,7.74a.49.49,0,0,1,.078.257.481.481,0,0,1-.078.257.448.448,0,0,1-.437.257h-1.465a1.55,1.55,0,0,1-1.389-.772l-3.4-5.683c-.033-.069-.077-.077-.129-.026l-2.288,2.649a.336.336,0,0,0-.078.206v2.7a.92.92,0,0,1-.926.926Z"
+          transform="translate(-412.163 -77.59)" fill="#fff" />
+        <path id="Path_4" data-name="Path 4"
+          d="M540.613,81.944a1.987,1.987,0,0,1-1.388.5,1.94,1.94,0,0,1-1.376-.5,1.661,1.661,0,0,1-.539-1.274,1.692,1.692,0,0,1,.539-1.3,1.942,1.942,0,0,1,1.376-.5,1.977,1.977,0,0,1,1.388.5,1.673,1.673,0,0,1,.553,1.3A1.649,1.649,0,0,1,540.613,81.944ZM538.646,99.65a.923.923,0,0,1-.928-.926V86.072a.86.86,0,0,1,.271-.63.892.892,0,0,1,.657-.269H539.8a.9.9,0,0,1,.657.269.863.863,0,0,1,.269.63V98.723a.92.92,0,0,1-.926.926Z"
+          transform="translate(-491.128 -78.666)" fill="#fff" />
+        <path id="Path_5" data-name="Path 5"
+          d="M589.735,137.187a.92.92,0,0,1-.925-.925V117.746a.92.92,0,0,1,.925-.926h.642a1.016,1.016,0,0,1,.682.257,1.136,1.136,0,0,1,.373.642l.077.642c.018.035.038.053.064.053a.1.1,0,0,0,.065-.026,7.051,7.051,0,0,1,4.424-1.929,5,5,0,0,1,4.231,1.993,8.742,8.742,0,0,1,1.5,5.388,10.164,10.164,0,0,1-.515,3.3,6.991,6.991,0,0,1-1.389,2.469,6.473,6.473,0,0,1-1.993,1.5,5.339,5.339,0,0,1-2.353.54,5.846,5.846,0,0,1-3.729-1.569.031.031,0,0,0-.051,0,.075.075,0,0,0-.025.053l.076,2.366v3.754a.92.92,0,0,1-.926.925h-1.159Zm5.246-8.023a3.153,3.153,0,0,0,2.65-1.4,6.426,6.426,0,0,0,1.028-3.871q0-4.912-3.394-4.912a5.135,5.135,0,0,0-3.368,1.7.245.245,0,0,0-.078.18v6.866a.243.243,0,0,0,.078.18A4.734,4.734,0,0,0,594.981,129.164Z"
+          transform="translate(-534.418 -110.264)" fill="#fff" />
+        <path id="Path_6" data-name="Path 6"
+          d="M691.509,105.4a4.264,4.264,0,0,1-3.073-1.143,4.27,4.27,0,0,1,.85-6.609,16.4,16.4,0,0,1,6.518-1.787c.069,0,.1-.041.1-.129q-.1-3.032-2.751-3.034a7.157,7.157,0,0,0-3.419,1,.864.864,0,0,1-.669.089.811.811,0,0,1-.539-.424l-.257-.462a.955.955,0,0,1-.089-.706.822.822,0,0,1,.424-.553,10.423,10.423,0,0,1,5.066-1.44,4.826,4.826,0,0,1,3.96,1.594,6.988,6.988,0,0,1,1.312,4.551v7.792a.923.923,0,0,1-.928.926h-.642a1.008,1.008,0,0,1-.681-.257,1.118,1.118,0,0,1-.373-.642l-.1-.721c-.018-.033-.038-.053-.065-.053s-.046.018-.064.053A7.155,7.155,0,0,1,691.509,105.4Zm-.977-18.027a.92.92,0,0,1-.926-.926v-.206a.92.92,0,0,1,.926-.926h6.3a.92.92,0,0,1,.925.926v.206a.92.92,0,0,1-.925.926Zm1.9,15.637a5.287,5.287,0,0,0,3.4-1.6.278.278,0,0,0,.077-.206V97.9c0-.086-.033-.12-.1-.1a11.688,11.688,0,0,0-4.346,1.17,2.336,2.336,0,0,0-1.286,2.045,1.82,1.82,0,0,0,.617,1.518A2.582,2.582,0,0,0,692.435,103.015Z"
+          transform="translate(-617.157 -84.088)" fill="#fff" />
+        <path id="Path_7" data-name="Path 7"
+          d="M792.08,98.907a2.68,2.68,0,0,1-2.3-.952,4.607,4.607,0,0,1-.708-2.779V78.489a.865.865,0,0,1,.271-.63A.893.893,0,0,1,790,77.59h1.157a.9.9,0,0,1,.657.269.865.865,0,0,1,.271.63V95.333a1.12,1.12,0,0,0,.411,1.028c.034.018.11.061.231.129s.206.12.257.155.12.081.206.14a.691.691,0,0,1,.193.193.438.438,0,0,1,.064.231l.1.566a.736.736,0,0,1,.026.18.96.96,0,0,1-.155.54.792.792,0,0,1-.591.386C792.585,98.9,792.336,98.907,792.08,98.907Z"
+          transform="translate(-702.754 -77.59)" fill="#fff" />
+        <path id="Path_8" data-name="Path 8"
+          d="M840.663,81.944a1.988,1.988,0,0,1-1.389.5,1.94,1.94,0,0,1-1.376-.5,1.661,1.661,0,0,1-.539-1.274,1.692,1.692,0,0,1,.539-1.3,1.939,1.939,0,0,1,1.376-.5,1.978,1.978,0,0,1,1.389.5,1.673,1.673,0,0,1,.553,1.3A1.649,1.649,0,0,1,840.663,81.944ZM838.7,99.65a.92.92,0,0,1-.926-.926V86.072a.864.864,0,0,1,.269-.63.892.892,0,0,1,.657-.269h1.157a.9.9,0,0,1,.657.269.865.865,0,0,1,.271.63V98.723a.923.923,0,0,1-.928.926Z"
+          transform="translate(-743.346 -78.666)" fill="#fff" />
+      </g>
+      <path id="Path_9" data-name="Path 9"
+        d="M125.632,125.382a1.531,1.531,0,0,1-1.532-1.532v-5.532c0-8.629,4.134-13.579,11.342-13.579a1.532,1.532,0,0,1,0,3.064c-5.493,0-8.28,3.537-8.28,10.517v5.532A1.529,1.529,0,0,1,125.632,125.382Z"
+        transform="translate(-104.317 -88.043)" fill="#f1ca23" />
+      <path id="Path_10" data-name="Path 10"
+        d="M144.722,179.085a1.532,1.532,0,1,1,0-3.064c2.987,0,5.076-4,5.076-9.727V149.842a1.532,1.532,0,0,1,3.064,0v16.452C152.86,175.13,148.773,179.085,144.722,179.085Z"
+        transform="translate(-120.364 -124.667)" fill="#f1ca23" />
+      <path id="Path_11" data-name="Path 11"
+        d="M84.262,37.339a1.531,1.531,0,0,1-1.532-1.532V1.532a1.532,1.532,0,0,1,3.064,0V35.809A1.531,1.531,0,0,1,84.262,37.339Z"
+        transform="translate(-69.542)" fill="#f1ca23" />
+      <path id="Path_12" data-name="Path 12"
+        d="M42.892,37.339a1.531,1.531,0,0,1-1.532-1.532V1.532a1.532,1.532,0,0,1,3.064,0V35.809A1.531,1.531,0,0,1,42.892,37.339Z"
+        transform="translate(-34.767)" fill="#f1ca23" />
+      <path id="Path_13" data-name="Path 13"
+        d="M1.532,37.339A1.531,1.531,0,0,1,0,35.808V1.532a1.532,1.532,0,0,1,3.064,0V35.809A1.533,1.533,0,0,1,1.532,37.339Z"
+        fill="#f1ca23" />
+    </g>
+    <text id="studio" transform="translate(542 353.2)" fill="#fff" font-size="24"
+      font-family="NotoSans-ExtraLight, Noto Sans" font-weight="200">
+      <tspan x="0" y="0">Library</tspan>
+    </text>
+  </g>
+</svg>

BIN
dashboard/src/assets/nut/code.png


+ 22 - 0
dashboard/src/assets/studio/images/wikipali_banner.svg

@@ -0,0 +1,22 @@
+<svg id="wikipali_banner" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 221 54.417">
+  <g id="Group_12" data-name="Group 12" transform="translate(-396 -320)">
+    <g id="Group_2" data-name="Group 2" transform="translate(396 320)">
+      <g id="Group_1" data-name="Group 1" transform="translate(39.472 12.369)">
+        <path id="Path_1" data-name="Path 1" d="M252.239,132.886a1.184,1.184,0,0,1-.733-.244,1.144,1.144,0,0,1-.424-.63l-3.447-12.729a.825.825,0,0,1-.026-.206.683.683,0,0,1,.155-.411.655.655,0,0,1,.539-.257h1.234a1.129,1.129,0,0,1,.721.244,1.171,1.171,0,0,1,.411.63l1.7,6.97q.026.1.8,4.063a.046.046,0,0,0,.053.051.046.046,0,0,0,.051-.051q.925-3.96.952-4.063l1.8-6.97a1.187,1.187,0,0,1,1.132-.874h1a1.187,1.187,0,0,1,1.13.874l1.851,6.97q.153.643.475,1.993t.5,2.071a.046.046,0,0,0,.051.051.084.084,0,0,0,.078-.051q.076-.464.36-1.865t.462-2.2l1.647-6.97a1.187,1.187,0,0,1,1.132-.874h1.028a.66.66,0,0,1,.54.257.723.723,0,0,1,.155.437.813.813,0,0,1-.026.18l-3.266,12.729a1.143,1.143,0,0,1-.424.63,1.174,1.174,0,0,1-.733.244h-1.8a1.129,1.129,0,0,1-.721-.244,1.165,1.165,0,0,1-.411-.63l-1.62-6.3q-.258-1.028-.9-4.114a.1.1,0,0,0-.091-.051.091.091,0,0,0-.089.051q-.514,2.726-.9,4.142l-1.543,6.275a1.166,1.166,0,0,1-.411.63,1.12,1.12,0,0,1-.721.244h-1.671Z" transform="translate(-247.61 -111.903)" fill="#fff"/>
+        <path id="Path_2" data-name="Path 2" d="M395.183,81.944a1.988,1.988,0,0,1-1.389.5,1.942,1.942,0,0,1-1.376-.5,1.661,1.661,0,0,1-.539-1.274,1.692,1.692,0,0,1,.539-1.3,1.94,1.94,0,0,1,1.376-.5,1.978,1.978,0,0,1,1.389.5,1.673,1.673,0,0,1,.553,1.3A1.644,1.644,0,0,1,395.183,81.944ZM393.216,99.65a.92.92,0,0,1-.926-.926V86.072a.864.864,0,0,1,.269-.63.892.892,0,0,1,.657-.269h1.157a.9.9,0,0,1,.657.269.865.865,0,0,1,.271.63V98.723a.923.923,0,0,1-.928.926Z" transform="translate(-368.881 -78.666)" fill="#fff"/>
+        <path id="Path_3" data-name="Path 3" d="M444.3,98.574a.92.92,0,0,1-.926-.926V78.489a.869.869,0,0,1,.269-.63.892.892,0,0,1,.657-.269H445.4a.9.9,0,0,1,.657.269.863.863,0,0,1,.269.63v12.6c0,.018.013.026.038.026a.091.091,0,0,0,.065-.026l5.092-6.3a1.831,1.831,0,0,1,1.492-.693h1.518a.387.387,0,0,1,.373.244.382.382,0,0,1-.064.45l-4.269,5.092a.167.167,0,0,0,0,.18l4.937,7.74a.49.49,0,0,1,.078.257.481.481,0,0,1-.078.257.448.448,0,0,1-.437.257h-1.465a1.55,1.55,0,0,1-1.389-.772l-3.4-5.683c-.033-.069-.077-.077-.129-.026l-2.288,2.649a.336.336,0,0,0-.078.206v2.7a.92.92,0,0,1-.926.926Z" transform="translate(-412.163 -77.59)" fill="#fff"/>
+        <path id="Path_4" data-name="Path 4" d="M540.613,81.944a1.987,1.987,0,0,1-1.388.5,1.94,1.94,0,0,1-1.376-.5,1.661,1.661,0,0,1-.539-1.274,1.692,1.692,0,0,1,.539-1.3,1.942,1.942,0,0,1,1.376-.5,1.977,1.977,0,0,1,1.388.5,1.673,1.673,0,0,1,.553,1.3A1.649,1.649,0,0,1,540.613,81.944ZM538.646,99.65a.923.923,0,0,1-.928-.926V86.072a.86.86,0,0,1,.271-.63.892.892,0,0,1,.657-.269H539.8a.9.9,0,0,1,.657.269.863.863,0,0,1,.269.63V98.723a.92.92,0,0,1-.926.926Z" transform="translate(-491.128 -78.666)" fill="#fff"/>
+        <path id="Path_5" data-name="Path 5" d="M589.735,137.187a.92.92,0,0,1-.925-.925V117.746a.92.92,0,0,1,.925-.926h.642a1.016,1.016,0,0,1,.682.257,1.136,1.136,0,0,1,.373.642l.077.642c.018.035.038.053.064.053a.1.1,0,0,0,.065-.026,7.051,7.051,0,0,1,4.424-1.929,5,5,0,0,1,4.231,1.993,8.742,8.742,0,0,1,1.5,5.388,10.164,10.164,0,0,1-.515,3.3,6.991,6.991,0,0,1-1.389,2.469,6.473,6.473,0,0,1-1.993,1.5,5.339,5.339,0,0,1-2.353.54,5.846,5.846,0,0,1-3.729-1.569.031.031,0,0,0-.051,0,.075.075,0,0,0-.025.053l.076,2.366v3.754a.92.92,0,0,1-.926.925h-1.159Zm5.246-8.023a3.153,3.153,0,0,0,2.65-1.4,6.426,6.426,0,0,0,1.028-3.871q0-4.912-3.394-4.912a5.135,5.135,0,0,0-3.368,1.7.245.245,0,0,0-.078.18v6.866a.243.243,0,0,0,.078.18A4.734,4.734,0,0,0,594.981,129.164Z" transform="translate(-534.418 -110.264)" fill="#fff"/>
+        <path id="Path_6" data-name="Path 6" d="M691.509,105.4a4.264,4.264,0,0,1-3.073-1.143,4.27,4.27,0,0,1,.85-6.609,16.4,16.4,0,0,1,6.518-1.787c.069,0,.1-.041.1-.129q-.1-3.032-2.751-3.034a7.157,7.157,0,0,0-3.419,1,.864.864,0,0,1-.669.089.811.811,0,0,1-.539-.424l-.257-.462a.955.955,0,0,1-.089-.706.822.822,0,0,1,.424-.553,10.423,10.423,0,0,1,5.066-1.44,4.826,4.826,0,0,1,3.96,1.594,6.988,6.988,0,0,1,1.312,4.551v7.792a.923.923,0,0,1-.928.926h-.642a1.008,1.008,0,0,1-.681-.257,1.118,1.118,0,0,1-.373-.642l-.1-.721c-.018-.033-.038-.053-.065-.053s-.046.018-.064.053A7.155,7.155,0,0,1,691.509,105.4Zm-.977-18.027a.92.92,0,0,1-.926-.926v-.206a.92.92,0,0,1,.926-.926h6.3a.92.92,0,0,1,.925.926v.206a.92.92,0,0,1-.925.926Zm1.9,15.637a5.287,5.287,0,0,0,3.4-1.6.278.278,0,0,0,.077-.206V97.9c0-.086-.033-.12-.1-.1a11.688,11.688,0,0,0-4.346,1.17,2.336,2.336,0,0,0-1.286,2.045,1.82,1.82,0,0,0,.617,1.518A2.582,2.582,0,0,0,692.435,103.015Z" transform="translate(-617.157 -84.088)" fill="#fff"/>
+        <path id="Path_7" data-name="Path 7" d="M792.08,98.907a2.68,2.68,0,0,1-2.3-.952,4.607,4.607,0,0,1-.708-2.779V78.489a.865.865,0,0,1,.271-.63A.893.893,0,0,1,790,77.59h1.157a.9.9,0,0,1,.657.269.865.865,0,0,1,.271.63V95.333a1.12,1.12,0,0,0,.411,1.028c.034.018.11.061.231.129s.206.12.257.155.12.081.206.14a.691.691,0,0,1,.193.193.438.438,0,0,1,.064.231l.1.566a.736.736,0,0,1,.026.18.96.96,0,0,1-.155.54.792.792,0,0,1-.591.386C792.585,98.9,792.336,98.907,792.08,98.907Z" transform="translate(-702.754 -77.59)" fill="#fff"/>
+        <path id="Path_8" data-name="Path 8" d="M840.663,81.944a1.988,1.988,0,0,1-1.389.5,1.94,1.94,0,0,1-1.376-.5,1.661,1.661,0,0,1-.539-1.274,1.692,1.692,0,0,1,.539-1.3,1.939,1.939,0,0,1,1.376-.5,1.978,1.978,0,0,1,1.389.5,1.673,1.673,0,0,1,.553,1.3A1.649,1.649,0,0,1,840.663,81.944ZM838.7,99.65a.92.92,0,0,1-.926-.926V86.072a.864.864,0,0,1,.269-.63.892.892,0,0,1,.657-.269h1.157a.9.9,0,0,1,.657.269.865.865,0,0,1,.271.63V98.723a.923.923,0,0,1-.928.926Z" transform="translate(-743.346 -78.666)" fill="#fff"/>
+      </g>
+      <path id="Path_9" data-name="Path 9" d="M125.632,125.382a1.531,1.531,0,0,1-1.532-1.532v-5.532c0-8.629,4.134-13.579,11.342-13.579a1.532,1.532,0,0,1,0,3.064c-5.493,0-8.28,3.537-8.28,10.517v5.532A1.529,1.529,0,0,1,125.632,125.382Z" transform="translate(-104.317 -88.043)" fill="#f1ca23"/>
+      <path id="Path_10" data-name="Path 10" d="M144.722,179.085a1.532,1.532,0,1,1,0-3.064c2.987,0,5.076-4,5.076-9.727V149.842a1.532,1.532,0,0,1,3.064,0v16.452C152.86,175.13,148.773,179.085,144.722,179.085Z" transform="translate(-120.364 -124.667)" fill="#f1ca23"/>
+      <path id="Path_11" data-name="Path 11" d="M84.262,37.339a1.531,1.531,0,0,1-1.532-1.532V1.532a1.532,1.532,0,0,1,3.064,0V35.809A1.531,1.531,0,0,1,84.262,37.339Z" transform="translate(-69.542)" fill="#f1ca23"/>
+      <path id="Path_12" data-name="Path 12" d="M42.892,37.339a1.531,1.531,0,0,1-1.532-1.532V1.532a1.532,1.532,0,0,1,3.064,0V35.809A1.531,1.531,0,0,1,42.892,37.339Z" transform="translate(-34.767)" fill="#f1ca23"/>
+      <path id="Path_13" data-name="Path 13" d="M1.532,37.339A1.531,1.531,0,0,1,0,35.808V1.532a1.532,1.532,0,0,1,3.064,0V35.809A1.533,1.533,0,0,1,1.532,37.339Z" fill="#f1ca23"/>
+    </g>
+    <text id="studio" transform="translate(542 353.2)" fill="#fff" font-size="27" font-family="NotoSans-ExtraLight, Noto Sans" font-weight="200"><tspan x="0" y="0">studio</tspan></text>
+  </g>
+</svg>

+ 12 - 0
dashboard/src/components/README.md

@@ -0,0 +1,12 @@
+# 组件
+
+## 目录
+
+某栏目的专用组件放在以该栏目命名的目录下
+
+- `libray` 前台(阅读)的栏目
+  - `栏目名称` 某栏目的专用组件
+  - `组件1.tsx` libray 下面的栏目的公共组件
+- `studio` 用户后台(课程发布等)
+
+nut目录为练习用途。里面的内容可能会被删除。**线上不要使用**。

+ 59 - 0
dashboard/src/components/admin/HeadBar.tsx

@@ -0,0 +1,59 @@
+import { Link } from "react-router-dom";
+import { Input, Layout, Space } from "antd";
+
+import img_banner from "../../assets/studio/images/wikipali_banner.svg";
+import UiLangSelect from "../general/UiLangSelect";
+import SignInAvatar from "../auth/SignInAvatar";
+import ToLibrary from "../auth/ToLibrary";
+import ThemeSelect from "../general/ThemeSelect";
+
+const { Search } = Input;
+const { Header } = Layout;
+
+const onSearch = (value: string) => console.log(value);
+
+const HeadBarWidget = () => {
+  return (
+    <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>
+        </div>
+        <div style={{ width: 500, lineHeight: 44 }}>
+          <Search
+            disabled
+            placeholder="input search text"
+            onSearch={onSearch}
+            style={{ width: "100%" }}
+          />
+        </div>
+        <div>
+          <Space>
+            <ToLibrary />
+            <SignInAvatar />
+            <UiLangSelect />
+            <ThemeSelect />
+          </Space>
+        </div>
+      </div>
+    </Header>
+  );
+};
+
+export default HeadBarWidget;

+ 80 - 0
dashboard/src/components/admin/LeftSider.tsx

@@ -0,0 +1,80 @@
+import { Link } from "react-router-dom";
+import type { MenuProps } from "antd";
+import { Affix, Layout } from "antd";
+import { Menu } from "antd";
+import { AppstoreOutlined, HomeOutlined } from "@ant-design/icons";
+
+const { Sider } = Layout;
+
+const onClick: MenuProps["onClick"] = (e) => {
+  console.log("click ", e);
+};
+
+type IWidgetHeadBar = {
+  selectedKeys?: string;
+};
+const LeftSiderWidget = ({ selectedKeys = "" }: IWidgetHeadBar) => {
+  const items: MenuProps["items"] = [
+    {
+      label: "API",
+      key: "api",
+      icon: <HomeOutlined />,
+      children: [
+        {
+          label: <Link to="/admin/api/dashboard">dashboard</Link>,
+          key: "dashboard",
+        },
+      ],
+    },
+    {
+      label: "管理",
+      key: "manage",
+      icon: <HomeOutlined />,
+      children: [
+        {
+          label: <Link to="/admin/relation/list">Relation</Link>,
+          key: "relation",
+        },
+        {
+          label: <Link to="/admin/nissaya-ending/list">Nissaya Ending</Link>,
+          key: "nissaya-ending",
+        },
+        {
+          label: <Link to="/admin/dictionary/list">Dictionary</Link>,
+          key: "dict",
+        },
+        {
+          label: <Link to="/admin/users/list">users</Link>,
+          key: "users",
+        },
+        {
+          label: <Link to="/admin/invite/list">invite</Link>,
+          key: "invite",
+        },
+      ],
+    },
+    {
+      label: "统计",
+      key: "advance",
+      icon: <AppstoreOutlined />,
+      children: [],
+    },
+  ];
+
+  return (
+    <Affix offsetTop={0}>
+      <Sider width={200} breakpoint="lg" className="site-layout-background">
+        <Menu
+          theme="light"
+          onClick={onClick}
+          defaultSelectedKeys={[selectedKeys]}
+          defaultOpenKeys={["basic", "advance", "collaboration"]}
+          mode="inline"
+          items={items}
+        />
+      </Sider>
+    </Affix>
+  );
+};
+
+export default LeftSiderWidget;

+ 64 - 0
dashboard/src/components/admin/api/ApiDelayHour.tsx

@@ -0,0 +1,64 @@
+import React, { useEffect, useState } from "react";
+import { Column } from "@ant-design/plots";
+import { put } from "../../../request";
+import { StatisticCard } from "@ant-design/pro-components";
+
+interface IApiDelay {
+  date: string;
+  value: number;
+}
+interface IApiDelayResponse {
+  ok: boolean;
+  message: string;
+  data: IApiDelay[];
+}
+interface IApiRequest {
+  api: string;
+  item: string;
+}
+
+interface IWidget {
+  title?: React.ReactNode;
+  type: "average" | "count" | "delay";
+  api?: string;
+}
+
+const ApiDelayHourWidget = ({ title, type, api = "all" }: IWidget) => {
+  const [delayData, setDelayData] = useState<IApiDelay[]>([]);
+
+  useEffect(() => {
+    put<IApiRequest, IApiDelayResponse>("/v2/api/10", {
+      api: api,
+      item: type,
+    }).then((json) => {
+      console.log("data", json.data);
+      setDelayData(json.data);
+    });
+  }, []);
+
+  const config = {
+    data: delayData,
+    xField: "date",
+    yField: "value",
+    seriesField: "",
+    xAxis: {
+      label: {
+        autoHide: true,
+        autoRotate: false,
+      },
+    },
+  };
+
+  return (
+    <StatisticCard
+      statistic={{
+        title: title,
+        value: "",
+        suffix: "/ ms",
+      }}
+      chart={<Column {...config} height={300} />}
+    />
+  );
+};
+
+export default ApiDelayHourWidget;

+ 83 - 0
dashboard/src/components/admin/api/ApiGauge.tsx

@@ -0,0 +1,83 @@
+import { useEffect, useRef, useState } from "react";
+import { Gauge } from "@ant-design/plots";
+import { get } from "../../../request";
+import { StatisticCard } from "@ant-design/pro-components";
+
+interface IApiResponse {
+  ok: boolean;
+  message: string;
+  data: number;
+}
+const ApiGaugeWidget = () => {
+  const min = 0;
+  const max = 1;
+  const [percent, setPercent] = useState<number>(0);
+  const [delay, setDelay] = useState<number>(0);
+  const maxAxis = 5000; //最大量程-毫秒
+
+  useEffect(() => {
+    let timer = setInterval(() => {
+      get<IApiResponse>("/v2/api/10?item=average").then((json) => {
+        setPercent(json.data / maxAxis);
+        setDelay(json.data);
+      });
+    }, 1000 * 5);
+    return () => {
+      clearInterval(timer);
+    };
+  }, []);
+
+  const graphRef: any = useRef(null);
+
+  const config = {
+    percent: percent,
+    range: {
+      ticks: [min, max],
+      color: ["l(0) 0:#30BF78 0.5:#FAAD14 1:#F4664A"],
+    },
+    indicator: {
+      pointer: {
+        style: {
+          stroke: "#D0D0D0",
+        },
+      },
+      pin: {
+        style: {
+          stroke: "#D0D0D0",
+        },
+      },
+    },
+    axis: {
+      label: {
+        formatter(v: any) {
+          return Number(v) * maxAxis;
+        },
+      },
+      subTickLine: {
+        count: 3,
+      },
+    },
+  };
+
+  return (
+    <StatisticCard
+      style={{ width: 400 }}
+      statistic={{
+        title: "平均相应时间",
+        value: delay,
+        suffix: "/ ms",
+      }}
+      chart={
+        <Gauge
+          ref={graphRef}
+          {...config}
+          onReady={(chart) => {
+            graphRef.current = chart;
+          }}
+        />
+      }
+    />
+  );
+};
+
+export default ApiGaugeWidget;

+ 42 - 0
dashboard/src/components/admin/relation/CaseSelect.tsx

@@ -0,0 +1,42 @@
+import { ProFormSelect } from "@ant-design/pro-components";
+
+import { useIntl } from "react-intl";
+
+interface IWidget {
+  name?: string;
+  width?: number | "md" | "sm" | "xl" | "xs" | "lg";
+}
+const CaseSelectWidget = ({ name = "case", width = "md" }: IWidget) => {
+  const intl = useIntl();
+  const _case = [
+    "nom",
+    "acc",
+    "gen",
+    "dat",
+    "inst",
+    "abl",
+    "loc",
+    "ger",
+    "adv",
+  ];
+  const caseOptions = _case.map((item) => {
+    return {
+      value: item,
+      label: intl.formatMessage({
+        id: `dict.fields.type.${item}.label`,
+        defaultMessage: item,
+      }),
+    };
+  });
+
+  return (
+    <ProFormSelect
+      options={caseOptions}
+      width={width}
+      name={name}
+      label={intl.formatMessage({ id: "forms.fields.case.label" })}
+    />
+  );
+};
+
+export default CaseSelectWidget;

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно