From d0ebfd56a19ee9c508b0b03ee9c23e7df26e2a62 Mon Sep 17 00:00:00 2001 From: mi1468 Date: Mon, 21 Apr 2025 16:17:59 +0330 Subject: [PATCH] add files page --- xroom-dashboard/src/assets/main.css | 44 ++ xroom-dashboard/src/axios.js | 16 + xroom-dashboard/src/components.rar | Bin 0 -> 7331 bytes .../src/components/DashboardPage.vue | 703 ++++++++++++++---- .../src/components/SidebarMenu.vue | 352 ++++++--- xroom-dashboard/src/main.js | 1 + .../src/{components => pages}/LoginPage.vue | 36 +- .../src/{components => pages}/SignupPage.vue | 0 xroom-dashboard/src/pages/dashboard/files.vue | 341 +++++++++ xroom-dashboard/src/pages/dashboard/index.vue | 575 ++++++++++++++ xroom-dashboard/src/router/index.js | 39 +- 11 files changed, 1858 insertions(+), 249 deletions(-) create mode 100644 xroom-dashboard/src/assets/main.css create mode 100644 xroom-dashboard/src/axios.js create mode 100644 xroom-dashboard/src/components.rar rename xroom-dashboard/src/{components => pages}/LoginPage.vue (83%) rename xroom-dashboard/src/{components => pages}/SignupPage.vue (100%) create mode 100644 xroom-dashboard/src/pages/dashboard/files.vue create mode 100644 xroom-dashboard/src/pages/dashboard/index.vue diff --git a/xroom-dashboard/src/assets/main.css b/xroom-dashboard/src/assets/main.css new file mode 100644 index 0000000..e6c28a9 --- /dev/null +++ b/xroom-dashboard/src/assets/main.css @@ -0,0 +1,44 @@ +/* main.css */ +@import url("https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css"); + +:root { + --white: rgba(255, 255, 255, 1); + --black: rgba(16, 16, 16, 1); + --accentcolor-accentcolor-600: rgba(230, 230, 230, 1); + --neutralcolorneutralcolor-25: rgba(198, 204, 213, 1); + --neutralcolorneutralcolor-300: rgba(141, 153, 171, 1); + --neutralcolorneutralcolor-600: rgba(102, 115, 135, 1); + --neutralcolorneutralcolor-500: rgba(113, 128, 150, 1); + --neutralcolorneutralcolor-800: rgba(79, 90, 105, 1); + --neutralcolorneutralcolor-900: rgba(68, 77, 90, 1); + --neutralcolorneutralcolor-400: rgba(127, 141, 161, 1); + --neutralcolorneutralcolor-50: rgba(184, 192, 203, 1); + --successcolor-successcolor-500: rgba(72, 187, 120, 1); + --brand-colorbrand-color-400: rgba(97, 121, 237, 1); + --neutralcolorneutralcolor-1000: rgba(45, 51, 60, 1); + --successcolor-successcolor-300: rgba(109, 201, 147, 1); + --brand-colorbrand-color-800: rgba(32, 48, 128, 1); +} + +* { + -webkit-font-smoothing: antialiased; + box-sizing: border-box; +} + +html, +body { + margin: 0px; + height: 100%; + background-color: #101010; + font-family: "IRANSansXFaNum-Medium", Helvetica; +} + +/* a blue color as a generic focus style */ +button:focus-visible { + outline: 2px solid #4a90e2 !important; + outline: -webkit-focus-ring-color auto 5px !important; +} + +a { + text-decoration: none; +} \ No newline at end of file diff --git a/xroom-dashboard/src/axios.js b/xroom-dashboard/src/axios.js new file mode 100644 index 0000000..2f0c375 --- /dev/null +++ b/xroom-dashboard/src/axios.js @@ -0,0 +1,16 @@ +// src/axios.js +import axios from 'axios'; + +const instance = axios.create({ + baseURL: 'http://194.62.43.230:8000', +}); + +instance.interceptors.request.use(config => { + const token = localStorage.getItem('token'); + if (token) { + config.headers.Authorization = `token ${token}`; + } + return config; +}); + +export default instance; diff --git a/xroom-dashboard/src/components.rar b/xroom-dashboard/src/components.rar new file mode 100644 index 0000000000000000000000000000000000000000..114429892829c104a859dd7c83bea24242d81c33 GIT binary patch literal 7331 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 - - - - - \ No newline at end of file + + + + + + + \ No newline at end of file diff --git a/xroom-dashboard/src/components/SidebarMenu.vue b/xroom-dashboard/src/components/SidebarMenu.vue index 4c24d65..fc447b6 100644 --- a/xroom-dashboard/src/components/SidebarMenu.vue +++ b/xroom-dashboard/src/components/SidebarMenu.vue @@ -1,94 +1,270 @@ + - - - - - \ No newline at end of file +} + + + \ No newline at end of file diff --git a/xroom-dashboard/src/main.js b/xroom-dashboard/src/main.js index 4ac17c1..49aabb8 100644 --- a/xroom-dashboard/src/main.js +++ b/xroom-dashboard/src/main.js @@ -1,6 +1,7 @@ import { createApp } from 'vue' import App from './App.vue' import router from './router' +import '@/assets/main.css' createApp(App) .use(router) // Make sure you use the router here diff --git a/xroom-dashboard/src/components/LoginPage.vue b/xroom-dashboard/src/pages/LoginPage.vue similarity index 83% rename from xroom-dashboard/src/components/LoginPage.vue rename to xroom-dashboard/src/pages/LoginPage.vue index 601f962..6654e00 100644 --- a/xroom-dashboard/src/components/LoginPage.vue +++ b/xroom-dashboard/src/pages/LoginPage.vue @@ -55,24 +55,26 @@ export default { }, methods: { async handleSubmit() { - // Prepare the data to match API format - const signupData = { - first_name: this.form.firstName, - last_name: this.form.lastName, - mobile_number: this.form.mobileNumber, - password: this.form.password, - }; + const loginData = { + mobile_number: this.form.mobileNumber, + password: this.form.password, + }; + + try { + const response = await axios.post('http://194.62.43.230:8000/login', loginData); + const token = response.data.token; + const user = response.data.user; + + localStorage.setItem('token', token); + localStorage.setItem('user', JSON.stringify(user)); + + this.$router.push('/dashboard'); + } catch (error) { + console.error('Login error:', error); + alert('خطا در ورود. لطفا دوباره تلاش کنید.'); + } +}, - try { - const response = await axios.post('http://194.62.43.230:8000/login', signupData); - console.log('Signup success:', response.data); - // Redirect to login page upon successful signup - this.$router.push('/dashboard'); - } catch (error) { - console.error('Signup error:', error); - // Handle error, show alert or error message - } - }, }, }; diff --git a/xroom-dashboard/src/components/SignupPage.vue b/xroom-dashboard/src/pages/SignupPage.vue similarity index 100% rename from xroom-dashboard/src/components/SignupPage.vue rename to xroom-dashboard/src/pages/SignupPage.vue diff --git a/xroom-dashboard/src/pages/dashboard/files.vue b/xroom-dashboard/src/pages/dashboard/files.vue new file mode 100644 index 0000000..cc70368 --- /dev/null +++ b/xroom-dashboard/src/pages/dashboard/files.vue @@ -0,0 +1,341 @@ + + + + + + \ No newline at end of file diff --git a/xroom-dashboard/src/pages/dashboard/index.vue b/xroom-dashboard/src/pages/dashboard/index.vue new file mode 100644 index 0000000..b35a535 --- /dev/null +++ b/xroom-dashboard/src/pages/dashboard/index.vue @@ -0,0 +1,575 @@ + + + + + + \ No newline at end of file diff --git a/xroom-dashboard/src/router/index.js b/xroom-dashboard/src/router/index.js index 8552811..16a439c 100644 --- a/xroom-dashboard/src/router/index.js +++ b/xroom-dashboard/src/router/index.js @@ -1,8 +1,9 @@ import { createRouter, createWebHistory } from 'vue-router' -import SignupPage from '../components/SignupPage.vue' // Renamed -import LoginPage from '../components/LoginPage.vue' // Renamed -import DashboardPage from '../components/DashboardPage.vue' -import FilesPage from '@/components/FilesPage.vue'; // import the new page +import SignupPage from '../pages/SignupPage.vue' // Renamed +import LoginPage from '../pages/LoginPage.vue' // Renamed +import DashboardPage from '../pages/dashboard/index.vue' +import FilesPage from '@/pages/dashboard/files.vue'; // import the new page +import axios from '@/axios'; const routes = [ { @@ -20,7 +21,7 @@ const routes = [ name: 'DashboardPage', // Renamed component: DashboardPage },{ - path: '/files', + path: '/dashboard/files', name: 'files', component: FilesPage, // link the files page } @@ -31,4 +32,32 @@ const router = createRouter({ routes }) + +router.beforeEach(async (to, from, next) => { + const token = localStorage.getItem('token'); + + // No token, redirect to login if trying to access dashboard + if (to.path === '/dashboard' && !token) { + return next('/login'); + } + + if (token) { + try { + await axios.get('/getInfo'); + if (to.path === '/login') { + return next('/dashboard'); + } + return next(); + } catch (err) { + // Invalid token, redirect to login + localStorage.removeItem('token'); + localStorage.removeItem('user'); + return next('/login'); + } + } + + next(); +}); + + export default router