From 6df0e78b223ed8bd69b33d29ee4f8d6ef20103e5 Mon Sep 17 00:00:00 2001 From: Soulter <905617992@qq.com> Date: Tue, 17 Dec 2024 23:40:32 +0800 Subject: [PATCH] upload: dashboard from Soulter/AstrBot-Dashboard --- .dockerignore | 2 + .gitignore | 6 +- dashboard/.gitignore | 4 + dashboard/LICENSE | 21 + dashboard/README.md | 3 + dashboard/env.d.ts | 1 + dashboard/index.html | 19 + dashboard/public/_redirects | 1 + dashboard/public/favicon.svg | 1 + dashboard/src/App.vue | 7 + .../src/assets/images/auth/social-google.svg | 6 + dashboard/src/assets/images/favicon.svg | 18 + .../src/assets/images/icons/icon-card.svg | 5 + dashboard/src/assets/images/logos/logo.svg | 12 + .../src/assets/images/logos/logolight.svg | 12 + .../images/maintenance/img-error-bg.svg | 34 ++ .../images/maintenance/img-error-blue.svg | 43 ++ .../images/maintenance/img-error-purple.svg | 42 ++ .../images/maintenance/img-error-text.svg | 27 ++ .../src/assets/images/profile/user-round.svg | 15 + .../src/components/shared/AstrBotConfig.vue | 126 ++++++ .../components/shared/ConfigDetailCard.vue | 41 ++ .../components/shared/ConsoleDisplayer.vue | 77 ++++ .../src/components/shared/ExtensionCard.vue | 26 ++ .../src/components/shared/UiParentCard.vue | 20 + .../components/shared/WaitingForRestart.vue | 86 ++++ dashboard/src/config.ts | 17 + dashboard/src/layouts/blank/BlankLayout.vue | 8 + dashboard/src/layouts/full/FullLayout.vue | 26 ++ .../full/vertical-header/VerticalHeader.vue | 223 ++++++++++ .../layouts/full/vertical-sidebar/NavItem.vue | 35 ++ .../full/vertical-sidebar/VerticalSidebar.vue | 72 ++++ .../full/vertical-sidebar/sidebarItem.ts | 45 ++ dashboard/src/main.ts | 32 ++ dashboard/src/plugins/vuetify.ts | 30 ++ dashboard/src/router/AuthRoutes.ts | 16 + dashboard/src/router/MainRoutes.ts | 43 ++ dashboard/src/router/index.ts | 35 ++ dashboard/src/scss/_override.scss | 36 ++ dashboard/src/scss/_variables.scss | 124 ++++++ dashboard/src/scss/components/_VButtons.scss | 23 ++ dashboard/src/scss/components/_VCard.scss | 26 ++ dashboard/src/scss/components/_VField.scss | 9 + dashboard/src/scss/components/_VInput.scss | 17 + .../scss/components/_VNavigationDrawer.scss | 3 + dashboard/src/scss/components/_VShadow.scss | 3 + dashboard/src/scss/components/_VTabs.scss | 11 + .../src/scss/components/_VTextField.scss | 17 + dashboard/src/scss/layout/_container.scss | 124 ++++++ dashboard/src/scss/layout/_sidebar.scss | 51 +++ dashboard/src/scss/pages/_dashboards.scss | 93 +++++ dashboard/src/scss/style.scss | 16 + dashboard/src/stores/auth.ts | 42 ++ dashboard/src/stores/common.js | 43 ++ dashboard/src/stores/customizer.ts | 26 ++ dashboard/src/theme/LightTheme.ts | 41 ++ dashboard/src/types/themeTypes/ThemeType.ts | 35 ++ dashboard/src/types/vue3-print-nb.d.ts | 1 + dashboard/src/types/vue_tabler_icon.d.ts | 10 + dashboard/src/views/ATRIProject.vue | 87 ++++ dashboard/src/views/ConfigPage.vue | 220 ++++++++++ dashboard/src/views/ConsolePage.vue | 36 ++ dashboard/src/views/ExtensionPage.vue | 391 ++++++++++++++++++ .../views/authentication/auth/LoginPage.vue | 25 ++ .../authentication/authForms/AuthLogin.vue | 87 ++++ .../dashboards/default/DefaultDashboard.vue | 50 +++ .../default/components/MessageStat.vue | 114 +++++ .../default/components/OnlinePlatform.vue | 37 ++ .../default/components/OnlineTime.vue | 61 +++ .../default/components/PlatformStat.vue | 116 ++++++ .../default/components/TotalMessage.vue | 40 ++ dashboard/tsconfig.json | 18 + dashboard/tsconfig.vite-config.json | 9 + dashboard/vite.config.ts | 47 +++ 74 files changed, 3325 insertions(+), 1 deletion(-) create mode 100644 dashboard/.gitignore create mode 100644 dashboard/LICENSE create mode 100644 dashboard/README.md create mode 100644 dashboard/env.d.ts create mode 100644 dashboard/index.html create mode 100644 dashboard/public/_redirects create mode 100644 dashboard/public/favicon.svg create mode 100644 dashboard/src/App.vue create mode 100644 dashboard/src/assets/images/auth/social-google.svg create mode 100644 dashboard/src/assets/images/favicon.svg create mode 100644 dashboard/src/assets/images/icons/icon-card.svg create mode 100644 dashboard/src/assets/images/logos/logo.svg create mode 100644 dashboard/src/assets/images/logos/logolight.svg create mode 100644 dashboard/src/assets/images/maintenance/img-error-bg.svg create mode 100644 dashboard/src/assets/images/maintenance/img-error-blue.svg create mode 100644 dashboard/src/assets/images/maintenance/img-error-purple.svg create mode 100644 dashboard/src/assets/images/maintenance/img-error-text.svg create mode 100644 dashboard/src/assets/images/profile/user-round.svg create mode 100644 dashboard/src/components/shared/AstrBotConfig.vue create mode 100644 dashboard/src/components/shared/ConfigDetailCard.vue create mode 100644 dashboard/src/components/shared/ConsoleDisplayer.vue create mode 100644 dashboard/src/components/shared/ExtensionCard.vue create mode 100644 dashboard/src/components/shared/UiParentCard.vue create mode 100644 dashboard/src/components/shared/WaitingForRestart.vue create mode 100644 dashboard/src/config.ts create mode 100644 dashboard/src/layouts/blank/BlankLayout.vue create mode 100644 dashboard/src/layouts/full/FullLayout.vue create mode 100644 dashboard/src/layouts/full/vertical-header/VerticalHeader.vue create mode 100644 dashboard/src/layouts/full/vertical-sidebar/NavItem.vue create mode 100644 dashboard/src/layouts/full/vertical-sidebar/VerticalSidebar.vue create mode 100644 dashboard/src/layouts/full/vertical-sidebar/sidebarItem.ts create mode 100644 dashboard/src/main.ts create mode 100644 dashboard/src/plugins/vuetify.ts create mode 100644 dashboard/src/router/AuthRoutes.ts create mode 100644 dashboard/src/router/MainRoutes.ts create mode 100644 dashboard/src/router/index.ts create mode 100644 dashboard/src/scss/_override.scss create mode 100644 dashboard/src/scss/_variables.scss create mode 100644 dashboard/src/scss/components/_VButtons.scss create mode 100644 dashboard/src/scss/components/_VCard.scss create mode 100644 dashboard/src/scss/components/_VField.scss create mode 100644 dashboard/src/scss/components/_VInput.scss create mode 100644 dashboard/src/scss/components/_VNavigationDrawer.scss create mode 100644 dashboard/src/scss/components/_VShadow.scss create mode 100644 dashboard/src/scss/components/_VTabs.scss create mode 100644 dashboard/src/scss/components/_VTextField.scss create mode 100644 dashboard/src/scss/layout/_container.scss create mode 100644 dashboard/src/scss/layout/_sidebar.scss create mode 100644 dashboard/src/scss/pages/_dashboards.scss create mode 100644 dashboard/src/scss/style.scss create mode 100644 dashboard/src/stores/auth.ts create mode 100644 dashboard/src/stores/common.js create mode 100644 dashboard/src/stores/customizer.ts create mode 100644 dashboard/src/theme/LightTheme.ts create mode 100644 dashboard/src/types/themeTypes/ThemeType.ts create mode 100644 dashboard/src/types/vue3-print-nb.d.ts create mode 100644 dashboard/src/types/vue_tabler_icon.d.ts create mode 100644 dashboard/src/views/ATRIProject.vue create mode 100644 dashboard/src/views/ConfigPage.vue create mode 100644 dashboard/src/views/ConsolePage.vue create mode 100644 dashboard/src/views/ExtensionPage.vue create mode 100644 dashboard/src/views/authentication/auth/LoginPage.vue create mode 100644 dashboard/src/views/authentication/authForms/AuthLogin.vue create mode 100644 dashboard/src/views/dashboards/default/DefaultDashboard.vue create mode 100644 dashboard/src/views/dashboards/default/components/MessageStat.vue create mode 100644 dashboard/src/views/dashboards/default/components/OnlinePlatform.vue create mode 100644 dashboard/src/views/dashboards/default/components/OnlineTime.vue create mode 100644 dashboard/src/views/dashboards/default/components/PlatformStat.vue create mode 100644 dashboard/src/views/dashboards/default/components/TotalMessage.vue create mode 100644 dashboard/tsconfig.json create mode 100644 dashboard/tsconfig.vite-config.json create mode 100644 dashboard/vite.config.ts diff --git a/.dockerignore b/.dockerignore index f27cf068c..bd7666337 100644 --- a/.dockerignore +++ b/.dockerignore @@ -16,3 +16,5 @@ venv*/ ENV/ .conda/ README*.md +dashboard/ +data/ \ No newline at end of file diff --git a/.gitignore b/.gitignore index 77409966d..aaf95b1a4 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,8 @@ addons/plugins tests/astrbot_plugin_openai -chroma \ No newline at end of file +chroma +node_modules/ +.DS_Store +package-lock.json +package.json \ No newline at end of file diff --git a/dashboard/.gitignore b/dashboard/.gitignore new file mode 100644 index 000000000..665846982 --- /dev/null +++ b/dashboard/.gitignore @@ -0,0 +1,4 @@ +node_modules/ +.DS_Store +package-lock.json +package.json \ No newline at end of file diff --git a/dashboard/LICENSE b/dashboard/LICENSE new file mode 100644 index 000000000..7e99c6802 --- /dev/null +++ b/dashboard/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 CodedThemes + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/dashboard/README.md b/dashboard/README.md new file mode 100644 index 000000000..52df63351 --- /dev/null +++ b/dashboard/README.md @@ -0,0 +1,3 @@ +# AstrBot 管理面板 + +基于 CodedThemes/Berry 模板开发。 \ No newline at end of file diff --git a/dashboard/env.d.ts b/dashboard/env.d.ts new file mode 100644 index 000000000..11f02fe2a --- /dev/null +++ b/dashboard/env.d.ts @@ -0,0 +1 @@ +/// diff --git a/dashboard/index.html b/dashboard/index.html new file mode 100644 index 000000000..f71608a69 --- /dev/null +++ b/dashboard/index.html @@ -0,0 +1,19 @@ + + + + + + + + + + AstrBot - 仪表盘 + + +
+ + + diff --git a/dashboard/public/_redirects b/dashboard/public/_redirects new file mode 100644 index 000000000..ad37e2c2c --- /dev/null +++ b/dashboard/public/_redirects @@ -0,0 +1 @@ +/* /index.html 200 diff --git a/dashboard/public/favicon.svg b/dashboard/public/favicon.svg new file mode 100644 index 000000000..db85f3f33 --- /dev/null +++ b/dashboard/public/favicon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dashboard/src/App.vue b/dashboard/src/App.vue new file mode 100644 index 000000000..bf88393fd --- /dev/null +++ b/dashboard/src/App.vue @@ -0,0 +1,7 @@ + + + diff --git a/dashboard/src/assets/images/auth/social-google.svg b/dashboard/src/assets/images/auth/social-google.svg new file mode 100644 index 000000000..2231ce986 --- /dev/null +++ b/dashboard/src/assets/images/auth/social-google.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/dashboard/src/assets/images/favicon.svg b/dashboard/src/assets/images/favicon.svg new file mode 100644 index 000000000..72033ff62 --- /dev/null +++ b/dashboard/src/assets/images/favicon.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/dashboard/src/assets/images/icons/icon-card.svg b/dashboard/src/assets/images/icons/icon-card.svg new file mode 100644 index 000000000..e877b599e --- /dev/null +++ b/dashboard/src/assets/images/icons/icon-card.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/dashboard/src/assets/images/logos/logo.svg b/dashboard/src/assets/images/logos/logo.svg new file mode 100644 index 000000000..79eb9bd9d --- /dev/null +++ b/dashboard/src/assets/images/logos/logo.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/dashboard/src/assets/images/logos/logolight.svg b/dashboard/src/assets/images/logos/logolight.svg new file mode 100644 index 000000000..a02bbbba9 --- /dev/null +++ b/dashboard/src/assets/images/logos/logolight.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/dashboard/src/assets/images/maintenance/img-error-bg.svg b/dashboard/src/assets/images/maintenance/img-error-bg.svg new file mode 100644 index 000000000..57af439c9 --- /dev/null +++ b/dashboard/src/assets/images/maintenance/img-error-bg.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dashboard/src/assets/images/maintenance/img-error-blue.svg b/dashboard/src/assets/images/maintenance/img-error-blue.svg new file mode 100644 index 000000000..a72084386 --- /dev/null +++ b/dashboard/src/assets/images/maintenance/img-error-blue.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dashboard/src/assets/images/maintenance/img-error-purple.svg b/dashboard/src/assets/images/maintenance/img-error-purple.svg new file mode 100644 index 000000000..12904c1a8 --- /dev/null +++ b/dashboard/src/assets/images/maintenance/img-error-purple.svg @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dashboard/src/assets/images/maintenance/img-error-text.svg b/dashboard/src/assets/images/maintenance/img-error-text.svg new file mode 100644 index 000000000..16ed50aaf --- /dev/null +++ b/dashboard/src/assets/images/maintenance/img-error-text.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dashboard/src/assets/images/profile/user-round.svg b/dashboard/src/assets/images/profile/user-round.svg new file mode 100644 index 000000000..db47c4ba8 --- /dev/null +++ b/dashboard/src/assets/images/profile/user-round.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/dashboard/src/components/shared/AstrBotConfig.vue b/dashboard/src/components/shared/AstrBotConfig.vue new file mode 100644 index 000000000..f9554158c --- /dev/null +++ b/dashboard/src/components/shared/AstrBotConfig.vue @@ -0,0 +1,126 @@ + + + \ No newline at end of file diff --git a/dashboard/src/components/shared/ConfigDetailCard.vue b/dashboard/src/components/shared/ConfigDetailCard.vue new file mode 100644 index 000000000..921c2d95d --- /dev/null +++ b/dashboard/src/components/shared/ConfigDetailCard.vue @@ -0,0 +1,41 @@ + + + diff --git a/dashboard/src/components/shared/ConsoleDisplayer.vue b/dashboard/src/components/shared/ConsoleDisplayer.vue new file mode 100644 index 000000000..c0f4447ff --- /dev/null +++ b/dashboard/src/components/shared/ConsoleDisplayer.vue @@ -0,0 +1,77 @@ + + + + + \ No newline at end of file diff --git a/dashboard/src/components/shared/ExtensionCard.vue b/dashboard/src/components/shared/ExtensionCard.vue new file mode 100644 index 000000000..0724b1bc7 --- /dev/null +++ b/dashboard/src/components/shared/ExtensionCard.vue @@ -0,0 +1,26 @@ + + + diff --git a/dashboard/src/components/shared/UiParentCard.vue b/dashboard/src/components/shared/UiParentCard.vue new file mode 100644 index 000000000..5eda86a4c --- /dev/null +++ b/dashboard/src/components/shared/UiParentCard.vue @@ -0,0 +1,20 @@ + + + diff --git a/dashboard/src/components/shared/WaitingForRestart.vue b/dashboard/src/components/shared/WaitingForRestart.vue new file mode 100644 index 000000000..3fad97832 --- /dev/null +++ b/dashboard/src/components/shared/WaitingForRestart.vue @@ -0,0 +1,86 @@ + + + \ No newline at end of file diff --git a/dashboard/src/config.ts b/dashboard/src/config.ts new file mode 100644 index 000000000..2bb5c5fd1 --- /dev/null +++ b/dashboard/src/config.ts @@ -0,0 +1,17 @@ +export type ConfigProps = { + Sidebar_drawer: boolean; + Customizer_drawer: boolean; + mini_sidebar: boolean; + fontTheme: string; + inputBg: boolean; +}; + +const config: ConfigProps = { + Sidebar_drawer: true, + Customizer_drawer: false, + mini_sidebar: false, + fontTheme: 'Roboto', + inputBg: false +}; + +export default config; diff --git a/dashboard/src/layouts/blank/BlankLayout.vue b/dashboard/src/layouts/blank/BlankLayout.vue new file mode 100644 index 000000000..09d66466e --- /dev/null +++ b/dashboard/src/layouts/blank/BlankLayout.vue @@ -0,0 +1,8 @@ + + diff --git a/dashboard/src/layouts/full/FullLayout.vue b/dashboard/src/layouts/full/FullLayout.vue new file mode 100644 index 000000000..013a1f2e0 --- /dev/null +++ b/dashboard/src/layouts/full/FullLayout.vue @@ -0,0 +1,26 @@ + + + diff --git a/dashboard/src/layouts/full/vertical-header/VerticalHeader.vue b/dashboard/src/layouts/full/vertical-header/VerticalHeader.vue new file mode 100644 index 000000000..4945a3911 --- /dev/null +++ b/dashboard/src/layouts/full/vertical-header/VerticalHeader.vue @@ -0,0 +1,223 @@ + + + diff --git a/dashboard/src/layouts/full/vertical-sidebar/NavItem.vue b/dashboard/src/layouts/full/vertical-sidebar/NavItem.vue new file mode 100644 index 000000000..4a29d7516 --- /dev/null +++ b/dashboard/src/layouts/full/vertical-sidebar/NavItem.vue @@ -0,0 +1,35 @@ + + + diff --git a/dashboard/src/layouts/full/vertical-sidebar/VerticalSidebar.vue b/dashboard/src/layouts/full/vertical-sidebar/VerticalSidebar.vue new file mode 100644 index 000000000..9c8e50f58 --- /dev/null +++ b/dashboard/src/layouts/full/vertical-sidebar/VerticalSidebar.vue @@ -0,0 +1,72 @@ + + + + + \ No newline at end of file diff --git a/dashboard/src/layouts/full/vertical-sidebar/sidebarItem.ts b/dashboard/src/layouts/full/vertical-sidebar/sidebarItem.ts new file mode 100644 index 000000000..7d4766bd3 --- /dev/null +++ b/dashboard/src/layouts/full/vertical-sidebar/sidebarItem.ts @@ -0,0 +1,45 @@ +export interface menu { + header?: string; + title?: string; + icon?: string; + to?: string; + divider?: boolean; + chip?: string; + chipColor?: string; + chipVariant?: string; + chipIcon?: string; + children?: menu[]; + disabled?: boolean; + type?: string; + subCaption?: string; +} + +const sidebarItem: menu[] = [ + { + title: '面板', + icon: 'mdi-view-dashboard', + to: '/dashboard/default' + }, + { + title: '配置', + icon: 'mdi-cog', + to: '/config', + }, + { + title: '插件', + icon: 'mdi-puzzle', + to: '/extension' + }, + { + title: '控制台', + icon: 'mdi-console', + to: '/console' + }, + // { + // title: 'Project ATRI', + // icon: 'mdi-grain', + // to: '/project-atri' + // }, +]; + +export default sidebarItem; diff --git a/dashboard/src/main.ts b/dashboard/src/main.ts new file mode 100644 index 000000000..1924ee731 --- /dev/null +++ b/dashboard/src/main.ts @@ -0,0 +1,32 @@ +import { createApp } from 'vue'; +import { createPinia } from 'pinia'; +import App from './App.vue'; +import { router } from './router'; +import vuetify from './plugins/vuetify'; +import '@/scss/style.scss'; +import VueApexCharts from 'vue3-apexcharts'; + +import print from 'vue3-print-nb'; +import { loader } from '@guolao/vue-monaco-editor' +import axios from 'axios'; + +const app = createApp(App); +app.use(router); +app.use(createPinia()); +app.use(print); +app.use(VueApexCharts); +app.use(vuetify).mount('#app'); + +axios.interceptors.request.use((config) => { + const token = localStorage.getItem('token'); + if (token) { + config.headers['Authorization'] = `Bearer ${token}`; + } + return config; +}); + +loader.config({ + paths: { + vs: 'https://cdn.jsdelivr.net/npm/monaco-editor@0.43.0/min/vs', + }, +}) \ No newline at end of file diff --git a/dashboard/src/plugins/vuetify.ts b/dashboard/src/plugins/vuetify.ts new file mode 100644 index 000000000..cbb865d23 --- /dev/null +++ b/dashboard/src/plugins/vuetify.ts @@ -0,0 +1,30 @@ +import { createVuetify } from 'vuetify'; +import '@mdi/font/css/materialdesignicons.css'; +import * as components from 'vuetify/components'; +import * as directives from 'vuetify/directives'; +import { PurpleTheme } from '@/theme/LightTheme'; + +export default createVuetify({ + components, + directives, + + theme: { + defaultTheme: 'PurpleTheme', + themes: { + PurpleTheme + } + }, + defaults: { + VBtn: {}, + VCard: { + rounded: 'md' + }, + VTextField: { + rounded: 'lg' + }, + VTooltip: { + // set v-tooltip default location to top + location: 'top' + } + } +}); diff --git a/dashboard/src/router/AuthRoutes.ts b/dashboard/src/router/AuthRoutes.ts new file mode 100644 index 000000000..89cbc603b --- /dev/null +++ b/dashboard/src/router/AuthRoutes.ts @@ -0,0 +1,16 @@ +const AuthRoutes = { + path: '/auth', + component: () => import('@/layouts/blank/BlankLayout.vue'), + meta: { + requiresAuth: false + }, + children: [ + { + name: 'Login', + path: '/auth/login', + component: () => import('@/views/authentication/auth/LoginPage.vue') + } + ] +}; + +export default AuthRoutes; diff --git a/dashboard/src/router/MainRoutes.ts b/dashboard/src/router/MainRoutes.ts new file mode 100644 index 000000000..32c82696a --- /dev/null +++ b/dashboard/src/router/MainRoutes.ts @@ -0,0 +1,43 @@ +const MainRoutes = { + path: '/main', + meta: { + requiresAuth: true + }, + redirect: '/main/dashboard/default', + component: () => import('@/layouts/full/FullLayout.vue'), + children: [ + { + name: 'Dashboard', + path: '/', + component: () => import('@/views/dashboards/default/DefaultDashboard.vue') + }, + { + name: 'Extensions', + path: '/extension', + component: () => import('@/views/ExtensionPage.vue') + }, + { + name: 'Configs', + path: '/config', + component: () => import('@/views/ConfigPage.vue') + }, + + { + name: 'Default', + path: '/dashboard/default', + component: () => import('@/views/dashboards/default/DefaultDashboard.vue') + }, + { + name: 'Console', + path: '/console', + component: () => import('@/views/ConsolePage.vue') + }, + { + name: 'Project ATRI', + path: '/project-atri', + component: () => import('@/views/ATRIProject.vue') + } + ] +}; + +export default MainRoutes; diff --git a/dashboard/src/router/index.ts b/dashboard/src/router/index.ts new file mode 100644 index 000000000..a56154f18 --- /dev/null +++ b/dashboard/src/router/index.ts @@ -0,0 +1,35 @@ +import { createRouter, createWebHistory } from 'vue-router'; +import MainRoutes from './MainRoutes'; +import AuthRoutes from './AuthRoutes'; +import { useAuthStore } from '@/stores/auth'; + +export const router = createRouter({ + history: createWebHistory(import.meta.env.BASE_URL), + routes: [ + MainRoutes, + AuthRoutes + ] +}); + +interface AuthStore { + username: string; + returnUrl: string | null; + login(username: string, password: string): Promise; + logout(): void; + has_token(): boolean; +} + +router.beforeEach(async (to, from, next) => { + const publicPages = ['/auth/login']; + const authRequired = !publicPages.includes(to.path); + const auth: AuthStore = useAuthStore(); + + if (to.matched.some((record) => record.meta.requiresAuth)) { + if (authRequired && !auth.has_token()) { + auth.returnUrl = to.fullPath; + return next('/auth/login'); + } else next(); + } else { + next(); + } +}); diff --git a/dashboard/src/scss/_override.scss b/dashboard/src/scss/_override.scss new file mode 100644 index 000000000..178c37da6 --- /dev/null +++ b/dashboard/src/scss/_override.scss @@ -0,0 +1,36 @@ +html { + .bg-success { + color: white !important; + } +} + +.v-row + .v-row { + margin-top: 0px; +} + +.v-divider { + opacity: 1; + border-color: rgba(var(--v-theme-borderLight), 0.36); +} + +.v-selection-control { + flex: unset; +} + +.customizer-btn .icon { + animation: progress-circular-rotate 1.4s linear infinite; + transform-origin: center center; + transition: all 0.2s ease-in-out; +} + +.no-spacer { + .v-list-item__spacer { + display: none !important; + } +} + +@keyframes progress-circular-rotate { + 100% { + transform: rotate(270deg); + } +} diff --git a/dashboard/src/scss/_variables.scss b/dashboard/src/scss/_variables.scss new file mode 100644 index 000000000..3584fff1e --- /dev/null +++ b/dashboard/src/scss/_variables.scss @@ -0,0 +1,124 @@ +@use 'sass:math'; +@use 'sass:map'; +@use 'sass:meta'; +@use 'vuetify/lib/styles/tools/functions' as *; + +// This will false all colors which is not necessory for theme +$color-pack: false; + +// Global font size and border radius +$font-size-root: 1rem; +$border-radius-root: 8px; +$body-font-family: 'Roboto', sans-serif !default; +$heading-font-family: $body-font-family !default; +$btn-font-weight: 400 !default; +$btn-letter-spacing: 0 !default; + +// Global Radius as per breakeven point +$rounded: () !default; +$rounded: map-deep-merge( + ( + 0: 0, + 'sm': $border-radius-root * 0.5, + null: $border-radius-root, + 'md': $border-radius-root * 1, + 'lg': $border-radius-root * 2, + 'xl': $border-radius-root * 6, + 'pill': 9999px, + 'circle': 50%, + 'shaped': $border-radius-root * 6 0 + ), + $rounded +); +// Global Typography +$typography: () !default; +$typography: map-deep-merge( + ( + 'h1': ( + 'size': 2.125rem, + 'weight': 700, + 'line-height': 3.5rem, + 'font-family': inherit + ), + 'h2': ( + 'size': 1.5rem, + 'weight': 700, + 'line-height': 2.5rem, + 'font-family': inherit + ), + 'h3': ( + 'size': 1.25rem, + 'weight': 600, + 'line-height': 2rem, + 'font-family': inherit + ), + 'h4': ( + 'size': 1rem, + 'weight': 600, + 'line-height': 1.5rem, + 'font-family': inherit + ), + 'h5': ( + 'size': 0.875rem, + 'weight': 500, + 'line-height': 1.2rem, + 'font-family': inherit + ), + 'h6': ( + 'size': 0.75rem, + 'weight': 500, + 'font-family': inherit + ), + 'subtitle-1': ( + 'size': 0.875rem, + 'weight': 500, + 'line-height': 1rem, + 'font-family': inherit + ), + 'subtitle-2': ( + 'size': 0.75rem, + 'weight': 400, + 'line-height': 1rem, + 'font-family': inherit + ), + 'body-1': ( + 'size': 0.875rem, + 'weight': 400, + 'font-family': inherit + ), + 'body-2': ( + 'size': 0.75rem, + 'weight': 400, + 'font-family': inherit + ), + 'button': ( + 'size': 0.875rem, + 'weight': 500, + 'font-family': inherit, + 'text-transform': uppercase + ), + 'caption': ( + 'size': 0.75rem, + 'weight': 400, + 'font-family': inherit + ), + 'overline': ( + 'size': 0.75rem, + 'weight': 500, + 'font-family': inherit, + 'text-transform': uppercase + ) + ), + $typography +); + +// Custom Variables +// colors +$white: #fff !default; + +// cards +$card-item-spacer-xy: 20px 24px !default; +$card-text-spacer: 24px !default; +$card-title-size: 18px !default; +// Global Shadow +$box-shadow: 1px 0 20px rgb(0 0 0 / 8%); diff --git a/dashboard/src/scss/components/_VButtons.scss b/dashboard/src/scss/components/_VButtons.scss new file mode 100644 index 000000000..a7d095e95 --- /dev/null +++ b/dashboard/src/scss/components/_VButtons.scss @@ -0,0 +1,23 @@ +// +// Light Buttons +// + +.v-btn { + &.bg-lightsecondary { + &:hover, + &:active, + &:focus { + background-color: rgb(var(--v-theme-secondary)) !important; + color: $white !important; + } + } +} + +.v-btn { + text-transform: capitalize; + letter-spacing: $btn-letter-spacing; +} +.v-btn--icon.v-btn--density-default { + width: calc(var(--v-btn-height) + 6px); + height: calc(var(--v-btn-height) + 6px); +} diff --git a/dashboard/src/scss/components/_VCard.scss b/dashboard/src/scss/components/_VCard.scss new file mode 100644 index 000000000..10dcaaf86 --- /dev/null +++ b/dashboard/src/scss/components/_VCard.scss @@ -0,0 +1,26 @@ +// Outline Card +.v-card--variant-outlined { + border-color: rgba(var(--v-theme-borderLight), 0.36); + .v-divider { + border-color: rgba(var(--v-theme-borderLight), 0.36); + } +} + +.v-card-text { + padding: $card-text-spacer; +} + +.v-card { + width: 100%; + overflow: visible; + &.withbg { + background-color: rgb(var(--v-theme-background)); + } + &.overflow-hidden { + overflow: hidden; + } +} + +.v-card-item { + padding: $card-item-spacer-xy; +} diff --git a/dashboard/src/scss/components/_VField.scss b/dashboard/src/scss/components/_VField.scss new file mode 100644 index 000000000..97352acf5 --- /dev/null +++ b/dashboard/src/scss/components/_VField.scss @@ -0,0 +1,9 @@ +.v-field--variant-outlined .v-field__outline__start.v-locale--is-ltr, +.v-locale--is-ltr .v-field--variant-outlined .v-field__outline__start { + border-radius: $border-radius-root 0 0 $border-radius-root; +} + +.v-field--variant-outlined .v-field__outline__end.v-locale--is-ltr, +.v-locale--is-ltr .v-field--variant-outlined .v-field__outline__end { + border-radius: 0 $border-radius-root $border-radius-root 0; +} diff --git a/dashboard/src/scss/components/_VInput.scss b/dashboard/src/scss/components/_VInput.scss new file mode 100644 index 000000000..60b0f320b --- /dev/null +++ b/dashboard/src/scss/components/_VInput.scss @@ -0,0 +1,17 @@ +.v-input--density-default, +.v-field--variant-solo, +.v-field--variant-filled { + --v-input-control-height: 51px; + --v-input-padding-top: 14px; +} +.v-input--density-comfortable { + --v-input-control-height: 56px; + --v-input-padding-top: 17px; +} +.v-label { + font-size: 0.975rem; +} +.v-switch .v-label, +.v-checkbox .v-label { + opacity: 1; +} diff --git a/dashboard/src/scss/components/_VNavigationDrawer.scss b/dashboard/src/scss/components/_VNavigationDrawer.scss new file mode 100644 index 000000000..9994ae913 --- /dev/null +++ b/dashboard/src/scss/components/_VNavigationDrawer.scss @@ -0,0 +1,3 @@ +.v-navigation-drawer__scrim.fade-transition-leave-to { + display: none; +} diff --git a/dashboard/src/scss/components/_VShadow.scss b/dashboard/src/scss/components/_VShadow.scss new file mode 100644 index 000000000..aebe0e8e4 --- /dev/null +++ b/dashboard/src/scss/components/_VShadow.scss @@ -0,0 +1,3 @@ +.elevation-10 { + box-shadow: $box-shadow !important; +} diff --git a/dashboard/src/scss/components/_VTabs.scss b/dashboard/src/scss/components/_VTabs.scss new file mode 100644 index 000000000..afb08fd46 --- /dev/null +++ b/dashboard/src/scss/components/_VTabs.scss @@ -0,0 +1,11 @@ +.theme-tab { + &.v-tabs { + .v-tab { + border-radius: $border-radius-root !important; + min-width: auto !important; + &.v-slide-group-item--active { + background: rgb(var(--v-theme-primary)); + } + } + } +} diff --git a/dashboard/src/scss/components/_VTextField.scss b/dashboard/src/scss/components/_VTextField.scss new file mode 100644 index 000000000..c74c9dadc --- /dev/null +++ b/dashboard/src/scss/components/_VTextField.scss @@ -0,0 +1,17 @@ +.v-text-field input { + font-size: 0.875rem; +} +.v-input--density-default { + .v-field__input { + min-height: 51px; + } +} + +.v-field__outline { + color: rgb(var(--v-theme-inputBorder)); +} +.inputWithbg { + .v-field--variant-outlined { + background-color: rgba(0, 0, 0, 0.025); + } +} diff --git a/dashboard/src/scss/layout/_container.scss b/dashboard/src/scss/layout/_container.scss new file mode 100644 index 000000000..45971e2e1 --- /dev/null +++ b/dashboard/src/scss/layout/_container.scss @@ -0,0 +1,124 @@ +html { + overflow-y: auto; +} +.v-main { + margin-right: 20px; +} +@media (max-width: 1279px) { + .v-main { + margin: 0 10px; + } +} +.spacer { + padding: 100px 0; +} +@media (max-width: 800px) { + .spacer { + padding: 40px 0; + } +} + +.page-wrapper { + min-height: calc(100vh - 100px); + padding: 15px; + border-radius: $border-radius-root; + background: rgb(var(--v-theme-containerBg)); +} +$sizes: ( + 'display-1': 44px, + 'display-2': 40px, + 'display-3': 30px, + 'h1': 36px, + 'h2': 30px, + 'h3': 21px, + 'h4': 18px, + 'h5': 16px, + 'h6': 14px, + 'text-8': 8px, + 'text-10': 10px, + 'text-13': 13px, + 'text-18': 18px, + 'text-20': 20px, + 'text-24': 24px, + 'body-text-1': 10px +); + +@each $pixel, $size in $sizes { + .#{$pixel} { + font-size: $size; + line-height: $size + 10; + } +} + +.customizer-btn { + position: fixed; + top: 25%; + right: 10px; + border-radius: 50% 50% 4px; + .icon { + animation: progress-circular-rotate 1.4s linear infinite; + transform-origin: center center; + transition: all 0.2s ease-in-out; + } +} +.w-100 { + width: 100%; +} + +.h-100vh { + height: 100vh; +} + +.gap-3 { + gap: 16px; +} + +.text-white { + color: rgb(255, 255, 255) !important; +} + +// font family + +body { + .Poppins { + font-family: 'Poppins', sans-serif !important; + } + + .Inter { + font-family: 'Inter', sans-serif !important; + } +} + +@keyframes blink { + 50% { + opacity: 0; + } + 100% { + opacity: 1; + } +} +@keyframes bounce { + 0%, + 20%, + 53%, + to { + animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + transform: translateZ(0); + } + 40%, + 43% { + animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06); + transform: translate3d(0, -5px, 0); + } + 70% { + animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06); + transform: translate3d(0, -7px, 0); + } + 80% { + transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + transform: translateZ(0); + } + 90% { + transform: translate3d(0, -2px, 0); + } +} diff --git a/dashboard/src/scss/layout/_sidebar.scss b/dashboard/src/scss/layout/_sidebar.scss new file mode 100644 index 000000000..13325e6c8 --- /dev/null +++ b/dashboard/src/scss/layout/_sidebar.scss @@ -0,0 +1,51 @@ +/*This is for the logo*/ +.leftSidebar { + border: 0px; + box-shadow: none !important; +} +.listitem { + height: calc(100vh - 100px); + .v-list { + color: rgb(var(--v-theme-lightText)); + } + .v-list-group__items .v-list-item, + .v-list-item { + border-radius: $border-radius-root; + padding-inline-start: calc(12px + var(--indent-padding) / 2) !important; + &:hover { + color: rgb(var(--v-theme-secondary)); + } + } + .leftPadding { + margin-left: 4px; + } +} +.v-navigation-drawer--rail { + .scrollnavbar .v-list .v-list-group__items, + .hide-menu { + opacity: 1; + } + .leftPadding { + margin-left: 0px; + } +} +@media only screen and (min-width: 1170px) { + .mini-sidebar { + .logo { + width: 90px; + overflow: hidden; + } + .leftSidebar:hover { + box-shadow: $box-shadow !important; + } + .v-navigation-drawer--expand-on-hover:hover { + .logo { + width: 100%; + } + .v-list .v-list-group__items, + .hide-menu { + opacity: 1; + } + } + } +} diff --git a/dashboard/src/scss/pages/_dashboards.scss b/dashboard/src/scss/pages/_dashboards.scss new file mode 100644 index 000000000..62b232636 --- /dev/null +++ b/dashboard/src/scss/pages/_dashboards.scss @@ -0,0 +1,93 @@ +.bubble-shape { + position: relative; + &:before { + content: ''; + position: absolute; + width: 210px; + height: 210px; + border-radius: 50%; + top: -125px; + right: -15px; + opacity: 0.5; + } + &:after { + content: ''; + position: absolute; + width: 210px; + height: 210px; + border-radius: 50%; + top: -85px; + right: -95px; + } + + // &.bubble-primary-shape { + // &::before { + // background: rgb(var(--v-theme-darkprimary)); + // } + // &::after { + // background: rgb(var(--v-theme-darkprimary)); + // } + // } + + // &.bubble-secondary-shape { + // &::before { + // background: rgb(var(--v-theme-darksecondary)); + // } + // &::after { + // background: rgb(var(--v-theme-darksecondary)); + // } + // } +} + +.z-1 { + z-index: 1; + position: relative; +} +.bubble-shape-sm { + position: relative; + &::before { + content: ''; + position: absolute; + width: 210px; + height: 210px; + border-radius: 50%; + top: -160px; + right: -130px; + } + // &.bubble-primary { + // &::before { + // background: linear-gradient(140.9deg, rgb(var(--v-theme-lightprimary)) -14.02%, rgba(var(--v-theme-darkprimary), 0) 77.58%); + // } + // } + &::after { + content: ''; + position: absolute; + width: 210px; + height: 210px; + border-radius: 50%; + top: -30px; + right: -180px; + } + // &.bubble-primary { + // &::after { + // background: linear-gradient(210.04deg, rgb(var(--v-theme-lightprimary)) -50.94%, rgba(var(--v-theme-darkprimary), 0) 83.49%); + // } + // } + + // &.bubble-warning { + // &::before { + // background: linear-gradient(140.9deg, rgb(var(--v-theme-warning)) -14.02%, rgba(144, 202, 249, 0) 70.5%); + // } + // } + + // &.bubble-warning { + // &::after { + // background: linear-gradient(210.04deg, rgb(var(--v-theme-warning)) -50.94%, rgba(144, 202, 249, 0) 83.49%); + // } + // } +} + +.rounded-square { + width: 20px; + height: 20px; +} diff --git a/dashboard/src/scss/style.scss b/dashboard/src/scss/style.scss new file mode 100644 index 000000000..60a8b11ff --- /dev/null +++ b/dashboard/src/scss/style.scss @@ -0,0 +1,16 @@ +@import './variables'; +@import 'vuetify/styles/main.sass'; +@import './override'; +@import './layout/container'; +@import './layout/sidebar'; + +@import './components/VButtons'; +@import './components/VCard'; +@import './components/VField'; +@import './components/VInput'; +@import './components/VNavigationDrawer'; +@import './components/VShadow'; +@import './components/VTextField'; +@import './components/VTabs'; + +@import './pages/dashboards'; diff --git a/dashboard/src/stores/auth.ts b/dashboard/src/stores/auth.ts new file mode 100644 index 000000000..7eece8eb5 --- /dev/null +++ b/dashboard/src/stores/auth.ts @@ -0,0 +1,42 @@ +import { defineStore } from 'pinia'; +import { router } from '@/router'; +import axios from 'axios'; + +export const useAuthStore = defineStore({ + id: 'auth', + state: () => ({ + // @ts-ignore + username: '', + returnUrl: null + }), + actions: { + async login(username: string, password: string): Promise { + try { + const res = await axios.post('/api/auth/login', { + username: username, + password: password + }); + + if (res.data.status === 'error') { + return Promise.reject(res.data.message); + } + + this.username = res.data.data.username + localStorage.setItem('user', this.username); + localStorage.setItem('token', res.data.data.token); + router.push(this.returnUrl || '/dashboard/default'); + } catch (error) { + return Promise.reject(error); + } + }, + logout() { + this.username = ''; + localStorage.removeItem('username'); + localStorage.removeItem('token'); + router.push('/auth/login'); + }, + has_token(): boolean { + return !!localStorage.getItem('token'); + } + } +}); diff --git a/dashboard/src/stores/common.js b/dashboard/src/stores/common.js new file mode 100644 index 000000000..92f6546b0 --- /dev/null +++ b/dashboard/src/stores/common.js @@ -0,0 +1,43 @@ +import { defineStore } from 'pinia'; +import axios from 'axios'; + +export const useCommonStore = defineStore({ + id: 'common', + state: () => ({ + // @ts-ignore + websocket: null, + log_cache: [], + log_cache_max_len: 1000, + startTime: -1, + }), + actions: { + createWebSocket() { + if (this.websocket) { + return + } + let protocol = window.location.protocol === 'https:' ? 'wss' : 'ws' + let route = '/api/live-log' + let port = window.location.port + let url = `${protocol}://${window.location.hostname}:${port}${route}` + console.log('websocket url:', url) + this.websocket = new WebSocket(url) + this.websocket.onmessage = (evt) => { + this.log_cache.push(evt.data) + if (this.log_cache.length > this.log_cache_max_len) { + this.log_cache.shift() + } + } + }, + getLogCache() { + return this.log_cache + }, + getStartTime() { + if (this.startTime !== -1) { + return this.startTime + } + axios.get('/api/stat/start-time').then((res) => { + this.startTime = res.data.data.start_time + }) + }, + } +}); diff --git a/dashboard/src/stores/customizer.ts b/dashboard/src/stores/customizer.ts new file mode 100644 index 000000000..2f431b4e2 --- /dev/null +++ b/dashboard/src/stores/customizer.ts @@ -0,0 +1,26 @@ +import { defineStore } from 'pinia'; +import config from '@/config'; + +export const useCustomizerStore = defineStore({ + id: 'customizer', + state: () => ({ + Sidebar_drawer: config.Sidebar_drawer, + Customizer_drawer: config.Customizer_drawer, + mini_sidebar: config.mini_sidebar, + fontTheme: "Poppins", + inputBg: config.inputBg + }), + + getters: {}, + actions: { + SET_SIDEBAR_DRAWER() { + this.Sidebar_drawer = !this.Sidebar_drawer; + }, + SET_MINI_SIDEBAR(payload: boolean) { + this.mini_sidebar = payload; + }, + SET_FONT(payload: string) { + this.fontTheme = payload; + } + } +}); diff --git a/dashboard/src/theme/LightTheme.ts b/dashboard/src/theme/LightTheme.ts new file mode 100644 index 000000000..e7cf93a1f --- /dev/null +++ b/dashboard/src/theme/LightTheme.ts @@ -0,0 +1,41 @@ +import type { ThemeTypes } from '@/types/themeTypes/ThemeType'; + +const PurpleTheme: ThemeTypes = { + name: 'PurpleTheme', + dark: false, + variables: { + 'border-color': '#1e88e5', + 'carousel-control-size': 10 + }, + colors: { + primary: '#1e88e5', + secondary: '#5e35b1', + info: '#03c9d7', + success: '#00c853', + accent: '#FFAB91', + warning: '#ffc107', + error: '#f44336', + lightprimary: '#eef2f6', + lightsecondary: '#ede7f6', + lightsuccess: '#b9f6ca', + lighterror: '#f9d8d8', + lightwarning: '#fff8e1', + darkText: '#212121', + lightText: '#616161', + darkprimary: '#1565c0', + darksecondary: '#4527a0', + borderLight: '#d0d0d0', + inputBorder: '#787878', + containerBg: '#eef2f6', + surface: '#fff', + 'on-surface-variant': '#fff', + facebook: '#4267b2', + twitter: '#1da1f2', + linkedin: '#0e76a8', + gray100: '#fafafa', + primary200: '#90caf9', + secondary200: '#b39ddb' + } +}; + +export { PurpleTheme }; diff --git a/dashboard/src/types/themeTypes/ThemeType.ts b/dashboard/src/types/themeTypes/ThemeType.ts new file mode 100644 index 000000000..52ed07ba3 --- /dev/null +++ b/dashboard/src/types/themeTypes/ThemeType.ts @@ -0,0 +1,35 @@ +export type ThemeTypes = { + name: string; + dark: boolean; + variables?: object; + colors: { + primary?: string; + secondary?: string; + info?: string; + success?: string; + accent?: string; + warning?: string; + error?: string; + lightprimary?: string; + lightsecondary?: string; + lightsuccess?: string; + lighterror?: string; + lightwarning?: string; + darkprimary?: string; + darksecondary?: string; + darkText?: string; + lightText?: string; + borderLight?: string; + inputBorder?: string; + containerBg?: string; + surface?: string; + background?: string; + 'on-surface-variant'?: string; + facebook?: string; + twitter?: string; + linkedin?: string; + gray100?: string; + primary200?: string; + secondary200?: string; + }; +}; diff --git a/dashboard/src/types/vue3-print-nb.d.ts b/dashboard/src/types/vue3-print-nb.d.ts new file mode 100644 index 000000000..6c5f78e18 --- /dev/null +++ b/dashboard/src/types/vue3-print-nb.d.ts @@ -0,0 +1 @@ +declare module 'vue3-print-nb'; diff --git a/dashboard/src/types/vue_tabler_icon.d.ts b/dashboard/src/types/vue_tabler_icon.d.ts new file mode 100644 index 000000000..8afdef5d2 --- /dev/null +++ b/dashboard/src/types/vue_tabler_icon.d.ts @@ -0,0 +1,10 @@ +import { VNodeChild } from 'vue'; +declare module '@vue/runtime-dom' { + export interface HTMLAttributes { + $children?: VNodeChild; + } + export interface SVGAttributes { + $children?: VNodeChild; + strokeWidth?: string | number; + } +} diff --git a/dashboard/src/views/ATRIProject.vue b/dashboard/src/views/ATRIProject.vue new file mode 100644 index 000000000..4c9a771d4 --- /dev/null +++ b/dashboard/src/views/ATRIProject.vue @@ -0,0 +1,87 @@ + + + + + + \ No newline at end of file diff --git a/dashboard/src/views/ConfigPage.vue b/dashboard/src/views/ConfigPage.vue new file mode 100644 index 000000000..9ff174669 --- /dev/null +++ b/dashboard/src/views/ConfigPage.vue @@ -0,0 +1,220 @@ + + + + + + + + \ No newline at end of file diff --git a/dashboard/src/views/ConsolePage.vue b/dashboard/src/views/ConsolePage.vue new file mode 100644 index 000000000..9732a0f6f --- /dev/null +++ b/dashboard/src/views/ConsolePage.vue @@ -0,0 +1,36 @@ + + + + + + \ No newline at end of file diff --git a/dashboard/src/views/ExtensionPage.vue b/dashboard/src/views/ExtensionPage.vue new file mode 100644 index 000000000..b0ae0ffd8 --- /dev/null +++ b/dashboard/src/views/ExtensionPage.vue @@ -0,0 +1,391 @@ + + + + + \ No newline at end of file diff --git a/dashboard/src/views/authentication/auth/LoginPage.vue b/dashboard/src/views/authentication/auth/LoginPage.vue new file mode 100644 index 000000000..63a1f809c --- /dev/null +++ b/dashboard/src/views/authentication/auth/LoginPage.vue @@ -0,0 +1,25 @@ + + + + diff --git a/dashboard/src/views/authentication/authForms/AuthLogin.vue b/dashboard/src/views/authentication/authForms/AuthLogin.vue new file mode 100644 index 000000000..55081f08a --- /dev/null +++ b/dashboard/src/views/authentication/authForms/AuthLogin.vue @@ -0,0 +1,87 @@ + + + + + diff --git a/dashboard/src/views/dashboards/default/DefaultDashboard.vue b/dashboard/src/views/dashboards/default/DefaultDashboard.vue new file mode 100644 index 000000000..2f6acbed3 --- /dev/null +++ b/dashboard/src/views/dashboards/default/DefaultDashboard.vue @@ -0,0 +1,50 @@ + + + + diff --git a/dashboard/src/views/dashboards/default/components/MessageStat.vue b/dashboard/src/views/dashboards/default/components/MessageStat.vue new file mode 100644 index 000000000..bd5967141 --- /dev/null +++ b/dashboard/src/views/dashboards/default/components/MessageStat.vue @@ -0,0 +1,114 @@ + + + + + \ No newline at end of file diff --git a/dashboard/src/views/dashboards/default/components/OnlinePlatform.vue b/dashboard/src/views/dashboards/default/components/OnlinePlatform.vue new file mode 100644 index 000000000..26fd6e8a1 --- /dev/null +++ b/dashboard/src/views/dashboards/default/components/OnlinePlatform.vue @@ -0,0 +1,37 @@ + + + + + + \ No newline at end of file diff --git a/dashboard/src/views/dashboards/default/components/OnlineTime.vue b/dashboard/src/views/dashboards/default/components/OnlineTime.vue new file mode 100644 index 000000000..4ba51a7d1 --- /dev/null +++ b/dashboard/src/views/dashboards/default/components/OnlineTime.vue @@ -0,0 +1,61 @@ + + + + + + \ No newline at end of file diff --git a/dashboard/src/views/dashboards/default/components/PlatformStat.vue b/dashboard/src/views/dashboards/default/components/PlatformStat.vue new file mode 100644 index 000000000..243fd5b18 --- /dev/null +++ b/dashboard/src/views/dashboards/default/components/PlatformStat.vue @@ -0,0 +1,116 @@ + + + + + + \ No newline at end of file diff --git a/dashboard/src/views/dashboards/default/components/TotalMessage.vue b/dashboard/src/views/dashboards/default/components/TotalMessage.vue new file mode 100644 index 000000000..8af94a754 --- /dev/null +++ b/dashboard/src/views/dashboards/default/components/TotalMessage.vue @@ -0,0 +1,40 @@ + + + + + \ No newline at end of file diff --git a/dashboard/tsconfig.json b/dashboard/tsconfig.json new file mode 100644 index 000000000..7820a40b1 --- /dev/null +++ b/dashboard/tsconfig.json @@ -0,0 +1,18 @@ +{ + "extends": "@vue/tsconfig/tsconfig.dom.json", + "include": ["env.d.ts", "src/**/*", "src/**/*.vue", "src/types/.d.ts"], + "compilerOptions": { + "ignoreDeprecations": "5.0", + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + }, + "allowJs": true + }, + + "references": [ + { + "path": "./tsconfig.vite-config.json" + } + ] +} diff --git a/dashboard/tsconfig.vite-config.json b/dashboard/tsconfig.vite-config.json new file mode 100644 index 000000000..a3d4b2151 --- /dev/null +++ b/dashboard/tsconfig.vite-config.json @@ -0,0 +1,9 @@ +{ + "extends": "@vue/tsconfig/tsconfig.json", + "include": ["vite.config.*"], + "compilerOptions": { + "composite": true, + "allowJs": true, + "types": ["node"] + } +} diff --git a/dashboard/vite.config.ts b/dashboard/vite.config.ts new file mode 100644 index 000000000..673187ded --- /dev/null +++ b/dashboard/vite.config.ts @@ -0,0 +1,47 @@ +import { fileURLToPath, URL } from 'url'; +import { defineConfig } from 'vite'; +import vue from '@vitejs/plugin-vue'; +import vuetify from 'vite-plugin-vuetify'; + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [ + vue({ + template: { + compilerOptions: { + isCustomElement: (tag) => ['v-list-recognize-title'].includes(tag) + } + } + }), + vuetify({ + autoImport: true + }) + ], + resolve: { + alias: { + '@': fileURLToPath(new URL('./src', import.meta.url)) + } + }, + css: { + preprocessorOptions: { + scss: {} + } + }, + build: { + chunkSizeWarningLimit: 1024 * 1024 // Set the limit to 1 MB + }, + optimizeDeps: { + exclude: ['vuetify'], + entries: ['./src/**/*.vue'] + }, + server: { + host: '0.0.0.0', + port: 3000, + proxy: { + '/api': { + target: 'http://localhost:6185/', + changeOrigin: true, + } + } + } +});